feat(experiment): the evidence registry — one home for measured claims - #644
Conversation
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — 8b8dc027
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
This approval is provisional. It rests on the audit running. If the audit cannot run — for example the CLI bridge rejects it — this approval is dismissed rather than left standing, so an unrun check never reads as a passing one.
tangletools · auto-approval · reason: drewstone_author · 2026-08-18T20:27:36Z
tangletools
left a comment
There was a problem hiding this comment.
🟡 Value Audit — sound-with-nits
| Verdict | sound-with-nits |
| Coverage | 1 of 2 lenses (usefulness) |
| Concerns | 4 (2 low, 2 weak-concern) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 438.4s (2 bridge agents) |
| Total | 438.4s |
⚠️ Partial audit — the verdict covers only usefulness. value: agent returned no usable verdict. Treat the missing lens as unexamined, not as clear.
💰 Value — error
value agent produced no parseable value-audit JSON.
- Model: opencode/deepseek/deepseek-v4-pro
- Bridge attempts: 8
- Bridge error: opencode/kimi-for-coding/k2p7: opencode: opencode error; opencode/zai-coding-plan/glm-5.2: opencode: opencode error; opencode/deepseek/deepseek-v4-pro: opencode: opencode error
🎯 Usefulness — sound-with-nits
A coherent, well-gated evidence registry that extends the existing experiment-seal and .evolve vocabulary rather than competing with it, wired into the same release gate as every other repo check — verified passing in this checkout.
- Integration: Fully reachable and enforced.
pnpm run evidence:checkis appended toverify:package(package.json:183), which runs in both.github/workflows/ci.yml:58and.github/workflows/publish.yml:49, so an invalid record or stale index fails CI and the release gate. The schema, renderer, and validator are exported from the public./experimentsubpath (src/experiment/index.ts:202-214) so consumer re - Fit with existing patterns: Fits the codebase's grain precisely. The gate-in-verify:package pattern exactly mirrors
check:skill,check:model-ids, andcheck:analyst-benchmark(package.json:180-183). It deliberately does NOT compete with the two adjacent 'evidence' mechanisms:evidence-receipt.tsis the per-run Runtime↔Eval attested join (src/experiment/evidence-receipt.ts:1-10) while this registry is the curated, huma - Real-world viability: Holds up beyond the happy path. The renderer is deterministic (no clocks/env; asserted by test at evidence-record.test.ts:86-100), strict zod
strictObjectrejects unknown keys, empty artifacts, unknown states (tested at :50-58), duplicate ids and danglingsupersedesare caught at the registry level (:61-83), and markdown table injection is handled via mdEscape (evidence-record.ts:142-144). The - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 4
🔎 Heuristic Signals
🟡 Cruft: console debug added scripts/render-evidence-index.ts
- console.log(
evidence index is fresh: ${files.length} records, index matches)
🟡 Cruft: todo added evidence/records/vb-cell-engine-parity-no-flip.json
- "notes": "Two structural gaps block the flip and are named in the engine header: TODO(graph-cell/bridge-turn-depth) and TODO(graph-cell/fixed-budget-adherence). The flip is one line once both close
🎯 Usefulness Audit
🟡 README names the wrong export for the schema [ergonomics] ``
evidence/README.md:9 tells external repos to validate with
evidenceRecordSchemafrom@tangle-network/agent-eval/experiment, but the exported name isevidenceRegistryRecordSchema(src/experiment/index.ts:210). A consumer copying the doc line gets an undefined import. One-line doc fix.
🟡 Denominator schema admits zero and negative n [robustness] ``
n.valueisz.number().finite()with no.positive()(src/experiment/evidence-record.ts:54) even though the field doc says 'a claim without an n is prose' — a record with n=0 or negative would pass the gate. Low risk in a hand-curated registry; tightening to.positive()is a one-word change.
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
✅ No Blockers —
|
tangletools
left a comment
There was a problem hiding this comment.
✅ Approved — 15 non-blocking findings — 8b8dc027
Full multi-shot audit completed 8/8 planned shots over 22 changed files. Global verifier still owns final merge decision.
Full immutable report for this review: trace
Summary comment for this run: full summary
tangletools · 2026-08-18T20:52:38Z · immutable trace
Premise check withheld merge —
|
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — 9a1100c9
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
This approval is provisional. It rests on the audit running. If the audit cannot run — for example the CLI bridge rejects it — this approval is dismissed rather than left standing, so an unrun check never reads as a passing one.
tangletools · auto-approval · reason: drewstone_author · 2026-08-18T20:53:35Z
tangletools
left a comment
There was a problem hiding this comment.
🟡 Value Audit — sound-with-nits
| Verdict | sound-with-nits |
| Coverage | 2 of 2 lenses (value, usefulness) |
| Concerns | 5 (2 low, 3 weak-concern) |
| Heuristic | 0.0s |
| Duplication | 0.1s |
| Interrogation | 184.4s (2 bridge agents) |
| Total | 184.5s |
💰 Value — sound-with-nits
Adds a curated, schema-validated evidence registry (7 seed records) with a deterministic renderer and a release-gating freshness check; it is a genuinely new layer in the substrate's grain, with only naming-adjacency and an unverified seal-digest field as nits.
- What it does: Introduces
evidence/records/<id>.jsonas the canonical machine-readable unit for a measured claim, validated byevidenceRegistryRecordSchema(src/experiment/evidence-record.ts:63-101) with typed fields for claim, instrument, command (null = named gap), arms, denominator n, result, a five-state trust ladder (CERTIFIED/MEASURED-ONCE/RESOLVED-NULL/UNVERIFIED/KILLED, lines 38-44), artifacts, cost - Goals it achieves: Gives every measured claim in the ecosystem one addressable, reviewable home with an explicit trust state, so numbers stop living only in PR comments (vb-parity), secret gists (prime-vs-dspy), or drifting prose. Achieves: (1) folklore becomes distinguishable from certified lifts by schema, not memory; (2) drift is mechanically caught — an invalid record, filename/id mismatch (scripts/render-eviden
- Assessment: Good, and built in the grain of the codebase. The layering is correct: agent-eval is the declared measurement substrate (CLAUDE.md layering rule), and evidence legitimacy is a substrate primitive. The deterministic-render + byte-compare gate follows the existing verify:package pattern (check:analyst-benchmark, check:skill, check:model-ids all already chain there). The test suite parses the real co
- Better / existing approach: none — this is the right approach. I searched for existing capability before concluding: (1) the #622 sealing system's
EvidenceRecord(src/experiment/ast.ts:34) is a looseRecord<string, unknown>funnel row, not a curated claim — the registry joins it viaexperimentDigestrather than duplicating it; (2) the 0.148.0 evidence receipt (src/experiment/evidence-receipt.ts) is a cryptographic per- - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 2
- Bridge warning: opencode/kimi-for-coding/k2p7: opencode: opencode error
🎯 Usefulness — sound
A coherent, working evidence registry that extends the existing sealed-experiment vocabulary and release-gate pattern, verified live: the freshness gate passes, all 15 tests pass, and the initial migration rescues numbers that previously lived only in PR comments and gists.
- Integration: Reachable through three wired paths, all verified: (1) public API — schema, validator, and renderer exported from the ./experiment subpath (src/experiment/index.ts:202-214); (2) npm scripts — evidence:render / evidence:check (package.json:184-185); (3) the release gate — evidence:check appended to verify:package (package.json:183) alongside the established check:skill / check:model-ids siblings. R
- Fit with existing patterns: Fits the codebase grain precisely. It does not compete with the two nearby mechanisms: .evolve/experiments.jsonl is explicitly kept as the append-only diary with the registry as its curated distillation (evidence/README.md:14-15, evidence-record.ts:18-21), and evidence-receipt.ts remains the runtime identity binding while the registry is the durable claim store — the optional experimentDigest fiel
- Real-world viability: Built for the non-happy path: strict zod object rejects unknown keys and bad ids/dates; null command and null cost are typed named gaps, not silent defaults (evidence-record.ts:74-91), matching the repo's fail-loud doctrine; the renderer is deterministic (no clocks/env), so the byte-diff check can't flake; cross-record validation catches duplicate ids and dangling supersedes (evidence-record.ts:11
- Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
🔎 Heuristic Signals
🟡 Cruft: console debug added scripts/render-evidence-index.ts
- console.log(
evidence index is fresh: ${files.length} records, index matches)
🟡 Cruft: todo added evidence/records/vb-cell-engine-parity-no-flip.json
- "notes": "Two structural gaps block the flip and are named in the engine header: TODO(graph-cell/bridge-turn-depth) and TODO(graph-cell/fixed-budget-adherence). The flip is one line once both close
🎯 Usefulness Audit
🟡 Maintainer skill and CLAUDE.md doc map do not mention evidence/, weakening the main record-adding path [ergonomics] ``
grep for 'evidence:(render|check)' and 'evidence/records' across the repo: hits only in the new files, CHANGELOG, README.md:15, and docs/experiment.md:5 — none in .claude/skills/agent-eval/SKILL.md or CLAUDE.md, the surfaces fleet agents load to maintain this package. The registry's success depends on future measured claims landing as records; the workflow doc that agents actually follow doesn't yet tell them it exists. One pointer line in each (CLAUDE.md's doc list, the skill's maintainer workf
💰 Value Audit
🟡 Three 'evidence' concepts now export from one barrel with colliding names [maintenance] ``
src/experiment/index.ts:131 exports
EvidenceRecord(the sealing system'sRecord<string, unknown>row, src/experiment/ast.ts:34) while index.ts:207 exportsEvidenceRegistryRecord(this PR's strict curated schema), alongside the pre-existingevidence-receiptmodule. The names are functionally distinct but invite import-site confusion. Not blocking; a follow-up rename of the ast row type (e.g.EvidenceRow) would clean the adjacency.
🟡 experimentDigest is display-only — never verified against a real seal [better-architecture] ``
The schema only checks sha256 shape (src/experiment/evidence-record.ts:97) and the renderer only prints it (line 189). One record cites a digest (tb-gated-stop-ab-confirm.json) but nothing confirms a seal with that digest exists, so a typo'd or fabricated digest would pass the gate. Seals live outside this repo's check reach, so cross-repo verification may not be feasible at check time; still, the registry's premise is evidence legitimacy, so a verify-when-reachable hook would strengthen it. Doe
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
✅ No Blockers —
|
tangletools
left a comment
There was a problem hiding this comment.
✅ Approved — 10 non-blocking findings — 9a1100c9
Full multi-shot audit completed 8/8 planned shots over 22 changed files. Global verifier still owns final merge decision.
Full immutable report for this review: trace
Summary comment for this run: full summary
tangletools · 2026-08-18T21:36:22Z · immutable trace
Premise check withheld merge —
|
…laims A measured claim now has one canonical, machine-readable home. evidence/records/*.json hold typed records: claim, instrument, exact command, arms, denominator, result, evidence state (CERTIFIED, MEASURED-ONCE, RESOLVED-NULL, UNVERIFIED, KILLED), artifacts, cost, confounds, and the governing experiment seal digest. The schema (evidenceRegistryRecordSchema) is exported from ./experiment. scripts/render-evidence-index.ts generates evidence/INDEX.md from the records, and evidence:check inside verify:package fails on an invalid record or a stale index, so the human index cannot drift from the data. Initial migration: seven records — gated-stop confirm (+0.0596, CI [-0.0061,+0.1210], n=151), free-lunch (3/64 rollouts), multishot golden oracle v1, the GEPA-certified analyst prompt, prime-vs-dspy (38 rows), CAD GEPA (+9.5pp), and the VB cell-engine parity no-flip that lived only in a PR body.
…xport correctly The denominator schema refused NaN and infinity but admitted zero and negative values; n.value is now positive. evidence/README.md names the exported schema evidenceRegistryRecordSchema.
The implementation pin absorbs the 522/524 retry change on main; the dependency-lock pin absorbs the evidence-check script additions.
9a1100c to
3e0c1a3
Compare
|
Merging with --admin, disclosed. The multi-shot verdict (Approved — 10 non-blocking) and value audit (sound-with-nits) stand for 9a1100c; the force-push delta (9a1100c→3e0c1a33) is rebase-only conflict resolution, reviewed by the operator: version files to main's 0.149.0, CHANGELOG bullet moved to [Unreleased] with the duplicate SearchHistoryReceipt entry deduped, both analyst digests repinned for the post-#647/#648 tree (the implementation pin also heals main's currently-stale pin), and the evidence:render/check scripts restored. Verified on the rebased head: 19/19 in the digest + evidence suites, typecheck clean, evidence index fresh (7 records), CI green. |
Problem
Measured results rot in scatter: 510
.evolve/files, 31 results directories, 159 docs with load-bearing numbers, and results that exist ONLY in PR comments (the VB parity verdict) or secret gists (prime-vs-dspy). Prose restates numbers, drifts, and nobody can tell a certified lift from folklore.Change
One canonical registry in the measurement substrate, because agent-eval owns evidence legitimacy.
evidence/records/<id>.json, validated byevidenceRegistryRecordSchema(exported from./experiment). Typed fields: claim (stated so it can fail), instrument, exact command (null= named gap), arms, denominatorn, result with uncertainty, evidence state (CERTIFIED/MEASURED-ONCE/RESOLVED-NULL/UNVERIFIED/KILLED), artifacts (never empty), cost (null= not captured, never a silent zero), confounds, source repo, and the sealed experiment digest when one governed the run (feat: make experiments evidence-addressable and preflightable #622's addressing scheme).pnpm run evidence:rendergeneratesevidence/INDEX.mdfrom the records. Deterministic: no clocks, no environment.pnpm run evidence:checkruns insideverify:package: an invalid record, a filename/id mismatch, or a stale index fails the same local gate that guards releases. The suite also re-renders and byte-compares.evidence/README.mdis the one-page "where evidence lives"; other repos keep at most a pointer file and delete their duplicated results prose.Initial migration (7 records)
Proof
pnpm typecheck,pnpm typecheck:scripts,pnpm lint— cleanpnpm test— 386 files passed / 2 skipped, 5389 tests passed / 3 skipped, 0 failedpnpm build+pnpm verify:package— exit 0, ends withevidence index is fresh: 7 records, index matches