[object Object]

← back to Slack To Steve

ingest: re-entrancy guard on tick() — prevents overlapping armed claude -p runs double-executing the same message

641bc939b453880fdbdb81f54c3963cd1c13b21a · 2026-07-13 09:52:39 -0700 · Steve Abrams

Files touched

Diff

commit 641bc939b453880fdbdb81f54c3963cd1c13b21a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jul 13 09:52:39 2026 -0700

    ingest: re-entrancy guard on tick() — prevents overlapping armed claude -p runs double-executing the same message
---
 ingest.mjs | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/ingest.mjs b/ingest.mjs
index 3daf8ee..f00fa16 100644
--- a/ingest.mjs
+++ b/ingest.mjs
@@ -80,11 +80,18 @@ async function processChannel(cid) {
   return acted;
 }
 
+let TICKING = false; // re-entrancy guard: an armed `claude -p` run can outlast the 90s
+                     // interval; without this the next tick re-reads the same message
+                     // (cursor not yet advanced) and double-executes it.
 async function tick() {
-  fs.mkdirSync(path.join(DIR, 'data'), { recursive: true });
-  let total = 0;
-  for (const cid of CHANNELS) total += await processChannel(cid);
-  log(`processed ${total} new message(s) from Steve · armed=${AUTO_EXECUTE} · channels=${CHANNELS.length}`);
+  if (TICKING) { log('tick skipped — previous still running (armed exec in flight)'); return; }
+  TICKING = true;
+  try {
+    fs.mkdirSync(path.join(DIR, 'data'), { recursive: true });
+    let total = 0;
+    for (const cid of CHANNELS) total += await processChannel(cid);
+    log(`processed ${total} new message(s) from Steve · armed=${AUTO_EXECUTE} · channels=${CHANNELS.length}`);
+  } finally { TICKING = false; }
 }
 
 (async () => {

← b51b813 dashboard: pipe status + inbox + transcripts viewer on :9897  ·  back to Slack To Steve  ·  ingest: adaptive polling — 3s while a convo is active, 12s i 8c5a8be →