Context
Operator confirmed 2026-05-10: "of course we want heartbeat and bridge daemon inside our new orchestrator!" — supersedes the originally-out-of-scope framing in v13-path.md:94 (which said "bridge-daemon's specialized HTTP/osascript-driven domain stays separate"). Fold direction is in-scope.
Operator further surfaced 2026-05-10: "sunset wakeups => KILL harness, restart, start a fresh session. important for nightshift mode... I challenge it should be in scope." This ticket includes sunset-wake handling in the fold scope.
Sibling-precedent shape: #11062 (BackupCoordinatorService) + HeartbeatCoordinatorService (filed in same batch).
The Problem
Bridge-daemon currently runs as a separate persistent-process daemon (ai/scripts/bridge-daemon.mjs):
- Operator must keep terminal open OR install launchd plist (anti-pattern per #11066/#11067 retraction)
- Tail-syncs SQLite GraphLog every ~2-3s for low-latency wake delivery
- Coalesces wake events per WAKE_SUBSCRIPTION
- Delivers via osascript (Antigravity / Claude Code / Codex Desktop) or tmux
- (Subprocess) Sunset detection + recovery dispatch via
checkSunsetted.mjs + resumeHarness.mjs
Folding into orchestrator unifies persistent-process management — operator runs one daemon (orchestrator), no separate bridge process.
Architectural Reality
Bridge-daemon's work split:
| Concern |
Substrate |
| GraphLog tail-sync |
SQLite polling (getLastSyncId, getGraphLogEntries) |
| Wake-event coalescing |
Per-subscription coalescing window |
| osascript / tmux delivery |
Operating-system-specific (macOS osascript) |
| Sunset detection |
Subprocess checkSunsetted.mjs |
| Sunset recovery |
Subprocess resumeHarness.mjs (KILL harness, spawn fresh session) |
| Idle-out nudge |
Subprocess idleOutNudge.mjs |
| All-agent-idle trio-wake |
Subprocess trioWakeCooldown.mjs |
Folding shape: WakeSubstrateCoordinatorService.getDueTask() returns trigger when pending wake events exist OR sunset detected; orchestrator's cadenceEngine.runIfDue('wake', ...) invokes the work. Tail-sync polling runs at orchestrator's poll cadence (3s default).
Sunset wake scope (operator-challenged in-scope): include sunset detection + resumeHarness recovery dispatch in this fold. Important for nightshift mode (operator-offline scenario where stale agent harnesses need automatic kill+restart).
Open questions for pickup /ticket-intake:
- Does the wake-coalescing window play well with orchestrator's 3s poll cadence?
- Subprocess-to-direct-import migration (#10795) — does this ticket include or sibling-defer?
- PID-lock substrate (
bridge-daemon.pid) retires; orchestrator's PID-file substrate absorbs single-instance enforcement
Acceptance Criteria
Dependencies
- Hard: Blocked by #11062 + #11065 merge for wire-in pattern
- Coordination: plist + docs cleanup ACs ride along
- Sibling: HeartbeatCoordinatorService (M4 fold sibling; both retire
learn/agentos/wake-substrate/ substrate together)
Out of Scope
- Detailed prescription pre-staged here (would go stale per #11062/#11065 lesson)
- Cross-platform wake delivery beyond current macOS osascript + tmux scope (sibling-fileable when Linux/Windows operators arrive)
- Subprocess elimination of remaining wake-substrate scripts beyond what's needed for the fold (ride-along OR sibling-defer per pickup-time judgment)
Related
- Parent landscape: #11022 → M4
- Siblings: #11062, #11065, HeartbeatCoord (filed in same batch), DreamCoord (filed in same batch), GoldenPathCoord (filed in same batch), GraphMaintenanceCoord (filed in same batch)
- Architectural conflict to resolve:
learn/agentos/v13-path.md:94 (says bridge stays separate; this ticket reverses that direction per operator clarification 2026-05-10)
- Source:
ai/scripts/bridge-daemon.mjs, ai/scripts/bridge-daemon-queries.mjs
- Subprocess-companion work: #10795 (CLI-shape scripts → dual-mode imports)
- Closed-as-anti-pattern: #11066/#11067 (per-daemon plist packaging)
- Operator correction trail: PR #11067 closure comment + 2026-05-10 swarm broadcast
Self-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — landscape-visibility filing 2026-05-10 per operator directive. Includes operator-challenged sunset-wake scope (originally framed out-of-scope; in-scope per nightshift-mode importance).
Origin Session ID: c2912891-b459-4a03-b2af-154d5e264df1
Context
Operator confirmed 2026-05-10: "of course we want heartbeat and bridge daemon inside our new orchestrator!" — supersedes the originally-out-of-scope framing in
v13-path.md:94(which said "bridge-daemon's specialized HTTP/osascript-driven domain stays separate"). Fold direction is in-scope.Operator further surfaced 2026-05-10: "sunset wakeups => KILL harness, restart, start a fresh session. important for nightshift mode... I challenge it should be in scope." This ticket includes sunset-wake handling in the fold scope.
Sibling-precedent shape: #11062 (BackupCoordinatorService) + HeartbeatCoordinatorService (filed in same batch).
The Problem
Bridge-daemon currently runs as a separate persistent-process daemon (
ai/scripts/bridge-daemon.mjs):checkSunsetted.mjs+resumeHarness.mjsFolding into orchestrator unifies persistent-process management — operator runs one daemon (orchestrator), no separate bridge process.
Architectural Reality
Bridge-daemon's work split:
getLastSyncId,getGraphLogEntries)checkSunsetted.mjsresumeHarness.mjs(KILL harness, spawn fresh session)idleOutNudge.mjstrioWakeCooldown.mjsFolding shape: WakeSubstrateCoordinatorService.getDueTask() returns trigger when pending wake events exist OR sunset detected; orchestrator's
cadenceEngine.runIfDue('wake', ...)invokes the work. Tail-sync polling runs at orchestrator's poll cadence (3s default).Sunset wake scope (operator-challenged in-scope): include sunset detection +
resumeHarnessrecovery dispatch in this fold. Important for nightshift mode (operator-offline scenario where stale agent harnesses need automatic kill+restart).Open questions for pickup
/ticket-intake:bridge-daemon.pid) retires; orchestrator's PID-file substrate absorbs single-instance enforcementAcceptance Criteria
/ticket-intakevalidates premise + 3 open questionsai/daemons/services/WakeSubstrateCoordinatorService.mjsper #11062 sibling shapeai/scripts/bridge-daemon.mjsdeleted (entry-point obsoleted by fold)com.neomjs.bridge-daemon.plist.templateever existed, deleted (it doesn't — was never created post-#11066/#11067 closure)learn/agentos/wake-substrate/PersistentProcessManagement.mdscope-trimmed or retiredcadenceEngine.runIfDuepull-request §6.1v13-path.md:94updated — replace "out of scope: wake-event delivery" with M4-fold referenceDependencies
learn/agentos/wake-substrate/substrate together)Out of Scope
Related
learn/agentos/v13-path.md:94(says bridge stays separate; this ticket reverses that direction per operator clarification 2026-05-10)ai/scripts/bridge-daemon.mjs,ai/scripts/bridge-daemon-queries.mjsSelf-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — landscape-visibility filing 2026-05-10 per operator directive. Includes operator-challenged sunset-wake scope (originally framed out-of-scope; in-scope per nightshift-mode importance).
Origin Session ID: c2912891-b459-4a03-b2af-154d5e264df1