Files
stack/docs/scratchpads/1099-pipefail-sweep.md
T
veronica f0d2dd9920 docs(W4): stamp kind and status front matter on 104 live documents
Applies the document contract from
docs/plans/2026-08-20_stack-docs-flatten-and-alignment.md section 3, partially:
`kind` and `status` only. `parent` is deliberately held until the flatten in
section 4 lands, so that 127 documents do not have to be re-pointed by hand
when docs/fleet/NORTH_STAR.yaml moves to docs/NORTH_STAR.yaml.

Scope, measured on origin/next at 63069149:

  127 live docs   = all *.md under docs/ minus docs/archive/ minus docs/_old_structure/
  104 stamped     here
   19 held        operator judgement (plan section 9), worklist in the same PR
    3 held        the SUPERSEDED TASKS.md stamps, which cite the moving path
    1 untouched   docs/fleet/FLEET-DOCTRINE.md, already stamped in W1

Kinds applied: 54 guide, 34 record, 9 spec, 6 tracking, 1 projection.
Every row carries a confidence and a one-line rationale in the worklist.

Two collisions with the existing state, both flagged rather than resolved:

1. docs/README.md:150-160 already documents a front-matter convention
   (title/type/audience/status/source_of_truth) with its own allowed values.
   It is applied to 4 of 127 files. Its `status` vocabulary is
   current|draft|deprecated|historical; the new contract's is active|superseded-by.
   The key collides. This commit lets the new contract win and rewrites
   `status: current` to `status: active` on those 4 files, keeping their other
   legacy keys untouched. No code reads any of them: `git grep source_of_truth`
   outside docs/ returns nothing. docs/README.md still prescribes the old
   convention and is an operator row, so it is not edited here.

2. Two of the plan's 20 operator rows are YAML files, not markdown
   (docs/fleet/examples/roster-v2.yaml, docs/openapi-tess.yaml), and the
   contract's front-matter form has no defined meaning for a .yaml document.
   That gap also applies to docs/fleet/NORTH_STAR.yaml, the source of truth
   itself. Raised in the worklist.

A third row from the plan, docs/fleet/north-star.md, no longer exists: W1
renamed it to docs/fleet/FLEET-DOCTRINE.md.

Verification: 104/104 parse with the expected kind and status in front matter;
the check was shown to reject a wrong kind before it was trusted. The diff
removes 4 lines total, all of them `status: current`.
2026-08-20 19:30:25 -05:00

3.4 KiB

kind, status
kind status
record active

#1099 — pipefail + early-exit sweep

Scope and decisions

  • Baseline df4c591ab42aa1ae62c12935fdc0e772684864a0, after #1100 removed its 35 sites.
  • Split into review-sized non-closing tranches: runtime/general; tmux/git/quality tests; wake validation/tests.
  • Do not equate class membership with demonstrated risk. Do not use payload size or pipeline stage count as a safety proxy.
  • Preserve the issue's withdrawn findings for qa-hook-stdin.sh and the two fresh-directory pnpm pack lookups. Fix install.sh:312 because malformed multi-root input must reach its named handler.

Tranche 1 TDD

RED-first control: node --test scripts/pipefail-early-exit.test.mjs reported exactly 26 non-accepted runtime/general sites, including install.sh:312, and exited 1. A checked-in fixture generated from immutable baseline df4c591a records all 26 normalized sites; the control passes every fixture entry through the same scanner, asserts exact identity/count/uniqueness, and separately requires zero findings in the current tree. It also inventories accepted sites rather than silently excluding whole files.

Construction choices:

  • here-string/file redirection for scalar grep assertions;
  • full capture then parameter expansion for first-line selection;
  • arrays/mapfile for complete populations;
  • direct jq/awk/grep selection where one tool can express the property;
  • no || true added to a load-bearing assertion.

Site-by-site verdicts: docs/reports/quality/1099-pipefail-sweep.md.

Tranche 2 TDD

Expanded the unconditional scanner over 11 non-wake test harnesses. RED named exactly 22 source lines; a second immutable-baseline fixture now asserts those 22 entries through the same scanner. Rewrites preserve command status by capturing producers before redirected assertions, use parameter expansion for line selection, and use complete mapfile populations where ordering matters. Current-tree finding count is zero for tranches 1 and 2.

Tranche 3 TDD

Expanded the shared scanner over four wake validation harnesses. RED named 26 occurrences. The wake fixture asserts 26 occurrences / 25 normalized identities through the same scanner; all scalar assertions now use redirection, direct jq selection, complete capture, or consuming diagnostic ranges. Current-tree finding count is zero across the full scoped population.

Verification so far

  • bash -n on every changed shell script: pass.
  • structural Node control: pass.
  • test-mutate-push-guard.sh: 8/8 pass.
  • test-send-message-verdict.sh: 3/3 pass.
  • test-send-message-socket.sh: pass.
  • Independent review 143 found two semantic regressions: a help-probe || true changed the failure truth table, and an unguarded Git capture changed non-Git data-dir behavior from rc 0 + JSON to silent rc 128. Both received RED-first regressions before correction; help status is now separate and required, and Git status remains condition-guarded.
  • Wake static inventory remains aligned at 261/261 after line-neutral rewrites; no static-set mismatch. Wake detector/reconcile/digest/preimage suites terminate at their existing fail-closed #973 BASH_LINENO environment probe (exit 97, observed [3 5], expected [3 4]) before subject tests. No bypass or skip was used; canonical CI remains required.
  • ShellCheck reports only pre-existing source-following, unused-variable, and untouched ls | head findings; no new diagnostic was introduced.