Skip to content

feat(arbitration): ECH-05 fidelity evidence and belief/epi/sound verdict levels - #430

Merged
hyperpolymath merged 3 commits into
mainfrom
claude/new-session-th4e9w
Oct 14, 2026
Merged

hyperpolymath merged 3 commits into
mainfrom
claude/new-session-th4e9w

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Implements ECH-05 (drafted in issues/echidna-05-fidelity-evidence.md; not yet filed). When backends agree, that doesn't show they proved the same statement. So the arbiter now takes per-attempt fidelity evidence and gives each fused verdict a level: belief < epi < sound. A synonym collision (statements aligned only by name) can no longer reach sound, however many backends agree. The numeric fusion is unchanged; a regression fixture taken before the change shows this.

The ECH-05 plan asks for three stacked PRs. This session can push to one branch only, so the three parts are three separate commits here, and each can be reviewed on its own:

Commit Part
6b6f54a A: FidelityEvidence on ProverAttempt; level / retracted / warranted_term on ArbitratedVerdict; the policy; regression fixture
48e8034 B: src/abi/EchidnaABI/Arbitration.idr, plus an accept/reject fixture falsifier wired into idris2-abi-ci.yml
33a3dc7 C: tests/arbitration_fidelity_test.rs, ROADMAP stage 6 acceptance, backend-pair table, issues/README.md row and issue draft

Changes

A: input and output types (src/rust/verification/result_arbiter.rs, src/rust/exchange/mod.rs)

  • FidelityEvidence = KernelTranslation { format, checked_by, term_hash } | DeclaredCorrespondence { consequence_tests, failures } | None. The default is None, and ProverAttempt::new keeps its signature.
  • EpistemicLevel { Belief, Epi, Sound } (ordered); fidelity_level() is the policy:
    • belief if the verdict needs review, rests on a retracted backend, fused nothing, or any attempt has None evidence.
    • sound only if every fused attempt is a KernelTranslation to the same non-empty term_hash.
    • epi if every fused attempt is a kernel translation or a correspondence with ≥ 1 consequence test and 0 failures, and the kernel hashes agree.
    • belief otherwise, e.g. two kernel translations to different terms.
  • ResultArbiter::retract(prover) marks a backend unsound. Any verdict that fuses one of its attempts drops to belief, and retracted lists the backend.
  • exchange::ExchangeFormat (one variant per bridge) and exchange::term_hash: a BLAKE3 hash of the rendered term, separated by format, with no canonicalisation. The failure mode is a missed sound, never a false one.
  • tests/fixtures/arbitration_regression.json was generated at 29b18ea before the change (16 scenarios × 4 policies). tests/arbitration_regression_test.rs replays it field by field (floats to 1e-12) and checks every verdict is at belief.

B: Idris2 ABI (EchidnaABI.Arbitration)

  • Level fused is a closed sum indexed by the fused evidence. Sound h requires an All (KernelAt h) fused proof, and each KernelAt holds the hash-equality proof. So a collision, a correspondence or missing evidence in fused cannot be typed Sound, whatever produced the value (collisionNotSound, correspondenceNotSound, noEvidenceNotSound).
  • The classifier level comes with blockedIsBelief, noEvidenceIsBelief, failedCorrespondenceIsBelief, untestedCorrespondenceIsBelief, emptyFusedIsBelief, blockingNeverRaises, and evaluation controls (alignedPairIsSound, collisionPairIsBelief, mixedPairIsEpi). It is total and needs only DecEq on the hash type.
  • epistemic-types 6a68de3 and residual-evidence-types 97244f5 are cited by pin in the module header, not imported. The cited lemma names were checked at those commits.
  • Falsifier: tests/abi/accept/ArbitrationAligned.idr must type-check, and tests/abi/reject/ArbitrationCollision.idr (identical apart from one hash) must fail with Mismatch between.
    • scripts/abi-fixtures.sh judges by output, because idris2 --check exits 0 on a missing import.
    • It checks each fixture in a fresh temp directory, because a stale build/ cache can silently skip the check (this bit me locally).
    • It runs in idris2-abi-ci.yml, whose path filter now includes tests/abi/ and the script, and as just abi-fixtures.

