[object Object]

← back to Tk 10965 Zero Price Analysis

Reload fixture truth and serialize competing Vienna CLI writers

c57e84a0926d004bada07437e617ebbdcb22d820 · 2026-09-08 05:59:33 -0700 · Steve Abrams

Files touched

Diff

commit c57e84a0926d004bada07437e617ebbdcb22d820
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Sep 8 05:59:33 2026 -0700

    Reload fixture truth and serialize competing Vienna CLI writers
---
 VIENNA-EXECUTOR.md                                |  20 ++-
 test/vienna-boundaries.cjs                        |  23 +++-
 test/vienna-executor.test.mjs                     |  35 ++++-
 verification/cli-preflight-e2e-proof-7fb358c.json |  70 ++++++++++
 verification/e2e-proof.json                       | 152 ++++++++++++++++------
 verification/vienna-e2e-proof.json                |  44 +++++--
 vienna-executor.mjs                               |  10 +-
 vienna-offline-adapter.mjs                        |  30 +++--
 8 files changed, 309 insertions(+), 75 deletions(-)

diff --git a/VIENNA-EXECUTOR.md b/VIENNA-EXECUTOR.md
index f88c409..47549a9 100644
--- a/VIENNA-EXECUTOR.md
+++ b/VIENNA-EXECUTOR.md
@@ -56,7 +56,17 @@ 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.
+under the exclusive journal lock to prevent a concurrent stale replay. A second
+lock covers the shared fixture state for the entire CLI journey, so supported
+competing CLI writers with different journals cannot race their compare/write.
+Both locks release only after their own successful acquisition. Abandoned locks
+remain conservative blockers after an actual process crash.
+
+The adapter reloads persisted state for every shop/read/set operation, rechecks
+the pinned store each time, and rechecks all record preconditions immediately
+before mutation. Reads are nonmutating and never persist an earlier snapshot.
+Direct unsynchronized file edits are test-injected drift, not supported writers;
+the separate live adapter must supply a real service-side compare-and-set.
 
 Journal parsing validates the chain, sequence, schema, manifest/store binding,
 frozen selection, exact quantities and valid per-record state transitions. It
@@ -76,7 +86,11 @@ 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.
+`7fb358ca8948290915678dd2c34f83a02d5a0532` and `verification/cli-preflight-e2e-proof-7fb358c.json`.
 Legacy write-mode test assertions now require manifest rejection rather than
-reaching runtime initialization. The new proof is `verification/vienna-e2e-proof.json`.
+reaching runtime initialization. The current canonical proof is `verification/e2e-proof.json`, with a detailed
+`verification/vienna-e2e-proof.json` sibling. The provisional87-test proof at
+commit7645583 predates an independently reproduced adapter stale-cache defect;
+the corrected91-test proof includes inter-operation drift and actual competing
+CLI subprocesses. That provisional claim is superseded, not accepted as final.
 All fixture directories and failed-run logs are retained; no cleanup is required.
diff --git a/test/vienna-boundaries.cjs b/test/vienna-boundaries.cjs
index b3dff05..c075814 100644
--- a/test/vienna-boundaries.cjs
+++ b/test/vienna-boundaries.cjs
@@ -1,6 +1,8 @@
 // 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 rawReadFile=fs.readFileSync.bind(fs),rawWriteFile=fs.writeFileSync.bind(fs);
+let lastJournalEvent, drifted=false;
 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||'[]'));
@@ -17,7 +19,7 @@ fs.openSync=function(file,flags,...rest){
 };
 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 ['writeFileSync','appendFileSync']){const orig=fs[name].bind(fs);fs[name]=function(file,...rest){if(!canWrite(file))return deny('fs.'+name);if(p(file)?.endsWith('.jsonl')) {try{lastJournalEvent=JSON.parse(String(rest[0]));}catch{}}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);};
