@tacuchi/agent-workflow-cli 22.4.2 → 24.0.0

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 (295) hide show
  1. package/README.md +39 -3
  2. package/dist/adapters/git-cli.js +59 -17
  3. package/dist/adapters/git-cli.js.map +1 -1
  4. package/dist/adapters/node-file-system.js +55 -1
  5. package/dist/adapters/node-file-system.js.map +1 -1
  6. package/dist/adapters/postgres-readonly-tools.js +277 -0
  7. package/dist/adapters/postgres-readonly-tools.js.map +1 -0
  8. package/dist/application/artifacts-service.js +2 -2
  9. package/dist/application/artifacts-service.js.map +1 -1
  10. package/dist/application/capability/dispatcher.js +2 -2
  11. package/dist/application/capability/dispatcher.js.map +1 -1
  12. package/dist/application/capability/installed-inventory.js +2 -2
  13. package/dist/application/capability/installed-inventory.js.map +1 -1
  14. package/dist/application/capability/readiness.js +1 -1
  15. package/dist/application/capability/readiness.js.map +1 -1
  16. package/dist/application/check-branch-service.js +2 -2
  17. package/dist/application/check-branch-service.js.map +1 -1
  18. package/dist/application/checkpoint/files-touched.js +271 -0
  19. package/dist/application/checkpoint/files-touched.js.map +1 -0
  20. package/dist/application/checkpoint/markdown.js +61 -8
  21. package/dist/application/checkpoint/markdown.js.map +1 -1
  22. package/dist/application/checkpoint/state-reader.js +8 -2
  23. package/dist/application/checkpoint/state-reader.js.map +1 -1
  24. package/dist/application/checkpoint-write-service.js +16 -5
  25. package/dist/application/checkpoint-write-service.js.map +1 -1
  26. package/dist/application/claims-ledger.js +330 -0
  27. package/dist/application/claims-ledger.js.map +1 -0
  28. package/dist/application/claims-recovery.js +338 -0
  29. package/dist/application/claims-recovery.js.map +1 -0
  30. package/dist/application/database-mcp-server.js +168 -0
  31. package/dist/application/database-mcp-server.js.map +1 -0
  32. package/dist/application/database-mcp-stdio.js +137 -0
  33. package/dist/application/database-mcp-stdio.js.map +1 -0
  34. package/dist/application/database-tool-catalog.js +226 -0
  35. package/dist/application/database-tool-catalog.js.map +1 -0
  36. package/dist/application/dev-only-services.js +154 -44
  37. package/dist/application/dev-only-services.js.map +1 -1
  38. package/dist/application/dsn-reader-service.js +1 -1
  39. package/dist/application/elicitation-server.js +382 -0
  40. package/dist/application/elicitation-server.js.map +1 -0
  41. package/dist/application/elicitation-stdio.js +48 -0
  42. package/dist/application/elicitation-stdio.js.map +1 -0
  43. package/dist/application/flow/advance.js +86 -5
  44. package/dist/application/flow/advance.js.map +1 -1
  45. package/dist/application/flow/checkout-observation.js +152 -0
  46. package/dist/application/flow/checkout-observation.js.map +1 -0
  47. package/dist/application/flow/flow-service.js +72 -13
  48. package/dist/application/flow/flow-service.js.map +1 -1
  49. package/dist/application/flow/internal-actions.js +460 -1
  50. package/dist/application/flow/internal-actions.js.map +1 -1
  51. package/dist/application/flow/internal-drive.js +22 -9
  52. package/dist/application/flow/internal-drive.js.map +1 -1
  53. package/dist/application/flow/prove.js +205 -0
  54. package/dist/application/flow/prove.js.map +1 -0
  55. package/dist/application/flow/run-journey.js +15 -0
  56. package/dist/application/flow/run-journey.js.map +1 -0
  57. package/dist/application/flow/run-projection.js +15 -3
  58. package/dist/application/flow/run-projection.js.map +1 -1
  59. package/dist/application/flow/run-state-service.js +19 -4
  60. package/dist/application/flow/run-state-service.js.map +1 -1
  61. package/dist/application/flow/submit.js +250 -72
  62. package/dist/application/flow/submit.js.map +1 -1
  63. package/dist/application/generate-launch-service.js +4 -4
  64. package/dist/application/generate-launch-service.js.map +1 -1
  65. package/dist/application/git-flow-service.js +9 -0
  66. package/dist/application/git-flow-service.js.map +1 -1
  67. package/dist/application/local-proposal.js +9 -0
  68. package/dist/application/local-proposal.js.map +1 -1
  69. package/dist/application/lock-service.js +96 -28
  70. package/dist/application/lock-service.js.map +1 -1
  71. package/dist/application/logging/log-events.js +19 -3
  72. package/dist/application/logging/log-events.js.map +1 -1
  73. package/dist/application/logging/logger.js +2 -2
  74. package/dist/application/logging/logger.js.map +1 -1
  75. package/dist/application/mcp-connections-service.js +115 -41
  76. package/dist/application/mcp-connections-service.js.map +1 -1
  77. package/dist/application/mcp-doctor-service.js +98 -54
  78. package/dist/application/mcp-doctor-service.js.map +1 -1
  79. package/dist/application/mcp-entry-classification.js +60 -0
  80. package/dist/application/mcp-entry-classification.js.map +1 -0
  81. package/dist/application/mcp-host-reader.js +114 -81
  82. package/dist/application/mcp-host-reader.js.map +1 -1
  83. package/dist/application/mcp-host-receipt-service.js +399 -0
  84. package/dist/application/mcp-host-receipt-service.js.map +1 -0
  85. package/dist/application/mcp-host-receipt-store.js +122 -0
  86. package/dist/application/mcp-host-receipt-store.js.map +1 -0
  87. package/dist/application/mcp-host-receipts.js +28 -0
  88. package/dist/application/mcp-host-receipts.js.map +1 -0
  89. package/dist/application/mcp-host-writer.js +321 -126
  90. package/dist/application/mcp-host-writer.js.map +1 -1
  91. package/dist/application/mcp-launch-probe-service.js +142 -0
  92. package/dist/application/mcp-launch-probe-service.js.map +1 -0
  93. package/dist/application/mcp-migration-service.js +351 -0
  94. package/dist/application/mcp-migration-service.js.map +1 -0
  95. package/dist/application/mcp-native-host-check-service.js +154 -0
  96. package/dist/application/mcp-native-host-check-service.js.map +1 -0
  97. package/dist/application/mcp-receipt-registration-service.js +105 -0
  98. package/dist/application/mcp-receipt-registration-service.js.map +1 -0
  99. package/dist/application/mcp-receipt-removal-service.js +62 -0
  100. package/dist/application/mcp-receipt-removal-service.js.map +1 -0
  101. package/dist/application/mcp-remove-service.js +84 -21
  102. package/dist/application/mcp-remove-service.js.map +1 -1
  103. package/dist/application/mcp-scope-common.js +2 -4
  104. package/dist/application/mcp-scope-common.js.map +1 -1
  105. package/dist/application/mcp-setup-service.js +60 -21
  106. package/dist/application/mcp-setup-service.js.map +1 -1
  107. package/dist/application/mcp-stdio-probe.js +526 -0
  108. package/dist/application/mcp-stdio-probe.js.map +1 -0
  109. package/dist/application/mcp-test-connection-service.js +23 -50
  110. package/dist/application/mcp-test-connection-service.js.map +1 -1
  111. package/dist/application/merge-state-service.js +10 -16
  112. package/dist/application/merge-state-service.js.map +1 -1
  113. package/dist/application/multiroot/claude.js +34 -15
  114. package/dist/application/multiroot/claude.js.map +1 -1
  115. package/dist/application/multiroot/codex.js +9 -5
  116. package/dist/application/multiroot/codex.js.map +1 -1
  117. package/dist/application/multiroot-service.js +20 -11
  118. package/dist/application/multiroot-service.js.map +1 -1
  119. package/dist/application/parsers/project-block.js +25 -2
  120. package/dist/application/parsers/project-block.js.map +1 -1
  121. package/dist/application/paths-service.js +30 -31
  122. package/dist/application/paths-service.js.map +1 -1
  123. package/dist/application/plan-exec-batch-service.js +549 -0
  124. package/dist/application/plan-exec-batch-service.js.map +1 -0
  125. package/dist/application/plan-exec-decision-service.js +273 -0
  126. package/dist/application/plan-exec-decision-service.js.map +1 -0
  127. package/dist/application/project-md-service.js +2 -2
  128. package/dist/application/project-md-service.js.map +1 -1
  129. package/dist/application/project-md-upsert-service.js +4 -4
  130. package/dist/application/project-md-upsert-service.js.map +1 -1
  131. package/dist/application/project-tab-data.js +12 -7
  132. package/dist/application/project-tab-data.js.map +1 -1
  133. package/dist/application/release-data-service.js +2 -2
  134. package/dist/application/release-data-service.js.map +1 -1
  135. package/dist/application/resume-service.js +32 -11
  136. package/dist/application/resume-service.js.map +1 -1
  137. package/dist/application/retirement/apply.js +84 -0
  138. package/dist/application/retirement/apply.js.map +1 -1
  139. package/dist/application/retirement/attribution.js +31 -1
  140. package/dist/application/retirement/attribution.js.map +1 -1
  141. package/dist/application/retirement/graph.js +19 -1
  142. package/dist/application/retirement/graph.js.map +1 -1
  143. package/dist/application/retirement/journal.js +11 -0
  144. package/dist/application/retirement/journal.js.map +1 -1
  145. package/dist/application/retirement/prepare.js +89 -3
  146. package/dist/application/retirement/prepare.js.map +1 -1
  147. package/dist/application/retirement/preview.js +16 -0
  148. package/dist/application/retirement/preview.js.map +1 -1
  149. package/dist/application/retirement/resolve.js +65 -0
  150. package/dist/application/retirement/resolve.js.map +1 -1
  151. package/dist/application/self/host-states.js +2 -0
  152. package/dist/application/self/host-states.js.map +1 -1
  153. package/dist/application/self/install-skill.js +21 -17
  154. package/dist/application/self/install-skill.js.map +1 -1
  155. package/dist/application/self/mcp-config.js +392 -84
  156. package/dist/application/self/mcp-config.js.map +1 -1
  157. package/dist/application/self/mcp-via-state.js +62 -0
  158. package/dist/application/self/mcp-via-state.js.map +1 -0
  159. package/dist/application/self/uninstall.js +15 -5
  160. package/dist/application/self/uninstall.js.map +1 -1
  161. package/dist/application/session-close-service.js +24 -1
  162. package/dist/application/session-close-service.js.map +1 -1
  163. package/dist/application/session-create-service.js +7 -0
  164. package/dist/application/session-create-service.js.map +1 -1
  165. package/dist/application/session-resume-service.js +2 -2
  166. package/dist/application/session-resume-service.js.map +1 -1
  167. package/dist/application/sessions-service.js +2 -4
  168. package/dist/application/sessions-service.js.map +1 -1
  169. package/dist/application/skills-resolver-service.js +4 -4
  170. package/dist/application/skills-resolver-service.js.map +1 -1
  171. package/dist/application/source-boundary-policy.js +18 -7
  172. package/dist/application/source-boundary-policy.js.map +1 -1
  173. package/dist/application/source-remove-service.js +12 -1
  174. package/dist/application/source-remove-service.js.map +1 -1
  175. package/dist/application/sources-service.js +2 -2
  176. package/dist/application/sources-service.js.map +1 -1
  177. package/dist/application/status-service.js +4 -0
  178. package/dist/application/status-service.js.map +1 -1
  179. package/dist/application/visibility-doctor-service.js +1 -1
  180. package/dist/application/visibility-doctor-service.js.map +1 -1
  181. package/dist/application/workline-index-service.js +182 -27
  182. package/dist/application/workline-index-service.js.map +1 -1
  183. package/dist/application/workspace-init-service.js +89 -271
  184. package/dist/application/workspace-init-service.js.map +1 -1
  185. package/dist/application/workspace-materialization-service.js +300 -0
  186. package/dist/application/workspace-materialization-service.js.map +1 -0
  187. package/dist/application/worktree-service.js +32 -3
  188. package/dist/application/worktree-service.js.map +1 -1
  189. package/dist/cli/commands/capability.js +4 -7
  190. package/dist/cli/commands/capability.js.map +1 -1
  191. package/dist/cli/commands/claims.js +72 -0
  192. package/dist/cli/commands/claims.js.map +1 -0
  193. package/dist/cli/commands/dev-only.js +73 -25
  194. package/dist/cli/commands/dev-only.js.map +1 -1
  195. package/dist/cli/commands/flow.js +145 -42
  196. package/dist/cli/commands/flow.js.map +1 -1
  197. package/dist/cli/commands/index.js +4 -0
  198. package/dist/cli/commands/index.js.map +1 -1
  199. package/dist/cli/commands/mcp.js +752 -76
  200. package/dist/cli/commands/mcp.js.map +1 -1
  201. package/dist/cli/commands/multiroot.js +40 -7
  202. package/dist/cli/commands/multiroot.js.map +1 -1
  203. package/dist/cli/commands/resume.js +9 -3
  204. package/dist/cli/commands/resume.js.map +1 -1
  205. package/dist/cli/commands/retirement.js +9 -0
  206. package/dist/cli/commands/retirement.js.map +1 -1
  207. package/dist/cli/commands/session-create.js +1 -1
  208. package/dist/cli/commands/session-create.js.map +1 -1
  209. package/dist/cli/commands/skills.js +1 -1
  210. package/dist/cli/commands/skills.js.map +1 -1
  211. package/dist/cli/commands/status.js +72 -24
  212. package/dist/cli/commands/status.js.map +1 -1
  213. package/dist/cli/commands/tool.js +141 -0
  214. package/dist/cli/commands/tool.js.map +1 -0
  215. package/dist/cli/commands/workspace-init.js +5 -5
  216. package/dist/cli/commands/workspace-init.js.map +1 -1
  217. package/dist/cli/help-groups.js +6 -1
  218. package/dist/cli/help-groups.js.map +1 -1
  219. package/dist/cli/main.js +272 -67
  220. package/dist/cli/main.js.map +1 -1
  221. package/dist/cli/parser.js +8 -1
  222. package/dist/cli/parser.js.map +1 -1
  223. package/dist/cli/registry.js.map +1 -1
  224. package/dist/cli/render.js +15 -2
  225. package/dist/cli/render.js.map +1 -1
  226. package/dist/cli/tui/app.js +3 -2
  227. package/dist/cli/tui/app.js.map +1 -1
  228. package/dist/cli/tui/components/workspace-init-form.js +7 -7
  229. package/dist/cli/tui/components/workspace-init-form.js.map +1 -1
  230. package/dist/cli/tui/data/workflow-content.js +2 -2
  231. package/dist/cli/tui/data/workflow-content.js.map +1 -1
  232. package/dist/cli/tui/tabs/config-tab.js +4 -3
  233. package/dist/cli/tui/tabs/config-tab.js.map +1 -1
  234. package/dist/cli/tui/tabs/mcp-tab-helpers.js +72 -1
  235. package/dist/cli/tui/tabs/mcp-tab-helpers.js.map +1 -1
  236. package/dist/cli/tui/tabs/mcp-tab.js +101 -42
  237. package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
  238. package/dist/cli/tui/tabs/project-tab.js +18 -21
  239. package/dist/cli/tui/tabs/project-tab.js.map +1 -1
  240. package/dist/cli/tui/workspace-root.js +13 -0
  241. package/dist/cli/tui/workspace-root.js.map +1 -0
  242. package/dist/domain/capability/protocol.js +2 -2
  243. package/dist/domain/capability/protocol.js.map +1 -1
  244. package/dist/domain/database-tools.js +445 -0
  245. package/dist/domain/database-tools.js.map +1 -0
  246. package/dist/domain/degradation-notice.js +60 -0
  247. package/dist/domain/degradation-notice.js.map +1 -0
  248. package/dist/domain/elicitation.js +152 -0
  249. package/dist/domain/elicitation.js.map +1 -0
  250. package/dist/domain/flow/answer.js +173 -42
  251. package/dist/domain/flow/answer.js.map +1 -1
  252. package/dist/domain/flow/authority.js +184 -127
  253. package/dist/domain/flow/authority.js.map +1 -1
  254. package/dist/domain/flow/directive.js +47 -1
  255. package/dist/domain/flow/directive.js.map +1 -1
  256. package/dist/domain/flow/rules.js +7 -4
  257. package/dist/domain/flow/rules.js.map +1 -1
  258. package/dist/domain/flow/run-state.js +636 -31
  259. package/dist/domain/flow/run-state.js.map +1 -1
  260. package/dist/domain/harnesses.js +16 -0
  261. package/dist/domain/harnesses.js.map +1 -1
  262. package/dist/domain/mcp-entry.js +164 -28
  263. package/dist/domain/mcp-entry.js.map +1 -1
  264. package/dist/domain/postgres-object-search.js +320 -0
  265. package/dist/domain/postgres-object-search.js.map +1 -0
  266. package/dist/domain/redaction.js +47 -0
  267. package/dist/domain/redaction.js.map +1 -0
  268. package/dist/domain/retirement/proposal.js +1 -0
  269. package/dist/domain/retirement/proposal.js.map +1 -1
  270. package/dist/domain/structured-choice-stamp.js +32 -4
  271. package/dist/domain/structured-choice-stamp.js.map +1 -1
  272. package/dist/domain/workline-mcp-entry.js +34 -0
  273. package/dist/domain/workline-mcp-entry.js.map +1 -0
  274. package/dist/ports/postgres-tools.js +10 -0
  275. package/dist/ports/postgres-tools.js.map +1 -0
  276. package/dist/runtime/namespace-resolver.js +104 -18
  277. package/dist/runtime/namespace-resolver.js.map +1 -1
  278. package/package.json +5 -1
  279. package/skills/w/README.md +2 -2
  280. package/skills/w/SKILL.md +9 -10
  281. package/skills/w/artifacts/README.md +1 -1
  282. package/skills/w/commands/README.md +3 -3
  283. package/skills/w/commands/persist.md +3 -1
  284. package/skills/w/commands/resume.md +1 -1
  285. package/skills/w/commands/spec-new.md +2 -2
  286. package/skills/w/commands/status.md +1 -1
  287. package/skills/w/commands/workspace-init.md +9 -10
  288. package/skills/w/context/MANIFEST.json +1 -4
  289. package/skills/w/harness/HARNESS.md +1 -1
  290. package/skills/w/loops/quick-loop/LOOP.md +1 -1
  291. package/skills/w/modules/PROMPT-CONTINUITY.md +1 -1
  292. package/skills/w/modules/WORKSPACE-SCAFFOLD.md +17 -20
  293. package/skills/w/schemas/capability-descriptor.schema.json +1 -1
  294. package/dist/application/mcp-dbhub-launcher.js +0 -216
  295. package/dist/application/mcp-dbhub-launcher.js.map +0 -1
@@ -91,7 +91,7 @@ export const RUN_PLACEHOLDERS = ["{session}", "{code}", "{slug}"];
91
91
  * NEVER interpreted — they stay as the equivalent command a person would run to
92
92
  * obtain the same reading, which is what keeps the two comparable.
93
93
  *
94
- * The four members are exactly the deterministic surface the plan names: the
94
+ * The five members are exactly the deterministic surface the plan names: the
95
95
  * board, the sessions' own artifacts (their reading and their seeding), the close
96
96
  * and the publication of an already approved proposal. Everything that runs code,
97
97
  * touches git or produces a judgment is deliberately NOT here.
@@ -111,6 +111,12 @@ export const INTERNAL_ACTION_OPERATIONS = [
111
111
  "worktree.ensure",
112
112
  /** Write the run's approved proposal, all of it or none of it. */
113
113
  "proposal.publish",
114
+ /** Seal the next plan-execution batch before any of its work is credited. */
115
+ "plan-exec.batch-infer",
116
+ /** Close one sealed plan-execution batch through the document/state CAS. */
117
+ "plan-exec.batch-close",
118
+ /** Seal a fully evidenced PLAN-exec document as done. */
119
+ "plan-exec.plan-done",
114
120
  ];
115
121
  /**
116
122
  * The effect classes each internal operation can really apply.
@@ -134,6 +140,15 @@ export const INTERNAL_OPERATION_EFFECTS = {
134
140
  // Creating and replacing, both real — and which of the two happens is decided
135
141
  // by the proposal, not by the row: what the row declares here is the ceiling.
136
142
  "proposal.publish": ["local_additive", "mutate_overwrite"],
143
+ // Inference writes only the run's sealed ledger. It changes no project
144
+ // artifact and therefore has no capability-world effect to authorize.
145
+ "plan-exec.batch-infer": [],
146
+ // Batch progress always rewrites the current plan document, but only from the
147
+ // exact before/after pair persisted in its v10 batch state.
148
+ "plan-exec.batch-close": ["mutate_overwrite"],
149
+ // The final seal is a deterministic rewrite, guarded by the completed batch,
150
+ // final validation, commit and integration evidence already in the run.
151
+ "plan-exec.plan-done": ["mutate_overwrite"],
137
152
  };
138
153
  /** The delegated action of a transition, or `null` when the engine applies it itself. */
