← back to Designerwallcoverings
TK-11758: gate snapshot write to --apply only; --undo reads only apply snapshots (Cody FIX FIRST)
7a1a14c3e43397e15d796294fea347507bd6e38e · 2026-09-16 17:14:14 -0700 · Steve Abrams
Dry-run no longer writes a snapshot (read-only by contract); newestSnapshot() filters to
snapshot-apply-*.json so --undo can never restore a stale/post-write dry-run map.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGzAvFJiSQ9qXCyjNQ6mjq
Files touched
M scripts/tk-11758-cork-continue-fix/fix.mjs
Diff
commit 7a1a14c3e43397e15d796294fea347507bd6e38e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 16 17:14:14 2026 -0700
TK-11758: gate snapshot write to --apply only; --undo reads only apply snapshots (Cody FIX FIRST)
Dry-run no longer writes a snapshot (read-only by contract); newestSnapshot() filters to
snapshot-apply-*.json so --undo can never restore a stale/post-write dry-run map.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGzAvFJiSQ9qXCyjNQ6mjq
---
scripts/tk-11758-cork-continue-fix/fix.mjs | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/scripts/tk-11758-cork-continue-fix/fix.mjs b/scripts/tk-11758-cork-continue-fix/fix.mjs
index 849634c..ccad672 100644
--- a/scripts/tk-11758-cork-continue-fix/fix.mjs
+++ b/scripts/tk-11758-cork-continue-fix/fix.mjs
@@ -44,8 +44,12 @@ async function readState() {
}
function newestSnapshot() {
- const files = fs.readdirSync(SNAP_DIR).filter(f => f.endsWith('.json')).sort();
- if (!files.length) throw new Error('no snapshot to undo from — run dry-run or --apply first');
+ // TK-11758 (Cody FIX FIRST): --undo must ONLY read an --apply snapshot. Dry-runs no longer
+ // write snapshots at all, but any pre-fix dry-run snapshot on disk (mode:"dry-run") is
+ // excluded here by the `snapshot-apply-` prefix so undo can never restore a stale/post-write map.
+ const files = fs.readdirSync(SNAP_DIR)
+ .filter(f => f.startsWith('snapshot-apply-') && f.endsWith('.json')).sort();
+ if (!files.length) throw new Error('no --apply snapshot to undo from — run --apply first');
return JSON.parse(fs.readFileSync(path.join(SNAP_DIR, files.at(-1)), 'utf8'));
}
@@ -74,11 +78,8 @@ async function setPolicy(productId, variantId, policy) {
const state = await readState();
const ts = new Date().toISOString().replace(/[:.]/g, '-');
- const snapFile = path.join(SNAP_DIR, `snapshot-${ts}.json`);
- fs.writeFileSync(snapFile, JSON.stringify({ ts, mode: MODE, variants: state }, null, 2));
- console.log(`TK-11758 — ${MODE.toUpperCase()} — 6 Latigo Real Cork variants`);
- console.log(`snapshot saved: ${snapFile}\n`);
+ console.log(`TK-11758 — ${MODE.toUpperCase()} — 6 Latigo Real Cork variants\n`);
const willChange = state.filter(v => v.inventoryPolicy === 'CONTINUE');
for (const v of state) {
const id = v.id.split('/').pop();
@@ -88,12 +89,15 @@ async function setPolicy(productId, variantId, policy) {
console.log(`\n${willChange.length} of ${state.length} variants would flip to DENY (price untouched).`);
if (MODE === 'dry-run') {
- console.log('\nDRY-RUN only. No writes performed. To apply (GATED):');
+ console.log('\nDRY-RUN only. No writes performed, NO snapshot written (read-only by contract). To apply (GATED):');
console.log(' node scripts/tk-11758-cork-continue-fix/fix.mjs --apply');
return;
}
- // --apply
+ // --apply: write the restore-map snapshot FIRST (tagged apply, pre-write state), THEN mutate.
+ const snapFile = path.join(SNAP_DIR, `snapshot-apply-${ts}.json`);
+ fs.writeFileSync(snapFile, JSON.stringify({ ts, mode: MODE, variants: state }, null, 2));
+ console.log(`snapshot saved (undo reads this): ${snapFile}`);
console.log('\nAPPLYING (gated write)…');
for (const v of willChange) {
const now = await setPolicy(v.product.id, v.id, 'DENY');
← eafc12e TK-11673: exhaustive post-apply verification (read-only) — r
·
back to Designerwallcoverings
·
auto-data-snapshot: 2026-09-16T17:20:14 (1 data files) — scr 2d5a8e1 →