Skip to content

iotlodge/ecosystem.harness

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ecosystem.harness (EH)

The governance plane above harness orchestration. EH turns harness-orchestration executions into institutional standards — the ? at the top of the abstraction ladder.

Full design spec: ../AGENTFIELD_CONTROL_PLANE_EF.md §15. Identity/NANDA: §8, §8.1.

flowchart BT
    I["Instructions"] --> P["Processes"] --> S["Services"] --> C["Containers"]
    C --> M["Model calls"] --> A["Agents"] --> H["Harnesses"] --> HO["Harness orchestration"]
    HO --> EH["ecosystem.harness — governance plane"]
    classDef top fill:#1f3a5f,color:#ffffff,stroke:#0d1b2a,stroke-width:3px;
    classDef base fill:#e8eef5,color:#1f3a5f,stroke:#9bb3cc;
    class EH top;
    class I,P,S,C,M,A,H,HO base;
Loading

Each era lifts the atomic unit of intelligence up a level, absorbing the complexity below. EH is the next lift: its atomic unit is a whole harness-orchestration run.


⭐ Deployment topology — one EH, many Fields (READ THIS FIRST)

EH runs as a single instance at the top. Many AgentField deployments ("Fields") report up. A fan-in: EH (exactly one) ← AgentField control planes (N, the "Fields") ← nodes/harnesses.

flowchart TB
    subgraph TRUST["🔐 Identity & Index — the trust fabric (spec §8, §8.1)"]
        direction LR
        BECKY["becky<br/>Identity & Access Manager<br/>Identity Store + DID issuer"]
        INDEX["NANDA Index / ARD catalog<br/>AgentAddr pointer + AgentFacts (W3C VC)<br/>+ revocation"]
        BECKY -->|"issues did:web / did:key"| INDEX
    end

    subgraph EHPLANE["EH — SINGLETON governance plane (its own container)"]
        EHCP["Control plane (stateless)"]
        OBS["Observation store<br/>scoped by (field_id, goal_hash)"]
        STD["Standards store<br/>versioned + scoped"]
        EHCP --- OBS
        EHCP --- STD
    end

    subgraph FIELDS["AgentField deployments — the Fields"]
        F1["Field A · did:web:acme<br/>control plane + harnesses"]
        F2["Field B · did:web:devbox<br/>(local, behind NAT)"]
        F3["Field C · did:web:custX<br/>harnesses"]
    end

    F1 -->|"① push SIGNED run records ▲"| EHCP
    F2 -->|"① push ▲"| EHCP
    F3 -->|"① push ▲"| EHCP
    EHCP -->|"② resolve + verify Field DID"| INDEX
    EHCP -->|"③ standards bundle — PULL ▼ (Field-signed verify)"| F1
    BECKY -.->|"governs global promotion"| STD

    classDef plane fill:#1f3a5f,color:#ffffff,stroke:#0d1b2a;
    classDef sec fill:#3a1f1f,color:#ffffff,stroke:#000000;
    class EHCP,OBS,STD plane;
    class BECKY,INDEX sec;
Loading
  • EH is its own Docker image — exactly like AgentField's control plane (spec §12.1): stateless compute, all state external, exactly one instance.
  • Anywhere a Field starts it is configured with EH's URL, port, and credentials. The Field is the client; EH is the backend it joins — the same join mechanism a harness uses, one tier up.
  • Direction: PUSH up, PULL down — never EH→Field polling. Fields sit behind NAT/firewalls; EH can never reach in. Observations are pushed up; standards are pulled down (GitOps-style).
  • Optional by design. No EH endpoint configured → the Field runs standalone; turning EH off changes nothing about how a Field runs.
  • Dev: one docker compose co-locates EH + a Field locally (same image). Cloud: one EH singleton; every Field points at it.

🔐 Security — Identity (DID) & the Index

Because one EH ingests run data from many independent Fields, every byte EH trusts must be cryptographically attributable to a Field. EH does not invent identity — it extends the existing becky → DID → NANDA chain (spec §8.1) one tier up. This is the backbone of tenant isolation, provenance integrity, and revocation.

The identity chain

flowchart LR
    IS["Identity Store row<br/>(becky-owned, boot invariant)"]
    DID["DID<br/>did:web / did:key"]
    AF["AgentFacts (W3C VC)<br/>capabilities + evaluations + telemetry"]
    NI["NANDA Index entry<br/>AgentAddr (≤120-byte pointer)"]
    EHV["EH trust check<br/>on every Field push"]

    IS -->|"provision_agentfield_did"| DID
    DID -->|"issue_agentfacts"| AF
    AF -->|"publish_nanda_entry"| NI
    NI -->|"resolve + verify + check revocation"| EHV
    EHV -.->|"runtime-earned metrics feed back (NANDA Goal G)"| AF

    classDef sec fill:#3a1f1f,color:#ffffff,stroke:#000000,stroke-width:2px;
    class EHV sec;
Loading

The loop matters: EH's cross-Field telemetry is exactly the runtime-earned evidence that populates AgentFacts evaluations/telemetry — audited trust, not self-advertised (spec §8).

