This is the record of an abcd-managed repository

abcdBetav0.16.2 · 2026-11-06

Development record

2026-07-28 — itd-101 part (b) second review round closed three holes the first round's fixes left open, all reproduced end-to-end by the reviewers. (1) The baseline-path containment check was purely LEXICAL, so a committed symlinked directory (`.abcd/evil -> /outside`) plus a lexically-innocent `"baseline": ".abcd/evil/x.json"` reopened the very arbitrary-file-write primitive the first fix claimed to close — `WriteFileAtomic` MkdirAll's *through* the link. Containment now also RESOLVES: `EvalSymlinks` on the deepest existing ancestor of the target (it usually does not exist yet on a first run), compared against an `EvalSymlinks`'d repo root, reusing the shape `internal/core/launch/bundle.go` already uses for symlinked bundle entries rather than adding a third copy. `CitationPolicy` now takes the repo root and returns a `CitationPolicySet` carrying both the repo-relative form (for messages, so no absolute path is ever rendered) and the absolute form (for I/O). (2) `cfg.Roots` had NO containment, and while reading outside the repo was inert for a reporting lint, this intent made the collector feed a live fetcher whose results are persisted into a baseline the workflow expects to be committed and pushed — `"roots": ["../private"]` therefore fetched and PUBLISHED every URL in a sibling directory. The collector (not the pre-existing lint walk) now refuses an escaping or symlinked root. (3) The wholesale-failure guard consulted `res.Preserved == 0`, but a preserved receipt was never fetched and so is no evidence the network worked: any repo that had ever run `confirm` — the designed steady state for robot-refusing sources — silently lost the protection entirely. The guard now reads a new `CheckOutcome.Answered` bit that the CHECKER sets when a host returned any status line at all. That is the bit `StatusBroken` was destroying (a DNS failure, a refused connection and a genuine 404 all landed there), and recovering it from a proxy was wrong in both directions — the old condition also made a sole genuine 404 permanently unrecordable, refusing forever with a false "check connectivity". RULE affirmed: when a guard needs a fact, carry the fact, never infer it downstream from something correlated.

decisiondcn-2607280000000001

2026-07-28 — itd-101 part (b) second review round closed three holes the first round's fixes left open, all reproduced end-to-end by the reviewers. (1) The baseline-path containment check was purely LEXICAL, so a committed symlinked directory (.abcd/evil -> /outside) plus a lexically-innocent "baseline": ".abcd/evil/x.json" reopened the very arbitrary-file-write primitive the first fix claimed to close — WriteFileAtomic MkdirAll's through the link. Containment now also RESOLVES: EvalSymlinks on the deepest existing ancestor of the target (it usually does not exist yet on a first run), compared against an EvalSymlinks'd repo root, reusing the shape internal/core/launch/bundle.go already uses for symlinked bundle entries rather than adding a third copy. CitationPolicy now takes the repo root and returns a CitationPolicySet carrying both the repo-relative form (for messages, so no absolute path is ever rendered) and the absolute form (for I/O). (2) cfg.Roots had NO containment, and while reading outside the repo was inert for a reporting lint, this intent made the collector feed a live fetcher whose results are persisted into a baseline the workflow expects to be committed and pushed — "roots": ["../private"] therefore fetched and PUBLISHED every URL in a sibling directory. The collector (not the pre-existing lint walk) now refuses an escaping or symlinked root. (3) The wholesale-failure guard consulted res.Preserved == 0, but a preserved receipt was never fetched and so is no evidence the network worked: any repo that had ever run confirm — the designed steady state for robot-refusing sources — silently lost the protection entirely. The guard now reads a new CheckOutcome.Answered bit that the CHECKER sets when a host returned any status line at all. That is the bit StatusBroken was destroying (a DNS failure, a refused connection and a genuine 404 all landed there), and recovering it from a proxy was wrong in both directions — the old condition also made a sole genuine 404 permanently unrecordable, refusing forever with a false "check connectivity". RULE affirmed: when a guard needs a fact, carry the fact, never infer it downstream from something correlated.

Frontmatter

iddcn-2607280000000001
typedecision
date2026-07-28

mentions1