[object Object]

← back to Approval Viewer

verify approval viewer across five local sweeps

c103c1525b2d87a5a4d411b14d2cdc3d905c604e · 2026-08-31 01:54:02 -0700 · Steve Abrams

Files touched

Diff

commit c103c1525b2d87a5a4d411b14d2cdc3d905c604e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 31 01:54:02 2026 -0700

    verify approval viewer across five local sweeps
---
 server.js                             |   1 +
 verification/tk10995-five-sweeps.json | 113 ++++++++++++++++++++++++++++++++++
 verification/tk10995-five-sweeps.mjs  |  94 ++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+)

diff --git a/server.js b/server.js
index 3555bd6..12523bc 100644
--- a/server.js
+++ b/server.js
@@ -29,6 +29,7 @@ function readDecisions(){ try{return fs.readFileSync(decisionsPath,'utf8').trim(
 function send(res,status,data,type='application/json'){res.writeHead(status,{'Content-Type':type});res.end(type==='application/json'?JSON.stringify(data):data);}
 function body(req){return new Promise(resolve=>{let s='';req.on('data',c=>s+=c);req.on('end',()=>resolve(s));});}
 const server=http.createServer(async (req,res)=>{
+  if(req.method==='GET' && req.url==='/favicon.ico') { res.writeHead(204); return res.end(); }
   if(req.method==='GET' && (req.url==='/'||req.url==='/index.html')) return send(res,200,fs.readFileSync(path.join(__dirname,'public/index.html'),'utf8'),'text/html; charset=utf-8');
   if(req.method==='GET' && req.url==='/api/items') return send(res,200,{items:items(),decisions:readDecisions(),writePerformed:false,source:queueItems().length?'pending-approval':'demo'});
   if(req.method==='POST' && req.url==='/api/decision'){
diff --git a/verification/tk10995-five-sweeps.json b/verification/tk10995-five-sweeps.json
new file mode 100644
index 0000000..cd67701
--- /dev/null
+++ b/verification/tk10995-five-sweeps.json
@@ -0,0 +1,113 @@
+{
+  "ticket": "TK-10995",
+  "intent": "Five local end-to-end verification sweeps of the approval viewer",
+  "riskTier": "R2 local user-facing flow",
+  "environment": "http://127.0.0.1:9788",
+  "startedAt": "2026-08-31T08:51:26.595Z",
+  "finishedAt": "2026-08-31T08:51:26.766Z",
+  "constraints": {
+    "emailSent": false,
+    "spendUsd": 0,
+    "productionActions": false
+  },
+  "sweeps": [
+    {
+      "pass": 1,
+      "verdict": "PASS",
+      "correlationId": "TK-10995-sweep-1-1788166286596",
+      "itemId": "QUEUE-070926-gmc-orphan-reconcile-2026-08-31.md",
+      "source": "pending-approval",
+      "rootStatus": 200,
+      "faviconStatus": 204,
+      "itemsStatus": 200,
+      "invalidJsonStatus": 400,
+      "unknownItemStatus": 404,
+      "recordStatus": 200,
+      "persisted": true,
+      "externalWritePerformed": false
+    },
+    {
+      "pass": 2,
+      "verdict": "PASS",
+      "correlationId": "TK-10995-sweep-2-1788166286658",
+      "itemId": "QUEUE-070926-gmc-orphan-reconcile-2026-08-31.md",
+      "source": "pending-approval",
+      "rootStatus": 200,
+      "faviconStatus": 204,
+      "itemsStatus": 200,
+      "invalidJsonStatus": 400,
+      "unknownItemStatus": 404,
+      "recordStatus": 200,
+      "persisted": true,
+      "externalWritePerformed": false
+    },
+    {
+      "pass": 3,
+      "verdict": "PASS",
+      "correlationId": "TK-10995-sweep-3-1788166286687",
+      "itemId": "QUEUE-070926-gmc-orphan-reconcile-2026-08-31.md",
+      "source": "pending-approval",
+      "rootStatus": 200,
+      "faviconStatus": 204,
+      "itemsStatus": 200,
+      "invalidJsonStatus": 400,
+      "unknownItemStatus": 404,
+      "recordStatus": 200,
+      "persisted": true,
+      "externalWritePerformed": false
+    },
+    {
+      "pass": 4,
+      "verdict": "PASS",
+      "correlationId": "TK-10995-sweep-4-1788166286714",
+      "itemId": "QUEUE-070926-gmc-orphan-reconcile-2026-08-31.md",
+      "source": "pending-approval",
+      "rootStatus": 200,
+      "faviconStatus": 204,
+      "itemsStatus": 200,
+      "invalidJsonStatus": 400,
+      "unknownItemStatus": 404,
+      "recordStatus": 200,
+      "persisted": true,
+      "externalWritePerformed": false
+    },
+    {
+      "pass": 5,
+      "verdict": "PASS",
+      "correlationId": "TK-10995-sweep-5-1788166286740",
+      "itemId": "QUEUE-070926-gmc-orphan-reconcile-2026-08-31.md",
+      "source": "pending-approval",
+      "rootStatus": 200,
+      "faviconStatus": 204,
+      "itemsStatus": 200,
+      "invalidJsonStatus": 400,
+      "unknownItemStatus": 404,
+      "recordStatus": 200,
+      "persisted": true,
+      "externalWritePerformed": false
+    }
+  ],
+  "browserProof": {
+    "tool": "3x",
+    "verdict": "PASS",
+    "attempted": 4,
+    "passed": 4,
+    "skipped": 2,
+    "checks": [
+      "HTTP contract",
+      "headless Chrome render",
+      "Playwright revise-button interaction with zero JavaScript errors",
+      "Google Chrome cross-browser render"
+    ],
+    "artifacts": "/var/folders/rq/j8g1f7nn6jv6_lr1cfmqym6w0000gn/T/3x-662aZO"
+  },
+  "service": {
+    "manager": "PM2",
+    "name": "approval-viewer",
+    "port": 9788,
+    "rootStatus": 200,
+    "faviconStatus": 204
+  },
+  "cleanup": "Removed the five correlated local test decisions and the one browser-click test decision after persistence was proven; pre-existing decision history was preserved.",
+  "verdict": "PASS"
+}
diff --git a/verification/tk10995-five-sweeps.mjs b/verification/tk10995-five-sweeps.mjs
new file mode 100644
index 0000000..7901077
--- /dev/null
+++ b/verification/tk10995-five-sweeps.mjs
@@ -0,0 +1,94 @@
+import fs from 'node:fs';
+
+const base = 'http://127.0.0.1:9788';
+const evidencePath = new URL('./tk10995-five-sweeps.json', import.meta.url);
+
+function assert(condition, message) {
+  if (!condition) throw new Error(message);
+}
+
+async function request(path, options = {}) {
+  const response = await fetch(`${base}${path}`, options);
+  const text = await response.text();
+  let json = null;
+  try { json = JSON.parse(text); } catch {}
+  return { status: response.status, text, json };
+}
+
+const startedAt = new Date().toISOString();
+const sweeps = [];
+
+for (let pass = 1; pass <= 5; pass += 1) {
+  const correlationId = `TK-10995-sweep-${pass}-${Date.now()}`;
+  const root = await request('/');
+  assert(root.status === 200, `sweep ${pass}: root status ${root.status}`);
+  assert(root.text.includes('Gated approvals'), `sweep ${pass}: root UI missing title`);
+  assert(root.text.includes('do not publish, email, spend, deploy, delete'), `sweep ${pass}: safe-mode rail missing`);
+
+  const favicon = await request('/favicon.ico');
+  assert(favicon.status === 204, `sweep ${pass}: favicon status ${favicon.status}`);
+
+  const before = await request('/api/items');
+  assert(before.status === 200, `sweep ${pass}: items status ${before.status}`);
+  assert(Array.isArray(before.json?.items) && before.json.items.length > 0, `sweep ${pass}: no items`);
+  assert(before.json.writePerformed === false, `sweep ${pass}: GET claimed a write`);
+  const item = before.json.items[0];
+  assert(item.created_at, `sweep ${pass}: admin card data lacks created_at`);
+
+  const invalid = await request('/api/decision', {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: '{not-json',
+  });
+  assert(invalid.status === 400 && invalid.json?.error === 'invalid json', `sweep ${pass}: invalid JSON was not rejected`);
+
+  const unknown = await request('/api/decision', {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: JSON.stringify({ id: `UNKNOWN-${correlationId}`, action: 'revise' }),
+  });
+  assert(unknown.status === 404 && unknown.json?.error === 'unknown item', `sweep ${pass}: unknown item was not rejected`);
+
+  const recorded = await request('/api/decision', {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: JSON.stringify({ id: item.id, action: 'revise', note: correlationId }),
+  });
+  assert(recorded.status === 200 && recorded.json?.ok === true, `sweep ${pass}: local decision was not recorded`);
+  assert(recorded.json?.writePerformed === false, `sweep ${pass}: response claimed an external write`);
+
+  const after = await request('/api/items');
+  const persisted = after.json?.decisions?.find((decision) => decision.note === correlationId);
+  assert(persisted?.id === item.id && persisted?.action === 'revise', `sweep ${pass}: decision did not persist`);
+
+  sweeps.push({
+    pass,
+    verdict: 'PASS',
+    correlationId,
+    itemId: item.id,
+    source: before.json.source,
+    rootStatus: root.status,
+    faviconStatus: favicon.status,
+    itemsStatus: before.status,
+    invalidJsonStatus: invalid.status,
+    unknownItemStatus: unknown.status,
+    recordStatus: recorded.status,
+    persisted: true,
+    externalWritePerformed: false,
+  });
+}
+
+const result = {
+  ticket: 'TK-10995',
+  intent: 'Five local end-to-end verification sweeps of the approval viewer',
+  riskTier: 'R2 local user-facing flow',
+  environment: base,
+  startedAt,
+  finishedAt: new Date().toISOString(),
+  constraints: { emailSent: false, spendUsd: 0, productionActions: false },
+  sweeps,
+  verdict: sweeps.length === 5 && sweeps.every((sweep) => sweep.verdict === 'PASS') ? 'PASS' : 'FAIL',
+};
+
+fs.writeFileSync(evidencePath, `${JSON.stringify(result, null, 2)}\n`);
+console.log(JSON.stringify(result, null, 2));

← 8f90371 snapshot before TK-10995 five-pass verification  ·  back to Approval Viewer  ·  auto-data-snapshot: 2026-08-31T02:00:54 (1 data files) — dec 52d1c00 →