← back to Dw Yolo Loop
cycle 79: officer REVISE — harden CNCP wrapper (node JSON.stringify body, smoke-tested http=200, log truncate-on-start) + runbook hbAbs watchdog entries + c78 INCONCLUSIVE-during-shrink nuance; chain+exit confirmed
23c80c1fba91d2034e505d149eda107a5ad762f6 · 2026-06-18 01:46:52 -0700 · Steve Abrams
Files touched
M scripts/canary-install/INSTALL-RUNBOOK.mdM scripts/canary-install/run-canary-with-cncp.sh
Diff
commit 23c80c1fba91d2034e505d149eda107a5ad762f6
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jun 18 01:46:52 2026 -0700
cycle 79: officer REVISE — harden CNCP wrapper (node JSON.stringify body, smoke-tested http=200, log truncate-on-start) + runbook hbAbs watchdog entries + c78 INCONCLUSIVE-during-shrink nuance; chain+exit confirmed
---
scripts/canary-install/INSTALL-RUNBOOK.md | 21 +++++++++++++++++++--
scripts/canary-install/run-canary-with-cncp.sh | 21 +++++++++++++++------
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/scripts/canary-install/INSTALL-RUNBOOK.md b/scripts/canary-install/INSTALL-RUNBOOK.md
index b8273dd..948c22c 100644
--- a/scripts/canary-install/INSTALL-RUNBOOK.md
+++ b/scripts/canary-install/INSTALL-RUNBOOK.md
@@ -60,6 +60,7 @@ launchctl kickstart -k gui/$(id -u)/com.steve.dw-sitemap-integrity # run-now t
1. **Reprice first, then install (simplest):** once the gated reprice clears the 145 + the 8 draft → the canary returns HEALTHY (0) → install it (same §2 steps, but promote the `run-zero-dollar.sh` thin wrapper: `promote-canary.sh dw-zero-dollar "$HOME/Projects/designerwallcoverings/scripts/canary-install/run-zero-dollar.sh" daily 6 20`) → it now guards purely against NEW free-checkout regressions (a future bad import).
2. **Add the set-difference acknowledged-baseline (one code change, a future cycle):** seed the known 145+8 as `{handle,position}` tuples; alert LOUD only on a tuple NOT in the acknowledged set (a NEW exposure) + quiet weekly reminder of the known count. Then it can install immediately and still surface regressions. (Per the c78 officer: must be set-difference, NOT count-delta — a count-delta could mask a new exposure that replaces an acknowledged one.)
- Either way the install mechanics are identical to §2 (promote-canary.sh + wrapper + PlistBuddy + bootstrap).
+- **Nuance (officer):** c78's coverage floor is `MIN_ACTIVE_SCAN=50000`. If the active catalog ever dips near that (e.g. *during* an archive event), c78 flips to INCONCLUSIVE (exit 2, posts a card) — that's the gate refusing to trust a shrunken scan, NOT the free-checkout failure it watches. Read an INCONCLUSIVE card as "scan was incomplete/small," and cross-check the c77 sitemap-integrity crater alarm (the actual population-collapse detector).
## §4 — Disable / uninstall (any guard)
```sh
@@ -67,8 +68,13 @@ launchctl bootout gui/$(id -u)/com.steve.<label>
rm ~/Library/LaunchAgents/com.steve.<label>.plist
```
-## §5 — Heartbeat / meta-watchdog
-Both canaries write `data/latest.json` under their script dir (in addition to `/tmp`) so the existing `dw-canary-meta-watchdog` can prove they ran. After install, add their labels to the meta-watchdog's expected-jobs list if it maintains one.
+## §5 — Heartbeat / meta-watchdog (REQUIRED — else liveness-blind, officer)
+Both canaries write `data/latest.json` under their script dir. But `dw-canary-meta-watchdog`'s `REGISTRY` (`~/.claude/skills/dw-canary-meta-watchdog/watchdog.mjs`) resolves heartbeats only via `skill:<name>` (→ `~/.claude/skills/<name>/data/latest.json`) or `hbAbs:<abspath>`. These canaries are NEITHER a skill dir NOR registered → **without an explicit `hbAbs:` entry the watchdog ignores them (or, with a naive `skill:` entry, reports "never ran" forever).** Add these two REGISTRY entries (absolute heartbeat paths) when you install:
+```js
+{ label:'com.steve.dw-sitemap-integrity', hbAbs:`${process.env.HOME}/Projects/designerwallcoverings/scripts/sitemap-integrity-canary/data/latest.json`, every:'daily', maxAgeMs: 30*60*60*1000 },
+{ label:'com.steve.dw-zero-dollar', hbAbs:`${process.env.HOME}/Projects/designerwallcoverings/scripts/zero-dollar-orderable-canary/data/latest.json`, every:'daily', maxAgeMs: 30*60*60*1000 },
+```
+(30h max-age = a daily job + slack. Add the zero-dollar entry only when you install c78 per §3.) Without this, the new guards have NO liveness coverage — the exact silent-death blind spot they were built to close.
## Notes / guardrails carried from the build cycles
- **Read-only / no prod write:** both canaries only GET the public sitemap (c77) or run read-only Admin GraphQL queries (c78). The wrapper only POSTs to local CNCP. No mutation anywhere. Install (launchctl) is the only privileged step and it's yours.
@@ -77,3 +83,14 @@ Both canaries write `data/latest.json` under their script dir (in addition to `/
- These two guards cover the two highest-severity classes this run found (mass-archive + free-checkout) that the existing fleet (c63/64/65 SEO, uptime, scraper, leak, map-auditor) did NOT watch.
_Cycle 79. DTD-picked C (unanimous 3/3). Wrote the paste-and-go install runbook + a CNCP-alert wrapper (`run-canary-with-cncp.sh`) so the c77 + c78 guards become installable by Steve in minutes via the existing `promote-canary.sh` harness. c77 = install now (HEALTHY); c78 = install after the gated reprice (or after the set-difference ack-baseline is added) to avoid daily-alert-on-the-known-open-P1. All steps are commands Steve runs (install Steve-gated); authoring was read-only in the worktree, $0. PlistBuddy-validate per c56; wrapper adds the CNCP-on-exit-3 the bare canaries lack; heartbeat wired for the meta-watchdog._
+
+---
+## 🏛️ OFFICER SIGN-OFF — vp-engineering: REVISE (chain correct; 2 install-correctness gaps) → fixed + re-verified
+The officer traced the full chain + read the watchdog registry. Chain + exit-propagation CONFIRMED correct; two gaps fixed in-cycle:
+- **Chain + exit propagation CONFIRMED:** promote-canary.sh `*.sh→/bin/bash <wrapper>` + `[ -f ]` passes (bare thin-wrapper path) → thin wrapper `exec`s the generic wrapper → `node "$CANARY"; rc=$?` (left of `;`, so `set -uo pipefail` doesn't abort) → `exit "$rc"` propagates 0/2/3 to launchd. CNCP-down can't kill the wrapper (`curl -s …` no `-e`) and the exit code still reaches launchd/watchdog. The `node -e require(json)` summary read handles missing/garbage json (catch → fallback).
+- **REVISE #1 — CNCP payload (FIXED + re-verified):** the heredoc-interpolated body could be malformed if the summary held a `"`/newline. → rebuilt the body via `node JSON.stringify` (safe escaping) + `[^\x20-\x7E]→space` (plain-ASCII) + 400-cap + truncate-on-start for the wrapper log. **Smoke-tested live:** a summary containing `\"orderable\"` + `& <special>` → valid JSON → live CNCP POST **http=200**. The {url,note} shape is the same one this run POSTed ~15× successfully. Wrapper now also logs the http code so a future 400/000 is visible.
+- **REVISE #2 — meta-watchdog liveness (FIXED in runbook §5):** the canaries' `data/latest.json` is neither a skill dir nor in the watchdog REGISTRY → as written the watchdog would report them "never ran" forever. §5 now gives the exact `hbAbs:` REGISTRY entries (abs heartbeat path, 30h max-age) to add at install — closing the silent-death blind spot the guards exist to close.
+- **Sequencing CONFIRMED:** c77-now (confirm-before-page + abort-on-partial + crater-floor + ratchet = low FP on a fresh schedule); c78-after-reprice (else daily-alert-on-the-open-145+8). Added the §3 nuance: c78's MIN_ACTIVE_SCAN floor → INCONCLUSIVE during a shrink event (refusing a small scan, not the failure it watches).
+- **Minor (addressed):** log-growth → truncate-on-start added to the wrapper. No relative-cwd bug (both canaries use `fileURLToPath`-derived absolute paths under launchd's `/` cwd).
+
+REVISE → chain merge-ready; the two gaps (live-verified CNCP payload + explicit watchdog hbAbs entries) fixed so a clean install is also alert-wired AND liveness-covered. Install remains Steve-gated (every launchctl/registry-edit step is his to run).
diff --git a/scripts/canary-install/run-canary-with-cncp.sh b/scripts/canary-install/run-canary-with-cncp.sh
index 651d820..84a75e2 100755
--- a/scripts/canary-install/run-canary-with-cncp.sh
+++ b/scripts/canary-install/run-canary-with-cncp.sh
@@ -18,17 +18,26 @@ LABEL="${3:?need label}"
URG="${4:-P2}"
CNCP="http://127.0.0.1:3333/api/parking-lot"
+: > "/tmp/${LABEL}.log" 2>/dev/null || true # truncate-on-start so the wrapper log can't grow unbounded (box never sleeps)
node "$CANARY"; rc=$?
# rc 0 = HEALTHY (no CNCP card — silence on green); 2 = INCONCLUSIVE; 3 = ALERT
if [ "$rc" -ne 0 ]; then
verdict=$([ "$rc" -eq 3 ] && echo ALERT || echo INCONCLUSIVE)
- # pull a compact one-line summary from the canary's /tmp json (plain-ASCII; CNCP 400s on heavy/long notes)
- summary=$(node -e "try{const d=require('$TMPJSON');const a=(d.alerts||[]).join(' | ');console.log((d.verdict||'$verdict')+': '+a.slice(0,420));}catch(e){console.log('$verdict (no json summary)');}" 2>/dev/null)
- curl -s -X POST "$CNCP" -H 'Content-Type: application/json' --data-binary @- >/dev/null 2>&1 <<JSON
-{"url":"file://$TMPJSON","note":"<!-- URGENCY: $URG --> [canary:$LABEL] $summary"}
-JSON
- echo "[run-canary-with-cncp] $LABEL rc=$rc → posted CNCP card ($verdict)"
+ # Build the POST body with node JSON.stringify so a quote/newline in the summary can't
+ # produce malformed JSON (CNCP {url,note} shape verified live this run). Plain-ASCII, capped.
+ BODY=$(TMPJSON="$TMPJSON" LABEL="$LABEL" URG="$URG" VERDICT="$verdict" node -e '
+ let d={}; try{ d=require(process.env.TMPJSON);}catch(e){}
+ const a=(d.alerts||[]).join(" | ").replace(/[^\x20-\x7E]/g," ").slice(0,400);
+ const note=`<!-- URGENCY: ${process.env.URG} --> [canary:${process.env.LABEL}] ${d.verdict||process.env.VERDICT}: ${a||"(no json summary)"}`;
+ process.stdout.write(JSON.stringify({url:"file://"+process.env.TMPJSON, note}));
+ ' 2>/dev/null)
+ if [ -n "$BODY" ]; then
+ code=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$CNCP" -H 'Content-Type: application/json' --data-binary "$BODY" 2>/dev/null || echo "000")
+ echo "[run-canary-with-cncp] $LABEL rc=$rc → CNCP POST http=$code ($verdict)"
+ else
+ echo "[run-canary-with-cncp] $LABEL rc=$rc → could not build CNCP body (verdict $verdict); exit code still propagates"
+ fi
else
echo "[run-canary-with-cncp] $LABEL rc=0 HEALTHY → no CNCP card (silence on green)"
fi
← 2718958 cycle 79: fix runbook promote-canary.sh invocation — add thi
·
back to Dw Yolo Loop
·
cycle 80: c78 set-difference acknowledged-baseline (c78/c79 479ecde →