← back to Dw Signup Fulfillment
Retire obsolete theme commands that could undo designer signup
dc1323fb12536ab29ccd276a2f909b574fdcc742 · 2026-09-05 00:23:03 -0700 · Steve Abrams
Files touched
M scripts/gate2-theme-put.mjsM scripts/gate2-theme-rollback.mjsA verification/tk11185-reconcile/RETIRED-COMMANDS.mdA verification/tk11185-reconcile/retired-boundaries.cjsA verification/tk11185-reconcile/retired-check.cjsA verification/tk11185-reconcile/retired-e2e-proof.json
Diff
commit dc1323fb12536ab29ccd276a2f909b574fdcc742
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Sep 5 00:23:03 2026 -0700
Retire obsolete theme commands that could undo designer signup
---
scripts/gate2-theme-put.mjs | 36 +--
scripts/gate2-theme-rollback.mjs | 25 +--
verification/tk11185-reconcile/RETIRED-COMMANDS.md | 29 +++
.../tk11185-reconcile/retired-boundaries.cjs | 35 +++
verification/tk11185-reconcile/retired-check.cjs | 106 +++++++++
.../tk11185-reconcile/retired-e2e-proof.json | 249 +++++++++++++++++++++
6 files changed, 439 insertions(+), 41 deletions(-)
diff --git a/scripts/gate2-theme-put.mjs b/scripts/gate2-theme-put.mjs
index 78c0eed..7c9637f 100644
--- a/scripts/gate2-theme-put.mjs
+++ b/scripts/gate2-theme-put.mjs
@@ -1,26 +1,10 @@
-// TK-11185 GATE 2 — live theme PUT of the patched trade-apply success handler.
-// Confirms 145121607731 is the live/main theme before writing (aborts on mismatch).
-// cwd-independent (absolute paths); token read inside Node (no shell quoting).
-import fs from "fs";
-import os from "os";
-const ROOT = os.homedir() + "/Projects/dw-signup-fulfillment";
-const env = fs.readFileSync(os.homedir() + "/Projects/secrets-manager/.env", "utf8");
-const TT = (env.match(/^SHOPIFY_THEME_TOKEN=(.*)$/m) || [])[1].replace(/^"|"$/g, "").trim();
-const DOMAIN = "designer-laboratory-sandbox.myshopify.com", VER = "2024-10", THEME = "145121607731";
-const H = { "X-Shopify-Access-Token": TT };
-
-const tj = await (await fetch(`https://${DOMAIN}/admin/api/${VER}/themes.json`, { headers: H })).json();
-const main = (tj.themes || []).find(t => t.role === "main");
-console.log("live/main theme:", main && main.id, main && main.name);
-if (!main || String(main.id) !== THEME) {
- console.error("ABORT: main theme is", main && main.id, "expected", THEME, "— do not PUT.");
- process.exit(1);
-}
-const value = fs.readFileSync(ROOT + "/theme-proposals/loggedin-trade-entry/dw-signin-modal.PATCHED-tk11185.liquid", "utf8");
-const r = await fetch(`https://${DOMAIN}/admin/api/${VER}/themes/${THEME}/assets.json`, {
- method: "PUT",
- headers: { ...H, "Content-Type": "application/json" },
- body: JSON.stringify({ asset: { key: "snippets/dw-signin-modal.liquid", value } }),
-});
-const j = await r.json();
-console.log("HTTP", r.status, j.asset ? ("PUT OK " + j.asset.key + " @ " + j.asset.updated_at) : JSON.stringify(j));
+// Retired TK-11185 command. Historical source: git show 5e609e8:scripts/gate2-theme-put.mjs
+// Keep inert: no imports, credential reads, network, or forwarding.
+console.error(`SUPERSEDED: TK-11185 theme PUT is retired (exit 78).
+TK-11283 published the required designer form and account/login flow. This old command would overwrite it.
+Read-only Shopify status (run from any directory):
+ node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status
+For the current guarded deploy/rollback procedure and approval requirements, read:
+ ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md
+No credentials were read and no Shopify request was made.`);
+process.exitCode = 78;
diff --git a/scripts/gate2-theme-rollback.mjs b/scripts/gate2-theme-rollback.mjs
index a35570c..ece8233 100644
--- a/scripts/gate2-theme-rollback.mjs
+++ b/scripts/gate2-theme-rollback.mjs
@@ -1,15 +1,10 @@
-// TK-11185 GATE 2 ROLLBACK — re-PUT the pre-change live snapshot of dw-signin-modal.liquid.
-import fs from "fs";
-import os from "os";
-const ROOT = os.homedir() + "/Projects/dw-signup-fulfillment";
-const env = fs.readFileSync(os.homedir() + "/Projects/secrets-manager/.env", "utf8");
-const TT = (env.match(/^SHOPIFY_THEME_TOKEN=(.*)$/m) || [])[1].replace(/^"|"$/g, "").trim();
-const DOMAIN = "designer-laboratory-sandbox.myshopify.com", VER = "2024-10", THEME = "145121607731";
-const value = fs.readFileSync(ROOT + "/theme-backups/live-snapshots/snippets__dw-signin-modal.liquid.20260903T181955.bak", "utf8");
-const r = await fetch(`https://${DOMAIN}/admin/api/${VER}/themes/${THEME}/assets.json`, {
- method: "PUT",
- headers: { "X-Shopify-Access-Token": TT, "Content-Type": "application/json" },
- body: JSON.stringify({ asset: { key: "snippets/dw-signin-modal.liquid", value } }),
-});
-const j = await r.json();
-console.log("HTTP", r.status, j.asset ? ("ROLLBACK OK " + j.asset.updated_at) : JSON.stringify(j));
+// Retired TK-11185 command. Historical source: git show 5e609e8:scripts/gate2-theme-rollback.mjs
+// Keep inert: no imports, credential reads, network, or forwarding.
+console.error(`SUPERSEDED: TK-11185 theme rollback is retired (exit 78).
+TK-11283 published the required designer form and account/login flow. This old command would overwrite it.
+Read-only Shopify status (run from any directory):
+ node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status
+For the current guarded deploy/rollback procedure and approval requirements, read:
+ ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md
+No credentials were read and no Shopify request was made.`);
+process.exitCode = 78;
diff --git a/verification/tk11185-reconcile/RETIRED-COMMANDS.md b/verification/tk11185-reconcile/RETIRED-COMMANDS.md
new file mode 100644
index 0000000..d88f829
--- /dev/null
+++ b/verification/tk11185-reconcile/RETIRED-COMMANDS.md
@@ -0,0 +1,29 @@
+# Retired TK-11185 theme commands
+
+`scripts/gate2-theme-put.mjs` and `scripts/gate2-theme-rollback.mjs` are intentionally retired. Both print a superseded message and exit 78 before imports, credential reads, network requests, or forwarding. Extra flags do not reactivate them.
+
+TK-11283 published the required full designer application and account/login flow. The former PUT checked only the main theme ID; the former rollback checked neither the main theme nor the current asset. Both could replace newer content with a historical snippet. Original files remain recoverable through `git show 5e609e8:scripts/gate2-theme-put.mjs` and the corresponding rollback path for historical review. Do not execute recovered historical scripts.
+
+## Current supported procedure
+
+Read current Shopify values using the guarded tool from any directory:
+
+```sh
+node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status
+```
+
+This mode performs Shopify GETs and saves current snapshots locally. Retired commands display this command; they never invoke it. Review [TK-11283 evidence](../tk11283/REVIEW.md), its preserved baselines, and current hashes before considering any change.
+
+The unchanged `verification/tk11283/publish-theme.cjs` owns the current two-asset deploy/rollback workflow. Its `--apply` and `--rollback` modes mutate the live theme and require explicit authorization for the exact action. Preserve its baseline, theme identity, content-hash, review-evidence and post-write checks. Retirement is not permission to run either mode.
+
+## Verification and limits
+
+```sh
+node --experimental-vm-modules verification/tk11185-reconcile/retired-check.cjs
+```
+
+The runner loads actual historical modules from Git in an isolated VM with synthetic `fs`/`os` imports and mocked Shopify responses. It starts with the current proposed designer-flow body and proves the historical commands overwrite it without inspecting its current value. No real credential or API is used.
+
+It then invokes each real retired entrypoint with Node, including `--apply` and `--rollback`, from the repository and `/private/tmp`. A preload blocks and records application file/credential and network attempts; plain invocations verify normal startup. Assertions require exit78, a superseded message, zero app-file/network attempts, and an unchanged guarded tool. Results are in [retired-e2e-proof.json](retired-e2e-proof.json).
+
+A repository-wide `rg` search found no callers of these exact filenames before retirement. This is local inventory only; external pasted commands or automation are not exhaustively inventoried. Exit78 deliberately reports failure to those callers and should not be retried. No customer/account/OTP journey changed. TK-11185's separate retained production smoke-record cleanup remains with the parent ticket; this report does not claim the whole ticket complete.
diff --git a/verification/tk11185-reconcile/retired-boundaries.cjs b/verification/tk11185-reconcile/retired-boundaries.cjs
new file mode 100644
index 0000000..0f153e3
--- /dev/null
+++ b/verification/tk11185-reconcile/retired-boundaries.cjs
@@ -0,0 +1,35 @@
+'use strict';
+// Preload the real entrypoint; reject and count all app file/network attempts.
+const fs = require('node:fs'), path = require('node:path');
+const { fileURLToPath } = require('node:url');
+const { syncBuiltinESMExports } = require('node:module');
+const entry = path.resolve(process.env.TK_RETIRE_ALLOWED_ENTRY);
+const audit = { entryLoads: 0, appFileAttempts: [], networkAttempts: [] };
+function checkFile(value) {
+ const filename = value instanceof URL ? fileURLToPath(value) : String(value);
+ if (path.resolve(filename) === entry) { audit.entryLoads++; return; }
+ audit.appFileAttempts.push(filename);
+ throw new Error('Unexpected application file access');
+}
+for (const name of ['readFileSync', 'readFile', 'openSync', 'open', 'createReadStream']) {
+ const original = fs[name];
+ fs[name] = function (filename, ...args) { checkFile(filename); return original.call(this, filename, ...args); };
+}
+for (const name of ['readFile', 'open']) {
+ const original = fs.promises[name];
+ fs.promises[name] = function (filename, ...args) { checkFile(filename); return original.call(this, filename, ...args); };
+}
+function blockNetwork(name) {
+ return function () { audit.networkAttempts.push(name); throw new Error('Network is forbidden in retirement proof'); };
+}
+globalThis.fetch = blockNetwork('fetch');
+for (const [moduleName, methods] of Object.entries({
+ 'node:http': ['request', 'get'], 'node:https': ['request', 'get'],
+ 'node:net': ['connect', 'createConnection'], 'node:tls': ['connect'],
+ 'node:dns': ['lookup', 'resolve'],
+})) {
+ const target = require(moduleName);
+ for (const name of methods) target[name] = blockNetwork(moduleName + '.' + name);
+}
+syncBuiltinESMExports();
+process.on('exit', () => process.stderr.write('\nRETIREMENT_BOUNDARY_AUDIT=' + JSON.stringify(audit) + '\n'));
diff --git a/verification/tk11185-reconcile/retired-check.cjs b/verification/tk11185-reconcile/retired-check.cjs
new file mode 100644
index 0000000..13cd301
--- /dev/null
+++ b/verification/tk11185-reconcile/retired-check.cjs
@@ -0,0 +1,106 @@
+'use strict';
+// Historical modules use synthetic imports; real current commands deny access.
+const fs = require('node:fs'), path = require('node:path'), vm = require('node:vm');
+const crypto = require('node:crypto'), assert = require('node:assert/strict');
+const { execFileSync, spawnSync } = require('node:child_process');
+const root = path.resolve(__dirname, '../..');
+const sha = value => crypto.createHash('sha256').update(value).digest('hex');
+const history = '5e609e8';
+const git = (...args) => execFileSync('git', args, { cwd: root, encoding: 'utf8' });
+const report = {
+ intent: 'Retire obsolete theme writes and preserve the current guarded tool',
+ risk: 'R1 local command; R3 external boundary tested with denied/mock APIs',
+ environment: { node: process.version, platform: process.platform, root },
+ timestamp: new Date().toISOString(), baselineCommit: history, buildBase: git('rev-parse', 'HEAD').trim(),
+ command: 'node --experimental-vm-modules verification/tk11185-reconcile/retired-check.cjs',
+ baseline: [], invocations: [], assertions: [],
+ cleanup: 'No real API calls, customers, emails, or production mutations. No temporary records.',
+ scope: 'Retirement only; TK11185 production smoke-record cleanup remains with the parent.',
+};
+async function reproduce(name, fixtureRelative) {
+ const file = 'scripts/' + name, source = git('show', history + ':' + file);
+ const historical = fs.readFileSync(path.join(root, fixtureRelative), 'utf8');
+ const published = fs.readFileSync(path.join(root, 'theme-proposals/designer-signin-tk11283/snippets/dw-signin-modal.liquid'), 'utf8');
+ assert.notEqual(sha(historical), sha(published));
+ let live = published;
+ const reads = [], calls = [], output = [], fakeHome = '/retirement-fixture';
+ const fakeFS = { readFileSync(filename) {
+ reads.push(filename);
+ if (filename === fakeHome + '/Projects/secrets-manager/.env') return 'SHOPIFY_THEME_TOKEN=dummy-test-token\n';
+ if (filename === fakeHome + '/Projects/dw-signup-fulfillment/' + fixtureRelative) return historical;
+ throw new Error('Unallowed fixture file: ' + filename);
+ } };
+ const context = vm.createContext({
+ console: { log: (...args) => output.push(args.join(' ')), error: (...args) => output.push(args.join(' ')) },
+ process: { exit(code) { throw new Error('Unexpected process.exit ' + code); } },
+ fetch: async (url, options = {}) => {
+ const method = options.method || 'GET', call = { method, url };
+ calls.push(call);
+ if (url.endsWith('/themes.json') && method === 'GET') return { json: async () => ({ themes: [{ role: 'main', id: 145121607731, name: 'fixture-main' }] }) };
+ if (url.endsWith('/assets.json') && method === 'PUT') {
+ const { asset } = JSON.parse(options.body);
+ assert.equal(asset.key, 'snippets/dw-signin-modal.liquid');
+ call.valueSHA256 = sha(asset.value);
+ live = asset.value;
+ return { status: 200, json: async () => ({ asset: { key: asset.key, updated_at: 'fixture-only' } }) };
+ }
+ throw new Error('Unexpected mock API access');
+ },
+ });
+ const module = new vm.SourceTextModule(source, { context, identifier: file });
+ await module.link(specifier => {
+ assert.ok(['fs', 'os'].includes(specifier), 'Only synthetic imports');
+ const value = specifier === 'fs' ? fakeFS : { homedir: () => fakeHome };
+ return new vm.SyntheticModule(['default'], function () { this.setExport('default', value); }, { context });
+ });
+ await module.evaluate();
+ assert.equal(live, historical, 'Original overwrites the newer published body');
+ assert.equal(calls.filter(x => x.method === 'PUT').length, 1);
+ assert.equal(calls.filter(x => x.method === 'GET' && x.url.includes('/assets')).length, 0, 'No current-content check');
+ report.baseline.push({ file, sourceSHA256: sha(source), publishedBeforeSHA256: sha(published), staleAfterSHA256: sha(live), reads, calls, output, reproduced: true });
+}
+async function main() {
+ await reproduce('gate2-theme-put.mjs', 'theme-proposals/loggedin-trade-entry/dw-signin-modal.PATCHED-tk11185.liquid');
+ await reproduce('gate2-theme-rollback.mjs', 'theme-backups/live-snapshots/snippets__dw-signin-modal.liquid.20260903T181955.bak');
+ const guardPath = 'verification/tk11283/publish-theme.cjs';
+ assert.equal(fs.readFileSync(path.join(root, guardPath), 'utf8'), git('show', 'HEAD:' + guardPath), 'Supported tool has no edits');
+ report.guardedToolSHA256 = sha(fs.readFileSync(path.join(root, guardPath)));
+ for (const name of ['gate2-theme-put.mjs', 'gate2-theme-rollback.mjs']) {
+ const entry = path.join(root, 'scripts', name);
+ for (const args of [[], ['--apply'], ['--rollback']]) {
+ const cwd = args.length ? '/private/tmp' : root;
+ const command = ['--require', path.join(__dirname, 'retired-boundaries.cjs'), entry, ...args];
+ const result = spawnSync(process.execPath, command, { cwd, encoding: 'utf8', timeout: 5000,
+ env: { PATH: process.env.PATH, TK_RETIRE_ALLOWED_ENTRY: entry } });
+ assert.ifError(result.error);
+ assert.equal(result.status, 78, name + ' must exit78');
+ assert.match(result.stderr, /SUPERSEDED/);
+ assert.match(result.stderr, /TK-11283/);
+ assert.match(result.stderr, /publish-theme\.cjs --status/);
+ assert.equal(result.stdout, '');
+ const auditLine = result.stderr.split('\n').find(line => line.startsWith('RETIREMENT_BOUNDARY_AUDIT='));
+ assert.ok(auditLine, 'Preload audit actually ran');
+ const audit = JSON.parse(auditLine.slice('RETIREMENT_BOUNDARY_AUDIT='.length));
+ assert.deepEqual(audit.appFileAttempts, [], 'No credential or application file reads');
+ assert.deepEqual(audit.networkAttempts, [], 'No network attempts');
+ report.invocations.push({ entry, args, cwd, exitCode: result.status, signal: result.signal,
+ command: [process.execPath, ...command], stderr: result.stderr, audit, sourceSHA256: sha(fs.readFileSync(entry)), verdict: 'PASS' });
+ }
+ const plain = spawnSync(process.execPath, [entry], { cwd: '/private/tmp', encoding: 'utf8', timeout: 5000, env: { PATH: process.env.PATH } });
+ assert.equal(plain.status, 78);
+ assert.match(plain.stderr, /SUPERSEDED/);
+ report.invocations.push({ entry, mode: 'plain direct Node, no preload', cwd: '/private/tmp', exitCode: plain.status, stderr: plain.stderr, verdict: 'PASS' });
+ }
+ report.assertions = [
+ { boundary: 'Historical fs/API', verdict: 'PASS', reason: 'Actual original sources read dummy credentials then overwrite newer body without checking current hash.' },
+ { boundary: 'Real CLI process', verdict: 'PASS', reason: 'Both exit78 from repository or unrelated cwd, even with apply/rollback flags.' },
+ { boundary: 'Credentials/files/network', verdict: 'PASS', reason: 'Six instrumented invocations report zero app file/network attempts.' },
+ { boundary: 'Supported tooling', verdict: 'PASS', reason: 'TK11283 guarded deploy/rollback tool byte-identical to HEAD.' },
+ { boundary: 'UI', verdict: 'N/A', reason: 'No storefront/UI changes.' },
+ ];
+ report.verdict = 'PASS';
+ fs.writeFileSync(path.join(__dirname, 'retired-e2e-proof.json'), JSON.stringify(report, null, 2) + '\n');
+ console.log(JSON.stringify({ verdict: report.verdict, historicalReproductions: report.baseline.length, directInvocations: report.invocations.length, networkCalls: 0,
+ evidence: path.join(__dirname, 'retired-e2e-proof.json') }, null, 2));
+}
+main().catch(error => { console.error(error); process.exitCode = 1; });
diff --git a/verification/tk11185-reconcile/retired-e2e-proof.json b/verification/tk11185-reconcile/retired-e2e-proof.json
new file mode 100644
index 0000000..5ef958f
--- /dev/null
+++ b/verification/tk11185-reconcile/retired-e2e-proof.json
@@ -0,0 +1,249 @@
+{
+ "intent": "Retire obsolete theme writes and preserve the current guarded tool",
+ "risk": "R1 local command; R3 external boundary tested with denied/mock APIs",
+ "environment": {
+ "node": "v26.4.0",
+ "platform": "darwin",
+ "root": "/Users/macstudio3/Projects/dw-signup-fulfillment"
+ },
+ "timestamp": "2026-09-05T07:22:49.286Z",
+ "baselineCommit": "5e609e8",
+ "buildBase": "8a877d4ed47ea559582c0944a702e60a8a6d927a",
+ "command": "node --experimental-vm-modules verification/tk11185-reconcile/retired-check.cjs",
+ "baseline": [
+ {
+ "file": "scripts/gate2-theme-put.mjs",
+ "sourceSHA256": "ef79df61e957697626f8b52b727ec23e4ea497563325c9ca0e62777e2362e758",
+ "publishedBeforeSHA256": "42e67a0e45ca602a2e23fd482ac2ecaefc17ab458d6440d9bfe4a206332999a0",
+ "staleAfterSHA256": "6108eff129c244b9c96b831e14479b5626b26a8ce32a4b3d79fca36ee560f3a6",
+ "reads": [
+ "/retirement-fixture/Projects/secrets-manager/.env",
+ "/retirement-fixture/Projects/dw-signup-fulfillment/theme-proposals/loggedin-trade-entry/dw-signin-modal.PATCHED-tk11185.liquid"
+ ],
+ "calls": [
+ {
+ "method": "GET",
+ "url": "https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/themes.json"
+ },
+ {
+ "method": "PUT",
+ "url": "https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/themes/145121607731/assets.json",
+ "valueSHA256": "6108eff129c244b9c96b831e14479b5626b26a8ce32a4b3d79fca36ee560f3a6"
+ }
+ ],
+ "output": [
+ "live/main theme: 145121607731 fixture-main",
+ "HTTP 200 PUT OK snippets/dw-signin-modal.liquid @ fixture-only"
+ ],
+ "reproduced": true
+ },
+ {
+ "file": "scripts/gate2-theme-rollback.mjs",
+ "sourceSHA256": "39f2ff000e502a18447bfee5d8d97fd11d4eb51f5d4732af7e92953ec7c313e0",
+ "publishedBeforeSHA256": "42e67a0e45ca602a2e23fd482ac2ecaefc17ab458d6440d9bfe4a206332999a0",
+ "staleAfterSHA256": "b69ff27a64730532a22e30a4e0f30eb116da0a7317e60d7052e1cb1657b52305",
+ "reads": [
+ "/retirement-fixture/Projects/secrets-manager/.env",
+ "/retirement-fixture/Projects/dw-signup-fulfillment/theme-backups/live-snapshots/snippets__dw-signin-modal.liquid.20260903T181955.bak"
+ ],
+ "calls": [
+ {
+ "method": "PUT",
+ "url": "https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/themes/145121607731/assets.json",
+ "valueSHA256": "b69ff27a64730532a22e30a4e0f30eb116da0a7317e60d7052e1cb1657b52305"
+ }
+ ],
+ "output": [
+ "HTTP 200 ROLLBACK OK fixture-only"
+ ],
+ "reproduced": true
+ }
+ ],
+ "invocations": [
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-put.mjs",
+ "args": [],
+ "cwd": "/Users/macstudio3/Projects/dw-signup-fulfillment",
+ "exitCode": 78,
+ "signal": null,
+ "command": [
+ "/opt/homebrew/Cellar/node/26.4.0/bin/node",
+ "--require",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/retired-boundaries.cjs",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-put.mjs"
+ ],
+ "stderr": "SUPERSEDED: TK-11185 theme PUT is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n\nRETIREMENT_BOUNDARY_AUDIT={\"entryLoads\":2,\"appFileAttempts\":[],\"networkAttempts\":[]}\n",
+ "audit": {
+ "entryLoads": 2,
+ "appFileAttempts": [],
+ "networkAttempts": []
+ },
+ "sourceSHA256": "a2a84c428210606345fb1115ecb7bb3122f221471cedf136959d0eafa55c054c",
+ "verdict": "PASS"
+ },
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-put.mjs",
+ "args": [
+ "--apply"
+ ],
+ "cwd": "/private/tmp",
+ "exitCode": 78,
+ "signal": null,
+ "command": [
+ "/opt/homebrew/Cellar/node/26.4.0/bin/node",
+ "--require",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/retired-boundaries.cjs",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-put.mjs",
+ "--apply"
+ ],
+ "stderr": "SUPERSEDED: TK-11185 theme PUT is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n\nRETIREMENT_BOUNDARY_AUDIT={\"entryLoads\":2,\"appFileAttempts\":[],\"networkAttempts\":[]}\n",
+ "audit": {
+ "entryLoads": 2,
+ "appFileAttempts": [],
+ "networkAttempts": []
+ },
+ "sourceSHA256": "a2a84c428210606345fb1115ecb7bb3122f221471cedf136959d0eafa55c054c",
+ "verdict": "PASS"
+ },
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-put.mjs",
+ "args": [
+ "--rollback"
+ ],
+ "cwd": "/private/tmp",
+ "exitCode": 78,
+ "signal": null,
+ "command": [
+ "/opt/homebrew/Cellar/node/26.4.0/bin/node",
+ "--require",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/retired-boundaries.cjs",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-put.mjs",
+ "--rollback"
+ ],
+ "stderr": "SUPERSEDED: TK-11185 theme PUT is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n\nRETIREMENT_BOUNDARY_AUDIT={\"entryLoads\":2,\"appFileAttempts\":[],\"networkAttempts\":[]}\n",
+ "audit": {
+ "entryLoads": 2,
+ "appFileAttempts": [],
+ "networkAttempts": []
+ },
+ "sourceSHA256": "a2a84c428210606345fb1115ecb7bb3122f221471cedf136959d0eafa55c054c",
+ "verdict": "PASS"
+ },
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-put.mjs",
+ "mode": "plain direct Node, no preload",
+ "cwd": "/private/tmp",
+ "exitCode": 78,
+ "stderr": "SUPERSEDED: TK-11185 theme PUT is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n",
+ "verdict": "PASS"
+ },
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-rollback.mjs",
+ "args": [],
+ "cwd": "/Users/macstudio3/Projects/dw-signup-fulfillment",
+ "exitCode": 78,
+ "signal": null,
+ "command": [
+ "/opt/homebrew/Cellar/node/26.4.0/bin/node",
+ "--require",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/retired-boundaries.cjs",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-rollback.mjs"
+ ],
+ "stderr": "SUPERSEDED: TK-11185 theme rollback is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n\nRETIREMENT_BOUNDARY_AUDIT={\"entryLoads\":2,\"appFileAttempts\":[],\"networkAttempts\":[]}\n",
+ "audit": {
+ "entryLoads": 2,
+ "appFileAttempts": [],
+ "networkAttempts": []
+ },
+ "sourceSHA256": "d5d1ed66c9092f51895d829e92e4fed19c6949b23a4c2f0cbb93e9f3170e6153",
+ "verdict": "PASS"
+ },
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-rollback.mjs",
+ "args": [
+ "--apply"
+ ],
+ "cwd": "/private/tmp",
+ "exitCode": 78,
+ "signal": null,
+ "command": [
+ "/opt/homebrew/Cellar/node/26.4.0/bin/node",
+ "--require",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/retired-boundaries.cjs",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-rollback.mjs",
+ "--apply"
+ ],
+ "stderr": "SUPERSEDED: TK-11185 theme rollback is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n\nRETIREMENT_BOUNDARY_AUDIT={\"entryLoads\":2,\"appFileAttempts\":[],\"networkAttempts\":[]}\n",
+ "audit": {
+ "entryLoads": 2,
+ "appFileAttempts": [],
+ "networkAttempts": []
+ },
+ "sourceSHA256": "d5d1ed66c9092f51895d829e92e4fed19c6949b23a4c2f0cbb93e9f3170e6153",
+ "verdict": "PASS"
+ },
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-rollback.mjs",
+ "args": [
+ "--rollback"
+ ],
+ "cwd": "/private/tmp",
+ "exitCode": 78,
+ "signal": null,
+ "command": [
+ "/opt/homebrew/Cellar/node/26.4.0/bin/node",
+ "--require",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/retired-boundaries.cjs",
+ "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-rollback.mjs",
+ "--rollback"
+ ],
+ "stderr": "SUPERSEDED: TK-11185 theme rollback is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n\nRETIREMENT_BOUNDARY_AUDIT={\"entryLoads\":2,\"appFileAttempts\":[],\"networkAttempts\":[]}\n",
+ "audit": {
+ "entryLoads": 2,
+ "appFileAttempts": [],
+ "networkAttempts": []
+ },
+ "sourceSHA256": "d5d1ed66c9092f51895d829e92e4fed19c6949b23a4c2f0cbb93e9f3170e6153",
+ "verdict": "PASS"
+ },
+ {
+ "entry": "/Users/macstudio3/Projects/dw-signup-fulfillment/scripts/gate2-theme-rollback.mjs",
+ "mode": "plain direct Node, no preload",
+ "cwd": "/private/tmp",
+ "exitCode": 78,
+ "stderr": "SUPERSEDED: TK-11185 theme rollback is retired (exit 78).\nTK-11283 published the required designer form and account/login flow. This old command would overwrite it.\nRead-only Shopify status (run from any directory):\n node ~/Projects/dw-signup-fulfillment/verification/tk11283/publish-theme.cjs --status\nFor the current guarded deploy/rollback procedure and approval requirements, read:\n ~/Projects/dw-signup-fulfillment/verification/tk11185-reconcile/RETIRED-COMMANDS.md\nNo credentials were read and no Shopify request was made.\n",
+ "verdict": "PASS"
+ }
+ ],
+ "assertions": [
+ {
+ "boundary": "Historical fs/API",
+ "verdict": "PASS",
+ "reason": "Actual original sources read dummy credentials then overwrite newer body without checking current hash."
+ },
+ {
+ "boundary": "Real CLI process",
+ "verdict": "PASS",
+ "reason": "Both exit78 from repository or unrelated cwd, even with apply/rollback flags."
+ },
+ {
+ "boundary": "Credentials/files/network",
+ "verdict": "PASS",
+ "reason": "Six instrumented invocations report zero app file/network attempts."
+ },
+ {
+ "boundary": "Supported tooling",
+ "verdict": "PASS",
+ "reason": "TK11283 guarded deploy/rollback tool byte-identical to HEAD."
+ },
+ {
+ "boundary": "UI",
+ "verdict": "N/A",
+ "reason": "No storefront/UI changes."
+ }
+ ],
+ "cleanup": "No real API calls, customers, emails, or production mutations. No temporary records.",
+ "scope": "Retirement only; TK11185 production smoke-record cleanup remains with the parent.",
+ "guardedToolSHA256": "2f37dc836fb0ddba07270d3608b584ccd29c917f0455363e0aaba1562fc68797",
+ "verdict": "PASS"
+}
← 116fc35 Serialize trade rejection with approval and preserve concurr
·
back to Dw Signup Fulfillment
·
auto-data-snapshot: 2026-09-05T01:06:29 (1 data files) — ver b8ee89a →