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

This commit is contained in:
agent-dd492b85242a98c5 2026-04-21 11:02:55 +02:00
parent 5f86c216a6
commit a443cdc797
13 changed files with 333 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

29
AGENTS.md Normal file
View File

@ -0,0 +1,29 @@
# MissionLedger Agents Guide
Overview
- MissionLedger is a production-grade core for verifiable, contract-driven planning in intermittently-connected fleets.
- This repo contains a minimal but production-oriented MVP to bootstrap the ecosystem: a DSL for per-asset LocalProblems, safety contracts, a shadow planner, a lightweight safety verifier, and a governanced ledger.
Architecture (high level)
- missionledger.dsl: Defines the LocalProblem, SafetyContracts, PrivacyContracts, and PlanDelta data models.
- missionledger.planner: ShadowPlanner that proposes a safe alternative plan in parallel to the executor.
- missionledger.safety: Lightweight safety verifier used by both the main planner and shadow planner.
- missionledger.governance: Tamper-evident governance ledger with hash chaining for auditability.
- missionledger.adapter (placeholder): SDK adapters for various assets and runtime stacks (rover, drone, habitat, orbiters).
Tech stack (current MVP)
- Python 3.8+ with a small, typed core using dataclasses.
- No external runtime dependencies for MVP; easy to extend with real solvers later.
Development commands
- Run tests: bash test.sh
- Build the package: python3 -m build
- Lint/type checks: not included in MVP yet; plan to add flake8/ruff and mypy in future iterations.
Tests and verification
- The test suite exercises the LocalProblem DSL, the ShadowPlanner, the safety verifier, and the governance ledger entries.
- Extend tests to cover full end-to-end delta-sync, proofs, and HIL adapters in later phases.
Contribution guidelines
- Follow the architecture layout described above.
- Add tests for any new feature and ensure tests pass locally before proposing PRs.

View File

@ -1,3 +1,21 @@
# idea19-missionledger-verifiable-contract
# MissionLedger: Verifiable, Contract-Driven AI Mission Planner (MVP)
Source logic for Idea #19
MissionLedger provides a minimal, production-ready core for contract-driven planning on intermittently-connected fleets. This MVP focuses on a clean, testable Python implementation of the DSL, a shadow planner, a lightweight safety verifier, and a tamper-evident governance ledger.
Whats included in this MVP
- LocalProblem DSL: per-asset objectives, variables, constraints, and risk budgets.
- SafetyContracts and PrivacyContracts scaffolding for future integration with verifiable proofs and privacy controls.
- ShadowPlanner: a simple, parallel planning agent that generates a safe delta alongside the primary plan.
- Lightweight safety verifier: deterministic checks for plan validity in the MVP.
- GovernanceLedger: append-only, tamper-evident log with hash chaining for auditability.
- A minimal tests suite to verify the core components.
Getting started
- Install dependencies and run tests via the provided test script.
- Build the package with the standard Python tooling.
Package metadata
- Package name: idea19_missionledger_verifiable_contract (Python project)
- Version: 0.1.0
This repository is intentionally minimal but designed to evolve into a full production-ready platform.

7
conftest.py Normal file
View File

@ -0,0 +1,7 @@
import sys
import os
# Ensure the repository root is on sys.path for test discovery/imports
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__)))
if ROOT not in map(os.path.abspath, sys.path):
sys.path.insert(0, ROOT)

23
missionledger/__init__.py Normal file
View File

@ -0,0 +1,23 @@
"""MissionLedger: Verifiable, Contract-Driven AI Mission Planner (Core)
This package provides a tiny, production-ready core to bootstrap the
MissionLedger MVP. It includes a lightweight DSL for per-asset LocalProblems
and Safety/Privacy contracts, a shadow planner, a simple on-device safety proof
hook, and a tamper-evident governance ledger.
"""
from .dsl import LocalProblem, SafetyContracts, PrivacyContracts, PlanDelta
from .planner import ShadowPlanner, PlanResult
from .safety import verify_plan
from .governance import GovernanceLedger
__all__ = [
"LocalProblem",
"SafetyContracts",
"PrivacyContracts",
"PlanDelta",
"ShadowPlanner",
"PlanResult",
"verify_plan",
"GovernanceLedger",
]

49
missionledger/dsl.py Normal file
View File

@ -0,0 +1,49 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict, List
@dataclass
class LocalProblem:
"""Per-asset planning objective and constraints.
- assets: mapping from asset_id to asset-specific objectives.
- variables: free-form variables used by the planner (e.g., timing, routing).
- constraints: list of simple constraint descriptors.
- risk_budget: a rough budget to limit risk (abstracted for this MVP).
"""
asset_objectives: Dict[str, Dict[str, Any]] = field(default_factory=dict)
variables: Dict[str, Any] = field(default_factory=dict)
constraints: List[str] = field(default_factory=list)
risk_budget: float = 0.0
@dataclass
class SafetyContracts:
"""Pre/post conditions and risk terms for safety proofs."""
pre_conditions: List[str] = field(default_factory=list)
post_conditions: List[str] = field(default_factory=list)
safety_budget: float = 0.0
collision_envelope: float = 0.0
cost_of_violation: float = 0.0
@dataclass
class PrivacyContracts:
"""Minimal data-exposure policies for privacy."""
allowed_publishers: List[str] = field(default_factory=list)
aggregate_signals: bool = True
per_message_privacy_budget: float = 0.0
@dataclass
class PlanDelta:
"""Compact representation of plan changes with metadata for auditability."""
delta: Dict[str, Any] = field(default_factory=dict)
version: int = 0
metadata: Dict[str, Any] = field(default_factory=dict)

View File

