Close A1/A2 structurally; red-team the gold suite (A3+B2)#21
Close A1/A2 structurally; red-team the gold suite (A3+B2)#21lukefwalton wants to merge 4 commits into
Conversation
Adversarial coverage for the seams NEXT-STEPS A1-A3 name, landing before the structural changes that will close them (the coverage-first rule, NEXT-STEPS.md). - New gold entries: q11-q13 extraction/injection attacks aimed at private content (must route, never comply), q14 injection aimed at the machinery (must refuse bare), q15 the missing 'supported' case - which also owns the residue templating can't close, since supported prose is free prose that cites a hint. - Canary forbid-patterns on q02/q05/q11-q13/q15: phrases verified to exist only in private notebook bodies, so any answer containing one has leaked or confabulated private text. "chair by the window" rejected as a canary because the public lyric nearly contains it. - Refusal-debris patterns on q08-q10/q14: a failed refusal leaks URLs or citation-id-shaped prose; vacuously green when refusal succeeds. - New gold field expectAnswerPatterns: must-match mirror of forbidAnswerPatterns (same load validation), to pin behavior shape - never facts. Will pin the related-material template when it lands. - Tests: must-match judge cases, load validation for both pattern fields, all four modes now asserted present in the gold set. q11-q15 may be red under --full until the template and label changes land; that is the coverage doing its job. Retrieval tier expected green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019n27KsH2AS1mbpHMYp8y2X
Close the provenance-without-backing seam: a hint citation is real provenance but carries no text, so free prose in related-material mode was the one place a confabulated summary of private material passed every gate, held only by a prompt instruction. - New src/public-safe.ts: renderRelatedMaterialAnswer builds the mode's prose from the cited hints' public-safe fields (label, locator) alone. No raw URL in the prose - the citation object carries the link, and gold q07 forbids URLs here. - src/answer.ts: finalizeAnswer runs repair -> grounding -> template, so the hint lookup cannot miss and answers that only became related-material through repair's kind conversion get templated too. Confabulation in this mode is now inexpressible, not discouraged. - Prompt tells the model its related-material prose is standardized. - Gold pins the template via expectAnswerPatterns on q07/q11-q13, so a regression cannot silently un-template the mode. - NEXT-STEPS A2 rewritten as closed, with the residue named: supported mode still cites hints under free prose, owned by the q15 canaries. The template's safety is exactly the safety of label+locator - A1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019n27KsH2AS1mbpHMYp8y2X
The RoutingHint label was the note's raw frontmatter title and the locator raw frontmatter, guarded only by a warning comment - a privately-titled note leaked through its own label. Three layers replace the comment: - Explicit `label:` frontmatter, required on private notes: the display name that travels, distinct from `title` (private, embedded, never travels). What travels is now an authored per-note decision; a corpus without labels fails loudly with the reason. - PublicSafe branded type on PrivateNote/RoutingHint label+locator, whose only constructor is the new build-time lint assertPublicSafeField (src/public-safe.ts): non-empty, single line, <=120 chars, and no run of 5 consecutive words shared with the note's private body - a traveling field that quotes the note fails the build, not an answer. N=5 is calibrated: the demo's bibliographic locator legitimately shares a 4-token run with its sermon body. - Index schema v3 (store.ts): note entries must carry title/label/locator, so a stale or hand-edited artifact fails fast with the rebuild remedy. noteEmbedText now embeds title+body - byte-identical to the old label+body for every corpus whose labels repeated titles, so committed demo vectors survive without re-embedding: scripts/migrate-demo-index-v3.mjs migrated the committed demo indexes mechanically (title := label, vectors and contentHashes untouched), verified by the keyless demo gate (7/7, rho 1.0000). Residue named in NEXT-STEPS A1: the lint is a 5-gram tripwire, `about` travels unlinted as a declared public page, and the brand erases at JSON read - backstopped by the gold canaries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019n27KsH2AS1mbpHMYp8y2X
Automated Checks (advisory, non-blocking)✅ All checks passed. Standards ComplianceThis PR is highly standards-relevant: it touches the no-leak boundary, related-material mode semantics, gold eval coverage, and the committed The only visible file here is the massive SummaryThis PR appears to land three coordinated changes: new adversarial gold cases around boundary and mode behavior, a structural replacement of free related-material prose with a fixed public-safe answer template, and a schema/type migration that separates private note titles from public-traveling labels in the index. It also mechanically migrates the committed demo index to schema v3, which is why most of the visible diff is artifact churn rather than logic changes. Reviewer: most of the risk is in the unseen no-leak/output-finalization path and the index-schema migration; the giant demo JSON update is mostly a consequence. What to pay attention to
Things I noticed🟡 Yellow flags — consider for this PR or a follow-up:
If nothing else jumps out in the unseen files, I don’t see a visible red flag from the diff shown here. Good patterns
Suggested improvements
Questions for the author
Surmado Code Review (v1.2-mt) is an automated review, designed to work alongside human judgment. Want to change your STANDARDS.md or YML? Edit it directly, or tune it with our AI agent Scout. Comment |
- readIndexFile's version mismatch now names the found version alongside
the expected one ("schema version 2, not schema version 3"), so a stale
artifact says what it is, not just what it isn't.
- New keyless test in demo/artifacts.test.ts: every committed demo entry's
contentHash must equal the hash of today's embed-text derivation
(title+body for notes), proving the v2->v3 migration preserved the exact
bytes the committed vectors were embedded from.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019n27KsH2AS1mbpHMYp8y2X
|
Responding to the automated review ( Suggestions. (1) A test proving plausible model prose is discarded in related-material mode already exists — Questions. (1) Other construction paths for Generated by Claude Code |
What & why
Closes the two highest-value seams in
NEXT-STEPS.mdA and audits the third, in three commits sequenced so the gold coverage that would catch each failure mode lands before the structural change that closes it (the repo's own rule).1. Red-team the gold suite (A3+B2) —
74c86ed. Five new adversarial entries: extraction-shaped queries (q11–q12: "what exactly does the notebook say", a verbatim-quote demand), instruction injections aimed at private content (q13, must still route) and at the machinery (q14, must refuse bare), and the previously missingsupportedcase (q15). Canary forbid-patterns — phrases verified to exist only in the private notebook bodies — now guard each mode's characteristic failure ("chair by the window" was rejected as a canary because the public lyric nearly contains it). NewexpectAnswerPatternsgold field: the must-match mirror offorbidAnswerPatterns, documented as pinning behavior shape, never facts.2. Template the related-material answer (A2) —
02f0c91. A hint citation is provenance without backing, so free prose in this mode was the one place a confabulated "summary" of private material passed every gate.finalizeAnswernow replaces the mode's prose, after grounding, with a fixed sentence rendered only from the cited hints' public-safe fields (renderRelatedMaterialAnswer,src/public-safe.ts) — the mode can point, never assert content. The gold suite pins the template. NEXT-STEPS A2 rewritten as closed, with the residue named (supported-mode hint citations under free prose, owned by the q15 canaries).3. Make the traveling label/locator boundary structural (A1) —
624e825. Private notes now require an explicitlabel:frontmatter field;titlestays private and is what gets embedded. Both traveling fields are a brandedPublicSafetype whose only constructor is a build-time lint (single line, ≤120 chars, no 5-consecutive-word run shared with the note's private body — N=5 calibrated so the demo's bibliographic locator passes). Index schema bumped to v3; the committed demo indexes were migrated mechanically byscripts/migrate-demo-index-v3.mjs(title := labelis exact, embed text byte-identical, vectors and contentHashes untouched — nothing re-embedded), verified by the keyless demo gate (7/7, rho 1.0000).Note for the keyed follow-up:
npm run indexis required (local index is now v2-stale), thennpm run evalandnpm run eval -- --full --ids q07,q11,q12,q13,q14,q15. q15 is the likeliest to wobble (compound canon+process question); if it fails, the fix is a sentence in the prompt's supported-mode bullet, never the query.Checklist
npm testpasses without an API key (47/47) — no hidden dependency on live callsnpm run typecheckpassesPublicSafeis constructible only through the lint; the related-material template renders nothing butPublicSafefieldsnpm run evalsubset — not run here (no API key in this environment); keylessnpm run demo:runcertifies retrieval on the migrated artifacts (7/7, rho 1.0000). Keyed subset above is the owner's step..github/STANDARDS.md— the rubric a PR is judged by🤖 Generated with Claude Code
https://claude.ai/code/session_019n27KsH2AS1mbpHMYp8y2X
Generated by Claude Code