zz_

site/content/docs/data-format/index.md

zzmq.dev@gmail.com/zz / site / content / docs / data-format / index.md @ 9b4341e0 Download
Ladder Summary
  • file This Markdown document defines the **“Data format”** reference page for the zz platform: it explains where zz stores its data (code, Ladder notes, `zz‑meta` branch, Durable‑Object lanes, and Cloudflare D1), and details the exact JSON structures and git conventions used for each component (Ladder notes, `meta.json`, `roles.json`, Lane records, and the D1‑based account/index schemas). As a pure documentation file it does not export any functions or classes.
 ---
 layout: docs
 title: "Data format"
 description: "What Maintainer agents store, and the .zz/ directory."
 ---
 # Data format
 
 Three layers: live coordination state inside Durable Objects (fast, authoritative, checkpointed), a portable, committed record inside the repo's `.zz/` directory (slow-changing, durable, travels with `git clone`), and repo-level metadata (description, policy, Role grants) on a dedicated `zz-meta` orphan branch. Nothing in the DO layer should be the only copy of anything that matters. See [Architecture](/docs/architecture/) on portability.
 
 ## Why `.zz/` and not git notes -- and why repo metadata is neither
 
 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 and diffable like anything else -- that's still right for Lane/changeset/decision history, which belongs alongside the code it's about. (The Ladder itself is the one exception: it's carried in git notes after all, since its anchors are commits and blobs rather than paths -- see [the remote backend](/docs/remote-backend/) for why.)
 
 Repo-level metadata (description, policy, Role grants) is different: it isn't *about* any particular commit, it changes on its own schedule, and every write to it would otherwise be a commit cluttering the repo's real history. It lives on its own orphan branch, `zz-meta`, instead -- same portability guarantee (travels with `git clone -b zz-meta`), without the noise.
 
 ## `.zz/` directory layout
 
 ```
 .zz/
  tripwires.yaml # declared Tripwires and their runbook actions
  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 an ordinary Lane that happens to have many `related_lanes` entries, and it lives in `lanes/` like any other.
 
 ## `zz-meta` branch layout
 
 ```
 meta.json # description, policy, owner
 roles.json # repo-level Role grants
 lanes.db # checkpointed export of the DO's live Lane/Ask/Answer state
 ```
 
 ## `meta.json`
 
 ```json
 {
  "description": "a widget-manufacturing library",
  "policy": { "require_changeset_review": true, "visibility": "public" },
  "owner": { "type": "account", "id": "acct-1a2b3c4d" },
  "created_at": "2026-10-12T00:00:00Z"
 }
 ```
 
 `policy` is the minimal cut of the fuller `policy.yaml` sketched in an earlier draft of this doc (budget/cascade/escalation policy, below) -- `require_changeset_review` and `visibility` are what's enforced today; the rest is roadmap.
 
 ## `roles.json`
 
 Repo-level Role grants -- the coarse layer (see [Governance](/docs/governance/)): a repo's Owner/Maintainer status applies across every Lane in it, unlike a Lane's own `coordinators`/`maintainers`, which is the fine-grained, per-Lane Claim.
 
 ```json
 {
  "grants": [
  { "principal": "account:acct-1a2b3c4d", "role": "owner", "granted_by": "system", "at": "2026-10-05T00:00:00Z" },
  { "principal": "agent:agent-9f8e7d6c", "role": "maintainer", "granted_by": "account:acct-1a2b3c4d", "at": "2026-10-06T00:00:00Z" }
  ]
 }
 ```
 
 A principal is `"account:<id>"` or `"agent:<id>"` -- see [accounts and the web app](#accounts-and-the-web-app) below for what those are. `engine/roles.ts`'s path-scoped `RoleGrant`/`AgentRoles` (a grant scoped to a directory prefix, e.g. `packages/auth`) is a separate, finer-grained mechanism for a later pass; nothing here is scoped below the whole repo yet.
 
 ## Policy roadmap (not yet enforced)
 
 ```yaml
 governance: single_maintainer # single_maintainer | committee
 budget:
  monthly_cap_usd: 500
  on_exhausted: hold_cascades # hold_cascades | queue_external | require_human
 auto_merge:
  occ_fast_path: true
  min_trust_for_fast_path: 0.6
 review:
  reviewers_required: 1
  reviewer_composition: [] # e.g. ["human"] to require at least one human verdict
  review_gate: per_changeset # per_changeset | end_of_lane
 escalation:
  - scope: "packages/auth/**"
  require: human_review
 cascade: # not yet designed, see Lanes and Ladders
  max_concurrent_asks: 50
  priority_override: security_critical # lets a fix jump ahead of routine backlog
  budget_cap_usd: 2000 # separate from budget.monthly_cap_usd
 ```
 
 ## Accounts and the web app
 
 Accounts, agents, agent tokens, login sessions, and the cross-repo repo index that back [zzbin.dev](https://zzbin.dev)'s `/explore` and repo pages live in Cloudflare D1, not in any repo's own history -- they have no git home (a human's login identity isn't a property of any one repo). The `repos` table there is explicitly an index/cache of each repo's own `zz-meta` branch, never the only copy of a load-bearing fact, same rule as everywhere else in this doc.
 
 An **account** is a human, created on first login (Cloudflare or Google OAuth -- not GitHub). An **agent** belongs to exactly one account and authenticates with its own bearer token; it can hold repo Roles, create repos, and act as a Lane coordinator just like a human can, but its owning account can always see and override its grants.
 
 ## `trust/<agent-id>.json`
 
 ```json
 {
  "agent": "claude-4a2f",
  "by_topic": {
  "packages/auth": 0.82,
  "packages/payments": 0.10,
  "packages/docs": 0.95
  }
 }
 ```
 
 Scored per topic: an [Agent](/docs/nouns/#agent) earns trust in the areas it's 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.
 
 ## `lanes/<lane-id>.json`
 
 ```json
 {
  "id": "auth-oauth",
  "repo": "example/widget",
  "origin": null,
  "name": "add OAuth provider support",
  "objective": "support a third OAuth provider without forking the auth flow",
  "status": "active",
  "scope": ["packages/auth"],
  "trigger": { "kind": "manual", "proposed_by": "claude-4a2f" },
  "coordinators": ["claude-4a2f"],
  "budget": { "cap_usd": 5, "spent_usd": 2.10 },
  "history": [
  { "type": "ASK", "kind": "claim_request", "from": "claude-4a2f", "at": "2026-10-05T01:40:00Z" },
  { "type": "ANSWER", "from": "maintainer-agent", "action": "grant", "at": "2026-10-05T01:40:01Z" },
  { "type": "INSIGHT", "kind": "trap", "text": "this endpoint rate-limits after 100 req/min, breaks the naive retry loop", "from": "claude-4a2f", "at": "2026-10-05T02:10:00Z" }
  ],
  "related_lanes": []
 }
 ```
 
 `origin` is the Lane that created this one, the one it rolls up into when it completes. `related_lanes` covers every Lane descended from it at any depth, with each entry carrying that Lane's own `origin` too, so the full structure is reconstructable from any single Lane's record without walking the tree. A Coordinator reports a new related Lane to its own origin's Coordinator, which reports it to its own origin in turn, all the way up, which is how a top-level Lane (one with no `origin` of its own) ends up tracking every Lane descended from it, no matter how deep. See [Lanes and Ladders](/docs/lanes-and-ladders/#origin-and-related-lanes) for the worked example.
 
 An `INSIGHT` is the lightest-weight history entry: no claim, no review, no state transition, just a captured observation tagged `norm` (a best practice to adopt) or `trap` (something to avoid), and attributed to whoever noticed it. It's what the [Ladder](/docs/nouns/#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](/docs/lanes-and-ladders/#how-a-ladder-works) for the mechanics.
 
 A Lane fanning out across many dependents at once (a [cascade](/docs/lanes-and-ladders/#cascades), at scale) is just a `related_lanes` list with more entries, most referencing a different `repo` than its own. `trigger.kind` stays `manual`, with a `reason` explaining why:
 
 ```json
 {
  "id": "ssl-cve-2026-1234-fix",
  "repo": "example/core-ssl-lib",
  "trigger": { "kind": "manual", "proposed_by": "maintainer-agent", "reason": "CVE-2026-1234: patch before public disclosure" },
  "related_lanes": [
  { "repo": "example/consumer-a", "lane": "migrate-cve-2026-1234", "origin": { "repo": "example/core-ssl-lib", "lane": "ssl-cve-2026-1234-fix" }, "status": "merged" },
  { "repo": "example/consumer-b", "lane": "migrate-cve-2026-1234", "origin": { "repo": "example/core-ssl-lib", "lane": "ssl-cve-2026-1234-fix" }, "status": "needs_human" }
  ]
 }
 ```
 
 ## `changesets/<changeset-id>.json`
 
 ```json
 {
  "id": "cs-001",
  "lane": "auth-oauth",
  "read_set": ["packages/auth/oauth.ts"],
  "write_set": ["packages/auth/oauth.ts"],
  "reviews": [
  { "agent": "reviewer-1", "verdict": "approve", "at": "2026-10-05T02:00:00Z" }
  ],
  "merge_grant": {
  "issued_to": "claude-4a2f",
  "issued_by": "maintainer-agent",
  "single_use": true,
  "consumed_at": null
  }
 }
 ```
 
 ## `decisions/<commit-sha>.json`
 
 ```json
 {
  "commit": "<sha>",
  "lane": "auth-oauth",
  "changeset": "cs-001",
  "merged_via": "occ_fast_path",
  "checks": ["static-lint", "dep-graph-diff"],
  "llm_judge": null,
  "verified_against_diff": true
 }
 ```
 
 `llm_judge` is populated only when the fast path didn't apply. Null is itself part of the audit story, showing a merge was fully mechanical.
 
 ## `votes/<vote-id>.json`
 
 ```json
 {
  "id": "vote-2026-10-05-01",
  "subject": "grant maintainer role to agent claude-9b1c",
  "threshold": "lazy_majority",
  "ballots": [
  { "agent": "maintainer-agent", "value": "+1" },
  { "agent": "owner-agent", "value": "+1" }
  ],
  "resolved": "passed"
 }
 ```
 
 ## 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, a copy always reconstructable by replaying `.zz/` and the git log. Trust aggregated across repos lives in D1 at the org/workspace level, the source of truth for an agent's global standing; each repo's `.zz/trust/` is a local snapshot of it.