@@ -32,3 +34,22 @@ 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();
+
+const rawFsync=fs.fsyncSync.bind(fs);
+fs.fsyncSync=function(fd){
+  const result=rawFsync(fd);
+  if(lastJournalEvent?.type==='intent'&&!drifted&&process.env.VIENNA_EXTERNAL_DRIFT){
+    drifted=true;
+    const file=process.env.VIENNA_EXTERNAL_DRIFT;
+    const current=JSON.parse(rawReadFile(file,'utf8'));
+    if(process.env.VIENNA_DRIFT_STORE==='1')current.store.id='gid://shopify/Shop/888';else current.records[0].onHand=9;
+    rawWriteFile(file,JSON.stringify(current,null,2)+'\n');
+  }
+  if(lastJournalEvent?.type==='header'&&process.env.VIENNA_HOLD_LOCK==='1') {
+    // Only a test process pauses. Parent test launches a competing actual CLI here.
+    process.stdout.write('TEST_LOCK_HELD\n');
+    Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,700);
+  }
+  return result;
+};
+syncBuiltinESMExports();
diff --git a/test/vienna-executor.test.mjs b/test/vienna-executor.test.mjs
index 7ca5268..0023542 100644
--- a/test/vienna-executor.test.mjs
+++ b/test/vienna-executor.test.mjs
@@ -3,7 +3,7 @@ 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 {spawnSync,spawn} 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));
@@ -29,7 +29,7 @@ function invoke(f,mode='--all',extra=[],opts={}){
   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'])}
+    encoding:'utf8',timeout:5000,env:{VIENNA_EXTERNAL_DRIFT:opts.externalDrift?f.state:'',VIENNA_DRIFT_STORE:opts.driftStore?'1':'',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',f.state+'.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));
@@ -118,3 +118,34 @@ test('actual CLI rejects linked manifest, state and journal without modifying ta
     assert.equal(hash(fs.readFileSync(original)),before);
   }
 });
+test('open adapter reloads external quantity drift and read never overwrites persisted truth',async()=>{
+  const {openOfflineAdapter}=await import('../vienna-offline-adapter.mjs');const f=fixture();
+  const adapter=openOfflineAdapter(f.state,store);updateState(f,s=>s.records[0].onHand=9);
+  const before=hash(fs.readFileSync(f.state));assert.equal((await adapter.read(f.manifest.records[0])).onHand,9);
+  assert.equal(hash(fs.readFileSync(f.state)),before);
+  assert.deepEqual(await adapter.set(f.manifest.records[0],2026,0),{kind:'rejected',confirmedNoWrite:true});
+  assert.equal(hash(fs.readFileSync(f.state)),before);
+});
+test('actual CLI rejects quantity drift injected after intent fsync before compare/write',()=>{
+  const f=fixture();fail(invoke(f,'--all',[],{externalDrift:true}),/Confirmed mutation rejection/);
+  assert.equal(state(f).records[0].onHand,9);assert.equal(journal(f).at(-1).type,'rejected');
+  assert.equal(journal(f).filter(e=>e.type==='success').length,0);
+  fail(invoke(f,'--all',[],{resume:true}),/precondition drift/);
+});
+test('actual CLI detects refreshed store drift after intent and leaves unresolved receipt',()=>{
+  const f=fixture();fail(invoke(f,'--all',[],{externalDrift:true,driftStore:true}),/Adapter store mismatch/);
+  assert.equal(state(f).records[0].onHand,2026);assert.equal(journal(f).at(-1).type,'intent');
+  fail(invoke(f,'--all',[],{resume:true,noWrites:true}),/Unresolved/);
+});
+test('competing actual CLI writers with different journals share one state lock',async()=>{
+  const f=fixture();const firstArgs=['--all','--manifest',f.path,'--expected-sha256',f.sha,'--expected-store-id',store.id,'--offline-state',f.state,'--journal',f.journal];
+  const child=spawn(process.execPath,['--require',guard,path.join(root,'apply-fix.mjs'),...firstArgs],{env:{VIENNA_HOLD_LOCK:'1',VIENNA_ALLOWED_READS:JSON.stringify([...sourceFiles,f.path,f.state,f.journal]),VIENNA_ALLOWED_WRITES:JSON.stringify([f.state,f.journal]),VIENNA_ALLOWED_DIRS:JSON.stringify([f.dir,f.journal+'.lock',f.state+'.lock'])},stdio:['ignore','pipe','pipe']});
+  let output='',errors='',contender;
+  child.stdout.on('data',b=>{output+=b;if(!contender&&output.includes('TEST_LOCK_HELD')){const second={...f,journal:path.join(f.dir,'second.jsonl')};contender=invoke(second);assert.equal(fs.existsSync(second.journal),false);}});
+  child.stderr.on('data',b=>errors+=b);
+  const code=await new Promise((resolve,reject)=>{child.on('error',reject);child.on('close',resolve);});
+  assert.equal(code,0,errors);assert.ok(contender,'First CLI exposed lock checkpoint');fail(contender,/EEXIST/);
+  assert.equal(state(f).calls.filter(c=>c.method==='set').length,4);
+  assert.equal(fs.existsSync(f.state+'.lock'),false);assert.equal(fs.existsSync(f.journal+'.lock'),false);
+  fs.writeFileSync(path.join(f.dir,'competing-writer-proof.json'),JSON.stringify({firstArgs,code,output,errors,contender},null,2));
+});
diff --git a/verification/cli-preflight-e2e-proof-7fb358c.json b/verification/cli-preflight-e2e-proof-7fb358c.json
new file mode 100644
index 0000000..83dec89
--- /dev/null
+++ b/verification/cli-preflight-e2e-proof-7fb358c.json
@@ -0,0 +1,70 @@
+{
+  "schema_version": 1,
+  "task_id": "cycle-20260908T1121Z.O0jFR4/vienna-cli-guard",
+  "ticket": "TK-11299-zero-price-bin-zsh-orderable-regression",
+  "intent": "Reject malformed invocations and safely show help before runtime initialization; preserve recognized parser modes",
+  "risk_tier": "R1 isolated CLI guard with actual subprocess integration; live inventory R4 remains blocked",
+  "environment": "/private/tmp/vienna-cli-guard-l81wngor/worktree",
+  "timestamp_utc": "2026-09-08T11:48:04.917315+00:00",
+  "baseline_commit": "55f8804fcd7c46032073893bf9724b1f99023739",
+  "node_version": "v26.4.0",
+  "code_sha256": {
+    "apply-fix.mjs": "d806221f4dc7751bf0e7fe35d4d88975ca0a0df67653e012677fb3080c09ee8a",
+    "cli-args.mjs": "cf52141b25bf74ff77cd1bd3b9e03bc7976b1df97aca4e2348c3bb1500c97888",
+    "test/cli-preflight.test.mjs": "1cedcc7da5904f16c5d66e05120e0addddc4cb6288ad9c0337d4f66375c119df",
+    "test/deny-side-effects.cjs": "a02860f2ae9043a3a12f64e394160a5bed24615dbfc5a352afcebb45a9b426fc"
+  },
+  "commands": [
+    "CLI_BASELINE_ENTRY=/Users/macstudio3/Projects/tk-10965-zero-price-analysis/apply-fix.mjs node --test test/cli-preflight.test.mjs",
+    "git diff --check"
+  ],
+  "checks": [
+    {
+      "name": "Original actual CLI with missing/help/typo arguments",
+      "verdict": "PASS",
+      "observed": "3 baseline invocations all attempt mkdirSync; preload throws before actual write or credentials"
+    },
+    {
+      "name": "Patched actual CLI invalid arguments",
+      "verdict": "PASS",
+      "cases": 25,
+      "observed": "Exit2, clear usage, zero intercepted filesystem mutation, sensitive-read, network or subprocess attempts"
+    },
+    {
+      "name": "Patched actual CLI help",
+      "verdict": "PASS",
+      "observed": "Exit0, usage, zero intercepted attempts"
+    },
+    {
+      "name": "Recognized modes parser and actual entry",
+      "verdict": "PASS",
+      "cases": 7,
+      "observed": "Expected parse outputs; actual CLI stops at intercepted mkdirSync only; no real initialization"
+    },
+    {
+      "name": "Deny-hook calibration",
+      "verdict": "PASS",
+      "cases": 6,
+      "observed": "Sensitive read/write, promise read, fetch, HTTPS and subprocess probes each intercepted and denied"
+    },
+    {
+      "name": "Whitespace diff check",
+      "verdict": "PASS"
+    },
+    {
+      "name": "Live inventory remediation and runtime integration",
+      "verdict": "SKIP",
+      "reason": "Outside scope and not approved; exact manifest, bounded executor, explicit write approval including canary still missing"
+    }
+  ],
+  "tests": {
+    "passed": 42,
+    "failed": 0,
+    "skipped": 0,
+    "output": "verification/cli-preflight-test-output.txt"
+  },
+  "boundary_harness": "Preload installed before actual entry imports. Only entry/parser source reads allowed; read-only opens of those source files permitted. Builtin ESM exports synced after fs/network/child-process overrides. First denied call throws. Child environment contains only allowlist; no inherited tokens or NODE_OPTIONS.",
+  "initial_harness_issue": "First test attempt blocked Node source-loader openSync too early; corrected by allowing read-only source opens only, then reran all tests. No real sensitive side effects occurred.",
+  "cleanup": "Isolated worktree and all artifacts retained; original checkout unmodified; no cleanup deletion",
+  "verdict": "PASS for bounded local CLI fix; operational ticket remains UNRESOLVED"
+}
diff --git a/verification/e2e-proof.json b/verification/e2e-proof.json
index 83dec89..981eff2 100644
--- a/verification/e2e-proof.json
+++ b/verification/e2e-proof.json
@@ -1,70 +1,136 @@
 {
-  "schema_version": 1,
-  "task_id": "cycle-20260908T1121Z.O0jFR4/vienna-cli-guard",
-  "ticket": "TK-11299-zero-price-bin-zsh-orderable-regression",
-  "intent": "Reject malformed invocations and safely show help before runtime initialization; preserve recognized parser modes",
-  "risk_tier": "R1 isolated CLI guard with actual subprocess integration; live inventory R4 remains blocked",
-  "environment": "/private/tmp/vienna-cli-guard-l81wngor/worktree",
-  "timestamp_utc": "2026-09-08T11:48:04.917315+00:00",
-  "baseline_commit": "55f8804fcd7c46032073893bf9724b1f99023739",
-  "node_version": "v26.4.0",
-  "code_sha256": {
-    "apply-fix.mjs": "d806221f4dc7751bf0e7fe35d4d88975ca0a0df67653e012677fb3080c09ee8a",
-    "cli-args.mjs": "cf52141b25bf74ff77cd1bd3b9e03bc7976b1df97aca4e2348c3bb1500c97888",
-    "test/cli-preflight.test.mjs": "1cedcc7da5904f16c5d66e05120e0addddc4cb6288ad9c0337d4f66375c119df",
-    "test/deny-side-effects.cjs": "a02860f2ae9043a3a12f64e394160a5bed24615dbfc5a352afcebb45a9b426fc"
-  },
+  "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:59:32.920387+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": [
-    "CLI_BASELINE_ENTRY=/Users/macstudio3/Projects/tk-10965-zero-price-analysis/apply-fix.mjs node --test test/cli-preflight.test.mjs",
+    "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": 91,
+    "pass_count": 91,
+    "failed": 0,
+    "skipped": 0
+  },
   "checks": [
     {
-      "name": "Original actual CLI with missing/help/typo arguments",
+      "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",
-      "observed": "3 baseline invocations all attempt mkdirSync; preload throws before actual write or credentials"
+      "evidence": "Exact frozen canary and all-record multi-location compare/set/postread with persisted fixture and journal assertions"
     },
     {
-      "name": "Patched actual CLI invalid arguments",
+      "check": "Retry and rollback",
       "verdict": "PASS",
-      "cases": 25,
-      "observed": "Exit2, clear usage, zero intercepted filesystem mutation, sensitive-read, network or subprocess attempts"
+      "evidence": "No duplicate successful writes; confirmed rejection separated; partial multi-location rollback uses only journal successes; idempotent restore"
     },
     {
-      "name": "Patched actual CLI help",
+      "check": "Ambiguous result and receipt gaps",
       "verdict": "PASS",
-      "observed": "Exit0, usage, zero intercepted attempts"
+      "evidence": "Throw before/after persisted write and confirmed response before success append; durable intent blocks apply/rollback before denied adapter boundary in both directions"
     },
     {
-      "name": "Recognized modes parser and actual entry",
+      "check": "Postread interruptions",
       "verdict": "PASS",
-      "cases": 7,
-      "observed": "Expected parse outputs; actual CLI stops at intercepted mkdirSync only; no real initialization"
+      "evidence": "Forward and rollback success retained, drift blocks further writes, restored matching state permits verification-only recovery"
     },
     {
-      "name": "Deny-hook calibration",
+      "check": "Journal integrity and concurrency",
       "verdict": "PASS",
-      "cases": 6,
-      "observed": "Sensitive read/write, promise read, fetch, HTTPS and subprocess probes each intercepted and denied"
+      "evidence": "External checkpoint plus chain/schema/state/membership/quantity checks; malformed/forged/truncated history rejection; existing exclusive lock rejected"
     },
     {
-      "name": "Whitespace diff check",
-      "verdict": "PASS"
+      "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"
     },
     {
-      "name": "Live inventory remediation and runtime integration",
-      "verdict": "SKIP",
-      "reason": "Outside scope and not approved; exact manifest, bounded executor, explicit write approval including canary still missing"
+      "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"
+    },
+    {
+      "check": "After-open and after-intent drift",
+      "verdict": "PASS",
+      "evidence": "Independent library regression read preserves quantity9 without writes; actual CLI preload injects external quantity9 after intent fsync, rejects compare/write, persists9 and records no successful mutation"
+    },
+    {
+      "check": "Refreshed store identity",
+      "verdict": "PASS",
+      "evidence": "Actual CLI injected store drift after intent fails renewed adapter pin; unresolved intent blocks further replay before adapter"
+    },
+    {
+      "check": "Competing CLI writers",
+      "verdict": "PASS",
+      "evidence": "Two real child CLI processes use different journals against one fixture; first pauses after journal header while state lock held, contender rejects EEXIST with no second journal, first completes4 writes; both owned locks released"
     }
   ],
-  "tests": {
-    "passed": 42,
-    "failed": 0,
-    "skipped": 0,
-    "output": "verification/cli-preflight-test-output.txt"
+  "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-fix3.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/cli-preflight-e2e-proof-7fb358c.json and source commit7fb358c; provisional87-test proof preserved in git7645583 and cycle/vienna-e2e-proof-provisional-7645583.json",
+  "correlations": [
+    "dm-mtsnoxgl-42285-kfum1h",
+    "action-mtsnr96r-13925-y5u8k8",
+    "action-mtso4bm9-13925-fmifo2",
+    "action-mtso70ap-13925-lhw161"
+  ],
+  "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; only supported CLI writers share fixture-state locking",
+    "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": "78203b13d56676a735f586baca0bce49bf521e5740024bf815a5f5e59ab2b03c",
+    "vienna-offline-adapter.mjs": "eba5810037757cdfb106a3b7d1cd93b9283c14b382ce72949b596031bd526698",
+    "test/vienna-executor.test.mjs": "c9fc5f45a0f3a2f17f0d5e9ce6be52ae8d622772edb12d1b776064036db3a197",
+    "test/vienna-boundaries.cjs": "5f16fb3d167d77fd340ff5d0933e5a12cb09be9cf98d3b305cac1930ac98de1d",
+    "test/fixtures/vienna-manifest.json": "1b21ab81983284920c22f857a1480741335b5513d003a23b38f9d1c2378bc1c7",
+    "test/fixtures/vienna-manifest.sha256": "061b8fe166b4744e4cef87c02d642f85561a404ffc8158873835af5a77c9a6f2",
+    "VIENNA-EXECUTOR.md": "4aed87b9797df54408cde1103a70a1080bd84cb11ad2c7e9dc8f60b94c6fb37e"
   },
-  "boundary_harness": "Preload installed before actual entry imports. Only entry/parser source reads allowed; read-only opens of those source files permitted. Builtin ESM exports synced after fs/network/child-process overrides. First denied call throws. Child environment contains only allowlist; no inherited tokens or NODE_OPTIONS.",
-  "initial_harness_issue": "First test attempt blocked Node source-loader openSync too early; corrected by allowing read-only source opens only, then reran all tests. No real sensitive side effects occurred.",
-  "cleanup": "Isolated worktree and all artifacts retained; original checkout unmodified; no cleanup deletion",
-  "verdict": "PASS for bounded local CLI fix; operational ticket remains UNRESOLVED"
+  "superseded_claim": "Provisional87-test proof did not cover persisted state changed after adapter open. Independent parent/Cody reproductions showed cached read logging could overwrite current quantities. FIX3 reload/nonmutating read and shared-state locking closes this scoped local defect; prior claim superseded.",
+  "decision": "Final DTD FIX-THEN-SHIP2/2, judge KEEP /private/tmp/dtd-cycle1221-final.l8xVdk; conditional parent/Cody independent verification still required"
 }