C: acceptance tests and docs

  • Synonym collision (Lean ℕ vs set.mm NN), under the portfolio, Bayesian and Dempster–Shafer policies. Four cases all stay at belief while verified = true / CrossChecked: lexical only; kernel translations to different terms; a correspondence with a failed consequence test; an untested correspondence.
  • MiniF2F mathd_numbertheory_3 positive control: the Lean and Isabelle statements were checked against openai/miniF2F@4e433ff and translate to one term, which reaches sound. Negative control: the same pair with an off-by-one translation does not.
  • Retraction: retracting Lean lowers the two verdicts that rested on it. The Isabelle + HOL Light verdict stays sound, and the numbers don't change.
  • The exchange-layer terms are hand-written translation targets. These tests check the arbiter given certificates, not that certificates can be produced (that is stage 6).
  • Docs:
    • ROADMAP stage 6 acceptance (§2) and a "Cross-prover semantics" row (§3).
    • Gap-analysis table "Backend pairs that can share a term": every row is DESIGNED in ECHIDNA, and external routes are named but not run.
    • Short notes in the comparison doc and Guides.
    • issues/README.md gains the ECH-05 row and lists its four labels missing on this repo.
    • CHANGELOG [Unreleased] entry.

RSR Quality Checklist

Required

  • Tests pass: cargo test --lib (1208 passed, 3 ignored) plus both new integration tests; full --workspace run is left to CI (see Testing)
  • Code is formatted (cargo fmt --all -- --check)
  • Linter is clean (cargo clippy --locked --workspace --exclude echidna-rest --all-targets -- -D warnings; see Testing for the exclusion)
  • No banned language patterns (Rust, Idris2, Bash only)
  • No unsafe blocks
  • No banned functions (the ABI dangerous-pattern grep over src/abi and tests/abi is empty)
  • SPDX license headers present on all new/modified source files
  • No secrets, credentials, or .env files included

As Applicable

  • Repo deed (status) / (maturity) updated: not touched; nothing ships to dispatch yet (every dispatched verdict is belief)
  • Repo deed (ecosystem) updated: n/a
  • Repo deed (meta) and/or docs/decisions/ updated: policy decisions are listed below for the owner
  • docs/ROADMAP.adoc updated (stage 6 acceptance + §3 row)
  • Documentation updated for user-facing changes (Guides, gap analysis, comparison doc)
  • TOPOLOGY.md updated: n/a
  • CHANGELOG updated
  • New dependencies reviewed: none added (blake3 already a dependency)
  • ABI changes validated: new module has no foreign declarations; ffi/zig untouched

Testing

$ cargo test --lib -- result_arbiter term_hash          → 23 passed
$ cargo test --test arbitration_regression_test        → 1 passed, 1 ignored (the generator)
$ cargo test --test arbitration_fidelity_test          → 4 passed
$ cargo test --lib                                     → 1208 passed; 0 failed; 3 ignored
$ cd src/abi && idris2 --build echidnaabi.ipkg         → 20/20 modules, exit 0 (Idris2 0.8.0)
$ bash scripts/abi-fixtures.sh
ok   accept: tests/abi/accept/ArbitrationAligned.idr
ok   reject: tests/abi/reject/ArbitrationCollision.idr
    Mismatch between: True and False.

Negative controls (applied, observed, then reverted):

  • A 1e-6 relative perturbation of the Bayesian conflict metric fails the regression test at unanimous_proven_three / bayesian(0.5): verdict.conflict.
  • Removing the term-hash equality check in fidelity_level fails synonym_collision_cannot_reach_sound and minif2f_mistranslated_pair_does_not_reach_sound.
  • Making the reject fixture aligned makes the falsifier fail ("type-checked"); breaking its import makes it fail ("non-type reason").

Not run locally:

  • echidna-rest builds utoipa-swagger-ui, whose build script downloads Swagger UI from GitHub, and the sandbox proxy blocks that. It is the only crate excluded from local clippy; CI builds the full workspace.
  • The full cargo test --workspace --all-targets was not run here; that is left to CI.