@ -0,0 +1,38 @@
from __future__ import annotations
import hashlib
import json
from datetime import datetime
from typing import List
class GovernanceLedger:
"""A simple tamper-evident governance ledger with per-entry hashes.
Logs are append-only and anchored via a rolling hash to the previous entry,
producing a chain of custody suitable for auditing even on intermittent
connectivity.
"""
def __init__(self, device_id: str = "unknown"):
self.device_id = device_id
self._entries: List[dict] = []
self._head_hash = ""
def log(self, entry: dict) -> None:
timestamp = datetime.utcnow().isoformat() + "Z"
payload = {
"device_id": self.device_id,
"timestamp": timestamp,
"entry": entry,
"parent": self._head_hash,
}
self._head_hash = hashlib.sha256(json.dumps(payload, sort_keys=True).encode()).hexdigest()
self._entries.append(payload)
@property
def entries(self) -> List[dict]:
return self._entries[:]
def latest_hash(self) -> str:
return self._head_hash

38
missionledger/planner.py Normal file
View File

@ -0,0 +1,38 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Dict
from .dsl import LocalProblem, PlanDelta
from .safety import verify_plan
@dataclass
class PlanResult:
"""Outcome from planning, including a safe delta and a proof flag."""
plan_delta: PlanDelta
proof_valid: bool
justification: str
class ShadowPlanner:
"""A lightweight shadow planner that runs in parallel to the executor.
For this MVP, it generates a conservative delta by slightly increasing
resource buffers to create a safe alternative plan if the primary plan is
infeasible with respect to LocalProblem.risk_budget.
"""
def __init__(self, local_problem: LocalProblem):
self.local_problem = local_problem
def plan(self, primary_delta: PlanDelta) -> PlanResult:
# Very simple heuristic: if risk_budget is low, persevere using a safer delta.
risk = float(self.local_problem.risk_budget or 0.0)
safe_delta = PlanDelta(delta={"safe_buffer": max(0.0, risk * 0.5)}, version=primary_delta.version + 1, metadata={"owner": "shadow"})
# Verify safety using the same (mocked) verify_plan hook
is_safe = verify_plan(self.local_problem, safe_delta)
justification = "Shadow plan generated" if is_safe else "Shadow plan could not be validated safely"
return PlanResult(plan_delta=safe_delta, proof_valid=is_safe, justification=justification)

24
missionledger/safety.py Normal file
View File

@ -0,0 +1,24 @@
from __future__ import annotations
from typing import Dict
from .dsl import LocalProblem, PlanDelta
def verify_plan(local_problem: LocalProblem, plan_delta: PlanDelta) -> bool:
"""Lightweight safety verification hook.
This is a minimal, deterministic verifier for the MVP:
- If the plan delta carries a non-negative 'safe_buffer', and the local
problem's risk_budget is compatible, accept the plan.
- Otherwise, reject.
This should be replaced with real formal verification hooks in a full build.
"""
buf = plan_delta.delta.get("safe_buffer", 0.0)
try:
risk = float(local_problem.risk_budget)
except Exception:
risk = 0.0
# Basic rule: safe if buffer does not exceed the risk budget.
return float(buf) <= max(0.0, risk)

15
pyproject.toml Normal file
View File

@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "idea19_missionledger_verifiable_contract"
version = "0.1.0"
description = "MVP core for verifiable contract-driven mission planning in intermittently-connected fleets."
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
[tool.setuptools.packages.find]
where = ["."]
include = ["missionledger*"]

20
sitecustomize.py Normal file
View File

@ -0,0 +1,20 @@
"""
Site customization for Python startup.
Ensures the repository root is on sys.path so tests can reliably import
the local package (e.g. `import missionledger.dsl`). This is a small,
non-invasive shim that helps CI environments where the Python path may not
include the project root by default.
"""
import sys
import os
try:
# Path to the repository root (directory containing this file)
_repo_root = os.path.dirname(os.path.abspath(__file__))
if _repo_root not in map(os.path.abspath, sys.path):
sys.path.insert(0, _repo_root)
except Exception:
# Be conservative: do not fail startup if this ever goes wrong
pass

9
test.sh Normal file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail
echo "==> Running tests with pytest ..."
pytest -q
echo "==> Building the package (python3 -m build) ..."
python3 -m build
echo "==> Build completed successfully."

40
tests/test_basic.py Normal file
View File

@ -0,0 +1,40 @@
import json
from missionledger.dsl import LocalProblem
from missionledger.planner import ShadowPlanner
from missionledger.dsl import PlanDelta
from missionledger.safety import verify_plan
from missionledger.governance import GovernanceLedger
def test_shadow_planner_and_safety_verification():
# Basic LocalProblem with a modest risk budget
lp = LocalProblem(
asset_objectives={"rover-1": {"energy": 1.0, "time": 2.0}},
variables={"start_time": 0},
constraints=["no_overload"],
risk_budget=1.0,
)
primary_delta = PlanDelta(delta={"basic_plan": True}, version=1, metadata={})
planner = ShadowPlanner(lp)
shadow = planner.plan(primary_delta)
# Validate safety proof via the lightweight verifier
assert shadow is not None
assert isinstance(shadow.plan_delta, PlanDelta)
assert shadow.proof_valid in (True, False)
# Sanity check: the safety verifier should be deterministic for the MVP
safe = verify_plan(lp, shadow.plan_delta)
assert safe == shadow.proof_valid
# Governance ledger usage: log an entry and inspect its wiring
gl = GovernanceLedger(device_id="test-device")
gl.log({"type": "plan_evaluation", "delta_version": shadow.plan_delta.version})
assert len(gl.entries) == 1
assert "parent" in gl.entries[0]
# latest_hash should be a non-empty string hash
assert isinstance(gl.latest_hash(), str)
assert len(gl.latest_hash()) > 0