How a signed push is verified (the trust boundary in action)

sequenceDiagram
    autonumber
    participant F as Field · AgentField
    participant B as becky · issuer
    participant X as Index · NANDA / ARD
    participant E as EH control plane

    B->>X: register Field DID + AgentFacts (VC)
    Note over F: run completes → build Run Record
    F->>F: sign Run Record with Field DID key
    F->>E: push { field_id, record, signature }
    E->>X: resolve Field DID + verify signature + revocation status
    X-->>E: DID document + AgentFacts (trust, status)
    alt valid & not revoked
        E->>E: attribute to field_id → store in (field_id, goal_hash) cohort
        E-->>F: ack
    else invalid / revoked / spoofed field_id
        E-->>F: reject (record dropped)
    end
    Note over E,F: standards pulled down later are EH-signed → Field verifies authenticity
Loading

What this buys (why DID + index = security):

Property Mechanism
Tenant isolation can't be spoofed A record's field_id is only trusted because the push is signed by that Field's DID and verified against the index. You cannot forge another tenant's data without its key.
Provenance integrity Run records are signed → tamper-evident end to end.
Revocation A compromised Field's DID is revoked in the index → EH rejects its pushes immediately.
No injected standards Standards pulled down are EH-signed; a Field verifies authenticity before applying — a poisoned standard can't be slipped in.
Auditable global promotion Crossing a tenant boundary (field → global) is becky-gated and recorded as a verifiable credential.

⭐ Tenancy — per-Field by default, global only by governed promotion

flowchart TB
    subgraph A["Field A (isolated)"]
        SA["standards scope=field"]
    end
    subgraph B["Field B (isolated)"]
        SB["standards scope=field"]
    end
    PROVEN["A standard proven across ≥ 2 Fields"]
    GATE{"becky / human gate<br/>consent-respecting"}
    GLOBAL["scope=global<br/>binds all Fields"]

    SA -->|"candidate"| PROVEN
    SB -->|"candidate"| PROVEN
    PROVEN --> GATE
    GATE -->|"approved (VC-attested)"| GLOBAL
    GATE -->|"declined"| SA

    classDef g fill:#1f3a2f,color:#ffffff,stroke:#0d2a1b;
    class GLOBAL g;
Loading
Rule
Cohort key Everything is scoped by (field_id, goal_hash). One Field's runs never implicitly mix with another's.
Standards default Learned from a Field's data → applies only to that Field (scope = "field").
Global promotion Proven across N Fields → may graduate to scope = "global", only via an explicit, becky/human-gated, consent-respecting step. Never automatic.
Global overview "See everything" is an explicit aggregation across field_ids, never silent cross-tenant leakage.

One customer's run data never shapes another's governance unless a human promotes it.


Why EH exists

A harness (SWE-AF, etc.) optimizes one task's accuracy. It systematically under-weights cross-cutting business objectives — cost, security, resilience, risk — because those are externalities to a single run, observable only across many runs. EH is the layer with that cross-Field visibility. It does not make execution traces deterministic (that would destroy the capability you pay for); it makes outcomes conformant and variance bounded — reproducible at "did this meet the standard," not "did it take the same path."

EH is a slow outer control loop: setpoint = human-governed business objectives · measurement = cross-Field telemetry · actuator = versioned standards bound back down.

The control loop (closes end-to-end in this repo)

flowchart LR
    OBS["Observe<br/>run records"] --> DR{"Drift?<br/>dead-band + persistence"}
    DR -- "no" --> OBS
    DR -- "yes" --> AT["Attribute<br/>config-diff bisect → seam"]
    AT --> PR["Propose Standard<br/>scope=field"]
    PR --> LANE{"Lane?<br/>low-risk seam + conf >= 0.8"}
    LANE -- "auto-apply" --> CAN["Canary<br/>full objective vector"]
    LANE -- "governed" --> APV{"becky / human<br/>approve?"}
    APV -- "approved" --> CAN
    APV -- "rejected" --> REJ["Rejected"]
    CAN --> ARB{"Objective Model<br/>arbitrate"}
    ARB -- "promote" --> PRO["Promoted ▼<br/>bind to Field"]
    ARB -- "reject / regression" --> REV["Reverted (versioned)"]
    ARB -- "ambiguous trade-off" --> ESC["Escalated → human"]
    ESC -- "promote" --> PRO
    ESC -- "revert" --> REV
    PRO --> GLOB{"Proven across<br/>>= 2 Fields?"}
    GLOB -- "yes — becky-gated" --> GP["Promote to GLOBAL"]

    classDef ok fill:#1f3a2f,color:#ffffff;
    classDef bad fill:#3a1f1f,color:#ffffff;
    class PRO,GP ok;
    class REJ,REV bad;
Loading

Objective Model — how a trade-off is arbitrated (§15.D)

The human-owned Objective Model is the governance setpoint. The canary delegates its promote/reject/escalate decision to it: hard floors are lexicographic (no trade-off), soft objectives are a weighted utility, and genuine ambiguity escalates to a human — whose decision then refines the weights.

