Skip to content

CHECK 6 — disposition integrity for the position ledger

ops/tool-proposals/validate_ledger.py.proposed (off every deploy path). Decision record: 2026-09-30:ledger-check6-proposal, approval: pending.

Why this exists

On 2026-09-30 the owner struck one record from position-ledger.jsonl — the second, invalid exit for nvda-220-straddle-261002 (the 9/28 kill-check row that had been transiently mislabelled EXIT, yielding exit marks of a structure already dead since 9/25; proposal 2026-09-30:ledger-strike-nvda-dup-exit). The owner had to be the guard: the validator returned exit 0 / 0 violations on the ledger with that record present, and exit 0 again after it was struck. A defect that leaves no trace in the validator is a defect class, not an incident.

The measurement (proof: proof-2026-09-30-check6/)

shadow_check6.py, run 2026-09-30 against the real ledger and its pre-strike backup:

[A] DEPLOYED validator on the real ledger: exit 0  (0 violation(s))
[B] DEPLOYED validator on the PRE-STRIKE ledger (struck record re-inserted, 59 records): exit 0
[D] duplicate-exit rule fires on the pre-strike state: True  (flags nvda-220-straddle-261002)

and the proposed file, same two states:

[1] proposed on the CURRENT ledger        : exit 0   0 violation(s)   (stdout byte-identical to deployed)
[2] proposed on the PRE-STRIKE state      : exit 1   1 violation(s)
[3] proposed --selftest                   : duplicate-exit rejected=True single-exit accepted=True

So the check is gating-neutral on today's ledger (identical stdout, identical exit code) and catches the class that actually happened (fault injection: the struck record re-inserted is rejected).

The rule, and the part that needed a measurement rather than a guess

Two shapes, deliberately treated differently:

  1. More than one exit for a position — always an error. One position cannot exit twice; if two exits exist, one was derived from a row that was not an exit. This is mechanically derivable and carried no ambiguity, so it fails the run.
  2. open coexisting with an exit/resolve — reported, not failed. The naive form of this rule flags seven positions on the current ledger (nvda-220, nvda-2275, pcg-14, spy-675-685p, spy-740-765p, spy-765, tlt-82) because the ledger records an entry and a closure and carries no disposition field — coexistence is the normal shape of a position's history, not a defect. Failing it would have lit up seven legitimate positions and trained readers to ignore the check entirely (the failure mode this ledger's checks are written to avoid).

The ruling that gives shape 2 a home: a confirm-integral record — an owner/entry determination that a position's disposition is integral. The absence of that disposition is the error class; its presence licenses the coexistence. No such record exists in the ledger today, so the ruled check and the naive check are identical in effect on the current file - which is why the shape-2 half is emitted as NOTE … ambiguous, not failed on stderr rather than as a violation, until the owner introduces the record type. That is a deliberate, stated ceiling, not an oversight: raising it to a violation would break seven green positions on deploy.

Scope and non-goals

  • Additive only. Checks 0–5 are untouched; the module's documented behaviour on the current ledger is byte-identical (proven in [4] above).
  • No schema change, no new record type authored here. confirm-integral is named as the ruling's home; adopting it is a separate owner decision, and this proposal works without it.
  • Not a repair tool. It detects; corrections remain append-only correct records.
  • The strike is unrelated to this file. The struck record is already gone; this check would have prevented the need for the exception, and does not re-open it.

Base and application

  • Base: the lead-surface copy, hermes-pilot/validate_ledger.py (that is the file that actually runs; the repo copy at ops/ is the versioned mirror). The proposal was produced by copying that file and patching it — never retyped — so unrelated lines cannot drift.
  • On approval: apply to BOTH surfaces (hermes-pilot/validate_ledger.py + the ops/ mirror), re-run --selftest and the 4-state proof in place, commit, and file the apply record.

What this does NOT do

  • Does not fail the run on open+exit coexistence (stated above; would break 7 green positions).
  • Does not validate that marks are fills, or that a disposition is correct — only that an exit history is not self-contradictory.
  • Does not authorize any change to the pilot book, the regime gate, or any cron prompt.

APPLIED 2026-10-01 — with one deviation from the proposal

Owner approval: card AyuMsJ4L8ee4s4o8R, comment "Approve", 2026-10-01. Applied to both surfaces (ocr/podcast/wiki/hermes-pilot/validate_ledger.py in the repo; deployed to ~/src/ocr/podcast/wiki/hermes-pilot/ on hermes — md5 identical, 315ebf15). Apply record: 2026-10-01:ledger-check6-applied.

The deviation, and why it was not cosmetic

The proposed file counted exit records over all rows, with no superseded-record filter — unlike checks 1–3, and against this module's own stated principle that a superseded record is "history in EVERY respect".

The ledger's documented repair for a wrong record is to append a correct record naming it. So repairing a bad exit — supersede it, append the corrected one — leaves two exit records on disk permanently. Measured before application: the proposed version fails that shape forever, and the only escape would be another append-only strike — the exception this check exists to make unnecessary.

This is the same bug class already fixed once in this file: on 2026-09-29, CHECK 1 ran ahead of the superseded exemption and made append-only records permanently unfixable.

7-state proof, run in place against the real ledger and its pre-strike backup

# state result
1 applied, current ledger exit 0 — stdout byte-identical to the deployed validator
2 applied, pre-strike (fault injected) exit 1, names nvda-220-straddle-261002
3 proposed, pre-strike exit 1 — the fix does not weaken detection
4 proposed, append-only exit repair blocks the repair
5 applied, append-only exit repair accepts the repair
6 deployed vs applied, current ledger exit 0 == 0, stdout identical
7 --selftest 3/3

--selftest was extended from two assertions to three, adding append-only-repair accepted, so this regression cannot return silently.

A correction to this note's own shape-2 argument

The argument above for reporting rather than failing open+exit coexistence rests on it flagging seven legitimate positions. With superseded records filtered, it flags one — spy-765-straddle-260918. Six of the seven were counted only because their superseded open records were being read as live, so the "seven" figure was itself an artifact of the missing filter.

The report-don't-fail ceiling is unchanged — that is the owner's ruling, not an implementation detail. But the ceiling could now be revisited against one position rather than seven, which is a materially easier decision than the one this note described. The confirm-integral record type remains unadopted and remains a separate owner decision.