build(agent): new-agents-3#dd492b iteration

This commit is contained in:
agent-dd492b85242a98c5 2026-04-20 15:24:33 +02:00
parent 7eb5c1a7b4
commit 6944eda72d
14 changed files with 321 additions and 2 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
node_modules/
.npmrc
.env
.env.*
__tests__/
coverage/
.nyc_output/
dist/
build/
.cache/
*.log
.DS_Store
tmp/
.tmp/
__pycache__/
*.pyc
.venv/
venv/
*.egg-info/
.pytest_cache/
READY_TO_PUBLISH

27
AGENTS.md Normal file
View File

@ -0,0 +1,27 @@
# HopeMesh AGENTS
- Overview
- A production-oriented skeleton for a cross-domain, offline-first resource allocation system with governance and adapters.
- Architecture
- Core primitives: LocalProblem, SharedSignals, PlanDelta (GoC-style contracts).
- Graph of Contracts (GoC): lightweight in-process graph to connect problems, signals, and actions.
- Adapters: pluggable endpoints for field units, warehouses, transport hubs; starter adapters included.
- Transport: TLS-backed channel abstraction for inter-device communication.
- Governance: skeleton ledger for provenance with per-message signatures (extensible to DID-based identities).
- Tech Stack
- Language: Python 3.9+
- Packaging: pyproject.toml (setuptools)
- Testing and quality gates
- Basic unit tests for core primitives.
- test.sh to run pytest and python -m build for packaging checks.
- AGENTS.md intentionally documents architecture so future agents can contribute without breaking it.
- How to run locally
- python3 -m pytest
- bash test.sh
- Publishing rules
- Follow the publish checklist in the main task description; ensure READY_TO_PUBLISH exists when ready.

View File

@ -1,3 +1,32 @@
# idea152-hopemesh-federated-privacy
# HopeMesh: Federated, Privacy-Preserving Humanitarian Resource Allocation
Source logic for Idea #152
Overview
- HopeMesh is a distributed, offline-first platform to coordinate humanitarian aid across agencies in crisis zones with intermittent connectivity.
- It models local needs as LocalProblem, supply signals as SharedSignals, and delta actions as PlanDelta within a Graph-of-Contracts (GoC) architecture.
- The MVP focuses on cross-domain adapters (supply-inventory tracker and field-needs collector) with TLS transport, governance ledger skeleton, and a small cross-domain objective.
Architecture (high level)
- Core primitives: LocalProblem, SharedSignals, PlanDelta
- Graph-of-Contracts (GoC): a lightweight graph of contracts and adapters
- Adapters: plug in domain-specific data sources and workflows (starter adapters included)
- Governance ledger: per-message provenance and signature trail (skeleton)
- TLS transport: secure channels between field units and hubs
Tech Stack (by component)
- Language: Python 3.9+
- Packaging: pyproject.toml (setuptools) with an executable test script
- API surface: lightweight Python classes and simple in-memory data stores
How to run (local dev)
- Install dependencies: (no heavy deps required yet)
- Run tests: ./test.sh
- Package and build: python3 -m build
Packaging hooks
- The project name in pyproject.toml is idea152-hopemesh-federated-privacy to satisfy publishing rules.
- The Python importable package is idea152_hopemesh_federated_privacy (underscore style) to align with Python packaging norms.
Contributing
- See AGENTS.md for architecture, testing commands, and contribution rules.
License: MIT (example)

18
pyproject.toml Normal file
View File

@ -0,0 +1,18 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "idea152-hopemesh-federated-privacy"
version = "0.1.0"
description = "Federated, privacy-preserving humanitarian resource allocation prototype (HopeMesh)"
readme = "README.md"
requires-python = ">=3.9"
license = { file = "LICENSE" }
[project.urls]
Homepage = "https://example.org/hope-mesh"
Repository = "https://github.com/example/hope-mesh"
[tool.setuptools.packages.find]
where = ["src"]

10
src/__init__.py Normal file
View File

@ -0,0 +1,10 @@
"""Temporary namespace for the HopeMesh Python package.
This package provides core primitives and a minimal MVP scaffolding.
"""
__all__ = [
"core",
"governance",
"adapters",
"tls_transport",
]

1
src/adapters/__init__.py Normal file
View File

@ -0,0 +1 @@
"""Adapters package for HopeMesh MVP."""

View File

@ -0,0 +1 @@
"""Starter adapters for HopeMesh MVP."""

View File

@ -0,0 +1,32 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import List, Dict
import time
@dataclass
class FieldNeedsCollector:
collected: List[Dict] = field(default_factory=list)
def add_need(self, location: str, need_type: str, quantity: int, time_window: tuple[str, str]) -> None:
need = {
"location": location,
"need_type": need_type,
"quantity": quantity,
"time_window": time_window,
"timestamp": time.time(),
}
self.collected.append(need)
def to_local_problem(self) -> dict:
# Simple translation to LocalProblem-like dict for MVP testability
if not self.collected:
return {}
n = self.collected[-1]
return {
"location": n["location"],
"need_type": n["need_type"],
"quantity": n["quantity"],
"time_window": n["time_window"],
"priority": 3,
}

View File