Decisions for the owner

  1. Stacked PRs: one branch with three commits, because of this session's single-branch constraint. Happy to split into A → B → C stacked PRs.
  2. Policy choices beyond the spec's text:
    • A correspondence needs ≥ 1 consequence test (otherwise zero failures is vacuous).
    • Mismatched kernel hashes among fused attempts give belief, not epi.
    • A verdict with needs_review (which covers inconsistent premises) is belief.
    • An empty term_hash is not a certificate.
  3. Stage 6 "pair X": proposed HOL4 ↔ HOL Light via OpenTheory first, then Lean 4 ↔ Rocq via Dedukti.
  4. Labels area:arbitration, area:exchange, epistemic-types, residual-evidence-types don't exist on this repo yet. They need creating before ECH-05 is filed.
  5. Open questions from the issue are unchanged: whether Dempster–Shafer stays limited to same-encoding provers, and who runs consequence testing.

🤖 Generated with Claude Code

https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3


Generated by Claude Code

…ratedVerdict

ECH-05 PR A. Agreement between backends says nothing about whether they
proved the same statement, so each ProverAttempt now carries
FidelityEvidence (KernelTranslation { format, checked_by, term_hash } |
DeclaredCorrespondence { consequence_tests, failures } | None) and
ArbitratedVerdict gains level (belief < epi < sound), retracted and
warranted_term.

Policy (fidelity_level): belief if the verdict needs review, rests on a
retracted backend, nothing was fused, or any attempt has no evidence;
sound only if every fused attempt is a kernel translation to the same
term_hash; epi if every fused attempt is a kernel translation or a
correspondence with >= 1 consequence test and 0 failures and the kernel
hashes agree; belief otherwise. ResultArbiter::retract marks a backend
unsound. exchange::ExchangeFormat names the six bridges and
exchange::term_hash gives a format-separated BLAKE3 term identity.

Numeric fusion is unchanged: tests/fixtures/arbitration_regression.json
was generated at 29b18ea (16 scenarios x 4 policies) and is replayed
against the new code, floats to 1e-12, with every verdict at belief.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3
…s hash equality

ECH-05 PR B. `Level fused` is a closed sum (Belief | Epi | Sound) indexed
by the evidence of the fused attempts; `Sound h` takes, for every fused
attempt, a KernelAt h proof whose constructor carries the hash equality.
A synonym collision, a declared correspondence or a missing certificate
in the fused list therefore cannot be typed Sound, whatever produced the
value (collisionNotSound, correspondenceNotSound, noEvidenceNotSound).

`level` is the classifier, parametric in the hash type (DecEq only), with
blockedIsBelief, noEvidenceIsBelief, failed/untestedCorrespondenceIsBelief,
emptyFusedIsBelief, blockingNeverRaises, and evaluation controls
(alignedPairIsSound, collisionPairIsBelief, mixedPairIsEpi). Total,
no believe-me / postulate / admit. Epistemic-types (6a68de3) and
residual-evidence-types (97244f5) are cited by pin, not consumed.

Falsifier: tests/abi/accept/ArbitrationAligned.idr must type-check and
tests/abi/reject/ArbitrationCollision.idr (the same file with one hash
changed) must fail with a unification error; scripts/abi-fixtures.sh
judges by output because `idris2 --check` exits 0 on a missing import.
Wired into idris2-abi-ci.yml and `just abi-fixtures`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3
…ce and pair table

ECH-05 PR C. tests/arbitration_fidelity_test.rs, under the portfolio,
Bayesian and Dempster-Shafer policies:
- synonym collision (Lean ℕ vs set.mm NN, aligned lexically): lexical
  only, kernel translations to different terms, a correspondence with a
  failed consequence test, and an untested correspondence all stay at
  belief while the numbers still say cross-checked;
- MiniF2F mathd_numbertheory_3 (Lean and Isabelle statements checked
  against openai/miniF2F@4e433ff) with kernel translations to one term
  reaches sound; the same pair with an off-by-one translation does not;
- retracting Lean lowers the two verdicts that rested on it, leaves the
  Isabelle + HOL Light verdict sound, and leaves the numbers unchanged.
The exchange-layer terms are hand-written translation targets: the tests
check the arbiter given certificates, not that certificates can be made.

Docs: ROADMAP stage 6 acceptance is now "a KernelTranslation certificate
is producible for a named backend pair" with a §3 row; the gap analysis
names which backend pairs can share a term (all DESIGNED in ECHIDNA);
the comparison doc and Guides describe the level; issues/README.md gains
ECH-05 (not filed) and the labels it is missing; the issue body is
drafted in issues/echidna-05-fidelity-evidence.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3
@coderabbitai

