This is the record of an abcd-managed repository

abcdBetav0.16.2 · 2026-11-06

Development record

2026-07-27 — itd-101 part (b) review round settled five more. (1) The committed `citation_baseline.baseline` config value is CONTAINED at one choke point (`lint.CitationPolicy`, which now returns an error): a `../../..` or absolute path is REFUSED, never silently normalised, because `SaveBaseline` MkdirAll's its parent and a contributor controls that file — this was a real arbitrary-file-write primitive found by the security review, reproduced against a built binary. Both writers and both readers resolve through the one check. (2) A refresh run in which NOTHING succeeded is REFUSED rather than committed, and only when a prior baseline existed: `Check` collapses DNS failure, refused connection and timeout into the same `broken` as a 404, so a run behind a captive portal would otherwise rewrite every entry as broken — stale human receipts included, since those are re-checked and so not covered by the blocked branch — and the operator would find the gate blocking every commit. A first run over genuinely dead citations has nothing to protect and still writes. (3) An unrecognised `Status` from a `Checker` is an ERROR, not a fall-through: the seam is exported for AC 5's adapter, and falling through would drop the URL from BOTH the baseline and the queue — the one outcome nothing downstream could detect. (4) The missing-entry lint message names BOTH verbs: the only state that produces a missing entry is a source refusing automated fetchers, so naming `refresh` alone sent the maintainer round a loop that cannot terminate — only `confirm` clears it. (5) A docs-lint config that arms the citation rule but fails to PARSE is reported to the release preflight as `Unreadable` and REFUSES, distinct from the nil "not armed" state — rendering a broken gate as an absent one would wave a release through on a false statement. Also consolidated: `daysBetween` is now the exported `lint.DaysBetween`, called by the verb and the gate alike, because two copies of the staleness boundary is two chances for the verb to call an entry current on the day the gate calls it overdue; and the CLI's ad-hoc `citeErrorDetail` was dropped for the canonical `scrubPaths`, which preserves the `*PathError` type the redactor needs (an absolute developer path was reaching machine output).

decisiondcn-2607270000000009

2026-07-27 — itd-101 part (b) review round settled five more. (1) The committed citation_baseline.baseline config value is CONTAINED at one choke point (lint.CitationPolicy, which now returns an error): a ../../.. or absolute path is REFUSED, never silently normalised, because SaveBaseline MkdirAll's its parent and a contributor controls that file — this was a real arbitrary-file-write primitive found by the security review, reproduced against a built binary. Both writers and both readers resolve through the one check. (2) A refresh run in which NOTHING succeeded is REFUSED rather than committed, and only when a prior baseline existed: Check collapses DNS failure, refused connection and timeout into the same broken as a 404, so a run behind a captive portal would otherwise rewrite every entry as broken — stale human receipts included, since those are re-checked and so not covered by the blocked branch — and the operator would find the gate blocking every commit. A first run over genuinely dead citations has nothing to protect and still writes. (3) An unrecognised Status from a Checker is an ERROR, not a fall-through: the seam is exported for AC 5's adapter, and falling through would drop the URL from BOTH the baseline and the queue — the one outcome nothing downstream could detect. (4) The missing-entry lint message names BOTH verbs: the only state that produces a missing entry is a source refusing automated fetchers, so naming refresh alone sent the maintainer round a loop that cannot terminate — only confirm clears it. (5) A docs-lint config that arms the citation rule but fails to PARSE is reported to the release preflight as Unreadable and REFUSES, distinct from the nil "not armed" state — rendering a broken gate as an absent one would wave a release through on a false statement. Also consolidated: daysBetween is now the exported lint.DaysBetween, called by the verb and the gate alike, because two copies of the staleness boundary is two chances for the verb to call an entry current on the day the gate calls it overdue; and the CLI's ad-hoc citeErrorDetail was dropped for the canonical scrubPaths, which preserves the *PathError type the redactor needs (an absolute developer path was reaching machine output).

Frontmatter

iddcn-2607270000000009
typedecision
date2026-07-27

mentions1