Audit — ADR-009 Authorship Binding

Step 1 of the 5-step chain. This task is doc-only: a single ADR file plus the four chain artefacts. Source code is not changed.

Trigger

A whole-system code review surfaced Finding #2: the ζ Decision Trail’s SHA-256 chain proves what was recorded in what order but does not cryptographically bind who authored each record. The ADR documents the gap and recommends one of three paths.

Surface inventory (read-only)

Source-of-truth files (the gap lives here)

File Lines Role
src/domains/trail/schema.ts 188 THOUGHT_TYPES, ZERO_HASH, ThoughtRecordSchema, canonicalize, computeHash (lines 170–188 — the 6-field subset). The docstring at lines 153–159 explicitly excludes agent_id from the hash input.
src/domains/trail/repository.ts 401 createThoughtRecord (lines 205–267) — stores agent_id in column 4 of the INSERT (line 247) but never feeds it into computeHash (lines 235–242).
src/domains/trail/verifier.ts 203 verifyChain (lines 119–153) — recomputes computeHash(record) and compares to stored record.hash. Has no concept of agent_id.
src/db/migrations/003_thought_records.sql 43 Defines thought_records table. agent_id is column 4 (line 33), declared TEXT NOT NULL. There is no signature column, no per-agent key material table.

ADR artefacts to create / touch

File Status Action
docs/architecture/decisions/ADR-009-authorship-binding.md absent Create as Status: Proposed, Date: 2026-05-06.
docs/architecture/decisions/index.md exists, lists 6 ADRs Append one row linking ADR-009.
docs/architecture/decisions/README.md exists, lists ADR-001/002/003 in its index table Do not touch — it’s already stale (lists 3 of 6 ADRs); reconciling it is out of scope.
docs/audits/adr-009-authorship-binding-audit.md absent This file.
docs/contracts/adr-009-authorship-binding-contract.md absent Step 2.
docs/packets/adr-009-authorship-binding-packet.md absent Step 3.
docs/verification/adr-009-authorship-binding-verification.md absent Step 5.

Cross-references the ADR will cite

Reference Location Why
Legitimacy promise CLAUDE.md §10 “execution of work + management of intelligence + legitimacy of action” — frames why the gap is structural.
Executable-meaning contract docs/architecture/decisions/ADR-006-executable-meaning.md The colibri_code field’s invariants. ADR-009 references it because authorship binding affects what “complete” means for ζ.
Multi-model defer docs/architecture/decisions/ADR-005-multi-model-defer.md Context for “library-only stub vs. full feature” precedent — Option A’s migration uses the same staging logic.
Hash-input docstring src/domains/trail/schema.ts:153-159 The deliberate exclusion of agent_id.
computeHash signature src/domains/trail/schema.ts:170-188 The 6-field subset.
INSERT call src/domains/trail/repository.ts:243-253 Where agent_id is written to the row.
Hash-recomputation in verifier src/domains/trail/verifier.ts:131-132 Where the integrity check runs.
λ Reputation phase note implicit in CLAUDE.md §10 Phase 2 will read agent_id as truth — Option C’s documented risk.

Existing ADR format conventions (observed)

From the 6 existing ADRs:

  • ADR-005 / ADR-006 use the cleanest modern format: frontmatter (title, description, tags, type, round, status, parent, updated, nav_order) + H1 heading + status block + horizontal rules between sections.
  • Sections in canonical order: Context → Decision → Consequences → Implementation → Alternatives Considered → Verification → References.
  • Some ADRs reorder Alternatives before Consequences (ADR-002, ADR-003) — both are accepted. This task’s prompt names the order “Decision → Alternatives Considered → Consequences → Implementation → Verification”, which I will follow.
  • ADR-002 and ADR-003 are still PROPOSED; ADR-005 and ADR-006 are ACCEPTED. ADR-009 must ship as PROPOSED per the task’s explicit instruction.
  • Frontmatter nav_order increments by 10 (10/20/30/40/50/60). Next free slot for ADR-009 is 90.

Database state to consider

Two databases hold ζ chains today:

  • data/colibri.db — Phase 0 production target. Created at runtime; not committed. Contains real Phase 0 chains from R75 Wave G onward.
  • data/ams.db — donor-era task store, retained per CLAUDE.md §1 through R78. The thought_records table schema is the same migration. Contains chains older than colibri.db.

The ADR’s Consequences §chain-validity table must address both.

Out of scope

Per the task prompt:

  • No source code changes. Forbidden in this round.
  • No migrations. Forbidden in this round.
  • No test updates. Forbidden in this round.
  • No edits to existing ADRs to mark superseded. Forbidden in this round (deferred to a follow-up if Option A or B is accepted).
  • The README.md ADR index table that already lists only ADR-001/002/003 is pre-existing drift. Reconciling it is its own hygiene task.

Test gate posture

Because this round produces zero source changes:

  • npm run build — must pass (no TS source change).
  • npm run lint — must pass (no TS / no JS changed; markdown only).
  • npm test — must pass (no test files touched).

The verification doc records the green-on-all-three result.

Risk assessment

  • Risk: ADR mis-recommends. The legitimacy axis is small enough today that the wrong recommendation can be reversed in a follow-up ADR before λ Reputation lands. Mitigation: lay out all three honestly, recommend only when the cross-axis evidence is decisive.
  • Risk: ADR undersells the gap. Finding #2 is real; an ADR that softens it would be worse than no ADR. Mitigation: the Context section names the practical attack (DB-level write, audit-sink replacement) explicitly.
  • Risk: word-count blow-up. ADR-005 is ~750 words pre-postscript, ~1.4k with the Wave I postscript. ADR-006 is ~1.2k. ADR-009 should target the ADR-006 size band (1k–1.5k words excluding tables).

Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.