Skip to content

witness network usability + cross-repo contract drift (plan)#397

Merged
bordumb merged 8 commits into
mainfrom
plan/witness-usability-contracts
Jul 20, 2026
Merged

witness network usability + cross-repo contract drift (plan)#397
bordumb merged 8 commits into
mainfrom
plan/witness-usability-contracts

Conversation

@bordumb

@bordumb bordumb commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Implements the tractable core of the approved plan (~/.claude/plans/fluffy-drifting-kahn.md) from the 2026-07-20 red-team findings. Two workstreams; every commit is agent-signed and CI-green.

Workstream A — make the witness network usable

A1 — registry sync (fixes RT-2). witness-node sync-registry --from <url> --registry <dir> force-fetches the refs/auths/* namespace the anchor role resolves party keys from. Root cause of RT-2: a plain git clone brings only refs/heads/*, so auths-w1's registry had no party KELs and every anchor 422'd. Reuses registry_ready; HTTPS via git2's vendored transport (added to auths-witness-node, allow-listed in deny.toml as a storage/adapter-layer wrapper).

A3 — deploy paths corrected. All four paths (Compose, README bare-metal, Helm, Terraform) told operators to git clone the registry — the same RT-2 bug, shipped as docs. Repointed at sync-registry. Also fixed flags that never matched the binary:

  • Helm + Terraform passed --anchor-store (no such flag) and omitted --data-dir/--registry/--witness-name; corrected, with a registry-sync init container (Helm) / pre-serve sync (Terraform).
  • Terraform ran the anchor store on --tmpfs /data — an amnesiac witness that co-signs a fork after any restart. Moved to a durable host dir.
  • Compose mounted the registry :ro, blocking in-place sync; made it writable (serve only reads).

Workstream B — kill cross-repo verdict drift (fixes RT-1)

Verdict strings are defined once per emitting enum's code(), but downstream repos hardcopy them — so 0.1.13's consistent → self-consistent / dropped-call → chain-break renames silently broke the @auths-dev/mcp release gate (caught only at release).

B1 — xtask gen-contracts. Scans each of the 6 verdict enums' inherent code() for the kebab literals it emits and writes them, namespaced by emitter, to schemas/contracts-v1.json. Comment-aware (a // "self-consistent" note above an arm can't leak a phantom code); unit tests assert the extraction against source.

B2 — CI drift gate. The schemas job regenerates the manifest and git diff --exit-codes it, so any rename becomes a visible, must-commit change (same idiom the JSON schemas use).

B3 — SDK distribution. sync-conformance.mjs copies the manifest into @auths-dev/sdk's conformance/verdicts.json, so every JS/TS consumer can pin verdicts to the exact SDK version it installs.

Deferred (tracked, not in this PR)

  • A1 re-sync watcher — the one-shot sync + documented re-run covers the common case; a serve --sync-from background loop is a follow-up.
  • A2 aggregated authoritative registry — needs the infra decision on which registry is canonical.
  • A3 live redeploy of auths-w1 — a prod infra change; gated on A2's registry URL.
  • A5 I-TRUST-3 (witness set anchored in KEL) — a security-sensitive verifier change across CLI + gateway + market; deserves its own reviewed PR.
  • B4 consumer rewiring — activates once an SDK release ships verdicts.json (this PR merges first).

🤖 Generated with Claude Code

The anchor role resolves party keys from the tree at refs/auths/registry,
but a plain `git clone` fetches only refs/heads/* — so an operator who
cloned the registry still 422s every submission (this is the RT-2 root
cause: auths-w1's /data/registry has no refs/auths/registry).

Add `witness-node sync-registry --from <url> --registry <dir>`: init the
dir, force-fetch +refs/auths/*:refs/auths/*, and confirm the result is
resolvable (registry_ready) before returning. HTTPS in-process via git2's
own transport (the workspace git2 is transportless; opt in here as
packages/auths-node does). Mirrors the SDK's fetch_registry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
@bordumb
bordumb force-pushed the plan/witness-usability-contracts branch from 3315275 to e518f07 Compare July 20, 2026 20:11
@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
e518f07d ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp

Result: ✅ 1/1 commits verified

Verdict strings are defined once, in a code() method per emitting enum, but
downstream consumers hardcode copies — so a rename silently breaks them (a
consistent → self-consistent rename broke the @auths-dev/mcp release gate).

Add `xtask gen-contracts`: scan each enum's inherent code() for the kebab
literals it emits and write them, namespaced by emitter, to
schemas/contracts-v1.json. Gate it in CI with the same generate-then-
`git diff --exit-code` idiom the JSON schemas use, so a rename becomes a
visible, must-commit change. Unit tests assert the extraction against source
(they run in CI where I can compile).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
12f92549 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
e518f07d ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp

Result: ✅ 2/2 commits verified

Extend sync-conformance to copy schemas/contracts-v1.json into the package's
conformance/ dir (alongside statuses.json), so a JS/TS consumer can pin every
verdict string to the exact contract the installed SDK version was built from.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
621ba9b5 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
12f92549 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
e518f07d ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp

Result: ✅ 3/3 commits verified

The witness reads party keys from refs/auths/*, which it now fetches with
git2 (A1). auths-witness-node is a server/adapter binary — exactly the
storage/adapter layer the git2 ban already permits — so add it to the
wrappers allowlist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
a2202636 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
621ba9b5 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
12f92549 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
e518f07d ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp

Result: ✅ 4/4 commits verified

claude-release and others added 2 commits July 20, 2026 21:36
The audit code() has a `// "self-consistent" …` note above the arm; the
scanner pulled the literal out of the comment too, emitting a phantom
duplicate. Skip comment-only lines (no code, no real brace scope), and add a
per-family uniqueness assertion so a future leak fails the unit test, not just
the CI diff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
The RT-2 root cause: every deploy path told operators to populate the party
registry with `git clone`, which brings only refs/heads/* — so the refs/auths/*
KELs the anchor role resolves keys from never arrived, and every submission
422'd. Point all four paths (Compose, README bare-metal, Helm, Terraform) at
the new `witness-node sync-registry` command, run before/alongside serve.

Also fix stale/broken serve flags that never matched the binary:
- Helm + Terraform passed `--anchor-store` (no such flag) and omitted
  --data-dir/--registry/--witness-name; correct them and add a registry
  init container (Helm) / pre-serve sync (Terraform).
- Terraform ran the anchor store on `--tmpfs /data` — an amnesiac witness that
  co-signs a fork after any restart. Move it to a durable host dir.
- Compose mounted the registry :ro, which blocks the in-place sync; make it
  writable (serve only reads it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
22c1fbbc ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
67e2d9d6 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
a2202636 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
621ba9b5 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
12f92549 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
e518f07d ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp

Result: ✅ 6/6 commits verified

The registry mount is now read-write so the in-place sync can populate it; the
compose-default test located the line by the literal `:/registry:ro`, so
dropping :ro made it fail to find the line. Match on ${WITNESS_REGISTRY}
instead and assert the /registry mount target explicitly — the test's real
subject (a `:-` default, never `:?`) is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
f414bbba ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
22c1fbbc ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
67e2d9d6 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
a2202636 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
621ba9b5 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
12f92549 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
e518f07d ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp

Result: ✅ 7/7 commits verified

test_unsigned_commit_advice_is_kel_native has been red since #396: it asserts
`auths verify` gives KEL-native advice for an UNSIGNED commit, but make_commit
runs a bare `git commit` — and the init_identity fixture (`auths init --profile
developer`) configures global commit signing plus a commit-trailer hook, so the
commit is signed and verify reports it verified instead of advising.

Give make_commit a `sign` flag; with sign=False it ignores global/system git
config (neither commit.gpgsign nor the hooks path apply) and passes
--no-gpg-sign, producing a genuinely bare commit. Pre-existing failure,
unrelated to this branch's changes — folded in so CI goes green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
ceb60ec0 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
f414bbba ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
22c1fbbc ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
67e2d9d6 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
a2202636 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
621ba9b5 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
12f92549 ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
e518f07d ✅ Verified Signed by did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp

Result: ✅ 8/8 commits verified

@bordumb
bordumb merged commit 190a50d into main Jul 20, 2026
24 checks passed
@bordumb
bordumb deleted the plan/witness-usability-contracts branch July 20, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant