[object Object]

← back to Tk 10965 Zero Price Analysis

Freeze Vienna executor scope and journal offline mutations safely

76455836991e5c5af27d6fde81b08e4c97e04c7d · 2026-09-08 05:52:25 -0700 · Steve Abrams

Files touched

Diff

commit 76455836991e5c5af27d6fde81b08e4c97e04c7d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Sep 8 05:52:25 2026 -0700

    Freeze Vienna executor scope and journal offline mutations safely
---
 README.md                            |   2 +
 VIENNA-EXECUTOR.md                   |  82 ++++++++++++++++++
 apply-fix.mjs                        | 126 ++-------------------------
 cli-args.mjs                         |  52 +++++------
 test/cli-preflight.test.mjs          |  17 ++--
 test/fixtures/vienna-manifest.json   |  78 +++++++++++++++++
 test/fixtures/vienna-manifest.sha256 |   1 +
 test/vienna-boundaries.cjs           |  34 ++++++++
 test/vienna-executor.test.mjs        | 120 ++++++++++++++++++++++++++
 verification/vienna-e2e-proof.json   | 118 +++++++++++++++++++++++++
 vienna-executor.mjs                  | 162 +++++++++++++++++++++++++++++++++++
 vienna-offline-adapter.mjs           |  24 ++++++
 12 files changed, 659 insertions(+), 157 deletions(-)

diff --git a/README.md b/README.md
index 27563b8..facd60f 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+> **TK-11300: live inventory execution is disabled.** The actual CLI now requires a frozen manifest and supports an offline adapter only. Read [VIENNA-EXECUTOR.md](VIENNA-EXECUTOR.md) before using historical commands below.
+
 # TK-10965 — zero-price-orderable analysis + verification harness
 
 READ-ONLY analysis of the `zero-price-orderable-canary` FAIL (underlying alert TK-10963):
diff --git a/VIENNA-EXECUTOR.md b/VIENNA-EXECUTOR.md
new file mode 100644
index 0000000..f88c409
--- /dev/null
+++ b/VIENNA-EXECUTOR.md
@@ -0,0 +1,82 @@
+# Vienna executor local increment — TK-11300
+
+**Production transport is disabled.** `designer-laboratory-sandbox.myshopify.com`
+is the production store despite its name. This code is an actual CLI manifest
+consumer and a local, file-backed operational rehearsal. It cannot perform live
+inventory recovery. TK-11299 retains authoritative paginated acquisition, actual
+shop identity, manifest review, token scope verification and explicit live approval.
+No synthetic fixture shop or catalog ID is evidence of a live identity.
+
+`apply-fix.mjs` no longer reads secrets or freshly enumerates products. Historical
+`--all`, numeric `--canary`, and restore-map rollback commands fail closed. The
+old token wrapper must not be used; live transport is absent, rather than hidden
+behind an environment switch. The fixed domain and separate `--expected-store-id`
+are validated against the manifest before the adapter is loaded, then against the
+adapter's own shop result. There are no catalog or price mutations.
+
+All modes except help require `--manifest FILE --expected-sha256 HASH
+--expected-store-id SHOP_GID`. The SHA256 must come from the independent review
+of the exact bytes; do not compute a fresh hash of unreviewed input as approval.
+`--plan` and its `--enumerate` alias only read the manifest and print JSON. They
+refuse adapter/journal options and create no files. Local execution additionally
+requires `--offline-state FILE --journal FILE`. Resuming either original mode, or
+`--rollback`, requires `--journal-sha256 HASH` from a separately trusted checkpoint.
+Never use historical restore maps as journals.
+
+Manifest v1 has exactly `version`, `scope`, `store`, `createdAt`, `expiresAt`,
+`records` and `canary`. `scope` is `{vendor:"Phillipe Romano",line:"Vienna"}`.
+Every record pins product, variant, inventory item and location GIDs plus the
+product/variant preconditions, positive original `onHand` and `target:0`. Every
+record must be a non-sample, zero-price, tracked DENY variant in the frozen line.
+Expiry and maximum age are 24 hours, with ISO UTC timestamps and no future issue
+date. `canary` contains explicit `inventoryItemId@locationId` keys; every frozen
+location of each selected product must be included. The test canary deliberately
+selects the third record to prove this is not a first-N approximation.
+
+Hashes are operator trust anchors for exact bytes. Neither a manifest hash nor a
+journal checkpoint establishes authoritative catalog completeness, arbitrary
+journal provenance, or legal operational authorization. Review and transport
+adapter integration remain separate. Structurally valid fabricated history with
+a newly trusted checkpoint cannot be distinguished from operator-approved input.
+
+Execution compares the full exact record before each compare-and-set write,
+fsyncs intent before the adapter call, appends/fsyncs only confirmed successes,
+then re-reads the exact identity and quantity before appending verification.
+Confirmed rejections are recorded separately and can be retried after another
+precondition comparison. Successfully verified mutations are only re-read on
+resume; never repeated. Rollback selects confirmed successful records in that
+journal, including successful locations from a partially failed product. Rollback
+uses the same intent/result/post-read protocol. Once rollback begins, apply
+cannot reopen a rolled-back run.
+
+An exception or unrecognized result after intent is ambiguous. Missing success
+never proves failure: retry and rollback block before adapter initialization.
+There is intentionally no automatic reconciliation or force flag. A confirmed
+success with interrupted verification can only advance after an exact read; it
+cannot authorize a duplicate mutation. A crashed lock also blocks invocation;
+it must be independently reviewed alongside the journal before any later work.
+Ordinary completed invocation releases its own lock. Checkpoints are rechecked
+under the exclusive journal lock to prevent a concurrent stale replay.
+
+Journal parsing validates the chain, sequence, schema, manifest/store binding,
+frozen selection, exact quantities and valid per-record state transitions. It
+rejects truncated, malformed, unbound or injected histories before the adapter.
+All data reads reject symlinks/hardlinks. Fixture state replacement uses fsynced
+exclusive temporary files, identity checks, atomic rename and directory fsync.
+Failed replacement retains its temporary file and prior durable fixture state.
+
+## Verification and retained evidence
+
+Run `node --test test/cli-preflight.test.mjs test/vienna-executor.test.mjs`.
+Set `VIENNA_EVIDENCE_DIR` to an existing local evidence directory to retain each
+fixture, manifest, journal, state and child CLI output there. Test time is fixed
+by the deny-by-default process preload; the application has no clock override.
+The guard denies canonical secrets, network and child processes and permits only
+specified fixture files. Calibration deliberately hits real protected entry
+points and proves denial. No real credentials, network or inventory are used.
+
+The former 42-check CLI proof remains in git at source commit
+`7fb358ca8948290915678dd2c34f83a02d5a0532` and its existing verification files.
+Legacy write-mode test assertions now require manifest rejection rather than
+reaching runtime initialization. The new proof is `verification/vienna-e2e-proof.json`.
+All fixture directories and failed-run logs are retained; no cleanup is required.
diff --git a/apply-fix.mjs b/apply-fix.mjs
index 77c7b00..2f9e0be 100644
--- a/apply-fix.mjs
+++ b/apply-fix.mjs
@@ -1,126 +1,12 @@
 #!/usr/bin/env node
-// TK-10965 — APPROVED remediation (Steve "go", 2026-08-30).
-// Make the $0 non-Sample variant NON-orderable by setting on_hand=0 at every location
-// that currently holds stock (keep inventoryPolicy=DENY, keep tracked). Does NOT touch
-// the $4.25 Sample variant. Fully reversible via the restore-map written before any write.
-//
-// Usage:
-//   node apply-fix.mjs --enumerate         # scan + write restore-map, NO writes
-//   node apply-fix.mjs --canary [N=50]     # fix first N, verify
-//   node apply-fix.mjs --all               # fix everything remaining
-//   node apply-fix.mjs --rollback FILE     # restore on_hand from a restore-map file
-import fs from 'node:fs';
-import path from 'node:path';
+// TK-11300: the actual CLI is fail-closed; historical approvals do not authorize
+// fresh scope. No credential loading, broad enumeration or production adapter.
 import { parseArgs, USAGE } from './cli-args.mjs';
-
-// Preflight must precede runtime directories, credentials and external calls.
 let cli;
 try { cli = parseArgs(process.argv.slice(2)); }
 catch (error) { console.error(`${error.message}\n\n${USAGE}`); process.exit(2); }
 if (cli.mode === '--help') { console.log(USAGE); process.exit(0); }
-const arg = cli.mode;
-const arg2 = cli.file;
-
-const HERE = path.dirname(new URL(import.meta.url).pathname);
-const RUNS = path.join(HERE, 'runs'); fs.mkdirSync(RUNS, { recursive: true });
-const env = fs.readFileSync('/Users/macstudio3/Projects/secrets-manager/.env', 'utf8');
-const val = k => (env.match(new RegExp('^' + k + '=(.*)$', 'm')) || [])[1]?.trim();
-// The canonical secrets-manager SHOPIFY_ADMIN_TOKEN is products-scoped only (no write_inventory).
-// Per TK-10965 guardrail, prefer a sanctioned inventory-write token supplied via the environment
-// (the DW importer runtime's SHOPIFY_ADMIN_ACCESS_TOKEN, which carries read/write_inventory).
-const DOM = process.env.SHOPIFY_STORE_DOMAIN || val('SHOPIFY_STORE_DOMAIN');
-const TOK = process.env.SHOPIFY_ADMIN_ACCESS_TOKEN || process.env.SHOPIFY_ADMIN_TOKEN || val('SHOPIFY_ADMIN_TOKEN');
-const API = `https://${DOM}/admin/api/2024-10/graphql.json`;
-
-if (!DOM || !TOK) throw new Error('Missing SHOPIFY_STORE_DOMAIN or SHOPIFY_ADMIN_TOKEN');
-
-async function gql(q, v) {
-  for (let a = 0; a < 8; a++) {
-    const r = await fetch(API, { method: 'POST', headers: { 'X-Shopify-Access-Token': TOK, 'Content-Type': 'application/json' }, body: JSON.stringify({ query: q, variables: v }) });
-    const j = await r.json();
-    if (j.errors) { if (JSON.stringify(j.errors).includes('THROTTLED')) { await new Promise(s => setTimeout(s, 1800 * (a + 1))); continue; } throw new Error(JSON.stringify(j.errors)); }
-    return j.data;
-  }
-  throw new Error('gql retries');
-}
-
-const VAR_Q = `variants(first:20){nodes{id title price availableForSale inventoryPolicy inventoryItem{id tracked inventoryLevels(first:10){nodes{location{id} quantities(names:["on_hand"]){name quantity}}}}}}`;
-const isBad = v => !/sample/i.test(v.title || '') && Number(v.price) === 0 && v.availableForSale === true;
-
-async function enumerateBad() {
-  const out = []; const seen = new Set();
-  // PR via the quote-only tag search (efficient, matches the canary's 1281 set)
-  const searches = [
-    `status:active AND (tag:'quote-only' OR tag:'Quote Only' OR tag:'quote_only' OR tag:'Quote-Only')`,
-    `status:active AND vendor:'Fentucci Naturals'`,
-  ];
-  for (const q of searches) {
-    let after = null, pages = 0;
-    do {
-      const d = await gql(`query($q:String!,$after:String){products(first:100,query:$q,after:$after){pageInfo{hasNextPage endCursor} nodes{id title vendor ${VAR_Q}}}}`, { q, after });
-      for (const p of d.products.nodes) {
-        if (seen.has(p.id)) continue; seen.add(p.id);
-        const v = p.variants.nodes.find(isBad);
-        if (!v) continue;
-        const levels = (v.inventoryItem.inventoryLevels.nodes || [])
-          .map(l => ({ locationId: l.location.id, onHand: (l.quantities.find(x => x.name === 'on_hand')?.quantity) ?? 0 }))
-          .filter(l => l.onHand > 0);
-        out.push({ productId: p.id, title: p.title, vendor: p.vendor, variantId: v.id, inventoryItemId: v.inventoryItem.id, levels });
-      }
-      after = d.products.pageInfo.hasNextPage ? d.products.pageInfo.endCursor : null; pages++;
-    } while (after && pages < 60);
-  }
-  return out;
-}
-
-async function requireInventoryWriteScope() {
-  const d = await gql(`query{currentAppInstallation{accessScopes{handle}}}`, {});
-  const scopes = d.currentAppInstallation.accessScopes.map(s => s.handle).sort();
-  if (!scopes.includes('write_inventory')) {
-    throw new Error(`BLOCKED: token lacks write_inventory (present scopes: ${scopes.join(', ')})`);
-  }
-  return scopes;
-}
-
-async function setOnHand(inventoryItemId, locationId, compareQuantity, quantity) {
-  const d = await gql(`mutation($input:InventorySetQuantitiesInput!){inventorySetQuantities(input:$input){userErrors{field message code}}}`,
-    { input: { name: 'on_hand', reason: 'correction', quantities: [{ inventoryItemId, locationId, compareQuantity, quantity }] } });
-  const errs = d.inventorySetQuantities.userErrors;
-  if (errs && errs.length) throw new Error(JSON.stringify(errs));
-}
-
-const stamp = () => new Date().toISOString().replace(/[:.]/g, '-');
-
-if (arg === '--rollback') {
-  await requireInventoryWriteScope();
-  const map = JSON.parse(fs.readFileSync(arg2, 'utf8'));
-  let n = 0; for (const it of map.items) for (const l of it.levels) { await setOnHand(it.inventoryItemId, l.locationId, 0, l.onHand); n++; }
-  console.log(`ROLLBACK: restored ${n} inventory levels from ${arg2}`);
-  process.exit(0);
-}
-
-const bad = await enumerateBad();
-const restorePath = path.join(RUNS, `restore-map-${stamp()}.json`);
-fs.writeFileSync(restorePath, JSON.stringify({ ts: new Date().toISOString(), count: bad.length, items: bad }, null, 2));
-console.log(`Enumerated ${bad.length} affected products. Restore-map: ${restorePath}`);
-const byV = {}; for (const b of bad) byV[b.vendor] = (byV[b.vendor] || 0) + 1;
-console.log('by vendor:', JSON.stringify(byV));
-
-if (arg === '--enumerate') { console.log('Enumerate-only. No writes.'); process.exit(0); }
-
-const scopes = await requireInventoryWriteScope();
-console.log(`Inventory write scope verified (${scopes.length} total scopes).`);
-
-const limit = arg === '--canary' ? cli.count : bad.length;
-const target = bad.slice(0, limit);
-console.log(`Applying on_hand=0 to ${target.length} products (${arg})...`);
-let done = 0, fail = 0;
-for (const b of target) {
-  try {
-    if (!b.levels.length) { done++; continue; } // already 0 everywhere
-    for (const l of b.levels) await setOnHand(b.inventoryItemId, l.locationId, l.onHand, 0);
-    done++;
-    if (done % 100 === 0) console.log(`  ...${done}/${target.length}`);
-  } catch (e) { fail++; console.error(`  FAIL ${b.title}: ${e.message}`); }
-}
-console.log(`Applied: ${done} ok, ${fail} failed of ${target.length}. Restore-map: ${restorePath}`);
+try {
+  const { run } = await import('./vienna-executor.mjs');
+  console.log(JSON.stringify(await run(cli), null, 2));
+} catch (error) { console.error('BLOCKED: '+error.message); process.exitCode=2; }
diff --git a/cli-args.mjs b/cli-args.mjs
index 5088c2b..3decc38 100644
--- a/cli-args.mjs
+++ b/cli-args.mjs
@@ -1,29 +1,29 @@
-export const USAGE = `Usage: node apply-fix.mjs <mode>
-  --help              Show usage without initialization
-  --enumerate         Scan and save restore map; no inventory writes
-  --canary [N]        Apply to first N results (default: 50)
-  --all               Apply to all freshly enumerated results
-  --rollback FILE     Restore quantities from FILE`;
-
+export const USAGE = `Usage: node apply-fix.mjs <mode> [options]
+  --help                 Show usage without initialization
+  --plan | --enumerate   Validate frozen manifest and print plan; no adapter or journal
+  --canary | --all       Execute frozen canary membership or complete manifest OFFLINE
+  --rollback             Restore only confirmed journal successes OFFLINE
+Required: --manifest FILE --expected-sha256 HASH --expected-store-id SHOP_GID
+Execution: --offline-state FILE --journal FILE
+Existing journal: --journal-sha256 HASH (external checkpoint required)
+Live execution is disabled. Legacy scans, numeric canaries and restore maps are refused.`;
 export function parseArgs(args) {
-  const [mode, value] = args;
-  if (!['--help', '--enumerate', '--canary', '--all', '--rollback'].includes(mode)) {
-    throw new Error(mode ? `Unrecognized mode: ${mode}` : 'A mode is required.');
+  const [mode, ...rest] = args;
+  if (!['--help','--plan','--enumerate','--canary','--all','--rollback'].includes(mode)) throw new Error('A recognized mode is required.');
+  if (mode === '--help') { if (rest.length) throw new Error('Unexpected arguments.'); return {mode}; }
+  const cli = {mode};
+  const options = new Set(['--manifest','--expected-sha256','--expected-store-id','--offline-state','--journal','--journal-sha256']);
+  for (let i=0;i<rest.length;i+=2) {
+    const [k,v] = rest.slice(i,i+2);
+    if (!options.has(k) || Object.hasOwn(cli,k) || !v?.trim() || v.startsWith('-')) throw new Error('Invalid, duplicate or missing option: ' + k);
+    cli[k] = v;
   }
-  if (mode === '--canary') {
-    if (args.length > 2) throw new Error('Unexpected extra arguments for --canary.');
-    const count = value === undefined ? 50 : Number(value);
-    if ((value !== undefined && !/^[0-9]+$/.test(value)) || !Number.isSafeInteger(count) || count <= 0) {
-      throw new Error('--canary count must be a positive safe integer.');
-    }
-    return { mode, count };
-  }
-  if (mode === '--rollback') {
-    if (args.length !== 2 || !value.trim() || value.startsWith('-')) {
-      throw new Error('--rollback requires exactly one file path (use ./ for a path beginning with a dash).');
-    }
-    return { mode, file: value };
-  }
-  if (args.length !== 1) throw new Error(`Unexpected extra arguments for ${mode}.`);
-  return { mode };
+  for (const k of ['--manifest','--expected-sha256','--expected-store-id']) if (!cli[k]) throw new Error('Required: ' + k);
+  for (const k of ['--expected-sha256','--journal-sha256']) if (cli[k] && !/^[a-f0-9]{64}$/.test(cli[k])) throw new Error('Invalid SHA256: '+k);
+  if (!/^gid:\/\/shopify\/Shop\/[1-9][0-9]*$/.test(cli['--expected-store-id'])) throw new Error('Invalid expected store ID.');
+  const plan = ['--plan','--enumerate'].includes(mode);
+  if (plan && ['--offline-state','--journal','--journal-sha256'].some(k=>cli[k])) throw new Error('Plan cannot initialize adapter or journal.');
+  if (!plan && (!cli['--offline-state'] || !cli['--journal'])) throw new Error('Live execution disabled; offline-state and journal required.');
+  if (mode==='--rollback' && !cli['--journal-sha256']) throw new Error('Rollback requires pinned journal SHA256.');
+  return cli;
 }
diff --git a/test/cli-preflight.test.mjs b/test/cli-preflight.test.mjs
index b734bb9..ad59bc7 100644
--- a/test/cli-preflight.test.mjs
+++ b/test/cli-preflight.test.mjs
@@ -30,18 +30,13 @@ test('--help is safe at actual entry point', () => {
   assert.match(result.stdout, /Usage: node apply-fix.mjs/);
   assert.deepEqual(result.attempts, []);
 });
-const recognized = [
-  [['--enumerate'], {mode:'--enumerate'}], [['--all'], {mode:'--all'}],
-  [['--canary'], {mode:'--canary',count:50}], [['--canary','1'], {mode:'--canary',count:1}],
-  [['--canary','9007199254740991'], {mode:'--canary',count:9007199254740991}],
-  [['--rollback','file.json'], {mode:'--rollback',file:'file.json'}],
-  [['--rollback','./--file.json'], {mode:'--rollback',file:'./--file.json'}]
-];
-for (const [args, expected] of recognized) test('recognized mode reaches blocked initialization only: ' + JSON.stringify(args), () => {
-  assert.deepEqual(parseArgs(args), expected);
+// Historical accepted write syntax now fails closed without a frozen manifest.
+const recognized = [['--enumerate'],['--all'],['--canary'],['--canary','1'],['--canary','9007199254740991'],['--rollback','file.json'],['--rollback','./--file.json']];
+for (const args of recognized) test('legacy mode requires frozen inputs: ' + JSON.stringify(args), () => {
+  assert.throws(() => parseArgs(args));
   const result = run(args);
-  assert.notEqual(result.status, 0);
-  assert.deepEqual(result.attempts, ['fs.mkdirSync'], result.stderr);
+  assert.equal(result.status, 2, result.stderr);
+  assert.deepEqual(result.attempts, [], result.stderr);
 });
 if (process.env.CLI_BASELINE_ENTRY) for (const args of [[], ['--help'], ['--typo']]) {
   test('prepatch entry exposes missing guard: ' + JSON.stringify(args), () => {
diff --git a/test/fixtures/vienna-manifest.json b/test/fixtures/vienna-manifest.json
new file mode 100644
index 0000000..7172921
--- /dev/null
+++ b/test/fixtures/vienna-manifest.json
@@ -0,0 +1,78 @@
+{
+  "version": 1,
+  "scope": {
+    "vendor": "Phillipe Romano",
+    "line": "Vienna"
+  },
+  "store": {
+    "domain": "designer-laboratory-sandbox.myshopify.com",
+    "id": "gid://shopify/Shop/900000000001"
+  },
+  "createdAt": "2026-09-08T11:00:00.000Z",
+  "expiresAt": "2026-09-09T11:00:00.000Z",
+  "records": [
+    {
+      "productId": "gid://shopify/Product/1",
+      "variantId": "gid://shopify/ProductVariant/1",
+      "inventoryItemId": "gid://shopify/InventoryItem/1",
+      "locationId": "gid://shopify/Location/1",
+      "vendor": "Phillipe Romano",
+      "line": "Vienna",
+      "title": "Vienna Fixture 1",
+      "variantTitle": "Full Material",
+      "price": 0,
+      "inventoryPolicy": "DENY",
+      "tracked": true,
+      "onHand": 2026,
+      "target": 0
+    },
+    {
+      "productId": "gid://shopify/Product/1",
+      "variantId": "gid://shopify/ProductVariant/1",
+      "inventoryItemId": "gid://shopify/InventoryItem/1",
+      "locationId": "gid://shopify/Location/2",
+      "vendor": "Phillipe Romano",
+      "line": "Vienna",
+      "title": "Vienna Fixture 1",
+      "variantTitle": "Full Material",
+      "price": 0,
+      "inventoryPolicy": "DENY",
+      "tracked": true,
+      "onHand": 2026,
+      "target": 0
+    },
+    {
+      "productId": "gid://shopify/Product/2",
+      "variantId": "gid://shopify/ProductVariant/2",
+      "inventoryItemId": "gid://shopify/InventoryItem/2",
+      "locationId": "gid://shopify/Location/1",
+      "vendor": "Phillipe Romano",
+      "line": "Vienna",
+      "title": "Vienna Fixture 2",
+      "variantTitle": "Full Material",
+      "price": 0,
+      "inventoryPolicy": "DENY",
+      "tracked": true,
+      "onHand": 2026,
+      "target": 0
+    },
+    {
+      "productId": "gid://shopify/Product/3",
+      "variantId": "gid://shopify/ProductVariant/3",
+      "inventoryItemId": "gid://shopify/InventoryItem/3",
+      "locationId": "gid://shopify/Location/1",
+      "vendor": "Phillipe Romano",
+      "line": "Vienna",
+      "title": "Vienna Fixture 3",
+      "variantTitle": "Full Material",
+      "price": 0,
+      "inventoryPolicy": "DENY",
+      "tracked": true,
+      "onHand": 2026,
+      "target": 0
+    }
+  ],
+  "canary": [
+    "gid://shopify/InventoryItem/2@gid://shopify/Location/1"
+  ]
+}
diff --git a/test/fixtures/vienna-manifest.sha256 b/test/fixtures/vienna-manifest.sha256
new file mode 100644
index 0000000..ae6b935
--- /dev/null
+++ b/test/fixtures/vienna-manifest.sha256
@@ -0,0 +1 @@
+1b21ab81983284920c22f857a1480741335b5513d003a23b38f9d1c2378bc1c7
diff --git a/test/vienna-boundaries.cjs b/test/vienna-boundaries.cjs
new file mode 100644
index 0000000..b3dff05
--- /dev/null
+++ b/test/vienna-boundaries.cjs
@@ -0,0 +1,34 @@
+// Calibrated deny-by-default process boundary guard; fixture I/O is explicitly allowlisted.
+const fs=require('node:fs'),url=require('node:url');
+const {syncBuiltinESMExports}=require('node:module');
+const rawWrite=fs.writeSync.bind(fs), rawOpen=fs.openSync.bind(fs), rawClose=fs.closeSync.bind(fs);
+const reads=new Set(JSON.parse(process.env.VIENNA_ALLOWED_READS||'[]'));
+const writes=new Set(JSON.parse(process.env.VIENNA_ALLOWED_WRITES||'[]'));
+const dirs=new Set(JSON.parse(process.env.VIENNA_ALLOWED_DIRS||'[]'));
+const fdPaths=new Map();
+const p=x=>x instanceof URL?url.fileURLToPath(x):typeof x==='number'?fdPaths.get(x):String(x);
+function deny(name){rawWrite(2,'BOUNDARY_DENIED:'+name+'\n');throw new Error('Boundary blocked: '+name);}
+function canRead(x){return reads.has(p(x))||writes.has(p(x))||dirs.has(p(x));}
+function canWrite(x){const name=p(x);return writes.has(name)||[...writes].some(base=>typeof name==='string'&&name.startsWith(base+'.pending-'));}
+fs.openSync=function(file,flags,...rest){
+  const writing=typeof flags==='number'?Boolean(flags&(fs.constants.O_WRONLY|fs.constants.O_RDWR|fs.constants.O_CREAT|fs.constants.O_APPEND|fs.constants.O_TRUNC)):flags!=='r';
+  if(writing?!canWrite(file):!canRead(file)) return deny('fs.openSync');
+  const fd=rawOpen(file,flags,...rest);fdPaths.set(fd,p(file));return fd;
+};
+fs.closeSync=function(fd){const r=rawClose(fd);fdPaths.delete(fd);return r;};
+for(const name of ['readFileSync','readFile','createReadStream']){const orig=fs[name].bind(fs);fs[name]=function(file,...rest){if(!canRead(file))return deny('fs.'+name);return orig(file,...rest);};}
+for(const name of ['writeFileSync','appendFileSync']){const orig=fs[name].bind(fs);fs[name]=function(file,...rest){if(!canWrite(file))return deny('fs.'+name);if(process.env.VIENNA_FAIL_SUCCESS_APPEND==='1'&&String(rest[0]).includes('\"type\":\"success\"'))throw new Error('Simulated crash after confirmed mutation before success append');return orig(file,...rest);};}
+for(const name of ['mkdirSync','rmdirSync']){const orig=fs[name].bind(fs);fs[name]=function(file,...rest){if(!dirs.has(p(file)))return deny('fs.'+name);return orig(file,...rest);};}
+for(const name of ['writeSync','writevSync']){const orig=fs[name].bind(fs);fs[name]=function(fd,...rest){if(fd!==1&&fd!==2&&!canWrite(fd))return deny('fs.'+name);return orig(fd,...rest);};}
+const rawRename=fs.renameSync.bind(fs);fs.renameSync=function(from,to){if(!canWrite(from)||!writes.has(p(to)))return deny('fs.renameSync');return rawRename(from,to);};
+for(const name of ['writeFile','appendFile','rename','unlink','rm','rmdir','mkdir','copyFile','cp','link','symlink','truncate','chmod','chown','utimes','open','createWriteStream']) {
+  if(typeof fs[name]==='function') fs[name]=()=>deny('fs.'+name);
+  if(fs.promises[name])fs.promises[name]=()=>deny('fs.promises.'+name);
+}
+const pr=fs.promises.readFile.bind(fs.promises);fs.promises.readFile=async(file,...rest)=>{if(!canRead(file))return deny('fs.promises.readFile');return pr(file,...rest);};
+for(const [mod,names] of Object.entries({'node:child_process':['spawn','spawnSync','exec','execSync','execFile','fork'],'node:http':['request','get'],'node:https':['request','get'],'node:net':['connect','createConnection','createServer'],'node:tls':['connect'],'node:dns':['lookup','resolve'],'node:dgram':['createSocket']}))for(const name of names)require(mod)[name]=()=>deny(mod+'.'+name);
+require('node:net').Socket.prototype.connect=()=>deny('net.Socket.connect');
+globalThis.fetch=()=>deny('fetch');
+// Clock seam lives only in the test preload. The shipped CLI never accepts a clock override.
+Date.now=()=>Date.parse('2026-09-08T12:00:00.000Z');
+syncBuiltinESMExports();
diff --git a/test/vienna-executor.test.mjs b/test/vienna-executor.test.mjs
new file mode 100644
index 0000000..7ca5268
--- /dev/null
+++ b/test/vienna-executor.test.mjs
@@ -0,0 +1,120 @@
+import test from 'node:test';
+import assert from 'node:assert/strict';
+import fs from 'node:fs';
+import path from 'node:path';
+import os from 'node:os';
+import {spawnSync} from 'node:child_process';
+import {fileURLToPath} from 'node:url';
+import {hash,DOMAIN,key} from '../vienna-executor.mjs';
+const root=fileURLToPath(new URL('..',import.meta.url));
+const evidence=process.env.VIENNA_EVIDENCE_DIR||os.tmpdir();
+const guard=path.join(root,'test/vienna-boundaries.cjs');
+const sourceFiles=['apply-fix.mjs','cli-args.mjs','vienna-executor.mjs','vienna-offline-adapter.mjs'].map(f=>path.join(root,f));
+const store={domain:DOMAIN,id:'gid://shopify/Shop/900000000001'}; // SYNTHETIC; never a live identity.
+function fixture(){
+  const dir=fs.mkdtempSync(path.join(evidence,'vienna-fixture-'));
+  const bytes=fs.readFileSync(path.join(root,'test/fixtures/vienna-manifest.json'));
+  assert.equal(hash(bytes),fs.readFileSync(path.join(root,'test/fixtures/vienna-manifest.sha256'),'utf8').trim());
+  const manifest=JSON.parse(bytes),records=manifest.records;
+  const f={dir,manifest,path:path.join(dir,'manifest.json'),state:path.join(dir,'state.json'),journal:path.join(dir,'journal.jsonl')};
+  fs.writeFileSync(f.path,JSON.stringify(manifest,null,2)+'\n');
+  fs.writeFileSync(f.state,JSON.stringify({fixture:true,version:1,store,records:structuredClone(records),calls:[],faults:{}},null,2)+'\n');
+  f.sha=hash(fs.readFileSync(f.path));return f;
+}
+function state(f){return JSON.parse(fs.readFileSync(f.state,'utf8'));}
+function updateState(f,fn){const s=state(f);fn(s);fs.writeFileSync(f.state,JSON.stringify(s,null,2)+'\n');}
+function journal(f){return fs.readFileSync(f.journal,'utf8').trimEnd().split('\n').map(x=>JSON.parse(x));}
+function invoke(f,mode='--all',extra=[],opts={}){
+  const args=[mode,'--manifest',f.path,'--expected-sha256',f.sha,'--expected-store-id',store.id];
+  if(!['--plan','--enumerate'].includes(mode))args.push('--offline-state',f.state,'--journal',f.journal);
+  if(opts.resume)args.push('--journal-sha256',hash(fs.readFileSync(f.journal)));
+  const result=spawnSync(process.execPath,['--require',guard,path.join(root,'apply-fix.mjs'),...args,...extra],{
+    encoding:'utf8',timeout:5000,env:{VIENNA_FAIL_SUCCESS_APPEND:opts.failSuccessAppend?'1':'',VIENNA_ALLOWED_READS:JSON.stringify([...sourceFiles,f.path,f.journal,...(!opts.noWrites||opts.allowAdapterRead?[f.state]:[])]),VIENNA_ALLOWED_WRITES:JSON.stringify(opts.noWrites?[]:[f.state,f.journal]),VIENNA_ALLOWED_DIRS:JSON.stringify(opts.noWrites?[]:[f.dir,f.journal+'.lock'])}
+  });
+  assert.ifError(result.error); assert.equal(result.signal,null,result.stderr);
+  fs.writeFileSync(path.join(f.dir,`result-${fs.readdirSync(f.dir).length}.json`),JSON.stringify({args,...result},null,2));
+  assert.doesNotMatch(result.stderr,/BOUNDARY_DENIED:/,result.stderr);
+  return result;
+}
+function fail(r,re){assert.equal(r.status,2,r.stdout+r.stderr);assert.match(r.stderr,re);}
+function unchanged(f,before){assert.equal(hash(fs.readFileSync(f.state)),before);assert.equal(fs.existsSync(f.journal),false);}
+for(const [name,change,re] of [
+  ['foreign vendor',m=>m.records[0].vendor='Fentucci Naturals',/scope/],
+  ['foreign line',m=>m.records[0].title='Other Line',/scope/],
+  ['malformed ID',m=>m.records[0].productId='gid://shopify/Product/*',/identity/],
+  ['sample injection',m=>m.records[0].variantTitle='Sample',/scope/],
+  ['duplicate item',m=>m.records.push(m.records[0]),/Duplicate/],
+  ['variant collision',m=>m.records[2].variantId=m.records[0].variantId,/collision/],
+  ['stale',m=>m.expiresAt='2026-09-08T11:59:59.000Z',/Stale/],
+  ['future',m=>m.createdAt='2026-09-08T12:01:00.000Z',/Stale/],
+  ['missing identity',m=>delete m.records[0].locationId,/Malformed/],
+  ['unknown field',m=>m.all=true,/Malformed/],
+  ['scope broadening',m=>m.scope.vendor='all',/scope/],
+  ['store mismatch',m=>m.store.id='gid://shopify/Shop/99',/Store/],
+  ['domain mismatch',m=>m.store.domain='other.myshopify.com',/Store/],
+  ['canary injection',m=>m.canary.push('foreign'),/Canary/],
+  ['split canary locations',m=>m.canary=[key(m.records[0])],/every frozen location/],
+  ['quantity injection',m=>m.records[0].onHand=-10,/scope/]
+])test('before adapter: '+name,()=>{const f=fixture();change(f.manifest);fs.writeFileSync(f.path,JSON.stringify(f.manifest));f.sha=hash(fs.readFileSync(f.path));const before=hash(fs.readFileSync(f.state));fail(invoke(f,'--all',[],{noWrites:true}),re);unchanged(f,before);});
+test('external hash rejects valid-looking foreign ID injection',()=>{const f=fixture(),before=hash(fs.readFileSync(f.state));f.manifest.records[0].productId='gid://shopify/Product/777';fs.writeFileSync(f.path,JSON.stringify(f.manifest));fail(invoke(f,'--all',[],{noWrites:true}),/SHA256/);unchanged(f,before);});
+test('malformed JSON and missing manifest fail before adapter',()=>{const f=fixture(),before=hash(fs.readFileSync(f.state));fs.writeFileSync(f.path,'{');f.sha=hash(fs.readFileSync(f.path));fail(invoke(f,'--all',[],{noWrites:true}),/JSON|property/);unchanged(f,before);f.path=path.join(f.dir,'missing.json');fail(invoke(f,'--all',[],{noWrites:true}),/ENOENT/);unchanged(f,before);});
+test('plan and enumerate have no adapter, journal or write effects',()=>{for(const mode of ['--plan','--enumerate']){const f=fixture(),before=hash(fs.readFileSync(f.state));const r=invoke(f,mode,[],{noWrites:true});assert.equal(r.status,0,r.stderr);assert.equal(JSON.parse(r.stdout).mutations,0);unchanged(f,before);}});
+test('adapter actual shop mismatch rejects before state or journal changes',()=>{const f=fixture();updateState(f,s=>s.store={...store,id:'gid://shopify/Shop/99'});const before=hash(fs.readFileSync(f.state));fail(invoke(f,'--all',[],{noWrites:true,allowAdapterRead:true}),/Adapter store/);unchanged(f,before);});
+test('happy all path exact multi-location postread; retry performs zero duplicate writes',()=>{const f=fixture();let r=invoke(f);assert.equal(r.status,0,r.stderr);assert.equal(JSON.parse(r.stdout).writes,4);assert.deepEqual(state(f).records.map(r=>r.onHand),[0,0,0,0]);assert.equal(journal(f).filter(e=>e.type==='verified').length,4);const sets=state(f).calls.filter(c=>c.method==='set').length;r=invoke(f,'--all',[],{resume:true});assert.equal(r.status,0,r.stderr);assert.equal(JSON.parse(r.stdout).writes,0);assert.equal(state(f).calls.filter(c=>c.method==='set').length,sets);});
+test('frozen canary uses explicit membership and cannot broaden on resume',()=>{const f=fixture();const r=invoke(f,'--canary');assert.equal(r.status,0,r.stderr);assert.deepEqual(state(f).records.map(r=>r.onHand),[2026,2026,0,2026]);assert.deepEqual(state(f).calls.filter(c=>c.method==='set').map(c=>c.key),f.manifest.canary);const before=hash(fs.readFileSync(f.state));fail(invoke(f,'--all',[],{resume:true,noWrites:true}),/broaden/);assert.equal(hash(fs.readFileSync(f.state)),before);});
+test('all locations of selected canary product execute',()=>{const f=fixture();f.manifest.canary=f.manifest.records.slice(0,2).map(key);fs.writeFileSync(f.path,JSON.stringify(f.manifest));f.sha=hash(fs.readFileSync(f.path));assert.equal(invoke(f,'--canary').status,0);assert.deepEqual(state(f).records.map(r=>r.onHand),[0,0,2026,2026]);});
+test('quantity and exact foreign identity drift prevent write',()=>{for(const change of [s=>s.records[0].onHand=9,s=>s.records[0].productId='gid://shopify/Product/888']){const f=fixture();updateState(f,change);fail(invoke(f),/precondition drift/);assert.equal(state(f).calls.filter(c=>c.method==='set').length,0);assert.equal(journal(f).length,1);}});
+test('partial multi-location rejection; rollback restores successes only and is idempotent',()=>{const f=fixture();updateState(f,s=>s.faults[key(s.records[1])]='reject');fail(invoke(f),/Confirmed mutation rejection/);assert.deepEqual(state(f).records.map(r=>r.onHand),[0,2026,2026,2026]);assert.equal(journal(f).filter(e=>e.type==='success').length,1);let r=invoke(f,'--rollback',[],{resume:true});assert.equal(r.status,0,r.stderr);assert.equal(JSON.parse(r.stdout).writes,1);assert.deepEqual(state(f).records.map(r=>r.onHand),[2026,2026,2026,2026]);const sets=state(f).calls.filter(c=>c.method==='set').length;r=invoke(f,'--rollback',[],{resume:true});assert.equal(r.status,0,r.stderr);assert.equal(state(f).calls.filter(c=>c.method==='set').length,sets);});
+test('confirmed rejection retry skips successes and compares untouched frozen rows',()=>{const f=fixture();updateState(f,s=>s.faults[key(s.records[1])]='reject');fail(invoke(f),/Confirmed/);updateState(f,s=>s.faults={});const r=invoke(f,'--all',[],{resume:true});assert.equal(r.status,0,r.stderr);assert.equal(state(f).calls.filter(c=>c.method==='set'&&c.key===key(f.manifest.records[0])).length,1);assert.deepEqual(state(f).records.map(r=>r.onHand),[0,0,0,0]);});
+for(const fault of ['throw-before','throw-after'])test('ambiguous '+fault+' blocks retry AND rollback before adapter',()=>{const f=fixture();updateState(f,s=>s.faults[key(s.records[0])]=fault);fail(invoke(f),/Simulated/);assert.equal(journal(f).at(-1).type,'intent');assert.equal(state(f).records[0].onHand,fault==='throw-after'?0:2026);for(const mode of ['--all','--rollback']){const before=hash(fs.readFileSync(f.state));fail(invoke(f,mode,[],{resume:true,noWrites:true}),/Unresolved mutation intent/);assert.equal(hash(fs.readFileSync(f.state)),before);}});
+test('rollback response ambiguity leaves unresolved intent and blocks further recovery',()=>{const f=fixture();assert.equal(invoke(f,'--canary').status,0);updateState(f,s=>s.faults[key(s.records[2])]='throw-after');fail(invoke(f,'--rollback',[],{resume:true}),/Simulated/);assert.equal(state(f).records[2].onHand,2026);assert.equal(journal(f).at(-1).direction,'rollback');fail(invoke(f,'--rollback',[],{resume:true,noWrites:true}),/Unresolved/);});
+test('postread failure retains confirmed success and blocks rollback on identity drift',()=>{const f=fixture();updateState(f,s=>s.faults[key(s.records[0])]='bad-postread');fail(invoke(f),/precondition drift/);assert.equal(journal(f).at(-1).type,'success');const sets=state(f).calls.filter(c=>c.method==='set').length;fail(invoke(f,'--rollback',[],{resume:true}),/precondition drift/);assert.equal(state(f).calls.filter(c=>c.method==='set').length,sets);});
+test('success before verification crash recovers by exact read without duplicate write',()=>{const f=fixture();updateState(f,s=>s.faults[key(s.records[0])]='bad-postread');fail(invoke(f),/precondition drift/);updateState(f,s=>{s.records[0].variantId=f.manifest.records[0].variantId;s.faults={};});const r=invoke(f,'--all',[],{resume:true});assert.equal(r.status,0,r.stderr);assert.equal(state(f).calls.filter(c=>c.method==='set'&&c.key===key(f.manifest.records[0])).length,1);});
+function forge(events){let prev='0'.repeat(64);return events.map((e,i)=>{const {hash:_,...body}=e;body.seq=i;body.prev=prev;prev=hash(JSON.stringify(body));return JSON.stringify({...body,hash:prev})+'\n';}).join('');}
+for(const [name,change] of [
+ ['foreign key',es=>es[1].key='gid://shopify/InventoryItem/999@gid://shopify/Location/1'],
+ ['quantity',es=>es[1].before=999],['missing intent',es=>es.splice(1,1)],
+ ['duplicate success',es=>es.splice(3,0,es[2])],['rollback without applied success',es=>{es[1].direction='rollback';es[1].before=0;es[1].after=2026;}],
+ ['foreign header',es=>es[0].manifestHash='a'.repeat(64)],['unknown event',es=>es[1].type='reconciled'],
+])test('forged history rejected even with recomputed checkpoint: '+name,()=>{const f=fixture();assert.equal(invoke(f,'--canary').status,0);const es=journal(f);change(es);fs.writeFileSync(f.journal,forge(es));const before=hash(fs.readFileSync(f.state));fail(invoke(f,'--rollback',[],{resume:true,noWrites:true}),/journal|Journal|Unbound|Foreign|Unknown|Invalid/);assert.equal(hash(fs.readFileSync(f.state)),before);});
+test('corrupt, truncated and wrong external journal hash refuse before adapter',()=>{for(const mutation of [s=>s.slice(0,-1),s=>s.replace('header','bogus')]){const f=fixture();assert.equal(invoke(f,'--canary').status,0);fs.writeFileSync(f.journal,mutation(fs.readFileSync(f.journal,'utf8')));fail(invoke(f,'--rollback',[],{resume:true,noWrites:true}),/Truncated|Corrupt/);}const f=fixture();assert.equal(invoke(f,'--canary').status,0);fail(invoke(f,'--canary',['--journal-sha256','a'.repeat(64)],{noWrites:true}),/Journal SHA256/);fail(invoke(f,'--canary',[],{noWrites:true}),/Existing journal requires/);});
+test('existing concurrent journal lock refuses without writes',()=>{const f=fixture();assert.equal(invoke(f,'--canary').status,0);fs.mkdirSync(f.journal+'.lock');const before=hash(fs.readFileSync(f.state));fail(invoke(f,'--canary',[],{resume:true}),/EEXIST/);assert.equal(hash(fs.readFileSync(f.state)),before);});
+for(const [code,label] of [["require('node:fs').readFileSync('/Users/macstudio3/Projects/secrets-manager/.env')",'fs.readFileSync'],["fetch('https://example.invalid')",'fetch'],["require('node:https').get('https://example.invalid')",'node:https.get'],["require('node:child_process').spawn('never-launch')",'node:child_process.spawn']])test('denied real boundary calibration '+label,()=>{const r=spawnSync(process.execPath,['--require',guard,'--eval',code],{encoding:'utf8',env:{}});assert.notEqual(r.status,0);assert.match(r.stderr,new RegExp('BOUNDARY_DENIED:'+label.replaceAll('.','\\.')));});
+test('confirmed adapter success then failed success append leaves only intent and blocks both recoveries',()=>{
+  for(const mode of ['--canary','--rollback']) {
+    const f=fixture();if(mode==='--rollback')assert.equal(invoke(f,'--canary').status,0);
+    fail(invoke(f,mode,[],{resume:mode==='--rollback',failSuccessAppend:true}),/after confirmed mutation before success append/);
+    assert.equal(journal(f).at(-1).type,'intent');
+    assert.equal(state(f).records[2].onHand,mode==='--canary'?0:2026);
+    for(const recovery of ['--canary','--rollback'])fail(invoke(f,recovery,[],{resume:true,noWrites:true}),/Unresolved mutation intent/);
+  }
+});
+test('rollback postread failure retains success; verified retry performs no duplicate restore',()=>{
+  const f=fixture();assert.equal(invoke(f,'--canary').status,0);
+  updateState(f,s=>s.faults[key(s.records[2])]='bad-postread');
+  fail(invoke(f,'--rollback',[],{resume:true}),/precondition drift/);
+  assert.equal(journal(f).at(-1).type,'success');assert.equal(journal(f).at(-1).direction,'rollback');
+  const sets=state(f).calls.filter(c=>c.method==='set').length;
+  fail(invoke(f,'--rollback',[],{resume:true}),/precondition drift/);
+  updateState(f,s=>{s.records[2].variantId=f.manifest.records[2].variantId;s.faults={};});
+  assert.equal(invoke(f,'--rollback',[],{resume:true}).status,0);
+  assert.equal(state(f).calls.filter(c=>c.method==='set').length,sets);
+  assert.equal(journal(f).at(-1).type,'verified');
+});
+test('durable helper rejects symlink and hardlink targets without altering victims',async()=>{
+  const {durableWrite}=await import('../vienna-executor.mjs');
+  for(const kind of ['symlink','hardlink']) {
+    const f=fixture(),victim=path.join(f.dir,'victim.json'),alias=path.join(f.dir,'alias.json');
+    fs.writeFileSync(victim,'retained'); if(kind==='symlink')fs.symlinkSync(victim,alias);else fs.linkSync(victim,alias);
+    assert.throws(()=>durableWrite(alias,'replaced'),/Unsafe write target/);assert.equal(fs.readFileSync(victim,'utf8'),'retained');
+  }
+});
+test('actual CLI rejects linked manifest, state and journal without modifying targets',()=>{
+  for(const file of ['path','state','journal']) {
+    const f=fixture();if(file==='journal')assert.equal(invoke(f,'--canary').status,0);
+    const original=f[file],alias=path.join(f.dir,'alias-'+file);fs.symlinkSync(original,alias);f[file]=alias;
+    const before=hash(fs.readFileSync(original));
+    fail(invoke(f,'--canary',[],{resume:file==='journal',noWrites:true,allowAdapterRead:file==='state'}),/ELOOP|symbolic/);
+    assert.equal(hash(fs.readFileSync(original)),before);
+  }
+});
diff --git a/verification/vienna-e2e-proof.json b/verification/vienna-e2e-proof.json
new file mode 100644
index 0000000..35d135a
--- /dev/null
+++ b/verification/vienna-e2e-proof.json
@@ -0,0 +1,118 @@
+{
+  "intent": "Harden actual Vienna inventory CLI and prove the local executor contract with hermetic persisted adapters",
+  "risk_tier": "R3 local integration rehearsal only",
+  "environment": "macOS; detached isolated worktree; no real secrets or network",
+  "baseline_commit": "7fb358ca8948290915678dd2c34f83a02d5a0532",
+  "build_identity": "Content hashes below; local commit reported in handoff",
+  "timestamp": "2026-09-08T12:52:25.579722+00:00",
+  "ticket": "TK-11300-vienna-inventory-executor-freeze-exact-m",
+  "parent_ticket": "TK-11299-zero-price-bin-zsh-orderable-regression",
+  "task_id": "cycle-20260908T1221Z.HzXvuQ/vienna-executor",
+  "worktree": "/private/tmp/vienna-executor.qdoRbR",
+  "commands": [
+    "VIENNA_EVIDENCE_DIR=/Users/macstudio3/Projects/ticket-system/data/codex-yoloforever/cycle-20260908T1221Z.HzXvuQ node --test test/cli-preflight.test.mjs test/vienna-executor.test.mjs",
+    "node --check apply-fix.mjs",
+    "node --check cli-args.mjs",
+    "node --check vienna-executor.mjs",
+    "node --check vienna-offline-adapter.mjs",
+    "git diff --check"
+  ],
+  "results": {
+    "tests": 87,
+    "pass_count": 87,
+    "failed": 0,
+    "skipped": 0
+  },
+  "checks": [
+    {
+      "check": "CLI preflight and help",
+      "verdict": "PASS",
+      "evidence": "42 legacy CLI and calibrated boundary checks preserved with stricter frozen-input rejection"
+    },
+    {
+      "check": "Manifest and store preflight",
+      "verdict": "PASS",
+      "evidence": "Strict schema, external SHA256, store GID/domain, age, exact GIDs, vendor/line, sample/price/tracking/policy, duplicate/collision, canary/full-location checks before denied adapter reads"
+    },
+    {
+      "check": "Plan",
+      "verdict": "PASS",
+      "evidence": "Actual --plan and --enumerate under denied writes/adapter-state read; no journal or fixture changes"
+    },
+    {
+      "check": "Offline execution",
+      "verdict": "PASS",
+      "evidence": "Exact frozen canary and all-record multi-location compare/set/postread with persisted fixture and journal assertions"
+    },
+    {
+      "check": "Retry and rollback",
+      "verdict": "PASS",
+      "evidence": "No duplicate successful writes; confirmed rejection separated; partial multi-location rollback uses only journal successes; idempotent restore"
+    },
+    {
+      "check": "Ambiguous result and receipt gaps",
+      "verdict": "PASS",
+      "evidence": "Throw before/after persisted write and confirmed response before success append; durable intent blocks apply/rollback before denied adapter boundary in both directions"
+    },
+    {
+      "check": "Postread interruptions",
+      "verdict": "PASS",
+      "evidence": "Forward and rollback success retained, drift blocks further writes, restored matching state permits verification-only recovery"
+    },
+    {
+      "check": "Journal integrity and concurrency",
+      "verdict": "PASS",
+      "evidence": "External checkpoint plus chain/schema/state/membership/quantity checks; malformed/forged/truncated history rejection; existing exclusive lock rejected"
+    },
+    {
+      "check": "File protection",
+      "verdict": "PASS",
+      "evidence": "Symlink and hardlink targets refused; exact input aliases rejected; atomic fixture replacement; retained temp/state"
+    },
+    {
+      "check": "Real denied boundaries",
+      "verdict": "PASS",
+      "evidence": "Canonical secret-file read, fetch, HTTPS and child spawn calibration under process preload; no live transport exists"
+    },
+    {
+      "check": "Syntax and diff",
+      "verdict": "PASS",
+      "evidence": "node --check for four shipped modules and git diff --check"
+    },
+    {
+      "check": "Production execution",
+      "verdict": "OUT_OF_SCOPE",
+      "evidence": "No live adapter, authoritative manifest acquisition, actual shop identity, credential scope or approval; separate parent TK11299 gate"
+    }
+  ],
+  "evidence_directory": "/Users/macstudio3/Projects/ticket-system/data/codex-yoloforever/cycle-20260908T1221Z.HzXvuQ",
+  "final_test_log": "/Users/macstudio3/Projects/ticket-system/data/codex-yoloforever/cycle-20260908T1221Z.HzXvuQ/vienna-test-boundary-final.txt",
+  "retained_failed_run": "/Users/macstudio3/Projects/ticket-system/data/codex-yoloforever/cycle-20260908T1221Z.HzXvuQ/vienna-test-first.txt",
+  "failed_run_cause": "Test factory aliased shared store object; negative mutation contaminated subsequent fixtures. Fixed cloning, then replaced generated baseline with versioned fixture+SHA256.",
+  "historical_proof": "verification/e2e-proof.json and verification/cli-preflight-test-output.txt remain unchanged; source commit7fb358c",
+  "correlations": [
+    "dm-mtsnoxgl-42285-kfum1h",
+    "action-mtsnr96r-13925-y5u8k8",
+    "action-mtso4bm9-13925-fmifo2"
+  ],
+  "cleanup": "All fixture directories, failing logs and interrupted journals retained. Only own completed-process lock is released by runtime code. No live cleanup.",
+  "trust_boundary": "External manifest and journal hashes are independent operator trust anchors, not catalog completeness or arbitrary journal provenance. Operator cannot derive approval by recomputing an unreviewed hash.",
+  "limitations": [
+    "Production adapter intentionally absent; actual transport semantics and permissions unverified",
+    "Synthetic shop and IDs only; authoritative manifest completeness and actual identity remain external preflight",
+    "No automatic resolution of ambiguous intent or crashed lock; independent reconciliation required",
+    "Local process fault injection proves conservative gaps; no physical power-loss experiment"
+  ],
+  "verdict": "PASS for scoped local consumer/executor and offline adapter proof; production recovery remains gated",
+  "file_sha256": {
+    "apply-fix.mjs": "73a910ebf571fae0e5ff69f894af172ce82e2e58c0f576d995b08739d8f192ba",
+    "cli-args.mjs": "716158c0530c7f06937e439dc26d64118a38d081c6bafc9e2d3ae1b3ac5d72fb",
+    "vienna-executor.mjs": "a444d85b388b04e639d7ccb9778dc770bf95e8840a479a94f6b88157ecf5cb4f",
+    "vienna-offline-adapter.mjs": "62b083184cb3ea0818624a97fd13b3068b9052856bff927ddf782abbc94770fc",
+    "test/vienna-executor.test.mjs": "1311d7988988178e8474c60ed86fa8a69c6f1c39c911ec832761df9ad97d8e21",
+    "test/vienna-boundaries.cjs": "2aad1e0b65227f9c74346465eb177c08c2cc606a601f33fb17d725f95d27c4f4",
+    "test/fixtures/vienna-manifest.json": "1b21ab81983284920c22f857a1480741335b5513d003a23b38f9d1c2378bc1c7",
+    "test/fixtures/vienna-manifest.sha256": "061b8fe166b4744e4cef87c02d642f85561a404ffc8158873835af5a77c9a6f2",
+    "VIENNA-EXECUTOR.md": "3d66ed3a13db4732f23e1f85395e41a758add870744cd1c66f9a7dc0252947d9"
+  }
+}
diff --git a/vienna-executor.mjs b/vienna-executor.mjs
new file mode 100644
index 0000000..a7d21f0
--- /dev/null
+++ b/vienna-executor.mjs
@@ -0,0 +1,162 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import {createHash,randomUUID} from 'node:crypto';
+export const DOMAIN='designer-laboratory-sandbox.myshopify.com'; // PRODUCTION despite its name.
+export const hash = bytes=>createHash('sha256').update(bytes).digest('hex');
+const fail = m=>{throw new Error(m);};
+const eq = (a,b)=>JSON.stringify(a)===JSON.stringify(b);
+function keys(x, fields, what) {
+  if (!x || typeof x!=='object' || Array.isArray(x) || !eq(Object.keys(x).sort(),fields.split(' ').sort())) fail('Malformed '+what);
+}
+export const key = r=>`${r.inventoryItemId}@${r.locationId}`;
+const gid=(s,type)=>typeof s==='string' && new RegExp('^gid://shopify/'+type+'/[1-9][0-9]*$').test(s);
+export function readRegular(file) {
+  const fd=fs.openSync(file, fs.constants.O_RDONLY|fs.constants.O_NOFOLLOW);
+  try {const stat=fs.fstatSync(fd); if(!stat.isFile() || stat.nlink!==1 || stat.size>10_000_000) fail('Unsafe file'); return fs.readFileSync(fd,'utf8');}
+  finally {fs.closeSync(fd);}
+}
+export function validateManifest(bytes, expectedHash, shopId, now=Date.now()) {
+  if (hash(bytes)!==expectedHash) fail('Manifest SHA256 mismatch');
+  const m=JSON.parse(bytes);
+  keys(m,'version scope store createdAt expiresAt records canary','manifest');
+  keys(m.store,'domain id','store'); keys(m.scope,'vendor line','scope');
+  if(m.version!==1 || m.scope.vendor!=='Phillipe Romano' || m.scope.line!=='Vienna') fail('Foreign manifest scope');
+  if(m.store.domain!==DOMAIN || m.store.id!==shopId || !gid(shopId,'Shop')) fail('Store pin mismatch');
+  const born=Date.parse(m.createdAt), expires=Date.parse(m.expiresAt);
+  if(!Number.isFinite(born) || !Number.isFinite(expires) || new Date(born).toISOString()!==m.createdAt || new Date(expires).toISOString()!==m.expiresAt || born>now || expires<=now || expires<=born || expires-born>86400000 || now-born>86400000) fail('Stale or invalid manifest validity');
+  if(!Array.isArray(m.records)||!m.records.length||m.records.length>50000||!Array.isArray(m.canary)||!m.canary.length) fail('Empty or excessive manifest scope');
+  const seen=new Set(), variants=new Map(), items=new Map();
+  for(const r of m.records) {
+    keys(r,'productId variantId inventoryItemId locationId vendor line title variantTitle price inventoryPolicy tracked onHand target','record');
+    for(const [f,t] of [['productId','Product'],['variantId','ProductVariant'],['inventoryItemId','InventoryItem'],['locationId','Location']]) if(!gid(r[f],t)) fail('Invalid exact identity '+f);
+    if(r.vendor!==m.scope.vendor || r.line!=='Vienna' || typeof r.title!=='string' || !/^Vienna(?:\s|$)/.test(r.title) || typeof r.variantTitle!=='string' || /sample/i.test(r.variantTitle) || r.price!==0 || r.inventoryPolicy!=='DENY' || r.tracked!==true || !Number.isSafeInteger(r.onHand) || r.onHand<=0 || r.target!==0) fail('Foreign or unsafe record scope');
+    if(seen.has(key(r))) fail('Duplicate inventory location'); seen.add(key(r));
+    const identity=JSON.stringify([r.productId,r.inventoryItemId]);
+    if(variants.has(r.variantId)&&variants.get(r.variantId)!==identity) fail('Variant identity collision'); variants.set(r.variantId,identity);
+    if(items.has(r.inventoryItemId)&&items.get(r.inventoryItemId)!==r.variantId) fail('Item identity collision'); items.set(r.inventoryItemId,r.variantId);
+  }
+  if(new Set(m.canary).size!==m.canary.length || m.canary.some(k=>!seen.has(k))) fail('Canary outside frozen scope');
+  const selected=new Set(m.canary), products=new Set(m.records.filter(r=>selected.has(key(r))).map(r=>r.productId));
+  if(m.records.some(r=>products.has(r.productId)&&!selected.has(key(r)))) fail('Canary must include every frozen location of each selected product');
+  return m;
+}
+function fsyncDirectory(file) { const fd=fs.openSync(path.dirname(file),'r');try{fs.fsyncSync(fd);}finally{fs.closeSync(fd);} }
+export function durableWrite(file, data, flag='w') {
+  // Atomic fixture replacement preserves the last durable truth on interruption.
+  // Refuse aliases before writing, and retain unfinished temp files for inspection.
+  let before;
+  try { before=fs.lstatSync(file); } catch(e) { if(e.code!=='ENOENT')throw e; }
+  if(before && (!before.isFile() || before.nlink!==1)) fail('Unsafe write target');
+  const target=flag==='wx'?file:file+'.pending-'+randomUUID();
+  const fd=fs.openSync(target,fs.constants.O_WRONLY|fs.constants.O_CREAT|fs.constants.O_EXCL|fs.constants.O_NOFOLLOW,0o600);
+  try {if(!fs.fstatSync(fd).isFile()||fs.fstatSync(fd).nlink!==1)fail('Unsafe write descriptor');fs.writeFileSync(fd,data);fs.fsyncSync(fd);} finally {fs.closeSync(fd);}
+  if(flag!=='wx') {
+    let current; try{current=fs.lstatSync(file);}catch(e){if(e.code!=='ENOENT')throw e;}
+    if(Boolean(current)!==Boolean(before) || (current && (!current.isFile()||current.nlink!==1||current.ino!==before.ino||current.dev!==before.dev))) fail('Write target changed');
+    fs.renameSync(target,file);
+  }
+  fsyncDirectory(file);
+}
+function eventLine(body, prev) {const event={...body,prev};return JSON.stringify({...event,hash:hash(JSON.stringify(event))})+'\n';}
+export function readJournal(bytes, manifestHash, m) {
+  if(!bytes.endsWith('\n')) fail('Truncated journal');
+  const lines=bytes.trimEnd().split('\n'); let prev='0'.repeat(64), header, pending=null;
+  const states=new Map(), records=new Map(m.records.map(r=>[key(r),r]));
+  for(let i=0;i<lines.length;i++) {
+    const e=JSON.parse(lines[i]); const {hash:digest,...body}=e;
+    if(digest!==hash(JSON.stringify(body)) || body.prev!==prev || body.seq!==i) fail('Corrupt journal chain'); prev=digest;
+    if(i===0) {
+      keys(e,'seq type manifestHash store selection prev hash','journal header');
+      if(e.type!=='header'||e.manifestHash!==manifestHash||!eq(e.store,m.store)||!['--canary','--all'].includes(e.selection)) fail('Foreign journal');
+      header=e; continue;
+    }
+    keys(e,'seq type key direction before after prev hash','journal event');
+    const r=records.get(e.key);
+    if(!r || (header.selection==='--canary'&&!m.canary.includes(e.key)) || !['apply','rollback'].includes(e.direction)) fail('Journal scope injection');
+    if(e.before!==(e.direction==='apply'?r.onHand:0)||e.after!==(e.direction==='apply'?0:r.onHand)) fail('Journal quantity injection');
+    const s=states.get(e.key)||'unattempted';
+    if(e.type==='intent') {
+      if(pending || (e.direction==='apply'&&!['unattempted','rejected'].includes(s)) || (e.direction==='rollback'&&s!=='applied')) fail('Invalid journal transition');
+      pending=e;
+    } else if(['success','rejected','verified'].includes(e.type)) {
+      if(e.type==='verified') {
+        if(pending || s!==(e.direction==='apply'?'applied-unverified':'rolledback-unverified')) fail('Unbound verification');
+        states.set(e.key,e.direction==='apply'?'applied':'rolledback');
+      } else {
+        if(!pending || !eq([pending.key,pending.direction,pending.before,pending.after],[e.key,e.direction,e.before,e.after])) fail('Unbound journal outcome');
+        states.set(e.key,e.type==='success'?(e.direction==='apply'?'applied-unverified':'rolledback-unverified'):(e.direction==='apply'?'rejected':'applied'));
+        pending=null;
+      }
+    } else fail('Unknown journal event');
+  }
+  if(pending) fail('Unresolved mutation intent: reconciliation required; never infer failure');
+  return {header,states,seq:lines.length,prev};
+}
+function assertSnapshot(actual,r,quantity) {
+  const expected={...r,onHand:quantity};
+  if(!eq(actual,expected)) fail('Identity, quantity or product precondition drift at '+key(r));
+}
+export async function run(cli) {
+  const manifestPath=path.resolve(cli['--manifest']);
+  const m=validateManifest(readRegular(manifestPath),cli['--expected-sha256'],cli['--expected-store-id']);
+  if(['--plan','--enumerate'].includes(cli.mode)) return {mode:'plan',manifestHash:cli['--expected-sha256'],store:m.store,records:m.records,canary:m.canary,mutations:0};
+  const journalPath=path.resolve(cli['--journal']),statePath=path.resolve(cli['--offline-state']);
+  if(new Set([manifestPath,journalPath,statePath]).size!==3) fail('Input/output paths must be distinct');
+  const exists=fs.existsSync(journalPath);
+  let journal;
+  if(exists) {
+    if(!cli['--journal-sha256']) fail('Existing journal requires external SHA256 checkpoint');
+    const bytes=readRegular(journalPath); if(hash(bytes)!==cli['--journal-sha256']) fail('Journal SHA256 mismatch');
+    journal=readJournal(bytes,cli['--expected-sha256'],m);
+    if(cli.mode!=='--rollback'&&journal.header.selection!==cli.mode) fail('Cannot broaden frozen journal selection');
+  } else if(cli.mode==='--rollback'||cli['--journal-sha256']) fail('Missing pinned journal');
+  // The only adapter shipped by this local increment is hermetic and explicitly selected.
+  // Future live wiring needs separate approval and a reviewed identity/auth contract.
+  const {openOfflineAdapter}=await import('./vienna-offline-adapter.mjs');
+  const adapter=openOfflineAdapter(statePath);
+  if(!eq(await adapter.shop(),m.store)) fail('Adapter store mismatch');
+  const selection=journal?.header.selection||cli.mode;
+  const records=m.records.filter(r=>selection==='--all'||m.canary.includes(key(r)));
+  if(cli.mode!=='--rollback' && [...(journal?.states.values()||[])].some(s=>s.startsWith('rolledback'))) fail('Rolled back run cannot reapply');
+  // Exclusive process lock. A crashed holder leaves the lock for independent reconciliation.
+  const lock=journalPath+'.lock'; fs.mkdirSync(lock,{mode:0o700});
+  try {
+    // Recheck checkpoint under lock: concurrent changes cannot pass a stale validation.
+    if(exists && hash(readRegular(journalPath))!==cli['--journal-sha256']) fail('Journal changed before lock');
+    if(!exists) {
+      const line=eventLine({seq:0,type:'header',manifestHash:cli['--expected-sha256'],store:m.store,selection},'0'.repeat(64));
+      durableWrite(journalPath,line,'wx'); journal=readJournal(line,cli['--expected-sha256'],m);
+    }
+    const append=(type,r,direction)=>{
+      const line=eventLine({seq:journal.seq,type,key:key(r),direction,before:direction==='apply'?r.onHand:0,after:direction==='apply'?0:r.onHand},journal.prev);
+      const fd=fs.openSync(journalPath,fs.constants.O_WRONLY|fs.constants.O_APPEND|fs.constants.O_NOFOLLOW);
+      try{const stat=fs.fstatSync(fd);if(!stat.isFile()||stat.nlink!==1)fail('Unsafe journal descriptor');fs.writeFileSync(fd,line);fs.fsyncSync(fd);}finally{fs.closeSync(fd);}
+      journal.seq++; journal.prev=JSON.parse(line).hash;
+    };
+    let writes=0,skipped=0;
+    for(const r of records) {
+      let s=journal.states.get(key(r))||'unattempted';
+      // A durable success whose post-read was interrupted is never written again.
+      if(s.endsWith('-unverified')) {
+        const direction=s==='applied-unverified'?'apply':'rollback';
+        assertSnapshot(await adapter.read(r),r,direction==='apply'?0:r.onHand);
+        append('verified',r,direction); s=direction==='apply'?'applied':'rolledback';
+      }
+      if(cli.mode==='--rollback' && s!=='applied') {skipped++;continue;}
+      if(cli.mode!=='--rollback' && s==='applied') {assertSnapshot(await adapter.read(r),r,0);skipped++;continue;}
+      const direction=cli.mode==='--rollback'?'rollback':'apply';
+      const before=direction==='apply'?r.onHand:0, after=direction==='apply'?0:r.onHand;
+      assertSnapshot(await adapter.read(r),r,before);
+      append('intent',r,direction); // fsync before crossing the mutation boundary.
+      const result=await adapter.set(r,before,after); // exceptions leave unresolved durable intent.
+      if(result?.kind==='rejected' && result.confirmedNoWrite===true) {
+        append('rejected',r,direction); fail('Confirmed mutation rejection at '+key(r));
+      }
+      if(result?.kind!=='success'||result.key!==key(r)||result.quantity!==after) fail('Ambiguous mutation result; reconciliation required');
+      append('success',r,direction); // only confirmed successes authorize rollback.
+      assertSnapshot(await adapter.read(r),r,after);
+      append('verified',r,direction); writes++;
+    }
+    return {mode:cli.mode,store:m.store,writes,skipped,journal:journalPath,journalSha256:hash(readRegular(journalPath)),manifestHash:cli['--expected-sha256'],adapter:'offline-only'};
+  } finally {fs.rmdirSync(lock);}
+}
diff --git a/vienna-offline-adapter.mjs b/vienna-offline-adapter.mjs
new file mode 100644
index 0000000..3323c6f
--- /dev/null
+++ b/vienna-offline-adapter.mjs
@@ -0,0 +1,24 @@
+// Deterministic file-backed test adapter. No secrets, imports of live clients, or network.
+import {readRegular,durableWrite,key} from './vienna-executor.mjs';
+export function openOfflineAdapter(file) {
+  const state=JSON.parse(readRegular(file));
+  if(state.fixture!==true || state.version!==1 || !Array.isArray(state.records) || !Array.isArray(state.calls)) throw new Error('Offline fixture required');
+  const persist=()=>durableWrite(file,JSON.stringify(state,null,2)+'\n');
+  const mark=(method,k)=>{state.calls.push({method,key:k});persist();};
+  return {
+    async shop(){return state.store;},
+    async read(r){ mark('read',key(r)); return state.records.find(x=>key(x)===key(r)); },
+    async set(r,before,after) {
+      mark('set',key(r));
+      const actual=state.records.find(x=>key(x)===key(r));
+      if(!actual||actual.onHand!==before) return {kind:'rejected',confirmedNoWrite:true};
+      const fault=state.faults?.[key(r)];
+      if(fault==='reject') return {kind:'rejected',confirmedNoWrite:true};
+      if(fault==='throw-before') throw new Error('Simulated transport failure before response');
+      actual.onHand=after; persist();
+      if(fault==='throw-after') throw new Error('Simulated transport failure after persisted write');
+      if(fault==='bad-postread') { actual.variantId='gid://shopify/ProductVariant/999';persist(); }
+      return {kind:'success',key:key(r),quantity:after};
+    }
+  };
+}

← 7fb358c Reject unsafe inventory CLI arguments before initialization  ·  back to Tk 10965 Zero Price Analysis  ·  Reload fixture truth and serialize competing Vienna CLI writ c57e84a →