fix(wake): #946 digest ack watermark clamped at quarantined seqs — disclose AND clamp
ci/woodpecker/pr/ci Pipeline was successful

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
This commit is contained in:
Jason Woltje
2026-07-30 10:10:21 -05:00
co-authored by Claude Fable 5
parent a6b5f6a01a
commit e11bc66223
6 changed files with 631 additions and 13 deletions
+66 -3
View File
@@ -112,6 +112,14 @@ Exit codes:
diagnostic (#924/G2a) — it never wedges the whole render either.
Reconciler enumerations (locators.reconciled==true) render ORIENTATION-tier,
gate-exempt.
#946: quarantined entries are DISCLOSED in a QUARANTINED section (by
seq/class only — content stays excluded) and the embedded ack copy-run
line is CLAMPED below the lowest quarantined seq (the digest never
instructs the consumer to record a delivery that never happened; the
clamp is announced as an ACK CLAMPED note). A store-mode render also
REPLACES the store's quarantined.set (store.sh quarantine-sync) so the
consume path enforces the same clamp; --from-file/--stdin renders never
touch the set.
2 usage error.
3 jq is required but missing.
@@ -544,7 +552,7 @@ cmd_render() {
# #920 head-of-line-blocking defect that exit-4'd the entire cumulative-state
# drain). Reconciler enumerations (locators.reconciled==true) are ORIENTATION-
# tier and gate-exempt, so they pass straight through to the deliverable set.
local line loc seq pending_ok='' quarantined=0
local line loc seq pending_ok='' quarantined=0 q_seqs='' q_disclose=''
while IFS= read -r line; do
[ -n "$line" ] || continue
printf '%s' "$line" | jq -e . >/dev/null 2>&1 || continue
@@ -554,6 +562,17 @@ cmd_render() {
seq="$(jq -r '.observed_seq // "?"' <<<"$line")"
_quarantine_entry "$line" "$seq"
quarantined=$((quarantined + 1))
# #946: collect the quarantined identity for DISCLOSURE + the ack
# CLAMP. Disclosure is by durable identity (observed_seq) + class ONLY:
# this entry failed the locator gate, so its content is exactly what
# this digest refuses to re-inject (the exclusion property Q1/Q4
# assert) — the consumer re-verifies via the dead-letter ledger, never
# via this line.
case "$seq" in
'' | *[!0-9]*) : ;; # an unnumbered entry cannot clamp the numeric cursor
*) q_seqs="$q_seqs$seq"$'\n' ;;
esac
q_disclose="$q_disclose * seq $seq [$(_scrub_inline "$(jq -r '.class // "actionable"' <<<"$line")")] HELD — dead-lettered (no §2.1 hard locator); content withheld, NOT delivered."$'\n'
continue
fi
fi
@@ -563,6 +582,33 @@ cmd_render() {
pending="$(printf '%s' "$pending_ok" | grep -v '^[[:space:]]*$' || true)"
depth="$(printf '%s\n' "$pending" | grep -c . || true)"
# --- #946: quarantine truth-sync + ack clamp ------------------------------
# (1) SYNC: an AUTHORITATIVE full-set render (src=store) REPLACES the store's
# quarantined.set with THIS render's quarantined seqs (possibly none — an
# empty replace IS the #944 recovery: once the gate is fixed and everything
# renders, the stale set clears and the store-side clamp self-heals). A
# foreign-data render (--from-file/--stdin) must NEVER rewrite lane truth.
if [ "$src" = "store" ]; then
if ! printf '%s' "$q_seqs" | "$STORE_SH" quarantine-sync; then
echo "digest.sh: WARN (#946) — store.sh quarantine-sync FAILED; the store-side consume clamp may be stale for this lane (the clamped ack line rendered below is still correct)." >&2
fi
fi
# (2) CLAMP: the embedded ack may advance AT MOST to just below the LOWEST
# quarantined seq — consume requires a contiguous prefix, so one held seq
# caps everything above it. With nothing quarantined this is the observed
# cursor unchanged. Render-local on purpose: it protects the copy-run line in
# EVERY mode, including hermetic --from-file renders.
local ack_upto="$observed" min_q='' qs q_list=''
while IFS= read -r qs; do
[ -n "$qs" ] || continue
if [ -z "$min_q" ] || [ "$qs" -lt "$min_q" ]; then min_q="$qs"; fi
done <<<"$q_seqs"
if [ -n "$min_q" ] && [ "$((min_q - 1))" -lt "$ack_upto" ]; then
ack_upto=$((min_q - 1))
fi
[ "$ack_upto" -ge 0 ] || ack_upto=0
q_list="$(printf '%s' "$q_seqs" | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')"
# --- render (all validated) ----------------------------------------------
local n_actionable=0
{
@@ -656,6 +702,16 @@ cmd_render() {
printf '%s\n' "$hbody"
fi
# #946: QUARANTINED disclosure — a held entry must be VISIBLE in the digest
# it was held from (five successive live digests each silently stepped the
# consumer past buried seq 68). Disclosure is by seq/class ONLY; the
# entry's content already failed the locator gate and stays EXCLUDED.
if [ -n "$q_disclose" ]; then
printf '\n-- QUARANTINED (dead-lettered; HELD — NOT delivered; the ack below does NOT cover these) --\n'
printf '%s' "$q_disclose"
printf ' disposition: see %s/dead-letter.jsonl — fix the source locator (re-delivery is automatic once the entry passes the gate), or step past EXPLICITLY with ack.sh consumed --force-past-quarantine.\n' "$STATE_DIR"
fi
# Embedded ack copy-run line (W2). CONSUMED is a consumer act; this is the
# exact local-write line the consumer runs after durable capture.
#
@@ -670,12 +726,19 @@ cmd_render() {
# itself was env-less (agent=="default"), baking "default" is no worse than
# today — the fix wins the common case where WAKE_AGENT was set at render.
printf '\n-- ACK (copy-run; local-write only, never blocks on network) --\n'
# #946: the embedded --upto is the CLAMPED cursor (ack_upto), never the raw
# observed cursor while a quarantined seq sits inside (consumed, observed] —
# the copy-run line itself must not instruct the consumer to record
# deliveries that never happened. The clamp is disclosed loudly.
if [ "$ack_upto" -ne "$observed" ]; then
printf '# ACK CLAMPED (#946): embedding --upto %s, not observed_seq %s — quarantined seq(s) %s were dead-lettered and NEVER delivered; an ordinary ack cannot step past them. Only ack.sh consumed ... --force-past-quarantine (loud) can.\n' "$ack_upto" "$observed" "$q_list"
fi
local ack_line agent_scrubbed
agent_scrubbed="$(_scrub_inline "$agent")"
if [ -n "$wake_id" ]; then
ack_line="$("$ACK_SH" embed --upto "$observed" --agent "$agent_scrubbed" --wake-id "$wake_id" 2>/dev/null || true)"
ack_line="$("$ACK_SH" embed --upto "$ack_upto" --agent "$agent_scrubbed" --wake-id "$wake_id" 2>/dev/null || true)"
else
ack_line="$("$ACK_SH" embed --upto "$observed" --agent "$agent_scrubbed" 2>/dev/null || true)"
ack_line="$("$ACK_SH" embed --upto "$ack_upto" --agent "$agent_scrubbed" 2>/dev/null || true)"
fi
printf '%s\n' "${ack_line:-# ack unavailable}"
} | _redact_secrets