flowchart TB
    V["Canary Δ-vector<br/>(cost, quality, security, …)"] --> HARD{"any HARD floor breached?<br/>(security_critical, compliance)"}
    HARD -- "yes" --> RJ["REJECT<br/>(lexicographic — non-negotiable)"]
    HARD -- "no" --> TGT{"target objective improved?"}
    TGT -- "no" --> RJ
    TGT -- "yes" --> U["Σ weightᵢ · signed_improvementᵢ<br/>over SOFT objectives"]
    U --> D{"utility vs margin"}
    D -- "≥ +margin" --> PRO["PROMOTE"]
    D -- "≤ −margin" --> RJ
    D -- "in between" --> ESC["ESCALATE → human<br/>(decision refines weights)"]

    classDef ok fill:#1f3a2f,color:#ffffff;
    classDef bad fill:#3a1f1f,color:#ffffff;
    classDef esc fill:#3a341f,color:#ffffff;
    class PRO ok;
    class RJ bad;
    class ESC esc;
Loading

Four proof obligations (spec §15.A–§15.D), all now executable: measurability (drift), attribution (bisect), stability (dead-band + canary + revert + versioning), trade-off arbitration (vector canary + lane routing).

This repo (build spike)

Module Role Spec
schema/run_record.py The normalized Run Record — the observation unit (field_id-tagged; outcome + process + risk faces), with EH-side derived metrics §15.A.8, §15.F
store/observation_store.py Immutable, time-stacked Observation Store; tenant-scoped (field_id, goal_hash) cohorts + explicit global_cohort §15.B, §15.F
drift/cost.py Cost-drift detector (Tier-A) with dead-band + persistence stability guards §15.A.6, §15.C
attribution/engine.py Attribution engine — drift → cause → seam → standard draft via config-diff bisect, loop-delta fallback, confidence + scope §15.A.9
governance/ Write-back loopStandard (versioned, scoped) · route (confidence/risk → lane) · CanaryVerifier (full objective vector) · GovernanceController (lifecycle, incl. escalation) · StandardsStore §15.C, §15.D, §15.F
objective/model.py Objective Model — human-owned objectives: hard floors (lexicographic) + soft weights; arbitrate() → promote/reject/escalate; feeds the canary verdict and the drift dead-band §15.D
ingestion/ Live transportIndex (DID registry + revocation) · sign/verify · SignedRecord/SignedBundle · IngestionGateway (push-up: resolve DID → revocation → anti-spoof → verify → store) · FieldClient (sign+push, pull+verify) §8, §15.F
service/ HTTP control plane — FastAPI app wrapping the gateway + loop: POST /api/v1/ingest (push-up), GET /api/v1/standards/{field_id} (pull-down), POST /api/v1/analyze/..., /healthz; Container composition root; field_simulator demo §12, §15.F

The full control loop closes end-to-end in code — Field signs + pushes run records up → EH verifies DID + stores → drift → attribute → propose → lane → canary → arbitrate → promote/revert/escalate → Field pulls + verifies its standards bundle down. Global promotion gated across ≥ 2 Fields. 61 tests (incl. a capstone live push→pull loop, the DID security model — unknown/revoked/spoofed/tampered all rejected — and HTTP-service tests). Runs as a containerized singleton (verified: image builds + serves /healthz).

The build spike is feature-complete and runnable. Next: real Ed25519/DID key material behind the sign/verify seam, and persistent stores (app.memory + git + Postgres) — packaging, not new logic.

Repository layout (spec §9)

ecosystem.harness/
├── README.md
├── docs/                 # docs/ARCHITECTURE.md (+ design refs)
├── backend/              # the EH control plane (this spike) + future HTTP service
│   ├── pyproject.toml
│   ├── src/ecosystem_harness/{schema,store,drift,attribution,objective,governance,ingestion}
│   └── tests/
├── infrastructure/       # Dockerfile(s), docker-compose, CDK, ARD/env config
└── frontend/             # (reserved) global cross-Field overview UI

Develop

cd backend
uv sync --extra dev
uv run pytest

Requires Python ≥ 3.12. The core library is pydantic-only; the HTTP service adds fastapi + uvicorn (the service extra).

Run it

Local (no Docker):

cd backend
uv run uvicorn ecosystem_harness.service.app:app --port 8080
# in another shell — simulate a Field pushing up / analyzing / pulling down:
EH_URL=http://localhost:8080 FIELD_ID=A uv run python -m ecosystem_harness.service.field_simulator

Containerized singleton:

docker compose -f infrastructure/docker-compose.yml up --build -d
curl localhost:8080/healthz

API: POST /api/v1/ingest (signed push-up) · GET /api/v1/standards/{field_id} (signed pull-down) · POST /api/v1/analyze/{field_id}/{goal_hash} · GET /healthz · OpenAPI at /docs.

About

The governance plane above harness orchestration — a cross-Field control loop that turns AI agent/harness executions into versioned, governed standards: drift detection → causal attribution → objective-arbitrated write-back, over DID-signed multi-tenant ingestion. The 4th plane atop LangGraph · AgentField · harness orchestration.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors