[object Object]

← back to Dw Yolo Loop

cycle 79: catalog-integrity guard INSTALL RUNBOOK + CNCP-alert wrapper (run-canary-with-cncp.sh) — makes the c77+c78 guards installable via promote-canary.sh in one Steve-gated pass; c77 install-now, c78 after reprice/ack-baseline; PlistBuddy-validate per c56; nothing installed (gated)

c5b52c53c3893c508d75d5eb4adac3e3ef6969c9 · 2026-06-18 01:41:42 -0700 · Steve Abrams

Files touched

Diff

commit c5b52c53c3893c508d75d5eb4adac3e3ef6969c9
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Jun 18 01:41:42 2026 -0700

    cycle 79: catalog-integrity guard INSTALL RUNBOOK + CNCP-alert wrapper (run-canary-with-cncp.sh) — makes the c77+c78 guards installable via promote-canary.sh in one Steve-gated pass; c77 install-now, c78 after reprice/ack-baseline; PlistBuddy-validate per c56; nothing installed (gated)
---
 scripts/canary-install/INSTALL-RUNBOOK.md      | 76 ++++++++++++++++++++++++++
 scripts/canary-install/run-canary-with-cncp.sh | 35 ++++++++++++
 2 files changed, 111 insertions(+)

diff --git a/scripts/canary-install/INSTALL-RUNBOOK.md b/scripts/canary-install/INSTALL-RUNBOOK.md
new file mode 100644
index 0000000..43d0fd3
--- /dev/null
+++ b/scripts/canary-install/INSTALL-RUNBOOK.md
@@ -0,0 +1,76 @@
+# Catalog-Integrity Guard — INSTALL RUNBOOK (paste-and-go, Steve-gated) — cycle 79
+
+**DTD verdict C (unanimous 3/3).** READ-ONLY authoring (files written in the worktree; **NOTHING installed** — every install step is a command YOU run). Converts the two built-but-dark guards into a turn-on-in-minutes package. Both guards currently protect NOTHING because nothing schedules them — this closes that gap.
+
+## The guard set (built this run, hardened, officer-signed)
+| Guard | Watches | Built/hardened | State now |
+|---|---|---|---|
+| **c77 sitemap-integrity** | population-collapse (the April-2026 mass-archive failure mode) | `sitemap-integrity-canary.mjs` (baseline 72,462) | HEALTHY — **ready to install now** |
+| **c78 zero-dollar-orderable** | free-checkout (orderable $0 variants, P1) | `zero-dollar-orderable-canary.mjs` | ALERTs on the open 145+8 — **install AFTER the gated reprice** (see §3) |
+| c75 dw-map-auditor extension | price/mislabel/disco (spec) | spec-only | not built yet (future cycle) |
+
+All three use the existing `scripts/promote-canary.sh` (writes the plist, PRINTS the bootstrap — never bootstraps; install is Steve-gated by design) + the new `scripts/canary-install/run-canary-with-cncp.sh` wrapper (adds the CNCP-alert-on-exit-3 that the bare canary lacks).
+
+## §1 — One-time: move the canaries to a durable main-repo location
+The canaries live on the loop's worktree branch (`dw-yolo-loop`); install should point at a stable path, not a dev worktree. Copy them into the main repo:
+```sh
+mkdir -p ~/Projects/designerwallcoverings/scripts/sitemap-integrity-canary \
+         ~/Projects/designerwallcoverings/scripts/zero-dollar-orderable-canary \
+         ~/Projects/designerwallcoverings/scripts/canary-install
+cp ~/Projects/dw-yolo-loop/scripts/sitemap-integrity-canary/{sitemap-integrity-canary.mjs,baseline.json} \
+   ~/Projects/designerwallcoverings/scripts/sitemap-integrity-canary/
+cp ~/Projects/dw-yolo-loop/scripts/zero-dollar-orderable-canary/zero-dollar-orderable-canary.mjs \
+   ~/Projects/designerwallcoverings/scripts/zero-dollar-orderable-canary/
+cp ~/Projects/dw-yolo-loop/scripts/canary-install/run-canary-with-cncp.sh \
+   ~/Projects/designerwallcoverings/scripts/canary-install/
+```
+
+## §2 — Install c77 sitemap-integrity (READY NOW — it's HEALTHY)
+```sh
+# (a) sanity-run it once by hand (read-only; should print VERDICT: HEALTHY, exit 0)
+node ~/Projects/designerwallcoverings/scripts/sitemap-integrity-canary/sitemap-integrity-canary.mjs; echo "rc=$?"
+
+# (b) schedule the CNCP-wrapped canary daily at 06:10 via the existing harness
+bash ~/Projects/dw-yolo-loop/scripts/promote-canary.sh dw-sitemap-integrity \
+  "$HOME/Projects/designerwallcoverings/scripts/canary-install/run-canary-with-cncp.sh \
+   $HOME/Projects/designerwallcoverings/scripts/sitemap-integrity-canary/sitemap-integrity-canary.mjs \
+   /tmp/sitemap-integrity-canary.json dw-sitemap-integrity P2" daily 6 10
+#   ^ promote-canary.sh writes ~/Library/LaunchAgents/com.steve.dw-sitemap-integrity.plist + PRINTS the bootstrap cmd
+
+# (c) VALIDATE the plist with PlistBuddy (c56 lesson — NOT plutil-lint alone):
+P=~/Library/LaunchAgents/com.steve.dw-sitemap-integrity.plist
+/usr/libexec/PlistBuddy -c "Print :Label" "$P"            # expect com.steve.dw-sitemap-integrity
+/usr/libexec/PlistBuddy -c "Print :ProgramArguments" "$P" # expect the wrapper+canary invocation
+/usr/libexec/PlistBuddy -c "Print :StartCalendarInterval" "$P"  # expect Hour 6 Minute 10
+
+# (d) ENABLE (Steve runs):
+launchctl bootstrap gui/$(id -u) "$P"
+launchctl list | grep dw-sitemap-integrity      # expect a line
+launchctl kickstart -k gui/$(id -u)/com.steve.dw-sitemap-integrity   # run-now to confirm
+```
+- Alert wiring: on a crater/non-200/stale (exit 3) the wrapper POSTs a CNCP card; HEALTHY = silent.
+- **Re-baseline only after an APPROVED large catalog change** (e.g. the Thibaut 122 unpublish): `rm baseline.json` then run once to re-seed, so a sanctioned change isn't a standing near-threshold alarm. (The canary already upward-ratchets on growth.)
+
+## §3 — c78 zero-dollar-orderable: install AFTER the gated reprice (or after the ack-baseline is added)
+- **Why not now:** as built it ALERTs on the known-open 145 active + 8 draft (the P1 is genuinely open, gated). Installing daily now = daily-alert-on-a-known-gated-item (fatigue).
+- **Two clean paths (Steve's choice):**
+  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, label `dw-zero-dollar`, `/tmp/zero-dollar-orderable-canary.json`, P1) → 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).
+
+## §4 — Disable / uninstall (any guard)
+```sh
+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.
+
+## 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.
+- **PlistBuddy not plutil-lint** (c56): plutil only checks XML well-formedness; PlistBuddy asserts the keys actually resolve.
+- **promote-canary.sh never bootstraps** (by design + classifier-blocked) — it writes the plist + prints the command; you run the bootstrap.
+- 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._
diff --git a/scripts/canary-install/run-canary-with-cncp.sh b/scripts/canary-install/run-canary-with-cncp.sh
new file mode 100755
index 0000000..651d820
--- /dev/null
+++ b/scripts/canary-install/run-canary-with-cncp.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# run-canary-with-cncp.sh — generic wrapper: run a read-only canary, and on a non-zero
+# exit (3=ALERT, 2=INCONCLUSIVE) POST its /tmp result summary to CNCP parking-lot.
+# promote-canary.sh schedules THIS wrapper (so launchd gets CNCP alerting the bare canary
+# lacks). Read-only w.r.t. prod ($0). The canary itself never mutates; this only reads its
+# /tmp json + POSTs a CNCP card on alert.
+#
+# Usage (what the plist runs):
+#   bash run-canary-with-cncp.sh <canary-abs-path.mjs> <tmp-json-path> <label> [urgency]
+# Example:
+#   bash run-canary-with-cncp.sh \
+#     "$HOME/Projects/designerwallcoverings/scripts/sitemap-integrity-canary/sitemap-integrity-canary.mjs" \
+#     /tmp/sitemap-integrity-canary.json dw-sitemap-integrity P2
+set -uo pipefail
+CANARY="${1:?need canary script path}"
+TMPJSON="${2:?need /tmp json path}"
+LABEL="${3:?need label}"
+URG="${4:-P2}"
+CNCP="http://127.0.0.1:3333/api/parking-lot"
+
+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)"
+else
+  echo "[run-canary-with-cncp] $LABEL rc=0 HEALTHY → no CNCP card (silence on green)"
+fi
+exit "$rc"

← 4fdf1b1 cycle 78: officer REVISE sign-off appended (3 false-clean bl  ·  back to Dw Yolo Loop  ·  cycle 79: fix runbook promote-canary.sh invocation — add thi 2718958 →