← back to Wallco Ai
drunk-animals: daemon preflight self-heals id_seq desync
5312be83396fc6b1b24f0d46cdadba4d6787e536 · 2026-05-13 07:31:19 -0700 · SteveStudio2
Before every tick, daemon queries spoon_all_designs_id_seq.last_value
+ max(id). If sequence is behind, setval's it to max+1. Prevents
recurrence of the silent INSERT...RETURNING failure that lost 6
designs (orphan PNGs salvaged manually 05:55 PT).
Smoke-tested: deliberately set seq=100, preflight detected 100 <
2526 and healed to 2527. Sequence intact.
Files touched
M scripts/drunk_animals_daemon.js
Diff
commit 5312be83396fc6b1b24f0d46cdadba4d6787e536
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 07:31:19 2026 -0700
drunk-animals: daemon preflight self-heals id_seq desync
Before every tick, daemon queries spoon_all_designs_id_seq.last_value
+ max(id). If sequence is behind, setval's it to max+1. Prevents
recurrence of the silent INSERT...RETURNING failure that lost 6
designs (orphan PNGs salvaged manually 05:55 PT).
Smoke-tested: deliberately set seq=100, preflight detected 100 <
2526 and healed to 2527. Sequence intact.
---
scripts/drunk_animals_daemon.js | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/scripts/drunk_animals_daemon.js b/scripts/drunk_animals_daemon.js
index 0044838..d1a47d2 100644
--- a/scripts/drunk_animals_daemon.js
+++ b/scripts/drunk_animals_daemon.js
@@ -11,7 +11,7 @@
* up (the tick script also has its own outside-window guard, redundant).
*/
-const { spawn } = require('child_process');
+const { spawn, execSync } = require('child_process');
const path = require('path');
const TICK_MS = parseInt(process.env.TICK_MS || '240000', 10); // 4 min
@@ -19,6 +19,29 @@ const STOP_HOUR = parseInt(process.env.STOP_HOUR || '6', 10);
const ROOT = path.join(__dirname, '..');
const TICK_SCRIPT = path.join(__dirname, 'drunk_animals_tick.js');
+// Preflight: spoon_all_designs_id_seq.last_value MUST be ≥ max(id), else
+// every INSERT ... RETURNING id fails with a duplicate-key error and the
+// generator silently drops designs (the 2026-05-13 05:25-05:50 PT incident
+// where 6 generations went orphan). Self-heal by setval'ing past max(id).
+function preflight() {
+ try {
+ const raw = execSync(
+ `psql dw_unified -At -F'|' -c "SELECT last_value, (SELECT max(id) FROM spoon_all_designs) FROM spoon_all_designs_id_seq;"`,
+ { encoding: 'utf8' }
+ ).trim();
+ const [seqStr, maxStr] = raw.split('|');
+ const seq = parseInt(seqStr, 10);
+ const max = parseInt(maxStr, 10);
+ if (!isFinite(seq) || !isFinite(max)) return;
+ if (seq < max) {
+ console.log(`[${new Date().toISOString()}] PREFLIGHT FIX: id_seq.last_value=${seq} < max(id)=${max} — self-healing`);
+ execSync(`psql dw_unified -At -c "SELECT setval('spoon_all_designs_id_seq', ${max + 1}, false);"`);
+ }
+ } catch (e) {
+ console.error(`[${new Date().toISOString()}] preflight err: ${e.message}`);
+ }
+}
+
function nowPT() {
return new Date(new Date().toLocaleString('en-US', { timeZone: 'America/Los_Angeles' }));
}
@@ -43,6 +66,7 @@ function fire() {
return;
}
running = true;
+ preflight();
const t0 = Date.now();
const child = spawn('node', [TICK_SCRIPT], { stdio: 'inherit', cwd: ROOT });
child.on('exit', code => {
← f12547c /admin/health: surface random-ETag hit/miss/rate alongside b
·
back to Wallco Ai
·
drunk-animals: daemon 5-min hard timeout on hung ticks 6fb2136 →