[object Object]

← back to Dw Launchd Canary

canary: running daemon with live PID is OK despite stale LastExitStatus

813d58785c4cee6ccefe0e7e663235f8a757049d · 2026-06-17 14:28:04 -0700 · Steve Abrams

A KeepAlive daemon (ollama-henry) that is running right now isn't failing just
because launchctl shows a nonzero LastExitStatus from a prior respawn cycle.
Parse the PID and treat a live PID as OK — kills the false-positive that flagged
ollama-henry and signal-exited-but-running daemons as FAILING/KILLED.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 813d58785c4cee6ccefe0e7e663235f8a757049d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Jun 17 14:28:04 2026 -0700

    canary: running daemon with live PID is OK despite stale LastExitStatus
    
    A KeepAlive daemon (ollama-henry) that is running right now isn't failing just
    because launchctl shows a nonzero LastExitStatus from a prior respawn cycle.
    Parse the PID and treat a live PID as OK — kills the false-positive that flagged
    ollama-henry and signal-exited-but-running daemons as FAILING/KILLED.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 canary.mjs | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/canary.mjs b/canary.mjs
index b6eaedd..899a815 100644
--- a/canary.mjs
+++ b/canary.mjs
@@ -43,21 +43,24 @@ const THRESH = manifest.consecutive_fail_threshold || 2;
 const plists = fs.readdirSync(LA).filter(f => /^com\.steve\..+\.plist$/.test(f));
 
 function launchctlInfo(label) {
-  // returns { loaded, exit } — exit is the macOS-raw LastExitStatus or null
+  // returns { loaded, running, exit } — exit is the macOS-raw LastExitStatus or null.
+  // running = a live PID is present; a KeepAlive daemon that's running now is NOT
+  // failing even if LastExitStatus is a stale nonzero from a prior respawn cycle.
   let line = '';
   try { line = execSync(`launchctl list ${label} 2>/dev/null`, { encoding: 'utf8' }); } catch { line = ''; }
   if (!line.trim()) {
     // fall back to the column form (some labels only show in the table)
     try {
       const tbl = execSync(`launchctl list 2>/dev/null | grep -F ${label}`, { encoding: 'utf8' }).trim();
-      if (!tbl) return { loaded: false, exit: null };
+      if (!tbl) return { loaded: false, running: false, exit: null };
       const cols = tbl.split(/\s+/); // PID  STATUS  LABEL
       const ex = cols[1] === '-' ? null : parseInt(cols[1], 10);
-      return { loaded: true, exit: Number.isNaN(ex) ? null : ex };
-    } catch { return { loaded: false, exit: null }; }
+      return { loaded: true, running: cols[0] !== '-' && /^\d+$/.test(cols[0]), exit: Number.isNaN(ex) ? null : ex };
+    } catch { return { loaded: false, running: false, exit: null }; }
   }
   const m = line.match(/"LastExitStatus"\s*=\s*(\d+)/);
-  return { loaded: true, exit: m ? parseInt(m[1], 10) : null };
+  const p = line.match(/"PID"\s*=\s*(\d+)/);
+  return { loaded: true, running: !!p, exit: m ? parseInt(m[1], 10) : null };
 }
 
 const results = [];
@@ -67,12 +70,13 @@ for (const f of plists) {
   // is it Disabled=true in the plist itself? (deliberate pause, keeps the .plist name)
   let disabled = false;
   try { disabled = /<key>Disabled<\/key>\s*<true\/>/.test(fs.readFileSync(path.join(LA, f), 'utf8')); } catch {}
-  const { loaded, exit } = launchctlInfo(label);
+  const { loaded, running, exit } = launchctlInfo(label);
 
   let verdict = 'OK', reason = 'loaded, exit 0';
   if (disabled) { verdict = 'PAUSED'; reason = 'Disabled=true in plist (deliberate)'; }
   else if (expectedUnloaded.has(short)) { verdict = 'EXPECTED_OFF'; reason = 'intentionally unloaded (manifest expected_unloaded)'; }
   else if (!loaded) { verdict = 'DROPPED'; reason = 'plist on disk but NOT in launchctl — silently unloaded (drift/reboot/failed bootstrap)'; }
+  else if (running) { verdict = 'OK'; reason = 'running now (live PID) — a stale LastExitStatus is prior-cycle residue, not a failure'; }
   else if (exit === null) { verdict = 'OK'; reason = 'loaded, no exit status yet (not run since load)'; }
   else if (exit === 0) { verdict = 'OK'; reason = 'loaded, exit 0'; }
   else if (exit % 256 !== 0) {

← 0a4edf7 Add gated-plist-install batcher (Officer Council #5)  ·  back to Dw Launchd Canary  ·  chore: macstudio3 migration — reconcile from mac2 + repoint fac0591 →