diff --git a/verification/vienna-e2e-proof.json b/verification/vienna-e2e-proof.json
index 35d135a..981eff2 100644
--- a/verification/vienna-e2e-proof.json
+++ b/verification/vienna-e2e-proof.json
@@ -4,7 +4,7 @@
   "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",
+  "timestamp": "2026-09-08T12:59:32.920387+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",
@@ -18,8 +18,8 @@
     "git diff --check"
   ],
   "results": {
-    "tests": 87,
-    "pass_count": 87,
+    "tests": 91,
+    "pass_count": 91,
     "failed": 0,
     "skipped": 0
   },
@@ -83,22 +83,38 @@
       "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"
+    },
+    {
+      "check": "After-open and after-intent drift",
+      "verdict": "PASS",
+      "evidence": "Independent library regression read preserves quantity9 without writes; actual CLI preload injects external quantity9 after intent fsync, rejects compare/write, persists9 and records no successful mutation"
+    },
+    {
+      "check": "Refreshed store identity",
+      "verdict": "PASS",
+      "evidence": "Actual CLI injected store drift after intent fails renewed adapter pin; unresolved intent blocks further replay before adapter"
+    },
+    {
+      "check": "Competing CLI writers",
+      "verdict": "PASS",
+      "evidence": "Two real child CLI processes use different journals against one fixture; first pauses after journal header while state lock held, contender rejects EEXIST with no second journal, first completes4 writes; both owned locks released"
     }
   ],
   "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",
