# Claims review — 0.2.42

- base: v0.2.41
- head: 3f1e1ac
- surface: sha256:cd23938f0f7bb0b2d82600be062b9d7bd2910b3663fe9f897729b5bd4bc37639
- verdict: pass
- reviewer: maintainer, running the binary rather than reading it — which is
  how the second finding was found and the first review missed it

One surface changed: the `conarium-verify` exit table in
`docs/RECEIPT-SPEC.md`. Two rows. The `2` row is new and is what the release
is for. The `20` row was rewritten during this review, in `3f1e1ac`, because
measuring it made the old text false.

## Findings

### 1. docs/RECEIPT-SPEC.md:191 — a table row is read as a class, and this one holds in only one direction

- Claim: "| 2 | Usage error — no receipt was read |"
- Mechanism: `bin/conarium-verify.mjs:428` and `:432` exit 2 on a `parseArgs`
  throw and on a missing target. `test/verify_usage_exit.mjs` asserts an
  unknown flag and a missing path are not 20, and that vector 007 still is.
- Why it falls short: the sentence is true of 2. An exit-code table is read as
  a partition, so a reader also takes the converse — no receipt read, therefore
  2 — and the converse is false in the same binary. Measured, all with a valid
  key: `--file x` → 2, no arguments → 2, `missing.jsonl` → **20**, no
  `--pubkey` → **13**. Two of the four ways to hand this tool nothing it can
  verify still answer inside the verdict range.
- Disposition: accepted, and answered in the `20` row rather than by weakening
  the `2` row, which is accurate. 13 is left alone: omitting `--pubkey` is
  documented fail-closed behaviour that predates this release and reversing it
  would trade a naming defect for a safety one.

### 2. CHANGELOG.md — the release named the remainder of its own defect, and the remainder was larger

- Claim, as written before this review: "The uncaught-exception path at the
  bottom of the file is also still 20; it is not a schema diagnosis, and this
  release does not rename it." Offered as the complete remainder.
- Mechanism: reading `bin/conarium-verify.mjs` for `exit(20)` and `fail(20`,
  which finds the schema call at 521 and the catch at 735.
- Why it falls short: reading finds those two. `loadReceipts` returns
  `{ error: 'path not found', code: 20 }` at line 252 — a literal on a return
  object, not a call the reader's eye was scanning for — and it fires before
  any file is opened. So a release whose entire subject is *a code that names
  an event which did not occur* was published with an incomplete list of the
  places it still does that. The check that caught it was running the command,
  not reading the file, and the first review of this branch did not run it.
- Disposition: corrected in `3f1e1ac` before publish, in both the changelog and
  the table. **The behaviour is unchanged and 0.2.42 does not fix it.** Whether
  an unreachable target is a usage error, a verdict, or a third code is a
  decision about the exit-code contract; making it in the last hour of the
  release that found it is how the contract acquires a fourth meaning for a
  number. It is named in the document where a reader can measure it.

## Not a finding, recorded so the next reader does not re-derive it

An empty directory is exit **0**. Measured: `conarium-verify <empty dir>
--pubkey <key>` prints `warning: empty chain (0 receipts) — this is not a
verification that nothing was deleted` and exits 0.

This is the shape the spec already argues about elsewhere. Its own note on
`--anchor-check` says: "The summary line always printed `0/N anchored`; the
exit code was the part that claimed more than was examined, and the exit code
is what a machine reads." The empty chain is that sentence with the nouns
swapped — stderr names the limit, the exit code does not, and a machine reads
the exit code. It differs from 0.2.40 in one way that matters: the warning is
unconditional and says exactly what was not established, where `--anchor-check`
printed a number and left the reader to infer it.

Not raised as a finding because it is not on this diff's surface and the
remedy is the same open contract decision as finding 2. Recorded because it is
the third instance of one class in three releases, and the next person to open
this file should be told that before they find it a fourth time.

`conarium-coverage`, `conarium-reconcile` and `conarium-stamp` still exit 20 on
usage errors. They were measured in this cycle and deliberately not changed;
the changelog says so.
