← back to Dtd Approval Viewer
TK-12268: add creds-in-URL fetch guard (fleet pattern) to gated page
870675472975e2737fe33628a965dafdb35969b3 · 2026-09-25 13:56:01 -0700 · Steve Abrams
Relative fetch() on a Basic-Auth page threw on user:pass@host bookmarks.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7LB6rCwpA7ubJTqYzqXEX
Files touched
A .gitignoreA data.jsonA index.htmlA server.js
Diff
commit 870675472975e2737fe33628a965dafdb35969b3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Sep 25 13:56:01 2026 -0700
TK-12268: add creds-in-URL fetch guard (fleet pattern) to gated page
Relative fetch() on a Basic-Auth page threw on user:pass@host bookmarks.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7LB6rCwpA7ubJTqYzqXEX
---
.gitignore | 8 +
data.json | 734 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index.html | 121 ++++++++++
server.js | 16 ++
4 files changed, 879 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1924158
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
diff --git a/data.json b/data.json
new file mode 100644
index 0000000..b5d01f3
--- /dev/null
+++ b/data.json
@@ -0,0 +1,734 @@
+[
+{
+"file": "2026-08-31-TK10978-pr-momentum-567-add-yard-pilot.md",
+"ticket": "TK-10978",
+"title": "PR/Momentum 567-product add-yard recovery \u2014 20-product live pilot",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 86,
+"reversible": true,
+"blast_radius": "20 products (pilot); 567 cohort",
+"panel_rationale": [
+"Per-product live guards + prestate + rollback-all.mjs make each add reversible via DELETE undo",
+"20-product pilot with hold-again before the 547 remainder is correct bounded staging",
+"Pricing $48.58-$71.60/yd is real money \u2014 pin hw_price vs retail_price before scaling"
+],
+"dissent": "'Sold Per Yard' uses inventory_policy=continue with no verified inventory \u2014 mispriced/oversellable variant is real exposure at 567 scale",
+"next_action": "Run the 20-product pilot --limit=20 --live, verify all 20, HOLD before the remaining 547"
+},
+{
+"file": "TK-11018-carnegie-metafield-backfill.md",
+"ticket": "TK-11018",
+"title": "Carnegie metafield + MFR backfill (3 real fields + 34 Arctic mfr)",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 88,
+"reversible": true,
+"blast_radius": "~5,907 products / ~13,280 metafields",
+"panel_rationale": [
+"Snapshot-first + metafieldsSet replay / metafieldDelete undo is fully reversible; join key verified 99.1%",
+"Fills only 3 genuinely-real fields + 34 Arctic mfr; correctly BLOCKS color/durability fabrication",
+"Writes dwc.* leaving legacy global.* \u2014 two live schema gens, acceptable churn-avoidance"
+],
+"dissent": "dw_sku metafield is 0/5,962 today \u2014 stamping DWAG- onto 5,907 is a large net-new field; a stale join stamps a wrong dw_sku",
+"next_action": "Snapshot-first in <=500 batches (>=90s gap), verify batch 1 joins, then proceed"
+},
+{
+"file": "2026-08-31-TK-10519-tiktok-golive-steve-portal.md",
+"ticket": "TK-10519",
+"title": "TikTok DW Marketing \u2014 one portal session to go live",
+"gate_class": "identity",
+"verdict": "HOLD",
+"confidence": 90,
+"reversible": true,
+"blast_radius": "1 TikTok channel (DW Marketing app)",
+"panel_rationale": [
+"All local prep done + verified \u2014 nothing left an agent CAN do",
+"Every remaining step is a TikTok portal write + DW OAuth authorize = identity/external, Steve-only",
+"SELF_ONLY sandbox posts are private + portal-undoable, so risk is low"
+],
+"dissent": "The demo-video chicken/egg could stall Steve mid-session; Part D review is days-to-weeks",
+"next_action": "Do Part A (attach icon + Save) then Part B (add DW as Sandbox Target User + Authorize) on developers.tiktok.com"
+},
+{
+"file": "TK-00058-muralsource-canary-launchd-install-2026-08-31.md",
+"ticket": "TK-00058",
+"title": "Install Muralsource off-Shopify guard (launchd)",
+"gate_class": "scheduled-job",
+"verdict": "APPROVE",
+"confidence": 94,
+"reversible": true,
+"blast_radius": "1 launchd job (2 fires/day, read-only)",
+"panel_rationale": [
+"Canary already built + ran clean; emits correct fleet-health vocabulary; only automates a read-only check",
+"Read-only Shopify GET twice daily, zero writes; closes Cody's real hardening gap",
+"Scheduled-job install is hard-gated but blast radius is minimal; bootout+rm reverses it"
+],
+"dissent": "Read-only canary with trivial undo \u2014 arguably friction-level gating, but scheduled-job install is an explicit hard-gate class",
+"next_action": "launchctl bootstrap the com.steve.muralsource-offshopify-canary.plist, kickstart to verify one run"
+},
+{
+"file": "TK-11029-maya-rep-width-request.md",
+"ticket": "TK-11029",
+"title": "Maya Romanoff rep \u2014 width request for 2 discontinued SKUs",
+"gate_class": "email",
+"verdict": "REVISE",
+"confidence": 82,
+"reversible": true,
+"blast_radius": "1 email, 2 SKUs",
+"panel_rationale": [
+"Draft is clean; the 2 SKUs are correctly web-unrecoverable (collection 404s)",
+"Send-to-list/outward = hard-gated AND under the standing 'do not send emails' rule \u2014 cannot auto-run",
+"Recipient address is a blank placeholder \u2014 cannot send as-is; needs the rep email first"
+],
+"dissent": "BLOCK is defensible \u2014 TK stays open on just 2 harmless width-less rows; may not be worth sending",
+"next_action": "Supply the current Maya rep email, then say 'send it' to route via steve-office George"
+},
+{
+"file": "TK-11036-usre-prod-redeploy-023.md",
+"ticket": "TK-11036",
+"title": "usre prod \u2014 apply migrations 020-023 to live box",
+"gate_class": "prod-db",
+"verdict": "APPROVE",
+"confidence": 80,
+"reversible": true,
+"blast_radius": "prod DB (usrealestate, 382k brokers) \u2014 4 additive migrations",
+"panel_rationale": [
+"Path A applies 4 idempotent ledger-tracked migrations; 020-022 additive, only 023 behavior-relevant (DELETE-survival FK)",
+"Prod is healthy, not urgent \u2014 Path A gets 023 with no code overwrite, far safer than v0.18->v0.22 Path B",
+"Live-serving DB, but additive columns + endpoint 200-verify + column-drop rollback keep it bounded"
+],
+"dissent": "Path B full redeploy is a manual rsync overwrite of a live instance w/ no .deploy.conf \u2014 higher-risk trap; DEFER also valid",
+"next_action": "Choose Path A: scp 02{0,1,2,3}_*.sql then ssh 'npm run migrate' via ! ; confirm endpoints stay 200"
+},
+{
+"file": "cron-fire-canary-gated-dead-2026-08-31.md",
+"ticket": "cron-fire-canary",
+"title": "3 gated launchd jobs not firing \u2014 kickstart approval",
+"gate_class": "scheduled-job",
+"verdict": "REVISE",
+"confidence": 76,
+"reversible": true,
+"blast_radius": "3 launchd jobs (one = sample-followup-SEND email)",
+"panel_rationale": [
+"Canary correctly refused to auto-kickstart; kickstart is reversible (bootout to stop)",
+"Must split not blanket-approve \u2014 sample-followup-SEND hits the 'do not send emails' rule, must NOT kickstart",
+"daily-overnight-skus + firm-phone-enrich lower-risk but confirm each safe first"
+],
+"dissent": "firm-phone-enrich/daily-overnight-skus may be silently broken (flat runs counter = crash) \u2014 check err.log, kickstart won't fix that",
+"next_action": "Kickstart ONLY firm-phone-enrich + daily-overnight-skus (check err.logs); HOLD sample-followup-send"
+},
+{
+"file": "2026-08-31-TK-10279-govarbitrage-app-review-rejection.md",
+"ticket": "TK-10279",
+"title": "GovArbitrage App Store review rejection \u2014 surface rejection text",
+"gate_class": "identity",
+"verdict": "HOLD",
+"confidence": 92,
+"reversible": true,
+"blast_radius": "1 iOS app v1.0 in Resolution Center",
+"panel_rationale": [
+"Mechanical prereqs pass; only the Apple-side rejection reason is unknown \u2014 no code fix knowable yet",
+"Pure Steve console action (paste rejection text); no agent-fireable step",
+"Correctly does NOT resubmit blind \u2014 invites a second bounce"
+],
+"dissent": "App may be waiting-on-Apple not us \u2014 confirm state isn't already re-review before Steve invests time",
+"next_action": "Steve pastes full Resolution Center rejection text (guideline #) into TK-10279 before any resubmit"
+},
+{
+"file": "2026-08-31-TK-10635-CONTAMINATED-DS-do-not-relink.md",
+"ticket": "TK-10635",
+"title": "Contaminated $4.25 price-override DS \u2014 do NOT re-link (variant-blind join)",
+"gate_class": "publish",
+"verdict": "BLOCK",
+"confidence": 98,
+"reversible": true,
+"blast_radius": "GMC primary feed / 38+ sample offers mispriced up to $1,312",
+"panel_rationale": [
+"Root cause proven \u2014 join by pid (variant-blind) stamps roll price onto shared-pid sample offers; $4.25 swatch -> $1,312 live",
+"Link fired then correctly rolled back pre-reprocess; both ledgered, feed restored \u2014 guardrail memo, honor it",
+"Re-linking as-built = customer-charge error + Merchant-Center suspension"
+],
+"dissent": "Verify the corrected variant-aware rebuild's genuine-roll-leak scope ('few dozen') before any relink \u2014 don't trust the estimate",
+"next_action": "Do NOT relink; rebuild payload variant-aware (exclude Sample:/-sample), re-canary 0 sample offers touched, then gate relink"
+},
+{
+"file": "GMC-remediation-trackA-trackB-runbook.md",
+"ticket": "TK-10406/10993/10751",
+"title": "GMC remediation Track A (kill auto-crawl offers) + Track B (drop-UK, add-CAD)",
+"gate_class": "publish",
+"verdict": "HOLD",
+"confidence": 85,
+"reversible": true,
+"blast_radius": "~17,252 CA/GB disapprovals + ~26.7k phantom offers",
+"panel_rationale": [
+"Each of A1/B1/B2 is console-only, reversible; order A-then-B stops regrowth first",
+"B1 CAD shipping rate needs a real number; B2 reverses TK-10406's enable-UK on a 9/9 DTD verdict \u2014 needs explicit confirm",
+"Track A must verify offer count drops by ~26.7k phantom, not the real catalog"
+],
+"dissent": "Confirm the DROP-UK verdict is still current business intent (vs enabling GBP) before B2 \u2014 the one business-owned fork",
+"next_action": "Steve confirms CAD rate + DROP-UK intent, then fires A1->B1->B2 from consoles; re-run GMC canary"
+},
+{
+"file": "TK-00058-fentucci-needs-width-clear-2026-08-31.md",
+"ticket": "TK-00058",
+"title": "Fentucci clear stale custom.needs_width flag (504 active)",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 90,
+"reversible": true,
+"blast_radius": "504 live Fentucci metafield writes",
+"panel_rationale": [
+"Audit proves flag stale \u2014 all 504 carry a real uniform 36in width; script snapshot-first + idempotent + guarded",
+"Reversible via snapshot re-set, $0 Admin API; only gate trigger is >500 cap + live-store touch",
+"504 barely exceeds the 500 cap, uniform + internally-verifiable \u2014 low real risk"
+],
+"dissent": "Value is a display metafield not price/status \u2014 arguably below hard-gate threshold, but 504>500 + live-store rule holds it",
+"next_action": "Fire dry-run -> --apply --limit=1 canary -> --apply all 504"
+},
+{
+"file": "TK-00058-sanderson-publish-506-READY-2026-08-31.md",
+"ticket": "TK-00058",
+"title": "Sanderson publish 506 CLEAR products (UK duty repriced)",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 88,
+"reversible": true,
+"blast_radius": "504 net-new creates + 2 upserts, 506 activations",
+"panel_rationale": [
+"Reprice done in staging (1.10 duty, snapshot+ledger); publishable-only payload (exactly 506) blocks the 81 settlement items",
+"Reversible (created products archivable via created.jsonl; price restorable); Google channel excluded to dodge $4.25 mismatch",
+"Settlement + 5-field + image gating enforced at activate"
+],
+"dissent": "Shared ~1k/day Shopify cap makes this multi-run/resumable \u2014 confirm dedup of the 2 existing Dalmatians drafts holds across resumes",
+"next_action": "Fire canary create+golive --limit=1, eyeball live PDP, then full create --apply then golive --apply"
+},
+{
+"file": "TK-10881-TOKEN-ROUTING-RUNBOOK.md",
+"ticket": "TK-10979",
+"title": "Route full-access Shopify token into scope-blocked write_inventory pipelines",
+"gate_class": "identity",
+"verdict": "APPROVE",
+"confidence": 86,
+"reversible": true,
+"blast_radius": "2 one-line script edits (var name flip)",
+"panel_rationale": [
+"Option A is surgical \u2014 flips SHOPIFY_ADMIN_TOKEN->SHOPIFY_FULL_ACCESS_TOKEN in 2 git-tracked files; edit fires nothing",
+"git-revertible per file; Option B (global secrets swap) correctly rejected for fleet-wide blast",
+"Broadens the live pipeline credential (identity-class) but the routing edit is inert; writes stay separately gated"
+],
+"dissent": "A scoped-broader default token is a standing footgun for future readers \u2014 add a comment noting why full-access is used",
+"next_action": "Say 'route it' -> apply Option A 2-line edits; the write_inventory --apply runs stay separately gated"
+},
+{
+"file": "TK-10286-wear-sales-live-golive.md",
+"ticket": "TK-10286",
+"title": "/wear apparel \u2014 flip real Stripe+Printful sales LIVE",
+"gate_class": "spend",
+"verdict": "HOLD",
+"confidence": 90,
+"reversible": true,
+"blast_radius": "Live e-commerce: real card charges + POD fulfillment",
+"panel_rationale": [
+"Hard blocker is PRINTFUL_API_KEY \u2014 flipping WEAR_SALES_LIVE=1 without POD charges cards with no fulfillment",
+"spend + customer-facing + deploy = always hard-gated; nothing fires until Steve does \u00a73",
+"Polo margin thin @27% ship-absorbed; pricing decisions are business-owned + unresolved"
+],
+"dissent": "Printful costs are ESTIMATES until the key lands \u2014 real base cost could push polo margin negative",
+"next_action": "Route PRINTFUL_API_KEY -> fetch exact costs -> decide shipping/polo pricing -> set 3 env flags + deploy + smoke one order"
+},
+{
+"file": "2026-08-31-GMC-DEGRADED-CONSOLIDATED-durable-fix.md",
+"ticket": "TK-10993",
+"title": "GMC DEGRADED consolidated durable fix (Tracks A-E)",
+"gate_class": "publish",
+"verdict": "REVISE",
+"confidence": 86,
+"reversible": true,
+"blast_radius": "~26.7k orphan deletes; CA/GB shipping; ~6.5k publish",
+"panel_rationale": [
+"Diagnosis fresh, read-only, codex-confirmed; C+D already fired, so only A (crawl-off + bounded delete) and B (CAD/GBP) remain",
+"A bundles a durable MC toggle with a large delete \u2014 enumerate to an exact deduped list before firing; don't approve as one blob",
+"Track E blanket 12,422 publish is correctly self-BLOCKed (5,921 Carnegie at-cost must not go live)"
+],
+"dissent": "Crawl-off vs CAD/GBP near-equal leverage; B is the safer independent single-action win, land it first",
+"next_action": "Approve B (Steve console); for A require enumerated deduped orphan list before delete; keep E blocked"
+},
+{
+"file": "2026-08-31-TK10978-unbuyable-recovery-remaining-gated-menu.md",
+"ticket": "TK-10978",
+"title": "Unbuyable-recovery closed + remaining-work decision menu",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 90,
+"reversible": true,
+"blast_radius": "Menu only; next = Rebel Walls 494 variant add",
+"panel_rationale": [
+"Decision menu not an auto-fire; ticket already CLOSED, 368 recovered w/ per-product DELETE undo",
+"Reframe is sound: 23,269 of 24,844 unbuyable are correctly quote-only by design",
+"Rebel Walls (494, per-m2 price staged, no spend/login) is the correct cheapest-first greenlight"
+],
+"dissent": "Rebel Walls per-m2 unit overlaps TK-10029 relabel judgment (280 roll/bolt) \u2014 confirm unit before the variant add",
+"next_action": "Greenlight Rebel Walls 494 as scoped reversible win; Track B awaits Steve cost list"
+},
+{
+"file": "TK-10999-stroheim-settlement-gate-BLOCKED-gemini-credits.md",
+"ticket": "TK-10999",
+"title": "Stroheim settlement-gate blocked on depleted Gemini credits",
+"gate_class": "spend",
+"verdict": "HOLD",
+"confidence": 95,
+"reversible": true,
+"blast_radius": "471 imgs ~$0.52 Gemini; verdicts idempotent",
+"panel_rationale": [
+"Genuinely blocked externality: prepay $0, all 429 RESOURCE_EXHAUSTED, $0 billed, nothing published",
+"Ran gate directly not resume.sh, so no customer-facing draft write fired",
+"Re-run is idempotent + cheap; blocker is purely Steve billing top-up"
+],
+"dissent": "None material \u2014 wait-on-Steve billing action, not a technical decision",
+"next_action": "Top up Gemini prepay credits, then re-run settlement-gate.mjs --apply"
+},
+{
+"file": "2026-08-31-TK-11026-firecities-agentabrams-alias.md",
+"ticket": "TK-11026",
+"title": "firecities.agentabrams.com short-alias (DNS + vhost)",
+"gate_class": "dns",
+"verdict": "APPROVE",
+"confidence": 88,
+"reversible": true,
+"blast_radius": "1 CF A-record + server_name + nginx reload",
+"panel_rationale": [
+"Cosmetic shorter-share alias to an already-live hub; paste-ready + rollback-documented",
+"Safe default (keep Basic-Auth gated, matching firecities.crcp) is the conservative choice",
+"DNS + nginx reload hard-gated by rule but low-risk + independently reversible"
+],
+"dissent": "Low value (skippable per memo itself) \u2014 could be deferred behind higher-ROI items",
+"next_action": "Run the 4 paste steps (CF A-record, HUB_PAGES, server_name, nginx reload) keeping auth gated"
+},
+{
+"file": "dedup-DRYRUN-20260831.md",
+"ticket": "\u2014",
+"title": "Catalog dedup dry-run (0 clean pairs, 1265 held)",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 92,
+"reversible": true,
+"blast_radius": "0 archives this run; live path gated behind LIVE-dedup touch",
+"panel_rationale": [
+"Dry-run is read-only + self-restraining: 0 clean pairs, 1265 ambiguous HELD, nothing auto-archived",
+"Restore-map written before any archive + ACTIVE->ARCHIVED only = fully reversible",
+"Going live is a separate manual gate (touch LIVE-dedup) \u2014 no fire requested"
+],
+"dissent": "With 0 clean pairs the report is a no-op; verify the descriptive-keeper heuristic before any future live run",
+"next_action": "No action \u2014 informational; do not touch LIVE-dedup until worklist CSV is reviewed"
+},
+{
+"file": "local-model-upgrade-2026-08-31.md",
+"ticket": "\u2014",
+"title": "Local model upgrade -> official Qwen3.8-27B-8bit",
+"gate_class": "other",
+"verdict": "APPROVE",
+"confidence": 80,
+"reversible": true,
+"blast_radius": "~27GB one-time HF download; no default swap until A/B",
+"panel_rationale": [
+"Official mlx-community 8-bit, verified HTTP 200, fits 96GB M3 Ultra, avoids abliterated fork",
+"No spend (bandwidth/disk); default stays Qwen3.6-35B until A/B proves the swap",
+"Download command correctly Steve-gated, not auto-run"
+],
+"dissent": "Pure disk/bandwidth $0 API arguably clears the reversibility tier \u2014 but leaving the swap gated is right",
+"next_action": "Run the huggingface-cli pull, then A/B vs Qwen3.6-35B before making it the standing default"
+},
+{
+"file": "TK-11002-COMMERCE-MORNING-DECISIONS.md",
+"ticket": "TK-11002",
+"title": "Commerce morning decision queue (overnight)",
+"gate_class": "shopify-write",
+"verdict": "REVISE",
+"confidence": 84,
+"reversible": true,
+"blast_radius": "TK-10029 relabel 1467; TK-10209 GMC publish 132",
+"panel_rationale": [
+"Clean overnight run: 0 emails/$0/0 writes, each item verified read-only",
+"TK-10029 Swipe B (apply 1187 unambiguous first, confirm the 280 roll/bolt unit before those) is the conservative path \u2014 don't blanket-apply 1467",
+"Correctly declined to self-escalate to full-access token for theme/content scopes"
+],
+"dissent": "TK-10209 GMC publish of 132 O&L is external-publish and should sequence AFTER the GMC disapproval floor (TK-10993 A/B) lands",
+"next_action": "Approve TK-10029 Swipe B; hold TK-10209 until GMC Tracks A/B land; leave token routing to Steve"
+},
+{
+"file": "070926-gmc-orphan-reconcile-2026-08-31.md",
+"ticket": "gmc-orphan-reconcile",
+"title": "GMC orphan reconcile \u2014 80 new orphans, 10 auto-deleted",
+"gate_class": "publish",
+"verdict": "APPROVE",
+"confidence": 78,
+"reversible": true,
+"blast_radius": "<=80 GMC offers (10 auto-fired, 70 gated)",
+"panel_rationale": [
+"Reversible \u2014 archived offer re-adds via the normal feed; deletes hit dead/archived landings only",
+"Option 1 (10 account-health, $4.25-on-dead-landing) is the real suspension risk and clears cleanly",
+"Memo already auto-fired 10 Content-API deletes under a prior standing approval \u2014 verify those 10 were account-health class"
+],
+"dissent": "Some 'approved'+$4.25 rows self-expire in 30 days; deleting an approved offer is a small opportunity cost",
+"next_action": "Approve option 1 (account-health list) only; hold option 2 pending a per-vendor spot-check of the Maharam 35"
+},
+{
+"file": "TK-10981-job1-innovations-mfrsku-backfill.md",
+"ticket": "TK-10981",
+"title": "Innovations mfr_sku backfill (13 archived rows)",
+"gate_class": "dw_unified-write",
+"verdict": "HOLD",
+"confidence": 88,
+"reversible": true,
+"blast_radius": "13 rows, all ARCHIVED",
+"panel_rationale": [
+"The 13 codes share provenance with the KNOWN-corrupted scrape \u2014 shape-plausible is not proof; fabrication risk",
+"All 13 ARCHIVED = zero customer-facing urgency, no cost to waiting for an authoritative re-scrape",
+"Codex second-opinion + the memo author itself recommend HOLD"
+],
+"dissent": "Write IS reversible (old value recorded), so fire-then-revert-if-wrong is technically low-risk",
+"next_action": "Hold; fold the 13 into a future authoritative Innovations re-scrape that corroborates each code"
+},
+{
+"file": "2026-08-30-TK-10981-junk-mfr-sku-repair.md",
+"ticket": "TK-10981",
+"title": "Canonical mfr_sku cleanup \u2014 13 recover, 4,009 to NULL",
+"gate_class": "dw_unified-write",
+"verdict": "REVISE",
+"confidence": 72,
+"reversible": true,
+"blast_radius": "4,022 shopify_products rows (391 ACTIVE)",
+"panel_rationale": [
+"Transactional design is sound (immutable restore-map, locked ID set, count asserts, auto-rollback)",
+"The 13-row recovery conflicts with the sibling JOB1 HOLD \u2014 same suspected-corrupt codes, should NOT write them",
+"391 ACTIVE rows go junk-token -> NULL \u2014 confirm GMC feed + go-live gate treat NULL no worse than 'TRUE'"
+],
+"dissent": "Nulling the 4,009 could be split out + auto-run as reversible cleanup, deferring only the 13 contested recoveries",
+"next_action": "Revise: drop the 13 recoveries (per JOB1 HOLD), execute only the 4,009->NULL transaction with restore-map"
+},
+{
+"file": "TK-10832-pj-mailer-presend-runbook.md",
+"ticket": "TK-10832",
+"title": "PJ Fall 2026 mailer pre-send runbook",
+"gate_class": "email",
+"verdict": "HOLD",
+"confidence": 90,
+"reversible": true,
+"blast_radius": "CC trade-list send + DNS DKIM write",
+"panel_rationale": [
+"Runbook is a $0 checklist, nothing executed; the DKIM gap is correctly the blocking step-1",
+"send-to-list + DNS write both hard-gated; must not go until DKIM aligns or Gmail munges the From (17529.5)",
+"List-Unsubscribe one-click + suppression scrub unverified \u2014 bulk send without them risks compliance"
+],
+"dissent": "DMARC p=none already adequate for CC; the only true blocker is the CC Self-Auth DKIM CNAMEs \u2014 short path to sendable",
+"next_action": "Hold send; run CC Self-Authentication -> add the 2 ctctN CNAMEs via the DNS agent, then test-send"
+},
+{
+"file": "dw-doubleroll-lengthless-273-regression.md",
+"ticket": "dw-doubleroll-canary",
+"title": "273 new roll SKUs shipped without S/R+D/R lengths",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 80,
+"reversible": true,
+"blast_radius": "413 length-less roll products + importer fix",
+"panel_rationale": [
+"Root-cause-first is correct \u2014 identify the vendor/importer (likely outside current VMAP tooling) before any backfill",
+"The read-only dig needs no gate; only the metafield backfill is the gated customer-facing write",
+"Evidence is a cached 13:26 canary verdict \u2014 re-verify with the token for the exact SKU/vendor list first"
+],
+"dissent": "Backfilling lengths without fixing the importer just re-accrues the backlog \u2014 the code fix must land first or in tandem",
+"next_action": "Approve the read-only root-cause dig; return vendor mix + SKU list before authorizing the gated backfill"
+},
+{
+"file": "2026-08-27-TK-10449-norma-ig-roster-past-35-DRAFT.md",
+"ticket": "TK-10449",
+"title": "Grow Norma IG roster past 35 (relinks + new accounts)",
+"gate_class": "identity",
+"verdict": "REVISE",
+"confidence": 83,
+"reversible": false,
+"blast_radius": "Meta fleet + never-expiring token (bulk-signup ban vector)",
+"panel_rationale": [
+"The drift finding (roster silently 35->34, @grasscloth unlinked) is real; its registry-regen auto-fix is reversible/ledgered",
+"Phase 0/0b zero-signup relinks are low-risk, need only Steve's one Meta login; bulk new-account creation is the ban vector",
+"New IG signups are irreversible identity actions under one Business Manager/IP \u2014 #1 trigger for Meta nuking the fleet"
+],
+"dissent": "Even Phase 0 relinks require the account-holder Connect, so nothing here is agent-executable regardless",
+"next_action": "Approve only Phase 0 relinks (@grasscloth, @hospitalityfabrics); Steve does the Meta login; hold all new-account creation",
+"escalated": {
+"verdict": "A",
+"vote": "6/6 unanimous",
+"confidence": "high",
+"note": "External 5-LLM panel CONFIRMS: Phase-0 relinks only, never batch new signups."
+}
+},
+{
+"file": "TK-10484-jeffrey-stevens-reonboard-RECONCILED.md",
+"ticket": "TK-10484",
+"title": "Jeffrey Stevens peel-and-stick re-onboard (reconciled)",
+"gate_class": "spend",
+"verdict": "HOLD",
+"confidence": 81,
+"reversible": true,
+"blast_radius": "portal scrape (uncertain spend) + 74-SKU pricing",
+"panel_rationale": [
+"Critical path is a yorkwall/NuWallpaper trade-portal scrape \u2014 metered, uncertain spend that can exceed the $5 auto-cap",
+"Reconcile corrected two stale claims; Item C archive is reversible/snapshot-backed and can go once cost is sourced",
+"51 mfr codes + cost are locally unrecoverable \u2014 no fabrication (keep-old-never-mint); downstream blocks on the scrape"
+],
+"dissent": "Item C (archive 34 junk slug rows) is fully reversible + snapshot-backed and could be approved independently now",
+"next_action": "Hold; run the gated /brewster yorkwall scrape to source cost + 51 codes, then price/activate"
+},
+{
+"file": "TK-10096-dwyg-vahallan-filemaker-add.md",
+"ticket": "TK-10096",
+"title": "Add DWYG (Vahallan) line to FileMaker WALLPAPER master",
+"gate_class": "other",
+"verdict": "APPROVE",
+"confidence": 83,
+"reversible": true,
+"blast_radius": "394 FM WALLPAPER records in 303,886-row live master",
+"panel_rationale": [
+"Reconcile verified live; per-record before/after snapshots + combo-sku uniqueness make creates idempotent + repairs revertible",
+"Quote-only mapping matches live storefront; contamination diagnosis (foreign FDG/F-codes) well-evidenced",
+"No delete verb in MCP forces neutralize-via-update (option b) \u2014 accept for audit trail"
+],
+"dissent": "394-record bulk write to canonical FM master with no delete primitive; want a 5-SKU pilot create+verify first",
+"next_action": "Approve Steps 1-2 via MCP + execute Step 3 as option (b) neutralize-update; pilot 5 creates first"
+},
+{
+"file": "TK-10066-reid-witlin-onboarding-reconcile.md",
+"ticket": "TK-10066",
+"title": "Reid Witlin private-label onboarding reconcile + registry fix",
+"gate_class": "prod-db",
+"verdict": "REVISE",
+"confidence": 80,
+"reversible": true,
+"blast_radius": "1-row vendor_registry write now; ~922+34 Shopify onboarding deferred",
+"panel_rationale": [
+"Registry fix DWRK-->DWKR- is a bounded reversible 1-row write with recorded rollback \u2014 approvable in isolation",
+"Vendor shrank 1071->149 \u2014 blind bulk onboarding would publish hundreds of discontinued SKUs; correct to hold",
+"Shared DWKR- prefix with dormant Edelman needs the allow-map decision resolved same-time, else prefix canary fires"
+],
+"dissent": "The registry write could ship now on its own; bundling it behind the re-scrape over-gates a clean reversible fix",
+"next_action": "Approve the 1-row registry SQL + Edelman allow-map option (a); run $0 rwltd re-scrape before any Shopify onboarding"
+},
+{
+"file": "2026-08-27-TK10875-130-variant-datarepair.md",
+"ticket": "TK-10875",
+"title": "130 irregular unbuyable products \u2014 variant data-repair",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 78,
+"reversible": true,
+"blast_radius": "130 live products (123 Ronald Redding + 5 Thibaut + 2 Cole & Son)",
+"panel_rationale": [
+"Three defect classes precisely characterized; restructure of live variants riskier than add but reversible",
+"Revenue-recoverable mislabeled-sellable products \u2014 real upside; RR sample-priced-at-retail is a clear defect",
+"Memo lacks explicit per-class rollback map + no pilot named \u2014 restructure touches live variants"
+],
+"dissent": "No stated rollback manifest or pilot; approve the PASS but require per-product before-state + pilot each class",
+"next_action": "Route to vp-dw-commerce as gated batch; require per-product before-snapshot + one-SKU pilot per defect class"
+},
+{
+"file": "carnegie-link-2075-2026-08-26.md",
+"ticket": "TK-10901",
+"title": "Carnegie mfr_sku/dw_sku recovery LINK from staging",
+"gate_class": "prod-db",
+"verdict": "APPROVE",
+"confidence": 85,
+"reversible": true,
+"blast_radius": "2,000 DUAL rows in Kamatera shopify_products (mfr_sku only)",
+"panel_rationale": [
+"Dual-key cross-validation 2000 agree / 0 disagree is strong; backup table + PRE/POST guards + one-line undo",
+"APPROVE-MFR-ONLY recovers only the unambiguous real mfr code \u2014 pure keep-old-number recovery, no minting",
+"DWAG- staging dw_sku resembles reverted mints \u2014 safe default leaves dw_sku blank pending Steve's ruling"
+],
+"dissent": "Kamatera-canonical shopify_products write = hard-gated per split-brain doctrine; 2,000 rows > caution even if reversible",
+"next_action": "Approve APPROVE-MFR-ONLY (2,000 DUAL, mfr_sku only); hold dw_sku + the 395 SINGLE + 3,526 ambiguous"
+},
+{
+"file": "sku-integrity-rescrape-scope-2026-08-26.md",
+"ticket": "TK-10896",
+"title": "Scope: recover canonical dw_sku for 15,577 blank rows, no minting",
+"gate_class": "other",
+"verdict": "APPROVE",
+"confidence": 88,
+"reversible": true,
+"blast_radius": "Scope/plan doc only \u2014 0 writes",
+"panel_rationale": [
+"Read-only scope classification A-E is sound and honors keep-old-never-mint; no execution requested",
+"Identifies JOB 1 (~2.7k recoverable-now via self-copy/LINK) as the cheap clear win, defers the 11.3k re-scrape",
+"Approving the SEQUENCING \u2014 each downstream write stays independently gated"
+],
+"dissent": "Per-vendor staging-LINK coverage is unmeasured (Romo probe empty) \u2014 JOB 1 sizing is optimistic until measured",
+"next_action": "Approve the scope/sequencing; require per-vendor LINK-coverage measurement before each JOB 1 batch"
+},
+{
+"file": "2026-08-26-MaharamSOURCE-price-load-plan.md",
+"ticket": "MaharamSOURCE",
+"title": "Load Maharam per-yard prices to Shopify + re-publish 1,429",
+"gate_class": "publish",
+"verdict": "REVISE",
+"confidence": 72,
+"reversible": true,
+"blast_radius": "1,429 live DWAX- products: add variant + reprice + re-publish to Google",
+"panel_rationale": [
+"Staging + rollback manifest exist; each step reversible (variant delete, price revert, unpublish)",
+"Assumed sell-at-list proceeds without the Maharam trade discount \u2014 margin unknown, could sell near cost",
+"Re-publish to Google channel is external-publish (GMC) \u2014 hard-gated regardless of reversibility; $/yd unit unconfirmed"
+],
+"dissent": "Sell-at-list default risks thin/negative margin; a 1,429-product GMC re-publish on an unverified unit risks disapproval recurrence",
+"next_action": "Confirm sell-at-list vs cost-markup + min-order increment, dry-run a handful, then gate GMC re-publish separately"
+},
+{
+"file": "sku-integrity-phase2-phase4-2026-08-26.md",
+"ticket": "TK-10896",
+"title": "SKU backlog Phase 2 disposition + Phase 4 prefix decision aid",
+"gate_class": "other",
+"verdict": "HOLD",
+"confidence": 82,
+"reversible": true,
+"blast_radius": "Decision-aid only \u2014 0 writes; Phase 4 = 12,590 rows pending rulings",
+"panel_rationale": [
+"Read-only analysis; Phase 2 correctly refuses to blind-fix collisions (would cement wrong identity)",
+"Bucket B/C allocate INTO prefixes \u2014 sequential MINTING, collides with keep-old-never-mint",
+"Phase 4's premise is the exact allocation Steve reverted 12,216 of; needs explicit prefix rulings"
+],
+"dissent": "Bucket A auto-adopt is trivially safe and could split off \u2014 but B/C minting means HOLD not APPROVE overall",
+"next_action": "Hold for Steve's per-bucket prefix rulings (esp. Carnegie DWAG- 5,921, PR, Hollywood); do not allocate until ruled"
+},
+{
+"file": "koroseal-quote-only-loadplan.md",
+"ticket": "KoroSealSOURCE",
+"title": "Koroseal quote-only load plan (no price/publish)",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 88,
+"reversible": true,
+"blast_radius": "~2,448 active Koroseal; ~212 $4.25-leak fix",
+"panel_rationale": [
+"No cost column anywhere, cost/0.65/0.85 uncomputable; auto-pricing would fabricate a price",
+"Option A (quote-only + fix $4.25 leak) is right; the leak is an active GMC-disapproval risk worth clearing",
+"display_prices flip is a global-default column read by unknown storefronts \u2014 verify no regress before flipping"
+],
+"dissent": "2,448>500 means even the reversible metafield/leak fix should stage (25->verify->rest), not one bulk run",
+"next_action": "Approve Option A; execute $4.25-leak fix + quote-flow wiring staged, hold pricing until dealer list ingested"
+},
+{
+"file": "TK-10881-sdg-cadence-arm.md",
+"ticket": "TK-10881",
+"title": "Arm SDG daily-publish cadence launchd job (~5,800 products)",
+"gate_class": "scheduled-job",
+"verdict": "HOLD",
+"confidence": 82,
+"reversible": true,
+"blast_radius": "~4,620 live products over ~23 days, unattended",
+"panel_rationale": [
+"Gates well-built (settlement + 6-field + 0.85 auto-halt + rollback), but this is a perpetual unattended external-publish job",
+"Hard-blocked on the sibling write_inventory scope anyway \u2014 arming now is premature",
+"A self-perpetuating job publishing 200/day live has no human eyes per-batch; the auto-halt is self-graded"
+],
+"dissent": "Once scope lands + batch-1 proves clean, the auto-halt+ledger+rollback may justify arming \u2014 but not before",
+"next_action": "Hold cadence until write_inventory granted and batch-1 ships clean; then re-review arming"
+},
+{
+"file": "TK-10881-shopify-write-inventory-scope.md",
+"ticket": "TK-10881",
+"title": "Grant write_inventory scope to DW Shopify admin app",
+"gate_class": "identity",
+"verdict": "APPROVE",
+"confidence": 90,
+"reversible": true,
+"blast_radius": "one credential scope on live store admin app",
+"panel_rationale": [
+"Clean root-cause \u2014 403 write_inventory missing, scope lapsed since the 7/26 import; agent cannot self-grant",
+"Low-risk additive scope, removable later, fully reversible; only Steve can do it in Shopify admin",
+"Granting also silently re-enables the cadence + Hollywood job to write inventory \u2014 confirm those consumers intended"
+],
+"dissent": "Approving the scope implicitly greenlights every inventory-writing job on the token \u2014 decouple approval from arming the cadence",
+"next_action": "Approve scope grant; if token rotates route new token via secrets skill and finish batch-1 only"
+},
+{
+"file": "2026-08-26-TK-10878-phase1-add-disk.md",
+"ticket": "TK-10878",
+"title": "Grow Kamatera Postgres volume >=100GB before pg_partman",
+"gate_class": "spend",
+"verdict": "APPROVE",
+"confidence": 85,
+"reversible": false,
+"blast_radius": "one Kamatera prod volume resize; recurring monthly spend",
+"panel_rationale": [
+"Box ~90% full, partman rewrite needs ~table-sized scratch, must grow before converting or it stalls prod",
+"Recurring monthly cost + can't-easily-shrink resize make this a genuine spend decision for Steve",
+"No data risk, but confirm the resize targets the correct PG mount (not just /)"
+],
+"dissent": "Adding disk treats the symptom; verify the 16GB/wk growth is truly unprunable before perpetual storage spend",
+"next_action": "Approve >=100GB grow; verify df on the PG mount shows >=75GB free, then draft Phase 2",
+"escalated": {
+"verdict": "C",
+"vote": "4C / 2A",
+"confidence": "med-high",
+"note": "External panel REFINES approve->C: grow >=100GB now AND add a retention/prune policy after."
+}
+},
+{
+"file": "2026-08-26-philromano-samples-and-price.md",
+"ticket": "TK-10872",
+"title": "Phillipe Romano/MDC: add Sample variants + make $0 non-orderable",
+"gate_class": "shopify-write",
+"verdict": "APPROVE",
+"confidence": 84,
+"reversible": true,
+"blast_radius": "1,280 live PR/MDC products (lamp excluded)",
+"panel_rationale": [
+"restore-original.json before each PUT + additive contact-for-price tag = fully reversible; lamp anomaly excluded via price==0 filter",
+"Closing a live $0-orderable hole across 1,280 SKUs is real value + a GMC risk; DTD 8/8 for Option A",
+"1,280>500 must stage (25->verify PDP live->rest); display_variant tag preservation re-checked on the pilot"
+],
+"dissent": "Sample-price $4.25 vs task-text $0.25 is an unresolved fork \u2014 proceed on $4.25 default but flag reversible if wrong",
+"next_action": "Approve staged 25-item pilot w/ price/prefix guard + display_variant preservation; verify live, then remainder"
+},
+{
+"file": "2026-08-26-chargeandexplore-4.3-spam-resubmit.md",
+"ticket": "chargeandexplore-release",
+"title": "Charge & Explore 4.3-spam rejection resubmit strategy",
+"gate_class": "publish",
+"verdict": "REVISE",
+"confidence": 72,
+"reversible": false,
+"blast_radius": "App Store account (9 apps) suspension risk; EAS spend; app deletion",
+"panel_rationale": [
+"P0 account-hygiene insight correct \u2014 resubmitting under a live duplicate-calculator pattern risks 4.3(a) escalation",
+"P0 app deletion is destructive+irreversible, P1 is metered EAS spend, Submit is an Apple-account write \u2014 3 distinct gates bundled",
+"A UX rebuild may still not overturn a saturated-category 4.3"
+],
+"dissent": "Don't delete the calculator app \u2014 de-emphasize/differentiate or withdraw C&E instead; deletion is the least-reversible lever",
+"next_action": "Split into 3 separate gated approvals; get Steve's explicit call on the app-deletion lever before any resubmit",
+"escalated": {
+"verdict": "A",
+"vote": "4A / 2B (split)",
+"confidence": "medium",
+"note": "External panel FLIPS to A (delete duplicate, then resubmit) vs the Claude-panel B. Human-gated: confirm the calc app has no independent value before the irreversible delete."
+}
+},
+{
+"file": "2026-08-25-dw-reels-ig-accounts-wireup.md",
+"ticket": "dw-marketing-reels",
+"title": "DW Reels IG accounts wireup \u2014 deploy + 5 missing IG accounts",
+"gate_class": "publish",
+"verdict": "APPROVE",
+"confidence": 86,
+"reversible": true,
+"blast_radius": "one prod deploy to marketing.dw; 5 IG-account creations (Steve-only)",
+"panel_rationale": [
+"Root-cause correct \u2014 one shared page token authorizes all 35; the '(needs creds)' label was a union artifact; fix committed + DRY-verified",
+"Deploy is git-revertable, no data/spend/DNS; posting stays gated behind SOCIAL_LIVE_ARMED",
+"Confirm the deploy doesn't flip SOCIAL_LIVE_ARMED + the 5 pending brands genuinely have no IG account"
+],
+"dissent": "The @philipperomano vs @philliperomanodesigns duplicate needs a keep/drop decision before creating a placeholder identity",
+"next_action": "Approve the /deploy (posting stays gated); hold the 5 IG-account creations, resolve the PR handle duplicate first"
+}
+]
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..9d1fa37
--- /dev/null
+++ b/index.html
@@ -0,0 +1,121 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<script>
+// Credential-safe fetch guard (fleet drop-in) — if this page is opened with
+// credentials in the URL (a saved bookmark / Chrome-remembered basic-auth:
+// https://user:pass@host/…), the browser poisons document.baseURI, so any
+// relative or root-relative fetch('/api/…') throws "Request cannot be constructed
+// from a URL that includes credentials" and callers silently fall to an empty
+// state. Resolve every non-absolute request URL against the credential-free
+// location instead of baseURI. Placed first so it wraps window.fetch before any
+// app script runs. Ref: creds-in-url-fetch-guard-fleet-pattern.
+(function () {
+ var _fetch = window.fetch.bind(window);
+ var cleanBase = function () { return location.origin + location.pathname; };
+ window.fetch = function (input, init) {
+ try {
+ if (typeof input === 'string' && !/^[a-z]+:\/\//i.test(input) && input.indexOf('//') !== 0) {
+ input = new URL(input, cleanBase()).href;
+ } else if (input instanceof Request && !/^[a-z]+:\/\//i.test(input.url)) {
+ input = new Request(new URL(input.url, cleanBase()).href, input);
+ }
+ } catch (_) { /* fall through to native */ }
+ return _fetch(input, init);
+ };
+})();
+</script>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>DTD Review — 42 Gated Memos</title>
+<style>
+ :root{--bg:#0f1115;--card:#191c22;--edge:#2a2f3a;--fg:#e7e9ee;--mut:#9aa2b1;
+ --approve:#2fbf71;--revise:#e0a83a;--block:#e5484d;--hold:#7b8494;}
+ *{box-sizing:border-box}
+ body{margin:0;background:var(--bg);color:var(--fg);font:14px/1.5 -apple-system,Inter,system-ui,sans-serif}
+ header{position:sticky;top:0;z-index:10;background:#12141a;border-bottom:1px solid var(--edge);padding:14px 20px}
+ h1{margin:0 0 4px;font-size:18px;font-weight:600;letter-spacing:.02em}
+ .sub{color:var(--mut);font-size:12px}
+ .tallies{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
+ .pill{border:1px solid var(--edge);border-radius:20px;padding:5px 12px;font-size:12px;cursor:pointer;user-select:none;background:var(--card);color:var(--fg)}
+ .pill.active{border-color:#6672ff;box-shadow:0 0 0 1px #6672ff}
+ .pill b{font-weight:700}
+ .dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;vertical-align:middle}
+ .d-approve{background:var(--approve)} .d-revise{background:var(--revise)} .d-block{background:var(--block)} .d-hold{background:var(--hold)}
+ #q{margin-top:10px;width:100%;max-width:420px;background:#0c0e12;border:1px solid var(--edge);border-radius:6px;color:var(--fg);padding:8px 12px;font-size:13px}
+ main{padding:18px 20px;display:grid;grid-template-columns:repeat(auto-fill,minmax(430px,1fr));gap:14px;align-items:start}
+ .card{background:var(--card);border:1px solid var(--edge);border-radius:10px;padding:14px 16px;border-left-width:4px}
+ .card.v-APPROVE{border-left-color:var(--approve)} .card.v-REVISE{border-left-color:var(--revise)}
+ .card.v-BLOCK{border-left-color:var(--block)} .card.v-HOLD{border-left-color:var(--hold)}
+ .crow{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}
+ .tk{font-size:11px;color:var(--mut);font-family:ui-monospace,Menlo,monospace}
+ .ttl{font-weight:600;font-size:14px;margin:2px 0 8px}
+ .verdict{font-weight:800;font-size:12px;letter-spacing:.06em;padding:3px 9px;border-radius:5px;white-space:nowrap}
+ .verdict.V-APPROVE{background:rgba(47,191,113,.16);color:var(--approve)}
+ .verdict.V-REVISE{background:rgba(224,168,58,.16);color:var(--revise)}
+ .verdict.V-BLOCK{background:rgba(229,72,77,.16);color:var(--block)}
+ .verdict.V-HOLD{background:rgba(123,132,148,.18);color:#c3cad6}
+ .meta{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}
+ .tag{font-size:11px;color:var(--mut);border:1px solid var(--edge);border-radius:4px;padding:2px 7px}
+ .tag.gate{color:#cdd3de}
+ .tag.irrev{color:var(--block);border-color:rgba(229,72,77,.4)}
+ ul{margin:6px 0 0;padding-left:18px} li{margin:3px 0;color:#d3d7e0}
+ .lab{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--mut);margin-top:11px;margin-bottom:2px}
+ .dissent{color:#e6b98a} .next{color:#9fd3ff}
+ .conf{font-family:ui-monospace,Menlo,monospace;font-size:11px;color:var(--mut)}
+ .esc{margin:10px 0 2px;padding:7px 10px;border:1px solid #4a52d6;background:rgba(102,114,255,.12);border-radius:6px;font-size:12px}
+ .esc b{color:#aeb6ff} .esc .escnote{color:#c6cbe6;margin-top:3px;font-size:11px}
+ footer{color:var(--mut);font-size:11px;padding:16px 20px;border-top:1px solid var(--edge)}
+</style>
+</head>
+<body>
+<header>
+ <h1>DTD Review — Gated Approval Queue</h1>
+ <div class="sub">42 memos · adversarial Claude-panel committed verdict each · <span id="stamp"></span> · review-only, nothing executed</div>
+ <div class="tallies" id="tallies"></div>
+ <input id="q" placeholder="filter by ticket, title, gate, next action…">
+</header>
+<main id="grid"></main>
+<footer>Verdict = engineer/operator/skeptic panel + contrarian, converged. Gate class shown per card. Every item stays Steve-gated — say “do X” to fire one. Source: ~/.claude/yolo-queue/pending-approval/</footer>
+<script>
+const order={BLOCK:0,HOLD:1,REVISE:2,APPROVE:3};
+let DATA=[],filterV=null,q='';
+function esc(s){return String(s).replace(/[&<>]/g,c=>({'&':'&','<':'<','>':'>'}[c]))}
+function tallies(){
+ const c={APPROVE:0,REVISE:0,BLOCK:0,HOLD:0};DATA.forEach(d=>c[d.verdict]++);
+ const el=document.getElementById('tallies');el.innerHTML='';
+ [['APPROVE','approve'],['REVISE','revise'],['HOLD','hold'],['BLOCK','block']].forEach(([v,k])=>{
+ const p=document.createElement('div');p.className='pill'+(filterV===v?' active':'');
+ p.innerHTML='<span class="dot d-'+k+'"></span>'+v+' <b>'+c[v]+'</b>';
+ p.onclick=()=>{filterV=filterV===v?null:v;render()};el.appendChild(p);
+ });
+ const all=document.createElement('div');all.className='pill'+(filterV===null?' active':'');
+ all.innerHTML='ALL <b>'+DATA.length+'</b>';all.onclick=()=>{filterV=null;render()};el.appendChild(all);
+}
+function render(){
+ tallies();
+ const g=document.getElementById('grid');g.innerHTML='';
+ DATA.filter(d=>!filterV||d.verdict===filterV)
+ .filter(d=>{if(!q)return true;const s=(d.ticket+' '+d.title+' '+d.gate_class+' '+d.next_action).toLowerCase();return s.includes(q)})
+ .sort((a,b)=>order[a.verdict]-order[b.verdict]||b.confidence-a.confidence)
+ .forEach(d=>{
+ const c=document.createElement('div');c.className='card v-'+d.verdict;
+ c.innerHTML=
+ '<div class="crow"><div><div class="tk">'+esc(d.ticket)+'</div><div class="ttl">'+esc(d.title)+'</div></div>'
+ +'<div class="verdict V-'+d.verdict+'">'+d.verdict+'</div></div>'
+ +'<div class="meta"><span class="tag gate">'+esc(d.gate_class)+'</span>'
+ +'<span class="tag conf">conf '+d.confidence+'%</span>'
+ +'<span class="tag '+(d.reversible?'':'irrev')+'">'+(d.reversible?'reversible':'IRREVERSIBLE')+'</span>'
+ +'<span class="tag">'+esc(d.blast_radius)+'</span></div>'
+ +(d.escalated?'<div class="esc">⚖ EXTERNAL 5-LLM PANEL — <b>'+d.escalated.verdict+'</b> · '+esc(d.escalated.vote)+' · '+esc(d.escalated.confidence)+'<div class="escnote">'+esc(d.escalated.note)+'</div></div>':'')
+ +'<div class="lab">panel</div><ul>'+d.panel_rationale.map(r=>'<li>'+esc(r)+'</li>').join('')+'</ul>'
+ +'<div class="lab">dissent</div><div class="dissent">'+esc(d.dissent)+'</div>'
+ +'<div class="lab">next action</div><div class="next">'+esc(d.next_action)+'</div>';
+ g.appendChild(c);
+ });
+}
+document.getElementById('q').addEventListener('input',e=>{q=e.target.value.toLowerCase();render()});
+fetch('data.json').then(r=>r.json()).then(d=>{DATA=d;document.getElementById('stamp').textContent=DATA.length+' reviewed';render()});
+</script>
+</body>
+</html>
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..dbb0b8a
--- /dev/null
+++ b/server.js
@@ -0,0 +1,16 @@
+const http=require('http'),fs=require('fs'),path=require('path');
+const USER='admin',PASS='DW2024!',DIR=__dirname;
+const PORT=process.env.PORT||9791;
+const TYPES={'.html':'text/html','.json':'application/json','.js':'text/javascript','.css':'text/css'};
+http.createServer((req,res)=>{
+ const auth=req.headers.authorization||'';
+ const [u,p]=Buffer.from(auth.split(' ')[1]||'',
+ 'base64').toString().split(':');
+ if(u!==USER||p!==PASS){res.writeHead(401,{'WWW-Authenticate':'Basic realm="DTD"'});return res.end('auth required')}
+ let f=decodeURIComponent((req.url.split('?')[0])||'/');
+ if(f==='/'||f==='')f='/index.html';
+ const fp=path.join(DIR,path.normalize(f).replace(/^\/+/,''));
+ if(!fp.startsWith(DIR)||!fs.existsSync(fp)){res.writeHead(404);return res.end('not found')}
+ res.writeHead(200,{'Content-Type':TYPES[path.extname(fp)]||'application/octet-stream'});
+ fs.createReadStream(fp).pipe(res);
+}).listen(PORT,'0.0.0.0',()=>console.log('DTD viewer on http://127.0.0.1:'+PORT+' (admin/DW2024!)'));
(oldest)
·
back to Dtd Approval Viewer
·
(newest)