← back to Approval Viewer
verify approval viewer across five local sweeps
c103c1525b2d87a5a4d411b14d2cdc3d905c604e · 2026-08-31 01:54:02 -0700 · Steve Abrams
Files touched
M server.jsA verification/tk10995-five-sweeps.jsonA verification/tk10995-five-sweeps.mjs
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 →