@topogram/cli 0.3.64 → 0.3.66

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 (278) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +716 -0
  3. package/src/adoption/plan.js +12 -703
  4. package/src/adoption/reporting.js +1 -1
  5. package/src/agent-brief.js +7 -21
  6. package/src/agent-ops/query-builders/auth.js +375 -0
  7. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  8. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  9. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  10. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  11. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  12. package/src/agent-ops/query-builders/change-risk.js +25 -0
  13. package/src/agent-ops/query-builders/common.js +149 -0
  14. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  15. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  16. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  17. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  18. package/src/agent-ops/query-builders/work-packets.js +417 -0
  19. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  20. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  21. package/src/agent-ops/query-builders/workflow-presets-core.js +677 -0
  22. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  23. package/src/agent-ops/query-builders.d.ts +26 -26
  24. package/src/agent-ops/query-builders.js +42 -5021
  25. package/src/archive/jsonl.js +2 -2
  26. package/src/archive/resolver-bridge.js +1 -1
  27. package/src/archive/unarchive.js +2 -1
  28. package/src/catalog/constants.js +10 -0
  29. package/src/catalog/copy.js +65 -0
  30. package/src/catalog/diagnostics.js +15 -0
  31. package/src/catalog/entries.js +42 -0
  32. package/src/catalog/files.js +67 -0
  33. package/src/catalog/provenance.js +123 -0
  34. package/src/catalog/source.js +150 -0
  35. package/src/catalog/validation.js +252 -0
  36. package/src/catalog.d.ts +2 -0
  37. package/src/catalog.js +18 -746
  38. package/src/cli/command-parsers/project.js +3 -0
  39. package/src/cli/command-parsers/shared.js +1 -1
  40. package/src/cli/commands/agent.js +2 -2
  41. package/src/cli/commands/catalog/check.js +31 -0
  42. package/src/cli/commands/catalog/copy.js +59 -0
  43. package/src/cli/commands/catalog/doctor.js +248 -0
  44. package/src/cli/commands/catalog/help.js +21 -0
  45. package/src/cli/commands/catalog/list.js +52 -0
  46. package/src/cli/commands/catalog/runner.js +92 -0
  47. package/src/cli/commands/catalog/shared.js +17 -0
  48. package/src/cli/commands/catalog/show.js +134 -0
  49. package/src/cli/commands/catalog.js +30 -615
  50. package/src/cli/commands/check.js +3 -3
  51. package/src/cli/commands/doctor.js +2 -9
  52. package/src/cli/commands/generator-policy/package-info.js +162 -0
  53. package/src/cli/commands/generator-policy/payloads.js +372 -0
  54. package/src/cli/commands/generator-policy/printers.js +159 -0
  55. package/src/cli/commands/generator-policy/runner.js +81 -0
  56. package/src/cli/commands/generator-policy/shared.js +39 -0
  57. package/src/cli/commands/generator-policy.js +15 -783
  58. package/src/cli/commands/import/adopt.js +170 -0
  59. package/src/cli/commands/import/check.js +91 -0
  60. package/src/cli/commands/import/diff.js +84 -0
  61. package/src/cli/commands/import/help.js +47 -0
  62. package/src/cli/commands/import/paths.js +269 -0
  63. package/src/cli/commands/import/plan.js +292 -0
  64. package/src/cli/commands/import/refresh.js +471 -0
  65. package/src/cli/commands/import/status-history.js +196 -0
  66. package/src/cli/commands/import/workspace.js +233 -0
  67. package/src/cli/commands/import.js +33 -1732
  68. package/src/cli/commands/migrate.js +153 -0
  69. package/src/cli/commands/package/constants.js +17 -0
  70. package/src/cli/commands/package/doctor.js +240 -0
  71. package/src/cli/commands/package/help.js +27 -0
  72. package/src/cli/commands/package/lockfile.js +135 -0
  73. package/src/cli/commands/package/npm.js +97 -0
  74. package/src/cli/commands/package/reporting.js +35 -0
  75. package/src/cli/commands/package/runner.js +33 -0
  76. package/src/cli/commands/package/shared.js +9 -0
  77. package/src/cli/commands/package/update-cli.js +252 -0
  78. package/src/cli/commands/package/versions.js +35 -0
  79. package/src/cli/commands/package.js +29 -813
  80. package/src/cli/commands/query/change-plan.js +68 -0
  81. package/src/cli/commands/query/definitions.js +202 -0
  82. package/src/cli/commands/query/import-adopt.js +121 -0
  83. package/src/cli/commands/query/runner/artifacts.js +102 -0
  84. package/src/cli/commands/query/runner/boundaries.js +211 -0
  85. package/src/cli/commands/query/runner/change.js +182 -0
  86. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  87. package/src/cli/commands/query/runner/index.js +31 -0
  88. package/src/cli/commands/query/runner/output.js +12 -0
  89. package/src/cli/commands/query/runner/workflow.js +241 -0
  90. package/src/cli/commands/query/runner.js +3 -0
  91. package/src/cli/commands/query/workflow-context.js +5 -0
  92. package/src/cli/commands/query/workspace.js +270 -0
  93. package/src/cli/commands/query.js +9 -1300
  94. package/src/cli/commands/source.js +3 -12
  95. package/src/cli/commands/template/baseline.js +100 -0
  96. package/src/cli/commands/template/check.js +467 -0
  97. package/src/cli/commands/template/constants.js +8 -0
  98. package/src/cli/commands/template/diagnostics.js +26 -0
  99. package/src/cli/commands/template/help.js +28 -0
  100. package/src/cli/commands/template/lifecycle.js +404 -0
  101. package/src/cli/commands/template/list-show.js +287 -0
  102. package/src/cli/commands/template/policy.js +422 -0
  103. package/src/cli/commands/template/shared.js +127 -0
  104. package/src/cli/commands/template/updates.js +352 -0
  105. package/src/cli/commands/template-runner.js +6 -6
  106. package/src/cli/commands/template.js +41 -2143
  107. package/src/cli/commands/trust.js +1 -1
  108. package/src/cli/commands/workflow.js +6 -1
  109. package/src/cli/dispatcher.js +6 -1
  110. package/src/cli/help.js +15 -14
  111. package/src/cli/migration-guidance.js +1 -1
  112. package/src/cli/output-safety.js +2 -1
  113. package/src/cli/path-normalization.js +3 -13
  114. package/src/generator/api/contracts.js +497 -0
  115. package/src/generator/api/metadata.js +221 -0
  116. package/src/generator/api/openapi.js +559 -0
  117. package/src/generator/api/schema.js +124 -0
  118. package/src/generator/api/types.d.ts +98 -0
  119. package/src/generator/api.js +3 -1195
  120. package/src/generator/context/domain-page.js +1 -1
  121. package/src/generator/context/shared/domain-sdlc.js +282 -0
  122. package/src/generator/context/shared/maintained-boundary.js +665 -0
  123. package/src/generator/context/shared/metrics.js +85 -0
  124. package/src/generator/context/shared/primitives.js +64 -0
  125. package/src/generator/context/shared/relationships.js +453 -0
  126. package/src/generator/context/shared/summaries.js +263 -0
  127. package/src/generator/context/shared/types.d.ts +207 -0
  128. package/src/generator/context/shared.d.ts +42 -0
  129. package/src/generator/context/shared.js +80 -1390
  130. package/src/generator/context/slice/core.js +397 -0
  131. package/src/generator/context/slice/sdlc.js +417 -0
  132. package/src/generator/context/slice/ui-packets.js +183 -0
  133. package/src/generator/context/slice.js +2 -859
  134. package/src/generator/context/task-mode.js +2 -2
  135. package/src/generator/registry/index.js +507 -0
  136. package/src/generator/registry.js +18 -504
  137. package/src/generator/runtime/environment/index.js +666 -0
  138. package/src/generator/runtime/environment.js +4 -666
  139. package/src/generator/runtime/runtime-check/index.js +554 -0
  140. package/src/generator/runtime/runtime-check.js +4 -554
  141. package/src/generator/runtime/shared/index.js +572 -0
  142. package/src/generator/runtime/shared.js +19 -570
  143. package/src/generator/sdlc/doc-page.js +1 -1
  144. package/src/generator/shared.d.ts +2 -0
  145. package/src/generator/surfaces/databases/lifecycle-shared.js +1 -1
  146. package/src/generator/surfaces/native/swiftui-templates/README.generated.md +1 -1
  147. package/src/generator/surfaces/shared.d.ts +3 -0
  148. package/src/generator/widget-conformance/behavior-report.js +258 -0
  149. package/src/generator/widget-conformance/checks.js +371 -0
  150. package/src/generator/widget-conformance/projection-context.js +200 -0
  151. package/src/generator/widget-conformance/report.js +166 -0
  152. package/src/generator/widget-conformance/types.d.ts +121 -0
  153. package/src/generator/widget-conformance.js +3 -824
  154. package/src/import/core/context.d.ts +3 -0
  155. package/src/import/core/context.js +5 -7
  156. package/src/import/core/contracts.d.ts +1 -0
  157. package/src/import/core/registry.d.ts +4 -0
  158. package/src/import/core/runner/candidates.js +337 -0
  159. package/src/import/core/runner/options.js +22 -0
  160. package/src/import/core/runner/reports.js +51 -0
  161. package/src/import/core/runner/run.js +79 -0
  162. package/src/import/core/runner/tracks.js +150 -0
  163. package/src/import/core/runner/ui-drafts.js +393 -0
  164. package/src/import/core/runner.js +3 -698
  165. package/src/import/core/shared/api-routes.js +221 -0
  166. package/src/import/core/shared/candidates.js +97 -0
  167. package/src/import/core/shared/files.js +177 -0
  168. package/src/import/core/shared/next-app.js +389 -0
  169. package/src/import/core/shared/types.d.ts +51 -0
  170. package/src/import/core/shared/ui-routes.js +230 -0
  171. package/src/import/core/shared.js +60 -861
  172. package/src/new-project/constants.js +128 -0
  173. package/src/new-project/create.js +90 -0
  174. package/src/new-project/json.js +28 -0
  175. package/src/new-project/metadata.js +96 -0
  176. package/src/new-project/package-spec.js +161 -0
  177. package/src/new-project/project-files.js +351 -0
  178. package/src/new-project/template-policy.js +269 -0
  179. package/src/new-project/template-resolution.js +370 -0
  180. package/src/new-project/template-snapshots.js +442 -0
  181. package/src/new-project/template-updates.js +512 -0
  182. package/src/new-project/types.d.ts +83 -0
  183. package/src/new-project.js +6 -2277
  184. package/src/parser.d.ts +87 -1
  185. package/src/parser.js +118 -0
  186. package/src/policy/review-boundaries.d.ts +15 -0
  187. package/src/project-config/index.js +591 -0
  188. package/src/project-config.js +19 -561
  189. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  190. package/src/resolver/enrich/bug.js +2 -0
  191. package/src/resolver/enrich/pitch.js +2 -0
  192. package/src/resolver/enrich/requirement.js +2 -0
  193. package/src/resolver/enrich/task.js +2 -0
  194. package/src/resolver/index.js +19 -2089
  195. package/src/resolver/normalize.js +384 -1
  196. package/src/resolver/plans.js +168 -0
  197. package/src/resolver/projections-api.js +494 -0
  198. package/src/resolver/projections-db.js +133 -0
  199. package/src/resolver/projections-ui.js +317 -0
  200. package/src/resolver/shapes.js +251 -0
  201. package/src/resolver/shared.js +278 -0
  202. package/src/resolver/widgets.js +132 -0
  203. package/src/sdlc/adopt.js +6 -5
  204. package/src/sdlc/paths.js +3 -5
  205. package/src/sdlc/scaffold.js +2 -1
  206. package/src/template-trust/constants.js +62 -0
  207. package/src/template-trust/content.js +258 -0
  208. package/src/template-trust/diff.js +92 -0
  209. package/src/template-trust/policy.js +61 -0
  210. package/src/template-trust/record.js +90 -0
  211. package/src/template-trust/status.js +182 -0
  212. package/src/template-trust.js +24 -687
  213. package/src/text-helpers.d.ts +1 -0
  214. package/src/topogram-types.d.ts +69 -0
  215. package/src/validator/common.js +488 -0
  216. package/src/validator/data-model.js +237 -0
  217. package/src/validator/docs.js +167 -0
  218. package/src/validator/expressions.js +146 -1
  219. package/src/validator/index.d.ts +23 -0
  220. package/src/validator/index.js +32 -3585
  221. package/src/validator/kinds.d.ts +41 -0
  222. package/src/validator/kinds.js +2 -0
  223. package/src/validator/model-helpers.js +46 -0
  224. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  225. package/src/validator/per-kind/bug.js +6 -0
  226. package/src/validator/per-kind/domain.js +15 -2
  227. package/src/validator/per-kind/pitch.js +7 -0
  228. package/src/validator/per-kind/requirement.js +5 -0
  229. package/src/validator/per-kind/task.js +7 -0
  230. package/src/validator/per-kind/widget.js +14 -0
  231. package/src/validator/projections/api-http-async.js +410 -0
  232. package/src/validator/projections/api-http-authz.js +88 -0
  233. package/src/validator/projections/api-http-core.js +205 -0
  234. package/src/validator/projections/api-http-policies.js +339 -0
  235. package/src/validator/projections/api-http-responses.js +233 -0
  236. package/src/validator/projections/api-http.js +44 -0
  237. package/src/validator/projections/db.js +353 -0
  238. package/src/validator/projections/generator-defaults.js +45 -0
  239. package/src/validator/projections/helpers.js +87 -0
  240. package/src/validator/projections/ui-helpers.js +214 -0
  241. package/src/validator/projections/ui-navigation.js +344 -0
  242. package/src/validator/projections/ui-structure.js +364 -0
  243. package/src/validator/projections/ui-widgets.js +493 -0
  244. package/src/validator/projections/ui.js +46 -0
  245. package/src/validator/registry.js +48 -1
  246. package/src/validator/utils.d.ts +20 -0
  247. package/src/validator/utils.js +115 -12
  248. package/src/widget-behavior.d.ts +1 -0
  249. package/src/workflows/import-app/api/collect.js +221 -0
  250. package/src/workflows/import-app/api/openapi.js +257 -0
  251. package/src/workflows/import-app/api/routes.js +327 -0
  252. package/src/workflows/import-app/api/sources.js +22 -0
  253. package/src/workflows/import-app/api.js +2 -797
  254. package/src/workflows/reconcile/adoption-plan/build.js +212 -0
  255. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  256. package/src/workflows/reconcile/adoption-plan/outputs.js +153 -0
  257. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  258. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  259. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  260. package/src/workflows/reconcile/adoption-plan.js +30 -740
  261. package/src/workflows/reconcile/auth/closures.js +115 -0
  262. package/src/workflows/reconcile/auth/formatters.js +142 -0
  263. package/src/workflows/reconcile/auth/inference.js +330 -0
  264. package/src/workflows/reconcile/auth/roles.js +122 -0
  265. package/src/workflows/reconcile/auth.js +35 -690
  266. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  267. package/src/workflows/reconcile/bundle-core.js +12 -598
  268. package/src/workflows/reconcile/candidate-model.js +18 -2
  269. package/src/workflows/reconcile/canonical-surface.js +1 -1
  270. package/src/workflows/reconcile/impacts/adoption-plan.js +196 -0
  271. package/src/workflows/reconcile/impacts/indexes.js +105 -0
  272. package/src/workflows/reconcile/impacts/patches.js +252 -0
  273. package/src/workflows/reconcile/impacts/reports.js +80 -0
  274. package/src/workflows/reconcile/impacts.js +14 -623
  275. package/src/workflows/reconcile/renderers.js +41 -6
  276. package/src/workflows/shared.js +5 -11
  277. package/src/workspace-docs.d.ts +29 -0
  278. package/src/workspace-paths.js +328 -0
@@ -0,0 +1,300 @@
1
+ import {
2
+ WORKFLOW_QUERY_FAMILIES_BY_MODE,
3
+ stableSortedStrings
4
+ } from "./common.js";
5
+ export function outputIdsForWorkflowContext(taskModeArtifact, maintainedBoundary = null) {
6
+ return stableSortedStrings([
7
+ ...((taskModeArtifact?.verification_targets?.output_verification_targets || []).map((entry) => entry.output_id)),
8
+ ...((maintainedBoundary?.outputs || []).map((entry) => entry.output_id))
9
+ ]);
10
+ }
11
+
12
+ export function integrationCategoriesForWorkflowContext(taskModeArtifact, importPlan = null) {
13
+ const categories = [];
14
+ if (taskModeArtifact?.mode === "import-adopt") categories.push("provider_adoption");
15
+ if (taskModeArtifact?.mode === "maintained-app-edit") categories.push("maintained_app");
16
+ if ((taskModeArtifact?.verification_targets?.maintained_app_checks || []).length > 0) categories.push("maintained_boundary");
17
+ if ((importPlan?.requires_human_review || []).length > 0) categories.push("human_review");
18
+ return stableSortedStrings(categories);
19
+ }
20
+
21
+ export function currentFocusFromTaskMode(taskModeArtifact) {
22
+ const selectedSurface = taskModeArtifact?.summary?.selected_surface || null;
23
+ if (selectedSurface) {
24
+ return selectedSurface;
25
+ }
26
+ const focus = taskModeArtifact?.summary?.focus || null;
27
+ return focus ? { kind: "mode_focus", label: focus } : null;
28
+ }
29
+
30
+ export function verificationSurfaceForTargets(verificationTargets) {
31
+ const targetCount = ((verificationTargets?.generated_checks || []).length)
32
+ + ((verificationTargets?.maintained_app_checks || []).length)
33
+ + ((verificationTargets?.verification_ids || []).length);
34
+ return targetCount > 0 ? "verification-targets" : null;
35
+ }
36
+
37
+ export function recommendedQueryFamilyForAction(nextAction, mode = null) {
38
+ switch (nextAction?.kind) {
39
+ case "review_staged":
40
+ case "review_bundle":
41
+ case "inspect_review_group":
42
+ case "inspect_proposal_surface":
43
+ case "customize_workflow_preset":
44
+ case "refresh_workflow_preset_customization":
45
+ case "import_declared_workflow_preset":
46
+ return "import-plan";
47
+ case "review_diff_impact":
48
+ case "inspect_projection":
49
+ case "inspect_diff":
50
+ case "review_diff_boundaries":
51
+ return "change-plan";
52
+ case "inspect_maintained_impact":
53
+ case "inspect_boundary_before_edit":
54
+ case "run_maintained_checks":
55
+ return "maintained-boundary";
56
+ case "inspect_verification_targets":
57
+ return "verification-targets";
58
+ case "inspect_workspace_digest":
59
+ return "single-agent-plan";
60
+ default:
61
+ break;
62
+ }
63
+
64
+ if (mode === "import-adopt") return "import-plan";
65
+ if (mode === "maintained-app-edit") return "maintained-boundary";
66
+ if (mode === "verification") return "verification-targets";
67
+ return "change-plan";
68
+ }
69
+
70
+ export function immediateArtifacts(primaryArtifacts = []) {
71
+ return (primaryArtifacts || []).slice(0, 2);
72
+ }
73
+
74
+ export function buildOperatorLoopSummary({
75
+ mode = null,
76
+ nextAction = null,
77
+ primaryArtifacts = [],
78
+ verificationTargets = null,
79
+ currentSurface = null
80
+ } = {}) {
81
+ return {
82
+ current_surface: currentSurface,
83
+ start_query_family: recommendedQueryFamilyForAction(nextAction, mode),
84
+ immediate_artifacts: immediateArtifacts(primaryArtifacts),
85
+ review_surface: "review-packet",
86
+ decision_surface: "proceed-decision",
87
+ verification_surface: verificationSurfaceForTargets(verificationTargets)
88
+ };
89
+ }
90
+
91
+ export function nextActionRequiresReview(nextAction) {
92
+ const reviewKinds = new Set([
93
+ "review_staged",
94
+ "inspect_review_group",
95
+ "inspect_proposal_surface",
96
+ "inspect_plan",
97
+ "inspect_boundary_before_edit",
98
+ "review_diff_boundaries",
99
+ "review_diff_impact",
100
+ "inspect_maintained_impact",
101
+ "inspect_generated_impact",
102
+ "inspect_diff",
103
+ "inspect_verification_targets",
104
+ "inspect_workspace_digest"
105
+ ]);
106
+ return reviewKinds.has(nextAction?.kind);
107
+ }
108
+
109
+ export function buildReviewBoundaries(taskModeArtifact, importPlan = null) {
110
+ return {
111
+ ownership_boundary: taskModeArtifact?.ownership_boundary || null,
112
+ review_emphasis: taskModeArtifact?.review_emphasis || [],
113
+ approved_review_groups: importPlan?.review_groups || [],
114
+ requires_human_review: importPlan?.requires_human_review || []
115
+ };
116
+ }
117
+
118
+ export function buildBlockingConditions(taskModeArtifact, importPlan = null) {
119
+ const blocking = [];
120
+ const nextAction = taskModeArtifact?.next_action || null;
121
+
122
+ if (nextAction?.kind === "missing_plan") {
123
+ blocking.push({
124
+ kind: "missing_artifact",
125
+ artifact: "candidates/reconcile/adoption-plan.agent.json",
126
+ reason: nextAction.reason || "No staged adoption plan exists yet.",
127
+ recommended_step: "Run reconcile first."
128
+ });
129
+ }
130
+
131
+ if ((importPlan?.requires_human_review || []).length > 0) {
132
+ blocking.push({
133
+ kind: "human_review_required",
134
+ count: importPlan.requires_human_review.length,
135
+ items: importPlan.requires_human_review,
136
+ reason: `${importPlan.requires_human_review.length} staged proposal(s) still require human review or mapping decisions before canonical adoption.`
137
+ });
138
+ }
139
+
140
+ if (nextAction && nextActionRequiresReview(nextAction)) {
141
+ blocking.push({
142
+ kind: "review_gate",
143
+ next_action_kind: nextAction.kind,
144
+ reason: nextAction.reason || "The next step is review-oriented rather than directly executable."
145
+ });
146
+ }
147
+
148
+ return blocking;
149
+ }
150
+
151
+ export function firstPrimaryArtifact(taskModeArtifact) {
152
+ return (taskModeArtifact?.preferred_context_artifacts || [])[0] || null;
153
+ }
154
+
155
+ export function buildImportAdoptSequence(taskModeArtifact, importPlan = null) {
156
+ const steps = [];
157
+ const primaryArtifact = firstPrimaryArtifact(taskModeArtifact);
158
+ if (primaryArtifact) {
159
+ steps.push({
160
+ order: steps.length + 1,
161
+ action: "read_primary_artifact",
162
+ artifact: primaryArtifact,
163
+ review_required: false,
164
+ reason: "Start from the staged adoption view before changing canonical Topogram."
165
+ });
166
+ }
167
+ if (importPlan) {
168
+ steps.push({
169
+ order: steps.length + 1,
170
+ action: "inspect_adoption_state",
171
+ review_required: (importPlan.requires_human_review || []).length > 0,
172
+ reason: `${(importPlan.staged_items || []).length} staged item(s) and ${(importPlan.requires_human_review || []).length} review-required item(s) are currently in scope.`
173
+ });
174
+ }
175
+ if (taskModeArtifact?.next_action) {
176
+ steps.push({
177
+ order: steps.length + 1,
178
+ action: "follow_next_action",
179
+ next_action_kind: taskModeArtifact.next_action.kind,
180
+ review_required: nextActionRequiresReview(taskModeArtifact.next_action),
181
+ reason: taskModeArtifact.next_action.reason || "Follow the current staged adoption step."
182
+ });
183
+ }
184
+ steps.push({
185
+ order: steps.length + 1,
186
+ action: "run_proof_targets",
187
+ review_required: false,
188
+ proof_targets: taskModeArtifact?.verification_targets || null,
189
+ reason: "Validate proposal state before any canonical write."
190
+ });
191
+ return steps;
192
+ }
193
+
194
+ export function buildMaintainedAppEditSequence(taskModeArtifact) {
195
+ const steps = [];
196
+ const primaryArtifact = firstPrimaryArtifact(taskModeArtifact);
197
+ if (primaryArtifact) {
198
+ steps.push({
199
+ order: 1,
200
+ action: "read_primary_artifact",
201
+ artifact: primaryArtifact,
202
+ review_required: false,
203
+ reason: "Start from the maintained-app bundle to see accepted, guarded, and no-go seams."
204
+ });
205
+ }
206
+ steps.push({
207
+ order: steps.length + 1,
208
+ action: "inspect_review_boundaries",
209
+ review_required: true,
210
+ reason: "Review human-owned seams and guarded boundaries before editing maintained code."
211
+ });
212
+ steps.push({
213
+ order: steps.length + 1,
214
+ action: "respect_write_scope",
215
+ review_required: false,
216
+ reason: "Keep edits inside the maintained write scope attached to the current proof bundle."
217
+ });
218
+ steps.push({
219
+ order: steps.length + 1,
220
+ action: "run_proof_targets",
221
+ review_required: false,
222
+ proof_targets: taskModeArtifact?.verification_targets || null,
223
+ reason: "Run maintained proof checks after the bounded edit."
224
+ });
225
+ return steps;
226
+ }
227
+
228
+ export function buildGenericSequence(taskModeArtifact, {
229
+ readReason,
230
+ reviewReason,
231
+ proofReason
232
+ } = {}) {
233
+ const steps = [];
234
+ const primaryArtifact = firstPrimaryArtifact(taskModeArtifact);
235
+ if (primaryArtifact) {
236
+ steps.push({
237
+ order: steps.length + 1,
238
+ action: "read_primary_artifact",
239
+ artifact: primaryArtifact,
240
+ review_required: false,
241
+ reason: readReason || "Start from the preferred context artifact for this mode."
242
+ });
243
+ }
244
+ if (taskModeArtifact?.next_action) {
245
+ steps.push({
246
+ order: steps.length + 1,
247
+ action: "follow_next_action",
248
+ next_action_kind: taskModeArtifact.next_action.kind,
249
+ review_required: nextActionRequiresReview(taskModeArtifact.next_action),
250
+ reason: taskModeArtifact.next_action.reason || "Follow the current recommended next action."
251
+ });
252
+ }
253
+ steps.push({
254
+ order: steps.length + 1,
255
+ action: "inspect_review_boundaries",
256
+ review_required: true,
257
+ reason: reviewReason || "Use the attached review emphasis and ownership boundary before mutating durable meaning."
258
+ });
259
+ steps.push({
260
+ order: steps.length + 1,
261
+ action: "run_proof_targets",
262
+ review_required: false,
263
+ proof_targets: taskModeArtifact?.verification_targets || null,
264
+ reason: proofReason || "Run the smallest proof set attached to this mode."
265
+ });
266
+ return steps;
267
+ }
268
+
269
+ export function buildRecommendedSequence(taskModeArtifact, importPlan = null) {
270
+ const mode = taskModeArtifact?.mode || null;
271
+ if (mode === "import-adopt") {
272
+ return buildImportAdoptSequence(taskModeArtifact, importPlan);
273
+ }
274
+ if (mode === "maintained-app-edit") {
275
+ return buildMaintainedAppEditSequence(taskModeArtifact);
276
+ }
277
+ if (mode === "diff-review") {
278
+ return buildGenericSequence(taskModeArtifact, {
279
+ readReason: "Start from the diff or focused slice before choosing an edit path.",
280
+ reviewReason: "Diff review should stay read-first until maintained and generated impact is clear.",
281
+ proofReason: "Keep proof selection attached to the affected semantic change."
282
+ });
283
+ }
284
+ if (mode === "verification") {
285
+ return buildGenericSequence(taskModeArtifact, {
286
+ readReason: "Start from the focused verification context before running checks.",
287
+ reviewReason: "Confirm the intended verification surface before widening the check set.",
288
+ proofReason: "Run the smallest correct proof set for the current task."
289
+ });
290
+ }
291
+ return buildGenericSequence(taskModeArtifact, {
292
+ readReason: "Start from the focused modeling context before editing canonical Topogram.",
293
+ reviewReason: "Review semantic boundaries before changing durable intent.",
294
+ proofReason: "Run the proof targets attached to the selected semantic closure."
295
+ });
296
+ }
297
+
298
+ export function coreWorkflowQueriesForMode(mode) {
299
+ return WORKFLOW_QUERY_FAMILIES_BY_MODE[mode] || ["change-plan", "risk-summary", "verification-targets"];
300
+ }
@@ -0,0 +1,398 @@
1
+ import {
2
+ CANONICAL_TASK_MODES,
3
+ artifactLoadOrderFromGeneratorTargets,
4
+ flattenVerificationTargets,
5
+ recommendedArtifactQueriesFromGeneratorTargets,
6
+ stableOrderedUnion,
7
+ stableSortedStrings
8
+ } from "./common.js";
9
+ import {
10
+ activeProviderPreset,
11
+ activeTeamPreset,
12
+ loadWorkflowPresetArtifacts,
13
+ presetAppliesToContext,
14
+ providerManifestWorkflowPresetDeclarations,
15
+ skippedPresetReason,
16
+ summarizeWorkflowPreset
17
+ } from "./workflow-presets-core.js";
18
+ import { buildWorkflowPresetInventory } from "./workflow-presets.js";
19
+ import {
20
+ buildBlockingConditions,
21
+ buildOperatorLoopSummary,
22
+ buildRecommendedSequence,
23
+ buildReviewBoundaries,
24
+ coreWorkflowQueriesForMode,
25
+ currentFocusFromTaskMode,
26
+ integrationCategoriesForWorkflowContext,
27
+ outputIdsForWorkflowContext
28
+ } from "./workflow-context-shared.js";
29
+ import { buildPresetGuidanceSummary, classifyRisk } from "./change-risk.js";
30
+ export function activeWorkflowPresetsForContext({
31
+ workspace = null,
32
+ providerPresets = null,
33
+ teamPresets = null,
34
+ providerManifests = null,
35
+ selectors = {}
36
+ } = {}) {
37
+ const loaded = (providerPresets && teamPresets)
38
+ ? { provider_presets: providerPresets, team_presets: teamPresets, provider_manifests: providerManifests || [] }
39
+ : loadWorkflowPresetArtifacts(workspace);
40
+
41
+ const activeProviderPresets = loaded.provider_presets
42
+ .filter((preset) => activeProviderPreset(preset) && presetAppliesToContext(preset, selectors))
43
+ .sort((a, b) => a.priority - b.priority || a.source_priority - b.source_priority || String(a.id).localeCompare(String(b.id)));
44
+ const activeTeamPresets = loaded.team_presets
45
+ .filter((preset) => activeTeamPreset(preset) && presetAppliesToContext(preset, selectors))
46
+ .sort((a, b) => a.priority - b.priority || a.source_priority - b.source_priority || String(a.id).localeCompare(String(b.id)));
47
+ const skippedPresets = [
48
+ ...loaded.provider_presets
49
+ .filter((preset) => !activeProviderPreset(preset) || !presetAppliesToContext(preset, selectors))
50
+ .map((preset) => ({
51
+ id: preset.id,
52
+ kind: preset.kind,
53
+ provider_id: preset.provider?.id || preset.provenance?.provider_id || null,
54
+ priority: preset.priority,
55
+ reason: skippedPresetReason(preset, selectors)
56
+ })),
57
+ ...loaded.team_presets
58
+ .filter((preset) => !activeTeamPreset(preset) || !presetAppliesToContext(preset, selectors))
59
+ .map((preset) => ({
60
+ id: preset.id,
61
+ kind: preset.kind,
62
+ provider_id: preset.provider?.id || preset.provenance?.provider_id || null,
63
+ priority: preset.priority,
64
+ reason: skippedPresetReason(preset, selectors)
65
+ }))
66
+ ].sort((a, b) => `${a.kind}:${a.id}`.localeCompare(`${b.kind}:${b.id}`));
67
+
68
+ return {
69
+ active_provider_presets: activeProviderPresets,
70
+ active_team_presets: activeTeamPresets,
71
+ skipped_presets: skippedPresets,
72
+ provider_manifest_declarations: providerManifestWorkflowPresetDeclarations(loaded.provider_manifests || [], loaded.provider_presets || [])
73
+ };
74
+ }
75
+
76
+ export function mergeFieldResolution(entries = []) {
77
+ return entries.filter(Boolean).map((entry) => ({
78
+ preset_id: entry.id,
79
+ kind: entry.kind,
80
+ priority: entry.priority,
81
+ source_priority: entry.source_priority
82
+ }));
83
+ }
84
+
85
+ export function buildWorkflowPresetActivationPayload({
86
+ workspace = null,
87
+ taskModeArtifact,
88
+ importPlan = null,
89
+ maintainedBoundary = null,
90
+ providerPresets = null,
91
+ teamPresets = null,
92
+ providerManifests = null,
93
+ selectors = {}
94
+ }) {
95
+ const resolvedSelectors = {
96
+ mode: taskModeArtifact?.mode || null,
97
+ task_class: taskModeArtifact?.mode || null,
98
+ outputs: outputIdsForWorkflowContext(taskModeArtifact, maintainedBoundary),
99
+ integration_categories: integrationCategoriesForWorkflowContext(taskModeArtifact, importPlan),
100
+ query_family: "workflow-activation",
101
+ manual_context: Boolean(importPlan?.requires_human_review?.length),
102
+ ...selectors
103
+ };
104
+ const inventory = buildWorkflowPresetInventory({
105
+ workspace,
106
+ providerPresets,
107
+ teamPresets,
108
+ providerManifests,
109
+ selectors: resolvedSelectors
110
+ });
111
+ const activation = activeWorkflowPresetsForContext({
112
+ workspace,
113
+ providerPresets,
114
+ teamPresets,
115
+ providerManifests,
116
+ selectors: resolvedSelectors
117
+ });
118
+ return {
119
+ type: "workflow_preset_activation_query",
120
+ mode: resolvedSelectors.mode,
121
+ selectors: resolvedSelectors,
122
+ active_presets: [
123
+ ...activation.active_provider_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors)),
124
+ ...activation.active_team_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors))
125
+ ].sort((a, b) => `${a.kind}:${a.priority}:${a.id}`.localeCompare(`${b.kind}:${b.priority}:${b.id}`)),
126
+ skipped_presets: activation.skipped_presets,
127
+ provider_manifest_declarations: inventory.provider_manifest_declarations || [],
128
+ summary: {
129
+ active_provider_count: activation.active_provider_presets.length,
130
+ active_team_count: activation.active_team_presets.length,
131
+ skipped_count: activation.skipped_presets.length,
132
+ missing_declared_workflow_preset_count: (inventory.provider_manifest_summary?.missing_declared_workflow_preset_count || 0)
133
+ }
134
+ };
135
+ }
136
+
137
+ export function composeWorkflowToolHints(providerPresets, teamPresets) {
138
+ const merged = {};
139
+ for (const preset of [...providerPresets, ...teamPresets]) {
140
+ for (const [toolName, value] of Object.entries(preset.tool_hints || {})) {
141
+ merged[toolName] = {
142
+ ...(merged[toolName] || {}),
143
+ ...(value && typeof value === "object" ? value : { value })
144
+ };
145
+ }
146
+ }
147
+ return merged;
148
+ }
149
+
150
+ export function buildResolvedWorkflowContextPayload({
151
+ workspace = null,
152
+ taskModeArtifact,
153
+ importPlan = null,
154
+ reviewBoundary = null,
155
+ maintainedBoundary = null,
156
+ generatorTargets = [],
157
+ providerPresets = null,
158
+ teamPresets = null,
159
+ providerManifests = null,
160
+ selectors = {}
161
+ }) {
162
+ const resolvedSelectors = {
163
+ mode: taskModeArtifact?.mode || null,
164
+ task_class: taskModeArtifact?.mode || null,
165
+ outputs: outputIdsForWorkflowContext(taskModeArtifact, maintainedBoundary),
166
+ integration_categories: integrationCategoriesForWorkflowContext(taskModeArtifact, importPlan),
167
+ query_family: "workflow",
168
+ manual_context: Boolean(importPlan?.requires_human_review?.length),
169
+ ...selectors
170
+ };
171
+ const presetInventory = buildWorkflowPresetInventory({
172
+ workspace,
173
+ providerPresets,
174
+ teamPresets,
175
+ providerManifests,
176
+ selectors: resolvedSelectors
177
+ });
178
+ const activePresets = activeWorkflowPresetsForContext({
179
+ workspace,
180
+ providerPresets,
181
+ teamPresets,
182
+ providerManifests,
183
+ selectors: resolvedSelectors
184
+ });
185
+ const providerPresetSummaries = activePresets.active_provider_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors));
186
+ const teamPresetSummaries = activePresets.active_team_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors));
187
+
188
+ const conflictNotes = [];
189
+ const policyNotes = [];
190
+ const appliedPresets = [];
191
+ let resolvedTaskMode = taskModeArtifact?.mode || null;
192
+ const fieldResolution = {
193
+ recommended_task_mode: [],
194
+ preferred_queries: [],
195
+ artifact_load_order: [],
196
+ review_policy: [],
197
+ verification_policy: [],
198
+ multi_agent_policy: [],
199
+ handoff_defaults: [],
200
+ tool_hints: []
201
+ };
202
+ for (const preset of [...activePresets.active_provider_presets, ...activePresets.active_team_presets]) {
203
+ if (preset.recommended_task_mode) {
204
+ fieldResolution.recommended_task_mode.push(...mergeFieldResolution([preset]));
205
+ if (CANONICAL_TASK_MODES.has(preset.recommended_task_mode)) {
206
+ if (resolvedTaskMode !== taskModeArtifact?.mode && resolvedTaskMode !== preset.recommended_task_mode) {
207
+ conflictNotes.push(`Preset ${preset.id} overrode an earlier task-mode recommendation; highest-precedence canonical task mode wins.`);
208
+ }
209
+ resolvedTaskMode = preset.recommended_task_mode;
210
+ } else {
211
+ conflictNotes.push(`Preset ${preset.id} requested unsupported task mode ${preset.recommended_task_mode}; ignoring override.`);
212
+ }
213
+ }
214
+ if (preset.write_scope || preset.ownership_boundary) {
215
+ conflictNotes.push(`Preset ${preset.id} attempted to override protected workflow boundaries; ignoring override.`);
216
+ }
217
+ appliedPresets.push({
218
+ id: preset.id,
219
+ kind: preset.kind,
220
+ source_priority: preset.source_priority,
221
+ provenance: preset.provenance || null
222
+ });
223
+ }
224
+
225
+ const coreQueries = coreWorkflowQueriesForMode(resolvedTaskMode);
226
+ const providerQueries = activePresets.active_provider_presets.flatMap((preset) => preset.preferred_queries || []);
227
+ const teamQueries = activePresets.active_team_presets.flatMap((preset) => preset.preferred_queries || []);
228
+ const preferredQueries = stableOrderedUnion([
229
+ ...teamQueries,
230
+ ...providerQueries,
231
+ ...coreQueries
232
+ ]);
233
+ fieldResolution.preferred_queries = mergeFieldResolution([
234
+ ...activePresets.active_team_presets.filter((preset) => (preset.preferred_queries || []).length > 0),
235
+ ...activePresets.active_provider_presets.filter((preset) => (preset.preferred_queries || []).length > 0)
236
+ ]);
237
+ const artifactLoadOrder = stableOrderedUnion([
238
+ ...activePresets.active_team_presets.flatMap((preset) => preset.artifact_load_order || []),
239
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.artifact_load_order || []),
240
+ ...(taskModeArtifact?.preferred_context_artifacts || []),
241
+ ...artifactLoadOrderFromGeneratorTargets(generatorTargets)
242
+ ]);
243
+ const recommendedArtifactQueries = recommendedArtifactQueriesFromGeneratorTargets(generatorTargets);
244
+ fieldResolution.artifact_load_order = mergeFieldResolution([
245
+ ...activePresets.active_team_presets.filter((preset) => (preset.artifact_load_order || []).length > 0),
246
+ ...activePresets.active_provider_presets.filter((preset) => (preset.artifact_load_order || []).length > 0)
247
+ ]);
248
+
249
+ const risk = classifyRisk({
250
+ reviewBoundary,
251
+ maintainedBoundary,
252
+ importPlan,
253
+ verificationTargets: taskModeArtifact?.verification_targets || null,
254
+ maintainedRisk: importPlan?.maintained_risk || null
255
+ });
256
+
257
+ const requiredVerification = stableOrderedUnion([
258
+ ...flattenVerificationTargets(taskModeArtifact?.verification_targets || null),
259
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.verification_policy?.required || []),
260
+ ...activePresets.active_team_presets.flatMap((preset) => preset.verification_policy?.required || [])
261
+ ]);
262
+ const recommendedVerification = stableOrderedUnion([
263
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.verification_policy?.recommended || []),
264
+ ...activePresets.active_team_presets.flatMap((preset) => preset.verification_policy?.recommended || [])
265
+ ]).filter((entry) => !requiredVerification.includes(entry));
266
+ fieldResolution.verification_policy = mergeFieldResolution([
267
+ ...activePresets.active_provider_presets.filter((preset) =>
268
+ (preset.verification_policy?.required || []).length > 0 ||
269
+ (preset.verification_policy?.recommended || []).length > 0
270
+ ),
271
+ ...activePresets.active_team_presets.filter((preset) =>
272
+ (preset.verification_policy?.required || []).length > 0 ||
273
+ (preset.verification_policy?.recommended || []).length > 0
274
+ )
275
+ ]);
276
+
277
+ const reviewBlockers = stableSortedStrings([
278
+ "no_go",
279
+ ...(risk.overall_risk === "manual_decision" || risk.overall_risk === "no_go" ? ["manual_decision"] : []),
280
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.review_policy?.block_on || []),
281
+ ...activePresets.active_team_presets.flatMap((preset) => preset.review_policy?.block_on || [])
282
+ ]);
283
+ const reviewEscalations = stableSortedStrings([
284
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.review_policy?.escalate_categories || []),
285
+ ...activePresets.active_team_presets.flatMap((preset) => preset.review_policy?.escalate_categories || [])
286
+ ]);
287
+ fieldResolution.review_policy = mergeFieldResolution([
288
+ ...activePresets.active_provider_presets.filter((preset) =>
289
+ (preset.review_policy?.block_on || []).length > 0 || (preset.review_policy?.escalate_categories || []).length > 0
290
+ ),
291
+ ...activePresets.active_team_presets.filter((preset) =>
292
+ (preset.review_policy?.block_on || []).length > 0 || (preset.review_policy?.escalate_categories || []).length > 0
293
+ )
294
+ ]);
295
+ if ((presetInventory.provider_manifest_summary?.missing_declared_workflow_preset_count || 0) > 0) {
296
+ policyNotes.push(`${presetInventory.provider_manifest_summary.missing_declared_workflow_preset_count} manifest-declared workflow preset(s) are not yet imported.`);
297
+ }
298
+ if (activePresets.skipped_presets.some((preset) => preset.reason === "inactive")) {
299
+ policyNotes.push("At least one workflow preset is present but inactive by local policy.");
300
+ }
301
+
302
+ const providerMultiAgentAllowed = activePresets.active_provider_presets.every((preset) => preset.multi_agent_policy?.allowed !== false);
303
+ const teamMultiAgentAllowed = activePresets.active_team_presets.every((preset) => preset.multi_agent_policy?.allowed !== false);
304
+ const teamDefaultStrategy = [...activePresets.active_team_presets].reverse().find((preset) => preset.multi_agent_policy?.default_strategy)?.multi_agent_policy?.default_strategy || null;
305
+ const providerDefaultStrategy = [...activePresets.active_provider_presets].reverse().find((preset) => preset.multi_agent_policy?.default_strategy)?.multi_agent_policy?.default_strategy || null;
306
+ fieldResolution.multi_agent_policy = mergeFieldResolution([
307
+ ...activePresets.active_provider_presets.filter((preset) =>
308
+ preset.multi_agent_policy?.allowed !== undefined || preset.multi_agent_policy?.default_strategy
309
+ ),
310
+ ...activePresets.active_team_presets.filter((preset) =>
311
+ preset.multi_agent_policy?.allowed !== undefined || preset.multi_agent_policy?.default_strategy
312
+ )
313
+ ]);
314
+ fieldResolution.handoff_defaults = mergeFieldResolution([
315
+ ...activePresets.active_provider_presets.filter((preset) => (preset.handoff_defaults?.required_fields || []).length > 0),
316
+ ...activePresets.active_team_presets.filter((preset) => (preset.handoff_defaults?.required_fields || []).length > 0)
317
+ ]);
318
+ fieldResolution.tool_hints = mergeFieldResolution([
319
+ ...activePresets.active_provider_presets.filter((preset) => Object.keys(preset.tool_hints || {}).length > 0),
320
+ ...activePresets.active_team_presets.filter((preset) => Object.keys(preset.tool_hints || {}).length > 0)
321
+ ]);
322
+
323
+ return {
324
+ type: "resolved_workflow_context_query",
325
+ resolved_task_mode: resolvedTaskMode,
326
+ preferred_queries: preferredQueries,
327
+ artifact_load_order: artifactLoadOrder,
328
+ recommended_artifact_queries: recommendedArtifactQueries,
329
+ effective_write_scope: taskModeArtifact?.write_scope || null,
330
+ effective_review_policy: {
331
+ block_on: reviewBlockers,
332
+ escalate_categories: reviewEscalations,
333
+ overall_risk: risk.overall_risk,
334
+ risk_reasons: risk.risk_reasons || []
335
+ },
336
+ effective_verification_policy: {
337
+ required: requiredVerification,
338
+ recommended: recommendedVerification,
339
+ output_verification_targets: taskModeArtifact?.verification_targets?.output_verification_targets || []
340
+ },
341
+ effective_multi_agent_policy: {
342
+ allowed: providerMultiAgentAllowed && teamMultiAgentAllowed,
343
+ default_strategy: teamDefaultStrategy || providerDefaultStrategy || null
344
+ },
345
+ effective_handoff_defaults: {
346
+ required_fields: stableOrderedUnion([
347
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.handoff_defaults?.required_fields || []),
348
+ ...activePresets.active_team_presets.flatMap((preset) => preset.handoff_defaults?.required_fields || [])
349
+ ])
350
+ },
351
+ tool_hints: composeWorkflowToolHints(activePresets.active_provider_presets, activePresets.active_team_presets),
352
+ applied_presets: appliedPresets,
353
+ skipped_presets: activePresets.skipped_presets,
354
+ field_resolution: fieldResolution,
355
+ conflict_notes: conflictNotes,
356
+ policy_notes: policyNotes,
357
+ workflow_presets: presetInventory
358
+ };
359
+ }
360
+
361
+ export function buildSingleAgentPlanPayload({
362
+ workspace,
363
+ taskModeArtifact,
364
+ importPlan = null,
365
+ resolvedWorkflowContext = null
366
+ }) {
367
+ const primaryArtifacts = stableOrderedUnion([
368
+ ...(resolvedWorkflowContext?.artifact_load_order || []),
369
+ ...(taskModeArtifact?.preferred_context_artifacts || [])
370
+ ]);
371
+ const presetGuidanceSummary = buildPresetGuidanceSummary(importPlan?.workflow_presets || null, resolvedWorkflowContext);
372
+ return {
373
+ type: "single_agent_plan",
374
+ workspace: workspace || null,
375
+ mode: taskModeArtifact?.mode || null,
376
+ summary: taskModeArtifact?.summary || null,
377
+ current_focus: currentFocusFromTaskMode(taskModeArtifact),
378
+ next_action: taskModeArtifact?.next_action || null,
379
+ write_scope: taskModeArtifact?.write_scope || null,
380
+ review_boundaries: buildReviewBoundaries(taskModeArtifact, importPlan),
381
+ proof_targets: taskModeArtifact?.verification_targets || null,
382
+ operator_loop: buildOperatorLoopSummary({
383
+ mode: taskModeArtifact?.mode || null,
384
+ nextAction: taskModeArtifact?.next_action || null,
385
+ primaryArtifacts,
386
+ verificationTargets: taskModeArtifact?.verification_targets || null,
387
+ currentSurface: "single-agent-plan"
388
+ }),
389
+ recommended_sequence: buildRecommendedSequence(taskModeArtifact, importPlan),
390
+ blocking_conditions: buildBlockingConditions(taskModeArtifact, importPlan),
391
+ primary_artifacts: primaryArtifacts,
392
+ preset_guidance_summary: presetGuidanceSummary,
393
+ active_preset_ids: presetGuidanceSummary.active_preset_ids,
394
+ preset_blockers: presetGuidanceSummary.preset_blockers,
395
+ recommended_preset_action: presetGuidanceSummary.recommended_preset_action,
396
+ resolved_workflow_context: resolvedWorkflowContext || null
397
+ };
398
+ }