@ -0,0 +1,22 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict
@dataclass
class SupplyInventoryTracker:
inventory: Dict[str, int] = field(default_factory=dict)
def register_item(self, item: str, quantity: int) -> None:
if item not in self.inventory:
self.inventory[item] = 0
self.inventory[item] += int(quantity)
def consume_item(self, item: str, quantity: int) -> bool:
if self.inventory.get(item, 0) < quantity:
return False
self.inventory[item] -= quantity
return True
def __repr__(self) -> str:
return f"SupplyInventoryTracker(inventory={self.inventory})"

51
src/core.py Normal file
View File

@ -0,0 +1,51 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, List, Tuple, Optional
@dataclass
class LocalProblem:
location: str
need_type: str
priority: int # 1-5, higher means more urgent
quantity: int
time_window: Tuple[str, str] # (start_iso, end_iso)
@dataclass
class SharedSignals:
stock_levels: Dict[str, int] # e.g., {"itemA": 100}
urgency_scores: Dict[str, float] # per-location urgency or need types
@dataclass
class PlanDelta:
plan_id: str
actions: List[Dict[str, object]] # simple action descriptors
timestamp: str # ISO timestamp
valid: bool = True
class GraphOfContracts:
"""Minimal GoC-like graph to connect problems, signals, and deltas."""
def __init__(self) -> None:
self.local_problems: List[LocalProblem] = []
self.shared_signals: Optional[SharedSignals] = None
self.plan_deltas: List[PlanDelta] = []
def add_local_problem(self, lp: LocalProblem) -> None:
self.local_problems.append(lp)
def set_shared_signals(self, ss: SharedSignals) -> None:
self.shared_signals = ss
def add_plan_delta(self, pd: PlanDelta) -> None:
self.plan_deltas.append(pd)
def __repr__(self) -> str:
return (
f"GraphOfContracts(LocalProblems={len(self.local_problems)}, "
f"SharedSignals={'set' if self.shared_signals else 'unset'}, "
f"PlanDeltas={len(self.plan_deltas)})"
)

36
src/governance.py Normal file
View File

@ -0,0 +1,36 @@
from __future__ import annotations
import hmac
import hashlib
from dataclasses import dataclass
from time import time
_SHARED_KEY = b"super-secret-key-for-tests" # In production, use DID-based keys or KMS
@dataclass
class GovernanceEntry:
message: str
signature: str
timestamp: float
class GovernanceLedger:
"""Skeleton governance ledger with simple HMAC-based signatures for testability."""
def __init__(self, key: bytes | None = None) -> None:
self.key = key or _SHARED_KEY
self.entries: list[GovernanceEntry] = []
def sign_message(self, message: str) -> GovernanceEntry:
ts = time()
sig = hmac.new(self.key, msg=message.encode("utf-8"), digestmod=hashlib.sha256).hexdigest()
entry = GovernanceEntry(message=message, signature=sig, timestamp=ts)
self.entries.append(entry)
return entry
def verify_entry(self, entry: GovernanceEntry) -> bool:
expected = hmac.new(self.key, msg=entry.message.encode("utf-8"), digestmod=hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, entry.signature)
def __repr__(self) -> str:
return f"GovernanceLedger(entries={len(self.entries)})"

22
src/tls_transport.py Normal file
View File

@ -0,0 +1,22 @@
from __future__ import annotations
class TLSEndpoint:
"""Minimal TLS transport stub for MVP. Not a full TLS server/client.
This provides a placeholder interface that future code can extend to use real TLS sockets.
"""
def __init__(self, address: str, use_tls: bool = True):
self.address = address
self.use_tls = use_tls
def send(self, data: bytes) -> None:
# Stub: in a real implementation this would write to a TLS-wrapped socket
if self.use_tls:
# pretend to encrypt and send
_ = data # no-op for placeholder
else:
pass
def receive(self) -> bytes:
# Stub: return empty bytes for MVP
return b""

6
test.sh Normal file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
printf "Running tests...\n"
pytest -q
printf "Building package...\n"
python3 -m build

43
test_core.py Normal file
View File

@ -0,0 +1,43 @@
import time
from src.core import LocalProblem, SharedSignals, PlanDelta, GraphOfContracts
def test_local_problem_dataclass():
lp = LocalProblem(
location="Site-A",
need_type="food_rations",
priority=4,
quantity=1000,
time_window=("2026-04-21T00:00:00Z", "2026-04-22T00:00:00Z"),
)
assert lp.location == "Site-A"
assert lp.need_type == "food_rations"
assert lp.quantity == 1000
def test_shared_signals_and_plan_delta_basics():
ss = SharedSignals(stock_levels={"itemA": 500}, urgency_scores={"Site-A": 0.8})
assert ss.stock_levels["itemA"] == 500
pd = PlanDelta(plan_id="P1", actions=[{"allocate": {"itemA": 100}}], timestamp=time.time())
assert pd.plan_id == "P1"
assert isinstance(pd.actions, list)
def test_graph_of_contracts_basic_flow():
go = GraphOfContracts()
lp = LocalProblem(
location="Site-B",
need_type="water",
priority=2,
quantity=200,
time_window=("2026-04-25T00:00:00Z", "2026-04-26T00:00:00Z"),
)
go.add_local_problem(lp)
ss = SharedSignals(stock_levels={"water": 1000}, urgency_scores={"Site-B": 0.5})
go.set_shared_signals(ss)
pd = PlanDelta(plan_id="P2", actions=[{"deliver": {"water": 200}}], timestamp=time.time())
go.add_plan_delta(pd)
assert len(go.local_problems) == 1
assert go.shared_signals is ss
assert len(go.plan_deltas) == 1