139
154
  export function actionOf(decision) {
@@ -678,16 +693,19 @@ export const FLOW_DECISIONS = [
678
693
  label: "Cambiar a SPEC",
679
694
  consequence: "no se crea sesión quick: la línea de trabajo pasa al flow SPEC con el objetivo original",
680
695
  recommended: true,
696
+ outcome: { kind: "continue" },
681
697
  },
682
698
  {
683
699
  label: "Seguir en quick",
684
700
  consequence: "el recorrido continúa como quick con el objetivo tal cual llegó",
685
701
  recommended: false,
702
+ outcome: { kind: "continue" },
686
703
  },
687
704
  {
688
705
  label: "Recortar alcance",
689
706
  consequence: "el objetivo pasa a ser la sub-tarea que sí entra en un quick y el resto queda en BACKLOG",
690
707
  recommended: false,
708
+ outcome: { kind: "continue" },
691
709
  },
692
710
  ],
693
711
  },
@@ -932,11 +950,13 @@ export const FLOW_DECISIONS = [
932
950
  label: "Aprobar el commit",
933
951
  consequence: "se crea un solo commit al cierre de la tarea; sin push, sin --amend y sin --no-verify",
934
952
  recommended: true,
953
+ outcome: { kind: "continue" },
935
954
  },