+  "final_test_log": "/Users/macstudio3/Projects/ticket-system/data/codex-yoloforever/cycle-20260908T1221Z.HzXvuQ/vienna-test-fix3.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",
+  "historical_proof": "verification/cli-preflight-e2e-proof-7fb358c.json and source commit7fb358c; provisional87-test proof preserved in git7645583 and cycle/vienna-e2e-proof-provisional-7645583.json",
   "correlations": [
     "dm-mtsnoxgl-42285-kfum1h",
     "action-mtsnr96r-13925-y5u8k8",
-    "action-mtso4bm9-13925-fmifo2"
+    "action-mtso4bm9-13925-fmifo2",
+    "action-mtso70ap-13925-lhw161"
   ],
   "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",
+    "Production adapter intentionally absent; actual transport semantics and permissions unverified; only supported CLI writers share fixture-state locking",
     "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"
@@ -107,12 +123,14 @@
   "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",
+    "vienna-executor.mjs": "78203b13d56676a735f586baca0bce49bf521e5740024bf815a5f5e59ab2b03c",
+    "vienna-offline-adapter.mjs": "eba5810037757cdfb106a3b7d1cd93b9283c14b382ce72949b596031bd526698",
+    "test/vienna-executor.test.mjs": "c9fc5f45a0f3a2f17f0d5e9ce6be52ae8d622772edb12d1b776064036db3a197",
+    "test/vienna-boundaries.cjs": "5f16fb3d167d77fd340ff5d0933e5a12cb09be9cf98d3b305cac1930ac98de1d",
     "test/fixtures/vienna-manifest.json": "1b21ab81983284920c22f857a1480741335b5513d003a23b38f9d1c2378bc1c7",
     "test/fixtures/vienna-manifest.sha256": "061b8fe166b4744e4cef87c02d642f85561a404ffc8158873835af5a77c9a6f2",
-    "VIENNA-EXECUTOR.md": "3d66ed3a13db4732f23e1f85395e41a758add870744cd1c66f9a7dc0252947d9"
-  }
+    "VIENNA-EXECUTOR.md": "4aed87b9797df54408cde1103a70a1080bd84cb11ad2c7e9dc8f60b94c6fb37e"
+  },
+  "superseded_claim": "Provisional87-test proof did not cover persisted state changed after adapter open. Independent parent/Cody reproductions showed cached read logging could overwrite current quantities. FIX3 reload/nonmutating read and shared-state locking closes this scoped local defect; prior claim superseded.",
+  "decision": "Final DTD FIX-THEN-SHIP2/2, judge KEEP /private/tmp/dtd-cycle1221-final.l8xVdk; conditional parent/Cody independent verification still required"
 }
diff --git a/vienna-executor.mjs b/vienna-executor.mjs
index a7d21f0..3746fbb 100644
--- a/vienna-executor.mjs
+++ b/vienna-executor.mjs
@@ -113,14 +113,17 @@ export async function run(cli) {
   // 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);
+  const adapter=openOfflineAdapter(statePath,m.store);
   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});
+  const stateLock=statePath+'.lock', lock=journalPath+'.lock';
+  fs.mkdirSync(stateLock,{mode:0o700});
   try {
+    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) {
@@ -158,5 +161,6 @@ export async function run(cli) {
       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);}
+    } finally {fs.rmdirSync(lock);}
+  } finally {fs.rmdirSync(stateLock);}
 }
diff --git a/vienna-offline-adapter.mjs b/vienna-offline-adapter.mjs
index 3323c6f..e3ef273 100644
--- a/vienna-offline-adapter.mjs
+++ b/vienna-offline-adapter.mjs
@@ -1,17 +1,27 @@
-// Deterministic file-backed test adapter. No secrets, imports of live clients, or network.
+// Deterministic file-backed test adapter. All supported CLI writers hold the
+// same state-file lock across the entire journey, including compare and write.
+// Reads never write logs or cached record state back to disk.
 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();};
+export function openOfflineAdapter(file,expectedStore) {
+  const pinned=JSON.stringify(expectedStore);
+  const load=()=>{
+    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');
+    if(JSON.stringify(state.store)!==pinned) throw new Error('Adapter store mismatch');
+    return state;
+  };
+  load();
   return {
-    async shop(){return state.store;},
-    async read(r){ mark('read',key(r)); return state.records.find(x=>key(x)===key(r)); },
+    async shop(){return load().store;},
+    async read(r){return load().records.find(x=>key(x)===key(r));},
     async set(r,before,after) {
-      mark('set',key(r));
+      const state=load();
       const actual=state.records.find(x=>key(x)===key(r));
-      if(!actual||actual.onHand!==before) return {kind:'rejected',confirmedNoWrite:true};
+      // Recompare full current identity/preconditions, not a previously read object.
+      if(JSON.stringify(actual)!==JSON.stringify({...r,onHand:before})) return {kind:'rejected',confirmedNoWrite:true};
+      state.calls.push({method:'set',key:key(r)});
+      const persist=()=>durableWrite(file,JSON.stringify(state,null,2)+'\n');
+      persist();
       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');

← 7645583 Freeze Vienna executor scope and journal offline mutations s  ·  back to Tk 10965 Zero Price Analysis  ·  Fix: prevention test imports canonical master, not stale loc 2525621 →