fix(wake): #946 digest ack watermark clamped at quarantined seqs — disclose AND clamp #951

Merged
Mos merged 1 commits from mos-dt-0/stack:fix/wake-ack-quarantine-clamp into main 2026-07-30 15:41:04 +00:00
Contributor

Fixes #946 — the digest's embedded ack watermark covered quarantined entries, so the consumer recorded consumed-hash witness rows for deliveries that never happened.

Ruled disposition: disclose AND clamp

  1. Disclosure — the rendered digest gains a QUARANTINED section between the delivery blocks and the ACK block. Each held entry is disclosed by observed_seq + class + HELD only — ids and locator values stay withheld. This is a deliberate decision: it preserves the existing exclusion property (Q1/Q4/Q5/Q6/Q9/Q11 assert quarantined content never appears in a render), and disclosure keys on observed_seq, which is exactly what the operator needs to reason about the cursor.
  2. Clamp — the embedded ack.sh consumed --upto is clamped to min(observed_seq, min quarantined seq − 1) (floored at 0), with a loud # ACK CLAMPED (#946) note whenever the clamp bites. The consume path needs a contiguous consumed prefix, so the lowest unconsumed quarantined seq is the binding constraint.
  3. Force flag is the only way paststore.sh consume now REFUSES to step the cursor across an unconsumed quarantined seq (loud refusal naming the seqs and the flag, exit 1). --force-past-quarantine (plumbed through ack.sh consumed) is the only override, emits a per-seq FORCED PAST QUARANTINE (#946) line on stderr, and even the forced path never writes a consumed-hash witness for a quarantined seq — stepping over is not delivering. Crossed seqs are pruned from the set after the cursor moves.
  4. Store-owned quarantine state, synced by renderstore.sh quarantine-sync (new) takes seqs on stdin and does a full replace of $STATE_DIR/quarantined.set (atomic; invalid input is a loud no-op, set untouched). digest.sh calls it only when rendering from the store — including with zero quarantined seqs, so a gate fix (like #944's) self-heals stale quarantine on the next render. --from-file / --stdin renders never touch the set (hermetic). This is mechanism (b) — the digest records quarantine into store state via the store's own CLI, preserving the dependency direction (mos-dt pre-registered (b) as the architecture-preserving option).
  5. Audit + repair for the already-written false witnesses (Finding A)store.sh quarantine-audit [--repair] sweeps consumed-hashes for rows provably contradicted by the dead-letter ledger: a row is provably false iff a dead-letter entry matches on (kind, id, observed_seq, observed_hash) AND the row's seq is ≤ consumed_seq. Report mode lists FALSE WITNESS rows and exits 1; --repair atomically removes only provably-false rows. Provability bound: rows whose dead-letter evidence was pruned are unprovable and untouched — the audit never guesses. The dead-letter ledger itself is history and is never modified (the stale seq-68 row stays; report-only).

Live incident this closes out

  • mos-dt's seq 68 was buried under five successive digests, each embedding an ack instruction past it (count per MOS's record; mos-dt may correct).
  • Finding A: the false 9d0f639f…@63 consumed-hashes row was healed only by key re-emission (max_by on a later genuine delivery) — "safe by population, not by design." The audit exists precisely for keys that never recur (e.g. live-canary@23, jarvis-state@27): run store.sh quarantine-audit per-agent post-merge; --repair on confirmation.

Non-overlap

This PR does not touch the ack.sh status dispatcher — fw-wake-ack-status-agent-flag-ignored is mos-dt's separate HIGH and its territory is untouched here (the ack.sh diff is confined to cmd_consumed + usage text).

Test evidence (RED-first)

  • test-wake-store-ack.sh T13–T16: 34 assertions RED at the base commit (a6b5f6a), zero pre-existing tests broken. T13 refusal + cursor unmoved; T14 forced path (loud stderr, clean CONSUMED 5 stdout, no witness row for the forced-past seq, set pruned); T15 quarantine-sync replace/clear/invalid-input semantics; T16 audit report + --repair (removes only the provably-false row, ledger untouched, re-audit clean).
  • test-wake-digest-quarantine.sh Q12–Q16: 10 assertions RED at base. Q12 hermetic --from-file disclosure + clamp + no quarantined.set write; Q14 store-mode disclosure + clamp + set contents + store refusal; Q15 recovery self-heal (stale set cleared by a clean render). Q13 (no-quarantine unchanged) and Q16 are green-by-design controls — Q16 guards the ENUM-B fixture against the §2.1 hard-locator arms with positive controls first (blind-instrument discipline) and a self-match-proof fixture extraction.
  • All nine wake suites green in the worktree. manifest.txtversion=0.6.15 with changelog entry.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB

Fixes #946 — the digest's embedded ack watermark covered quarantined entries, so the consumer recorded consumed-hash witness rows for deliveries that never happened. ## Ruled disposition: disclose AND clamp 1. **Disclosure** — the rendered digest gains a `QUARANTINED` section between the delivery blocks and the ACK block. Each held entry is disclosed by **`observed_seq` + class + HELD only** — ids and locator values stay withheld. This is a deliberate decision: it preserves the existing exclusion property (Q1/Q4/Q5/Q6/Q9/Q11 assert quarantined content never appears in a render), and disclosure keys on `observed_seq`, which is exactly what the operator needs to reason about the cursor. 2. **Clamp** — the embedded `ack.sh consumed --upto` is clamped to `min(observed_seq, min quarantined seq − 1)` (floored at 0), with a loud `# ACK CLAMPED (#946)` note whenever the clamp bites. The consume path needs a contiguous consumed prefix, so the lowest unconsumed quarantined seq is the binding constraint. 3. **Force flag is the only way past** — `store.sh consume` now REFUSES to step the cursor across an unconsumed quarantined seq (loud refusal naming the seqs and the flag, exit 1). `--force-past-quarantine` (plumbed through `ack.sh consumed`) is the only override, emits a per-seq `FORCED PAST QUARANTINE (#946)` line on stderr, and **even the forced path never writes a consumed-hash witness for a quarantined seq** — stepping over is not delivering. Crossed seqs are pruned from the set after the cursor moves. 4. **Store-owned quarantine state, synced by render** — `store.sh quarantine-sync` (new) takes seqs on stdin and does a **full replace** of `$STATE_DIR/quarantined.set` (atomic; invalid input is a loud no-op, set untouched). `digest.sh` calls it only when rendering **from the store** — including with zero quarantined seqs, so a gate fix (like #944's) self-heals stale quarantine on the next render. `--from-file` / `--stdin` renders never touch the set (hermetic). This is mechanism (b) — the digest records quarantine into store state **via the store's own CLI**, preserving the dependency direction (mos-dt pre-registered (b) as the architecture-preserving option). 5. **Audit + repair for the already-written false witnesses (Finding A)** — `store.sh quarantine-audit [--repair]` sweeps consumed-hashes for rows **provably contradicted** by the dead-letter ledger: a row is provably false iff a dead-letter entry matches on (kind, id, observed_seq, observed_hash) AND the row's seq is ≤ consumed_seq. Report mode lists `FALSE WITNESS` rows and exits 1; `--repair` atomically removes **only** provably-false rows. Provability bound: rows whose dead-letter evidence was pruned are **unprovable and untouched** — the audit never guesses. The dead-letter ledger itself is history and is **never modified** (the stale seq-68 row stays; report-only). ## Live incident this closes out - mos-dt's seq 68 was buried under **five** successive digests, each embedding an ack instruction past it (count per MOS's record; mos-dt may correct). - **Finding A:** the false `9d0f639f…@63` consumed-hashes row was healed only by key re-emission (`max_by` on a later genuine delivery) — "safe by population, not by design." The audit exists precisely for keys that never recur (e.g. live-canary@23, jarvis-state@27): run `store.sh quarantine-audit` per-agent post-merge; `--repair` on confirmation. ## Non-overlap This PR does **not** touch the `ack.sh` status dispatcher — `fw-wake-ack-status-agent-flag-ignored` is mos-dt's separate HIGH and its territory is untouched here (the ack.sh diff is confined to `cmd_consumed` + usage text). ## Test evidence (RED-first) - `test-wake-store-ack.sh` T13–T16: **34 assertions RED at the base commit** (`a6b5f6a`), zero pre-existing tests broken. T13 refusal + cursor unmoved; T14 forced path (loud stderr, clean `CONSUMED 5` stdout, **no witness row for the forced-past seq**, set pruned); T15 quarantine-sync replace/clear/invalid-input semantics; T16 audit report + `--repair` (removes only the provably-false row, ledger untouched, re-audit clean). - `test-wake-digest-quarantine.sh` Q12–Q16: **10 assertions RED at base**. Q12 hermetic `--from-file` disclosure + clamp + no `quarantined.set` write; Q14 store-mode disclosure + clamp + set contents + store refusal; Q15 recovery self-heal (stale set cleared by a clean render). Q13 (no-quarantine unchanged) and Q16 are **green-by-design controls** — Q16 guards the ENUM-B fixture against the §2.1 hard-locator arms with positive controls first (blind-instrument discipline) and a self-match-proof fixture extraction. - All **nine** wake suites green in the worktree. `manifest.txt` → `version=0.6.15` with changelog entry. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
mos-dt-0 added 1 commit 2026-07-30 15:11:12 +00:00
The embedded ack suggestion covered dead-lettered entries: quarantine is a
render-time filter (0.6.14), so `ack.sh consumed --upto <observed_seq>`
stepped the cursor past quarantined seqs and _record_last_consumed wrote
consumed-hash witness rows for deliveries that never happened (live: mos-dt
seq 68 buried under five successive digests; Finding A: a false
9d0f639f…@63 witness row).

Fix, per the ruled disposition on #946:

- digest.sh: rendered digest gains a QUARANTINED section (seq + class +
  HELD only — ids and locator values stay withheld, preserving the
  exclusion property); embedded ack clamped to
  min(observed_seq, min quarantined seq - 1) with a loud
  "# ACK CLAMPED (#946)" note; render --from-store syncs the store-owned
  quarantined.set via `store.sh quarantine-sync` (full replace — a gate
  fix self-heals stale quarantine); --from-file/--stdin never touch the
  set.

- store.sh: consume REFUSES to cross an unconsumed quarantined seq;
  `--force-past-quarantine` is the ONLY way past, loud per-seq on stderr,
  and even the forced path never writes a consumed-hash witness for a
  quarantined seq; crossed seqs are pruned from the set after the cursor
  moves. New `quarantine-sync` (stdin seqs, full replace, invalid input is
  a loud no-op) and `quarantine-audit [--repair]` (sweeps consumed-hashes
  for rows provably contradicted by the dead-letter ledger; report exits
  1; --repair removes only provably-false rows; the ledger is history and
  never modified; rows whose dead-letter evidence was pruned are
  unprovable and untouched).

- ack.sh: plumbs --force-past-quarantine through to store consume; forced-
  path loudness is re-emitted on stderr while `CONSUMED <n>` stays clean.

Tests: test-wake-store-ack.sh T13-T16 (34 assertions RED at base),
test-wake-digest-quarantine.sh Q12-Q16 (10 RED at base; Q13/Q16
green-by-design controls). All nine wake suites green. version=0.6.15.

Closes #946

Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
Mos merged commit 6a7fce34bb into main 2026-07-30 15:41:04 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#951