936
955
  {
937
956
  label: "Dejar la tarea sin commitear",
938
957
  consequence: "los cambios quedan en el árbol de trabajo y la tarea se registra en BACKLOG",
939
958
  recommended: false,
959
+ outcome: { kind: "continue" },
940
960
  },
941
961
  ],
942
962
  },
@@ -1050,11 +1070,13 @@ export const FLOW_DECISIONS = [
1050
1070
  label: "Dividir en varias specs",
1051
1071
  consequence: "el original queda reducido a su resultado restante y cada resultado extraído nace como spec hermana",
1052
1072
  recommended: true,
1073
+ outcome: { kind: "continue" },
1053
1074
  },
1054
1075
  {
1055
1076
  label: "Una sola spec",
1056
1077
  consequence: "el gap queda agotado para esta corrida y el refinamiento sigue sobre esta spec",
1057
1078
  recommended: false,
1079
+ outcome: { kind: "continue" },
1058
1080
  },
1059
1081
  ],
1060
1082
  },
@@ -1114,11 +1136,13 @@ export const FLOW_DECISIONS = [
1114
1136
  label: "Explorar ideas",
1115
1137
  consequence: "se corre una ronda de ideación y sus veredictos vuelven como un lote propio de la conversación",
1116
1138
  recommended: true,
1139
+ outcome: { kind: "continue" },
1117
1140
  },
1118
1141
  {
1119
1142
  label: "Seguir sin ideación",
1120
1143
  consequence: "el gap queda agotado para esta corrida y el refinamiento sigue sin la ronda",
1121
1144
  recommended: false,
1145
+ outcome: { kind: "continue" },
1122
1146
  },
1123
1147
  ],
1124
1148
  },
@@ -1236,11 +1260,13 @@ export const FLOW_DECISIONS = [
1236
1260
  label: "Aprobar y guardar",
1237
1261
  consequence: "se escriben exactamente los archivos de la vista previa —la spec en su lugar, sellada como ready-for-plan— y no se vuelve a preguntar por esos efectos",
1238
1262
  recommended: true,
1263
+ outcome: { kind: "continue" },
1239
1264
  },
1240
1265
  {
1241
1266
  label: "Refinar",
1242
1267
  consequence: "el refinamiento sigue abierto, no se escribe nada y la spec queda como está",
1243
1268
  recommended: false,
1269
+ outcome: { kind: "continue" },
1244
1270
  },
1245
1271
  ],
1246
1272
  },
@@ -1437,11 +1463,13 @@ export const FLOW_DECISIONS = [
1437
1463
  label: "Dividir en varios planes",
1438
1464
  consequence: "cada tramo se elabora completo como plan hermano, con su origen y el orden entre ellos",
1439
1465
  recommended: true,
1466
+ outcome: { kind: "continue" },
1440
1467
  },
1441
1468
  {
1442
1469
  label: "Un solo plan",
1443
1470
  consequence: "el gap queda agotado para esta corrida y el trabajo sigue como un plan único",
1444
1471
  recommended: false,
1472
+ outcome: { kind: "continue" },
1445
1473
  },
1446
1474
  ],
1447
1475
  },
@@ -1504,11 +1532,13 @@ export const FLOW_DECISIONS = [
1504
1532
  label: "Aprobar y guardar",
1505
1533
  consequence: `se escriben exactamente los archivos de la vista previa en ${PLAN_DOCS_DIR}, hermanos incluidos si el split fue aceptado`,
1506
1534
  recommended: true,
1535
+ outcome: { kind: "continue" },
1507
1536
  },
1508
1537
  {
1509
1538
  label: "Refinar",
1510
1539
  consequence: "la generación sigue abierta y no se escribe ningún documento",
1511
1540
  recommended: false,
1541
+ outcome: { kind: "continue" },
1512
1542
  },
1513
1543
  ],
1514
1544
  },
@@ -1713,11 +1743,13 @@ export const FLOW_DECISIONS = [
1713
1743
  label: "Aprobar y guardar",
1714
1744
  consequence: "se escriben exactamente los archivos de la vista previa —el plan en su lugar y los hermanos extraídos, si los hay— y no se vuelve a preguntar por esos efectos",
1715
1745
  recommended: true,
1746
+ outcome: { kind: "continue" },
1716
1747
  },
1717
1748
  {
1718
1749
  label: "Refinar",
1719
1750
  consequence: "el refinamiento sigue abierto, no se escribe nada y el plan queda como está",
1720
1751
  recommended: false,
1752
+ outcome: { kind: "continue" },
1721
1753
  },
1722
1754
  ],
1723
1755
  },
@@ -1835,14 +1867,38 @@ export const FLOW_DECISIONS = [
1835
1867
  label: "Normalizar y ejecutar",
1836
1868
  consequence: "los bloques de fase se editan en su lugar sin agregar alcance ni mover ninguna frontera, y la ejecución sigue",
1837
1869
  recommended: true,
1870
+ outcome: { kind: "continue" },
1838
1871
  },
1839
1872
  {
1840
1873
  label: "Ir a plan-refine",
1841
1874
  consequence: "la ejecución no arranca: el hallazgo queda en CHECKPOINT y el trabajo sigue en /w:plan-refine",
1842
1875
  recommended: false,
1876
+ outcome: { kind: "handoff", destination: "plan-refine" },
1843
1877
  },
1844
1878
  ],
1845
1879
  },
1880
+ {
1881
+ id: "plan-exec.source-scope",
1882
+ scope: "plan-exec",
1883
+ title: "fijar el plan de la corrida y las fuentes exactas que va a editar",
1884
+ authority: "agent",
1885
+ ownership: "cli-owned",
1886
+ document: CODE_POLICIES_MD,
1887
+ attribution: PLAN_ATTRIBUTION,
1888
+ // Which sources a plan touches is read off the plan, and the engine never read
1889
+ // one — so this is judgment, and it is the only thing here that is. What the
1890
+ // answer hands over is CHECKED before it is persisted: an alias the WORKSPACE
1891
+ // block does not declare, or one the plan never names, is refused. That is the
1892
+ // half a rule can hold; the other half is why the row exists at all.
1893
+ //
1894
+ // It carries no signals on purpose. A vocabulary would be a verdict over a
1895
+ // fixed taxonomy, and the aliases of a workspace are not one.
1896
+ //
1897
+ // It is deliberately outside the repeatable batch segment: every later batch
1898
+ // must inherit the same already-validated plan/sources, never ask to widen
1899
+ // the edit boundary while work is in progress.
1900
+ scopes_sources: true,
1901
+ },
1846
1902
  {
1847
1903
  id: "plan-exec.batch-eligibility-signal",
1848
1904
  scope: "plan-exec",
@@ -1864,6 +1920,21 @@ export const FLOW_DECISIONS = [
1864
1920
  ownership: "cli-owned",
1865
1921
  document: BATCHES_MD,
1866
1922
  attribution: PLAN_ATTRIBUTION,
1923
+ // Its durable snapshot lives in the run ledger, not in the project world.
1924
+ // The plan is read to derive it, but no capability effect is claimed.
1925
+ effects: [],
1926
+ action: {
1927
+ invocation: {
1928
+ program: "aw",
1929
+ args: ["flow", "advance", "--code", "{code}"],
1930
+ target: ".",
1931
+ input: null,
1932
+ },
1933
+ execution: { kind: "internal", operation: "plan-exec.batch-infer" },
1934
+ evidence: ["plan.batch-inferido"],
1935
+ idempotent: true,
1936
+ recovery: "reanudá con 'aw flow advance': el batch inferido conserva su digest y sólo se vuelve a inferir si todavía no quedó sellado",
1937
+ },
1867
1938
  },
1868
1939
  {
1869
1940
  id: "plan-exec.batch-isolation",
@@ -1887,24 +1958,6 @@ export const FLOW_DECISIONS = [
1887
1958
  document: "modules/DESIGN-REFERENCES.md",
1888
1959
  attribution: "`aw designs --plan`",
1889
1960
  },
1890
- {
1891
- id: "plan-exec.source-scope",
1892
- scope: "plan-exec",
1893
- title: "fijar el plan de la corrida y las fuentes exactas que va a editar",
1894
- authority: "agent",
1895
- ownership: "cli-owned",
1896
- document: CODE_POLICIES_MD,
1897
- attribution: PLAN_ATTRIBUTION,
1898
- // Which sources a plan touches is read off the plan, and the engine never read
1899
- // one — so this is judgment, and it is the only thing here that is. What the
1900
- // answer hands over is CHECKED before it is persisted: an alias the WORKSPACE
1901
- // block does not declare, or one the plan never names, is refused. That is the
1902
- // half a rule can hold; the other half is why the row exists at all.
1903
- //
1904
- // It carries no signals on purpose. A vocabulary would be a verdict over a
1905
- // fixed taxonomy, and the aliases of a workspace are not one.
1906
- scopes_sources: true,
1907
- },
1908
1961
  {
1909
1962
  id: "plan-exec.unit-acquisition",
1910
1963
  scope: "plan-exec",
@@ -2035,8 +2088,8 @@ export const FLOW_DECISIONS = [
2035
2088
  document: PLAN_EXEC_LOOP,
2036
2089
  attribution: PLAN_ATTRIBUTION,
2037
2090
  // This row used to declare no action, no alternatives and no effects, so the
2038
- // walk AUTO-APPLIED it and carried on to `pending-effects`, `task-marking`
2039
- // and the commit. Declaring a structural deviation stopped nothing, asked
2091
+ // walk AUTO-APPLIED it and carried on to manual progress writes and the commit.
2092
+ // Declaring a structural deviation stopped nothing, asked
2040
2093
  // nothing and routed nowhere: the structured-choice the doctrine promised
2041
2094
  // existed only in prose. It is a real boundary now, and which way the run
2042
2095
  // leaves is the person's.
@@ -2049,21 +2102,25 @@ export const FLOW_DECISIONS = [
2049
2102
  label: "Registrar la decisión y seguir",
2050
2103
  consequence: "queda una nota de decisión durable sobre el contrato efectivo y la ejecución sigue desde su punto de reanudación; la spec y el plan no se tocan",
2051
2104
  recommended: true,
2105
+ outcome: { kind: "register-decision" },
2052
2106
  },
2053
2107
  {
2054
2108
  label: "Volver a plan-refine",
2055
2109
  consequence: "la desviación es estructural: la corrida para, el plan se reabre con /w:plan-refine y recibe el paquete de escalación ya reunido",
2056
2110
  recommended: false,
2111
+ outcome: { kind: "handoff", destination: "plan-refine" },
2057
2112
  },
2058
2113
  {
2059
2114
  label: "Volver a spec-refine",
2060
2115
  consequence: "la desviación cambia lo prometido: la corrida para y /w:spec-refine recibe el paquete, sin rehacer el análisis",
2061
2116
  recommended: false,
2117
+ outcome: { kind: "handoff", destination: "spec-refine" },
2062
2118
  },
2063
2119
  {
2064
2120
  label: "Escalar a una spec nueva",
2065
2121
  consequence: "lo hallado no compone contra este linaje: nace una spec propia con el diagnóstico, las decisiones y la evidencia ya reunidos",
2066
2122
  recommended: false,
2123
+ outcome: { kind: "handoff", destination: "spec-new" },
2067
2124
  },
2068
2125
  ],
2069
2126
  },
@@ -2087,89 +2144,6 @@ export const FLOW_DECISIONS = [
2087
2144
  otherwise: "la desviación se resolvió componiendo: no hay escalación que empaquetar",
2088
2145
  },
2089
2146
  },
2090
- {
2091
- id: "plan-exec.pending-effects",
2092
- scope: "plan-exec",
2093
- title: "reconocer qué queda por hacer al cerrar el batch",
2094
- authority: "agent",
2095
- ownership: "cli-owned",
2096
- document: PLAN_EXEC_LOOP,
2097
- attribution: PLAN_ATTRIBUTION,
2098
- // The three rows below it write, run or commit — and in a legitimate batch any
2099
- // of the three may have nothing to do: boxes already ticked by an earlier run,
2100
- // phases still pending, a batch with no code. Without this row each of them
2101
- // demanded its effect anyway, so the only truthful answer was to refuse, and a
2102
- // refused boundary that keeps being re-emitted exhausts and stops the run.
2103
- //
2104
- // The signals are POSITIVE — "there IS something to do" — because the engine's
2105
- // threshold is positive: a row applies when its signal was observed and is
2106
- // passed over when it was not. The inverse cannot be expressed, and inverting
2107
- // one by mistake would skip a step that DID apply, crediting work nobody did.
2108
- signals: ["plan.tasks-to-mark", "plan.plan-closable", "plan.commit-pending"],
2109
- },
2110
- {
2111
- id: "plan-exec.task-marking",
2112
- scope: "plan-exec",
2113
- title: "marcar la tarea cuando su trabajo local termina",
2114
- authority: "cli",
2115
- ownership: "cli-owned",
2116
- document: PLAN_EXEC_LOOP,
2117
- attribution: PLAN_ATTRIBUTION,
2118
- effects: ["mutate_overwrite"],
2119
- // The checkbox is the run's own progress mark on the flow's document —
2120
- // bookkeeping under run custody, so no preflight; the board's real reading
2121
- // is still what applies it.
2122
- custody: "run",
2123
- condition: {
2124
- threshold: {
2125
- observed: "plan-exec.pending-effects",
2126
- of: ["plan.tasks-to-mark"],
2127
- min: 1,
2128
- },
2129
- otherwise: "ninguna casilla terminó su trabajo local en este batch: no hay nada que marcar en el plan",
2130
- },
2131
- // The plan-doc is the per-task source of truth, and the engine does not edit
2132
- // it — so the write is delegated and what comes back is the board's count of
2133
- // ticked boxes. "I marked it" is the one thing this contract will not take.
2134
- action: {
2135
- invocation: { program: "aw", args: ["status", "--json"], target: ".", input: null },
2136
- execution: {
2137
- kind: "external",
2138
- reason: "marcar la casilla reescribe el plan-doc, y este motor no lo edita",
2139
- },
2140
- evidence: ["plan.casillas-marcadas"],
2141
- idempotent: true,
2142
- recovery: "marcá la casilla de la tarea cuyo trabajo local terminó y volvé a devolver la lectura del tablero; marcar de nuevo lo ya marcado no rompe nada",
2143
- },
2144
- },
2145
- {
2146
- id: "plan-exec.phase-state-transition",
2147
- scope: "plan-exec",
2148
- title: "aplicar la transición de estado de fase con sus precondiciones",
2149
- authority: "cli",
2150
- ownership: "cli-owned",
2151
- document: PLAN_EXEC_LOOP,
2152
- attribution: PLAN_ATTRIBUTION,
2153
- effects: ["mutate_overwrite"],
2154
- // The `> Estado:` line is the run's own phase ledger on the flow's document:
2155
- // run custody, no preflight — the precondition below is what really guards it.
2156
- custody: "run",
2157
- // The precondition is what this row exists for: `validada` requires the proof
2158
- // to have RUN and passed, never the checkboxes. The state line is a write on a
2159
- // document the engine does not own, so the board's reading of that line is the
2160
- // evidence — and the board is the same thing that calls a plan `inconsistent`
2161
- // when a state and its boxes disagree.
2162
- action: {
2163
- invocation: { program: "aw", args: ["status", "--json"], target: ".", input: null },
2164
- execution: {
2165
- kind: "external",
2166
- reason: "escribir el '> Estado:' de la fase reescribe el plan-doc, y este motor no lo edita",
2167
- },
2168
- evidence: ["plan.estado-de-fase-aplicado"],
2169
- idempotent: true,
2170
- recovery: "escribí el '> Estado:' que la fase realmente tiene —con su '> Bloqueo:' si quedó bloqueada— y volvé a devolver la lectura; una fase sin su prueba corrida no pasa a validada",
2171
- },
2172
- },
2173
2147
  {
2174
2148
  id: "plan-exec.validation-execution",
2175
2149
  scope: "plan-exec",
@@ -2221,6 +2195,33 @@ export const FLOW_DECISIONS = [
2221
2195
  document: CODE_POLICIES_MD,
2222
2196
  attribution: PLAN_ATTRIBUTION,
2223
2197
  },
2198
+ {
2199
+ id: "plan-exec.batch-close",
2200
+ scope: "plan-exec",
2201
+ title: "publicar el cierre acreditado del batch en el plan y su traza v10",
2202
+ authority: "cli",
2203
+ ownership: "cli-owned",
2204
+ document: BATCHES_MD,
2205
+ attribution: PLAN_ATTRIBUTION,
2206
+ effects: ["mutate_overwrite"],
2207
+ custody: "run",
2208
+ // The phase validation and review are immediately before this row. Reaching
2209
+ // it is the only authorization for the deterministic publication: the
2210
+ // service derives the next unchecked phase, seals its exact before/after
2211
+ // bytes, writes the intent, and then commits the plan/state CAS.
2212
+ action: {
2213
+ invocation: {
2214
+ program: "aw",
2215
+ args: ["flow", "advance", "--code", "{code}"],
2216
+ target: ".",
2217
+ input: null,
2218
+ },
2219
+ execution: { kind: "internal", operation: "plan-exec.batch-close" },
2220
+ evidence: ["plan.batch-publicado"],
2221
+ idempotent: true,
2222
+ recovery: "reanudá con 'aw flow advance': el batch conserva su before/after sellado y o termina exactamente esa publicación o rechaza el plan movido",
2223
+ },
2224
+ },
2224
2225
  {
2225
2226
  id: "plan-exec.final-validation",
2226
2227
  scope: "plan-exec",
@@ -2282,11 +2283,13 @@ export const FLOW_DECISIONS = [
2282
2283
  label: "Aprobar los commits del batch",
2283
2284
  consequence: "se crea exactamente un commit por fuente afectada; sin push, sin --amend y sin --no-verify",
2284
2285
  recommended: true,
2286
+ outcome: { kind: "continue" },
2285
2287
  },
2286
2288
  {
2287
2289
  label: "Dejar el batch sin commitear",
2288
2290
  consequence: "los cambios quedan en el árbol de trabajo y el batch se registra sin commitear en CHECKPOINT y BACKLOG",
2289
2291
  recommended: false,
2292
+ outcome: { kind: "continue" },
2290
2293
  },
2291
2294
  ],
2292
2295
  },
@@ -2299,14 +2302,6 @@ export const FLOW_DECISIONS = [
2299
2302
  document: CODE_POLICIES_MD,
2300
2303
  attribution: PLAN_ATTRIBUTION,
2301
2304
  effects: ["execute", "local_additive"],
2302
- condition: {
2303
- threshold: {
2304
- observed: "plan-exec.pending-effects",
2305
- of: ["plan.commit-pending"],
2306
- min: 1,
2307
- },
2308
- otherwise: "ninguna fuente afectada quedó con cambios sin commitear: no hay commit que crear",
2309
- },
2310
2305
  // Approving is not committing: the human approval above already carries the
2311
2306
  // grant over this row's exact seal, and what applies the transition is still
2312
2307
  // the real git state coming back — which is also the between-unit precondition
@@ -2390,23 +2385,17 @@ export const FLOW_DECISIONS = [
2390
2385
  // The done seal is the last progress mark of the flow's own document: run
2391
2386
  // custody — its condition and the board's reading are the guards that count.
2392
2387
  custody: "run",
2393
- condition: {
2394
- threshold: {
2395
- observed: "plan-exec.pending-effects",
2396
- of: ["plan.plan-closable"],
2397
- min: 1,
2398
- },
2399
- otherwise: "al plan le quedan fases sin validar: sellarlo acá sería marcarlo done desde los contadores",
2400
- },
2401
2388
  action: {
2402
- invocation: { program: "aw", args: ["status", "--json"], target: ".", input: null },
2403
- execution: {
2404
- kind: "external",
2405
- reason: "sellar el done reescribe el plan-doc, y este motor no lo edita",
2389
+ invocation: {
2390
+ program: "aw",
2391
+ args: ["flow", "advance", "--code", "{code}"],
2392
+ target: ".",
2393
+ input: null,
2406
2394
  },
2395
+ execution: { kind: "internal", operation: "plan-exec.plan-done" },
2407
2396
  evidence: ["plan.estado-done-sellado"],
2408
2397
  idempotent: true,
2409
- recovery: "escribí '> Estado: done' y su '> Cierre:' en la línea de abajo y volvé a devolver la lectura; si el tablero no lo lee cerrado, la transición sigue pendiente",
2398
+ recovery: "reanudá con 'aw flow advance': el CLI vuelve a comprobar tareas, fases, reconciliación, validación final e integración antes de sellar exactamente el estado done y su cierre",
2410
2399
  },
2411
2400
  },
2412
2401
  // ── Transversal commands (universe = the command registry) ────────────────
@@ -2682,9 +2671,9 @@ export const FLOW_DECISIONS = [
2682
2671
  attribution: "`aw designs`",
2683
2672
  },
2684
2673
  {
2685
- id: "workspace-init.scaffold",
2674
+ id: "workspace-init.materialize-or-configure",
2686
2675
  scope: cmd("workspace-init"),
2687
- title: "sembrar el andamiaje mínimo del workspace",
2676
+ title: "materializar el runtime mínimo o configurar fuentes explícitas del workspace",
2688
2677
  authority: "cli",
2689
2678
  ownership: "cli-owned",
2690
2679
  document: "modules/WORKSPACE-SCAFFOLD.md",
@@ -2771,6 +2760,10 @@ export const COMMAND_EXCLUSIONS = [
2771
2760
  command: "reset",
2772
2761
  reason: "comando transversal de retiro: mismo contrato que `discard` en modo restauración, sin corrida propia por la misma razón — la sesión que vuelve atrás es la que se retira",
2773
2762
  },
2763
+ {
2764
+ command: "claims",
2765
+ reason: "comando transversal de reservas: mismo contrato que `discard` y `reset` —vista previa y `--approval` con el digest recomputado sobre el árbol vivo— y sin corrida propia por una razón más fuerte todavía, porque la reserva que libera puede ser la de la corrida que lo dirigiera. Su autoridad es el orden que aplica: comprobar que el marcador sigue intacto, sellar la revocación irrevocable acotada al claim y sólo después liberar",
2766
+ },
2774
2767
  { command: "sessions", reason: "listado read-only del inventario de sesiones" },
2775
2768
  { command: "session-artifacts", reason: "inspección read-only de lo que guarda una sesión" },
2776
2769
  { command: "checkpoint-read", reason: "lectura del CHECKPOINT sin decidir continuación" },
@@ -2813,6 +2806,10 @@ export const COMMAND_EXCLUSIONS = [
2813
2806
  { command: "release-data", reason: "datos de release del paquete" },
2814
2807
  { command: "hook", reason: "punto de entrada de los hooks del host" },
2815
2808
  { command: "mcp", reason: "configuración de servidores MCP" },
2809
+ {
2810
+ command: "tool",
2811
+ reason: "ejecutor directo de tools registradas: valida y llama el catálogo sin abrir un recorrido",
2812
+ },
2816
2813
  { command: "self", reason: "instalación y mantenimiento del propio CLI" },
2817
2814
  { command: "harness", reason: "dev-only: inspección del harness" },
2818
2815
  { command: "profiles", reason: "dev-only: perfiles de ejecución" },
@@ -2843,6 +2840,66 @@ export function journeyOfFlow(flow) {
2843
2840
  const at = (placement) => transversal.filter((decision) => decision.placement === placement);
2844
2841
  return [...at("prefix"), ...decisionsOfScope(flow), ...at("suffix")];
2845
2842
  }
2843
+ /**
2844
+ * The actual cursor journey for a persisted run.
2845
+ *
2846
+ * PLAN-exec alone has a repeatable middle: every sealed batch appends another
2847
+ * copy of `batch-inference … batch-close` to the journey while an open phase
2848
+ * remains. The cursor therefore remains a normal append-only prefix — it never
2849
+ * rewinds to make a second batch look like a first one — and the final close
2850
+ * simply stops adding a copy, exposing final validation, Git and `done`.
2851
+ *
2852
+ * This intentionally accepts only the small state shape it reads, avoiding a
2853
+ * runtime dependency back from the authority registry to the run-state domain.
2854
+ */
2855
+ export function journeyForState(state, baseJourney) {
2856
+ // The runtime normally supplies no base, so this reads the registry directly.
2857
+ // A controlled host may supply its own fixture journey: PLAN-exec still adds
2858
+ // its cursor only when that journey actually contains the batch segment.
2859
+ const base = baseJourney ?? journeyOfFlow(state.flow);
2860
+ if (state.flow !== "plan-exec")
2861
+ return base;
2862
+ const first = base.findIndex((decision) => decision.id === "plan-exec.batch-eligibility-signal");
2863
+ const last = base.findIndex((decision) => decision.id === "plan-exec.batch-close");
2864
+ // A registry build missing either boundary must keep the ordinary path rather
2865
+ // than manufacture a cursor whose ids no longer correspond to a real row.
2866
+ if (first < 0 || last < first)
2867
+ return base;
2868
+ // An inferred batch belongs to the iteration currently being walked. Counting
2869
+ // it as another completed segment would insert an unearned copy between
2870
+ // inference and implementation. A segment becomes historical only when its
2871
+ // document publication sealed an after-digest.
2872
+ const closed = state.batches?.filter((batch) => batch.published_plan_digest !== undefined).length ?? 0;
2873
+ // A v10 file written before `batch_loop` cannot say whether an already recorded
2874
+ // batch had another phase after it. Preserve its linear history. A brand-new
2875
+ // run is the one safe default: it has to walk its first batch segment.
2876
+ const pending = state.batch_loop?.pending ?? closed === 0;
2877
+ const copies = closed + (pending ? 1 : 0);
2878
+ // A plan can arrive already fully accredited (the 7/9 recovery reaches this
2879
+ // branch only after its last real batch; a legacy 9/9 plan reaches it on its
2880
+ // first inference). The eligibility answer and inference action have already
2881
+ // been appended, so removing their segment would make the cursor inconsistent.
2882
+ // Keep just those two rows, then expose final validation without inventing an
2883
+ // empty batch or walking isolation/implementation over work that does not exist.
2884
+ const inference = base.findIndex((decision) => decision.id === "plan-exec.batch-inference");
2885
+ const noWorkInferenceStarted = copies === 0 &&
2886
+ inference >= first &&
2887
+ (state.applied?.includes("plan-exec.batch-inference") === true ||
2888
+ state.boundary === "plan-exec.batch-inference");
2889
+ if (noWorkInferenceStarted) {
2890
+ return [...base.slice(0, first), ...base.slice(first, inference + 1), ...base.slice(last + 1)];
2891
+ }
2892
+ if (copies === 0)
2893
+ return [...base.slice(0, first), ...base.slice(last + 1)];
2894
+ if (copies === 1)
2895
+ return base;
2896
+ const segment = base.slice(first, last + 1);
2897
+ return [
2898
+ ...base.slice(0, first),
2899
+ ...Array.from({ length: copies }, () => segment).flat(),
2900
+ ...base.slice(last + 1),
2901
+ ];
2902
+ }
2846
2903
  /**
2847
2904
  * The `docs/` folders a flow may write, as the chassis' boundary states them.
2848
2905
  *