feat(FN-1661): merge fusion/fn-1661 (auto-resolved)

- feat(FN-1661): complete Step 4 — document task-worker health fix
- feat(FN-1661): complete Step 3 — verify task-worker agent health fix
This commit is contained in:
gsxdsm
2026-04-13 08:54:19 -07:00
parent c5e8fc7633
commit d4f42787d1
8 changed files with 247 additions and 26 deletions

View File

@@ -23,6 +23,7 @@
- `HeartbeatMonitor.executeHeartbeat()` uses the Paperclip wake→check→work→exit model. The lazy `import("./pi.js")` pattern keeps pi SDK out of the module graph when only monitoring (not execution) is needed.
- Agent tool factories (`createTaskCreateTool`, `createTaskLogTool`) live in `agent-tools.ts` and are shared between `TaskExecutor` and `HeartbeatMonitor` to avoid duplication.
- **Heartbeat Control-Plane Lane (FN-1487)**: Heartbeat runs from the Agents panel run on a separate control-plane lane that is independent of task execution concurrency limits. `HeartbeatMonitor` and `HeartbeatTriggerScheduler` are created WITHOUT the task-lane semaphore in both `runDashboard()` and `runServe()`. The semaphore boundary is documented in comments with "UTILITY PATH: This component does NOT receive the task-lane semaphore." This ensures agent responsiveness is preserved even when task pipelines are saturated.
- **Task-worker agent contract (FN-1661)**: Runtime-created executor task workers (for example `executor-FN-1234`) must be explicitly marked with `metadata.agentKind = "task-worker"` and `runtimeConfig.enabled = false`, then transition `idle -> active -> running` after assignment wiring completes. `HeartbeatTriggerScheduler.watchAssignments()` must skip assignment wakeups when `runtimeConfig.enabled === false`; otherwise task workers inherit user-agent heartbeat semantics and show false "Unresponsive" health in the dashboard.
- Dashboard SSE clients (planning/subtask/mission interview) now use a shared keep-alive pattern: start a 25s `setInterval` in stream `onOpen` that `POST`s `/api/ai-sessions/:id/ping`, and always stop it on stream `close`, `complete`, and fatal errors.
- **Subtask Session ProjectId Propagation (FN-1479)**: Subtask breakdown sessions must persist `projectId` throughout their lifecycle to enable project-scoped resume. Key patterns:
- `POST /api/subtasks/start-streaming` forwards `projectId` from the route handler to `createSubtaskSession()`