Gate fault-arm audit: what remains

Lane gate-marker-audit on yonatangross/orchestkit. Snapshot generated 2026-09-06 12:43. Every number marked MEASURED was printed by a probe or a suite on this machine; CLAIMED means read from code or a screenshot, not executed.

68
gates exercised, two arms each
37
FAILS OPEN, fixed on this branch
26
SOUND at HEAD
2 + 1
by design (labelled) + filed #3937
2
NOT EXERCISED (lychee, claude -p)

1. The shape, before and after

The #3933 shape: a gate whose "nothing found" result is byte-identical to "checked and clean". Every consumer reads the empty result as pass. The fix is the same everywhere: assert the input exists and is non-empty before judging it.

Before (35 gates)

flowchart LR
  A["input absent: empty dir, empty JSON file, failed fetch, wrong path"] --> B["loop never iterates, or a guard short-circuits"]
  B --> C["counter stays 0"]
  C --> D{"failures == 0 ?"}
  D -->|yes| E["PASSED: All 0 skills ... exit 0"]
  style E fill:#3a1d1d,stroke:#f85149,color:#fff
  style A fill:#1d2230,stroke:#58a6ff,color:#fff

After (this branch)

flowchart LR
  A["input absent"] --> B["loop never iterates"]
  B --> C["counter stays 0"]
  C --> F{"scanned == 0 ?"}
  F -->|yes| G["FAIL: zero X found, nothing was checked, exit 1"]
  F -->|no| D{"failures == 0 ?"}
  D -->|yes| E["PASSED with N above 0"]
  style G fill:#1d3a24,stroke:#3fb950,color:#fff
  style E fill:#1d3a24,stroke:#3fb950,color:#fff
  style A fill:#1d2230,stroke:#58a6ff,color:#fff

Five shapes found, by count

pie showData title FAILS OPEN by mechanism (37)
  "loop never iterates, N=0 passes" : 22
  "presence guard turns absence into skip" : 7
  "swallowed failure read as empty result" : 5
  "jq | while subshell drops the fail counter" : 2
  "dead guard (nullglob, path that no longer exists)" : 1

2. Every gate

Columns: control = control-arm exit at HEAD 911cdd8bf; fault before = fault-arm exit at HEAD; fault after = re-run on this branch (MEASURED for every fixed row). Filter by state.

#gatefilecontrolfault beforefault afterstatepass condition (why it passed on nothing)

3. Verify latest

This branch (MEASURED)

branch: feat/gate-marker-audit
main:   c492d3221 chore(main): release 10.0.0-alpha.81 (#3934)

9a6720fe1 docs(audits): gate fault-arm audit 2026-09-06, plus three last guards
d461c1764 fix(ci): fail 27 more gates on absent input, with paired fault arms
960a09e1c fix(ci): fail three gates that passed on absent input

Paired tests on this branch (MEASURED)

tests/ci/test-run-tests-empty-roster.sh           3 passed, 0 failed
tests/ci/test-check-skill-structure.sh            6 passed, 0 failed
tests/ci/test-audit-skill-claims-blind-sweep.sh   7 passed, 0 failed
tests/manifests/test-fault-arms.sh                10 probes, 0 failed
tests/plugins/test-fault-arms.sh                  6 probes, 0 failed
tests/ci/test-fault-arms.sh                       9 probes, 0 failed
tests/ci/test-workflow-step-fault-arms.sh         26 passed, 0 failed
real-repo controls: validate-counts PASSED, sync-skills OK,
  lint.sh 6/6, check-workflow-gates OK, index-generation OK,
  stamp-counts --check OK, eval:static rc 0, actionlint clean

Suite and CI

npm test --quick: IN PROGRESS at render time (48 passed, 2 failed so far)
CI on the PR: not opened yet at render time (waits on the suite line)
main moved to alpha.81 (c492d3221) while this ran; no file overlap, rebase pending

Still CLAIMED, not measured

  • scripts/parity-check.py zero-event guard: needs the npm dist build plus a pip install.
  • run-restricted-smoke.sh zero-row guard: spawns a real claude -p.
  • readme-link-audit.yml: lychee not installed; unset step output coerces to 0 (reads clean).

4. What remains: milestone board and the path through it

From the milestones page (CLAIMED from the screenshot, 10 open, 124 closed) plus gh issue list per milestone (MEASURED). The recommendation is to close the two near-complete milestones before touching the four opened on 2026-09-02.

flowchart TD
  PR["this PR: 37 gates fail closed, audit doc, paired arms"] --> E3306["issue 3306 EPIC A: DELETE what never ran"]
  PR --> I3937["issue 3937 validate-all.sh orphan: delete or fix"]
  I3937 --> E3306
  E3306 --> V10["v10.0.0 Convergence: 3 open, goes to 2"]
  I3448["issue 3448 brainstorm loses teammate research on timeout"] --> V10
  I3424["issue 3424 sandbox loose-first: a decision, not code"] --> V10
  I1848["issue 1848 wire claude agents cwd into ork dev"] --> CC["CC adoption: 1 open, closes"]
  V10 --> NEW["four 09-02 milestones: Sales, Glyph docs, page serve, Commerce. 0 of 9 done, hold until v10 closes"]
  H["Hook and Agent Quality: 8 open"] --> H1["issue 3493 git-validator remediation bug"]
  H --> H2["issue 3000 seed quality-index baseline"]
  H --> H3["6 enhancement items: park"]
  style PR fill:#1d3a24,stroke:#3fb950,color:#fff
  style V10 fill:#1d2230,stroke:#58a6ff,color:#fff
  style CC fill:#1d2230,stroke:#58a6ff,color:#fff
  style NEW fill:#3a2d1d,stroke:#d29922,color:#fff
  style H3 fill:#2a2f3a,stroke:#9aa3b2,color:#ddd
rankmilestoneopenclosedwhat actually closes itsize
1v10.0.0 Convergence and Correctness3118#3306 (this PR feeds it), #3448 (bug), #3424 (a written decision)1 PR + 1 bug + 1 call
2CC adoption1371#1848, one wiring PR into /ork:dev1 PR
3Hook and Agent Quality842#3493 bug, #3000 gate; the other six are research enhancements2 PRs, park 6
holdMemory 9 / Docs 16 / Video 83336no charter change; Video is 2 months overdue and deferred by its own descriptionre-scope or close
holdSales, Glyph docs, page serve, Commerce (opened 09-02)90nothing until v10 closes; four fresh 0% milestones in one day is how the middle tier got to 33 opensequence after v10

5. Follow-ups found by the audit, outside this PR

DECIDE
  1. #3937: delete validate-all.sh (recommended) or repair and wire it.
  2. After this PR merges: open the #3306 lane next (recommended), or #1848 to close CC adoption first.
  3. Video Gallery milestone: re-scope with a new date, or close as deferred (recommended: close).