coderabbitai Bot commented Oct 14, 2026

Copy link
Copy Markdown

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 776e4918-aa98-4fb3-870e-5eee34949f97
📥 Commits

Reviewing files that changed from the base of the PR and between 29b18ea and 33a3dc7.

📒 Files selected for processing: 20
  • .github/workflows/idris2-abi-ci.yml
  • CHANGELOG.adoc
  • Justfile
  • docs/ROADMAP.adoc
  • docs/design/ADVANCED_TYPING_GAP_ANALYSIS.adoc
  • docs/design/TYPING_CAPABILITIES_COMPARISON.adoc
  • docs/wikis/Guides.md
  • issues/README.md
  • issues/echidna-05-fidelity-evidence.md
  • scripts/abi-fixtures.sh
  • src/abi/EchidnaABI/Arbitration.idr
  • src/abi/echidnaabi.ipkg
  • src/rust/exchange/mod.rs
  • src/rust/verification/mod.rs
  • src/rust/verification/result_arbiter.rs
  • tests/abi/accept/ArbitrationAligned.idr
  • tests/abi/reject/ArbitrationCollision.idr
  • tests/arbitration_fidelity_test.rs
  • tests/arbitration_regression_test.rs
  • tests/fixtures/arbitration_regression.json
 ________________________________________
< Ship it? Sure-after we unship the bug. >
 ----------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath
hyperpolymath marked this pull request as ready for review October 14, 2026 01:33
@hyperpolymath
hyperpolymath merged commit 6883126 into main Oct 14, 2026
71 of 75 checks passed
@hyperpolymath
hyperpolymath deleted the claude/new-session-th4e9w branch October 14, 2026 01:34

Copy link
Copy Markdown
Owner Author

CI: Cargo Audit / Dependency audit is red, and the cause is not in this PR.

  • What fails: cargo audit reports five advisories against quinn-proto 0.11.15: RUSTSEC-2026-0338, -0339, -0340, -0341 and -0342 (two rated 7.5 high). It is pulled in only through reqwest → quinn 0.11.9, an optional HTTP/3 path. cargo audit scans the whole lockfile, so it is flagged anyway.
  • Why it isn't this PR's: this PR doesn't touch Cargo.toml or Cargo.lock, and the PR's lockfile is byte-identical to main's at 29b18ea. Cargo Audit last passed on main in its scheduled run on 2026-10-12, so the advisories reached the RustSec database after that. Running cargo audit -f on main's lockfile locally reproduces the same five IDs. I didn't re-run the job: it is deterministic, and the local reproduction is the stronger check.
  • Fix: no open PR addresses it. The proposed patch is lockfile-only and semver-compatible (quinn 0.11.9 requires quinn-proto ^0.11.12):
    cargo update -p quinn-proto   # 0.11.15 -> 0.11.19 (pulls rand 0.10 / getrandom 0.4 / rand_pcg into quinn-proto's subtree)
    cargo audit on the bumped lockfile reports no vulnerabilities. I've left it out of this PR to keep ECH-05's scope; it can land on its own, or ride here if the owner prefers.

Generated by Claude Code

Copy link
Copy Markdown
Owner Author

