security-remediation: gateway/SDK/witness-network hardening + productization#396
Merged
Conversation
Auths Commit Verification
Result: ❌ 0/6 commits verified How to fixCommit 1. Install auths macOS: 2. One-time setup (creates your identity and configures Git) auths init3. Sign this branch and push auths sign origin/main..HEAD
git push --force-with-leaseFor CI to verify the signer, commit an identity bundle: auths id export-bundle --alias main --output .auths/ci-bundle.json --max-age-secs 31536000 |
…quality
Wire the three unenforced bounds and make each audit verdict state what it proved.
- 1.1 wrap --ttl now threaded into `id agent add --expires-in` (chain.rs, proxy.rs,
main.rs, replay.rs) so TTL is anchored as an expiry seal the verifier already
enforces (AgentExpired). Previously parsed + printed in the banner, enforced nowhere.
- 1.2 verify-spend cross-checks the signed `Auths-Settle-Ref`; new counterparty-mismatch
verdict + a verified `counterparty` field on the report (audit.rs, evidence types + schema).
- 1.3 truncated/rolled-back log no longer audits bare `consistent` — `self-consistent`
with an explicit head-pin/completeness caveat.
- 1.4 portable `--json` verdict object + MCP error `data` payload for live refusals.
- 1.5 MISSING/REORDERED/DUPLICATE distinguished; positional record index.
- 1.6 receipt display fields not vouched-for unless signed.
- 1.7 fs.read read-family tool mapping (gate.rs).
- 1.8 budget boundary rule (`>` vs `>=`) surfaced in --budget help.
- 1.9 revocation KEL re-resolve (close the session cache window).
- 1.10 deterministic/announced spend-log path.
- 1.11 metered-0c / empty log no longer reads as a clean audit.
- 1.12 malformed-log voice: corrupt vs tampered distinguished.
- 1.13 wrap keychain-alias idempotency.
- 1.14 doubled verdict-word fix (main.rs).
- 1.15 KEEP+LOCK regression tests: amount tamper caught, exact-token scope incl.
Cyrillic/prefix/suffix/`../` near-misses, signature binding, TOCTOU race.
Tests: new tests/e2e/test_mcp_gate_bounds.py (+ helpers/mcp_downstream.py);
extended test_mcp_spend_log_audit.py and test_receipts_threat_model.py.
Spec: product-findings/remediation/EPIC-1.md. Not locally built — GitHub CI is the gate.
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
…ness, version honesty
Make the embedded witness anchor a real gate and report the assurance tier, so a
relying party never launders a signed claim into a witnessed fact.
- Embedded anchor is now a GATE (auths-evidence): a bad / foreign-witness /
threshold-unmet / duplicated / removed-when-witness-claimed anchor fails the WHOLE
document with a named check; an AnchorSummary (tier, witnesses, threshold, failed
check) rides every verdict. verify_embedded_anchor no longer returns Ok on absence.
- Freshness is a first-class verdict field against an injected clock: a future as_of
is rejected; fresh|unknown|stale; the strict policy denies offline-Unknown for a
witness-tier claim. anchor:null / live / stale are legibly distinguishable.
- Head binding: head_bound is true only when a verified anchor cosigns the head; the
monotonicity rule is documented as load-bearing only at the witness tier.
- napi verdict shape (packages/auths-node) surfaces anchor / freshness / headBound and
the AnchorInvalid -> {status, failedCheck} arm; cumulativeCents documented as a signed
claim, witnessed only at a non-stale witness anchor (market display gate is separate).
version() now reads the real package version (version.workspace = true).
- Call sites updated for the new signatures: packages/auths-node and packages/auths-python
evidence bindings (clock + opts + new verdict fields).
- Tests: anchor-forgery + freshness + head-binding battery
(auths-evidence/tests/cases/attestation.rs; auths-anchor test-support builders in
finalize.rs/lib.rs), a freshness 24h-boundary lock, and napi verdict-shape + version
contract tests.
Release remains a user step: bump workspace version 0.1.12 -> 0.1.13, rebuild the committed
.node, and push v0.1.13 so publish-node.yml ships it. A registry-backed anchor e2e is
deferred (needs a live witness lab, unbuildable under the CI-is-the-gate policy).
Spec: product-findings/remediation/EPIC-2.md. Not locally built — GitHub CI is the gate.
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
Make the witness node refuse to serve unsynced, give operators a working conformance +
onboarding path, and give a duplicity victim something portable to run.
- Registry-mount readiness (witness-node): build_state probes the registry with a sentinel
and refuses to bind on an unsynced/absent registry instead of 422-ing every submission;
PartyResolveError split into RegistryUnavailable (503, operator) vs IdentityNotInRegistry
(422, stranger), classified structurally — no libgit2/registry path leak. The anchor
router is lifted into anchor_role.rs so it is testable via oneshot.
- deploy/witness compose defaults WITNESS_REGISTRY (${..:-./registry}) so `docker compose
up` no longer dies at paste time; README documents the registry-sync prerequisite.
- .gitignore re-includes .cargo/config.toml and the alias ships, so `cargo xtask` works
from a fresh clone (the alias file was previously gitignored).
- `auths anchor verify <proof>` wraps DuplicityProof::verify (exit 0 proven / non-zero on
tamper) — the portable, offline duplicity-proof check a victim or regulator can run.
- Equivocation is durably recorded (<data_dir>/duplicity/<seed>.json) and re-served at
GET /v1/duplicity/{seed}; auths-monitor pushes AUTHS_ALERT_WEBHOOK on duplicity and
withholding (tracing unchanged when unset) — the proof no longer goes only to the cheater.
- Exact replay (AlreadyAnchored -> 200 no-op) distinguished from a true rollback
(IndexRollback -> 422); the seed param is shape-validated to one named 400 (no "Odd number
of digits"); conformance echoes the certified node's witness_did and creates --emit dirs.
- release.yml builds + stages the witness-node binary (previously shipped in no artifact).
- Tests: HTTP-level anchor.rs (readiness 503-not-422, 409 duplicity, rollback, seed
validation), DuplicityProof::verify round-trip + tamper, e2e test_anchor_duplicity.py
(offline CLI verify + tamper, withholding webhook, readiness refusal).
Note: on this machine .cargo/config.toml is force-added past a global gitignore; the repo
.gitignore fix works on CI/fresh clones. A live-node submission e2e is deferred (no shipped
anchor-submit tool) — guarantees are locked at the protocol/service/HTTP level instead.
Spec: product-findings/remediation/EPIC-3.md. Not locally built — GitHub CI is the gate.
Auths-Scope: sign_commit
Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd
Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp
Auths-Anchor-Seq: 13
Fix headless identity first-run and make the error corpus lookup-able. - Headless init no longer hangs: keychain backend selection is TTY/interactivity-aware (auths-core keychain + init/gather) — a non-interactive run auto-selects the file backend (or fails fast naming the backend env var) instead of blocking forever on a Touch-ID prompt. - One state-root resolver: init/sign and verify/doctor now resolve the same registry root (factories/mod, verify_commit, unified_verify, doctor), so a freshly-signed commit verifies instead of "Device KEL could not be resolved" against a different root. - CI passphrase generator (ci/types) satisfies its own policy (the encryption validator) — the documented CI path no longer fails on its own generated passphrase. - Errors point somewhere real: the renderer + error_lookup route to the working offline `auths error show <CODE>` (and accept a bare `E4203`) instead of the 404 docs URL. - Error-corpus honesty: retired pre-KEL SSH/allowed-signers advice rewritten to the KEL-native flow (commit_error); a missing key alias reports "no such alias", not "keychain unavailable" (signing service/workflow); the untyped "Device KEL could not be resolved" and the bare AUTHS-E0031 are registered/typed; the gateway error namespace aligned (mcp-server). - gen_error_docs parses rustfmt-wrapped multi-line suggestion arms so every code carries its next step; a new xtask check_error_codes lint fails CI if any emitted AUTHS-E code is unregistered or lacks a suggestion. - Tests: identity-lifecycle + git-signing e2e (headless-init-no-hang, sign->verify passes, isolated via AUTHS_REPO + file keychain); the CI passphrase satisfies the validator; every registered code round-trips through `auths error show`. Spec: product-findings/remediation/EPIC-4.md. Not locally built — GitHub CI is the gate. Auths-Scope: sign_commit Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp Auths-Anchor-Seq: 13
Kill the FINDING-000 class at the source: a new `cargo xtask check-paste-integrity --path <dir>` scans, in one binary runnable against any of the three repos, every fenced shell block (bash/sh/console/shell/zsh in .md/.mdx/.mdoc) and every copyable site string (`copy="..."`, <Prompt>/<BashLines> in .ts/.tsx, HTML-entity-decoded first) and fails CI on: an <...> angle placeholder in a copyable command, a bare $VAR with no matching export/assignment in the block, or a leading `$ ` prompt glyph. A block opts out with a `paste-integrity: illustrative` marker. Mirrors the existing check_*.rs style (walkdir + regex_lite, per-violation lines, bail on any hit); wired into xtask main.rs as `check-paste-integrity`. Unit battery locks the placeholder- flagged and paste-clean-passes cases plus the buyer-integration-pane positive control. Spec: product-findings/remediation/EPIC-6.md. Not locally built — GitHub CI is the gate. Auths-Scope: sign_commit Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp Auths-Anchor-Seq: 13
A new `cargo xtask check-error-docs-published` guards drift between the error registry and the generated docs/errors/ pages: every registered AUTHS-E code must have a docs/errors/AUTHS-E<code>.md page, and every page must map to a registered code (no orphans). Enumerates codes via the same registry path check_error_codes uses; distinct from that lint (registration + suggestion coverage). Self-contained to the auths repo — the docs.auths.dev publish of the corpus is a separate step. Wired into xtask main.rs; unit battery covers missing-page, orphan-page, and complete-set-passes. Passes against the current tree (373 codes / 373 pages). Note: this is only the auths-side lint for epic 7. The auths-docs content rewrites (publish-receipts artifact, anchor-page version banners, error-page publish, freshness window, witness key/URL, etc.) are deferred — see product-findings/remediation/EPIC-7.md, to be applied after the witness-network docs reorganization lands. Spec: product-findings/remediation/EPIC-7.md. Not locally built — GitHub CI is the gate. Auths-Scope: sign_commit Auths-Id: did:keri:EB5cPHY0t-ejNC_rUzPS1dclTvd6kG-R9mQzjozCuGgd Auths-Device: did:keri:EO1cBsYoV5izKvdIL6TstN5TOQl1hYN3WnhtAOh1lwAp Auths-Anchor-Seq: 13
- gate ShellBlock::copy with #[cfg(test)] (used only by tests; dead in a plain build under -D warnings, breaking the schema + tree-sitter jobs) - collapse nested ifs into let-chains (clippy::collapsible_if) in check_anchor_discipline, check_constant_time, gen_error_docs - add the Acceptance::AlreadyAnchored arm to the accept.rs duplicity test (non-exhaustive match E0004 after the idempotent-replay variant landed) 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
force-pushed
the
security-remediation
branch
from
July 20, 2026 15:54
83b90ee to
c7f1889
Compare
Auths Commit Verification
Result: ✅ 7/7 commits verified |
The AST-walking lint checkers nest tree-sitter node guards deliberately; collapsing them into let-chains reads worse. Added to the existing tooling-lint allow block, alongside print_stdout/unwrap_used/etc. Clears the remaining collapsible_if failures across check_curve_agnostic, check_rfc6979, check_verify_path_completeness, gen_docs, gen_error_docs. 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
Auths Commit Verification
Result: ✅ 8/8 commits verified |
…lockfile
- auths-receipts api/error.rs: map the new EvidenceError::AnchorInvalid
{code, detail} to a 422 (E0004 non-exhaustive match; the variant landed
with embedded-anchor verification)
- registry.rs error suggestions: reference real flags — pairing relay is
`auths device pair --registry <url>` (no --mode); replace the
non-existent `auths verify --trust` with `auths trust pin` guidance
(command-drift lint)
- packages/auths-python/Cargo.lock: add auths-anchor + the auths-evidence
→ auths-anchor edge the pre-commit hook regenerates
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
Auths Commit Verification
Result: ✅ 9/9 commits verified |
The command-drift fix belonged in the AuthsErrorInfo::suggestion() impls, not the generated registry.rs — editing only the generated file left the error docs out of date (gen-error-docs --check). Fix the source so regeneration is a no-op AND won't reintroduce the bad flags: - auths-core PairingError (QrCodeFailed, MdnsError): relay via `auths device pair --registry <url>` - auths-sdk auth TofuRequiresInteraction: `auths trust pin` guidance 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
Auths Commit Verification
Result: ✅ 10/10 commits verified |
- cargo fmt wrapped the longer Some("...") suggestion lines (fmt --check --all)
- docs/errors/AUTHS-E3202/E3205/E5554.md: sync the generated per-code docs
to the new source suggestions (gen-error-docs --check)
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
Auths Commit Verification
Result: ✅ 11/11 commits verified |
bordumb
pushed a commit
that referenced
this pull request
Jul 20, 2026
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
bordumb
added a commit
that referenced
this pull request
Jul 20, 2026
* witness-node: sync-registry subcommand (fetch refs/auths/*)
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
* xtask: generate the verdict contract manifest + drift gate
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
* sdk(node): ship the verdict manifest in conformance/verdicts.json
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
* deny: allow git2 in auths-witness-node (registry sync)
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
* xtask: gen-contracts skips comment lines in code() bodies
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
* deploy(witness): sync the registry with refs/auths/*, not git clone
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
* test(witness): match compose registry mount by var, not :ro
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
* test(e2e): make the unsigned-commit test commit genuinely unsigned
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
---------
Co-authored-by: claude-release <claude@auths.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security-remediation epics 1–7: gateway enforcement & spend-log audit quality, published verifier SDK (anchors, freshness, version honesty), witness-network productization, identity/CLI first-run + error corpus, paste-integrity CI lint, error-docs completeness lint.
🤖 Generated with Claude Code