Development record
2026-08-21 — Bug-hunt round 5, branch bughunt-b/round-5. Baseline (make preflight
decisiondcn-2608210000000003
2026-08-21 — Bug-hunt round 5, branch bughunt-b/round-5. Baseline (make preflight
- gofmt -l .) green before any change. Five parallel Opus 5 hunters swept the four dimensions; each candidate was adversarially refuted by an independent Opus 5 subagent before capture. Findings: 4 substantive, 9 nitpick, 9 refuted. The C1 ScrubbedEnv/GIT_CONFIG_GLOBAL candidate split the refuters (one CONFIRMED, one REFUTED); adjudicated REFUTED — keeping the developer's global git config readable is deliberate and test-pinned (TestScrubbedEnvStripsHijackKeepsGlobalConfig), the attack needs control of abcd's process env (out of scope under the trusted-env model), and the obvious fix (scrub to /dev/null) would blind the redaction probe for every developer whose identity lives in global config. Fixed and resolved this round (code, each with a watched-fail test): iss-2608211432258689 launch --dry-run printed WouldRefuseOn unsanitised so a committed control-char filename injected raw terminal escapes into the preview and CI log (now termsafe); iss-2608211432257954 the same dry-run leaked a raw absolute path in lockstep.detail (a success envelope that never passes the error-surface scrub) — stripped at loadJSON; iss-2608211432258975 abcd lint mapped a rule-engine fault to exit 1 (the tri-state's warnings-only code) so a CI gate keying on >=2 read a lint that never ran as an advisory pass — now exit 2; iss-2608211432254405 launch scaffold deriveBranch assumed .git is a directory, stamping the fallback branch main into the generated release workflows from a linked worktree — now resolves the gitfile (worktree gitdir HEAD + shared commondir origin/HEAD). Nitpicks fixed: iss-2608211432389181 the intent verdict reader was the last CLI operand on Lstat-then-os.ReadFile (false benign-TOCTOU comment) — routed through fsutil.ReadGuarded; iss-2608211432384430 the history rootSHA diagnostic named only 40 chars though the regex accepts 64 (SHA-256); iss-2608211432384091/389477/389791 three user-facing doc claims (README SessionEnd self-bootstrap overclaim, memory.md source.class vs source_class, ahoy.md missing the shadowed-on-PATH install_mode suffix); iss-2608211432489481/489288/482363/483805 record hygiene (seven display-text/href link mismatches, two bare paths to absent dirs, the rfc-1/itd-26 one-sided pair, the work-tier roster omitting the issue ledger/reviews/rulesets). Refuted / prior art (kept out of the ledger): C1 above; C2 folding local_username to case-insensitive (net-negative — broadens a documented hard_fail false-positive class and reopens iss-31); S3 widening hasControlChar (the render sanitiser, not the integrity gate, is the fix); S4 launch --no-index dropping a force-added tracked file (dry-run preview writes no artefact, exclusion is visible and over-exclusion is the safe direction); D2 guard check exit-2 enumeration (the governing "could not be evaluated at all" definition already covers a disabled registry); R2 itd-3 spc-1 (a documented, minting-honored reservation). Model routing: orchestration on Claude Fable 5; five parallel hunters and nine 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-2608210000000003 |
|---|---|
| type | decision |
| date | 2026-08-21 |
.abcd/work/decisions/dcn-2608210000000003-bug-hunt-round-5-branch-bughunt-b.md
open on GitHub ↗ · commit history ↗
mentions11
- iss-31launch dry-run cannot pass on its own repo: the identity scanner hard-fails on /dev/null as a local-username false positive (internal/adapter/scanner/identity.go:230) so the launch gates can never pass here; the launch payload omits skills/ and every file its own fallback instructions depend on (.abcd/config/launch-payload.json); globRegexpCache in the bundle resolver is an unsynchronized package-level map — a data race if the transport-agnostic core is ever driven concurrently (internal/core/launch/bundle.go:559). Detector: a dogfood gate — CI runs abcd launch --dry-run against this repo and expects a pass, plus -race coverage of concurrent resolver use. Acceptance corpus: the three instances above; the dogfood gate fails on all of them today.
- iss-2608211432254405launch scaffold deriveBranch assumes .git is a directory and reads HEAD/origin-HEAD with raw os.ReadFile, so in a linked worktree or submodule (where .git is a gitfile) both reads fail and it stamps the fallback branch main into the generated release workflows, leaving the release gate silently inert on a non-main-default repo
- iss-2608211432257954launch --dry-run leaks a cwd/home-rooted absolute path into lockstep.detail and would_refuse_on when a pinned manifest is unreadable, violating the no-absolute-paths-in-machine-output norm; the dry-run is a success envelope so scrubPaths never reaches it
- iss-2608211432258689launch --dry-run prints WouldRefuseOn with %v and no termsafe.Sanitize, so a committed repo filename carrying raw terminal escapes reaches the terminal and CI log (sibling of iss-259/iss-264 at an unrecorded site)
- iss-2608211432258975abcd lint maps a rule-engine fault to exit 1 which its documented Conftest tri-state reserves for warnings-only, so a CI gate keying on exit>=2 reads a lint that never ran as an advisory pass (fail-open)
- iss-2608211432384091README claims every non-SessionStart hook self-bootstraps, but the SessionEnd hook deliberately never downloads the binary (pinned by TestSessionEndNeverBootstraps); the universal is false for SessionEnd
- iss-2608211432384430history Capture/List reject an invalid rootSHA with a message naming only 40 chars though rootSHARe accepts 40 or 64 (SHA-256); the diagnostic contradicts the widened regex
- iss-2608211432389181readVerdictFile does Lstat-then-os.ReadFile with a comment claiming the swap window is not a symlink escape, but os.ReadFile follows a swapped-in symlink and ignores the size cap; it is the last CLI-operand reader not routed through fsutil.ReadGuarded
- iss-2608211432489481seven markdown links across the record carry a backticked display path that does not resolve from the containing file while the href does, evading links_resolve (recurrence of iss-391)
- itd-3abcd Loads Its Own Rules On Demand
- itd-26Raid the Open Ocean, Bring the Cargo Home with Papers