CI: governance / Validate Hypatia Baseline is red, and it is already red on main.

  • What fails: Gate failed: 6 unfiltered finding(s) at or above 'info'. Five are SD022 "doc references src/…/ but no such directory exists", in issues/echidnabot-01-adaptive-ci-portfolio-scheduler.md (×3: src/api/, src/scheduler/, src/modes/), .github/issues/echidnabot-01-adaptive-ci-portfolio-scheduler.md (src/api/) and docs/handover/PARADISEO-ROADMAP-PROMPT.adoc (src/dispatcher/). The sixth is download_then_run_shell at echidna-playground/ci-templates/mirror.yml:131 (curl -sSf https://radicle.xyz/install | sh).

  • Why it isn't this PR's: none of these files is in this PR's diff. main's Governance run at 29b18ea (run 38003834638) fails with the same six findings. They arrived with Merge arena/16d27c7e-echidna: ParadisEO roadmap and issue specs #426 and Arena/9aef7602 echidna #427.

  • Fix: no open PR addresses it. Proposed patch:

    1. The five SD022 hits: the paths name echidnabot's tree, not echidna's (the drafts and the handover describe the other repository), so they are false positives. Add baseline entries in the existing .hypatia-baseline.json form, one per (file, type) pair:
      { "severity": "medium", "rule_module": "structural_drift", "type": "SD022",
        "file": "issues/echidnabot-01-adaptive-ci-portfolio-scheduler.md",
        "note": "cross-repo draft: src/ paths are hyperpolymath/echidnabot's tree",
        "tracking_issue": "hyperpolymath/echidna#314" }
      plus the same for .github/issues/echidnabot-01-adaptive-ci-portfolio-scheduler.md and docs/handover/PARADISEO-ROADMAP-PROMPT.adoc.
    2. mirror.yml:131: this is a real pipe-to-shell, so it wants a real fix: pin the Radicle installer version and verify a checksum before running it. A baseline acknowledgement is the alternative, and that one is the owner's call.

    I've left both out of this PR to keep ECH-05's scope.


Generated by Claude Code

hyperpolymath added a commit that referenced this pull request Oct 14, 2026
…2) [stack 1/3] (#432)

## Summary

Stack 1 of 3: follow-ups to #430 / ECH-05 (#431). This PR fixes the
`cargo audit` failure, which is red on `main` and on every PR (both the
`rust-ci / Cargo audit` and `Cargo Audit / Dependency audit` jobs).

The RustSec database added five `quinn-proto` advisories after `main`'s
last green audit on 2026-10-12: RUSTSEC-2026-0338, -0339, -0340, -0341
and -0342, two of them rated 7.5 high. `quinn-proto` is reached only
through `reqwest` → `quinn 0.11.9`, an optional HTTP/3 path that the
default build doesn't compile, but the audit scans the whole lockfile.

## Changes

- `Cargo.lock` only: `quinn-proto` 0.11.15 → 0.11.19 via `cargo update
-p quinn-proto`. `quinn` requires `^0.11.12`, so the bump is
semver-compatible. It also pulls `rand 0.10`, `getrandom 0.4` and
`rand_pcg` into `quinn-proto`'s subtree only.

## RSR Quality Checklist

### Required

- [x] Tests pass (no code change; `cargo check --locked --workspace
--all-targets` passes)
- [x] Code is formatted (n/a, lockfile only)
- [x] Linter is clean (n/a)
- [x] No banned language patterns
- [x] No `unsafe` blocks without `// SAFETY:` comments
- [x] No banned functions
- [x] SPDX license headers present on all new/modified source files
(n/a)
- [x] No secrets, credentials, or `.env` files included

### As Applicable

- [x] New dependencies reviewed for license compatibility: `rand_pcg` is
MIT/Apache-2.0, from the rust-random project like the existing `rand`
- [ ] Others: n/a

## Testing

```
$ cargo audit                     → no vulnerabilities (490 crate dependencies), exit 0
  (before: "error: 5 vulnerabilities found!" on main's lockfile)
$ cargo check --locked --workspace --exclude echidna-rest --all-targets → ok
$ cargo metadata --locked (full workspace, incl. echidna-rest) → ok
```

`echidna-rest` was excluded from the local `check` only because its
build script downloads Swagger UI, which this sandbox blocks. CI builds
it.

## Stack

1. **This PR**: lockfile bump
2. Hypatia baseline fix: delete the dead `ci-templates/mirror.yml`,
baseline the echidnabot-path SD022 hits, `.hypatia-baseline.json` → JCS
3. ECH-05 follow-ups: regression fixture → JCS, stage 6 first target,
issues row #431, norms in `.claude/CLAUDE.md`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3

---
_Generated by [Claude
Code](https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3)_

Co-authored-by: Claude <noreply@anthropic.com>
hyperpolymath pushed a commit that referenced this pull request Oct 14, 2026
… filed as #431

- tests/fixtures/arbitration_regression.json is now JCS (RFC 8785)
  I-JSON plus a final LF, the estate format standard. Re-serialised, not
  regenerated: all 327 numbers and the whole document compare equal to
  the 29b18ea fixture (only spellings like 0.0 -> 0 change). The
  regenerator writes JCS, and fixture_is_jcs_canonical fails on a
  pretty-printed fixture (negative control run).
- ROADMAP stage 6 and the gap-analysis pair table: HOL4 <-> HOL Light
  through OpenTheory is the first target (owner decision 2026-10-14);
  Lean 4 <-> Rocq through Dedukti is the next candidate.
- issues/README.md: ECH-05 is #431, closed as completed by #430, the
  arbiter-typing slice of #429 (open). Its four labels now exist on the
  repo (created by filing) but not yet in the estate label source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3
hyperpolymath added a commit that referenced this pull request Oct 14, 2026
…w, owner norms [stack 3/3] (#435)

## Summary

Stack 3 of 3. #432 and #433 have merged, so this PR now targets `main`.
It holds the ECH-05 follow-ups the owner decided after #430 merged, plus
the owner's norms written down where agent sessions read them.

**History rebuilt, 2026-10-14 (owner decision: force-with-lease).** The
branch used to carry the pre-squash copies of #432 and #433.
Rebase-merge replayed them onto `main`, which already had the squash
commits, and conflicted on `.hypatia-baseline.json`. The branch is now
this PR's own four commits on current `main` (5583c70), so it
rebase-merges cleanly. Its tree is byte-identical to the old head
(75288e7) merged with `main`.

## Changes

- **`tests/fixtures/arbitration_regression.json` → JCS** (RFC 8785)
I-JSON plus a final LF.
- It is re-serialised, not regenerated. All 327 numbers, and the whole
document, compare equal to the fixture recorded at `29b18ea`; only
spellings change (`0.0` → `0`). This is the source of the large deletion
count.
  - The regenerator now writes JCS.
- A new test, `fixture_is_jcs_canonical`, keeps it canonical. A
pretty-printed fixture fails it; I ran that negative control.
- **ROADMAP stage 6 and the gap-analysis pair table:** HOL4 ↔ HOL Light
through OpenTheory is the first target (owner decision, 2026-10-14).
Lean 4 ↔ Rocq through Dedukti is the next candidate.
- **`issues/README.md`:** ECH-05 is #431, closed as completed by #430,
and is the arbiter-typing slice of #429, which stays open.
- **`.claude/CLAUDE.md`, owner norms:**
  - decisions are asked with the selector tool;
  - work lands as stacked PRs;
- findings are fixed at source. The exemption ratchet admits ledger
growth only with a `Ratchet-exception:` line naming the ledger.
- The format standards point at their normative source in standards:
`YAML-POLICY.adoc` (KYAML, `.kyaml`; D280/D307/D293), the workflow gate
in standards#1025, `JSON-POLICY.adoc` (I-JSON as JCS; D306) and ADR-008
(UUID v8; D305/D305b/D320).
- The UUID rule is scoped until the `ids.rs` migration lands. `ids.rs`
still mints v7 records and v8 content ids without a domain. This is the
wording the owner accepted on proof-burrower#111.

## RSR Quality Checklist

### Required

- [x] Tests pass (`cargo test --test arbitration_regression_test`: 2
passed, 1 ignored)
- [x] Code is formatted (`cargo fmt --all -- --check`)
- [x] Linter is clean
- [x] No banned language patterns
- [x] No `unsafe` blocks
- [x] No banned functions
- [x] SPDX license headers present on all new/modified source files
- [x] No secrets, credentials, or `.env` files included

### As Applicable

- [x] `docs/ROADMAP.adoc` updated (stage 6 first target)
- [x] Documentation updated
- [ ] Others: n/a

## Testing

```
$ cargo test --test arbitration_regression_test
test numeric_fusion_unchanged_and_level_is_belief ... ok
test fixture_is_jcs_canonical ... ok
negative control: pretty-printed fixture → fixture_is_jcs_canonical FAILED ("fixture must be JCS (RFC 8785) canonical")
jq: 327 numbers equal, documents equal (29b18ea fixture vs JCS fixture)
```

## Stack

1. #432: `quinn-proto` lockfile bump (merged)
2. #433: Hypatia findings fixed at source, baseline → JCS (merged)
3. **This PR**: ECH-05 follow-ups and owner norms
4. #436: workflow checkers read KYAML (S4), stacked on this PR

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants