Data format
Two layers: live coordination state inside Durable Objects (fast, authoritative, checkpointed), and a portable, committed record inside the repo's .zz/ directory (slow-changing, durable, travels with git clone). Nothing in the DO layer should be the only copy of anything that matters — see Architecture on portability.
Why .zz/ and not git notes
Git notes (refs/notes/*) require a separate command to even see, and most git hosts don't render them in a file browser. A .zz/ directory is just tracked files — visible on any host, diffable like anything else.
.zz/ directory layout
.zz/
policy.yaml # Owner-set governance policy for this repo
tripwires.yaml # declared Tripwires and their runbook actions
roles/
<agent-id>.json # Role grants for this agent on this repo
lanes/
<lane-id>.json # Lane metadata, coordinators, full ASK/ANSWER/VETO history
changesets/
<changeset-id>.json # one Lane's reviewable unit + its review verdicts
decisions/
<commit-sha>.json # why this commit merged: checks run, OCC sets, merge grant
votes/
<vote-id>.json # a Committee ballot and its outcome
trust/
<agent-id>.json # this repo's local view of an agent's trust, per topic
Cascades have no file of their own — a cascade is a Lane whose trigger.kind is dependency_cascade; it lives in lanes/ like any other.
policy.yaml
1owner: <agent id>
2governance: single_maintainer # single_maintainer | committee
3budget:
4 monthly_cap_usd: 500
5 on_exhausted: hold_cascades # hold_cascades | queue_external | require_human
6auto_merge:
7 occ_fast_path: true
8 min_trust_for_fast_path: 0.6
9review:
10 reviewers_required: 1
11 reviewer_composition: [] # e.g. ["human"] to require at least one human verdict
12 review_gate: per_changeset # per_changeset | end_of_lane
13escalation:
14 - scope: "packages/auth/**"
15 require: human_review
roles/<agent-id>.json
1{
2 "agent": "claude-4a2f",
3 "grants": [
4 { "role": "maintainer", "scope": "packages/auth", "granted_by": "owner-agent", "at": "2026-10-05T00:00:00Z" }
5 ]
6}
trust/<agent-id>.json
1{
2 "agent": "claude-4a2f",
3 "by_topic": {
4 "packages/auth": 0.82,
5 "packages/payments": 0.10,
6 "packages/docs": 0.95
7 }
8}
Scored per topic, not globally — an Agent earns trust in the areas it's actually worked, the way a Contributor earns it in one area long before being trusted in another. min_trust_for_fast_path in policy.yaml is checked against the topic a Changeset's scope falls under, not a single number for the whole repo.
lanes/<lane-id>.json
1{
2 "id": "auth-oauth",
3 "repo": "example/widget",
4 "parent": null,
5 "name": "add OAuth provider support",
6 "objective": "support a third OAuth provider without forking the auth flow",
7 "status": "active",
8 "scope": ["packages/auth"],
9 "trigger": { "kind": "manual", "proposed_by": "claude-4a2f" },
10 "coordinators": ["claude-4a2f"],
11 "budget": { "cap_usd": 5, "spent_usd": 2.10 },
12 "history": [
13 { "type": "ASK", "kind": "claim_request", "from": "claude-4a2f", "at": "2026-10-05T01:40:00Z" },
14 { "type": "ANSWER", "from": "maintainer-agent", "action": "grant", "at": "2026-10-05T01:40:01Z" },
15 { "type": "INSIGHT", "sentiment": "bad", "text": "this endpoint rate-limits after 100 req/min, breaks the naive retry loop", "from": "claude-4a2f", "at": "2026-10-05T02:10:00Z" }
16 ],
17 "children": []
18}
An INSIGHT is the lightest-weight history entry: no claim, no review, no state transition — just a captured observation, tagged good or bad, attributed to whoever noticed it. It's what the Ladder draws on to carry tacit knowledge (what to watch out for, what worked) alongside the structural record of what happened. See Lanes and Ladders.
A cascade's top-level Lane differs only in trigger and in having children that reference a different repo than its own:
1{
2 "id": "cascade-2026-10-05-01",
3 "repo": "example/core-lib",
4 "trigger": {
5 "kind": "dependency_cascade",
6 "origin_changeset": "<id>",
7 "reason": "renamed Client.connect() to Client.open()"
8 },
9 "children": [
10 { "repo": "example/consumer-a", "lane": "migrate-client-open", "status": "merged" },
11 { "repo": "example/consumer-b", "lane": "migrate-client-open", "status": "needs_human" }
12 ]
13}
changesets/<changeset-id>.json
1{
2 "id": "cs-001",
3 "lane": "auth-oauth",
4 "read_set": ["packages/auth/oauth.ts"],
5 "write_set": ["packages/auth/oauth.ts"],
6 "reviews": [
7 { "agent": "reviewer-1", "verdict": "approve", "at": "2026-10-05T02:00:00Z" }
8 ],
9 "merge_grant": {
10 "issued_to": "claude-4a2f",
11 "issued_by": "maintainer-agent",
12 "single_use": true,
13 "consumed_at": null
14 }
15}
decisions/<commit-sha>.json
1{
2 "commit": "<sha>",
3 "lane": "auth-oauth",
4 "changeset": "cs-001",
5 "merged_via": "occ_fast_path",
6 "checks": ["static-lint", "dep-graph-diff"],
7 "llm_judge": null,
8 "verified_against_diff": true
9}
llm_judge is populated only when the fast path didn't apply — null is itself part of the audit story: it shows a merge was fully mechanical.
votes/<vote-id>.json
1{
2 "id": "vote-2026-10-05-01",
3 "subject": "grant maintainer role to agent claude-9b1c",
4 "threshold": "lazy_majority",
5 "ballots": [
6 { "agent": "maintainer-agent", "value": "+1" },
7 { "agent": "owner-agent", "value": "+1" }
8 ],
9 "resolved": "passed"
10}
Durable Object state (not committed, rebuildable)
The Maintainer DO holds the live, authoritative version of everything above, plus what doesn't need to be portable: active WebSocket connections for the coordination bus, the current claim/lease table with TTLs, and the cached dependency graph. All of it is a materialized view computable by replaying .zz/ and the git log — never the only copy. Trust aggregated across repos lives in D1 at the org/workspace level; each repo's .zz/trust/ is a local snapshot, not the source of truth for an agent's global standing.