build(agent): new-agents-4#58ba63 iteration
This commit is contained in:
parent
112c4eed2f
commit
222c185427
37
README.md
37
README.md
|
|
@ -1,33 +1,12 @@
|
||||||
# AidMesh: Federated, Privacy-Preserving Disaster Response Orchestrator
|
# AidMesh Federated Privacy Primitives
|
||||||
|
|
||||||
Overview
|
This repository provides production-ready Python primitives for a privacy-preserving, offline-first disaster relief orchestration framework inspired by the Graph-of-Contracts (GoC) concept. The initial MVP focuses on core data models and deterministic replay semantics to enable islanded operation and later cross-organization coordination.
|
||||||
- AidMesh provides a privacy-preserving, offline-first orchestration framework for disaster relief planning across partner organizations. It models core primitives as a Graph-of-Contracts (GoC) with:
|
|
||||||
- Objects: LocalProblems (per-site relief tasks)
|
|
||||||
- Morphisms: SharedSignals and DualVariables
|
|
||||||
- PlanDelta: cryptographically-tagged actions
|
|
||||||
- AuditLog / PrivacyBudget: provenance and privacy controls
|
|
||||||
- Time rounds: delta-sync cadence for islanded operation and deterministic replay
|
|
||||||
|
|
||||||
Delivery Goal
|
What you get:
|
||||||
- A production-ready skeleton with a small, testable core ensuring end-to-end delta-sync between partners over TLS-like channels, plus a toy ADMM-lite solver for cross-organization optimization.
|
- Dataclass-based core primitives: LocalProblem, SharedSignals, PlanDelta, DualVariables, AuditLog, PolicyBlock
|
||||||
|
- Lightweight serialization via to_dict() for easy transport and auditing
|
||||||
|
- Packaging that validates with test.sh: unit tests and a packaging build
|
||||||
|
|
||||||
What’s included
|
Usage note: The first milestone focuses on end-to-end data flow between a couple of toy adapters in a TLS-secured channel. See tests for basic dataclass behavior.
|
||||||
- Core data models (dataclasses)
|
|
||||||
- Lightweight ADMM-lite solver
|
|
||||||
- Toy adapters for onboarding (SupplyDepotController, FieldDistributionPlanner)
|
|
||||||
- Basic tests and packaging metadata (pyproject.toml)
|
|
||||||
- test.sh that runs pytest and builds the package
|
|
||||||
|
|
||||||
- How to use
|
This README will be expanded as we ship more MVP phases and adapters.
|
||||||
- Run tests: ./test.sh
|
|
||||||
- Explore modules under src/idea151_aidmesh_federated_privacy/
|
|
||||||
- Extend with adapters by following the toy adapters pattern in adapters.py
|
|
||||||
- Package metadata and publishing notes are in pyproject.toml
|
|
||||||
- Run tests: ./test.sh
|
|
||||||
- Explore modules under src/idea151_aidmesh_federated_privacy/
|
|
||||||
- Extend with adapters by following the toy adapters pattern in adapters.py
|
|
||||||
|
|
||||||
Contribution
|
|
||||||
- See AGENTS.md for architectural details and contribution guidelines.
|
|
||||||
|
|
||||||
Note: This repository is intended as a production-ready, testable chunk that can be extended by subsequent teams in the SWARM.
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
"""Top-level shim package for tests to import the AidMesh models without needing an editable install.
|
||||||
|
This mirrors the src package contents for import compatibility in test environments that don't install the package.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .models import * # noqa: F401,F403
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"LocalProblem",
|
||||||
|
"SharedSignals",
|
||||||
|
"PlanDelta",
|
||||||
|
"DualVariables",
|
||||||
|
"AuditLog",
|
||||||
|
"PolicyBlock",
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass, asdict
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
|
||||||
|
def _to_iso(dt: datetime) -> str:
|
||||||
|
if isinstance(dt, datetime):
|
||||||
|
return dt.isoformat()
|
||||||
|
return dt # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class LocalProblem:
|
||||||
|
id: str
|
||||||
|
domain: str
|
||||||
|
assets: Dict[str, Any]
|
||||||
|
objectives: List[str]
|
||||||
|
constraints: Dict[str, Any]
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
return dict(asdict(self))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class SharedSignals:
|
||||||
|
forecast: Dict[str, Any]
|
||||||
|
capacity_proxies: Dict[str, Any]
|
||||||
|
privacy_budget: float
|
||||||
|
version: int
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
return dict(asdict(self))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class PlanDelta:
|
||||||
|
delta: Dict[str, Any]
|
||||||
|
timestamp: datetime
|
||||||
|
author: str
|
||||||
|
contract_id: str
|
||||||
|
signature: str
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
d = dict(asdict(self))
|
||||||
|
d["timestamp"] = _to_iso(self.timestamp)
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class DualVariables:
|
||||||
|
multipliers: Dict[str, float]
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
return dict(asdict(self))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class AuditLog:
|
||||||
|
entry: str
|
||||||
|
signer: str
|
||||||
|
timestamp: datetime
|
||||||
|
contract_id: str
|
||||||
|
version: int
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
d = dict(asdict(self))
|
||||||
|
d["timestamp"] = _to_iso(self.timestamp)
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class PolicyBlock:
|
||||||
|
safety_exposure: float
|
||||||
|
data_exposure_limit: float
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
return dict(asdict(self))
|
||||||
|
|
@ -1,22 +1,13 @@
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=61.0","wheel"]
|
requires = ["setuptools>=42", "wheel"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "aidmesh"
|
name = "idea151-aidmesh-federated-privacy"
|
||||||
version = "0.1.0"
|
version = "0.0.1"
|
||||||
description = "Federated, privacy-preserving disaster response orchestrator (AidMesh) skeleton"
|
description = "Core primitives for AidMesh: federated, privacy-preserving disaster response orchestration"
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.8"
|
||||||
|
dynamic = ["readme", "license", "authors"]
|
||||||
|
|
||||||
authors = [
|
[tool.setuptools]
|
||||||
{ name = "OpenCode" },
|
packages = ["idea151_aidmesh_federated_privacy"]
|
||||||
]
|
|
||||||
|
|
||||||
dependencies = []
|
|
||||||
|
|
||||||
[project.urls]
|
|
||||||
Homepage = "https://example.org/aidmesh"
|
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
|
||||||
where = ["src"]
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
[metadata]
|
||||||
|
name = idea151-aidmesh-federated-privacy
|
||||||
|
version = 0.0.1
|
||||||
|
description = Core primitives for AidMesh: federated, privacy-preserving disaster response orchestration
|
||||||
|
author = OpenCode
|
||||||
|
license = MIT
|
||||||
|
long_description = file: README.md
|
||||||
|
long_description_content_type = text/markdown
|
||||||
|
|
||||||
|
[options]
|
||||||
|
packages = find:
|
||||||
|
package_dir = =src
|
||||||
|
python_requires = >=3.8
|
||||||
|
include_package_data = true
|
||||||
|
|
||||||
|
[options.packages.find]
|
||||||
|
where = src
|
||||||
|
|
@ -1,23 +1,9 @@
|
||||||
"""AidMesh Federated Privacy Core Package
|
"""Idea151 AidMesh Federated Privacy Package
|
||||||
|
|
||||||
Lightweight, production-ready primitives to bootstrap a privacy-preserving,
|
Public package initializer. Exposes core datamodels for tests and consumers.
|
||||||
offline-first disaster-relief orchestration framework.
|
|
||||||
|
|
||||||
This package provides:
|
|
||||||
- Dataclass models: LocalProblem, SharedSignals, PlanDelta, DualVariables,
|
|
||||||
AuditLog, PolicyBlock
|
|
||||||
- A minimal DeltaSyncEngine to demonstrate deterministic replay semantics
|
|
||||||
- Toy adapters (NeedsCollector, ResourcePlanner) for onboarding
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from . import models # re-export for convenient access
|
from . import models # noqa: F401
|
||||||
from .core import DeltaSyncEngine
|
|
||||||
from .adapters import Adapter, NeedsCollector, ResourcePlanner
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = ["models"]
|
||||||
"models",
|
__version__ = "0.0.1"
|
||||||
"DeltaSyncEngine",
|
|
||||||
"Adapter",
|
|
||||||
"NeedsCollector",
|
|
||||||
"ResourcePlanner",
|
|
||||||
]
|
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,38 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, asdict, field
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
|
||||||
|
def _to_iso(dt: datetime) -> str:
|
||||||
|
if isinstance(dt, datetime):
|
||||||
|
return dt.isoformat()
|
||||||
|
return dt # type: ignore
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class LocalProblem:
|
class LocalProblem:
|
||||||
id: str
|
id: str
|
||||||
domain: str # e.g., "water_dist" or "shelter_allocation"
|
domain: str
|
||||||
assets: Dict[str, Any] # e.g., available resources at site
|
assets: Dict[str, Any]
|
||||||
objectives: List[str]
|
objectives: List[str]
|
||||||
constraints: Dict[str, Any]
|
constraints: Dict[str, Any]
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
return {
|
# Use asdict to ensure all fields are serializable types
|
||||||
"id": self.id,
|
return dict(asdict(self))
|
||||||
"domain": self.domain,
|
|
||||||
"assets": self.assets,
|
|
||||||
"objectives": self.objectives,
|
|
||||||
"constraints": self.constraints,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SharedSignals:
|
class SharedSignals:
|
||||||
forecast: Dict[str, Any]
|
forecast: Dict[str, Any]
|
||||||
capacity_proxies: Dict[str, float]
|
capacity_proxies: Dict[str, Any]
|
||||||
privacy_budget: Optional[float] = None
|
privacy_budget: float
|
||||||
version: int = 0
|
version: int
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
return {
|
return dict(asdict(self))
|
||||||
"forecast": self.forecast,
|
|
||||||
"capacity_proxies": self.capacity_proxies,
|
|
||||||
"privacy_budget": self.privacy_budget,
|
|
||||||
"version": self.version,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|
@ -45,16 +41,13 @@ class PlanDelta:
|
||||||
timestamp: datetime
|
timestamp: datetime
|
||||||
author: str
|
author: str
|
||||||
contract_id: str
|
contract_id: str
|
||||||
signature: str # placeholder for cryptographic tag
|
signature: str
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
return {
|
d = dict(asdict(self))
|
||||||
"delta": self.delta,
|
# ensure datetime is serialized in a stable format
|
||||||
"timestamp": self.timestamp.isoformat(),
|
d["timestamp"] = _to_iso(self.timestamp)
|
||||||
"author": self.author,
|
return d
|
||||||
"contract_id": self.contract_id,
|
|
||||||
"signature": self.signature,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|
@ -62,7 +55,7 @@ class DualVariables:
|
||||||
multipliers: Dict[str, float]
|
multipliers: Dict[str, float]
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
return {"multipliers": self.multipliers}
|
return dict(asdict(self))
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|
@ -74,24 +67,15 @@ class AuditLog:
|
||||||
version: int
|
version: int
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
return {
|
d = dict(asdict(self))
|
||||||
"entry": self.entry,
|
d["timestamp"] = _to_iso(self.timestamp)
|
||||||
"signer": self.signer,
|
return d
|
||||||
"timestamp": self.timestamp.isoformat(),
|
|
||||||
"contract_id": self.contract_id,
|
|
||||||
"version": self.version,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class PolicyBlock:
|
class PolicyBlock:
|
||||||
safety_exposure: float
|
safety_exposure: float
|
||||||
data_exposure_limit: float
|
data_exposure_limit: float
|
||||||
description: Optional[str] = None
|
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
return {
|
return dict(asdict(self))
|
||||||
"safety_exposure": self.safety_exposure,
|
|
||||||
"data_exposure_limit": self.data_exposure_limit,
|
|
||||||
"description": self.description,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue