← back to Designerwallcoverings
TK-11644: write-ahead the rollback row before the gated delete
71fc81e518df302fa73623826997c1567da13d75 · 2026-09-16 14:15:58 -0700 · Steve Abrams
The ledger append sat inside the same try as the Shopify delete, so a delete that
SUCCEEDED followed by a failing append would lose the undo record for a completed
live customer-facing write (unrecoverable) and double-count the row as an error
after ok++ had already run. Now the undo row is written BEFORE the delete, in its
own try: a ledger failure aborts that row's delete entirely (fail-safe), and a
write-ahead row for a delete that then fails is harmless because its undo re-sets
the value to what it already is. Also guards the per-row gql() __err shape.
Dry-run re-verified identical: 5 DELETE / 6 LEAVE / 0 skipped, no write fired.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NbiFp4yxwRthCmDhbkwQnu
Files touched
M assets/TK-11644-identity-manifest.jsonM scripts/tk11644-identity-fix.mjs
Diff
commit 71fc81e518df302fa73623826997c1567da13d75
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 16 14:15:58 2026 -0700
TK-11644: write-ahead the rollback row before the gated delete
The ledger append sat inside the same try as the Shopify delete, so a delete that
SUCCEEDED followed by a failing append would lose the undo record for a completed
live customer-facing write (unrecoverable) and double-count the row as an error
after ok++ had already run. Now the undo row is written BEFORE the delete, in its
own try: a ledger failure aborts that row's delete entirely (fail-safe), and a
write-ahead row for a delete that then fails is harmless because its undo re-sets
the value to what it already is. Also guards the per-row gql() __err shape.
Dry-run re-verified identical: 5 DELETE / 6 LEAVE / 0 skipped, no write fired.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NbiFp4yxwRthCmDhbkwQnu
---
assets/TK-11644-identity-manifest.json | 2 +-
scripts/tk11644-identity-fix.mjs | 16 ++++++++++++----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/assets/TK-11644-identity-manifest.json b/assets/TK-11644-identity-manifest.json
index 7fd2e56..d4dcd21 100644
--- a/assets/TK-11644-identity-manifest.json
+++ b/assets/TK-11644-identity-manifest.json
@@ -1,5 +1,5 @@
{
- "generated_at": "2026-09-16T21:09:12.145Z",
+ "generated_at": "2026-09-16T21:15:31.866Z",
"will_delete": 5,
"skipped": [],
"leave": [
diff --git a/scripts/tk11644-identity-fix.mjs b/scripts/tk11644-identity-fix.mjs
index d756fa8..41c8323 100644
--- a/scripts/tk11644-identity-fix.mjs
+++ b/scripts/tk11644-identity-fix.mjs
@@ -74,15 +74,23 @@ const ledger=process.env.HOME+'/.claude/yolo-queue/executed-reversible/ledger.js
let ok=0,err=0;
for(const v of verified){
const q=`mutation { metafieldsDelete(metafields:[{ownerId:${JSON.stringify(v.gid)},namespace:"global",key:"description_tag"}]) { deletedMetafields { key } userErrors { field message } } }`;
+ // WRITE-AHEAD the undo record BEFORE firing the delete. If the ledger append were done
+ // after a successful delete (inside the same try), a failed append would lose the rollback
+ // row for a delete that ALREADY happened — unrecoverable — and would also double-count the
+ // row as an error after ok++ had run. A write-ahead row for a delete that then fails is
+ // harmless by comparison: its undo re-sets the value to what it already is, a no-op.
try{
- const r=await gql(q);
- const ue=r.metafieldsDelete.userErrors;
- if(ue && ue.length){ err++; console.error('userErrors',v.handle,JSON.stringify(ue)); continue; }
- ok++;
fs.appendFileSync(ledger,JSON.stringify({ts:new Date().toISOString(),agent:'claude-run-11644',ticket:'TK-11644',
action:'delete global.description_tag (identity-contradiction residual)',pid:v.pid,handle:v.handle,blast_radius:1,
undo_cmd:`re-set global.description_tag=${JSON.stringify(v.old_value)} on product ${v.pid}`,
verify:`storefront meta description now falls back to body_html`})+'\n');
+ }catch(e){ err++; console.error('LEDGER-FAIL (delete NOT attempted)',v.handle,e.message); continue; }
+ try{
+ const r=await gql(q);
+ if(r && r.__err){ err++; console.error('GraphQL error',v.handle,JSON.stringify(r.__err)); continue; }
+ const ue=r.metafieldsDelete.userErrors;
+ if(ue && ue.length){ err++; console.error('userErrors',v.handle,JSON.stringify(ue)); continue; }
+ ok++;
}catch(e){ err++; console.error('ERR',v.handle,e.message); }
}
console.log(`\nAPPLIED: deleted=${ok} err=${err}`);
← d8ce050 TK-11644: add missing gql() error-object guard to postfix-ve
·
back to Designerwallcoverings
·
TK-11357: stop the action-C tripwire fabricating success rec ef068c8 →