* docs(#3889): ADR-3889 — the process-exit contract
Records the decision for epic #3889: one Outcome vocabulary, one pure
projection to an integer, two terminators sharing both.
Doc-only. Regenerates docs/adr/README.md via gen-adr-index.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(#3889): rewrite ADR-3889 as an exit-code registry, on measured evidence
The first draft's census was grep-derived and roughly 2x inflated: it counted
comment prose and also matched process.exitCode, the correct pattern. An AST
census (@typescript-eslint/parser, CallExpression on process.exit) gives 128
deduped call sites, 71% of them in hooks/, against 88 process.exitCode
assignments already in use. scripts/ is effectively migrated (39:1).
Corrects the framing accordingly: the seam (src/cli-exit.cts) already exists
and is already adopted; what is missing is an allocator and a hooks adapter.
Replaces the fixed six-value enum with a registry: 0 and 1 free, 2 reserved to
the Claude Code hook protocol, 3-13 forbidden (Node reserves them), 64+
allocated with one meaning and one owner per code. Domain codes permitted.
Adds three findings obtained by reading and executing the code:
- ui-safety-gate/api-coverage report empty stdin as an authoritative negative
verdict (exit 1) — reproduced with a control
- four modules hand-roll the same three-outcome convention, documented only in
a comment at src/ui-safety-gate.cts:137
- two capability fragments fabricate {"detected":false} on probe failure, while
the honest {"skipped":true,"reason":"sdk-failed"} form already exists in-tree
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: sim <sim@local>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>