@sayknow-cli/coding-agent 0.3.7 → 0.3.9

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 (272) hide show
  1. package/dist/types/append-only-mode.d.ts +31 -0
  2. package/dist/types/capability/rule.d.ts +8 -0
  3. package/dist/types/cli/completion-cli.d.ts +41 -0
  4. package/dist/types/cli/config-cli.d.ts +1 -0
  5. package/dist/types/cli/fixture-report.d.ts +20 -0
  6. package/dist/types/cli/fixture-report.test.d.ts +1 -0
  7. package/dist/types/cli/nofile-limit.d.ts +11 -0
  8. package/dist/types/cli/notify-cli.d.ts +7 -0
  9. package/dist/types/cli/update-cli.d.ts +22 -0
  10. package/dist/types/cli.d.ts +124 -1
  11. package/dist/types/commands/completion.d.ts +29 -0
  12. package/dist/types/commands/config.d.ts +3 -0
  13. package/dist/types/commands/deep-interview.d.ts +3 -0
  14. package/dist/types/config/file-lock.d.ts +7 -6
  15. package/dist/types/config/keybindings.d.ts +2 -2
  16. package/dist/types/config/model-profile-activation.d.ts +6 -0
  17. package/dist/types/config/model-profiles.d.ts +1 -0
  18. package/dist/types/config/settings-schema.d.ts +119 -1
  19. package/dist/types/config/settings.d.ts +8 -0
  20. package/dist/types/discovery/index.d.ts +1 -0
  21. package/dist/types/export/html/template.generated.d.ts +1 -1
  22. package/dist/types/export/ttsr.d.ts +14 -3
  23. package/dist/types/extensibility/extensions/runner.d.ts +2 -1
  24. package/dist/types/extensibility/extensions/types.d.ts +8 -0
  25. package/dist/types/goals/runtime.d.ts +1 -0
  26. package/dist/types/hooks/native-skill-hook.d.ts +12 -0
  27. package/dist/types/main.d.ts +4 -1
  28. package/dist/types/modes/components/assistant-message.d.ts +5 -1
  29. package/dist/types/modes/components/model-selector.d.ts +4 -0
  30. package/dist/types/modes/components/queued-message-selector.d.ts +12 -0
  31. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  32. package/dist/types/modes/components/status-line.d.ts +9 -0
  33. package/dist/types/modes/components/thinking-selector.d.ts +2 -2
  34. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  35. package/dist/types/modes/controllers/event-controller.d.ts +5 -0
  36. package/dist/types/modes/controllers/input-controller.d.ts +1 -3
  37. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  38. package/dist/types/modes/interactive-mode.d.ts +4 -0
  39. package/dist/types/modes/print-mode.d.ts +13 -1
  40. package/dist/types/modes/prompt-action-autocomplete.d.ts +1 -1
  41. package/dist/types/modes/rpc/rpc-mode.d.ts +1 -3
  42. package/dist/types/modes/rpc/rpc-socket-security.d.ts +3 -0
  43. package/dist/types/modes/rpc/rpc-types.d.ts +14 -0
  44. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +19 -0
  45. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +23 -1
  46. package/dist/types/modes/types.d.ts +3 -0
  47. package/dist/types/modes/utils/injected-user-submission.d.ts +52 -0
  48. package/dist/types/modes/utils/ui-helpers.d.ts +1 -0
  49. package/dist/types/notifications/config-commands.d.ts +9 -0
  50. package/dist/types/notifications/config.d.ts +30 -1
  51. package/dist/types/notifications/daemon-paths.d.ts +1 -0
  52. package/dist/types/notifications/index.d.ts +8 -3
  53. package/dist/types/notifications/lifecycle-commands.d.ts +12 -3
  54. package/dist/types/notifications/lifecycle-control-runtime.d.ts +2 -1
  55. package/dist/types/notifications/reply-sent-store.d.ts +53 -0
  56. package/dist/types/notifications/rich-draft.d.ts +68 -0
  57. package/dist/types/notifications/rich-render.d.ts +90 -0
  58. package/dist/types/notifications/telegram-daemon.d.ts +45 -3
  59. package/dist/types/notifications/telegram-reference.d.ts +7 -5
  60. package/dist/types/notifications/threaded-render.d.ts +14 -0
  61. package/dist/types/runtime-api-key.d.ts +7 -0
  62. package/dist/types/sdk.d.ts +3 -0
  63. package/dist/types/session/agent-session.d.ts +61 -6
  64. package/dist/types/session/agent-storage.d.ts +1 -0
  65. package/dist/types/session/file-mention-pruning.d.ts +8 -0
  66. package/dist/types/session/messages.d.ts +4 -0
  67. package/dist/types/session/session-manager.d.ts +17 -1
  68. package/dist/types/skc-runtime/deep-interview-ambiguity.d.ts +39 -0
  69. package/dist/types/skc-runtime/deep-interview-recorder.d.ts +10 -1
  70. package/dist/types/skc-runtime/deep-interview-state.d.ts +17 -2
  71. package/dist/types/skc-runtime/session-state-sidecar.d.ts +7 -0
  72. package/dist/types/skc-runtime/state-writer.d.ts +3 -0
  73. package/dist/types/skc-runtime/tmux-common.d.ts +1 -0
  74. package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +42 -0
  75. package/dist/types/skc-runtime/ultragoal-runtime.d.ts +120 -13
  76. package/dist/types/skill-state/active-state.d.ts +18 -1
  77. package/dist/types/system-prompt.d.ts +18 -2
  78. package/dist/types/task/executor.d.ts +3 -0
  79. package/dist/types/task/fork-context-budget.d.ts +7 -0
  80. package/dist/types/task/token-log.d.ts +30 -0
  81. package/dist/types/task/token-log.test.d.ts +1 -0
  82. package/dist/types/tools/bisect.d.ts +81 -0
  83. package/dist/types/tools/computer.d.ts +2 -2
  84. package/dist/types/tools/index.d.ts +1 -0
  85. package/dist/types/tools/search.d.ts +2 -2
  86. package/dist/types/tools/ultragoal-ask-guard.d.ts +9 -2
  87. package/dist/types/utils/file-mentions.d.ts +14 -0
  88. package/dist/types/utils/git.d.ts +32 -0
  89. package/dist/types/utils/pasted-image-path.d.ts +30 -0
  90. package/dist/types/web/scrapers/youtube.d.ts +8 -0
  91. package/dist/types/workflow/workflow-intent-diff.d.ts +8 -2
  92. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +50 -0
  93. package/dist/types/workflow/workflow-intent-report-schema.d.ts +2 -0
  94. package/dist/types/workflow/workflow-intent-report.d.ts +48 -0
  95. package/package.json +8 -8
  96. package/src/append-only-mode.ts +58 -0
  97. package/src/autoresearch/prompt.md +1 -1
  98. package/src/autoresearch/tools/log-experiment.ts +1 -1
  99. package/src/capability/rule.ts +9 -0
  100. package/src/cli/completion-cli.ts +234 -0
  101. package/src/cli/config-cli.ts +61 -9
  102. package/src/cli/fast-help.ts +1 -0
  103. package/src/cli/fixture-report.test.ts +230 -0
  104. package/src/cli/fixture-report.ts +171 -0
  105. package/src/cli/nofile-limit.ts +48 -0
  106. package/src/cli/notify-cli.ts +103 -17
  107. package/src/cli/telegram-cli.ts +1 -1
  108. package/src/cli/update-cli.ts +148 -33
  109. package/src/cli.ts +29 -1
  110. package/src/commands/completion.ts +84 -0
  111. package/src/commands/config.ts +2 -0
  112. package/src/commands/contribution-prep.ts +1 -1
  113. package/src/commands/deep-interview.ts +2 -1
  114. package/src/config/file-lock.ts +73 -34
  115. package/src/config/keybindings.ts +3 -3
  116. package/src/config/model-profile-activation.ts +65 -0
  117. package/src/config/model-profiles.ts +31 -2
  118. package/src/config/settings-schema.ts +76 -1
  119. package/src/config/settings.ts +22 -0
  120. package/src/defaults/skc/skills/team/SKILL.md +17 -14
  121. package/src/defaults/skc/skills/ultragoal/SKILL.md +59 -4
  122. package/src/defaults/skc/skills/ultragoal/pipeline-validation-contracts.md +30 -0
  123. package/src/defaults/skc-defaults.ts +9 -0
  124. package/src/discovery/helpers.ts +10 -0
  125. package/src/discovery/index.ts +1 -0
  126. package/src/export/html/template.generated.ts +1 -1
  127. package/src/export/html/template.js +60 -2
  128. package/src/export/ttsr.ts +96 -18
  129. package/src/extensibility/extensions/runner.ts +183 -219
  130. package/src/extensibility/extensions/types.ts +9 -0
  131. package/src/extensibility/skc-plugins/runtime-adapters.ts +156 -44
  132. package/src/goals/runtime.ts +10 -2
  133. package/src/hindsight/backend.ts +1 -3
  134. package/src/hooks/native-skill-hook.ts +124 -4
  135. package/src/internal-urls/docs-index.generated.ts +17 -8
  136. package/src/lsp/client.ts +1 -0
  137. package/src/main.ts +95 -43
  138. package/src/memories/index.ts +12 -1
  139. package/src/modes/components/assistant-message.ts +241 -82
  140. package/src/modes/components/custom-editor.ts +1 -0
  141. package/src/modes/components/footer.ts +7 -2
  142. package/src/modes/components/model-selector.ts +54 -11
  143. package/src/modes/components/queued-message-selector.ts +92 -0
  144. package/src/modes/components/settings-selector.ts +4 -0
  145. package/src/modes/components/status-line.ts +167 -54
  146. package/src/modes/components/thinking-selector.ts +10 -8
  147. package/src/modes/components/tool-execution.ts +44 -19
  148. package/src/modes/components/welcome.ts +181 -44
  149. package/src/modes/controllers/command-controller.ts +40 -4
  150. package/src/modes/controllers/event-controller.ts +77 -49
  151. package/src/modes/controllers/extension-ui-controller.ts +12 -11
  152. package/src/modes/controllers/input-controller.ts +192 -35
  153. package/src/modes/controllers/selector-controller.ts +168 -24
  154. package/src/modes/interactive-mode.ts +56 -16
  155. package/src/modes/print-mode.ts +43 -4
  156. package/src/modes/prompt-action-autocomplete.ts +21 -20
  157. package/src/modes/rpc/rpc-mode.ts +32 -12
  158. package/src/modes/rpc/rpc-socket-security.ts +13 -1
  159. package/src/modes/rpc/rpc-types.ts +9 -0
  160. package/src/modes/shared/agent-wire/command-validation.ts +4 -0
  161. package/src/modes/shared/agent-wire/event-contract.ts +22 -0
  162. package/src/modes/shared/agent-wire/event-envelope.ts +82 -0
  163. package/src/modes/shared/agent-wire/scopes.ts +1 -0
  164. package/src/modes/types.ts +3 -0
  165. package/src/modes/utils/hotkeys-markdown.ts +1 -0
  166. package/src/modes/utils/injected-user-submission.ts +94 -0
  167. package/src/modes/utils/ui-helpers.ts +20 -7
  168. package/src/notifications/config-commands.ts +20 -0
  169. package/src/notifications/config.ts +52 -5
  170. package/src/notifications/daemon-paths.ts +2 -0
  171. package/src/notifications/index.ts +144 -18
  172. package/src/notifications/lifecycle-commands.ts +74 -23
  173. package/src/notifications/lifecycle-control-runtime.ts +8 -3
  174. package/src/notifications/lifecycle-orchestrator.ts +19 -6
  175. package/src/notifications/reply-sent-store.ts +134 -0
  176. package/src/notifications/rich-draft.ts +107 -0
  177. package/src/notifications/rich-render.ts +142 -0
  178. package/src/notifications/telegram-daemon-control.ts +5 -3
  179. package/src/notifications/telegram-daemon.ts +606 -98
  180. package/src/notifications/telegram-reference.ts +17 -16
  181. package/src/notifications/threaded-render.ts +45 -2
  182. package/src/prompts/agents/architect.md +19 -10
  183. package/src/prompts/agents/critic.md +16 -18
  184. package/src/prompts/agents/executor.md +14 -11
  185. package/src/prompts/agents/planner.md +18 -13
  186. package/src/prompts/ci-green-request.md +3 -8
  187. package/src/prompts/goals/goal-continuation.md +0 -5
  188. package/src/prompts/goals/goal-mode-active.md +0 -5
  189. package/src/prompts/system/agent-creation-architect.md +2 -2
  190. package/src/prompts/system/plan-mode-active.md +1 -1
  191. package/src/prompts/system/plan-mode-subagent.md +3 -3
  192. package/src/prompts/system/project-prompt.md +0 -13
  193. package/src/prompts/system/subagent-system-prompt.md +3 -2
  194. package/src/prompts/system/system-prompt.md +29 -17
  195. package/src/prompts/system/volatile-project-context.md +10 -0
  196. package/src/prompts/system/web-search.md +4 -7
  197. package/src/prompts/tools/apply-patch.md +6 -0
  198. package/src/prompts/tools/ast-edit.md +1 -0
  199. package/src/prompts/tools/bash.md +1 -1
  200. package/src/prompts/tools/bisect.md +22 -0
  201. package/src/prompts/tools/browser.md +1 -1
  202. package/src/prompts/tools/computer.md +2 -2
  203. package/src/prompts/tools/cron.md +0 -2
  204. package/src/prompts/tools/eval.md +2 -2
  205. package/src/prompts/tools/find.md +1 -1
  206. package/src/prompts/tools/github.md +6 -6
  207. package/src/prompts/tools/goal.md +1 -3
  208. package/src/prompts/tools/image-gen.md +12 -5
  209. package/src/prompts/tools/irc.md +5 -4
  210. package/src/prompts/tools/job.md +2 -2
  211. package/src/prompts/tools/lsp.md +1 -1
  212. package/src/prompts/tools/monitor.md +2 -2
  213. package/src/prompts/tools/patch.md +2 -2
  214. package/src/prompts/tools/replace.md +2 -21
  215. package/src/prompts/tools/rewind.md +1 -1
  216. package/src/prompts/tools/search-tool-bm25.md +6 -11
  217. package/src/prompts/tools/search.md +1 -1
  218. package/src/prompts/tools/skill.md +3 -2
  219. package/src/prompts/tools/ssh.md +2 -1
  220. package/src/prompts/tools/subagent.md +2 -2
  221. package/src/prompts/tools/task.md +4 -5
  222. package/src/prompts/tools/todo-write.md +1 -1
  223. package/src/prompts/tools/vim.md +1 -0
  224. package/src/prompts/tools/web-search.md +2 -0
  225. package/src/prompts/tools/write.md +8 -2
  226. package/src/runtime-api-key.ts +16 -0
  227. package/src/sdk.ts +88 -36
  228. package/src/session/agent-session.ts +1013 -141
  229. package/src/session/agent-storage.ts +4 -0
  230. package/src/session/file-mention-pruning.ts +64 -0
  231. package/src/session/messages.ts +4 -0
  232. package/src/session/session-manager.ts +103 -4
  233. package/src/skc-runtime/deep-interview-ambiguity.ts +206 -0
  234. package/src/skc-runtime/deep-interview-recorder.ts +62 -8
  235. package/src/skc-runtime/deep-interview-state.ts +44 -2
  236. package/src/skc-runtime/session-state-sidecar.ts +263 -20
  237. package/src/skc-runtime/state-runtime.ts +12 -2
  238. package/src/skc-runtime/state-writer.ts +15 -0
  239. package/src/skc-runtime/tmux-common.ts +1 -0
  240. package/src/skc-runtime/ultragoal-guard.ts +55 -66
  241. package/src/skc-runtime/ultragoal-receipt-freshness.ts +315 -0
  242. package/src/skc-runtime/ultragoal-runtime.ts +1672 -159
  243. package/src/skc-runtime/workflow-manifest.generated.json +113 -2
  244. package/src/skc-runtime/workflow-manifest.ts +74 -1
  245. package/src/skill-state/active-state.ts +141 -5
  246. package/src/skill-state/deep-interview-mutation-guard.ts +67 -3
  247. package/src/slash-commands/builtin-registry.ts +296 -72
  248. package/src/system-prompt.ts +57 -16
  249. package/src/task/executor.ts +132 -24
  250. package/src/task/fork-context-advisory.ts +2 -7
  251. package/src/task/fork-context-budget.ts +9 -0
  252. package/src/task/index.ts +13 -6
  253. package/src/task/output-manager.ts +20 -8
  254. package/src/task/receipt.ts +26 -7
  255. package/src/task/token-log.test.ts +188 -0
  256. package/src/task/token-log.ts +179 -0
  257. package/src/tools/bisect.ts +367 -0
  258. package/src/tools/computer.ts +246 -43
  259. package/src/tools/index.ts +3 -0
  260. package/src/tools/output-meta.ts +116 -4
  261. package/src/tools/search.ts +8 -2
  262. package/src/tools/skill.ts +15 -0
  263. package/src/tools/telegram-send.ts +6 -0
  264. package/src/tools/ultragoal-ask-guard.ts +39 -5
  265. package/src/utils/file-mentions.ts +39 -7
  266. package/src/utils/git.ts +73 -0
  267. package/src/utils/pasted-image-path.ts +170 -0
  268. package/src/web/scrapers/youtube.ts +24 -12
  269. package/src/workflow/workflow-intent-diff.ts +29 -6
  270. package/src/workflow/workflow-intent-report-consumer.ts +221 -0
  271. package/src/workflow/workflow-intent-report-schema.ts +129 -0
  272. package/src/workflow/workflow-intent-report.ts +135 -0
@@ -262,6 +262,8 @@ export const SETTINGS_SCHEMA = {
262
262
  "notifications.enabled": { type: "boolean", default: false },
263
263
  "notifications.telegram.botToken": { type: "string", default: undefined },
264
264
  "notifications.telegram.chatId": { type: "string", default: undefined },
265
+ "notifications.telegram.rich.enabled": { type: "boolean", default: true },
266
+ "notifications.telegram.richDraft.enabled": { type: "boolean", default: false },
265
267
  "notifications.discord.botToken": { type: "string", default: undefined },
266
268
  "notifications.discord.channelId": { type: "string", default: undefined },
267
269
  "notifications.slack.botToken": { type: "string", default: undefined },
@@ -570,6 +572,42 @@ export const SETTINGS_SCHEMA = {
570
572
  ],
571
573
  },
572
574
  },
575
+
576
+ "tools.readArtifactSpillThreshold": {
577
+ type: "number",
578
+ default: 0,
579
+ ui: {
580
+ tab: "tools",
581
+ label: "Experimental read-tool artifact spill threshold (KB)",
582
+ description:
583
+ "Advanced opt-in only: combined-size cap for `read` output across all requested ranges. Above this the full output is saved as an artifact and a bounded head+tail snippet is kept inline. Live layofflabs/gpt-5.5 medium evidence on 2026-07-07 found no token savings and a lower cache-hit rate at 50 KB, so normal coding sessions should leave this Off unless intentionally measuring large-read behavior.",
584
+ options: [
585
+ { value: "0", label: "Off", description: "Default; no read-specific spill (backstop only)" },
586
+ { value: "50", label: "50 KB", description: "~12.5K tokens" },
587
+ { value: "100", label: "100 KB", description: "~25K tokens" },
588
+ { value: "256", label: "256 KB", description: "~64K tokens" },
589
+ { value: "512", label: "512 KB", description: "~128K tokens" },
590
+ { value: "1000", label: "1 MB", description: "~250K tokens" },
591
+ ],
592
+ },
593
+ },
594
+
595
+ "tools.fileMentionInlineBytes": {
596
+ type: "number",
597
+ default: 20,
598
+ ui: {
599
+ tab: "tools",
600
+ label: "File-mention inline cap (KB)",
601
+ description:
602
+ "Inline byte cap for auto-read `@path` file mentions, deliberately below the read-tool cap so an incidental mention injects a smaller snippet than an explicit read. The full file is still available via the read tool.",
603
+ options: [
604
+ { value: "5", label: "5 KB", description: "~1.25K tokens" },
605
+ { value: "10", label: "10 KB", description: "~2.5K tokens" },
606
+ { value: "20", label: "20 KB", description: "Default; ~5K tokens" },
607
+ { value: "50", label: "50 KB", description: "~12.5K tokens (matches read cap)" },
608
+ ],
609
+ },
610
+ },
573
611
  "tools.artifactTailBytes": {
574
612
  type: "number",
575
613
  default: 20,
@@ -648,6 +686,25 @@ export const SETTINGS_SCHEMA = {
648
686
  },
649
687
  },
