titan-agent 6.2.2 → 6.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/agent/goalDriver.js +154 -4
  2. package/dist/agent/goalDriver.js.map +1 -1
  3. package/dist/agent/orchestrator.js +9 -10
  4. package/dist/agent/orchestrator.js.map +1 -1
  5. package/dist/agent/planner.js +42 -10
  6. package/dist/agent/planner.js.map +1 -1
  7. package/dist/agent/systemPromptParts.js +13 -16
  8. package/dist/agent/systemPromptParts.js.map +1 -1
  9. package/dist/utils/constants.js +1 -1
  10. package/dist/utils/constants.js.map +1 -1
  11. package/package.json +1 -1
  12. package/ui/dist/assets/{AuditPanel-BmFAKA7p.js → AuditPanel-TdDAyJUQ.js} +1 -1
  13. package/ui/dist/assets/{AutonomyPanel-BzuCEsiG.js → AutonomyPanel-B6EIpuFt.js} +1 -1
  14. package/ui/dist/assets/{AutopilotPanel-DA1vFEl4.js → AutopilotPanel-CLe14-eq.js} +1 -1
  15. package/ui/dist/assets/{AutoresearchPanel-BeUCXYtX.js → AutoresearchPanel-C14q_kh7.js} +1 -1
  16. package/ui/dist/assets/{BackupPanel-B6N1pfMT.js → BackupPanel-CoEbryip.js} +1 -1
  17. package/ui/dist/assets/{BrowserPanel-BGHaPi3O.js → BrowserPanel-CRTJOXQV.js} +1 -1
  18. package/ui/dist/assets/{CPActivity-BUSwjFj2.js → CPActivity-DjT8p5Dn.js} +1 -1
  19. package/ui/dist/assets/{CPAgentDetail-DlUEVujH.js → CPAgentDetail-CR1ciISN.js} +1 -1
  20. package/ui/dist/assets/{CPAgents-CnRmsSMo.js → CPAgents-DIYCdpQR.js} +1 -1
  21. package/ui/dist/assets/{CPApprovals-CXdkzebd.js → CPApprovals-DAKmaSkN.js} +1 -1
  22. package/ui/dist/assets/{CPCosts-CfcyIUZg.js → CPCosts-CCCh_VY0.js} +1 -1
  23. package/ui/dist/assets/{CPDashboard-DHlfE1mT.js → CPDashboard-CyKZGlHB.js} +1 -1
  24. package/ui/dist/assets/{CPFiles-DyV9vsjE.js → CPFiles-CI252ucO.js} +1 -1
  25. package/ui/dist/assets/{CPGoals-C17G2F0e.js → CPGoals-BtcgDUY5.js} +1 -1
  26. package/ui/dist/assets/{CPInbox-D5A3ja_Q.js → CPInbox-igQoKOuB.js} +1 -1
  27. package/ui/dist/assets/{CPIssueDetail-CoPv27Ll.js → CPIssueDetail-DD5iL5mT.js} +1 -1
  28. package/ui/dist/assets/{CPIssues-C9EdfW1J.js → CPIssues-C1XUjgdv.js} +1 -1
  29. package/ui/dist/assets/CPLayout-VXhuxAHd.js +2 -0
  30. package/ui/dist/assets/{CPOrg-DzoVDLKI.js → CPOrg-JyXp44DB.js} +1 -1
  31. package/ui/dist/assets/{CPRuns-BHAyFv0K.js → CPRuns-C-gZX28e.js} +1 -1
  32. package/ui/dist/assets/{CPSocial-CjHD8dKM.js → CPSocial-sMl4vqmX.js} +1 -1
  33. package/ui/dist/assets/{CPVoice-aybMotU5.js → CPVoice-BXTY3vl7.js} +1 -1
  34. package/ui/dist/assets/{ChannelsPanel-8KfvAEYM.js → ChannelsPanel-rF_yHmYD.js} +1 -1
  35. package/ui/dist/assets/{CheckpointsPanel-BCyLRLcg.js → CheckpointsPanel-DO0QSjuz.js} +1 -1
  36. package/ui/dist/assets/{CommandPostHub-Ce-mWsu2.js → CommandPostHub-BLnNTvBO.js} +3 -3
  37. package/ui/dist/assets/{CronPanel-A9JHvU_O.js → CronPanel-DELTcCV-.js} +1 -1
  38. package/ui/dist/assets/{DataTable-ol6IZMRj.js → DataTable-BmbYppBc.js} +1 -1
  39. package/ui/dist/assets/{DreamPanel-ZiOF8ybh.js → DreamPanel-B28qIraZ.js} +1 -1
  40. package/ui/dist/assets/{EmptyState-B1i1ZK0x.js → EmptyState-CxJGUl_w.js} +1 -1
  41. package/ui/dist/assets/{EvalHarnessPanel-DRGc1zbp.js → EvalHarnessPanel-DvI-dsqQ.js} +1 -1
  42. package/ui/dist/assets/{EvalPanel-B_fiFImG.js → EvalPanel-DKdn69V8.js} +1 -1
  43. package/ui/dist/assets/{FileViewer-D14G6MQq.js → FileViewer-Deg5Z7ng.js} +1 -1
  44. package/ui/dist/assets/{FilesPanel-BIsMoSfg.js → FilesPanel-DDRjQukY.js} +1 -1
  45. package/ui/dist/assets/{FleetPanel-CSjOOsbX.js → FleetPanel-eEudyOkP.js} +1 -1
  46. package/ui/dist/assets/{HomelabPanel-XHMxqiHu.js → HomelabPanel-Dov1f68P.js} +1 -1
  47. package/ui/dist/assets/InfraView-DgasEqoR.js +2 -0
  48. package/ui/dist/assets/{InlineEditableField-AOS-LBh_.js → InlineEditableField-4ZA-KEfv.js} +1 -1
  49. package/ui/dist/assets/{Input-CTK9oH9g.js → Input-C7lzcGqx.js} +1 -1
  50. package/ui/dist/assets/{IntegrationsPanel-BKuC_5El.js → IntegrationsPanel-BmnWsnvF.js} +1 -1
  51. package/ui/dist/assets/IntelligenceView-DXYSyS1a.js +2 -0
  52. package/ui/dist/assets/{LearningPanel-RpDaPvCj.js → LearningPanel-BsKhgbeS.js} +1 -1
  53. package/ui/dist/assets/{LogsPanel-9zIJP1Xv.js → LogsPanel-C-H_axtp.js} +1 -1
  54. package/ui/dist/assets/{McpPanel-CNE7MhDu.js → McpPanel-BizAlt2h.js} +1 -1
  55. package/ui/dist/assets/{MemoryGraphPanel-9DEsbOZF.js → MemoryGraphPanel-Qle7Bodz.js} +1 -1
  56. package/ui/dist/assets/{MemoryWikiPanel-CqNen9A6.js → MemoryWikiPanel-CKY4HY4k.js} +1 -1
  57. package/ui/dist/assets/{MeshPanel-Bq3pHHIT.js → MeshPanel-D35hLDX4.js} +1 -1
  58. package/ui/dist/assets/MissionCanvas-BU6dvWdk.js +72 -0
  59. package/ui/dist/assets/{MissionChat-BDqlCplQ.js → MissionChat-BCxqk708.js} +1 -1
  60. package/ui/dist/assets/{MissionLibrary-9SMdJnfa.js → MissionLibrary-DtovbHf7.js} +1 -1
  61. package/ui/dist/assets/{MissionStart-Cm7C3kyo.js → MissionStart-DQCW6cLo.js} +1 -1
  62. package/ui/dist/assets/{Modal-B9KCAwCK.js → Modal-CpcFi-Gm.js} +1 -1
  63. package/ui/dist/assets/{NvidiaPanel-CpGBj1sn.js → NvidiaPanel-Dwvf8UD2.js} +1 -1
  64. package/ui/dist/assets/{OrganismPanel-DBHyylxC.js → OrganismPanel-mhCf2syl.js} +1 -1
  65. package/ui/dist/assets/{OverviewPanel-DII4H_R7.js → OverviewPanel-DiOrl6LB.js} +1 -1
  66. package/ui/dist/assets/{PageHeader-Bzb_WXw0.js → PageHeader-CPfyiZIM.js} +1 -1
  67. package/ui/dist/assets/{PersonaProfilesPanel-CXZTZhjo.js → PersonaProfilesPanel-BvQlozzS.js} +1 -1
  68. package/ui/dist/assets/{PersonasPanel-BYbD8XiV.js → PersonasPanel-G5Jz55AB.js} +1 -1
  69. package/ui/dist/assets/{PhoneDeskPanel-Bol7fCCN.js → PhoneDeskPanel-Cx4wlgRT.js} +1 -1
  70. package/ui/dist/assets/{RecipesPanel-BRbXRcEn.js → RecipesPanel-DB6Kuo1a.js} +1 -1
  71. package/ui/dist/assets/{SecurityPanel-BR3BT7Rb.js → SecurityPanel-BcnpsElV.js} +1 -1
  72. package/ui/dist/assets/{SelfImprovePanel-BX9xYBxl.js → SelfImprovePanel-do5xDzc8.js} +1 -1
  73. package/ui/dist/assets/{SelfProposalsPanel-BOoDEAYp.js → SelfProposalsPanel-DM4B-HLa.js} +1 -1
  74. package/ui/dist/assets/{SessionsPanel-BICnNmn0.js → SessionsPanel-Bl8h6Bfu.js} +1 -1
  75. package/ui/dist/assets/{SessionsTab-X10FeDWA.js → SessionsTab-hihe8Dc7.js} +1 -1
  76. package/ui/dist/assets/{SettingsPanel-MuC32AXw.js → SettingsPanel-Cp8decIS.js} +1 -1
  77. package/ui/dist/assets/SettingsView-BZIgBz0P.js +2 -0
  78. package/ui/dist/assets/{SkeletonLoader-fwI4Z-f0.js → SkeletonLoader-DLzSaIMH.js} +1 -1
  79. package/ui/dist/assets/{SkillsPanel-CKFndekU.js → SkillsPanel-B0VL9cO1.js} +1 -1
  80. package/ui/dist/assets/{SomaView-Ch7WlmBy.js → SomaView-BejcfdMM.js} +1 -1
  81. package/ui/dist/assets/{StatCard-Bj2Q_4WS.js → StatCard-Bt-57DK2.js} +1 -1
  82. package/ui/dist/assets/{StatusBadge-NtdTQ8_L.js → StatusBadge-BE0SQNPu.js} +1 -1
  83. package/ui/dist/assets/{Tabs-CC9aTVuL.js → Tabs-dEteLxhl.js} +1 -1
  84. package/ui/dist/assets/{TeamsPanel-DjFcLsdR.js → TeamsPanel-7UwGxnbj.js} +1 -1
  85. package/ui/dist/assets/{TelemetryPanel-k7gJbZyS.js → TelemetryPanel-CqbkTW3V.js} +1 -1
  86. package/ui/dist/assets/{TitanCanvas-MzLkpZhp.js → TitanCanvas-RVuBEoV1.js} +4 -4
  87. package/ui/dist/assets/{ToolsView-DcxwuM2l.js → ToolsView-C97QnPeY.js} +2 -2
  88. package/ui/dist/assets/{Tooltip-CFYHfpgQ.js → Tooltip-BGe4ZrLD.js} +1 -1
  89. package/ui/dist/assets/{TraceViewer-BfLO9vwI.js → TraceViewer-CSj_fZou.js} +1 -1
  90. package/ui/dist/assets/{TrainingPanel-DUl6qChY.js → TrainingPanel-43gDnkVS.js} +1 -1
  91. package/ui/dist/assets/{VoiceOverlay-Dj_cR5_Y.js → VoiceOverlay-CvZcewVV.js} +1 -1
  92. package/ui/dist/assets/{VramPanel-th0_Eo8o.js → VramPanel-nadiVKRZ.js} +1 -1
  93. package/ui/dist/assets/{WatchView-DyGhpKbv.js → WatchView-CUGArdWk.js} +1 -1
  94. package/ui/dist/assets/{WorkTab-BG5VBljJ.js → WorkTab-iCDNyX60.js} +1 -1
  95. package/ui/dist/assets/{WorkflowsPanel-C1hVHqAc.js → WorkflowsPanel-Do5EOPQ-.js} +1 -1
  96. package/ui/dist/assets/{archive-C2_hAJXj.js → archive-96Jj-QYz.js} +1 -1
  97. package/ui/dist/assets/{arrow-left-DFCBXvKS.js → arrow-left-DvmiAV7y.js} +1 -1
  98. package/ui/dist/assets/{book-open-BgDKDGcH.js → book-open-DvAaokKW.js} +1 -1
  99. package/ui/dist/assets/{bot-C4ICYImG.js → bot-DFsTWhzD.js} +1 -1
  100. package/ui/dist/assets/{chart-column-BIFJOG_f.js → chart-column-BWW8khga.js} +1 -1
  101. package/ui/dist/assets/{check-CmCL8yzl.js → check-4bqUIREX.js} +1 -1
  102. package/ui/dist/assets/{chevron-right-U0Ujye5i.js → chevron-right-DhAaVOkv.js} +1 -1
  103. package/ui/dist/assets/{chevron-up-B6uSBxbj.js → chevron-up-DhONR6eV.js} +1 -1
  104. package/ui/dist/assets/{circle-check-big-BFw1nom4.js → circle-check-big-CrrpTfnZ.js} +1 -1
  105. package/ui/dist/assets/{circle-stop-DbtGpdaw.js → circle-stop-BOU58Urf.js} +1 -1
  106. package/ui/dist/assets/{clipboard-list-Dd3_U8cK.js → clipboard-list-GcIgVrYh.js} +1 -1
  107. package/ui/dist/assets/{clock-DpJIc30t.js → clock-D5MlrzQb.js} +1 -1
  108. package/ui/dist/assets/{dollar-sign-DlrOHVzA.js → dollar-sign-B9t2KmrG.js} +1 -1
  109. package/ui/dist/assets/{download-CZ5kTONh.js → download-DzgUP-io.js} +1 -1
  110. package/ui/dist/assets/{external-link-CX-GvMky.js → external-link--90_rW_r.js} +1 -1
  111. package/ui/dist/assets/{file-text-BtTsNJbB.js → file-text-C-9as3zm.js} +1 -1
  112. package/ui/dist/assets/{flask-conical-BaPYppKH.js → flask-conical-BJnD20AK.js} +1 -1
  113. package/ui/dist/assets/{folder-BOnpha2-.js → folder-BXotS0h-.js} +1 -1
  114. package/ui/dist/assets/{funnel-DaNi6kwp.js → funnel-BkW9zcis.js} +1 -1
  115. package/ui/dist/assets/{git-branch-gs6g9dSe.js → git-branch-D7pbvkyu.js} +1 -1
  116. package/ui/dist/assets/{index-Dbv5oKsp.js → index-DczEfArU.js} +2 -2
  117. package/ui/dist/assets/index-DmgXt1oB.css +1 -0
  118. package/ui/dist/assets/{layers-BKZz8iD1.js → layers-BgUh-m00.js} +1 -1
  119. package/ui/dist/assets/{legacy-DbwFsW2A.js → legacy-Wbf7An22.js} +1 -1
  120. package/ui/dist/assets/{lightbulb-DX6YLtPe.js → lightbulb-4Yox7P7Z.js} +1 -1
  121. package/ui/dist/assets/{list-todo-qdMNm4-Q.js → list-todo-JeleiL5r.js} +1 -1
  122. package/ui/dist/assets/{message-square-Cwo5FOho.js → message-square-C9bK5TAD.js} +1 -1
  123. package/ui/dist/assets/{mic-BzvwK4IS.js → mic-DwEnBcFd.js} +1 -1
  124. package/ui/dist/assets/{missions-CYlXuJED.js → missions-Jbe_PHaT.js} +1 -1
  125. package/ui/dist/assets/{network-Dt-RBtO_.js → network-BjQmrmO8.js} +1 -1
  126. package/ui/dist/assets/{pause-Do3XNLtx.js → pause-9vYiD-5Y.js} +1 -1
  127. package/ui/dist/assets/{pencil-DAGs9RFs.js → pencil-CygyIvE1.js} +1 -1
  128. package/ui/dist/assets/{play-CNElkzEq.js → play-7ImYx-M6.js} +1 -1
  129. package/ui/dist/assets/{plug-DCgrVnB8.js → plug-DXmJpsfC.js} +1 -1
  130. package/ui/dist/assets/{plus-BnsXhqXc.js → plus-LIrhsu2s.js} +1 -1
  131. package/ui/dist/assets/{proxy-BXHdgwrk.js → proxy-B72L9I2p.js} +1 -1
  132. package/ui/dist/assets/{radio-BPz7sHXW.js → radio-DN9FsrLZ.js} +1 -1
  133. package/ui/dist/assets/{refresh-cw-Cs4oDMNE.js → refresh-cw-DyPWslHB.js} +1 -1
  134. package/ui/dist/assets/{rotate-ccw-DSpsA3Wr.js → rotate-ccw-C7z7lzst.js} +1 -1
  135. package/ui/dist/assets/{save-BhGg2pZh.js → save-Bl0vY0Ur.js} +1 -1
  136. package/ui/dist/assets/{search-BtxlIgqN.js → search-DLl1kVch.js} +1 -1
  137. package/ui/dist/assets/{send-BzKTXI3q.js → send-BqZ0Qzz-.js} +1 -1
  138. package/ui/dist/assets/{server-B1gIgixS.js → server-DvPKxeOK.js} +1 -1
  139. package/ui/dist/assets/{shield-check-C39B-Wi3.js → shield-check-DMM8OpD5.js} +1 -1
  140. package/ui/dist/assets/{terminal-CubaeYlJ.js → terminal-DD6OAIa2.js} +1 -1
  141. package/ui/dist/assets/{test-tube-CYYLfFIz.js → test-tube-BoC1tTKm.js} +1 -1
  142. package/ui/dist/assets/{toggle-right-BQ3iDgLG.js → toggle-right-CrEdx-9K.js} +1 -1
  143. package/ui/dist/assets/{trash-2-CSxfLiVB.js → trash-2-Co50XYSn.js} +1 -1
  144. package/ui/dist/assets/{trending-up-DXxKT18Q.js → trending-up-SFD19agk.js} +1 -1
  145. package/ui/dist/assets/{trophy-osEOm2Vi.js → trophy-DLTd-oCR.js} +1 -1
  146. package/ui/dist/assets/{volume-2-C1OkTurz.js → volume-2-vQvjPYVu.js} +1 -1
  147. package/ui/dist/assets/{wifi-off-DAhvsjnD.js → wifi-off-DVwDeeLz.js} +1 -1
  148. package/ui/dist/index.html +2 -2
  149. package/ui/dist/sw.js +1 -1
  150. package/ui/dist/assets/CPLayout-CHrlktMs.js +0 -2
  151. package/ui/dist/assets/InfraView-DNYgRXkB.js +0 -2
  152. package/ui/dist/assets/IntelligenceView-BUKpVpDQ.js +0 -2
  153. package/ui/dist/assets/MissionCanvas-Ci0hbAF0.js +0 -69
  154. package/ui/dist/assets/SettingsView-Cv9IZqiU.js +0 -2
  155. package/ui/dist/assets/index-OZm1iJy9.css +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agent/goalDriver.ts"],"sourcesContent":["/**\n * TITAN — Goal Driver (v4.10.0-local, Phase A)\n *\n * Owns a goal from \"active\" to terminal (done | failed | cancelled).\n * Replaces the passive \"initiative picks one subtask per 5-min tick\"\n * model with an active phase state machine that drives subtasks through\n * specialists, verifies each one, retries on failure via fallbackChain,\n * and reports outcomes back to SOMA.\n *\n * Design principles:\n * - State is persisted to ~/.titan/driver-state/<goalId>.json after\n * every phase transition. Restart-safe.\n * - One tick = one phase transition. Scheduler loops ticks until the\n * driver reaches a terminal phase OR requires waiting (observing a\n * spawned specialist, or blocked on human).\n * - Every phase's state transition is logged to driver state history\n * for UI replay + debugging.\n * - Kill-switch / scope-lock / staging are handled by toolRunner —\n * the driver inherits that protection automatically.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, rmSync, renameSync } from 'fs';\nimport { join, dirname } from 'path';\nimport logger from '../utils/logger.js';\nimport { TITAN_HOME } from '../utils/constants.js';\nimport type {\n DriverPhase, DriverState, DriverSubtaskState, DriverHistoryEvent,\n} from './goalDriverTypes.js';\nimport type { SubtaskKind } from './subtaskTaxonomy.js';\nimport { classifyAll } from './subtaskTaxonomy.js';\nimport { routeForKind, pickAttempt } from './specialistRouter.js';\nimport { nextFallback } from './fallbackChain.js';\nimport { DEFAULT_BUDGET_CAPS, checkBudget, suggestDegradation, recordSpend } from './budgetEnforcer.js';\nimport { structuredSpawn } from './structuredSpawn.js';\nimport { verifyByKind } from './verifier.js';\nimport { isGenericQuestion, forceCommitDirective } from './questionQuality.js';\nimport { verificationEventsSince } from './verification.js';\nimport { onGoalCompleted, onGoalFailed, onGoalBlocked } from './somaFeedback.js';\nimport type { Goal, Subtask } from './goals.js';\nimport { emitAgentEvent } from './agentEvents.js';\n\nconst COMPONENT = 'GoalDriver';\nconst STATE_DIR = join(TITAN_HOME, 'driver-state');\n\n// ── Storage ──────────────────────────────────────────────────────\n\nfunction ensureStateDir(): void {\n try { mkdirSync(STATE_DIR, { recursive: true }); } catch { /* ok */ }\n}\n\nfunction statePath(goalId: string): string {\n return join(STATE_DIR, `${goalId}.json`);\n}\n\nfunction loadState(goalId: string): DriverState | null {\n const path = statePath(goalId);\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf-8')) as DriverState;\n if (parsed.schemaVersion !== 1) {\n logger.warn(COMPONENT, `State for ${goalId} has unknown schemaVersion=${parsed.schemaVersion} — ignoring`);\n return null;\n }\n return parsed;\n } catch (err) {\n logger.warn(COMPONENT, `Could not parse state for ${goalId}: ${(err as Error).message}`);\n return null;\n }\n}\n\nfunction saveState(state: DriverState): void {\n ensureStateDir();\n state.lastTickAt = new Date().toISOString();\n const path = statePath(state.goalId);\n try {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path + '.tmp', JSON.stringify(state, null, 2));\n // Atomic rename so partial writes never surface\n // (Windows rename-over-existing is OK on Node 22+)\n renameSync(path + '.tmp', path);\n } catch (err) {\n logger.warn(COMPONENT, `Could not persist state for ${state.goalId}: ${(err as Error).message}`);\n }\n}\n\nfunction appendHistory(state: DriverState, phase: DriverPhase, note: string): void {\n const event: DriverHistoryEvent = { at: new Date().toISOString(), phase, note };\n state.history.push(event);\n if (state.history.length > 200) state.history = state.history.slice(-200);\n}\n\n// v6.0.3 — Approval-guidance composer. Distinguishes between a generic\n// \"yes proceed\" click vs real textual guidance, and synthesizes the right\n// follow-up directive for the specialist's next attempt.\n//\n// Generic markers (after trim + lowercase): \"approved\", \"approve\", \"ok\",\n// \"yes\", \"y\", \"go\", \"proceed\", \"do it\", \"lgtm\" — these mean \"go ahead,\n// make your best call.\" Real guidance is anything else >8 chars.\n//\n// Exported for the unit tests.\nconst GENERIC_APPROVAL_NOTES = new Set([\n 'approved', 'approve', 'ok', 'okay', 'yes', 'y', 'go', 'proceed',\n 'do it', 'lgtm', 'sure', 'fine', 'continue', 'yeah', 'yep',\n]);\n\nexport function composeApprovalGuidance(rawNote: string | undefined | null): string {\n const note = (rawNote ?? '').trim();\n const isGeneric = note === '' || note.length <= 8 || GENERIC_APPROVAL_NOTES.has(note.toLowerCase());\n if (isGeneric) {\n return [\n 'The user approved this subtask to proceed but did NOT provide additional textual guidance.',\n 'Interpretation: \"go ahead with your best-effort interpretation of the original task.\"',\n 'Do NOT re-ask the same question that caused the block — pick a reasonable assumption from',\n 'the available context and proceed. If you genuinely cannot make a reasonable assumption,',\n 'complete what you can and report what was unresolved in your reply rather than blocking again.',\n ].join(' ');\n }\n // Real textual guidance — pass it through as before, but reframe so\n // the specialist knows it is the user's explicit answer (not a prior\n // attempt's reasoning).\n return `The user's answer to the question that caused the previous block is: \"${note}\". Use this as authoritative guidance for the next attempt.`;\n}\n\n// ── Daemon-spawned auto-cancel guard (v6.0.3) ────────────────────\n//\n// When an autonomous producer (Soma pressure cycle, dreaming proposer,\n// self-repair daemon, autopilot, mission auto-decomposer) spins up a\n// goal and the goal hits the SAME blocking question twice within an\n// hour, we cancel it rather than file another approval. Rationale: the\n// question is structurally unanswerable by the specialist — re-asking\n// doesn't fix that, it just fills Tony's approval queue. A human-\n// authored goal stays in the queue forever (Tony will answer when he's\n// ready); only daemon goals get this auto-cancel.\n//\n// Detection is by tag — Goal has no `requestedBy` field, so we check\n// the canonical autonomous-tag set the producers attach.\n\nconst DAEMON_SPAWN_TAG_MARKERS = [\n /^soma:/i,\n /^autopilot/i,\n /^mission-auto$/i,\n /^self-repair$/i,\n /^self-mod$/i,\n /^self-healing$/i,\n /^self-modification$/i,\n /^canary-eval$/i,\n /^dreaming$/i,\n /^pressure$/i,\n];\n\n/** True if any of the goal's tags suggest an autonomous producer made it. */\nexport function isDaemonSpawnedGoal(goal: { tags?: string[] }): boolean {\n const tags = goal.tags ?? [];\n for (const t of tags) {\n for (const re of DAEMON_SPAWN_TAG_MARKERS) {\n if (re.test(t)) return true;\n }\n }\n return false;\n}\n\n/**\n * Normalize a blocking question into a stable fingerprint so trivial\n * formatting variations (whitespace, the rolling \"attempt N\" counter,\n * timestamp echoes) don't defeat the same-block-twice check.\n */\nexport function fingerprintBlockedQuestion(q: string): string {\n return q\n .toLowerCase()\n // Strip rolling counters / numbers / timestamps\n .replace(/attempt\\s*\\d+/g, 'attempt N')\n .replace(/\\b\\d{4}-\\d{2}-\\d{2}t[\\d:.]+z?\\b/g, '')\n .replace(/\\b\\d+(\\.\\d+)?\\b/g, 'N')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, 120);\n}\n\n/** Configurable in tests via the optional override; default 1h. */\nexport const SAME_BLOCK_TWICE_WINDOW_MS = 60 * 60 * 1000;\n\n/**\n * Check whether the next-block-to-be-filed is a recurrence of an\n * earlier one within the daemon-auto-cancel window. Mutates `state`\n * to append the new fingerprint regardless (so the next call can\n * still see it).\n *\n * Returns true if the goal should be auto-cancelled.\n */\nexport function shouldAutoCancelOnRecurringBlock(\n state: DriverState,\n goal: { tags?: string[] },\n blockKind: string,\n question: string,\n windowMs: number = SAME_BLOCK_TWICE_WINDOW_MS,\n): boolean {\n if (!isDaemonSpawnedGoal(goal)) {\n return false;\n }\n const fp = fingerprintBlockedQuestion(question);\n const now = Date.now();\n const history = state.blockHistory ?? [];\n const cutoff = now - windowMs;\n // Look for ANY prior block whose fingerprint matches and is within the window.\n const recurrence = history.find(ev => {\n if (ev.fingerprint !== fp) return false;\n const t = Date.parse(ev.at);\n return Number.isFinite(t) && t >= cutoff;\n });\n // Always record the new event (bounded to last 16 entries).\n const next: typeof history = [...history, { at: new Date(now).toISOString(), fingerprint: fp, kind: blockKind }];\n state.blockHistory = next.slice(-16);\n return !!recurrence;\n}\n\n// ── Infrastructure failure detection ──────────────────────────────\n\n/**\n * Detect systematic infrastructure failures that warrant human escalation.\n * Returns true if the error indicates all specialists are failing to produce\n * structured JSON output (thinking patterns, parse errors).\n */\nfunction isInfrastructureFailure(error: string | undefined): boolean {\n if (!error) return false;\n const e = error.toLowerCase();\n // JSON parse failures from structuredSpawn\n const parseFailurePatterns = [\n 'parser could not extract json',\n 'no json block found',\n 'json.parse failure',\n 'prose-fallback:thinking',\n 'thinking prose instead of structured json',\n ];\n return parseFailurePatterns.some(p => e.includes(p));\n}\n\n// ── Init / creation ──────────────────────────────────────────────\n\nfunction freshDriverState(goal: Goal): DriverState {\n const subtaskStates: Record<string, DriverSubtaskState> = {};\n const kinds = classifyAll(goal.subtasks || []);\n for (const sub of goal.subtasks || []) {\n subtaskStates[sub.id] = {\n kind: kinds[sub.id] ?? 'analysis',\n attempts: 0,\n // v4.10.0-local (post-deploy): 5 = full ladder depth\n // (primary + 4 fallbacks). Ensures the claude-code MAX-plan\n // tier is reachable before the subtask gives up. Goal-level\n // maxRetries: 10 remains as the cross-subtask backstop.\n maxAttempts: 5,\n artifacts: [],\n };\n }\n const now = new Date().toISOString();\n return {\n schemaVersion: 1,\n goalId: goal.id,\n phase: 'planning',\n startedAt: now,\n lastTickAt: now,\n budget: { tokensUsed: 0, costUsd: 0, elapsedMs: 0, totalRetries: 0 },\n budgetCaps: { ...DEFAULT_BUDGET_CAPS },\n userControls: {\n paused: false,\n cancelRequested: false,\n priority: (goal.priority as 1 | 2 | 3 | 4 | 5) ?? 3,\n },\n subtaskStates,\n history: [{ at: now, phase: 'planning', note: `Driver started for \"${goal.title}\"` }],\n };\n}\n\n// ── Phase transitions (one tick = one transition) ───────────────\n\nasync function tickPlanning(goal: Goal, state: DriverState): Promise<void> {\n // Ensure subtasks exist (the proposer usually creates them; if a goal\n // came without any, we classify based on title and create a single\n // `analysis` subtask as a placeholder).\n if (!goal.subtasks || goal.subtasks.length === 0) {\n appendHistory(state, 'planning', 'No subtasks — creating single analysis subtask from title');\n try {\n const { addSubtask } = await import('./goals.js');\n addSubtask(goal.id, goal.title, goal.description);\n } catch (err) {\n logger.warn(COMPONENT, `Could not add default subtask to ${goal.id}: ${(err as Error).message}`);\n }\n }\n\n // v4.10.0-local (post-deploy, Fix 9): classify lazily and persist\n // once. Previously this called classifyAll unconditionally on every\n // planning pass, but only persisted new entries — if taxonomy rules\n // changed between boots, restored drivers kept their stale kinds\n // silently. Only classify when we actually need to create a new\n // subtask state entry.\n let kinds: Record<string, ReturnType<typeof classifyAll>[string]> | null = null;\n for (const sub of goal.subtasks || []) {\n if (!state.subtaskStates[sub.id]) {\n if (!kinds) kinds = classifyAll(goal.subtasks || []);\n state.subtaskStates[sub.id] = {\n kind: kinds[sub.id] ?? 'analysis',\n attempts: 0,\n maxAttempts: 5, // per Fix B — matches ladder depth\n artifacts: [],\n };\n }\n }\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Planned: ${Object.keys(state.subtaskStates).length} subtasks classified`);\n}\n\nasync function tickDelegating(goal: Goal, state: DriverState): Promise<void> {\n // Find the next ready subtask (dependencies satisfied, not already done/failed)\n const next = await pickNextReadySubtask(goal, state);\n if (!next) {\n // Re-fetch goal so the allResolved check sees any subtasks that\n // pickNextReadySubtask just marked as failed (durable deadlock\n // recovery from Fix C). Falls back to the stale reference on\n // import failure — worst case we deadlock once more and recover\n // next tick.\n let freshGoal: Goal = goal;\n try {\n const { getGoal } = await import('./goals.js');\n freshGoal = getGoal(goal.id) || goal;\n } catch { /* ok */ }\n // No more ready subtasks — either all done or all blocked on deps.\n // Check if everything's done or failed:\n const allResolved = (freshGoal.subtasks || []).every(\n s => s.status === 'done' || s.status === 'failed' || s.status === 'skipped',\n );\n if (allResolved) {\n // v4.10.0-local (post-deploy): clear currentSubtaskId so\n // tickVerifying takes the whole-goal-verify branch\n // (line 316). Otherwise it keeps trying to verify the\n // last-touched subtask (which may be stale or terminal)\n // and oscillates verifying → iterating → delegating.\n state.currentSubtaskId = undefined;\n state.phase = 'verifying';\n appendHistory(state, 'verifying', 'All subtasks resolved — running final verification');\n } else {\n // Dependencies blocking — pause-block for human\n state.phase = 'blocked';\n state.blockedReason = {\n question: `Goal \"${goal.title}\" is deadlocked. All pending subtasks have unresolved dependencies and none are ready to run. Please review the subtask order and dependencies.`,\n approvalId: '', // filled below if we file an approval\n sinceAt: new Date().toISOString(),\n kind: 'dep_deadlock',\n };\n appendHistory(state, 'blocked', 'Dependency deadlock');\n }\n return;\n }\n\n state.currentSubtaskId = next.id;\n const subState = state.subtaskStates[next.id];\n subState.attempts += 1;\n\n // v4.10.0-local (post-deploy, Fix B): per-subtask attempt cap. A single\n // unlucky subtask can no longer consume the whole goal's retry budget.\n // We fail fast on THIS subtask and let the driver move to the next one.\n const cap = subState.maxAttempts ?? 5;\n if (subState.attempts > cap) {\n subState.verificationResult = {\n passed: false,\n reason: `Per-subtask cap exceeded (${cap})`,\n verifier: 'budget',\n };\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, subState.lastError || `per-subtask cap exceeded (${cap} attempts)`);\n } catch { /* ok */ }\n state.currentSubtaskId = undefined;\n state.phase = 'delegating'; // next tick picks up the next ready subtask\n appendHistory(state, 'delegating', `Subtask ${next.id} exceeded per-subtask cap (${cap}) — moved on`);\n return;\n }\n\n // Pass the per-subtask cap — NOT goal-level maxRetries — to\n // nextFallback. The ladder has 5 tiers; matching means we can reach\n // the final (claude-code MAX) tier before declaring exhaustion.\n const strategy = nextFallback(subState.kind, subState.attempts - 1, subState.lastError, cap);\n if (!strategy) {\n // v4.10.0-local fix: Check if exhaustion is due to infrastructure failure\n // (systematic JSON parse errors). If so, escalate to human instead of\n // silently failing the subtask.\n if (isInfrastructureFailure(subState.lastError)) {\n state.phase = 'escalated';\n state.blockedReason = {\n question: `Goal \"${goal.title}\" — all specialists failed to produce valid output after ${goal.subtasks?.length ?? 0} subtask(s). This usually means the model is misconfigured, the task is too vague, or the specialist doesn't have the right tools. Please review the goal description or switch the model tier.`,\n approvalId: '',\n sinceAt: new Date().toISOString(),\n kind: 'infrastructure_failure',\n };\n appendHistory(state, 'escalated', `Subtask ${next.id}: infrastructure failure — all specialists failed JSON output`);\n await fileBlockedApproval(state, goal, [state.blockedReason.question]);\n return;\n }\n\n // Exhausted retries for this subtask (normal failure)\n subState.verificationResult = {\n passed: false,\n reason: 'Max retries exhausted',\n verifier: 'budget',\n };\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, 'max-retries-exhausted');\n } catch { /* ok */ }\n state.currentSubtaskId = undefined;\n state.phase = 'delegating'; // try next subtask\n appendHistory(state, 'delegating', `Subtask ${next.id} exhausted retries — moved on`);\n return;\n }\n\n subState.specialist = strategy.specialist;\n subState.pendingSpawn = {\n attemptedAt: new Date().toISOString(),\n specialist: strategy.specialist,\n };\n state.phase = 'observing';\n appendHistory(\n state,\n 'observing',\n `Spawning ${strategy.specialist} for subtask \"${next.title}\" (kind=${subState.kind}, attempt ${subState.attempts})`,\n );\n\n // v6.1.0-alpha.1 — emit a structured \"agent_spawn\" event on the shared\n // bus so listeners (Mission Chat lifecycle bridge, the SSE dashboard\n // tail, the Agent Watcher) know who's starting on what. Includes the\n // goalId so listeners can correlate without having to peer-into driver\n // state.\n try {\n emitAgentEvent({\n type: 'agent_spawn',\n agentId: strategy.specialist,\n agentName: strategy.specialist,\n timestamp: Date.now(),\n data: {\n goalId: goal.id,\n subtaskId: next.id,\n subtaskTitle: next.title,\n subtaskKind: subState.kind,\n attempt: subState.attempts,\n },\n });\n } catch { /* event bus failure should never block a spawn */ }\n\n // Actually fire the spawn — runs in-tick, driver waits for the return.\n // (Future: async wakeup path so driver can observe multiple concurrent\n // spawns; for now one at a time per goal.)\n try {\n const startMs = Date.now();\n // v6.1.0-alpha.32 — if the goal looks like a document deliverable,\n // prepend a hard FORMAT directive to the task description. Belt\n // and suspenders with the specialist system prompt's HTML_REPORT_\n // GUIDANCE: even strong system-prompt rules can be drowned by a\n // long context, but a directive at the top of the per-task user\n // message is the LAST thing the LLM sees before producing output.\n const baseTask = `${next.title}\\n\\n${next.description}${strategy.promptAdjustment ?? ''}`;\n const documentLike = /\\b(essay|report|briefing|writeup|write-up|summary|article|document|memo|paper|analysis|whitepaper|brief)\\b/i.test(goal.title)\n || /\\b(essay|report|briefing|writeup|summary|article)\\b/i.test(next.title);\n const taskWithFormat = documentLike\n ? `OUTPUT FORMAT — REQUIRED:\\nThe user wants a real document they can view with images, charts, and styling. You MUST deliver this as a single self-contained .html file (write_file with a path ending in .html, e.g. \"${slugForGoal(goal.title)}.html\"). Do NOT write .md or .markdown — those can't show images or charts. See the OUTPUT FORMAT FOR DOCUMENTS section of your system prompt for the structure.\\n\\n──────────\\n\\n${baseTask}`\n : baseTask;\n const result = await structuredSpawn({\n specialistId: strategy.specialist,\n task: taskWithFormat,\n modelOverride: strategy.modelOverride,\n toolAllowlist: routeForKind(subState.kind).toolAllowlist,\n maxRounds: strategy.maxRounds,\n // v6.1.0-alpha.41 — thread goalId so subAgent's tool_call\n // events carry data.goalId and the lifecycle bridge can\n // correlate them back to the mission room.\n goalId: goal.id,\n });\n const durationMs = Date.now() - startMs;\n\n // v6.1.0-alpha.1 — emit the result on the agent bus too. The Mission\n // Chat bridge turns this into a chat message; the SSE dashboard tail\n // logs it for replay. We always emit, even on failed/needs_info\n // status, so the UI can show the specialist's reasoning regardless.\n try {\n emitAgentEvent({\n type: 'agent_done',\n agentId: strategy.specialist,\n agentName: strategy.specialist,\n timestamp: Date.now(),\n data: {\n goalId: goal.id,\n subtaskId: next.id,\n subtaskTitle: next.title,\n status: result.status,\n reasoning: result.reasoning,\n artifactCount: result.artifacts.length,\n artifacts: result.artifacts.map(a => ({ ref: a.ref, type: a.type })),\n toolsUsed: result.toolsUsed ?? [],\n tokensUsed: result.tokensUsed ?? 0,\n costUsd: result.costUsd ?? 0,\n durationMs,\n // v6.1.0-alpha.4 — include the resolved model so the\n // Mission Chat UI can show \"ran on X\" when the user\n // expands a bubble. Use modelOverride if set, otherwise\n // the specialist's id (UI maps id → friendly model name\n // via the registry when needed).\n model: strategy.modelOverride ?? strategy.specialist,\n },\n });\n } catch { /* event bus failure should never affect driver state */ }\n recordSpend(state, {\n elapsedMs: durationMs,\n tokens: result.tokensUsed ?? 0,\n costUsd: result.costUsd ?? 0,\n });\n\n // Store artifacts\n subState.artifacts = [...new Set([\n ...subState.artifacts,\n ...result.artifacts.map(a => a.ref),\n ])];\n\n // Decide phase based on spawn status\n if (result.status === 'done') {\n subState.consecutiveNeedsInfoCount = 0; // reset on non-needs_info\n\n // beta.10 — runtime assertion failure detector. Look at the\n // verification ring for events recorded during this spawn\n // window (between pendingSpawn.attemptedAt and now). If any\n // verifications failed AND none passed, increment the\n // assertion counter; if any passed, reset it. Threshold\n // 3 → fail the subtask with verify_fail block kind so we\n // don't loop forever on a spawn that keeps producing\n // artifacts that don't survive readback.\n try {\n const spawnStartMs = subState.pendingSpawn?.attemptedAt\n ? new Date(subState.pendingSpawn.attemptedAt).getTime()\n : Date.now() - durationMs;\n const events = verificationEventsSince(spawnStartMs);\n const failed = events.filter(e => !e.result.passed);\n const passed = events.filter(e => e.result.passed);\n if (failed.length > 0 && passed.length === 0) {\n subState.consecutiveAssertionFailures =\n (subState.consecutiveAssertionFailures ?? 0) + 1;\n const count = subState.consecutiveAssertionFailures;\n appendHistory(\n state,\n 'observing',\n `Spawn produced ${failed.length} verification failure(s) (counter=${count}): ${failed[0].result.reason.slice(0, 100)}`,\n );\n if (count >= 3) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(\n goal.id,\n next.id,\n `Subtask failed verification ${count}× in a row. Last failure: ${failed[0].result.reason.slice(0, 200)}. The specialist keeps producing artifacts that don't survive readback (byte-count drift, magic-header mismatch, partial write). Failing to break the loop.`,\n );\n } catch { /* ok */ }\n subState.lastError = `Failed: ${count} consecutive verification failures`;\n subState.pendingSpawn = undefined;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Verification stuck-loop fail on ${next.id} (${count}× failures)`);\n return;\n }\n } else if (passed.length > 0) {\n subState.consecutiveAssertionFailures = 0;\n }\n } catch { /* assertion counting never gates the happy path */ }\n\n state.phase = 'verifying';\n appendHistory(state, 'verifying', `Spawn returned done with ${result.artifacts.length} artifact(s), confidence ${result.confidence.toFixed(2)}`);\n // Stash the spawn result so verifying can read it\n (subState as DriverSubtaskState & { lastSpawnResult?: unknown }).lastSpawnResult = result;\n } else if (result.status === 'failed') {\n subState.lastError = result.reasoning || 'failed';\n subState.consecutiveNeedsInfoCount = 0; // reset on non-needs_info\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Spawn returned failed: ${subState.lastError.slice(0, 120)}`);\n } else if (result.status === 'needs_info' || result.status === 'blocked') {\n // v4.14.0: build a rich, contextual blocked reason instead of\n // the generic \"Specialist requires input\" that tells the user\n // nothing about what actually went wrong.\n const subtaskTitle = next.title || 'Unnamed subtask';\n const specialistName = strategy.specialist || subState.specialist || 'specialist';\n const attemptCount = subState.attempts;\n const lastErr = subState.lastError;\n const rawQuestion = result.questions[0] ?? '';\n\n // v6.1.0-beta.4 — defensive consecutive-needs_info counter.\n // Reproduces the mzzbajnj bug: a specialist returns\n // `needs_info` with EMPTY question string, the\n // genericQuestionRejected→fail path *should* terminate it on\n // attempt 2, but in practice the loop ran 17 minutes before\n // Tony cancelled. Belt-and-suspenders guard independent of\n // genericQuestionRejected/commitOverride/dedupe state: count\n // consecutive needs_info, force-fail at threshold regardless\n // of any other flag. This guarantees termination even if a\n // future refactor breaks one of the other guards.\n subState.consecutiveNeedsInfoCount = (subState.consecutiveNeedsInfoCount || 0) + 1;\n const trimmedQuestion = rawQuestion.trim();\n const needsInfoCount = subState.consecutiveNeedsInfoCount;\n // Empty/whitespace question + attempts >= 2 → fail\n // immediately. An empty needs_info on a retry is a sure\n // sign the specialist has nothing to say.\n if (trimmedQuestion.length === 0 && attemptCount >= 2) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Specialist ${specialistName} returned needs_info with an empty question on attempt ${attemptCount}. No actionable signal — failing subtask to break the loop.`);\n } catch { /* ok */ }\n subState.lastError = `Failed: empty needs_info on attempt ${attemptCount} (specialist ${specialistName})`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Empty needs_info fail on ${next.id} (attempt ${attemptCount})`);\n subState.pendingSpawn = undefined;\n return;\n }\n // Three consecutive needs_info on this subtask → fail\n // regardless of question content. Forward progress check.\n if (needsInfoCount >= 3) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Specialist ${specialistName} returned needs_info ${needsInfoCount}× in a row on this subtask. Forcing failure to break the loop. Last question: \"${trimmedQuestion.slice(0, 160)}\"`);\n } catch { /* ok */ }\n subState.lastError = `Failed: ${needsInfoCount} consecutive needs_info returns`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Consecutive needs_info fail on ${next.id} (${needsInfoCount}×)`);\n subState.pendingSpawn = undefined;\n return;\n }\n\n // v6.1.0-alpha.51 — commit-override short-circuit. If the\n // previous block was auto-rejected (15-min timeout) we set\n // commitOverride. The specialist had its one free re-try with\n // a \"commit, don't re-ask\" directive in lastError; if it STILL\n // came back with needs_info, the question is structurally\n // unanswerable from current context. File the subtask as\n // committed (best-effort done) rather than re-blocking — this\n // breaks the \"Auto-rejected... What should the specialist do\n // next?\" infinite ask loop Tony reported.\n if (subState.commitOverride) {\n subState.commitOverride = false; // one-shot\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Auto-committed after timeout: specialist still needs info but no human is available. Original question: \"${rawQuestion.slice(0, 160)}\"`);\n } catch { /* ok */ }\n subState.lastError = `Auto-committed after timeout. Last unresolved question: ${rawQuestion.slice(0, 160)}`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Commit-override applied on ${next.id} — no re-block after timeout`);\n subState.pendingSpawn = undefined;\n return;\n }\n\n // v6.1.0-alpha.51 — dedupe repeated questions. If the\n // specialist has already asked this same question (by\n // fingerprint) before on this subtask, don't file the\n // approval again. Convert to a forced commit instead so\n // the user isn't pestered with the same prompt 3 times.\n const rawFp = rawQuestion ? fingerprintBlockedQuestion(rawQuestion) : '';\n const askedBefore = !!rawFp && (subState.askedQuestionFingerprints || []).includes(rawFp);\n if (askedBefore) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Repeat-question dedupe: specialist asked the same question (\"${rawQuestion.slice(0, 120)}\") twice. Marking subtask failed to avoid pestering the human.`);\n } catch { /* ok */ }\n subState.lastError = `Repeat question detected — failed subtask. Last question: ${rawQuestion.slice(0, 160)}`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Repeat-question dedupe on ${next.id}`);\n subState.pendingSpawn = undefined;\n return;\n }\n if (rawFp) {\n subState.askedQuestionFingerprints = [\n ...(subState.askedQuestionFingerprints || []),\n rawFp,\n ].slice(-8);\n }\n\n // v6.1.0-alpha.54 — generic-question pre-pass. Tony asked\n // not to be pinged with low-info questions (\"What should\n // I focus on?\", \"Please clarify\", etc.). isGenericQuestion\n // classifies the rawQuestion; if generic AND we haven't\n // already rejected one for this subtask, we set\n // `lastError` to a forceCommitDirective and bounce back\n // to delegating — the specialist gets one free retry with\n // explicit \"commit your best interpretation OR consult a\n // teammate\" guidance. If the specialist STILL returns\n // generic on the retry, we fail the subtask rather than\n // burn Tony's attention. Specific questions (with a\n // decision marker, named option, year, URL, quoted name,\n // etc.) pass through to the existing approval flow.\n if (isGenericQuestion(rawQuestion)) {\n if (!subState.genericQuestionRejected) {\n subState.genericQuestionRejected = true;\n subState.lastError = forceCommitDirective(rawQuestion, goal.title);\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Generic question rejected — forcing commit retry on ${next.id}`);\n subState.pendingSpawn = undefined;\n return;\n }\n // Second generic question in a row → fail the subtask\n // instead of looping. Don't ship to Tony either way.\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Two generic questions in a row from ${specialistName}. Last: \"${rawQuestion.slice(0, 160)}\". The specialist couldn't commit on its own after a force-retry — marking subtask failed rather than escalating a low-info question to the human.`);\n } catch { /* ok */ }\n subState.lastError = `Failed after two generic questions. Last: ${rawQuestion.slice(0, 160)}`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Generic-question fail on ${next.id} after force-retry`);\n subState.pendingSpawn = undefined;\n return;\n }\n\n state.phase = 'blocked';\n let richQuestion: string;\n if (rawQuestion && rawQuestion.length > 10 && !rawQuestion.toLowerCase().includes('specialist requires')) {\n // The specialist gave a real question — use it but wrap with context\n richQuestion = `Goal \"${goal.title}\" is stuck on subtask \"${subtaskTitle}\" (attempt ${attemptCount}, specialist: ${specialistName}).\\n\\n${rawQuestion}`;\n } else if (lastErr && !/TIMEOUT_DIRECTIVE/.test(lastErr)) {\n // v6.1.0-alpha.51 — guard against propagating internal\n // commit-override directive into the user-facing question.\n richQuestion = `Goal \"${goal.title}\" — subtask \"${subtaskTitle}\" failed after ${attemptCount} attempt(s) with specialist ${specialistName}.\\n\\nError: ${lastErr.slice(0, 200)}\\n\\nWhat should the specialist do next?`;\n } else {\n richQuestion = `Goal \"${goal.title}\" — subtask \"${subtaskTitle}\" is blocked after ${attemptCount} attempt(s) with specialist ${specialistName}. The specialist could not complete the task and needs guidance on how to proceed.`;\n }\n\n state.blockedReason = {\n question: richQuestion,\n approvalId: '',\n sinceAt: new Date().toISOString(),\n kind: 'needs_info',\n };\n appendHistory(state, 'blocked', `Spawn needs info: ${richQuestion.slice(0, 120)}`);\n await fileBlockedApproval(state, goal, [richQuestion, ...result.questions.slice(1)]);\n }\n subState.pendingSpawn = undefined;\n } catch (err) {\n const msg = (err as Error).message;\n subState.lastError = msg;\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Spawn threw: ${msg.slice(0, 120)}`);\n }\n}\n\nasync function tickObserving(goal: Goal, state: DriverState): Promise<void> {\n // In Phase A, spawns are sync (await structuredSpawn completes in tickDelegating).\n // This phase exists for future async-wakeup integration; for now it just\n // advances based on whatever subState said after the spawn.\n //\n // v4.10.0-local (post-deploy, Fix 8): be a no-op unless there's a\n // pending spawn waiting for a wakeup. Previously this unconditionally\n // transitioned to iterating, which tickIterating treated as a failure\n // and burned an attempt on goals that never actually spawned. Now the\n // observing phase only advances when there's a spawn to observe.\n void goal;\n const currentId = state.currentSubtaskId;\n const subState = currentId ? state.subtaskStates[currentId] : undefined;\n if (!subState?.pendingSpawn) {\n // Nothing to observe — bounce back to delegating without counting\n // as a retry.\n state.phase = 'delegating';\n return;\n }\n state.phase = 'iterating';\n appendHistory(state, 'iterating', 'Observe tick with no spawn progress — iterating');\n}\n\nasync function tickIterating(goal: Goal, state: DriverState): Promise<void> {\n const currentId = state.currentSubtaskId;\n if (!currentId) {\n state.phase = 'delegating';\n return;\n }\n const subState = state.subtaskStates[currentId];\n\n // v4.10.0-local (post-deploy, Fix A): forward-progress detector.\n // If the same lastError (first 80 chars) repeats 3 times in a row,\n // retrying isn't producing new information — fail this subtask and\n // move on. Prevents the verifying↔iterating→delegating oscillation\n // observed on stuck drivers. Uses a semantic signal (error text)\n // rather than phase-pattern detection, which false-positives on\n // legitimate multi-phase verify passes.\n const fingerprint = (subState.lastError || '').slice(0, 80).toLowerCase().trim();\n if (fingerprint) {\n if (fingerprint === subState.lastErrorFingerprint) {\n subState.consecutiveIdenticalErrors = (subState.consecutiveIdenticalErrors || 0) + 1;\n } else {\n subState.consecutiveIdenticalErrors = 1;\n subState.lastErrorFingerprint = fingerprint;\n }\n if ((subState.consecutiveIdenticalErrors ?? 0) >= 3) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, currentId, `Stuck loop: same error 3× in a row: ${fingerprint}`);\n } catch { /* ok */ }\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Broke stall loop on ${currentId} (same error 3×)`);\n return;\n }\n }\n\n // v4.10.0-local (post-deploy, Fix 8): do NOT increment totalRetries\n // here. Per-subtask attempts are counted in tickDelegating. Counting\n // again here caused double-billing: one failed spawn consumed 2 budget\n // units. Retry budget is meant to track subtask-transition retries,\n // not individual spawn retries.\n const check = checkBudget(state);\n if (check.status === 'exceeded') {\n const suggestion = suggestDegradation(state);\n if (suggestion === 'ask_human') {\n state.phase = 'blocked';\n state.blockedReason = {\n question: `Goal \"${goal.title}\" — budget exceeded (${check.message}). The driver has used ${state.budget.costUsd.toFixed(2)} USD so far. Continue with extended budget, de-scope, or cancel?`,\n approvalId: '',\n sinceAt: new Date().toISOString(),\n kind: 'budget_exceeded',\n };\n appendHistory(state, 'blocked', check.message);\n await fileBlockedApproval(state, goal, [state.blockedReason.question]);\n return;\n }\n }\n\n if (subState.attempts >= state.budgetCaps.maxRetries) {\n // Gap 2 (plan-this-logical-ocean): before giving up on this subtask,\n // consult the bounded continuation counter. If the per-subtask cap\n // hasn't been hit (max 2, persisted to disk so restarts can't\n // bypass), halve attempts and let it try again. This is the\n // \"plan_only\" signal — spawns kept producing plans/output that\n // wouldn't verify. Two extra cycles across a restart boundary is\n // the cheapest escape from the verifying↔iterating oscillation that\n // the existing stuck-loop detector can't catch (different errors\n // each time, but no real progress).\n const { shouldContinue } = await import('./runContinuations.js');\n const continuationKey = `${goal.id}:${currentId}`;\n if (shouldContinue(continuationKey, 'plan_only')) {\n const before = subState.attempts;\n subState.attempts = Math.max(0, Math.floor(subState.attempts / 2));\n subState.consecutiveIdenticalErrors = 0;\n subState.lastErrorFingerprint = undefined;\n appendHistory(state, 'delegating', `Continuation granted on ${currentId}: attempts halved ${before} → ${subState.attempts}`);\n state.phase = 'delegating';\n return;\n }\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, currentId, subState.lastError || 'max retries');\n } catch { /* ok */ }\n appendHistory(state, 'delegating', `Subtask ${currentId} failed after ${subState.attempts} attempts`);\n state.phase = 'delegating';\n return;\n }\n\n // Back to delegating to try the next fallback\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Iterating on subtask ${currentId} — attempt ${subState.attempts + 1}`);\n}\n\nasync function tickVerifying(goal: Goal, state: DriverState): Promise<void> {\n const currentId = state.currentSubtaskId;\n if (!currentId) {\n // Whole-goal verify — check per-subtask results against the goal\n // file's subtask statuses. A subtask passes the whole-goal check\n // iff EITHER (a) its verificationResult.passed === true, OR\n // (b) the goal file reports it as done/skipped (completed through\n // an external path, e.g. human marked it done).\n //\n // v4.10.0-local (post-deploy, Fix 8): previous check was\n // `passed !== false`, which treated subtasks that never got\n // verified at all (verificationResult undefined) as passing\n // vacuously. Now we require an explicit pass signal OR an\n // explicit terminal status on the goal-side subtask.\n const goalSubs = goal.subtasks || [];\n const subById = new Map(goalSubs.map(s => [s.id, s]));\n const allPassed = Object.entries(state.subtaskStates).every(([subId, subState]) => {\n if (subState.verificationResult?.passed === true) return true;\n const goalSub = subById.get(subId);\n if (goalSub?.status === 'done' || goalSub?.status === 'skipped') return true;\n return false;\n });\n state.phase = allPassed ? 'reporting' : 'failed';\n appendHistory(state, state.phase, allPassed ? 'All subtasks verified' : 'Some subtasks failed verification');\n return;\n }\n const subState = state.subtaskStates[currentId];\n const subtask = (goal.subtasks || []).find(s => s.id === currentId);\n if (!subtask) {\n state.phase = 'delegating';\n return;\n }\n const lastSpawn = (subState as DriverSubtaskState & { lastSpawnResult?: unknown }).lastSpawnResult;\n if (!lastSpawn) {\n // No spawn result to verify against — iterate\n state.phase = 'iterating';\n appendHistory(state, 'iterating', 'Verify with no spawn result — iterating');\n return;\n }\n\n const verifyResult = await verifyByKind({\n kind: subState.kind,\n subtask,\n spawnResult: lastSpawn as Parameters<typeof verifyByKind>[0]['spawnResult'],\n });\n subState.verificationResult = verifyResult;\n\n if (verifyResult.passed) {\n try {\n const { completeSubtask } = await import('./goals.js');\n // v4.10.0-local polish: store the SPAWN'S actual output\n // (reasoning + artifacts summary), not the verifier's pass\n // message. Prior behavior stored \"Analysis 171 chars, conf 0.95\"\n // in the subtask.result field, losing the actual content.\n const spawn = lastSpawn as Parameters<typeof verifyByKind>[0]['spawnResult'];\n const artifactSummary = spawn.artifacts.length > 0\n ? `\\n\\nArtifacts:\\n${spawn.artifacts.map(a => ` - [${a.type}] ${a.ref}${a.description ? ` — ${a.description}` : ''}`).join('\\n')}`\n : '';\n const contentToSave = (spawn.reasoning || spawn.rawResponse || verifyResult.reason) + artifactSummary;\n completeSubtask(goal.id, currentId, contentToSave);\n } catch { /* ok */ }\n appendHistory(state, 'delegating', `Subtask ${currentId} verified: ${verifyResult.reason.slice(0, 120)}`);\n state.currentSubtaskId = undefined;\n\n // Bug #3 fix — v6.1.0-alpha.43: when the subtask we just\n // verified was the LAST remaining pending subtask, jump\n // straight to 'reporting' rather than back through\n // 'delegating'. Going through delegating left the goal\n // stuck in 'active' forever when the scheduler stopped\n // driving it after this tick.\n const goalSubs = goal.subtasks || [];\n const allResolved = goalSubs.every(\n s => s.status === 'done' || s.status === 'failed' || s.status === 'skipped',\n );\n if (allResolved) {\n state.phase = 'verifying'; // next tick → whole-goal verify → reporting\n appendHistory(state, 'verifying', 'Last subtask resolved — final whole-goal verify');\n } else {\n state.phase = 'delegating';\n }\n } else {\n subState.lastError = `Verification failed: ${verifyResult.reason}`;\n appendHistory(state, 'iterating', `Verification failed: ${verifyResult.reason.slice(0, 120)}`);\n state.phase = 'iterating';\n }\n}\n\nasync function tickReporting(goal: Goal, state: DriverState): Promise<void> {\n const durationMs = Date.now() - new Date(state.startedAt).getTime();\n const specialistsUsed = [...new Set(\n Object.values(state.subtaskStates)\n .map(s => s.specialist)\n .filter((x): x is string => !!x),\n )];\n state.retrospective = {\n success: true,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n lessonsLearned: [\n `Completed ${Object.keys(state.subtaskStates).length} subtasks across ${specialistsUsed.length} specialist(s) in ${Math.round(durationMs / 1000)}s`,\n ],\n specialistsUsed,\n };\n try {\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'completed' });\n } catch { /* ok */ }\n state.phase = 'done';\n appendHistory(state, 'done', `Goal completed: ${state.retrospective.lessonsLearned[0]}`);\n // v6.1.0-alpha.7 — broadcast on titanEvents so Mission Chat (and any\n // future listener) knows the goal finished. Without this, the mission\n // room sat in 'working' state with no completion message and looked\n // stuck even though the goal driver had returned status=completed in\n // goals.json. Bridge in missionLifecycle.ts maps this to a \"Mission\n // complete\" system message + status=done in the room.\n try {\n const { titanEvents } = await import('./daemon.js');\n titanEvents.emit('goal:completed', {\n goalId: goal.id,\n title: goal.title,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n specialistsUsed,\n subtaskCount: Object.keys(state.subtaskStates).length,\n });\n } catch { /* event bus failure never blocks driver state transitions */ }\n try { await onGoalCompleted(goal, state); } catch { /* ok */ }\n // v4.10.0-local (Phase B): record retrospective for future goal learning\n try {\n const { saveRetrospective } = await import('./retrospectives.js');\n await saveRetrospective(goal, state);\n } catch { /* ok */ }\n\n // Fire episode\n try {\n const { recordEpisode } = await import('../memory/episodic.js');\n recordEpisode({\n kind: 'goal_completed',\n summary: `Driver completed goal \"${goal.title}\" (${Math.round(durationMs / 1000)}s, ${Object.keys(state.subtaskStates).length} subtasks, specialists: ${specialistsUsed.join(', ')})`,\n detail: state.history.slice(-10).map(h => `${h.at} ${h.phase}: ${h.note}`).join('\\n'),\n tags: ['goal-driver', 'goal_completed', goal.id, ...(goal.tags || [])],\n });\n } catch { /* ok */ }\n}\n\nasync function tickBlocked(goal: Goal, state: DriverState): Promise<void> {\n // v4.10.0-local (post-deploy, Fix F): auto-unblock stale blocked states.\n // The block was either never backed by an approval (approvalId empty —\n // bookkeeping bug) or the approval no longer exists (deleted / TTL'd).\n // After 10 minutes of sitting idle with no live approval, retry the\n // subtask rather than sitting forever waiting for a human who has no\n // way to resolve this. Uses forceUnblockDriver so the recovery is\n // consistent with the manual API path.\n const approvalId = state.blockedReason?.approvalId;\n const sinceAt = state.blockedReason?.sinceAt;\n const sinceMs = sinceAt ? Date.now() - new Date(sinceAt).getTime() : 0;\n const STALE_MS = 10 * 60 * 1000;\n if (sinceMs > STALE_MS) {\n let approval: { status?: string } | null = null;\n if (approvalId) {\n try {\n const { getApproval } = await import('./commandPost.js');\n approval = getApproval(approvalId) as { status?: string } | null;\n } catch { /* ok */ }\n }\n if (!approvalId || !approval) {\n // Unblock in-place on the shared state reference. We can't\n // call forceUnblockDriver here because it does its own\n // loadState/saveState cycle, and tickDriver's outer saveState\n // would then overwrite those changes with our stale local\n // state. Mirror forceUnblockDriver's logic here.\n logger.info(COMPONENT, `Auto-unblocking stale blocked state for ${goal.id} (approvalId=${approvalId || 'empty'}, age=${Math.round(sinceMs / 60000)}min)`);\n const note = `stale block auto-recovered (age ${Math.round(sinceMs / 60000)}min)`;\n const wasBudget = state.blockedReason?.kind === 'budget_exceeded'\n || /budget.*exceed|retries exceed/i.test(state.blockedReason?.question || '');\n if (wasBudget) {\n state.budget.totalRetries = Math.floor(state.budget.totalRetries / 2);\n }\n const currentId = state.currentSubtaskId;\n if (currentId && state.subtaskStates[currentId]) {\n const sub = state.subtaskStates[currentId];\n sub.attempts = Math.floor(sub.attempts / 2);\n sub.consecutiveIdenticalErrors = 0;\n }\n state.blockedReason = undefined;\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Force-unblocked: ${note}`);\n return;\n }\n\n // Bug #6 fix — v6.1.0-alpha.43: if the approval is still\n // \"pending\" after 15 minutes, the human is unlikely to answer\n // soon (asleep, away, etc.). Auto-reject it so the goal\n // doesn't stay blocked forever. The specialist will retry\n // with a fresh attempt rather than spinning.\n const STALE_PENDING_MS = 15 * 60 * 1000;\n if (approval.status === 'pending' && sinceMs > STALE_PENDING_MS) {\n try {\n const { rejectApproval } = await import('./commandPost.js');\n rejectApproval(approvalId, 'auto:timeout', `Auto-rejected after ${Math.round(sinceMs / 60000)}min with no human response`);\n } catch { /* ok */ }\n const currentId = state.currentSubtaskId;\n if (currentId && state.subtaskStates[currentId]) {\n const sub = state.subtaskStates[currentId];\n sub.attempts = Math.floor(sub.attempts / 2);\n sub.consecutiveIdenticalErrors = 0;\n // v6.1.0-alpha.51 — the previous wording (\"Retry with\n // your best interpretation. What should the specialist\n // do next?\") would propagate into the next richQuestion\n // (line ~543) and surface verbatim to the user as a\n // pending question, creating an infinite ask loop. Rephrase\n // as a directive that does NOT read like a user-question,\n // and set commitOverride so the next needs_info short-\n // circuits to a commit/fail instead of filing another\n // approval.\n sub.lastError = 'TIMEOUT_DIRECTIVE: previous block timed out (no human within 15min). Commit to your best-effort interpretation now and proceed — do NOT ask another question. If no reasonable assumption is possible, return status=done with a \"could not complete: <reason>\" note in reasoning.';\n sub.commitOverride = true;\n }\n state.blockedReason = undefined;\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Stale pending approval ${approvalId} auto-rejected after ${Math.round(sinceMs / 60000)}min — iterating with commit-override`);\n return;\n }\n }\n\n // Check if the blocking approval has been decided\n if (!approvalId) return; // nothing to unblock from\n try {\n const { getApproval } = await import('./commandPost.js');\n const approval = getApproval(approvalId);\n if (!approval) return;\n if (approval.status === 'pending') return; // still waiting\n if (approval.status === 'approved') {\n // v6.0.3 — Incorporate the human's response into the current\n // subtask's context. The pre-v6.0.3 path composed\n // `Previous attempt needed info; human provided: \"${note}\".\n // Try again using this.` regardless of what the note was.\n //\n // When the user clicked \"Approve\" WITHOUT supplying actual\n // textual guidance via /api/command-post/approvals/:id/reply,\n // `decisionNote` was either undefined OR a generic verb like\n // \"Approved\" / \"OK\" / \"Yes\". The specialist would then try\n // to use the literal string \"Approved\" as the answer to a\n // question like \"What project should I document?\", fail\n // because that isn't actionable info, and re-block. Tony\n // would approve again, same loop. Approvals became useless\n // for `needs_info` blocks.\n //\n // Fix: detect generic/empty notes and synthesize a \"proceed\n // with best-effort interpretation; do NOT re-ask the same\n // question\" directive instead of feeding the action label.\n // When the note IS real textual guidance (>8 chars, not a\n // common approve-verb), pass it through as before.\n const currentId = state.currentSubtaskId;\n if (currentId) {\n const subState = state.subtaskStates[currentId];\n subState.lastError = composeApprovalGuidance(approval.decisionNote);\n }\n state.blockedReason = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Unblocked by human (approval ${approvalId})`);\n return;\n }\n if (approval.status === 'rejected') {\n state.phase = 'failed';\n appendHistory(state, 'failed', `Goal rejected by human via approval ${approvalId}`);\n await onGoalFailed(goal, state, 'rejected by human');\n return;\n }\n } catch { /* ok */ }\n}\n\nasync function tickEscalated(goal: Goal, state: DriverState): Promise<void> {\n // v4.10.0-local: Escalated phase handles systematic infrastructure failures.\n // Similar to blocked, but specifically for JSON parse failures that indicate\n // model tier issues. Requires human intervention to fix infrastructure.\n\n const approvalId = state.blockedReason?.approvalId;\n const sinceAt = state.blockedReason?.sinceAt;\n const sinceMs = sinceAt ? Date.now() - new Date(sinceAt).getTime() : 0;\n\n // Check if the escalation approval has been decided\n if (!approvalId) return;\n try {\n const { getApproval } = await import('./commandPost.js');\n const approval = getApproval(approvalId);\n if (!approval) return;\n if (approval.status === 'pending') return; // still waiting\n\n if (approval.status === 'approved') {\n // Human acknowledged the infrastructure issue and wants to retry\n // Reset the subtask attempts to give it another go with potentially\n // new model configuration\n const currentId = state.currentSubtaskId;\n if (currentId) {\n const subState = state.subtaskStates[currentId];\n subState.attempts = 0; // Reset to allow fresh attempts\n subState.consecutiveIdenticalErrors = 0;\n subState.lastError = undefined;\n subState.lastErrorFingerprint = undefined;\n }\n state.blockedReason = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Escalation resolved by human — retrying subtask ${currentId} with fresh attempts`);\n return;\n }\n\n if (approval.status === 'rejected') {\n // Human decided to fail the goal rather than retry\n state.phase = 'failed';\n appendHistory(state, 'failed', `Infrastructure escalation rejected — goal failed`);\n await onGoalFailed(goal, state, 'infrastructure escalation rejected by human');\n return;\n }\n } catch { /* ok */ }\n}\n\nasync function tickFailed(goal: Goal, state: DriverState): Promise<void> {\n const durationMs = Date.now() - new Date(state.startedAt).getTime();\n state.retrospective = {\n success: false,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n lessonsLearned: [\n `Goal failed after ${Math.round(durationMs / 1000)}s, ${state.budget.totalRetries} retries`,\n ],\n specialistsUsed: [...new Set(Object.values(state.subtaskStates).map(s => s.specialist).filter((x): x is string => !!x))],\n };\n try {\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'failed' });\n } catch { /* ok */ }\n // v6.1.0-alpha.7 — same broadcast pattern as completion. The Mission\n // Chat bridge translates this to a \"Couldn't finish this one.\" system\n // message + status=failed so the user sees closure instead of an\n // idle team strip.\n try {\n const { titanEvents } = await import('./daemon.js');\n titanEvents.emit('goal:failed', {\n goalId: goal.id,\n title: goal.title,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n retries: state.budget.totalRetries,\n });\n } catch { /* event bus failure never blocks driver state transitions */ }\n try { await onGoalFailed(goal, state, 'driver terminated in failed state'); } catch { /* ok */ }\n // Phase B: failed retrospectives are the most valuable — they teach us what to avoid\n try {\n const { saveRetrospective } = await import('./retrospectives.js');\n await saveRetrospective(goal, state);\n } catch { /* ok */ }\n try {\n const { recordEpisode } = await import('../memory/episodic.js');\n recordEpisode({\n kind: 'goal_failed',\n summary: `Driver failed goal \"${goal.title}\" after ${Math.round(durationMs / 1000)}s`,\n detail: state.history.slice(-15).map(h => `${h.at} ${h.phase}: ${h.note}`).join('\\n'),\n tags: ['goal-driver', 'goal_failed', goal.id, ...(goal.tags || [])],\n });\n } catch { /* ok */ }\n}\n\nasync function tickCancelled(goal: Goal, state: DriverState): Promise<void> {\n try {\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'failed' });\n } catch { /* ok */ }\n appendHistory(state, 'cancelled', 'Cancelled by user');\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nasync function pickNextReadySubtask(goal: Goal, state: DriverState): Promise<Subtask | null> {\n // v4.10.0-local (post-deploy, Fix C): synchronous deadlock recovery.\n // If a pending subtask has exhausted its attempts with a failed\n // verification, await failSubtask to persist the failure *before*\n // continuing. The previous async mutation was ephemeral — the next\n // tick's getGoal() call saw stale data and re-entered the deadlock\n // branch in tickDelegating. This version is durable.\n const cap = (id: string) => state.subtaskStates[id]?.maxAttempts ?? 5;\n for (const sub of goal.subtasks || []) {\n if (sub.status !== 'pending') continue;\n const subState = state.subtaskStates[sub.id];\n if (!subState) continue;\n const exhaustedAttempts = subState.attempts >= cap(sub.id)\n || subState.attempts >= state.budgetCaps.maxRetries;\n if (subState.verificationResult?.passed === false && exhaustedAttempts) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, sub.id, subState.lastError || 'max retries exceeded (deadlock recovery)');\n // failSubtask mutates the cached goalsCache in place, so our\n // `goal` reference (passed by the caller, loaded from the\n // same cache) now reflects status: 'failed'. Belt-and-braces:\n // also update our local object in case the cache was bypassed.\n sub.status = 'failed';\n } catch { /* ok — driver will re-try next tick */ }\n continue;\n }\n // Respect dependsOn: skip subtasks whose prerequisites are not completed\n const depsSatisfied = (sub.dependsOn ?? []).every(depId => {\n const dep = goal.subtasks?.find(s => s.id === depId);\n return dep?.status === 'done';\n });\n if (!depsSatisfied) continue;\n return sub;\n }\n return null;\n}\n\n/**\n * v6.1.0-alpha.32 — turn a goal title into a reasonable filename\n * stem the LLM can use as a default for write_file. Lowercase,\n * kebab-case, only alphanumerics + dashes, capped at 40 chars.\n * Example: \"Write a 3 page essay about Martin Luther King\" →\n * \"write-a-3-page-essay-about-martin-l\".\n */\nfunction slugForGoal(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40)\n || 'report';\n}\n\nasync function fileBlockedApproval(\n state: DriverState,\n goal: Goal,\n questions: string[],\n): Promise<void> {\n const primaryQuestion = questions[0] ?? state.blockedReason?.question ?? 'Specialist requires input';\n const blockKind = state.blockedReason?.kind ?? 'needs_info';\n\n // v6.0.3 — same-block-twice auto-cancel for daemon-spawned goals.\n // We do this BEFORE the throttle / approval-create path so a\n // recurring block on an autonomous goal collapses the loop instead\n // of throttling the surface signal.\n if (shouldAutoCancelOnRecurringBlock(state, goal, blockKind, primaryQuestion)) {\n const tagSummary = (goal.tags || []).slice(0, 4).join(',') || '(no tags)';\n logger.warn(\n COMPONENT,\n `Auto-cancelling daemon-spawned goal ${goal.id} (\"${goal.title.slice(0, 60)}\"): same block recurred within ${Math.round(SAME_BLOCK_TWICE_WINDOW_MS / 60000)}min [tags=${tagSummary}, kind=${blockKind}]`\n );\n state.phase = 'cancelled';\n state.blockedReason = undefined;\n state.userControls.cancelRequested = true;\n appendHistory(\n state,\n 'cancelled',\n `Auto-cancelled: daemon-spawned goal hit the same block (${blockKind}) twice within the recurrence window.`\n );\n try {\n // Goal model has no `cancelled` status — convention is to flip\n // to `failed` while the driver phase records `cancelled`. This\n // matches tickCancelled()'s own behavior.\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'failed' });\n } catch (err) {\n logger.warn(COMPONENT, `Could not flip goal ${goal.id} status after auto-cancel: ${(err as Error).message}`);\n }\n try { await onGoalBlocked(goal, state); } catch { /* ok */ }\n return;\n }\n\n // v4.10.0-local (Phase B): throttle to 1 per (goalId, driver_blocked) per 5 min\n try {\n const { shouldCreateApproval } = await import('./notificationThrottle.js');\n if (!shouldCreateApproval(goal.id, 'driver_blocked')) {\n logger.debug(COMPONENT, `Throttled duplicate driver_blocked approval for goal ${goal.id}`);\n // Still record SOMA feedback since we DID get blocked\n try { await onGoalBlocked(goal, state); } catch { /* ok */ }\n return;\n }\n } catch { /* if throttle module unavailable, fall through */ }\n try {\n const { createApproval } = await import('./commandPost.js');\n const subState = state.currentSubtaskId ? state.subtaskStates[state.currentSubtaskId] : undefined;\n const subtaskTitle = goal.subtasks?.find(s => s.id === state.currentSubtaskId)?.title;\n const approval = createApproval({\n type: 'custom',\n requestedBy: 'goal-driver',\n payload: {\n kind: 'driver_blocked',\n goalId: goal.id,\n goalTitle: goal.title,\n question: questions[0] ?? state.blockedReason?.question ?? 'Specialist requires input',\n allQuestions: questions,\n blockedPhase: state.phase,\n currentSubtaskId: state.currentSubtaskId,\n subtaskKind: subState?.kind,\n subtaskTitle,\n specialist: subState?.specialist,\n attempts: subState?.attempts,\n lastError: subState?.lastError,\n urgency: 'high',\n },\n linkedIssueIds: [],\n });\n if (approval?.id && state.blockedReason) {\n state.blockedReason.approvalId = approval.id;\n }\n // Broadcast via SSE if broadcaster exists (throttled separately)\n try {\n const { shouldBroadcast } = await import('./notificationThrottle.js');\n if (shouldBroadcast('driver:blocked', goal.id)) {\n const g = globalThis as unknown as { __titan_sse_broadcast?: (topic: string, payload: unknown) => void };\n if (typeof g.__titan_sse_broadcast === 'function') {\n g.__titan_sse_broadcast('driver:blocked', {\n goalId: goal.id,\n goalTitle: goal.title,\n question: questions[0] ?? 'Specialist requires input',\n approvalId: approval?.id,\n });\n }\n }\n } catch { /* ok */ }\n } catch (err) {\n logger.warn(COMPONENT, `Could not file blocked-on-human approval: ${(err as Error).message}`);\n }\n // SOMA feedback: small hunger bump + slight purpose stall (via metricGuard)\n try { await onGoalBlocked(goal, state); } catch { /* ok */ }\n}\n\n// ── Main tick loop ──────────────────────────────────────────────\n\nexport async function tickDriver(goalId: string): Promise<DriverPhase> {\n const { getGoal } = await import('./goals.js');\n const goal = getGoal(goalId);\n if (!goal) return 'failed';\n\n let state = loadState(goalId);\n if (!state) {\n state = freshDriverState(goal);\n saveState(state);\n }\n\n // Respect user controls\n if (state.userControls.cancelRequested) {\n state.phase = 'cancelled';\n await tickCancelled(goal, state);\n saveState(state);\n return 'cancelled';\n }\n if (state.userControls.paused) return state.phase;\n\n // Kill switch inherits automatically — toolRunner gates writes,\n // spawn_agent early-returns. Drivers don't need to re-check.\n\n try {\n switch (state.phase) {\n case 'planning': await tickPlanning(goal, state); break;\n case 'delegating': await tickDelegating(goal, state); break;\n case 'observing': await tickObserving(goal, state); break;\n case 'iterating': await tickIterating(goal, state); break;\n case 'verifying': await tickVerifying(goal, state); break;\n case 'reporting': await tickReporting(goal, state); break;\n case 'blocked': await tickBlocked(goal, state); break;\n case 'escalated': await tickEscalated(goal, state); break;\n case 'failed': await tickFailed(goal, state); break;\n case 'done':\n case 'cancelled':\n break;\n }\n } catch (err) {\n logger.warn(COMPONENT, `Tick for ${goalId} threw in phase=${state.phase}: ${(err as Error).message}`);\n appendHistory(state, state.phase, `Tick threw: ${(err as Error).message.slice(0, 120)}`);\n }\n\n saveState(state);\n return state.phase;\n}\n\n/**\n * Drive a goal synchronously to a terminal or waiting state. Ticks in a\n * loop with a small pause between ticks so observing/blocked states give\n * the event loop time to breathe. Returns when the driver is terminal\n * (done/failed/cancelled) or waiting on a human (blocked).\n */\nexport async function driveGoal(goalId: string, maxTicks = 200): Promise<DriverPhase> {\n let last: DriverPhase = 'planning';\n for (let i = 0; i < maxTicks; i++) {\n last = await tickDriver(goalId);\n if (last === 'done' || last === 'failed' || last === 'cancelled' || last === 'blocked' || last === 'escalated') break;\n // Mini-delay between ticks to let IO + timers run\n await new Promise(res => setTimeout(res, 50));\n }\n return last;\n}\n\n// ── External API ────────────────────────────────────────────────\n\nexport function getDriverState(goalId: string): DriverState | null {\n return loadState(goalId);\n}\n\nexport function listActiveDrivers(): DriverState[] {\n ensureStateDir();\n if (!existsSync(STATE_DIR)) return [];\n const out: DriverState[] = [];\n for (const file of readdirSync(STATE_DIR)) {\n if (!file.endsWith('.json')) continue;\n const goalId = file.slice(0, -5);\n const s = loadState(goalId);\n if (s && s.phase !== 'done' && s.phase !== 'failed' && s.phase !== 'cancelled') out.push(s);\n }\n return out;\n}\n\nexport function listAllDrivers(): DriverState[] {\n ensureStateDir();\n if (!existsSync(STATE_DIR)) return [];\n const out: DriverState[] = [];\n for (const file of readdirSync(STATE_DIR)) {\n if (!file.endsWith('.json')) continue;\n const goalId = file.slice(0, -5);\n const s = loadState(goalId);\n if (s) out.push(s);\n }\n return out;\n}\n\nexport function pauseDriver(goalId: string): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.paused = true;\n saveState(s);\n return true;\n}\n\nexport function resumeDriverControl(goalId: string): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.paused = false;\n saveState(s);\n return true;\n}\n\n/**\n * Force a blocked driver back to iterating. Used when the block was\n * triggered by a machine-level failure (parse error, model glitch)\n * rather than a genuine human-answerable question, and the underlying\n * issue has been fixed (e.g. model swap).\n *\n * Also auto-rejects any pending approval the driver was blocked on so\n * it doesn't clutter the Approvals UI forever.\n */\nexport async function forceUnblockDriver(goalId: string, note = 'auto-unblock'): Promise<boolean> {\n const s = loadState(goalId);\n if (!s) return false;\n if (s.phase !== 'blocked') return false;\n\n // Auto-reject the bogus approval if one exists\n const approvalId = s.blockedReason?.approvalId;\n if (approvalId) {\n try {\n const { rejectApproval } = await import('./commandPost.js');\n rejectApproval(approvalId, 'force-unblock', `Auto-rejected by force-unblock: ${note}`);\n } catch { /* ok — approval might not exist anymore */ }\n }\n\n // If the block was budget-related, halve the retry counter so the\n // driver has headroom to retry with the underlying fix in place.\n // This is preferable to a full reset — it still records that the\n // goal has been difficult, just gives it another shot.\n const wasBudget = s.blockedReason?.kind === 'budget_exceeded'\n || /budget.*exceed|retries exceed/i.test(s.blockedReason?.question || '');\n if (wasBudget) {\n s.budget.totalRetries = Math.floor(s.budget.totalRetries / 2);\n appendHistory(s, 'iterating', `Force-unblock: budget halved (${s.budget.totalRetries} / ${s.budgetCaps.maxRetries} retries)`);\n }\n\n // v4.10.0-local (post-deploy, Fix F): also halve the per-subtask\n // attempt counter for the current subtask. Otherwise the subtask\n // re-hits its per-subtask cap immediately on resume (from Fix B)\n // and we just re-enter the blocked state next tick.\n const currentId = s.currentSubtaskId;\n if (currentId && s.subtaskStates[currentId]) {\n const sub = s.subtaskStates[currentId];\n const before = sub.attempts;\n sub.attempts = Math.floor(sub.attempts / 2);\n sub.consecutiveIdenticalErrors = 0; // reset stall detector too\n appendHistory(s, 'iterating', `Force-unblock: per-subtask attempts halved on ${currentId} (${before} → ${sub.attempts})`);\n }\n\n s.blockedReason = undefined;\n s.phase = 'iterating'; // iterating retries the current subtask with a fresh spawn\n appendHistory(s, 'iterating', `Force-unblocked: ${note}`);\n saveState(s);\n logger.info(COMPONENT, `Force-unblocked driver ${goalId}: ${note}${wasBudget ? ' (budget halved)' : ''}`);\n return true;\n}\n\nexport function cancelDriver(goalId: string): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.cancelRequested = true;\n saveState(s);\n return true;\n}\n\n/**\n * Permanently remove a driver state file. Used by `resumeDriversAfterRestart`\n * to reap drivers whose goal no longer exists, and by the boot-time stale\n * sweep to cull drivers that haven't ticked in a long time.\n *\n * v5.5.31+. Before this, `cancelDriver` only flipped a `cancelRequested`\n * flag without deleting — meaning orphan driver files (e.g. tests pointing\n * at deleted goals) accumulated forever and the scheduler could re-tick\n * them. Audit 2026-05-08 found `mtime-cache-test.json` actively ticking\n * for 14h+ after the test that created it had finished.\n */\nexport function deleteDriverState(goalId: string): boolean {\n const path = statePath(goalId);\n if (!existsSync(path)) return false;\n try { rmSync(path, { force: true }); return true; }\n catch (err) { logger.warn(COMPONENT, `deleteDriverState ${goalId}: ${(err as Error).message}`); return false; }\n}\n\n/**\n * Sweep stale driver-state files. Returns count + ids of removed files.\n * A driver is considered stale if its `lastTickAt` is older than `maxAgeMs`\n * (default 24h). Called on gateway boot via `resumeDriversAfterRestart`.\n *\n * The audit found 5 driver-state files at 395+ hours old (16-17 days)\n * that resumeDriversAfterRestart kept \"cancelling\" via the flag but never\n * actually removing.\n */\nexport function sweepStaleDriverStates(maxAgeMs = 24 * 60 * 60 * 1000): { removed: number; ids: string[] } {\n ensureStateDir();\n const removed: string[] = [];\n const cutoff = Date.now() - maxAgeMs;\n try {\n const entries = readdirSync(STATE_DIR);\n for (const name of entries) {\n if (!name.endsWith('.json')) continue;\n const goalId = name.replace(/\\.json$/, '');\n const s = loadState(goalId);\n if (!s) continue;\n const lastTickMs = new Date(s.lastTickAt || s.startedAt).getTime();\n if (Number.isFinite(lastTickMs) && lastTickMs < cutoff) {\n if (deleteDriverState(goalId)) removed.push(goalId);\n }\n }\n } catch (err) {\n logger.warn(COMPONENT, `sweepStaleDriverStates: ${(err as Error).message}`);\n }\n return { removed: removed.length, ids: removed };\n}\n\nexport function reprioritizeDriver(goalId: string, priority: 1 | 2 | 3 | 4 | 5): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.priority = priority;\n saveState(s);\n return true;\n}\n\nexport function _resetDriverStateForTests(goalId?: string): void {\n if (goalId) {\n try { rmSync(statePath(goalId), { force: true }); } catch { /* ok */ }\n } else {\n try { rmSync(STATE_DIR, { recursive: true, force: true }); } catch { /* ok */ }\n }\n}\n"],"mappings":"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","names":["subState"]}
1
+ {"version":3,"sources":["../../src/agent/goalDriver.ts"],"sourcesContent":["/**\n * TITAN — Goal Driver (v4.10.0-local, Phase A)\n *\n * Owns a goal from \"active\" to terminal (done | failed | cancelled).\n * Replaces the passive \"initiative picks one subtask per 5-min tick\"\n * model with an active phase state machine that drives subtasks through\n * specialists, verifies each one, retries on failure via fallbackChain,\n * and reports outcomes back to SOMA.\n *\n * Design principles:\n * - State is persisted to ~/.titan/driver-state/<goalId>.json after\n * every phase transition. Restart-safe.\n * - One tick = one phase transition. Scheduler loops ticks until the\n * driver reaches a terminal phase OR requires waiting (observing a\n * spawned specialist, or blocked on human).\n * - Every phase's state transition is logged to driver state history\n * for UI replay + debugging.\n * - Kill-switch / scope-lock / staging are handled by toolRunner —\n * the driver inherits that protection automatically.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, rmSync, renameSync } from 'fs';\nimport { join, dirname } from 'path';\nimport logger from '../utils/logger.js';\nimport { TITAN_HOME } from '../utils/constants.js';\nimport type {\n DriverPhase, DriverState, DriverSubtaskState, DriverHistoryEvent,\n} from './goalDriverTypes.js';\nimport type { SubtaskKind } from './subtaskTaxonomy.js';\nimport { classifyAll } from './subtaskTaxonomy.js';\nimport { routeForKind, pickAttempt } from './specialistRouter.js';\nimport { nextFallback } from './fallbackChain.js';\nimport { DEFAULT_BUDGET_CAPS, checkBudget, suggestDegradation, recordSpend } from './budgetEnforcer.js';\nimport { structuredSpawn } from './structuredSpawn.js';\nimport { verifyByKind } from './verifier.js';\nimport { isGenericQuestion, forceCommitDirective } from './questionQuality.js';\nimport { verificationEventsSince } from './verification.js';\nimport { onGoalCompleted, onGoalFailed, onGoalBlocked } from './somaFeedback.js';\nimport type { Goal, Subtask } from './goals.js';\nimport { emitAgentEvent } from './agentEvents.js';\n\nconst COMPONENT = 'GoalDriver';\nconst STATE_DIR = join(TITAN_HOME, 'driver-state');\n\n// ── Storage ──────────────────────────────────────────────────────\n\nfunction ensureStateDir(): void {\n try { mkdirSync(STATE_DIR, { recursive: true }); } catch { /* ok */ }\n}\n\nfunction statePath(goalId: string): string {\n return join(STATE_DIR, `${goalId}.json`);\n}\n\nfunction loadState(goalId: string): DriverState | null {\n const path = statePath(goalId);\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf-8')) as DriverState;\n if (parsed.schemaVersion !== 1) {\n logger.warn(COMPONENT, `State for ${goalId} has unknown schemaVersion=${parsed.schemaVersion} — ignoring`);\n return null;\n }\n return parsed;\n } catch (err) {\n logger.warn(COMPONENT, `Could not parse state for ${goalId}: ${(err as Error).message}`);\n return null;\n }\n}\n\nfunction saveState(state: DriverState): void {\n ensureStateDir();\n state.lastTickAt = new Date().toISOString();\n const path = statePath(state.goalId);\n try {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path + '.tmp', JSON.stringify(state, null, 2));\n // Atomic rename so partial writes never surface\n // (Windows rename-over-existing is OK on Node 22+)\n renameSync(path + '.tmp', path);\n } catch (err) {\n logger.warn(COMPONENT, `Could not persist state for ${state.goalId}: ${(err as Error).message}`);\n }\n}\n\nfunction appendHistory(state: DriverState, phase: DriverPhase, note: string): void {\n const event: DriverHistoryEvent = { at: new Date().toISOString(), phase, note };\n state.history.push(event);\n if (state.history.length > 200) state.history = state.history.slice(-200);\n}\n\n// v6.0.3 — Approval-guidance composer. Distinguishes between a generic\n// \"yes proceed\" click vs real textual guidance, and synthesizes the right\n// follow-up directive for the specialist's next attempt.\n//\n// Generic markers (after trim + lowercase): \"approved\", \"approve\", \"ok\",\n// \"yes\", \"y\", \"go\", \"proceed\", \"do it\", \"lgtm\" — these mean \"go ahead,\n// make your best call.\" Real guidance is anything else >8 chars.\n//\n// Exported for the unit tests.\nconst GENERIC_APPROVAL_NOTES = new Set([\n 'approved', 'approve', 'ok', 'okay', 'yes', 'y', 'go', 'proceed',\n 'do it', 'lgtm', 'sure', 'fine', 'continue', 'yeah', 'yep',\n]);\n\nexport function composeApprovalGuidance(rawNote: string | undefined | null): string {\n const note = (rawNote ?? '').trim();\n const isGeneric = note === '' || note.length <= 8 || GENERIC_APPROVAL_NOTES.has(note.toLowerCase());\n if (isGeneric) {\n return [\n 'The user approved this subtask to proceed but did NOT provide additional textual guidance.',\n 'Interpretation: \"go ahead with your best-effort interpretation of the original task.\"',\n 'Do NOT re-ask the same question that caused the block — pick a reasonable assumption from',\n 'the available context and proceed. If you genuinely cannot make a reasonable assumption,',\n 'complete what you can and report what was unresolved in your reply rather than blocking again.',\n ].join(' ');\n }\n // Real textual guidance — pass it through as before, but reframe so\n // the specialist knows it is the user's explicit answer (not a prior\n // attempt's reasoning).\n return `The user's answer to the question that caused the previous block is: \"${note}\". Use this as authoritative guidance for the next attempt.`;\n}\n\n// ── Daemon-spawned auto-cancel guard (v6.0.3) ────────────────────\n//\n// When an autonomous producer (Soma pressure cycle, dreaming proposer,\n// self-repair daemon, autopilot, mission auto-decomposer) spins up a\n// goal and the goal hits the SAME blocking question twice within an\n// hour, we cancel it rather than file another approval. Rationale: the\n// question is structurally unanswerable by the specialist — re-asking\n// doesn't fix that, it just fills Tony's approval queue. A human-\n// authored goal stays in the queue forever (Tony will answer when he's\n// ready); only daemon goals get this auto-cancel.\n//\n// Detection is by tag — Goal has no `requestedBy` field, so we check\n// the canonical autonomous-tag set the producers attach.\n\nconst DAEMON_SPAWN_TAG_MARKERS = [\n /^soma:/i,\n /^autopilot/i,\n /^mission-auto$/i,\n /^self-repair$/i,\n /^self-mod$/i,\n /^self-healing$/i,\n /^self-modification$/i,\n /^canary-eval$/i,\n /^dreaming$/i,\n /^pressure$/i,\n];\n\n/** True if any of the goal's tags suggest an autonomous producer made it. */\nexport function isDaemonSpawnedGoal(goal: { tags?: string[] }): boolean {\n const tags = goal.tags ?? [];\n for (const t of tags) {\n for (const re of DAEMON_SPAWN_TAG_MARKERS) {\n if (re.test(t)) return true;\n }\n }\n return false;\n}\n\n/**\n * Normalize a blocking question into a stable fingerprint so trivial\n * formatting variations (whitespace, the rolling \"attempt N\" counter,\n * timestamp echoes) don't defeat the same-block-twice check.\n */\nexport function fingerprintBlockedQuestion(q: string): string {\n return q\n .toLowerCase()\n // Strip rolling counters / numbers / timestamps\n .replace(/attempt\\s*\\d+/g, 'attempt N')\n .replace(/\\b\\d{4}-\\d{2}-\\d{2}t[\\d:.]+z?\\b/g, '')\n .replace(/\\b\\d+(\\.\\d+)?\\b/g, 'N')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, 120);\n}\n\n/** Configurable in tests via the optional override; default 1h. */\nexport const SAME_BLOCK_TWICE_WINDOW_MS = 60 * 60 * 1000;\n\n/**\n * Check whether the next-block-to-be-filed is a recurrence of an\n * earlier one within the daemon-auto-cancel window. Mutates `state`\n * to append the new fingerprint regardless (so the next call can\n * still see it).\n *\n * Returns true if the goal should be auto-cancelled.\n */\nexport function shouldAutoCancelOnRecurringBlock(\n state: DriverState,\n goal: { tags?: string[] },\n blockKind: string,\n question: string,\n windowMs: number = SAME_BLOCK_TWICE_WINDOW_MS,\n): boolean {\n if (!isDaemonSpawnedGoal(goal)) {\n return false;\n }\n const fp = fingerprintBlockedQuestion(question);\n const now = Date.now();\n const history = state.blockHistory ?? [];\n const cutoff = now - windowMs;\n // Look for ANY prior block whose fingerprint matches and is within the window.\n const recurrence = history.find(ev => {\n if (ev.fingerprint !== fp) return false;\n const t = Date.parse(ev.at);\n return Number.isFinite(t) && t >= cutoff;\n });\n // Always record the new event (bounded to last 16 entries).\n const next: typeof history = [...history, { at: new Date(now).toISOString(), fingerprint: fp, kind: blockKind }];\n state.blockHistory = next.slice(-16);\n return !!recurrence;\n}\n\n// ── Infrastructure failure detection ──────────────────────────────\n\n/**\n * Detect systematic infrastructure failures that warrant human escalation.\n * Returns true if the error indicates all specialists are failing to produce\n * structured JSON output (thinking patterns, parse errors).\n */\nfunction isInfrastructureFailure(error: string | undefined): boolean {\n if (!error) return false;\n const e = error.toLowerCase();\n // JSON parse failures from structuredSpawn\n const parseFailurePatterns = [\n 'parser could not extract json',\n 'no json block found',\n 'json.parse failure',\n 'prose-fallback:thinking',\n 'thinking prose instead of structured json',\n ];\n return parseFailurePatterns.some(p => e.includes(p));\n}\n\n// ── Init / creation ──────────────────────────────────────────────\n\nfunction freshDriverState(goal: Goal): DriverState {\n const subtaskStates: Record<string, DriverSubtaskState> = {};\n const kinds = classifyAll(goal.subtasks || []);\n for (const sub of goal.subtasks || []) {\n subtaskStates[sub.id] = {\n kind: kinds[sub.id] ?? 'analysis',\n attempts: 0,\n // v4.10.0-local (post-deploy): 5 = full ladder depth\n // (primary + 4 fallbacks). Ensures the claude-code MAX-plan\n // tier is reachable before the subtask gives up. Goal-level\n // maxRetries: 10 remains as the cross-subtask backstop.\n maxAttempts: 5,\n artifacts: [],\n };\n }\n const now = new Date().toISOString();\n return {\n schemaVersion: 1,\n goalId: goal.id,\n phase: 'planning',\n startedAt: now,\n lastTickAt: now,\n budget: { tokensUsed: 0, costUsd: 0, elapsedMs: 0, totalRetries: 0 },\n budgetCaps: { ...DEFAULT_BUDGET_CAPS },\n userControls: {\n paused: false,\n cancelRequested: false,\n priority: (goal.priority as 1 | 2 | 3 | 4 | 5) ?? 3,\n },\n subtaskStates,\n history: [{ at: now, phase: 'planning', note: `Driver started for \"${goal.title}\"` }],\n };\n}\n\n// ── Phase transitions (one tick = one transition) ───────────────\n\nasync function tickPlanning(goal: Goal, state: DriverState): Promise<void> {\n // Ensure subtasks exist (the proposer usually creates them; if a goal\n // came without any, we classify based on title and create a single\n // `analysis` subtask as a placeholder).\n if (!goal.subtasks || goal.subtasks.length === 0) {\n appendHistory(state, 'planning', 'No subtasks — creating single analysis subtask from title');\n try {\n const { addSubtask } = await import('./goals.js');\n addSubtask(goal.id, goal.title, goal.description);\n } catch (err) {\n logger.warn(COMPONENT, `Could not add default subtask to ${goal.id}: ${(err as Error).message}`);\n }\n }\n\n // v4.10.0-local (post-deploy, Fix 9): classify lazily and persist\n // once. Previously this called classifyAll unconditionally on every\n // planning pass, but only persisted new entries — if taxonomy rules\n // changed between boots, restored drivers kept their stale kinds\n // silently. Only classify when we actually need to create a new\n // subtask state entry.\n let kinds: Record<string, ReturnType<typeof classifyAll>[string]> | null = null;\n for (const sub of goal.subtasks || []) {\n if (!state.subtaskStates[sub.id]) {\n if (!kinds) kinds = classifyAll(goal.subtasks || []);\n state.subtaskStates[sub.id] = {\n kind: kinds[sub.id] ?? 'analysis',\n attempts: 0,\n maxAttempts: 5, // per Fix B — matches ladder depth\n artifacts: [],\n };\n }\n }\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Planned: ${Object.keys(state.subtaskStates).length} subtasks classified`);\n}\n\n/**\n * v6.3.0 — max number of subtasks dispatched in parallel by tryBurstDispatch.\n * Capped to keep LLM provider rate limits + Soma drives sane. The mirrors\n * `agent_team`'s own 6-agent cap with a slight haircut for goal-driver\n * overhead.\n */\nconst MAX_BURST_PARALLEL = 4;\n\n/**\n * v6.3.0 — burst dispatch. If 2+ subtasks are ready in this tick, fire\n * them via Promise.all and process the results in-place. Returns\n * 'handled' when a burst ran (caller returns immediately), 'fallthrough'\n * when only 0 or 1 subtasks were ready (caller continues with the\n * existing single-subtask path).\n *\n * Design notes:\n * - Each subtask's attempts/spec/state-mutation mirrors the single\n * path, so on the next tick the single-subtask path can recover any\n * subtask whose burst result wasn't a clean 'done'.\n * - We only mark subtasks 'done' in storage on a happy-path result.\n * Anything else (failed/needs_info/blocked) keeps the subtask in\n * 'pending', and the next tick re-enters via single-subtask flow\n * with all the accreted edge-case guards (commit_override, dedupe,\n * generic_question, etc.) still applying.\n * - We do NOT transition phase to 'verifying' from a burst even if\n * all succeeded — that's the existing single-path's job on the\n * subsequent tick when pickNextReadySubtask returns null. Burst's\n * only commitment is \"spend less wall-clock when work is parallel\".\n */\nasync function tryBurstDispatch(goal: Goal, state: DriverState): Promise<'handled' | 'fallthrough'> {\n const ready = await pickAllReadySubtasks(goal, state, MAX_BURST_PARALLEL);\n if (ready.length < 2) return 'fallthrough';\n\n // Validate each subtask: attempt cap + fallback strategy. If any\n // would fail validation, drop it from the burst (single-path will\n // handle the per-subtask failure deterministically next tick).\n type Validated = {\n subtask: Subtask;\n subState: DriverSubtaskState;\n strategy: ReturnType<typeof nextFallback>;\n };\n const validated: Validated[] = [];\n for (const sub of ready) {\n const subState = state.subtaskStates[sub.id];\n if (!subState) continue;\n const cap = subState.maxAttempts ?? 5;\n if (subState.attempts + 1 > cap) continue; // single-path will fast-fail it\n const strategy = nextFallback(subState.kind, subState.attempts, subState.lastError, cap);\n if (!strategy) continue; // exhausted; single-path will resolve\n validated.push({ subtask: sub, subState, strategy });\n }\n\n if (validated.length < 2) return 'fallthrough';\n\n // Mark the batch + per-subtask state BEFORE dispatch. If anything\n // throws in Promise.all, the state still reflects the attempt.\n const batchStartedAt = new Date().toISOString();\n state.parallelBatch = {\n ids: validated.map(v => v.subtask.id),\n startedAt: batchStartedAt,\n };\n for (const v of validated) {\n v.subState.attempts += 1;\n v.subState.specialist = v.strategy!.specialist;\n v.subState.pendingSpawn = {\n attemptedAt: batchStartedAt,\n specialist: v.strategy!.specialist,\n };\n try {\n emitAgentEvent({\n type: 'agent_spawn',\n agentId: v.strategy!.specialist,\n agentName: v.strategy!.specialist,\n timestamp: Date.now(),\n data: {\n goalId: goal.id,\n subtaskId: v.subtask.id,\n subtaskTitle: v.subtask.title,\n subtaskKind: v.subState.kind,\n attempt: v.subState.attempts,\n burst: true,\n burstSize: validated.length,\n },\n });\n } catch { /* event bus failure should never block a spawn */ }\n }\n appendHistory(\n state,\n 'observing',\n `Burst dispatch: ${validated.length} subtasks in parallel (${validated.map(v => v.subtask.title.slice(0, 32)).join(' | ')})`,\n );\n state.phase = 'observing';\n\n // Fire them all. Promise.allSettled so one rejection doesn't lose\n // the others' results.\n const burstStartMs = Date.now();\n const settled = await Promise.allSettled(\n validated.map(v => structuredSpawn({\n specialistId: v.strategy!.specialist,\n task: `${v.subtask.title}\\n\\n${v.subtask.description}${v.strategy!.promptAdjustment ?? ''}`,\n modelOverride: v.strategy!.modelOverride,\n toolAllowlist: routeForKind(v.subState.kind).toolAllowlist,\n maxRounds: v.strategy!.maxRounds,\n goalId: goal.id,\n })),\n );\n const burstDurationMs = Date.now() - burstStartMs;\n\n // Process each result. Record telemetry, store artifacts, and ONLY\n // mark a subtask 'done' on the happy path. Everything else (failed,\n // needs_info, blocked, thrown) is left pending so the next tick\n // re-enters single-path with the full edge-case guard stack.\n let happyCount = 0;\n for (let i = 0; i < validated.length; i++) {\n const v = validated[i];\n const outcome = settled[i];\n v.subState.pendingSpawn = undefined;\n if (outcome.status === 'rejected') {\n v.subState.lastError = (outcome.reason as Error)?.message ?? String(outcome.reason);\n appendHistory(state, 'iterating', `Burst spawn threw for ${v.subtask.id}: ${v.subState.lastError.slice(0, 100)}`);\n continue;\n }\n const result = outcome.value;\n recordSpend(state, {\n elapsedMs: burstDurationMs / validated.length, // amortized; the wall-clock saving is the point\n tokens: result.tokensUsed ?? 0,\n costUsd: result.costUsd ?? 0,\n });\n v.subState.artifacts = [...new Set([\n ...v.subState.artifacts,\n ...result.artifacts.map(a => a.ref),\n ])];\n try {\n emitAgentEvent({\n type: 'agent_done',\n agentId: v.strategy!.specialist,\n agentName: v.strategy!.specialist,\n timestamp: Date.now(),\n data: {\n goalId: goal.id,\n subtaskId: v.subtask.id,\n subtaskTitle: v.subtask.title,\n status: result.status,\n reasoning: result.reasoning,\n artifactCount: result.artifacts.length,\n artifacts: result.artifacts.map(a => ({ ref: a.ref, type: a.type })),\n toolsUsed: result.toolsUsed ?? [],\n tokensUsed: result.tokensUsed ?? 0,\n costUsd: result.costUsd ?? 0,\n durationMs: burstDurationMs,\n model: v.strategy!.modelOverride ?? v.strategy!.specialist,\n burst: true,\n },\n });\n } catch { /* event bus failure never affects driver state */ }\n\n if (result.status === 'done') {\n v.subState.consecutiveNeedsInfoCount = 0;\n // Stash spawn result so the eventual single-path verify reads it.\n (v.subState as DriverSubtaskState & { lastSpawnResult?: unknown }).lastSpawnResult = result;\n // Mark the subtask 'done' in goals storage. Subsequent ticks\n // see this and skip it via pickAllReadySubtasks's status check.\n try {\n const { completeSubtask } = await import('./goals.js');\n completeSubtask(goal.id, v.subtask.id, result.reasoning || 'completed via burst');\n } catch (err) {\n // If completion fails to persist, treat as non-happy so single-path can retry.\n v.subState.lastError = `Burst completion persist failed: ${(err as Error).message}`;\n continue;\n }\n happyCount++;\n } else if (result.status === 'failed') {\n v.subState.lastError = result.reasoning || 'failed';\n v.subState.consecutiveNeedsInfoCount = 0; // mirrors single-path reset semantics\n } else {\n // needs_info / blocked / anything else — leave pending so\n // single-path picks it up next tick with the full guard stack.\n v.subState.lastError = result.reasoning || `Burst returned ${result.status}; deferring to single-path retry.`;\n }\n }\n\n state.parallelBatch = undefined;\n appendHistory(\n state,\n 'delegating',\n `Burst complete: ${happyCount}/${validated.length} succeeded in ${burstDurationMs}ms (parallel)`,\n );\n state.phase = 'delegating';\n return 'handled';\n}\n\nasync function tickDelegating(goal: Goal, state: DriverState): Promise<void> {\n // v6.3.0 — burst dispatch path. When the planner emits multiple\n // genuinely-independent subtasks (no dependsOn between them), fire\n // them in parallel via Promise.all instead of one-per-tick.\n //\n // Safety design:\n // - If only 1 subtask is ready, fall straight through to the proven\n // single-subtask path below. Zero risk to the existing state\n // machine.\n // - In burst mode we ONLY handle the all-success happy path. Any\n // non-success result (failed / needs_info / blocked) means we\n // persist the subState delta and let the next tick re-enter via\n // the single-subtask path, which has all the accreted edge-case\n // guards (commit_override, dedupe, generic_question, etc.). So\n // the burst is purely a \"fast path when everything goes right\"\n // overlay; weird cases still get the full state-machine treatment.\n if (!state.parallelBatch) {\n const burst = await tryBurstDispatch(goal, state);\n if (burst === 'handled') return;\n }\n\n // Find the next ready subtask (dependencies satisfied, not already done/failed)\n const next = await pickNextReadySubtask(goal, state);\n if (!next) {\n // Re-fetch goal so the allResolved check sees any subtasks that\n // pickNextReadySubtask just marked as failed (durable deadlock\n // recovery from Fix C). Falls back to the stale reference on\n // import failure — worst case we deadlock once more and recover\n // next tick.\n let freshGoal: Goal = goal;\n try {\n const { getGoal } = await import('./goals.js');\n freshGoal = getGoal(goal.id) || goal;\n } catch { /* ok */ }\n // No more ready subtasks — either all done or all blocked on deps.\n // Check if everything's done or failed:\n const allResolved = (freshGoal.subtasks || []).every(\n s => s.status === 'done' || s.status === 'failed' || s.status === 'skipped',\n );\n if (allResolved) {\n // v4.10.0-local (post-deploy): clear currentSubtaskId so\n // tickVerifying takes the whole-goal-verify branch\n // (line 316). Otherwise it keeps trying to verify the\n // last-touched subtask (which may be stale or terminal)\n // and oscillates verifying → iterating → delegating.\n state.currentSubtaskId = undefined;\n state.phase = 'verifying';\n appendHistory(state, 'verifying', 'All subtasks resolved — running final verification');\n } else {\n // Dependencies blocking — pause-block for human\n state.phase = 'blocked';\n state.blockedReason = {\n question: `Goal \"${goal.title}\" is deadlocked. All pending subtasks have unresolved dependencies and none are ready to run. Please review the subtask order and dependencies.`,\n approvalId: '', // filled below if we file an approval\n sinceAt: new Date().toISOString(),\n kind: 'dep_deadlock',\n };\n appendHistory(state, 'blocked', 'Dependency deadlock');\n }\n return;\n }\n\n state.currentSubtaskId = next.id;\n const subState = state.subtaskStates[next.id];\n subState.attempts += 1;\n\n // v4.10.0-local (post-deploy, Fix B): per-subtask attempt cap. A single\n // unlucky subtask can no longer consume the whole goal's retry budget.\n // We fail fast on THIS subtask and let the driver move to the next one.\n const cap = subState.maxAttempts ?? 5;\n if (subState.attempts > cap) {\n subState.verificationResult = {\n passed: false,\n reason: `Per-subtask cap exceeded (${cap})`,\n verifier: 'budget',\n };\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, subState.lastError || `per-subtask cap exceeded (${cap} attempts)`);\n } catch { /* ok */ }\n state.currentSubtaskId = undefined;\n state.phase = 'delegating'; // next tick picks up the next ready subtask\n appendHistory(state, 'delegating', `Subtask ${next.id} exceeded per-subtask cap (${cap}) — moved on`);\n return;\n }\n\n // Pass the per-subtask cap — NOT goal-level maxRetries — to\n // nextFallback. The ladder has 5 tiers; matching means we can reach\n // the final (claude-code MAX) tier before declaring exhaustion.\n const strategy = nextFallback(subState.kind, subState.attempts - 1, subState.lastError, cap);\n if (!strategy) {\n // v4.10.0-local fix: Check if exhaustion is due to infrastructure failure\n // (systematic JSON parse errors). If so, escalate to human instead of\n // silently failing the subtask.\n if (isInfrastructureFailure(subState.lastError)) {\n state.phase = 'escalated';\n state.blockedReason = {\n question: `Goal \"${goal.title}\" — all specialists failed to produce valid output after ${goal.subtasks?.length ?? 0} subtask(s). This usually means the model is misconfigured, the task is too vague, or the specialist doesn't have the right tools. Please review the goal description or switch the model tier.`,\n approvalId: '',\n sinceAt: new Date().toISOString(),\n kind: 'infrastructure_failure',\n };\n appendHistory(state, 'escalated', `Subtask ${next.id}: infrastructure failure — all specialists failed JSON output`);\n await fileBlockedApproval(state, goal, [state.blockedReason.question]);\n return;\n }\n\n // Exhausted retries for this subtask (normal failure)\n subState.verificationResult = {\n passed: false,\n reason: 'Max retries exhausted',\n verifier: 'budget',\n };\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, 'max-retries-exhausted');\n } catch { /* ok */ }\n state.currentSubtaskId = undefined;\n state.phase = 'delegating'; // try next subtask\n appendHistory(state, 'delegating', `Subtask ${next.id} exhausted retries — moved on`);\n return;\n }\n\n subState.specialist = strategy.specialist;\n subState.pendingSpawn = {\n attemptedAt: new Date().toISOString(),\n specialist: strategy.specialist,\n };\n state.phase = 'observing';\n appendHistory(\n state,\n 'observing',\n `Spawning ${strategy.specialist} for subtask \"${next.title}\" (kind=${subState.kind}, attempt ${subState.attempts})`,\n );\n\n // v6.1.0-alpha.1 — emit a structured \"agent_spawn\" event on the shared\n // bus so listeners (Mission Chat lifecycle bridge, the SSE dashboard\n // tail, the Agent Watcher) know who's starting on what. Includes the\n // goalId so listeners can correlate without having to peer-into driver\n // state.\n try {\n emitAgentEvent({\n type: 'agent_spawn',\n agentId: strategy.specialist,\n agentName: strategy.specialist,\n timestamp: Date.now(),\n data: {\n goalId: goal.id,\n subtaskId: next.id,\n subtaskTitle: next.title,\n subtaskKind: subState.kind,\n attempt: subState.attempts,\n },\n });\n } catch { /* event bus failure should never block a spawn */ }\n\n // Actually fire the spawn — runs in-tick, driver waits for the return.\n // (Future: async wakeup path so driver can observe multiple concurrent\n // spawns; for now one at a time per goal.)\n try {\n const startMs = Date.now();\n // v6.1.0-alpha.32 — if the goal looks like a document deliverable,\n // prepend a hard FORMAT directive to the task description. Belt\n // and suspenders with the specialist system prompt's HTML_REPORT_\n // GUIDANCE: even strong system-prompt rules can be drowned by a\n // long context, but a directive at the top of the per-task user\n // message is the LAST thing the LLM sees before producing output.\n const baseTask = `${next.title}\\n\\n${next.description}${strategy.promptAdjustment ?? ''}`;\n const documentLike = /\\b(essay|report|briefing|writeup|write-up|summary|article|document|memo|paper|analysis|whitepaper|brief)\\b/i.test(goal.title)\n || /\\b(essay|report|briefing|writeup|summary|article)\\b/i.test(next.title);\n const taskWithFormat = documentLike\n ? `OUTPUT FORMAT — REQUIRED:\\nThe user wants a real document they can view with images, charts, and styling. You MUST deliver this as a single self-contained .html file (write_file with a path ending in .html, e.g. \"${slugForGoal(goal.title)}.html\"). Do NOT write .md or .markdown — those can't show images or charts. See the OUTPUT FORMAT FOR DOCUMENTS section of your system prompt for the structure.\\n\\n──────────\\n\\n${baseTask}`\n : baseTask;\n const result = await structuredSpawn({\n specialistId: strategy.specialist,\n task: taskWithFormat,\n modelOverride: strategy.modelOverride,\n toolAllowlist: routeForKind(subState.kind).toolAllowlist,\n maxRounds: strategy.maxRounds,\n // v6.1.0-alpha.41 — thread goalId so subAgent's tool_call\n // events carry data.goalId and the lifecycle bridge can\n // correlate them back to the mission room.\n goalId: goal.id,\n });\n const durationMs = Date.now() - startMs;\n\n // v6.1.0-alpha.1 — emit the result on the agent bus too. The Mission\n // Chat bridge turns this into a chat message; the SSE dashboard tail\n // logs it for replay. We always emit, even on failed/needs_info\n // status, so the UI can show the specialist's reasoning regardless.\n try {\n emitAgentEvent({\n type: 'agent_done',\n agentId: strategy.specialist,\n agentName: strategy.specialist,\n timestamp: Date.now(),\n data: {\n goalId: goal.id,\n subtaskId: next.id,\n subtaskTitle: next.title,\n status: result.status,\n reasoning: result.reasoning,\n artifactCount: result.artifacts.length,\n artifacts: result.artifacts.map(a => ({ ref: a.ref, type: a.type })),\n toolsUsed: result.toolsUsed ?? [],\n tokensUsed: result.tokensUsed ?? 0,\n costUsd: result.costUsd ?? 0,\n durationMs,\n // v6.1.0-alpha.4 — include the resolved model so the\n // Mission Chat UI can show \"ran on X\" when the user\n // expands a bubble. Use modelOverride if set, otherwise\n // the specialist's id (UI maps id → friendly model name\n // via the registry when needed).\n model: strategy.modelOverride ?? strategy.specialist,\n },\n });\n } catch { /* event bus failure should never affect driver state */ }\n recordSpend(state, {\n elapsedMs: durationMs,\n tokens: result.tokensUsed ?? 0,\n costUsd: result.costUsd ?? 0,\n });\n\n // Store artifacts\n subState.artifacts = [...new Set([\n ...subState.artifacts,\n ...result.artifacts.map(a => a.ref),\n ])];\n\n // Decide phase based on spawn status\n if (result.status === 'done') {\n subState.consecutiveNeedsInfoCount = 0; // reset on non-needs_info\n\n // beta.10 — runtime assertion failure detector. Look at the\n // verification ring for events recorded during this spawn\n // window (between pendingSpawn.attemptedAt and now). If any\n // verifications failed AND none passed, increment the\n // assertion counter; if any passed, reset it. Threshold\n // 3 → fail the subtask with verify_fail block kind so we\n // don't loop forever on a spawn that keeps producing\n // artifacts that don't survive readback.\n try {\n const spawnStartMs = subState.pendingSpawn?.attemptedAt\n ? new Date(subState.pendingSpawn.attemptedAt).getTime()\n : Date.now() - durationMs;\n const events = verificationEventsSince(spawnStartMs);\n const failed = events.filter(e => !e.result.passed);\n const passed = events.filter(e => e.result.passed);\n if (failed.length > 0 && passed.length === 0) {\n subState.consecutiveAssertionFailures =\n (subState.consecutiveAssertionFailures ?? 0) + 1;\n const count = subState.consecutiveAssertionFailures;\n appendHistory(\n state,\n 'observing',\n `Spawn produced ${failed.length} verification failure(s) (counter=${count}): ${failed[0].result.reason.slice(0, 100)}`,\n );\n if (count >= 3) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(\n goal.id,\n next.id,\n `Subtask failed verification ${count}× in a row. Last failure: ${failed[0].result.reason.slice(0, 200)}. The specialist keeps producing artifacts that don't survive readback (byte-count drift, magic-header mismatch, partial write). Failing to break the loop.`,\n );\n } catch { /* ok */ }\n subState.lastError = `Failed: ${count} consecutive verification failures`;\n subState.pendingSpawn = undefined;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Verification stuck-loop fail on ${next.id} (${count}× failures)`);\n return;\n }\n } else if (passed.length > 0) {\n subState.consecutiveAssertionFailures = 0;\n }\n } catch { /* assertion counting never gates the happy path */ }\n\n state.phase = 'verifying';\n appendHistory(state, 'verifying', `Spawn returned done with ${result.artifacts.length} artifact(s), confidence ${result.confidence.toFixed(2)}`);\n // Stash the spawn result so verifying can read it\n (subState as DriverSubtaskState & { lastSpawnResult?: unknown }).lastSpawnResult = result;\n } else if (result.status === 'failed') {\n subState.lastError = result.reasoning || 'failed';\n subState.consecutiveNeedsInfoCount = 0; // reset on non-needs_info\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Spawn returned failed: ${subState.lastError.slice(0, 120)}`);\n } else if (result.status === 'needs_info' || result.status === 'blocked') {\n // v4.14.0: build a rich, contextual blocked reason instead of\n // the generic \"Specialist requires input\" that tells the user\n // nothing about what actually went wrong.\n const subtaskTitle = next.title || 'Unnamed subtask';\n const specialistName = strategy.specialist || subState.specialist || 'specialist';\n const attemptCount = subState.attempts;\n const lastErr = subState.lastError;\n const rawQuestion = result.questions[0] ?? '';\n\n // v6.1.0-beta.4 — defensive consecutive-needs_info counter.\n // Reproduces the mzzbajnj bug: a specialist returns\n // `needs_info` with EMPTY question string, the\n // genericQuestionRejected→fail path *should* terminate it on\n // attempt 2, but in practice the loop ran 17 minutes before\n // Tony cancelled. Belt-and-suspenders guard independent of\n // genericQuestionRejected/commitOverride/dedupe state: count\n // consecutive needs_info, force-fail at threshold regardless\n // of any other flag. This guarantees termination even if a\n // future refactor breaks one of the other guards.\n subState.consecutiveNeedsInfoCount = (subState.consecutiveNeedsInfoCount || 0) + 1;\n const trimmedQuestion = rawQuestion.trim();\n const needsInfoCount = subState.consecutiveNeedsInfoCount;\n // Empty/whitespace question + attempts >= 2 → fail\n // immediately. An empty needs_info on a retry is a sure\n // sign the specialist has nothing to say.\n if (trimmedQuestion.length === 0 && attemptCount >= 2) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Specialist ${specialistName} returned needs_info with an empty question on attempt ${attemptCount}. No actionable signal — failing subtask to break the loop.`);\n } catch { /* ok */ }\n subState.lastError = `Failed: empty needs_info on attempt ${attemptCount} (specialist ${specialistName})`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Empty needs_info fail on ${next.id} (attempt ${attemptCount})`);\n subState.pendingSpawn = undefined;\n return;\n }\n // Three consecutive needs_info on this subtask → fail\n // regardless of question content. Forward progress check.\n if (needsInfoCount >= 3) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Specialist ${specialistName} returned needs_info ${needsInfoCount}× in a row on this subtask. Forcing failure to break the loop. Last question: \"${trimmedQuestion.slice(0, 160)}\"`);\n } catch { /* ok */ }\n subState.lastError = `Failed: ${needsInfoCount} consecutive needs_info returns`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Consecutive needs_info fail on ${next.id} (${needsInfoCount}×)`);\n subState.pendingSpawn = undefined;\n return;\n }\n\n // v6.1.0-alpha.51 — commit-override short-circuit. If the\n // previous block was auto-rejected (15-min timeout) we set\n // commitOverride. The specialist had its one free re-try with\n // a \"commit, don't re-ask\" directive in lastError; if it STILL\n // came back with needs_info, the question is structurally\n // unanswerable from current context. File the subtask as\n // committed (best-effort done) rather than re-blocking — this\n // breaks the \"Auto-rejected... What should the specialist do\n // next?\" infinite ask loop Tony reported.\n if (subState.commitOverride) {\n subState.commitOverride = false; // one-shot\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Auto-committed after timeout: specialist still needs info but no human is available. Original question: \"${rawQuestion.slice(0, 160)}\"`);\n } catch { /* ok */ }\n subState.lastError = `Auto-committed after timeout. Last unresolved question: ${rawQuestion.slice(0, 160)}`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Commit-override applied on ${next.id} — no re-block after timeout`);\n subState.pendingSpawn = undefined;\n return;\n }\n\n // v6.1.0-alpha.51 — dedupe repeated questions. If the\n // specialist has already asked this same question (by\n // fingerprint) before on this subtask, don't file the\n // approval again. Convert to a forced commit instead so\n // the user isn't pestered with the same prompt 3 times.\n const rawFp = rawQuestion ? fingerprintBlockedQuestion(rawQuestion) : '';\n const askedBefore = !!rawFp && (subState.askedQuestionFingerprints || []).includes(rawFp);\n if (askedBefore) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Repeat-question dedupe: specialist asked the same question (\"${rawQuestion.slice(0, 120)}\") twice. Marking subtask failed to avoid pestering the human.`);\n } catch { /* ok */ }\n subState.lastError = `Repeat question detected — failed subtask. Last question: ${rawQuestion.slice(0, 160)}`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Repeat-question dedupe on ${next.id}`);\n subState.pendingSpawn = undefined;\n return;\n }\n if (rawFp) {\n subState.askedQuestionFingerprints = [\n ...(subState.askedQuestionFingerprints || []),\n rawFp,\n ].slice(-8);\n }\n\n // v6.1.0-alpha.54 — generic-question pre-pass. Tony asked\n // not to be pinged with low-info questions (\"What should\n // I focus on?\", \"Please clarify\", etc.). isGenericQuestion\n // classifies the rawQuestion; if generic AND we haven't\n // already rejected one for this subtask, we set\n // `lastError` to a forceCommitDirective and bounce back\n // to delegating — the specialist gets one free retry with\n // explicit \"commit your best interpretation OR consult a\n // teammate\" guidance. If the specialist STILL returns\n // generic on the retry, we fail the subtask rather than\n // burn Tony's attention. Specific questions (with a\n // decision marker, named option, year, URL, quoted name,\n // etc.) pass through to the existing approval flow.\n if (isGenericQuestion(rawQuestion)) {\n if (!subState.genericQuestionRejected) {\n subState.genericQuestionRejected = true;\n subState.lastError = forceCommitDirective(rawQuestion, goal.title);\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Generic question rejected — forcing commit retry on ${next.id}`);\n subState.pendingSpawn = undefined;\n return;\n }\n // Second generic question in a row → fail the subtask\n // instead of looping. Don't ship to Tony either way.\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, next.id, `Two generic questions in a row from ${specialistName}. Last: \"${rawQuestion.slice(0, 160)}\". The specialist couldn't commit on its own after a force-retry — marking subtask failed rather than escalating a low-info question to the human.`);\n } catch { /* ok */ }\n subState.lastError = `Failed after two generic questions. Last: ${rawQuestion.slice(0, 160)}`;\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Generic-question fail on ${next.id} after force-retry`);\n subState.pendingSpawn = undefined;\n return;\n }\n\n state.phase = 'blocked';\n let richQuestion: string;\n if (rawQuestion && rawQuestion.length > 10 && !rawQuestion.toLowerCase().includes('specialist requires')) {\n // The specialist gave a real question — use it but wrap with context\n richQuestion = `Goal \"${goal.title}\" is stuck on subtask \"${subtaskTitle}\" (attempt ${attemptCount}, specialist: ${specialistName}).\\n\\n${rawQuestion}`;\n } else if (lastErr && !/TIMEOUT_DIRECTIVE/.test(lastErr)) {\n // v6.1.0-alpha.51 — guard against propagating internal\n // commit-override directive into the user-facing question.\n richQuestion = `Goal \"${goal.title}\" — subtask \"${subtaskTitle}\" failed after ${attemptCount} attempt(s) with specialist ${specialistName}.\\n\\nError: ${lastErr.slice(0, 200)}\\n\\nWhat should the specialist do next?`;\n } else {\n richQuestion = `Goal \"${goal.title}\" — subtask \"${subtaskTitle}\" is blocked after ${attemptCount} attempt(s) with specialist ${specialistName}. The specialist could not complete the task and needs guidance on how to proceed.`;\n }\n\n state.blockedReason = {\n question: richQuestion,\n approvalId: '',\n sinceAt: new Date().toISOString(),\n kind: 'needs_info',\n };\n appendHistory(state, 'blocked', `Spawn needs info: ${richQuestion.slice(0, 120)}`);\n await fileBlockedApproval(state, goal, [richQuestion, ...result.questions.slice(1)]);\n }\n subState.pendingSpawn = undefined;\n } catch (err) {\n const msg = (err as Error).message;\n subState.lastError = msg;\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Spawn threw: ${msg.slice(0, 120)}`);\n }\n}\n\nasync function tickObserving(goal: Goal, state: DriverState): Promise<void> {\n // In Phase A, spawns are sync (await structuredSpawn completes in tickDelegating).\n // This phase exists for future async-wakeup integration; for now it just\n // advances based on whatever subState said after the spawn.\n //\n // v4.10.0-local (post-deploy, Fix 8): be a no-op unless there's a\n // pending spawn waiting for a wakeup. Previously this unconditionally\n // transitioned to iterating, which tickIterating treated as a failure\n // and burned an attempt on goals that never actually spawned. Now the\n // observing phase only advances when there's a spawn to observe.\n void goal;\n const currentId = state.currentSubtaskId;\n const subState = currentId ? state.subtaskStates[currentId] : undefined;\n if (!subState?.pendingSpawn) {\n // Nothing to observe — bounce back to delegating without counting\n // as a retry.\n state.phase = 'delegating';\n return;\n }\n state.phase = 'iterating';\n appendHistory(state, 'iterating', 'Observe tick with no spawn progress — iterating');\n}\n\nasync function tickIterating(goal: Goal, state: DriverState): Promise<void> {\n const currentId = state.currentSubtaskId;\n if (!currentId) {\n state.phase = 'delegating';\n return;\n }\n const subState = state.subtaskStates[currentId];\n\n // v4.10.0-local (post-deploy, Fix A): forward-progress detector.\n // If the same lastError (first 80 chars) repeats 3 times in a row,\n // retrying isn't producing new information — fail this subtask and\n // move on. Prevents the verifying↔iterating→delegating oscillation\n // observed on stuck drivers. Uses a semantic signal (error text)\n // rather than phase-pattern detection, which false-positives on\n // legitimate multi-phase verify passes.\n const fingerprint = (subState.lastError || '').slice(0, 80).toLowerCase().trim();\n if (fingerprint) {\n if (fingerprint === subState.lastErrorFingerprint) {\n subState.consecutiveIdenticalErrors = (subState.consecutiveIdenticalErrors || 0) + 1;\n } else {\n subState.consecutiveIdenticalErrors = 1;\n subState.lastErrorFingerprint = fingerprint;\n }\n if ((subState.consecutiveIdenticalErrors ?? 0) >= 3) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, currentId, `Stuck loop: same error 3× in a row: ${fingerprint}`);\n } catch { /* ok */ }\n state.currentSubtaskId = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Broke stall loop on ${currentId} (same error 3×)`);\n return;\n }\n }\n\n // v4.10.0-local (post-deploy, Fix 8): do NOT increment totalRetries\n // here. Per-subtask attempts are counted in tickDelegating. Counting\n // again here caused double-billing: one failed spawn consumed 2 budget\n // units. Retry budget is meant to track subtask-transition retries,\n // not individual spawn retries.\n const check = checkBudget(state);\n if (check.status === 'exceeded') {\n const suggestion = suggestDegradation(state);\n if (suggestion === 'ask_human') {\n state.phase = 'blocked';\n state.blockedReason = {\n question: `Goal \"${goal.title}\" — budget exceeded (${check.message}). The driver has used ${state.budget.costUsd.toFixed(2)} USD so far. Continue with extended budget, de-scope, or cancel?`,\n approvalId: '',\n sinceAt: new Date().toISOString(),\n kind: 'budget_exceeded',\n };\n appendHistory(state, 'blocked', check.message);\n await fileBlockedApproval(state, goal, [state.blockedReason.question]);\n return;\n }\n }\n\n if (subState.attempts >= state.budgetCaps.maxRetries) {\n // Gap 2 (plan-this-logical-ocean): before giving up on this subtask,\n // consult the bounded continuation counter. If the per-subtask cap\n // hasn't been hit (max 2, persisted to disk so restarts can't\n // bypass), halve attempts and let it try again. This is the\n // \"plan_only\" signal — spawns kept producing plans/output that\n // wouldn't verify. Two extra cycles across a restart boundary is\n // the cheapest escape from the verifying↔iterating oscillation that\n // the existing stuck-loop detector can't catch (different errors\n // each time, but no real progress).\n const { shouldContinue } = await import('./runContinuations.js');\n const continuationKey = `${goal.id}:${currentId}`;\n if (shouldContinue(continuationKey, 'plan_only')) {\n const before = subState.attempts;\n subState.attempts = Math.max(0, Math.floor(subState.attempts / 2));\n subState.consecutiveIdenticalErrors = 0;\n subState.lastErrorFingerprint = undefined;\n appendHistory(state, 'delegating', `Continuation granted on ${currentId}: attempts halved ${before} → ${subState.attempts}`);\n state.phase = 'delegating';\n return;\n }\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, currentId, subState.lastError || 'max retries');\n } catch { /* ok */ }\n appendHistory(state, 'delegating', `Subtask ${currentId} failed after ${subState.attempts} attempts`);\n state.phase = 'delegating';\n return;\n }\n\n // Back to delegating to try the next fallback\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Iterating on subtask ${currentId} — attempt ${subState.attempts + 1}`);\n}\n\nasync function tickVerifying(goal: Goal, state: DriverState): Promise<void> {\n const currentId = state.currentSubtaskId;\n if (!currentId) {\n // Whole-goal verify — check per-subtask results against the goal\n // file's subtask statuses. A subtask passes the whole-goal check\n // iff EITHER (a) its verificationResult.passed === true, OR\n // (b) the goal file reports it as done/skipped (completed through\n // an external path, e.g. human marked it done).\n //\n // v4.10.0-local (post-deploy, Fix 8): previous check was\n // `passed !== false`, which treated subtasks that never got\n // verified at all (verificationResult undefined) as passing\n // vacuously. Now we require an explicit pass signal OR an\n // explicit terminal status on the goal-side subtask.\n const goalSubs = goal.subtasks || [];\n const subById = new Map(goalSubs.map(s => [s.id, s]));\n const allPassed = Object.entries(state.subtaskStates).every(([subId, subState]) => {\n if (subState.verificationResult?.passed === true) return true;\n const goalSub = subById.get(subId);\n if (goalSub?.status === 'done' || goalSub?.status === 'skipped') return true;\n return false;\n });\n state.phase = allPassed ? 'reporting' : 'failed';\n appendHistory(state, state.phase, allPassed ? 'All subtasks verified' : 'Some subtasks failed verification');\n return;\n }\n const subState = state.subtaskStates[currentId];\n const subtask = (goal.subtasks || []).find(s => s.id === currentId);\n if (!subtask) {\n state.phase = 'delegating';\n return;\n }\n const lastSpawn = (subState as DriverSubtaskState & { lastSpawnResult?: unknown }).lastSpawnResult;\n if (!lastSpawn) {\n // No spawn result to verify against — iterate\n state.phase = 'iterating';\n appendHistory(state, 'iterating', 'Verify with no spawn result — iterating');\n return;\n }\n\n const verifyResult = await verifyByKind({\n kind: subState.kind,\n subtask,\n spawnResult: lastSpawn as Parameters<typeof verifyByKind>[0]['spawnResult'],\n });\n subState.verificationResult = verifyResult;\n\n if (verifyResult.passed) {\n try {\n const { completeSubtask } = await import('./goals.js');\n // v4.10.0-local polish: store the SPAWN'S actual output\n // (reasoning + artifacts summary), not the verifier's pass\n // message. Prior behavior stored \"Analysis 171 chars, conf 0.95\"\n // in the subtask.result field, losing the actual content.\n const spawn = lastSpawn as Parameters<typeof verifyByKind>[0]['spawnResult'];\n const artifactSummary = spawn.artifacts.length > 0\n ? `\\n\\nArtifacts:\\n${spawn.artifacts.map(a => ` - [${a.type}] ${a.ref}${a.description ? ` — ${a.description}` : ''}`).join('\\n')}`\n : '';\n const contentToSave = (spawn.reasoning || spawn.rawResponse || verifyResult.reason) + artifactSummary;\n completeSubtask(goal.id, currentId, contentToSave);\n } catch { /* ok */ }\n appendHistory(state, 'delegating', `Subtask ${currentId} verified: ${verifyResult.reason.slice(0, 120)}`);\n state.currentSubtaskId = undefined;\n\n // Bug #3 fix — v6.1.0-alpha.43: when the subtask we just\n // verified was the LAST remaining pending subtask, jump\n // straight to 'reporting' rather than back through\n // 'delegating'. Going through delegating left the goal\n // stuck in 'active' forever when the scheduler stopped\n // driving it after this tick.\n const goalSubs = goal.subtasks || [];\n const allResolved = goalSubs.every(\n s => s.status === 'done' || s.status === 'failed' || s.status === 'skipped',\n );\n if (allResolved) {\n state.phase = 'verifying'; // next tick → whole-goal verify → reporting\n appendHistory(state, 'verifying', 'Last subtask resolved — final whole-goal verify');\n } else {\n state.phase = 'delegating';\n }\n } else {\n subState.lastError = `Verification failed: ${verifyResult.reason}`;\n appendHistory(state, 'iterating', `Verification failed: ${verifyResult.reason.slice(0, 120)}`);\n state.phase = 'iterating';\n }\n}\n\nasync function tickReporting(goal: Goal, state: DriverState): Promise<void> {\n const durationMs = Date.now() - new Date(state.startedAt).getTime();\n const specialistsUsed = [...new Set(\n Object.values(state.subtaskStates)\n .map(s => s.specialist)\n .filter((x): x is string => !!x),\n )];\n state.retrospective = {\n success: true,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n lessonsLearned: [\n `Completed ${Object.keys(state.subtaskStates).length} subtasks across ${specialistsUsed.length} specialist(s) in ${Math.round(durationMs / 1000)}s`,\n ],\n specialistsUsed,\n };\n try {\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'completed' });\n } catch { /* ok */ }\n state.phase = 'done';\n appendHistory(state, 'done', `Goal completed: ${state.retrospective.lessonsLearned[0]}`);\n // v6.1.0-alpha.7 — broadcast on titanEvents so Mission Chat (and any\n // future listener) knows the goal finished. Without this, the mission\n // room sat in 'working' state with no completion message and looked\n // stuck even though the goal driver had returned status=completed in\n // goals.json. Bridge in missionLifecycle.ts maps this to a \"Mission\n // complete\" system message + status=done in the room.\n try {\n const { titanEvents } = await import('./daemon.js');\n titanEvents.emit('goal:completed', {\n goalId: goal.id,\n title: goal.title,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n specialistsUsed,\n subtaskCount: Object.keys(state.subtaskStates).length,\n });\n } catch { /* event bus failure never blocks driver state transitions */ }\n try { await onGoalCompleted(goal, state); } catch { /* ok */ }\n // v4.10.0-local (Phase B): record retrospective for future goal learning\n try {\n const { saveRetrospective } = await import('./retrospectives.js');\n await saveRetrospective(goal, state);\n } catch { /* ok */ }\n\n // Fire episode\n try {\n const { recordEpisode } = await import('../memory/episodic.js');\n recordEpisode({\n kind: 'goal_completed',\n summary: `Driver completed goal \"${goal.title}\" (${Math.round(durationMs / 1000)}s, ${Object.keys(state.subtaskStates).length} subtasks, specialists: ${specialistsUsed.join(', ')})`,\n detail: state.history.slice(-10).map(h => `${h.at} ${h.phase}: ${h.note}`).join('\\n'),\n tags: ['goal-driver', 'goal_completed', goal.id, ...(goal.tags || [])],\n });\n } catch { /* ok */ }\n}\n\nasync function tickBlocked(goal: Goal, state: DriverState): Promise<void> {\n // v4.10.0-local (post-deploy, Fix F): auto-unblock stale blocked states.\n // The block was either never backed by an approval (approvalId empty —\n // bookkeeping bug) or the approval no longer exists (deleted / TTL'd).\n // After 10 minutes of sitting idle with no live approval, retry the\n // subtask rather than sitting forever waiting for a human who has no\n // way to resolve this. Uses forceUnblockDriver so the recovery is\n // consistent with the manual API path.\n const approvalId = state.blockedReason?.approvalId;\n const sinceAt = state.blockedReason?.sinceAt;\n const sinceMs = sinceAt ? Date.now() - new Date(sinceAt).getTime() : 0;\n const STALE_MS = 10 * 60 * 1000;\n if (sinceMs > STALE_MS) {\n let approval: { status?: string } | null = null;\n if (approvalId) {\n try {\n const { getApproval } = await import('./commandPost.js');\n approval = getApproval(approvalId) as { status?: string } | null;\n } catch { /* ok */ }\n }\n if (!approvalId || !approval) {\n // Unblock in-place on the shared state reference. We can't\n // call forceUnblockDriver here because it does its own\n // loadState/saveState cycle, and tickDriver's outer saveState\n // would then overwrite those changes with our stale local\n // state. Mirror forceUnblockDriver's logic here.\n logger.info(COMPONENT, `Auto-unblocking stale blocked state for ${goal.id} (approvalId=${approvalId || 'empty'}, age=${Math.round(sinceMs / 60000)}min)`);\n const note = `stale block auto-recovered (age ${Math.round(sinceMs / 60000)}min)`;\n const wasBudget = state.blockedReason?.kind === 'budget_exceeded'\n || /budget.*exceed|retries exceed/i.test(state.blockedReason?.question || '');\n if (wasBudget) {\n state.budget.totalRetries = Math.floor(state.budget.totalRetries / 2);\n }\n const currentId = state.currentSubtaskId;\n if (currentId && state.subtaskStates[currentId]) {\n const sub = state.subtaskStates[currentId];\n sub.attempts = Math.floor(sub.attempts / 2);\n sub.consecutiveIdenticalErrors = 0;\n }\n state.blockedReason = undefined;\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Force-unblocked: ${note}`);\n return;\n }\n\n // Bug #6 fix — v6.1.0-alpha.43: if the approval is still\n // \"pending\" after 15 minutes, the human is unlikely to answer\n // soon (asleep, away, etc.). Auto-reject it so the goal\n // doesn't stay blocked forever. The specialist will retry\n // with a fresh attempt rather than spinning.\n const STALE_PENDING_MS = 15 * 60 * 1000;\n if (approval.status === 'pending' && sinceMs > STALE_PENDING_MS) {\n try {\n const { rejectApproval } = await import('./commandPost.js');\n rejectApproval(approvalId, 'auto:timeout', `Auto-rejected after ${Math.round(sinceMs / 60000)}min with no human response`);\n } catch { /* ok */ }\n const currentId = state.currentSubtaskId;\n if (currentId && state.subtaskStates[currentId]) {\n const sub = state.subtaskStates[currentId];\n sub.attempts = Math.floor(sub.attempts / 2);\n sub.consecutiveIdenticalErrors = 0;\n // v6.1.0-alpha.51 — the previous wording (\"Retry with\n // your best interpretation. What should the specialist\n // do next?\") would propagate into the next richQuestion\n // (line ~543) and surface verbatim to the user as a\n // pending question, creating an infinite ask loop. Rephrase\n // as a directive that does NOT read like a user-question,\n // and set commitOverride so the next needs_info short-\n // circuits to a commit/fail instead of filing another\n // approval.\n sub.lastError = 'TIMEOUT_DIRECTIVE: previous block timed out (no human within 15min). Commit to your best-effort interpretation now and proceed — do NOT ask another question. If no reasonable assumption is possible, return status=done with a \"could not complete: <reason>\" note in reasoning.';\n sub.commitOverride = true;\n }\n state.blockedReason = undefined;\n state.phase = 'iterating';\n appendHistory(state, 'iterating', `Stale pending approval ${approvalId} auto-rejected after ${Math.round(sinceMs / 60000)}min — iterating with commit-override`);\n return;\n }\n }\n\n // Check if the blocking approval has been decided\n if (!approvalId) return; // nothing to unblock from\n try {\n const { getApproval } = await import('./commandPost.js');\n const approval = getApproval(approvalId);\n if (!approval) return;\n if (approval.status === 'pending') return; // still waiting\n if (approval.status === 'approved') {\n // v6.0.3 — Incorporate the human's response into the current\n // subtask's context. The pre-v6.0.3 path composed\n // `Previous attempt needed info; human provided: \"${note}\".\n // Try again using this.` regardless of what the note was.\n //\n // When the user clicked \"Approve\" WITHOUT supplying actual\n // textual guidance via /api/command-post/approvals/:id/reply,\n // `decisionNote` was either undefined OR a generic verb like\n // \"Approved\" / \"OK\" / \"Yes\". The specialist would then try\n // to use the literal string \"Approved\" as the answer to a\n // question like \"What project should I document?\", fail\n // because that isn't actionable info, and re-block. Tony\n // would approve again, same loop. Approvals became useless\n // for `needs_info` blocks.\n //\n // Fix: detect generic/empty notes and synthesize a \"proceed\n // with best-effort interpretation; do NOT re-ask the same\n // question\" directive instead of feeding the action label.\n // When the note IS real textual guidance (>8 chars, not a\n // common approve-verb), pass it through as before.\n const currentId = state.currentSubtaskId;\n if (currentId) {\n const subState = state.subtaskStates[currentId];\n subState.lastError = composeApprovalGuidance(approval.decisionNote);\n }\n state.blockedReason = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Unblocked by human (approval ${approvalId})`);\n return;\n }\n if (approval.status === 'rejected') {\n state.phase = 'failed';\n appendHistory(state, 'failed', `Goal rejected by human via approval ${approvalId}`);\n await onGoalFailed(goal, state, 'rejected by human');\n return;\n }\n } catch { /* ok */ }\n}\n\nasync function tickEscalated(goal: Goal, state: DriverState): Promise<void> {\n // v4.10.0-local: Escalated phase handles systematic infrastructure failures.\n // Similar to blocked, but specifically for JSON parse failures that indicate\n // model tier issues. Requires human intervention to fix infrastructure.\n\n const approvalId = state.blockedReason?.approvalId;\n const sinceAt = state.blockedReason?.sinceAt;\n const sinceMs = sinceAt ? Date.now() - new Date(sinceAt).getTime() : 0;\n\n // Check if the escalation approval has been decided\n if (!approvalId) return;\n try {\n const { getApproval } = await import('./commandPost.js');\n const approval = getApproval(approvalId);\n if (!approval) return;\n if (approval.status === 'pending') return; // still waiting\n\n if (approval.status === 'approved') {\n // Human acknowledged the infrastructure issue and wants to retry\n // Reset the subtask attempts to give it another go with potentially\n // new model configuration\n const currentId = state.currentSubtaskId;\n if (currentId) {\n const subState = state.subtaskStates[currentId];\n subState.attempts = 0; // Reset to allow fresh attempts\n subState.consecutiveIdenticalErrors = 0;\n subState.lastError = undefined;\n subState.lastErrorFingerprint = undefined;\n }\n state.blockedReason = undefined;\n state.phase = 'delegating';\n appendHistory(state, 'delegating', `Escalation resolved by human — retrying subtask ${currentId} with fresh attempts`);\n return;\n }\n\n if (approval.status === 'rejected') {\n // Human decided to fail the goal rather than retry\n state.phase = 'failed';\n appendHistory(state, 'failed', `Infrastructure escalation rejected — goal failed`);\n await onGoalFailed(goal, state, 'infrastructure escalation rejected by human');\n return;\n }\n } catch { /* ok */ }\n}\n\nasync function tickFailed(goal: Goal, state: DriverState): Promise<void> {\n const durationMs = Date.now() - new Date(state.startedAt).getTime();\n state.retrospective = {\n success: false,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n lessonsLearned: [\n `Goal failed after ${Math.round(durationMs / 1000)}s, ${state.budget.totalRetries} retries`,\n ],\n specialistsUsed: [...new Set(Object.values(state.subtaskStates).map(s => s.specialist).filter((x): x is string => !!x))],\n };\n try {\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'failed' });\n } catch { /* ok */ }\n // v6.1.0-alpha.7 — same broadcast pattern as completion. The Mission\n // Chat bridge translates this to a \"Couldn't finish this one.\" system\n // message + status=failed so the user sees closure instead of an\n // idle team strip.\n try {\n const { titanEvents } = await import('./daemon.js');\n titanEvents.emit('goal:failed', {\n goalId: goal.id,\n title: goal.title,\n durationMs,\n tokensUsed: state.budget.tokensUsed,\n costUsd: state.budget.costUsd,\n retries: state.budget.totalRetries,\n });\n } catch { /* event bus failure never blocks driver state transitions */ }\n try { await onGoalFailed(goal, state, 'driver terminated in failed state'); } catch { /* ok */ }\n // Phase B: failed retrospectives are the most valuable — they teach us what to avoid\n try {\n const { saveRetrospective } = await import('./retrospectives.js');\n await saveRetrospective(goal, state);\n } catch { /* ok */ }\n try {\n const { recordEpisode } = await import('../memory/episodic.js');\n recordEpisode({\n kind: 'goal_failed',\n summary: `Driver failed goal \"${goal.title}\" after ${Math.round(durationMs / 1000)}s`,\n detail: state.history.slice(-15).map(h => `${h.at} ${h.phase}: ${h.note}`).join('\\n'),\n tags: ['goal-driver', 'goal_failed', goal.id, ...(goal.tags || [])],\n });\n } catch { /* ok */ }\n}\n\nasync function tickCancelled(goal: Goal, state: DriverState): Promise<void> {\n try {\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'failed' });\n } catch { /* ok */ }\n appendHistory(state, 'cancelled', 'Cancelled by user');\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nasync function pickNextReadySubtask(goal: Goal, state: DriverState): Promise<Subtask | null> {\n const ready = await pickAllReadySubtasks(goal, state, 1);\n return ready[0] ?? null;\n}\n\n/**\n * Return up to `cap` ready subtasks (status=pending, deps satisfied, not\n * exhausted-and-failed). Burst dispatch in tickDelegating uses this to\n * find genuinely-independent subtasks that can run concurrently.\n *\n * Synchronous deadlock recovery (originally v4.10.0-local Fix C) is\n * preserved: if a subtask has exhausted attempts with a failed\n * verification, we await failSubtask to persist before continuing. This\n * matters for both single-pick and burst paths.\n *\n * Exported for tests.\n */\nexport async function pickAllReadySubtasks(goal: Goal, state: DriverState, cap: number): Promise<Subtask[]> {\n if (cap < 1) return [];\n const attemptCap = (id: string) => state.subtaskStates[id]?.maxAttempts ?? 5;\n const ready: Subtask[] = [];\n for (const sub of goal.subtasks || []) {\n if (ready.length >= cap) break;\n if (sub.status !== 'pending') continue;\n const subState = state.subtaskStates[sub.id];\n if (!subState) continue;\n const exhaustedAttempts = subState.attempts >= attemptCap(sub.id)\n || subState.attempts >= state.budgetCaps.maxRetries;\n if (subState.verificationResult?.passed === false && exhaustedAttempts) {\n try {\n const { failSubtask } = await import('./goals.js');\n failSubtask(goal.id, sub.id, subState.lastError || 'max retries exceeded (deadlock recovery)');\n sub.status = 'failed';\n } catch { /* ok — driver will re-try next tick */ }\n continue;\n }\n const depsSatisfied = (sub.dependsOn ?? []).every(depId => {\n const dep = goal.subtasks?.find(s => s.id === depId);\n return dep?.status === 'done';\n });\n if (!depsSatisfied) continue;\n ready.push(sub);\n }\n return ready;\n}\n\n/**\n * v6.1.0-alpha.32 — turn a goal title into a reasonable filename\n * stem the LLM can use as a default for write_file. Lowercase,\n * kebab-case, only alphanumerics + dashes, capped at 40 chars.\n * Example: \"Write a 3 page essay about Martin Luther King\" →\n * \"write-a-3-page-essay-about-martin-l\".\n */\nfunction slugForGoal(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40)\n || 'report';\n}\n\nasync function fileBlockedApproval(\n state: DriverState,\n goal: Goal,\n questions: string[],\n): Promise<void> {\n const primaryQuestion = questions[0] ?? state.blockedReason?.question ?? 'Specialist requires input';\n const blockKind = state.blockedReason?.kind ?? 'needs_info';\n\n // v6.0.3 — same-block-twice auto-cancel for daemon-spawned goals.\n // We do this BEFORE the throttle / approval-create path so a\n // recurring block on an autonomous goal collapses the loop instead\n // of throttling the surface signal.\n if (shouldAutoCancelOnRecurringBlock(state, goal, blockKind, primaryQuestion)) {\n const tagSummary = (goal.tags || []).slice(0, 4).join(',') || '(no tags)';\n logger.warn(\n COMPONENT,\n `Auto-cancelling daemon-spawned goal ${goal.id} (\"${goal.title.slice(0, 60)}\"): same block recurred within ${Math.round(SAME_BLOCK_TWICE_WINDOW_MS / 60000)}min [tags=${tagSummary}, kind=${blockKind}]`\n );\n state.phase = 'cancelled';\n state.blockedReason = undefined;\n state.userControls.cancelRequested = true;\n appendHistory(\n state,\n 'cancelled',\n `Auto-cancelled: daemon-spawned goal hit the same block (${blockKind}) twice within the recurrence window.`\n );\n try {\n // Goal model has no `cancelled` status — convention is to flip\n // to `failed` while the driver phase records `cancelled`. This\n // matches tickCancelled()'s own behavior.\n const { updateGoal } = await import('./goals.js');\n updateGoal(goal.id, { status: 'failed' });\n } catch (err) {\n logger.warn(COMPONENT, `Could not flip goal ${goal.id} status after auto-cancel: ${(err as Error).message}`);\n }\n try { await onGoalBlocked(goal, state); } catch { /* ok */ }\n return;\n }\n\n // v4.10.0-local (Phase B): throttle to 1 per (goalId, driver_blocked) per 5 min\n try {\n const { shouldCreateApproval } = await import('./notificationThrottle.js');\n if (!shouldCreateApproval(goal.id, 'driver_blocked')) {\n logger.debug(COMPONENT, `Throttled duplicate driver_blocked approval for goal ${goal.id}`);\n // Still record SOMA feedback since we DID get blocked\n try { await onGoalBlocked(goal, state); } catch { /* ok */ }\n return;\n }\n } catch { /* if throttle module unavailable, fall through */ }\n try {\n const { createApproval } = await import('./commandPost.js');\n const subState = state.currentSubtaskId ? state.subtaskStates[state.currentSubtaskId] : undefined;\n const subtaskTitle = goal.subtasks?.find(s => s.id === state.currentSubtaskId)?.title;\n const approval = createApproval({\n type: 'custom',\n requestedBy: 'goal-driver',\n payload: {\n kind: 'driver_blocked',\n goalId: goal.id,\n goalTitle: goal.title,\n question: questions[0] ?? state.blockedReason?.question ?? 'Specialist requires input',\n allQuestions: questions,\n blockedPhase: state.phase,\n currentSubtaskId: state.currentSubtaskId,\n subtaskKind: subState?.kind,\n subtaskTitle,\n specialist: subState?.specialist,\n attempts: subState?.attempts,\n lastError: subState?.lastError,\n urgency: 'high',\n },\n linkedIssueIds: [],\n });\n if (approval?.id && state.blockedReason) {\n state.blockedReason.approvalId = approval.id;\n }\n // Broadcast via SSE if broadcaster exists (throttled separately)\n try {\n const { shouldBroadcast } = await import('./notificationThrottle.js');\n if (shouldBroadcast('driver:blocked', goal.id)) {\n const g = globalThis as unknown as { __titan_sse_broadcast?: (topic: string, payload: unknown) => void };\n if (typeof g.__titan_sse_broadcast === 'function') {\n g.__titan_sse_broadcast('driver:blocked', {\n goalId: goal.id,\n goalTitle: goal.title,\n question: questions[0] ?? 'Specialist requires input',\n approvalId: approval?.id,\n });\n }\n }\n } catch { /* ok */ }\n } catch (err) {\n logger.warn(COMPONENT, `Could not file blocked-on-human approval: ${(err as Error).message}`);\n }\n // SOMA feedback: small hunger bump + slight purpose stall (via metricGuard)\n try { await onGoalBlocked(goal, state); } catch { /* ok */ }\n}\n\n// ── Main tick loop ──────────────────────────────────────────────\n\nexport async function tickDriver(goalId: string): Promise<DriverPhase> {\n const { getGoal } = await import('./goals.js');\n const goal = getGoal(goalId);\n if (!goal) return 'failed';\n\n let state = loadState(goalId);\n if (!state) {\n state = freshDriverState(goal);\n saveState(state);\n }\n\n // Respect user controls\n if (state.userControls.cancelRequested) {\n state.phase = 'cancelled';\n await tickCancelled(goal, state);\n saveState(state);\n return 'cancelled';\n }\n if (state.userControls.paused) return state.phase;\n\n // Kill switch inherits automatically — toolRunner gates writes,\n // spawn_agent early-returns. Drivers don't need to re-check.\n\n try {\n switch (state.phase) {\n case 'planning': await tickPlanning(goal, state); break;\n case 'delegating': await tickDelegating(goal, state); break;\n case 'observing': await tickObserving(goal, state); break;\n case 'iterating': await tickIterating(goal, state); break;\n case 'verifying': await tickVerifying(goal, state); break;\n case 'reporting': await tickReporting(goal, state); break;\n case 'blocked': await tickBlocked(goal, state); break;\n case 'escalated': await tickEscalated(goal, state); break;\n case 'failed': await tickFailed(goal, state); break;\n case 'done':\n case 'cancelled':\n break;\n }\n } catch (err) {\n logger.warn(COMPONENT, `Tick for ${goalId} threw in phase=${state.phase}: ${(err as Error).message}`);\n appendHistory(state, state.phase, `Tick threw: ${(err as Error).message.slice(0, 120)}`);\n }\n\n saveState(state);\n return state.phase;\n}\n\n/**\n * Drive a goal synchronously to a terminal or waiting state. Ticks in a\n * loop with a small pause between ticks so observing/blocked states give\n * the event loop time to breathe. Returns when the driver is terminal\n * (done/failed/cancelled) or waiting on a human (blocked).\n */\nexport async function driveGoal(goalId: string, maxTicks = 200): Promise<DriverPhase> {\n let last: DriverPhase = 'planning';\n for (let i = 0; i < maxTicks; i++) {\n last = await tickDriver(goalId);\n if (last === 'done' || last === 'failed' || last === 'cancelled' || last === 'blocked' || last === 'escalated') break;\n // Mini-delay between ticks to let IO + timers run\n await new Promise(res => setTimeout(res, 50));\n }\n return last;\n}\n\n// ── External API ────────────────────────────────────────────────\n\nexport function getDriverState(goalId: string): DriverState | null {\n return loadState(goalId);\n}\n\nexport function listActiveDrivers(): DriverState[] {\n ensureStateDir();\n if (!existsSync(STATE_DIR)) return [];\n const out: DriverState[] = [];\n for (const file of readdirSync(STATE_DIR)) {\n if (!file.endsWith('.json')) continue;\n const goalId = file.slice(0, -5);\n const s = loadState(goalId);\n if (s && s.phase !== 'done' && s.phase !== 'failed' && s.phase !== 'cancelled') out.push(s);\n }\n return out;\n}\n\nexport function listAllDrivers(): DriverState[] {\n ensureStateDir();\n if (!existsSync(STATE_DIR)) return [];\n const out: DriverState[] = [];\n for (const file of readdirSync(STATE_DIR)) {\n if (!file.endsWith('.json')) continue;\n const goalId = file.slice(0, -5);\n const s = loadState(goalId);\n if (s) out.push(s);\n }\n return out;\n}\n\nexport function pauseDriver(goalId: string): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.paused = true;\n saveState(s);\n return true;\n}\n\nexport function resumeDriverControl(goalId: string): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.paused = false;\n saveState(s);\n return true;\n}\n\n/**\n * Force a blocked driver back to iterating. Used when the block was\n * triggered by a machine-level failure (parse error, model glitch)\n * rather than a genuine human-answerable question, and the underlying\n * issue has been fixed (e.g. model swap).\n *\n * Also auto-rejects any pending approval the driver was blocked on so\n * it doesn't clutter the Approvals UI forever.\n */\nexport async function forceUnblockDriver(goalId: string, note = 'auto-unblock'): Promise<boolean> {\n const s = loadState(goalId);\n if (!s) return false;\n if (s.phase !== 'blocked') return false;\n\n // Auto-reject the bogus approval if one exists\n const approvalId = s.blockedReason?.approvalId;\n if (approvalId) {\n try {\n const { rejectApproval } = await import('./commandPost.js');\n rejectApproval(approvalId, 'force-unblock', `Auto-rejected by force-unblock: ${note}`);\n } catch { /* ok — approval might not exist anymore */ }\n }\n\n // If the block was budget-related, halve the retry counter so the\n // driver has headroom to retry with the underlying fix in place.\n // This is preferable to a full reset — it still records that the\n // goal has been difficult, just gives it another shot.\n const wasBudget = s.blockedReason?.kind === 'budget_exceeded'\n || /budget.*exceed|retries exceed/i.test(s.blockedReason?.question || '');\n if (wasBudget) {\n s.budget.totalRetries = Math.floor(s.budget.totalRetries / 2);\n appendHistory(s, 'iterating', `Force-unblock: budget halved (${s.budget.totalRetries} / ${s.budgetCaps.maxRetries} retries)`);\n }\n\n // v4.10.0-local (post-deploy, Fix F): also halve the per-subtask\n // attempt counter for the current subtask. Otherwise the subtask\n // re-hits its per-subtask cap immediately on resume (from Fix B)\n // and we just re-enter the blocked state next tick.\n const currentId = s.currentSubtaskId;\n if (currentId && s.subtaskStates[currentId]) {\n const sub = s.subtaskStates[currentId];\n const before = sub.attempts;\n sub.attempts = Math.floor(sub.attempts / 2);\n sub.consecutiveIdenticalErrors = 0; // reset stall detector too\n appendHistory(s, 'iterating', `Force-unblock: per-subtask attempts halved on ${currentId} (${before} → ${sub.attempts})`);\n }\n\n s.blockedReason = undefined;\n s.phase = 'iterating'; // iterating retries the current subtask with a fresh spawn\n appendHistory(s, 'iterating', `Force-unblocked: ${note}`);\n saveState(s);\n logger.info(COMPONENT, `Force-unblocked driver ${goalId}: ${note}${wasBudget ? ' (budget halved)' : ''}`);\n return true;\n}\n\nexport function cancelDriver(goalId: string): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.cancelRequested = true;\n saveState(s);\n return true;\n}\n\n/**\n * Permanently remove a driver state file. Used by `resumeDriversAfterRestart`\n * to reap drivers whose goal no longer exists, and by the boot-time stale\n * sweep to cull drivers that haven't ticked in a long time.\n *\n * v5.5.31+. Before this, `cancelDriver` only flipped a `cancelRequested`\n * flag without deleting — meaning orphan driver files (e.g. tests pointing\n * at deleted goals) accumulated forever and the scheduler could re-tick\n * them. Audit 2026-05-08 found `mtime-cache-test.json` actively ticking\n * for 14h+ after the test that created it had finished.\n */\nexport function deleteDriverState(goalId: string): boolean {\n const path = statePath(goalId);\n if (!existsSync(path)) return false;\n try { rmSync(path, { force: true }); return true; }\n catch (err) { logger.warn(COMPONENT, `deleteDriverState ${goalId}: ${(err as Error).message}`); return false; }\n}\n\n/**\n * Sweep stale driver-state files. Returns count + ids of removed files.\n * A driver is considered stale if its `lastTickAt` is older than `maxAgeMs`\n * (default 24h). Called on gateway boot via `resumeDriversAfterRestart`.\n *\n * The audit found 5 driver-state files at 395+ hours old (16-17 days)\n * that resumeDriversAfterRestart kept \"cancelling\" via the flag but never\n * actually removing.\n */\nexport function sweepStaleDriverStates(maxAgeMs = 24 * 60 * 60 * 1000): { removed: number; ids: string[] } {\n ensureStateDir();\n const removed: string[] = [];\n const cutoff = Date.now() - maxAgeMs;\n try {\n const entries = readdirSync(STATE_DIR);\n for (const name of entries) {\n if (!name.endsWith('.json')) continue;\n const goalId = name.replace(/\\.json$/, '');\n const s = loadState(goalId);\n if (!s) continue;\n const lastTickMs = new Date(s.lastTickAt || s.startedAt).getTime();\n if (Number.isFinite(lastTickMs) && lastTickMs < cutoff) {\n if (deleteDriverState(goalId)) removed.push(goalId);\n }\n }\n } catch (err) {\n logger.warn(COMPONENT, `sweepStaleDriverStates: ${(err as Error).message}`);\n }\n return { removed: removed.length, ids: removed };\n}\n\nexport function reprioritizeDriver(goalId: string, priority: 1 | 2 | 3 | 4 | 5): boolean {\n const s = loadState(goalId);\n if (!s) return false;\n s.userControls.priority = priority;\n saveState(s);\n return true;\n}\n\nexport function _resetDriverStateForTests(goalId?: string): void {\n if (goalId) {\n try { rmSync(statePath(goalId), { force: true }); } catch { /* ok */ }\n } else {\n try { rmSync(STATE_DIR, { recursive: true, force: true }); } catch { /* ok */ }\n }\n}\n"],"mappings":"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","names":["subState"]}