Context
A recent bridge-daemon restart revealed failures in wake subscription delivery via osascript. The failures were functionally opaque (logging only "osascript exited with code 1") because the bridge-daemon suppressed standard error output. This observability gap compounded the regression introduced during the manage_wake_subscription rollout.
The Problem
Because stderr was ignored in the spawnAsync utility within bridge-daemon.mjs (via stdio: 'ignore'), the actual macOS TCC (Transparency, Consent, and Control) error (error 1002, osascript is not allowed to send keystrokes) was hidden from the logs. This made the initial diagnostics blind and delayed root cause identification, forcing reliance on manual probes to discover the OS-level permission block.
The Architectural Reality
In ai/scripts/bridge-daemon.mjs, the spawnAsync wrapper executes system commands (like osascript and tmux) but discards all output streams using { stdio: 'ignore' }. While stdout isn't needed for these asynchronous fire-and-forget commands, discarding stderr destroys critical diagnostic forensics when commands fail with non-zero exit codes.
The Fix
Modify spawnAsync in ai/scripts/bridge-daemon.mjs:
- Change
stdio configuration to { stdio: ['ignore', 'ignore', 'pipe'] }.
- Capture
child.stderr.on('data') chunks.
- Append the captured and trimmed
stderr string to the Error object message when the process exits with a non-zero code.
Acceptance Criteria
Out of Scope
- Fixing the underlying macOS TCC permissions (this is an operational host-level concern).
- Addressing the MCP cache staleness or Codex whitelist gaps detailed in #10636.
Avoided Traps
- Trap: Piping
stderr to process.stderr directly instead of capturing it.
Resolution: Capturing and embedding it in the Error object ensures the existing catch blocks in deliverDigest can properly format and log the failure contextually within the daemon's log file format, rather than causing unformatted stream pollution.
Origin Session ID: d28a63c7-a4ec-40ff-aaaa-62d862e031f5
Retrieval Hint: query_raw_memories("bridge-daemon.mjs stderr stdio ignore osascript exit code 1")
Context
A recent bridge-daemon restart revealed failures in wake subscription delivery via osascript. The failures were functionally opaque (logging only "osascript exited with code 1") because the bridge-daemon suppressed standard error output. This observability gap compounded the regression introduced during the
manage_wake_subscriptionrollout.The Problem
Because
stderrwas ignored in thespawnAsyncutility withinbridge-daemon.mjs(viastdio: 'ignore'), the actual macOS TCC (Transparency, Consent, and Control) error (error 1002, osascript is not allowed to send keystrokes) was hidden from the logs. This made the initial diagnostics blind and delayed root cause identification, forcing reliance on manual probes to discover the OS-level permission block.The Architectural Reality
In
ai/scripts/bridge-daemon.mjs, thespawnAsyncwrapper executes system commands (likeosascriptandtmux) but discards all output streams using{ stdio: 'ignore' }. Whilestdoutisn't needed for these asynchronous fire-and-forget commands, discardingstderrdestroys critical diagnostic forensics when commands fail with non-zero exit codes.The Fix
Modify
spawnAsyncinai/scripts/bridge-daemon.mjs:stdioconfiguration to{ stdio: ['ignore', 'ignore', 'pipe'] }.child.stderr.on('data')chunks.stderrstring to theErrorobject message when the process exits with a non-zero code.Acceptance Criteria
spawnAsynccapturesstderroutput instead of ignoring it.spawnAsyncinclude thestderrtext (if present) alongside the exit code.Out of Scope
Avoided Traps
stderrtoprocess.stderrdirectly instead of capturing it. Resolution: Capturing and embedding it in theErrorobject ensures the existingcatchblocks indeliverDigestcan properly format and log the failure contextually within the daemon's log file format, rather than causing unformatted stream pollution.Origin Session ID: d28a63c7-a4ec-40ff-aaaa-62d862e031f5 Retrieval Hint:
query_raw_memories("bridge-daemon.mjs stderr stdio ignore osascript exit code 1")