Development record
2026-08-20 — bughunt round 2 (branch bughunt-b/round-2): captured the round-2 records (iss-346..iss-357, with the two colliding ids re-minted as iss-358/iss-359), fixed
2026-08-20 — bughunt round 2 (branch bughunt-b/round-2): captured the round-2 records (iss-346..iss-357, with the two colliding ids re-minted as iss-358/iss-359), fixed eleven records, closed iss-201, and wontfixed iss-358 on pre-merge review evidence. Code: iss-358 lanHostRe/deviceHostRe trailing-\b redaction miss (the iss-307 sweep's residual) — BUILT, then REVERTED: the pre-merge adversarial review proved the loosened pattern flags snake_case selectors (stream.local_addr, args.local_rank) and Stage-1 redaction rewrites findings into the irreversible history store, so the warn-tier miss is the accepted cost, pinned by TestSnakeCaseSelectorsStayQuiet; iss-359 redirect-controlled FinalURL carried C1/bidi/zero-width runes raw into --json and the committed baseline (fetch boundary percent-encodes, baseline validates, termsafe/coverage doc claims corrected); iss-346 guard also-matched dropped a matched warn under a synthetic block; iss-347 readTranscript symlink-follow + truncation (now fsutil.ReadGuarded); iss-201 hook stdin over-cap misdiagnosis (cap+1 probe at readHookInput and the guard hook); iss-356 batch (urlguard RFC 6890 ranges incl. CGNAT, repolint not-scanned warn, 64-hex resolve sha, CLI help truths, release.yml wording + templates, dependabot pip). iss-357 records the memory-ingest FinalURL sibling site the cite fix did not reach. Records: iss-348/349/350 user-facing doc truths; iss-351 discipline roster -> pointer; iss-352 phantom research/adr repointed; iss-353 note naming yields to adr-30; iss-354 go-version lockstep test (mutation-verified). Recorded not fixed: iss-355 — a batched merge-queue push tags the batch tip, so auto-release + the HEAD^2^ derivation wedge a release roll merged as a non-final queue entry (iss-326's outcome by a route itd-93 cannot close); required-check workflow logic, left with two proposed fixes. Refuted this round (kept out of the ledger): the external-review pull_request_target check-sha wedge (check runs attach to the PR head, proven from run history), the docs-site ungated claim (docs-lint gates docs/ on every PR; iss-234 records the inert design), the empty Diataxis indexes (owned by iss-216 and the facilitator plan), identity email case-folding (byte-exact parity with the sh pre-commit gate is the contract), and the guard backtick parser gap as a fix target (iss-148 records the reverted attempt; only its missing help-text disclosure was new). Dedup boundary: iss-307/311/317/319/321/325 and the v0.6.0 wedge (iss-326/327) were already held by hunt A or the maintainer and were not re-reported.
Frontmatter
| id | dcn-2608200000000002 |
|---|---|
| type | decision |
| date | 2026-08-20 |
.abcd/work/decisions/dcn-2608200000000002-bughunt-round-2-branch-bughunt-b-round-2.md
open on GitHub ↗ · commit history ↗
mentions20
- adr-30Design-record information architecture — flat artefact-type folders
- iss-148guard registry coverage gaps found while wiring itd-103 (registry content, not matching semantics): a push whose refspec carries a leading plus is a force in disguise and no entry describes it; xargs, timeout and exec are absent from the matcher's wrappers set, so a hazard launched through one of them is not seen; a backtick command substitution is not followed, while the dollar-paren form is; and a wrapper that IS in the set defangs an entry the moment it carries its own flags, because only the wrapper name is stepped over — `sudo <hazard>` is seen, `sudo -u bob <hazard>` is not, and the same holds for `env -i` and `time -p`. That last one is the sharpest: it turns an entry the registry does describe into an allow with one extra token, and it is the only item here that a facilitator would reasonably assume was covered. Candidates for the admission gate as the registry grows from reality; the wrapper-flag item is matcher-side (`commandOf` in internal/core/guard/match.go), not registry content.
- iss-201abcd guard hook reads its PreToolUse stdin payload via a bare LimitReader with no overflow check, so a payload padded past the 1 MiB cap (e.g. a blocked command with a trailing shell comment full of junk) is silently truncated, breaks JSON parsing, and routes to the fail-open-loud path (exit 1, command runs) with a diagnostic that misleadingly blames the host ('not readable JSON') instead of reporting the actual cap overflow; the sibling check verb's guardCandidate already reads cap+1 specifically to detect and refuse this. Independently verified: threshold is sharp and deterministic (cap-1 blocks, cap+1 fails open), always a loud (not silent) fail-open, exploitation cost bounded by needing >1 MiB of attacker-influenced content inside one tool_input
- iss-216Install instructions need a getting-started page once more than one harness is supported, and the version floor needs a home in it. Raised at the itd-108 grill (2026-08-11) while ruling that no migration is owed to existing users, because there are none yet.
- iss-234docs-only PRs pay the full two-OS build+test matrix — add a fail-closed inert-path skip gate
- iss-307scanner network ipv4Re and macRe rely on a trailing ASCII word boundary, silently missing a hard_fail address whose only sin is an adjacent word char
- iss-326The v0.6.0 tag is permanently unpublishable: its roll branch carried no receipts commit, the receipt gate fail-closed at release time, and the re-release path builds only from the tagged commit whose frozen tree can never contain receipts naming its own content commit. The tag stays as a record (anti-tag-move); v0.6.1 is the recovery
- iss-346guard check's also-matched line assumes Matches[0] is the winner, so a synthetic block over registry warns silently drops the matched warn entry and echoes the winner twice
- iss-347readTranscript opens the hook-supplied transcript path without O_NOFOLLOW or an over-cap probe, the one guarded read left off fsutil.ReadGuarded, so a symlinked transcript_path is followed and an over-cap file is stored silently truncated
- iss-348the root command's Use and help omit the shipped record-id dispatch, so the generated CLI reference states Usage: abcd with no positional and abcd --help never mentions that abcd iss-N describes a record
- iss-351the three-disciplines roster itd-1 itd-5 itd-37 is hand-enumerated at six sites while intents/disciplines/ holds six active disciplines, dropping itd-79 itd-81 itd-84 from the mental model, scope, roadmap dashboard and phase-0 acceptance
- iss-352three current-state records cite ADRs at development/research/adr/, a path that does not exist and a layout adr-30 explicitly rejected; all three are backticked code spans links_resolve never checks
- iss-353research/notes/README.md prescribes topic-kind note naming while adr-30 and development/README.md ratify date-prefixed naming and the record-lint successor plus ideate both emit dated notes; the notes README is the outlier and 29 of 41 notes are dated
- iss-354ci.yml's three go-version pins are coupled to nothing: TestSelfScaffoldParity gates release.yml and auto-release.yml against scaffold substitutions but no test reads ci.yml, so the d594511 drift where CI scanned green on a newer toolchain than the release build recurs silently on the next bump
- iss-355a batched merge-queue push makes github.sha the batch tip, so auto-release tags the wrong commit and release.yml's HEAD-caret-2-caret receipt derivation resolves an unrelated PR's commit whenever the release roll is not the last entry in its queue batch; the ancestry guard passes and the run wedges after the immutable tag, the iss-326 outcome by a route itd-93's pre-merge check cannot close because batch composition is decided by the queue
- iss-356round-2 fixed nitpick batch: guard check help omits the disclosed backtick limit; urlguard misses CGNAT 100.64/10 and other RFC 6890 ranges; readHookInput misreports an over-cap payload as malformed (iss-201's class at the shared helper); repolint privacy-hygiene silently skips textual files over the 4 MiB cap; capture reCommitSha refuses 64-hex commits; launch Short hides that --dry-run is required; release.yml verify-tag comment overstates what gh verifies; release.yml header says dispatch runs only the rehearsal job; dependabot covers no pip ecosystem for docs; brief pointer lines enumerate five of nine internals chapters; phase-6 and 06-lint carry change-narration blocks; 05-internals cites a ledger entry that does not exist; 03-evidence names the retired activity record nitpick documentation
- iss-357memory ingest records a redirect-controlled FinalURL verbatim into stored material origins — the iss-359 class one door over; the cite fix neither touched nor recorded the sibling site
- iss-358scanner lanHostRe and deviceHostRe keep the trailing ASCII word boundary the iss-307 sweep dropped from ipv4Re and macRe, so a LAN or device hostname abutting an underscore or alnum suffix is silently missed
- iss-359cite fetch records a redirect-controlled FinalURL verbatim, so C1, bidi and zero-width runes in a hostile Location query reach abcd docs lint --json and the committed citations baseline raw; the termsafe doc claim that encoding/json escapes control characters is false for those classes
- itd-93abcd Scaffolds a Release Gate That Works on the First Try