Development record
Eight resolved records name, in their resolution notes, a test no longer in the tree; each was true when written, and RS006 reads only records entering a terminal folder, so none is refused, but a reader following the note finds nothing. Verified at b7646ff1, with the commit that removed each test: iss-184 names TestTokenizeRejectsUnterminatedHeredoc (16d50feb renamed it TestTokenizeFlagsUnterminatedHeredoc and changed the behaviour: an unterminated heredoc is a verdict, not ErrUnparsableCommand, so the note's part (2) is stale too); iss-2608301808193750 names TestIsAbsentValueIsASpellingTestNotANullTest (3eb4b549 replaced the spelling predicate with a class-based one, TestAbsenceIsDecidedByClassNotBySpelling, so the note's 'deliberately NOT widened' is superseded); iss-2608311632382737 names TestPreflightRunsBothEvalLanes (the test is TestPreflightRunsEveryTaggedEvalLane, which derives the lanes from the Makefile; the one clean rename of the eight); iss-2608311632439831 names TestComparativeRefusesToAssemble (3b62c967 made the comparative position assemble from the widening run's items, so the refusal the note describes no longer exists); iss-2609012039117381 names TestBinaryHooksFallBackToAPathBinary and iss-275 names TestGuardShimFallsBackToPATH (c637a734 removed the PATH rung those tests pinned: the shims run only the abcd the machine recorded); iss-354 names TestWorkflowGoVersionsMatchSubstitutions (removed in df377ee6, replaced by TestEverySetupGoResolvesTheToolchainFromGoMod under iss-2609090951291799); iss-2609090951291799 names TestWorkflowGoVersionsMatchSubstitutions only to say it was replaced, which stays accurate. Six of the eight need an amendment note stating what superseded the test and the claim, not a rename, so the set is not a mechanical fix.
Eight resolved records name, in their resolution notes, a test no longer in the tree; each was true when written, and RS006 reads only records entering a terminal folder, so none is refused, but a reader following the note finds nothing. Verified at b7646ff1, with the commit that removed each test: iss-184 names TestTokenizeRejectsUnterminatedHeredoc (16d50feb renamed it TestTokenizeFlagsUnterminatedHeredoc and changed the behaviour: an unterminated heredoc is a verdict, not ErrUnparsableCommand, so the note's part (2) is stale too); iss-2608301808193750 names TestIsAbsentValueIsASpellingTestNotANullTest (3eb4b549 replaced the spelling predicate with a class-based one, TestAbsenceIsDecidedByClassNotBySpelling, so the note's 'deliberately NOT widened' is superseded); iss-2608311632382737 names TestPreflightRunsBothEvalLanes (the test is TestPreflightRunsEveryTaggedEvalLane, which derives the lanes from the Makefile; the one clean rename of the eight); iss-2608311632439831 names TestComparativeRefusesToAssemble (3b62c967 made the comparative position assemble from the widening run's items, so the refusal the note describes no longer exists); iss-2609012039117381 names TestBinaryHooksFallBackToAPathBinary and iss-275 names TestGuardShimFallsBackToPATH (c637a734 removed the PATH rung those tests pinned: the shims run only the abcd the machine recorded); iss-354 names TestWorkflowGoVersionsMatchSubstitutions (removed in df377ee6, replaced by TestEverySetupGoResolvesTheToolchainFromGoMod under iss-2609090951291799); iss-2609090951291799 names TestWorkflowGoVersionsMatchSubstitutions only to say it was replaced, which stays accurate. Six of the eight need an amendment note stating what superseded the test and the claim, not a rename, so the set is not a mechanical fix.
Grounds
- pursued: a reader following any of the eight notes to a test that is gone finds, in the same record, the commit that removed it and what pins the behaviour now; a resolved record naming a test absent from the tree with no Correction section saying so would show it wrong
Frontmatter
| id | iss-2609261034583909 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-2609261034583909-eight-resolved-records-name-in-their.md
open on GitHub ↗ · commit history ↗
mentions8
- iss-184guard tokenizer heredoc misparse: an unquoted arithmetic left-shift with an identifier operand (e.g. `$((1<<shift))`) is misparsed as a here-document start by isDelimStart (tokenize.go:206, accepts any word starting with a letter/underscore) plus readHeredocDelim (tokenize.go:249, terminates the delimiter word on ')'). skipHeredocBodies (tokenize.go:264) then scans for a line equal to the bogus delimiter, finds none, and silently swallows every subsequent line of the command before it reaches command position. A dangerous command on a later line (git push --force, rm -rf, gh repo delete, etc.) is never seen by Registry.Check and the guard returns VerdictAllow with no error — a silent fail-open, not the loud could-not-answer path the shim reserves for unparsable input. Confirmed live via both CLI front doors (internal/surface/cli/guard.go: guard check and guard hook). The literal-digit form (1<<20) is unaffected; only identifier/variable operands trip it. Reproducing test: internal/core/guard/tokenize_test.go, TestArithmeticShiftByIdentifierIsNotAHeredoc.
- iss-275TestGuardShimFailsOpenLoud's runShim inherits the host PATH, so on a machine with a real abcd installed the guard hook's PATH-fallback rung (shipped with the hook resolution ladder) finds it: the binary-absent case genuinely guards the session via the PATH binary, no UNGUARDED warning prints, and the test fails — environmentally, exactly the machines that dogfood the install. CI is unaffected (no abcd on PATH). Same class as iss-249, in the cli shim harness; the hooks_selfprovision_test hookRun helper already pins PATH for this reason and is the pattern to copy. Detector: the test itself on an affected machine; acceptance: go test ./internal/surface/cli/ -run TestGuardShim passes unmodified with an abcd on PATH — including a new case asserting the PATH rung guards the session when the plugin root is empty.
- 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-2608301808193750the blank grounds enumeration claims the trailing comment is the last gap while eleven further nothing carrying spellings pass green
- iss-2608311632382737The pre-push gate is blind to both eval lanes, so the read-block eval is guarded by nothing that blocks anything. make preflight runs the six lint gates, go build, go vet, go test over the untagged packages and the race lane, and neither make smoke nor make evals-cold-reading; the eval files sit behind a build tag, so the untagged test run does not compile them. A defect in the cold-reading evals therefore passes every local gate and surfaces only in CI. That was not hypothetical: a path-elision defect in the amnesia eval's own guard was unsatisfiable wherever the process temp directory is the Linux one, so it would have landed green locally and red in the merge queue, and it was found by an adversarial review rather than by any gate. Pair this with the CI job not being a required status check and the position is that the eval which certifies the firewall runs in no gate that can stop anything: preflight does not execute it, and the job that does execute it cannot block a merge.
- iss-2608311632439831spc-64's Positions exercised paragraph is stale against the eval it specifies. It says widening, entailment and detection are asserted in full and that at the comparative position the eval asserts only the read-block over the instrument's own stored prior outputs, making no claim about the in-cycle candidate set. The delivered eval asserts every sentinel class at every position, which the first review round required after finding that carving comparative out made an assembler leak at that one position invisible. The spec therefore understates its own delivery, and understating is not harmless here: a reader deciding what the eval covers would conclude that a comparative-only leak goes unnoticed, which is exactly the defect the round closed.
- iss-2609012039117381Sub-finding of GHSA-gx3m-3224-qqcv that does not need the design decision: the hook shims' PATH rung accepts an `abcd` that `command -v` resolves from inside the working tree or from a world-writable directory. With a dot or empty PATH entry — or a PATH entry naming a directory under the checkout — `command -v abcd` in `hooks/hooks.json` (UserPromptSubmit, PreToolUse, PreCompact, SessionEnd) returns a file the checkout controls, so a hostile clone carrying an executable `abcd` becomes the guard and rules loader for a session whose plugin-root binary is missing; a world-writable PATH directory hands the same role to any local user. The documented contract (docs/how-to/install.md: plugin root first, then an abcd on PATH, the one-liner installs into `~/.local/bin`) never places the binary in either location, so refusing both keeps the documented rescue intact. The fix must establish, for all four events, that a PATH abcd whose directory is under the shim's working directory or is world-writable is not executed, that the shim degrades to its existing loud line (PreToolUse: UNGUARDED, exit 1) plus one line saying the PATH binary was ignored and why, and that an abcd in an ordinary PATH directory still serves as the fallback. SessionStart is unchanged (no PATH rung). The full owned-only rung stays with the parent record.
- iss-2609090951291799The format gate exists because two gofmt versions judge a tree differently, and it goes to some trouble to derive the toolchain version from the go directive in go.mod so that one declaration governs. The workflows then declare it again: nine setup-go steps across four workflow files pin the version as a literal string, four of them in the CI workflow and the rest in the release, site and screenshot workflows. The action already accepts a reference to the go.mod file in place of a literal, which is the form that removes the second spelling. Verified by grepping the workflow tree. It matters in exactly the direction the format gate was built for: bump the go directive and forget one of the nine, and CI compiles and tests on the old toolchain while the format gate resolves and fetches the new one, so the gate and the lane disagree about which gofmt is correct, reintroducing at the CI boundary the skew the gate refuses to allow locally. Fix direction: replace every literal pin with the go.mod file reference so the go directive is the only place the version is written. Detector: a change to the go directive in go.mod must change which toolchain every workflow job runs, with no workflow edit.