650
688
 
689
+ "tools.maxInlineResultBytes": {
690
+ type: "number",
691
+ default: 0,
692
+ ui: {
693
+ tab: "tools",
694
+ label: "Max inline tool-result size (KB)",
695
+ description:
696
+ "Absolute backstop cap on inline tool-result text, enforced after artifact spill for every tool (including read and tools that set their own partial artifact meta). Output above this size is force-saved as an artifact and truncated to head+tail. 0 disables (default; opt-in pending measurement).",
697
+ options: [
698
+ { value: "0", label: "Off", description: "Disabled; no absolute inline cap" },
699
+ { value: "20", label: "20 KB", description: "~5K tokens" },
700
+ { value: "30", label: "30 KB", description: "~7.5K tokens" },
701
+ { value: "50", label: "50 KB", description: "~12.5K tokens" },
702
+ { value: "75", label: "75 KB", description: "~19K tokens" },
703
+ { value: "100", label: "100 KB", description: "~25K tokens" },
704
+ ],
705
+ },
706
+ },
707
+
651
708
  "statusLine.showHookStatus": {
652
709
  type: "boolean",
653
710
  default: false,
@@ -1410,6 +1467,15 @@ export const SETTINGS_SCHEMA = {
1410
1467
 
1411
1468
  "compaction.remoteEndpoint": { type: "string", default: undefined },
1412
1469
 
1470
+ // Below-threshold maintenance pruning (Finding 13). Internal/measurement-only:
1471
+ // keep the runtime setting for targeted experiments, but do not expose it in
1472
+ // settings UI. Live layofflabs/gpt-5.5 medium evidence on 2026-07-07 showed no
1473
+ // savings and a cache-hit regression; pruning rewrites already-sent history and
1474
+ // can force a provider cache-epoch reset.
1475
+ "compaction.maintenancePruningEnabled": { type: "boolean", default: false },
1476
+
1477
+ "compaction.maintenancePruningMinSavingsTokens": { type: "number", default: 8000 },
1478
+
1413
1479
  // Idle compaction
1414
1480
  "compaction.idleEnabled": {
1415
1481
  type: "boolean",
@@ -1683,7 +1749,8 @@ export const SETTINGS_SCHEMA = {
1683
1749
  ui: {
1684
1750
  tab: "context",
1685
1751
  label: "TTSR Context Mode",
1686
- description: "What to do with partial output when TTSR triggers",
1752
+ description:
1753
+ "What to do with partial output when TTSR triggers. 'discard' (recommended) drops the aborted partial turn so it never accumulates in context. 'keep' retains every aborted partial turn, which grows the token footprint each time a rule fires — prefer 'discard' unless you specifically need the partial output.",
1687
1754
  },
1688
1755
  },
1689
1756
 
@@ -3421,6 +3488,8 @@ export interface CompactionSettings {
3421
3488
  autoContinue: boolean;
3422
3489
  remoteEnabled: boolean;
3423
3490
  remoteEndpoint: string | undefined;
3491
+ maintenancePruningEnabled: boolean;
3492
+ maintenancePruningMinSavingsTokens: number;
3424
3493
  idleEnabled: boolean;
3425
3494
  idleThresholdTokens: number;
3426
3495
  idleTimeoutSeconds: number;
@@ -3543,6 +3612,12 @@ export interface NotificationsSettings {
3543
3612
  telegram: {
3544
3613
  botToken: string | undefined;
3545
3614
  chatId: string | undefined;
3615
+ rich: {
3616
+ enabled: boolean;
3617
+ };
3618
+ richDraft: {
3619
+ enabled: boolean;
3620
+ };
3546
3621
  };
3547
3622
  discord: {
3548
3623
  botToken: string | undefined;
@@ -476,6 +476,28 @@ export class Settings {
476
476
  this.override("modelRoles", { ...shallowStringRecord(runtimeOverrides), [role]: modelId });
477
477
  }
478
478
  }
479
+ /**
480
+ * Set an agent model override while keeping any live runtime override aligned.
481
+ *
482
+ * Runtime model profiles override `task.agentModelOverrides` for the current
483
+ * session. A user-selected role assignment must win immediately in that same
484
+ * session, but only the explicit agent change should be persisted.
485
+ */
486
+ setAgentModelOverride(agentName: string, modelId: string): void {
487
+ const current = shallowStringRecord(getByPath(this.#global, ["task", "agentModelOverrides"]));
488
+ const runtimeOverrides = getByPath(this.#overrides, ["task", "agentModelOverrides"]);
489
+ const updateRuntimeOverride =
490
+ !!runtimeOverrides && typeof runtimeOverrides === "object" && !Array.isArray(runtimeOverrides);
491
+
492
+ this.set("task.agentModelOverrides", { ...current, [agentName]: modelId });
493
+
494
+ if (updateRuntimeOverride) {
495
+ this.override("task.agentModelOverrides", {
496
+ ...shallowStringRecord(runtimeOverrides),
497
+ [agentName]: modelId,
498
+ });
499
+ }
500
+ }
479
501
 
480
502
  /**
481
503
  * Get a model role (helper for modelRoles record).
@@ -112,7 +112,7 @@ Before launching `skc team`, require a grounded context snapshot:
112
112
  - unknowns/open questions
113
113
  - likely codebase touchpoints
114
114
  4. If ambiguity remains high, gather brownfield facts with focused repo inspection or a canonical read-only role agent first, then run `$deep-interview --quick <task>` before team launch.
115
- 5. If current correctness depends on official docs, version-aware framework guidance, best practices, or external dependency behavior, auto-delegate `researcher` as an evidence lane before or alongside worker launch instead of relying on repo-local recall alone.
115
+ 5. If current correctness depends on official docs, version-aware framework guidance, best practices, or external dependency behavior, gather evidence before or alongside worker launch using supported surfaces only: focused repo inspection for local facts, `planner` for broad context mapping/sequencing, `architect` for architecture or external-doc-risk assessment, and direct web/search tools when configured.
116
116
 
117
117
  Do not start the worker pane until this gate is satisfied; if forced to proceed quickly, state explicit scope/risk limitations in the launch report.
118
118
 
@@ -343,14 +343,15 @@ Use only after checking `skc team status <team>` and state evidence:
343
343
  - `.skc/_session-{sessionid}/state/team/<team>/config.json`
344
344
  - `.skc/_session-{sessionid}/state/team/<team>/tasks/task-1.json`
345
345
  - `.skc/_session-{sessionid}/state/team/<team>/mailbox/worker-1.json`
346
- 2. Capture pane tail to confirm current worker state:
347
- - `tmux capture-pane -t %<worker-pane> -p -S -120`
348
- - If a larger-tail read or bounded summary would help, prefer explicit opt-in inspection via `skc sparkshell --tmux-pane %<worker-pane> --tail-lines 400` before improvising extra tmux commands.
349
- 3. If the pane is stuck in an interactive state, safely return to idle prompt first:
350
- - optional interrupt `C-c` or escape flow (CLI-specific) once, then re-check pane capture
346
+ 2. Use supported team surfaces before manual pane intervention:
347
+ - `skc team status <team>` for current recorded state
348
+ - `skc team monitor <team>` when a live monitor/update loop is needed
349
+ - `skc team api <team>` only for documented programmatic operations
350
+ 3. If the recorded worker pane is stuck in an interactive state, safely return to idle prompt first:
351
+ - optional interrupt `C-c` or escape flow (CLI-specific) once, then re-check `skc team status <team>` and relevant state files
351
352
  4. Send one concise trigger only when runtime/state checks show manual prompt input is needed:
352
353
  - `tmux send-keys -t %<worker-pane> "continue current task; report status" C-m`
353
- 5. Re-check pane output, task state, worker mailbox, and `skc team status <team>`.
354
+ 5. Re-check task state, worker mailbox, and `skc team status <team>`.
354
355
 
355
356
  ### Shutdown reports success but stale worker panes remain
356
357
 
@@ -372,8 +373,9 @@ tmux list-panes -F '#{pane_id} #{pane_current_command} #{pane_start_command}'
372
373
  tmux kill-pane -t %450
373
374
  tmux kill-pane -t %451
374
375
 
375
- # 3) Remove stale team state only after preserving needed evidence, using the state runtime
376
- # cleanup verb documented by the current manifest
376
+ # 3) Shut down recorded team state/workers through the supported team runtime
377
+ # Replace <team-name> with the team from `skc team list` / `skc team status`.
378
+ skc team shutdown <team-name>
377
379
 
378
380
  # 4) Retry
379
381
  skc team executor "fresh retry"
@@ -396,7 +398,7 @@ When operating this skill, provide concrete progress evidence:
396
398
 
397
399
  Do not claim success without file/pane evidence.
398
400
  Do not claim clean completion if shutdown occurred with `in_progress>0`.
399
- Use `skc sparkshell --tmux-pane ...` as an explicit opt-in operator aid for pane inspection and summaries; keep raw `tmux capture-pane` evidence available for manual intervention and proof.
401
+ Use `skc team status <team>` and `skc team monitor <team>` as the supported operator aids for status inspection; keep raw state-file or pane evidence available for manual intervention and proof.
400
402
 
401
403
  ## Programmatic Team Orchestration
402
404
 
@@ -405,14 +407,15 @@ Use the `skc team ...` CLI as the supported team-launch surface. For automation,
405
407
  ### Supported current surfaces
406
408
 
407
409
  - **`skc team ...` CLI** — Primary method for interactive or automated team orchestration. Use this when you want direct tmux-pane visibility or a scriptable launch path.
410
+ - **`skc team status <team>`** — Read current team/task/worker state.
411
+ - **`skc team monitor <team>`** — Follow live progress through the supported runtime surface.
412
+ - **`skc team shutdown <team>`** — Stop recorded active workers and move the team toward terminal state.
413
+ - **`skc team api <team>`** — Use only for documented programmatic operations exposed by the team runtime.
408
414
  - **Team state files** — Inspect `.skc/_session-{sessionid}/state/team/<team>/` when you need status, task, or mailbox evidence after launch.
409
415
 
410
416
  ### Cleanup distinction
411
417
 
412
- Two cleanup paths exist and must not be confused:
413
-
414
- - `team_cleanup` (**state-server**): Deletes team state **files** on disk (`.skc/_session-{sessionid}/state/team/<team>/`). Use after a team run is fully complete.
415
- - tmux/session cleanup: Use the documented `skc team` shutdown / cleanup flow when you need to stop the worker pane or clean up an interrupted run.
418
+ Use `skc team shutdown <team>` for recorded active workers. After shutdown reports a terminal state and required evidence is preserved, use supported `skc state ...` session/mode cleanup commands only when you are intentionally clearing state; do not delete team state by hand during an active run. Use manual tmux/session cleanup only for verified stale panes that are not handled by the documented shutdown flow.
416
419
 
417
420
  ### Automation example
418
421
 
@@ -87,6 +87,17 @@ Durable completion is single-source: `goals.json` defines which goals exist and
87
87
  - `skc ultragoal create-goals --skc-goal-mode per-story --brief "<brief>"` only when one SKC goal context per story is explicitly preferred
88
88
  3. Inspect `.skc/_session-{sessionid}/ultragoal/goals.json` and refine if needed.
89
89
 
90
+ ### Create-goals granularity: merge validation-coupled stories
91
+
92
+ Before splitting a brief into many thin stories, check whether the candidate stories are **validation-coupled**. Merge validation-coupled stories into one goal and fan out executor slices inside that goal instead of creating one goal per slice. Two stories are validation-coupled when they share any of:
93
+
94
+ - the same feature stack (one story's code cannot be meaningfully verified without the other's),
95
+ - the same acceptance surface,
96
+ - the same red-team surface, or
97
+ - the same final review boundary (they can only be signed off as a unit).
98
+
99
+ Fanning out executor slices inside a single merged goal keeps one review/QA boundary while preserving parallel implementation. When validation-coupled stories must stay as separate goals for scheduling reasons, use an aggregate-mode **validation batch** (below) so the coupled review happens once at the final member.
100
+
90
101
  ## Complete goals
91
102
 
92
103
  Loop until `skc ultragoal status` reports all goals complete:
@@ -192,6 +203,49 @@ If an Ultragoal request has no approved plan or consensus artifact, run `ralplan
192
203
 
193
204
  The Ultragoal leader owns `.skc/_session-{sessionid}/ultragoal/goals.json` and `.skc/_session-{sessionid}/ultragoal/ledger.jsonl`. Role agents return implementation/review evidence; they do not checkpoint Ultragoal or mutate goal state.
194
205
 
206
+ ### Native executor parallelism contract
207
+
208
+ Native subagent parallelism is a contract for bounded `executor` delegation, not a runtime scheduler and not a Team-mode rule:
209
+
210
+ - **MUST use native `executor` parallelism** when a story meets the big-scope delegation threshold above and decomposes into independent implementation slices that can be bounded by per-slice coordination contracts.
211
+ - **SHOULD prefer parallel `executor` subagents** for independent files/surfaces, and sequence only real dependencies, unsafe shared-file overlap, sub-threshold trivial work, or work that lacks a safe contract.
212
+ - Worker agents **MUST NOT mutate `.skc/_session-{sessionid}/ultragoal`**, call goal tools, make checkpoint decisions, own integration, or own final verification. The Ultragoal leader keeps those responsibilities.
213
+
214
+ Before workers start, each per-slice coordination contract MUST name the target files/surfaces, independence assumptions, allowed coordination channel, conflict-escalation rule, expected evidence, and terminal status. Conflict or assignment changes remain leader-owned and must be auditable through durable ledger evidence.
215
+
216
+ For failed, timed-out, or contract-violating slices, record durable ledger evidence; preserve successful terminal slices only when safe; and reassign, retry, or collapse the invalid work to serial execution under an updated contract. Completion after parallel work still requires terminal worker evidence, leader integration, targeted verification, and the existing cleaner + architect + executor QA/red-team gate before checkpoint complete.
217
+
218
+ ### Runtime-backed pipelined scheduling
219
+
220
+ Sequential execution remains the default. Ultragoal may use runtime-backed pipelined scheduling only when `goals.json` metadata proves original-plan independence and disjoint target files/surfaces for the prior and next goals. This is a leader-owned Ultragoal runtime contract, not hidden Team scheduling and not a substitute for the native executor parallelism contract above.
221
+
222
+ Pipeline metadata is explicit-only: create eligible goals with `skc ultragoal create-goals --goal-metadata-json '<json>'` or the equivalent runtime `createUltragoalPlan({ goalMetadata })` input. Brief-only or missing metadata remains valid but non-eligible and falls back to ordinary sequential scheduling. The initial pipeline contract is **aggregate mode only**; per-story mode remains sequential until a separate UX/state contract exists.
223
+
224
+ The full lifecycle commands (`start-pipeline-overlap`, `join-pipeline-overlap`, `rebaseline-pipeline-overlap`) and the fail-closed overlap rules — at most one eligible next goal per join window, G(N) remains active until a clean join, quarantine and re-baseline on dirty joins or lost handles, complete checkpoints fail closed on open overlaps or unattributable change-set paths — are specified in the internal `pipeline-validation-contracts` fragment (`skill-fragments/ultragoal/pipeline-validation-contracts.md`). Load that fragment before operating an overlap; the runtime enforces its rules verbatim.
225
+
226
+ Team remains explicit and separate: Team is not auto-launched, not a hidden pipeline scheduler, and never owns Ultragoal goals, checkpoints, or ledger state.
227
+
228
+ ## Validation batches (aggregate-only)
229
+
230
+ Validation batches let several aggregate-mode goals that share one review/QA boundary defer their heavyweight architect + executor QA/red-team review to a single **final member**, while each non-final member still proves targeted verification and cleanup. Validation batches are **aggregate-only**, **explicit-only**, and **fail-closed**. They are created only through `--validation-batch-json`; there is no inference from brief prose and no per-story batching.
231
+
232
+ Batches and #1701 pipeline metadata/overlap are **mutually exclusive**: `--validation-batch-json` and `--goal-metadata-json` cannot be combined, and a goal may not carry both `validationBatch` and eligible `pipelineMetadata`. There is no batch/pipeline mixing.
233
+
234
+ Create a batch explicitly:
235
+
236
+ ```sh
237
+ skc ultragoal create-goals --brief-file <path> --validation-batch-json '[{"schemaVersion":1,"batchId":"VB001","memberIds":["G001","G002","G003"],"finalGoalId":"G003"}]'
238
+ ```
239
+
240
+ Checkpoint contract summary — the full contract lives in the `pipeline-validation-contracts` fragment (`skill-fragments/ultragoal/pipeline-validation-contracts.md`); load it before checkpointing any batch member:
241
+
242
+ - **Non-final members** checkpoint `complete` with a single top-level `deferredToBatch` quality gate (kind `validation-batch-deferred`) proving targeted verification, an ai-slop-cleaner pass, a rerun iteration, and a cumulative-since-base change set — never `architectReview`, `executorQa`, or `validationBatchClose`; deferring never manufactures fake review approvals.
243
+ - **The final member** (`finalGoalId`) checkpoints `complete` with the normal full strict gate PLUS a top-level `validationBatchClose` proof covering all members; out-of-order close is rejected, close state is append-only proof on the final member only, and batch invalidation is fail-closed.
244
+
245
+ ### Intra-goal validation-lane parallelism
246
+
247
+ Within a single goal (including a single-goal run or one validation-batch member), architect review and the executor QA/red-team lane MAY run in parallel, but only on the same **frozen post-cleaner change set**: run the ai-slop-cleaner to a zero-blocker pass and rerun verification first, then hand both lanes the identical frozen change-set summary. Parallel architect + executor QA/red-team lanes must **join before checkpoint** — neither lane may checkpoint independently. Fall back to **sequential** lanes when code is still changing, when the two lanes would see divergent snapshots, when the red-team lane depends on architect fixes, or when architect findings gate the QA scope.
248
+
195
249
  ## Use Ultragoal and Team together
196
250
 
197
251
  Use ultragoal and team together for a durable Ultragoal story that benefits from one visible tmux worker session. Ultragoal remains leader-owned: `.skc/_session-{sessionid}/ultragoal/goals.json` stores the story plan and `.skc/_session-{sessionid}/ultragoal/ledger.jsonl` stores checkpoints. Team is the single-worker tmux execution engine and returns task/evidence status to the leader.
@@ -219,8 +273,8 @@ The completion-gate cleanup sweep is driven by `ai-slop-cleaner`, an internal Ul
219
273
  An ultragoal story cannot be checkpointed `complete` until the active agent has run the quality gate. The gate is plan-first, contract-driven, and surface-based:
220
274
 
221
275
  1. Run targeted implementation verification for the story.
222
- 2. Run the internal ai-slop-cleaner skill fragment as the final cleanup sweep on the story's changed files only, before verification and red-team so only clean code is reviewed. It is a read-only detector that emits an `AI SLOP CLEANUP REPORT`; if there are no relevant edits it still runs and records a passed/no-op report. Every BLOCKING cleaner finding is a completion blocker: the leader spawns an `executor` to fix blocking findings only, then reruns the cleaner until blocking findings are zero. Advisory findings are included in the gate report only and are not written to the Ultragoal ledger. Carry the report through the existing `qualityGate.iteration.evidence` field; do not add a new top-level quality-gate key.
223
- 3. Rerun verification after the cleaner pass.
276
+ 2. Run the internal ai-slop-cleaner skill fragment as the cleanup sweep on the story's changed files only, so only clean code reaches the review and red-team lanes. It is a read-only detector that emits an `AI SLOP CLEANUP REPORT`; if there are no relevant edits it still runs and records a passed/no-op report. Every BLOCKING cleaner finding is a completion blocker: the leader spawns an `executor` to fix blocking findings only, then reruns the cleaner until blocking findings are zero. Advisory findings are included in the gate report only and are not written to the Ultragoal ledger. Carry the report through the existing `qualityGate.iteration.evidence` field; do not add a new top-level quality-gate key.
277
+ 3. Rerun verification after the cleaner pass so reviewed evidence covers the cleaned code.
224
278
  4. Delegate an `architect` review covering all three lanes:
225
279
  - architecture-side: system boundaries, layering, data/control flow, operational risks.
226
280
  - product-side: user-visible behavior, acceptance criteria, edge cases, regressions.
@@ -228,7 +282,7 @@ An ultragoal story cannot be checkpointed `complete` until the active agent has
228
282
  5. Delegate an `executor` QA/red-team lane to build and run the e2e/read-teaming QA suite appropriate for the story. This lane must try to break the change, not just confirm the happy path. It must start from the approved plan/spec/acceptance criteria, then user-facing contracts, and only then implementation code as supporting evidence. Plan/code mismatches are blockers, not items to paper over with implementation intent.
229
283
  6. The executor QA/red-team lane must prove evidence by the real surface under test:
230
284
  - GUI/web surfaces require a valid automation transcript plus a non-uniform screenshot. Bare `inlineEvidence` text or typed receipts never prove live GUI/web execution.
231
- - CLI surfaces require runtime argv replay: `replaySafe: true`, an allowlisted argv `command`, and replayed normalized stdout matching `recordedStdout`. The conservative allowlist is intentionally small: `bun --version`, `node --version`, deterministic `bun/node -e "console.log(...)"`, `npm|pnpm|yarn --version`, `npm|pnpm|yarn list`, read-only `git status|rev-parse|merge-base|diff|show|log` with safe args, and `skc read|status`. Unsafe, non-deterministic, credentialed, interactive, or otherwise unallowlisted commands require audited `replayExempt` metadata with exact fields `reasonCode`, `reason`, `approvedBy`, and `fallbackArtifactRefs` plus a structurally valid fallback artifact. Allowed `reasonCode` values are exactly `unsafe_side_effect`, `requires_credentials`, `requires_network`, `non_deterministic_external`, `destructive`, `interactive_only`, and `platform_unavailable`.
285
+ - CLI surfaces require runtime argv replay: `schemaVersion: 1`, `kind: "cli-replay"`, `replaySafe: true`, an allowlisted argv `command`, and replayed output validation. The complete field-by-field replay schema, command allowlist, and `replayExempt` audit contract are specified once in the "For CLI replay artifacts" paragraph below the quality-gate JSON; follow it exactly.
232
286
  - Native/desktop/tui surfaces require a structurally valid screenshot, PTY capture with terminal control codes, or app-automation transcript.
233
287
  - API/package surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `api`, `package`, `consumer`, `black-box`, or `test-report`; examples: `api-package-test-report`, `package-consumer-report`, `black-box-api-receipt`. Algorithm/math surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `property`, `boundary`, `edge`, `adversarial`, `failure`, `math`, `algorithm`, or `test-report`; examples: `property-test-report`, `algorithm-boundary-report`. Bare `inlineEvidence` text alone is not sufficient for any surface.
234
288
  - The mandatory **computer-use** red-team suite (`kill-switch-bypass`, `suspended-enforcement`, `permission-revoked`, …) is conditional, not universal: require it only when computer/desktop control is genuinely part of the product surface being dogfooded. For every other product type, prove the change through the matching live surface instead — browser-use automation for web/GUI, bash/CLI live invocation or argv replay for CLI, and real artifacts or typed receipts for API/package/algorithm/math. Editing docs, prompts, or skills that merely mention computer-use does not by itself make the computer-use suite applicable; pick the red-team surface that matches what the change actually ships.
@@ -289,7 +343,7 @@ The native `checkpoint --status complete` command rejects missing or shallow gat
289
343
 
290
344
  Provide one `artifactRefs` entry per live surface actually exercised, using the surface-appropriate `kind` and evidence rules from steps 6–7 above; the CLI rejects missing or shallow gates. `status: "not_applicable"` rows are allowed only in `contractCoverage` and `surfaceEvidence` and each requires `contractRef` plus `reason`.
291
345
 
292
- For CLI replay artifacts, the JSON at `path` must be an object like `{"schemaVersion":1,"kind":"cli-replay","replaySafe":true,"command":["bun","-e","console.log(\"ultragoal-cli-ok\")"],"recordedStdout":"ultragoal-cli-ok\n"}`. Use `replayExempt` only for audited unsafe/non-deterministic invocations, with exact fields `reasonCode`, `reason`, `approvedBy`, and `fallbackArtifactRefs`. `reason` must be substantive and audited, `approvedBy` must identify the verifier, and `fallbackArtifactRefs` must reference same-surface structurally valid fallback artifacts. Allowed `reasonCode` values are exactly `unsafe_side_effect`, `requires_credentials`, `requires_network`, `non_deterministic_external`, `destructive`, `interactive_only`, and `platform_unavailable`.
346
+ For CLI replay artifacts, the JSON at `path` must be an object like `{"schemaVersion":1,"kind":"cli-replay","replaySafe":true,"command":["bun","-e","console.log(\"ultragoal-cli-ok\")"],"cwd":".","env":{"LC_ALL":"C"},"timeoutMs":30000,"expectedExitCode":0,"recordedStdout":"ultragoal-cli-ok\n","recordedStderr":"","invariants":[{"type":"substring","value":"ultragoal-cli-ok"},{"type":"not-substring","value":"error"}]}`. Accepted replay fields are `command` (string array), optional `cwd`, safe `env`, `timeoutMs`, `expectedExitCode`, `recordedStdout`, `recordedStderr`, `normalization`, and `invariants`. The conservative command allowlist is intentionally small: `bun --version`, `node --version`, deterministic `bun/node -e "console.log(...)"`, `npm|pnpm|yarn --version`, `npm|pnpm|yarn list`, read-only `git status|rev-parse|merge-base|diff|show|log` with safe args, and `skc read|status`. `env` must contain only safe deterministic variables, never credentials or machine/user-specific secrets. `normalization` is optional and, when provided, must be exactly the string `"default"` (the built-in normalizer already strips ANSI codes, normalizes line endings, scrubs paths, and trims trailing whitespace); object-shaped normalization is rejected. Invariants may be substring, regex, or not-substring checks; when present, they replace exact `recordedStdout` equality — without `invariants`, replayed normalized stdout must match `recordedStdout` exactly. Unsafe, non-deterministic, credentialed, interactive, or otherwise unallowlisted commands require audited `replayExempt` metadata with exact fields `reasonCode`, `reason`, `approvedBy`, and `fallbackArtifactRefs` plus a structurally valid same-surface fallback artifact. `reason` must be substantive and audited, and `approvedBy` must identify the verifier. Allowed `reasonCode` values are exactly `unsafe_side_effect`, `requires_credentials`, `requires_network`, `non_deterministic_external`, `destructive`, `interactive_only`, and `platform_unavailable`.
293
347
 
294
348
  ## Review mode
295
349
 
@@ -299,6 +353,7 @@ Receipts are freshness-scoped:
299
353
  - Per-goal receipts remain fresh for their target goal unless that goal, its blocker metadata, or its supersession metadata changes.
300
354
  - Normal later `goal_started` or clean receipt-backed `goal_checkpointed` events for other goals do not stale older per-goal receipts.
301
355
  - Appending required goals or changing final required-goal state stales final aggregate receipts. Final aggregate completion requires a fresh final aggregate receipt proving no incomplete, blocked, or `review_blocked` required goals remain.
356
+ - Deferred per-goal receipts (validation-batch members) are incomplete until a matching fresh batch-close receipt exists on the batch's `finalGoalId`; a story-scope query for a deferred member stays blocked until that close, and mutating a member after close stales the batch-close and final aggregate receipts.
302
357
 
303
358
  ## Handoff back to planning
304
359
 
@@ -0,0 +1,30 @@
1
+ # Ultragoal Pipeline & Validation-Batch Contracts Fragment
2
+
3
+ Internal Ultragoal sub-skill fragment (`kind: "skill-fragment"`, parent skill `ultragoal`, installed at `skill-fragments/ultragoal/pipeline-validation-contracts.md`). The Ultragoal leader loads it on demand before operating a pipeline overlap or checkpointing a validation-batch member; it is never user-facing, not slash-command discoverable, and never resolvable through `skill://`. The runtime enforces every rule below verbatim and fails closed.
4
+
5
+ ## Runtime-backed pipeline overlap lifecycle
6
+
7
+ Use the lifecycle commands exactly when runtime metadata proves safety:
8
+
9
+ ```sh
10
+ skc ultragoal start-pipeline-overlap --prior-goal-id G001 --next-goal-id G002 --review-handles-json '<json>' --qa-handles-json '<json>' --implementation-handle-json '<json>' --json
11
+ skc ultragoal join-pipeline-overlap --overlap-id <id> --review-result-json '<json>' --qa-result-json '<json>' --json
12
+ skc ultragoal rebaseline-pipeline-overlap --overlap-id <id> --goal-id G002 --evidence "<evidence>" --target-state-json '<json>' --json
13
+ ```
14
+
15
+ Runtime-backed pipelining is deliberately narrow:
16
+
17
+ - At most one eligible next goal may overlap the current goal's review/QA join window.
18
+ - G(N) remains active until `join-pipeline-overlap` records a clean join; do not checkpoint G(N) complete before clean join evidence exists.
19
+ - `start-pipeline-overlap` must fail closed for missing metadata, one-sided independence, shared target files/surfaces, stale metadata hashes, missing handles, another open overlap, or per-story mode.
20
+ - `join-pipeline-overlap` must fail closed for missing lane evidence or unresolved blockers. Continue G(N+1) only when structured blocker footprints are disjoint from G(N+1) targets; otherwise quarantine and re-baseline with `rebaseline-pipeline-overlap` before G(N+1) can complete.
21
+ - Complete checkpoints must fail closed for open overlaps, missing clean joins, stale metadata, quarantined next goals, shared or unattributable change-set paths, and any missing pipeline evidence.
22
+ - After a crash or lost live handles, the leader reruns review/QA lanes and joins with replacement evidence when metadata hashes still match; otherwise quarantine and re-baseline. Ultragoal must not auto-start G(N+2) during recovery.
23
+
24
+ ## Validation-batch checkpoint contract
25
+
26
+ - **Non-final members** checkpoint `complete` with a single top-level `deferredToBatch` quality gate (kind `validation-batch-deferred`): targeted verification, ai-slop-cleaner pass, and a rerun iteration, plus a cumulative-since-base change set. A `deferredToBatch` gate must NOT contain `architectReview`, `executorQa`, or `validationBatchClose` — deferring never manufactures fake review approvals.
27
+ - **The final member** (`finalGoalId`) checkpoints `complete` with the normal full strict gate PLUS a top-level `validationBatchClose` proof that covers all member IDs, member metadata hashes, member receipt/checkpoint-ledger-event IDs, per-member change-set hashes, and union change-set coverage. The final close only starts once every non-final member is already `complete` with a structurally fresh deferred receipt (out-of-order close is rejected).
28
+ - Close state is append-only proof: it lives in the final member's checkpoint receipt and matching `goal_checkpointed` ledger row only. Never stamp `closedReceiptId`/`closedAt` or any close-state field onto member goals, and never append a separate close ledger event.
29
+ - Change sets are cumulative-since-base: each member's `changeSet.paths` is the whole-worktree diff vs base (`cumulativeFromBase: true`), `memberGoalId` is a label not a per-path attribution, and `unionChangeSet.paths` carries no per-goal attribution.
30
+ - Batch invalidation is fail-closed: steering mutations that would invalidate a batch are rejected while any member holds a fresh deferred receipt.
@@ -9,6 +9,9 @@ import deepInterviewSkill from "./skc/skills/deep-interview/SKILL.md" with { typ
9
9
  import ralplanSkill from "./skc/skills/ralplan/SKILL.md" with { type: "text" };
10
10
  import teamSkill from "./skc/skills/team/SKILL.md" with { type: "text" };
11
11
  import aiSlopCleanerFragment from "./skc/skills/ultragoal/ai-slop-cleaner.md" with { type: "text" };
12
+ import pipelineValidationContractsFragment from "./skc/skills/ultragoal/pipeline-validation-contracts.md" with {
13
+ type: "text",
14
+ };
12
15
  import ultragoalSkill from "./skc/skills/ultragoal/SKILL.md" with { type: "text" };
13
16
 
14
17
  export const DEFAULT_SKC_DEFINITION_NAMES = ["deep-interview", "ralplan", "team", "ultragoal"] as const;
@@ -113,6 +116,12 @@ const DEFAULT_SKC_DEFINITIONS: readonly DefaultSkcDefinition[] = [
113
116
  relativePath: "skill-fragments/ultragoal/ai-slop-cleaner.md",
114
117
  content: aiSlopCleanerFragment,
115
118
  },
119
+ {
120
+ kind: "skill-fragment",
121
+ parentSkillName: "ultragoal",
122
+ relativePath: "skill-fragments/ultragoal/pipeline-validation-contracts.md",
123
+ content: pipelineValidationContractsFragment,
124
+ },
116
125
  ];
117
126
 
118
127
  export function getDefaultSkcDefinitions(): readonly DefaultSkcDefinition[] {
@@ -180,6 +180,14 @@ export function buildRuleFromMarkdown(
180
180
  rawMode === "never" || rawMode === "prose-only" || rawMode === "tool-only" || rawMode === "always"
181
181
  ? rawMode
182
182
  : undefined;
183
+ const rawRepeatMode = frontmatter.repeatMode;
184
+ const repeatMode: Rule["repeatMode"] =
185
+ rawRepeatMode === "once" || rawRepeatMode === "after-gap" ? rawRepeatMode : undefined;
186
+ const repeatGap =
187
+ typeof frontmatter.repeatGap === "number" && Number.isInteger(frontmatter.repeatGap) && frontmatter.repeatGap > 0
188
+ ? frontmatter.repeatGap
189
+ : undefined;
190
+
183
191
  return {
184
192
  name: resolvedName,
185
193
  path: filePath,
@@ -190,6 +198,8 @@ export function buildRuleFromMarkdown(
190
198
  condition,
191
199
  scope,
192
200
  interruptMode,
201
+ repeatMode,
202
+ repeatGap,
193
203
  _source: source,
194
204
  };
195
205
  }
@@ -22,6 +22,7 @@ import "../capability/tool";
22
22
  // Import providers (each registers itself on import)
23
23
  import "./agents-md";
24
24
  import "./builtin";
25
+ import "./claude-plugins";
25
26
  import "./cline";
26
27
  import "./agents";
27
28
  import "./cursor";