Development record
2026-08-21 — Bug-hunt round 6, branch bughunt-b/round-6. Baseline (make preflight
decisiondcn-2608210000000004
2026-08-21 — Bug-hunt round 6, branch bughunt-b/round-6. Baseline (make preflight
- gofmt -l .) green before any change and on the final tree. Five parallel Opus 5 hunters swept the four dimensions; each candidate was adversarially refuted by an independent Opus 5 subagent before capture. Findings: 8 substantive + 2 confirmed doc/CLI, 5 refuted, 1 (I2) reverted on implementation. Fixed and resolved this round (each behaviour-changing code/script fix carries a test watched fail before the change, the lifeboat probe size-TOCTOU excepted — that race is closed by construction and its boundary test guards the cap, not the race): iss-2608211849467013 the guard tokenizer did not know shell redirection operators, so a glued redirection (git push --force>/dev/null) mutated the flag token and the blocker missed — a silent allow — and a leading redirection degraded a Tier-1 block to a warn; the tokenizer now drops a redirection and its target. iss-2608211849463840 the record/docs lint reporting walk read cfg.Roots with a raw os.ReadFile and no containment while the sibling citation collector guards the same field, so a cloned repo's committed lint config could read/lint/follow a file outside the tree (reproduced: escaping root, symlinked leaf, /dev/zero OOM) — routed through containedRepoPath/resolvedInsideRoot/containedRealPath/ReadGuarded, and the sibling glossary_dir walk in loadForbiddenSynonyms (the same cloned-repo-config read path, caught by both pre-merge reviews) was swept through the same stack; the remaining config-derived record reads in the lint package are tracked as a follow-up (iss-2608211914592726). iss-2608211849461061 frontmatter.Fields requires --- on line 0, so a comment-led record (13 glossary term files) slipped the no_git_metadata blocker; the lint-local frontmatterFields now slices past the comment, preserving absolute line numbers. iss-2608211849466878 citation DaysBetween took each date's local calendar day and restamped UTC, making staleness and the release-gate overdue blocker timezone-dependent; both ends now convert to UTC first. iss-2608211849468791 the attribution gate's trailer/None presence checks are line-end-anchored over a class excluding CR, so a CRLF web-UI pull-request body false-red a correct trailer on the required check; check_text now normalises CRLF before every rule, with CRLF corpus cases. iss-2608211850070541 identity init faults exit 2 (was 1); iss-2608211850074600 the lifeboat probe read cap+1 and refuses a file grown past the cap (size TOCTOU); iss-2608211850070318 history list --json emits [] not null. Doc/record: iss-2608211849581263 + iss-2608211849583757 the persona brief said the picker chooses at random and omitted Nia (a residual of resolved iss-300 — selection is by role, never by name; roster is fourteen); iss-2608211849583208 the bundled INTENTS default persona rule reached this repo's own intent authors because .abcd/rules.json never overrode INTENTS, so an INTENTS override now points authors at the registry (the default stays correct for a registry-less adopter); iss-2608211849580624 the README described download-on-every-update and a no-op .binary-meta remedy, rewritten for the spc-35 persistent cache; iss-2608211849582190 CONTRIBUTING granted the fenced-quotation carve-out for commit messages too, now scoped to the pull-request body. Refuted / considered-and-rejected (kept out of the ledger): R3 the release-gate manifest prompt naming ten of twenty commands (an illustrative grounding string, not a gated inventory, and editing it ripples into receipt hashes); R4/R5 related_adrs and prose citations of superseded ADRs (resolve via the retired-set mechanism, deliberate historical provenance); R6 "11 adapters" vs "five capability seams" (implementations vs categories, not a contradiction); R7 the adr-13 bare path to itd-36's old bucket (a benign ungated breadcrumb; the authoritative related_intents resolves by id); the update.go redirect-host case-fold (fails closed, availability only, impractical to test through a loopback redirect). I2 (release.yml "dormant until the public flip" comments) was implemented then reverted: release.yml is a scaffold template rendered for adopters who may be private, so the visibility-flip framing is generic-correct there, unlike the abcd-specific runbook round 4 corrected. Model routing: orchestration on Claude Fable 5; five parallel hunters and eight per-finding adversarial refuters on Claude Opus 5; the dual pre-merge review runs one reviewer as Claude Opus 5 and one as Claude Fable 5.
Frontmatter
| id | dcn-2608210000000004 |
|---|---|
| type | decision |
| date | 2026-08-21 |
.abcd/work/decisions/dcn-2608210000000004-bug-hunt-round-6-branch-bughunt-b.md
open on GitHub ↗ · commit history ↗
mentions18
- adr-13Durable memory writes — single-writer, atomic-rename crash model
- iss-300The persona glossary (brief/glossary/core/persona.md) and brief/01-product/05-personas.md say the persona picker 'chooses at random', contradicting personas.json and itd-79 whose rule is 'selection is by role, never by name'; the glossary's worked examples also assign off-role names (Carol as product lead, Alice as developer)
- iss-2608211849461061frontmatter.Fields requires --- on line 0, so a comment-led record file bypasses the no_git_metadata blocker (13 glossary term files)
- iss-2608211849463840docs-lint/record-lint main walk lacks the root containment and guarded read its sibling citation collector applies to the same cfg.Roots, so a cloned repo reads and lints files outside the repository
- iss-2608211849466878citation DaysBetween reads local calendar date then restamps UTC, so citation staleness and the release-gate overdue blocker depend on the maintainer timezone
- iss-2608211849467013guard tokenizer does not recognise redirection operators, so gluing >file onto a token silently downgrades a Tier-1 block to allow
- iss-2608211849468791attribution gate trailer/None regexes are dollar-anchored over a class excluding CR, so a CRLF pull-request body false-reds the required attribution check
- iss-2608211849580624README provisioning section describes download-on-every-update, but spc-35 shipped a persistent CLAUDE_PLUGIN_DATA cache that provisions by verified copy; the .binary-meta deletion remedy is also a no-op on cache-provisioned roots
- iss-2608211849581263brief 05-personas.md says the persona picker chooses at random, contradicting personas.json and itd-79 (selection is by role, never by name); a live residual of resolved iss-300
- iss-2608211849582190CONTRIBUTING grants the fenced-quotation carve-out for commit messages and pull-request bodies alike, but the gate strips fences on the body arm only, so a fenced footer in a commit message still fails CI
- iss-2608211849583208the bundled INTENTS default rule (Personas are always Alice, Bob, Carol) reaches abcd own intent authors because .abcd/rules.json never overrides INTENTS, contradicting the armed 14-persona registry
- iss-2608211849583757brief 05-personas.md roster lists thirteen personas, omitting Nia; the registry has fourteen and Nia is in live use
- iss-2608211850070318abcd history list --json emits bare null on an empty store while the command doc promises an empty list
- iss-2608211850070541abcd identity init maps a structural fault to exit 1 (the rendered-refusal code) while its sibling verbs and the tree-wide usage-error contract use exit 2; init renders nothing on that path
- iss-2608211850074600lifeboat SourceContext.ReadFile sizes with fstat then reads exactly the cap, so a file that grows past the cap between check and read is silently truncated to a prefix rather than refused
- iss-2608211914592726residual config-derived os.ReadFile sites in internal/core/lint read cloned-repo-controlled paths without the containment/guarded-read stack the roots and glossary walks now use: persona.go registry, lint.go spec-doc and record-store reads, speclinks.go, contextcurrency.go, deliverystate.go changelog, indexdrift.go, subverbs.go snapshots. Triage each by attacker-controllability under a cloned repo and guard those in scope
- itd-36Knowledge That Compounds, Not Knowledge That Re-Derives
- spc-35hook-binary-to-persistent-data-dir