Implements W2 of the wake/heartbeat canon (EPIC #892) — the durable-queue "heart" — honoring the CONVERGED-DESIGN contracts exactly.
Piece → contract map
A2 store.sh — three-cursor durable store + drain lib
§1.2 three-cursor data-flow.observed_seq (detector-assigned monotonic int; this lib records/stores it) is the authoritative cursor; the durable pending-inbox retains until CONSUMED; consumed_seq advances over a contiguous prefix.
§2.4 cursor semantics.observed_seq is authoritative; source SHAs are descriptors, not the cursor. consumed_seq NEVER advances on enqueue / sender exit-0 / pane-paste — only on a consumer CONSUMED ack.
§2.3 classes & durability.class=digestREPLACES the pending cumulative-state entry (newest subsumes prior); actionable/humanAPPEND (never replaced). ALL classes land in the durable store — durability is never bypassed. Absent class ⇒ treated as actionable (fail-safe).
Durable entry = {observed_seq, locators, class, emit_ts, hmac}; hmac is an unsigned placeholder (HMAC signing is W3/A5, out of W2 scope).
drain returns the deliverable set (WHAT to deliver; actual paste via existing send-message.sh is out of scope), gated on an optional idle predicate.
Every state mutation is atomic write-tmp+rename (write temp in-dir → mv rename); all state under XDG (${XDG_STATE_HOME:-$HOME/.local/state}/mosaic/wake/).
A4 ack.sh — RECEIVED / CONSUMED ack-wrapper (§2.2)
RECEIVED records delivery; wake_iddedups DELIVERY only (dup delivery = re-RECEIVE, never re-action); never advances consumed_seq.
CONSUMED N is LOCAL-WRITE-ONLY to the XDG ledger, cumulative, and enforces the contiguous gapless prefix (rejects ack N while N-1 is unconsumed). A background sync ships the ack — the ack path never blocks on the network; the sync runs once and records an outage marker (no retry spam).
embed emits the one copy-run line meant to be embedded in each digest.
Watch-list SCHEMA contract + Gate B manifest
framework/defaults/wake-watch-list.schema.json — repos, board files, lane anchors, per-class SLOs, source-parity watches inventory; SCHEMA only (operator supplies values), with schema_version.
framework/tools/wake/manifest.txt — component semver + supported schema range (schema_min/schema_max) as Gate B. It is VERSION metadata only; path-ownership stays with framework-manifest.txt (Gate A) — the new paths are already framework-owned via the existing tools/** and defaults/** globs, so no ownership edit was needed.
RED-first evidence
Harness framework/tools/wake/test-wake-store-ack.sh, wired into test:framework-shell. Each invariant was proven to go RED when its contract point is mutated:
Test
Invariant
Mutation → RED
T1
three-cursor advancement
enqueue also writes consumed_seq → "consumed_seq must NOT advance on enqueue"
T2
digest coalesce-REPLACE vs actionable-APPEND
digest APPENDs → "digest must COALESCE to a single pending entry, got 2"
T3
contiguous-prefix CONSUMED
drop gap guard → "CONSUMED 3 must be REJECTED while seq 2 is a gap"
T4
wake_id delivery-dedup
dedup always false → "duplicate delivery should be DUP, got 'RECEIVED'"
T5/T5b
atomic write-tmp+rename crash-safety
_atomic_write → direct write → "target corrupted by a killed mid-write"
T6
durability survives restart
human class bypasses store → "human must APPEND / stay durable, got 0"
T7
ack local-write never blocks on network
run sync foreground → "ack path blocked 3s"
A real bug was caught RED-first during development: jq -e over an empty ledger returns exit 0, so the initial wake_id dedup false-positived on the first delivery (T4) — fixed to a count-based slurp check.
Implements **W2** of the wake/heartbeat canon (EPIC #892) — the durable-queue "heart" — honoring the CONVERGED-DESIGN contracts exactly.
## Piece → contract map
### A2 `store.sh` — three-cursor durable store + drain lib
- **§1.2 three-cursor data-flow.** `observed_seq` (detector-assigned monotonic int; this lib records/stores it) is the authoritative cursor; the durable **pending-inbox** retains until CONSUMED; `consumed_seq` advances over a contiguous prefix.
- **§2.4 cursor semantics.** `observed_seq` is authoritative; source SHAs are descriptors, not the cursor. `consumed_seq` NEVER advances on enqueue / sender exit-0 / pane-paste — only on a consumer CONSUMED ack.
- **§2.3 classes & durability.** `class=digest` **REPLACES** the pending cumulative-state entry (newest subsumes prior); `actionable`/`human` **APPEND** (never replaced). **ALL** classes land in the durable store — durability is never bypassed. Absent class ⇒ treated as `actionable` (fail-safe).
- **Durable entry** = `{observed_seq, locators, class, emit_ts, hmac}`; `hmac` is an **unsigned placeholder** (HMAC signing is W3/A5, out of W2 scope).
- **drain** returns the deliverable set (WHAT to deliver; actual paste via existing send-message.sh is out of scope), gated on an optional idle predicate.
- Every state mutation is **atomic write-tmp+rename** (write temp in-dir → `mv` rename); all state under XDG (`${XDG_STATE_HOME:-$HOME/.local/state}/mosaic/wake/`).
### A4 `ack.sh` — RECEIVED / CONSUMED ack-wrapper (§2.2)
- **RECEIVED** records delivery; `wake_id` **dedups DELIVERY only** (dup delivery = re-RECEIVE, never re-action); never advances `consumed_seq`.
- **CONSUMED N** is **LOCAL-WRITE-ONLY** to the XDG ledger, **cumulative**, and enforces the **contiguous gapless prefix** (rejects ack N while N-1 is unconsumed). A **background sync** ships the ack — the ack path **never blocks on the network**; the sync runs **once** and records an outage marker (no retry spam).
- `embed` emits the one copy-run line meant to be embedded in each digest.
### Watch-list SCHEMA contract + Gate B manifest
- `framework/defaults/wake-watch-list.schema.json` — repos, board files, lane anchors, per-class SLOs, source-parity `watches` inventory; **SCHEMA only** (operator supplies values), with `schema_version`.
- `framework/tools/wake/manifest.txt` — component semver + supported schema **range** (`schema_min`/`schema_max`) as **Gate B**. It is **VERSION metadata only**; path-ownership stays with `framework-manifest.txt` (Gate A) — the new paths are already framework-owned via the existing `tools/**` and `defaults/**` globs, so no ownership edit was needed.
## RED-first evidence
Harness `framework/tools/wake/test-wake-store-ack.sh`, wired into `test:framework-shell`. Each invariant was proven to go **RED** when its contract point is mutated:
| Test | Invariant | Mutation → RED |
|---|---|---|
| T1 | three-cursor advancement | enqueue also writes `consumed_seq` → "consumed_seq must NOT advance on enqueue" |
| T2 | digest coalesce-REPLACE vs actionable-APPEND | digest APPENDs → "digest must COALESCE to a single pending entry, got 2" |
| T3 | contiguous-prefix CONSUMED | drop gap guard → "CONSUMED 3 must be REJECTED while seq 2 is a gap" |
| T4 | wake_id delivery-dedup | dedup always false → "duplicate delivery should be DUP, got 'RECEIVED'" |
| T5/T5b | atomic write-tmp+rename crash-safety | `_atomic_write` → direct write → "target corrupted by a killed mid-write" |
| T6 | durability survives restart | human class bypasses store → "human must APPEND / stay durable, got 0" |
| T7 | ack local-write never blocks on network | run sync foreground → "ack path blocked 3s" |
A real bug was caught RED-first during development: `jq -e` over an empty ledger returns exit 0, so the initial `wake_id` dedup false-positived on the first delivery (T4) — fixed to a count-based slurp check.
## Gates
- `shellcheck` clean on all four scripts.
- `verify-sanitized.sh` passes; operator firewall `grep -niE 'jason|woltje|jarvis'` = 0.
- Full `pnpm test:framework-shell` passes end-to-end with the harness wired in as the final step.
- `prettier --check` passes on the schema + package.json (no TS changed).
## Out of W2 scope (not built)
detector (W4), digest renderer/HMAC signer (W3), FN-oracle/reconciler (W5), beacon (W6), installer (W7).
Part of #892
Implements W2 of the wake/heartbeat canon (EPIC #892), honoring the
CONVERGED-DESIGN contracts exactly.
A2 store.sh — three-cursor durable queue (§1.2/§2.3/§2.4):
- observed_seq authoritative monotonic cursor (detector assigns, lib records);
SHAs are descriptors, not the cursor.
- durable pending-inbox {observed_seq, locators, class, emit_ts, hmac}; hmac is
an UNSIGNED placeholder (signing is W3/A5).
- consumed_seq advances ONLY on a CONSUMED ack over a CONTIGUOUS gapless prefix
<=N; never on enqueue/exit-0/paste.
- coalesce: digest REPLACES the pending cumulative-state entry; actionable/human
APPEND; ALL classes durable (durability never bypassed); absent class => actionable.
- drain returns the deliverable set; every mutation is atomic write-tmp+rename.
A4 ack.sh — RECEIVED/CONSUMED wrapper (§2.2):
- RECEIVED dedups DELIVERY via wake_id (dup = re-RECEIVE, never re-action).
- CONSUMED N local-write-only to the XDG ledger, cumulative, gapless-prefix
enforced; background sync ships the ack (never blocks on network).
- `embed` prints the one copy-run line a digest embeds.
Watch-list SCHEMA contract (defaults/wake-watch-list.schema.json) with
schema_version; wake manifest.txt declares component semver + supported schema
range (schema_min/schema_max, Gate B — version metadata only, NOT path ownership).
RED-first shell harness wired into test:framework-shell covers each invariant
(three-cursor, coalesce-vs-append, contiguous-prefix CONSUMED, wake_id dedup,
atomic tmp+rename crash-safety, durability-across-restart, ack-never-blocks-on-net).
shellcheck clean; sanitization gate + operator firewall pass.
Part of #892
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0158NZqN2n2ymKFeJAZ4GUCb
Record of Review — PR #903 W2 (wake store+ack+schema) AFTER union-rebase — full-40, supersedes prior
VERDICT: APPROVE (GO on CI terminal-green). Substance reviewer:a9dead50 (opus, all 8 contract criteria PASS vs CONVERGED-DESIGN §1.2/2.2/2.3/2.4; red-first T1-T7 reproduced; ack never-blocks-net verified). ≠ builder (mosaic-coder). REVIEWED-HEAD (full-40):7575d42f011c2b9a82dd96d68c3340e0ddd58a55. Delta re-review (rebase) — PASS:git diff 0f1a37ed 7575d42f -- tools/wake/ defaults/wake-watch-list.schema.json = EMPTY (W2 contract code BYTE-UNCHANGED). The only change from the substance-reviewed head is the git merge origin/main bringing #901 + the package.json UNION-resolution of the test:framework-shell line — keeps BOTH agent-send.test.sh (#901) AND wake/test-wake-store-ack.sh (this PR); neither dropped. Builder verified full chain green (agent-send 18/18 + wake 8-groups) + prettier clean. mergeable=true. ★ CONSUMED gap semantics RATIFIED (reviewer + coordinator): gapless-contiguous-prefix over observed seqs = §1.2 contiguous-prefix + §2.2 cumulative-batch; strict one-at-a-time would CONTRADICT §2.2. Coalescing does not create false gaps (observed.set covers all classes). No change. GO for id-11 at FULL-40 7575d42f011c2b9a82dd96d68c3340e0ddd58a55 on CI terminal-green. Part of #892. Non-executor.
# Record of Review — PR #903 W2 (wake store+ack+schema) AFTER union-rebase — full-40, supersedes prior
**VERDICT: APPROVE** (GO on CI terminal-green). **Substance reviewer:** `a9dead50` (opus, all 8 contract criteria PASS vs CONVERGED-DESIGN §1.2/2.2/2.3/2.4; red-first T1-T7 reproduced; ack never-blocks-net verified). ≠ builder (`mosaic-coder`).
**REVIEWED-HEAD (full-40):** `7575d42f011c2b9a82dd96d68c3340e0ddd58a55`.
**Delta re-review (rebase) — PASS:** `git diff 0f1a37ed 7575d42f -- tools/wake/ defaults/wake-watch-list.schema.json` = EMPTY (W2 contract code BYTE-UNCHANGED). The only change from the substance-reviewed head is the `git merge origin/main` bringing #901 + the package.json UNION-resolution of the `test:framework-shell` line — keeps BOTH `agent-send.test.sh` (#901) AND `wake/test-wake-store-ack.sh` (this PR); neither dropped. Builder verified full chain green (agent-send 18/18 + wake 8-groups) + prettier clean. mergeable=true.
**★ CONSUMED gap semantics RATIFIED** (reviewer + coordinator): gapless-contiguous-prefix over observed seqs = §1.2 contiguous-prefix + §2.2 cumulative-batch; strict one-at-a-time would CONTRADICT §2.2. Coalescing does not create false gaps (observed.set covers all classes). No change.
**GO for id-11 at FULL-40 `7575d42f011c2b9a82dd96d68c3340e0ddd58a55` on CI terminal-green. Part of #892. Non-executor.**
Ghost
approved these changes 2026-07-25 23:58:07 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Implements W2 of the wake/heartbeat canon (EPIC #892) — the durable-queue "heart" — honoring the CONVERGED-DESIGN contracts exactly.
Piece → contract map
A2
store.sh— three-cursor durable store + drain libobserved_seq(detector-assigned monotonic int; this lib records/stores it) is the authoritative cursor; the durable pending-inbox retains until CONSUMED;consumed_seqadvances over a contiguous prefix.observed_seqis authoritative; source SHAs are descriptors, not the cursor.consumed_seqNEVER advances on enqueue / sender exit-0 / pane-paste — only on a consumer CONSUMED ack.class=digestREPLACES the pending cumulative-state entry (newest subsumes prior);actionable/humanAPPEND (never replaced). ALL classes land in the durable store — durability is never bypassed. Absent class ⇒ treated asactionable(fail-safe).{observed_seq, locators, class, emit_ts, hmac};hmacis an unsigned placeholder (HMAC signing is W3/A5, out of W2 scope).mvrename); all state under XDG (${XDG_STATE_HOME:-$HOME/.local/state}/mosaic/wake/).A4
ack.sh— RECEIVED / CONSUMED ack-wrapper (§2.2)wake_iddedups DELIVERY only (dup delivery = re-RECEIVE, never re-action); never advancesconsumed_seq.embedemits the one copy-run line meant to be embedded in each digest.Watch-list SCHEMA contract + Gate B manifest
framework/defaults/wake-watch-list.schema.json— repos, board files, lane anchors, per-class SLOs, source-paritywatchesinventory; SCHEMA only (operator supplies values), withschema_version.framework/tools/wake/manifest.txt— component semver + supported schema range (schema_min/schema_max) as Gate B. It is VERSION metadata only; path-ownership stays withframework-manifest.txt(Gate A) — the new paths are already framework-owned via the existingtools/**anddefaults/**globs, so no ownership edit was needed.RED-first evidence
Harness
framework/tools/wake/test-wake-store-ack.sh, wired intotest:framework-shell. Each invariant was proven to go RED when its contract point is mutated:consumed_seq→ "consumed_seq must NOT advance on enqueue"_atomic_write→ direct write → "target corrupted by a killed mid-write"A real bug was caught RED-first during development:
jq -eover an empty ledger returns exit 0, so the initialwake_iddedup false-positived on the first delivery (T4) — fixed to a count-based slurp check.Gates
shellcheckclean on all four scripts.verify-sanitized.shpasses; operator firewallgrep -niE 'jason|woltje|jarvis'= 0.pnpm test:framework-shellpasses end-to-end with the harness wired in as the final step.prettier --checkpasses on the schema + package.json (no TS changed).Out of W2 scope (not built)
detector (W4), digest renderer/HMAC signer (W3), FN-oracle/reconciler (W5), beacon (W6), installer (W7).
Part of #892
Record of Review — PR #903 W2 (wake store+ack+schema) AFTER union-rebase — full-40, supersedes prior
VERDICT: APPROVE (GO on CI terminal-green). Substance reviewer:
a9dead50(opus, all 8 contract criteria PASS vs CONVERGED-DESIGN §1.2/2.2/2.3/2.4; red-first T1-T7 reproduced; ack never-blocks-net verified). ≠ builder (mosaic-coder).REVIEWED-HEAD (full-40):
7575d42f011c2b9a82dd96d68c3340e0ddd58a55.Delta re-review (rebase) — PASS:
git diff 0f1a37ed 7575d42f -- tools/wake/ defaults/wake-watch-list.schema.json= EMPTY (W2 contract code BYTE-UNCHANGED). The only change from the substance-reviewed head is thegit merge origin/mainbringing #901 + the package.json UNION-resolution of thetest:framework-shellline — keeps BOTHagent-send.test.sh(#901) ANDwake/test-wake-store-ack.sh(this PR); neither dropped. Builder verified full chain green (agent-send 18/18 + wake 8-groups) + prettier clean. mergeable=true.★ CONSUMED gap semantics RATIFIED (reviewer + coordinator): gapless-contiguous-prefix over observed seqs = §1.2 contiguous-prefix + §2.2 cumulative-batch; strict one-at-a-time would CONTRADICT §2.2. Coalescing does not create false gaps (observed.set covers all classes). No change.
GO for id-11 at FULL-40
7575d42f011c2b9a82dd96d68c3340e0ddd58a55on CI terminal-green. Part of #892. Non-executor.GO — Gate-16 id-11 stamp, pinned to exact FULL head
7575d42f01. Basis: verbatim RoRs — substance APPROVE a9dead50 (all 8 contract criteria vs CONVERGED-DESIGN §1.2/2.2/2.3/2.4, red-first T1-T7 independently reproduced) + delta re-review 18877 (union-rebase: contract code byte-unchanged, package.json unions BOTH test entries). CONSUMED gapless-contiguous-prefix semantics RATIFIED (builder/Mos/reviewer concordant). CI terminal-green at head. W2 of EPIC #892 — the wake-canon heart. Named executor: Mos (id-11), squash pinned.