@topogram/cli 0.3.63 → 0.3.65

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 (344) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +703 -0
  3. package/src/adoption/plan.d.ts +6 -0
  4. package/src/adoption/plan.js +12 -703
  5. package/src/adoption/reporting.d.ts +10 -0
  6. package/src/adoption/review-groups.d.ts +6 -0
  7. package/src/agent-brief.d.ts +3 -0
  8. package/src/agent-brief.js +495 -0
  9. package/src/agent-ops/query-builders/auth.js +375 -0
  10. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  11. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  12. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  13. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  14. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  15. package/src/agent-ops/query-builders/change-risk.js +25 -0
  16. package/src/agent-ops/query-builders/common.js +149 -0
  17. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  18. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  19. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  20. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  21. package/src/agent-ops/query-builders/work-packets.js +417 -0
  22. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  23. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  24. package/src/agent-ops/query-builders/workflow-presets-core.js +676 -0
  25. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  26. package/src/agent-ops/query-builders.d.ts +26 -0
  27. package/src/agent-ops/query-builders.js +42 -5021
  28. package/src/archive/archive.d.ts +2 -0
  29. package/src/archive/compact.d.ts +1 -0
  30. package/src/archive/unarchive.d.ts +1 -0
  31. package/src/catalog/constants.js +10 -0
  32. package/src/catalog/copy.js +60 -0
  33. package/src/catalog/diagnostics.js +15 -0
  34. package/src/catalog/entries.js +42 -0
  35. package/src/catalog/files.js +67 -0
  36. package/src/catalog/provenance.js +122 -0
  37. package/src/catalog/source.js +150 -0
  38. package/src/catalog/validation.js +252 -0
  39. package/src/catalog.d.ts +12 -0
  40. package/src/catalog.js +18 -750
  41. package/src/cli/catalog-alias.d.ts +1 -0
  42. package/src/cli/command-parser.js +38 -0
  43. package/src/cli/command-parsers/core.js +102 -0
  44. package/src/cli/command-parsers/generator.js +39 -0
  45. package/src/cli/command-parsers/import.js +44 -0
  46. package/src/cli/command-parsers/legacy-workflow.js +21 -0
  47. package/src/cli/command-parsers/project.js +47 -0
  48. package/src/cli/command-parsers/sdlc.js +47 -0
  49. package/src/cli/command-parsers/shared.js +51 -0
  50. package/src/cli/command-parsers/template.js +48 -0
  51. package/src/cli/commands/agent.js +47 -0
  52. package/src/cli/commands/catalog/check.js +31 -0
  53. package/src/cli/commands/catalog/copy.js +59 -0
  54. package/src/cli/commands/catalog/doctor.js +248 -0
  55. package/src/cli/commands/catalog/help.js +21 -0
  56. package/src/cli/commands/catalog/list.js +52 -0
  57. package/src/cli/commands/catalog/runner.js +92 -0
  58. package/src/cli/commands/catalog/shared.js +17 -0
  59. package/src/cli/commands/catalog/show.js +134 -0
  60. package/src/cli/commands/catalog.js +32 -0
  61. package/src/cli/commands/check.js +268 -0
  62. package/src/cli/commands/doctor.js +268 -0
  63. package/src/cli/commands/emit.js +149 -0
  64. package/src/cli/commands/generate.js +96 -0
  65. package/src/cli/commands/generator-policy/package-info.js +162 -0
  66. package/src/cli/commands/generator-policy/payloads.js +372 -0
  67. package/src/cli/commands/generator-policy/printers.js +159 -0
  68. package/src/cli/commands/generator-policy/runner.js +81 -0
  69. package/src/cli/commands/generator-policy/shared.js +39 -0
  70. package/src/cli/commands/generator-policy.js +17 -0
  71. package/src/cli/commands/generator.js +443 -0
  72. package/src/cli/commands/import/adopt.js +170 -0
  73. package/src/cli/commands/import/check.js +91 -0
  74. package/src/cli/commands/import/diff.js +84 -0
  75. package/src/cli/commands/import/help.js +47 -0
  76. package/src/cli/commands/import/paths.js +277 -0
  77. package/src/cli/commands/import/plan.js +284 -0
  78. package/src/cli/commands/import/refresh.js +470 -0
  79. package/src/cli/commands/import/status-history.js +196 -0
  80. package/src/cli/commands/import/workspace.js +230 -0
  81. package/src/cli/commands/import-runner.js +157 -0
  82. package/src/cli/commands/import.js +35 -0
  83. package/src/cli/commands/inspect.js +55 -0
  84. package/src/cli/commands/new.js +94 -0
  85. package/src/cli/commands/package/constants.js +17 -0
  86. package/src/cli/commands/package/doctor.js +240 -0
  87. package/src/cli/commands/package/help.js +27 -0
  88. package/src/cli/commands/package/lockfile.js +135 -0
  89. package/src/cli/commands/package/npm.js +97 -0
  90. package/src/cli/commands/package/reporting.js +35 -0
  91. package/src/cli/commands/package/runner.js +33 -0
  92. package/src/cli/commands/package/shared.js +9 -0
  93. package/src/cli/commands/package/update-cli.js +252 -0
  94. package/src/cli/commands/package/versions.js +35 -0
  95. package/src/cli/commands/package.js +31 -0
  96. package/src/cli/commands/query/change-plan.js +68 -0
  97. package/src/cli/commands/query/definitions.js +202 -0
  98. package/src/cli/commands/query/import-adopt.js +121 -0
  99. package/src/cli/commands/query/runner/artifacts.js +102 -0
  100. package/src/cli/commands/query/runner/boundaries.js +211 -0
  101. package/src/cli/commands/query/runner/change.js +182 -0
  102. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  103. package/src/cli/commands/query/runner/index.js +31 -0
  104. package/src/cli/commands/query/runner/output.js +12 -0
  105. package/src/cli/commands/query/runner/workflow.js +241 -0
  106. package/src/cli/commands/query/runner.js +3 -0
  107. package/src/cli/commands/query/workflow-context.js +5 -0
  108. package/src/cli/commands/query/workspace.js +274 -0
  109. package/src/cli/commands/query.js +11 -0
  110. package/src/cli/commands/release-rollout.js +257 -0
  111. package/src/cli/commands/release-shared.js +528 -0
  112. package/src/cli/commands/release-status.js +429 -0
  113. package/src/cli/commands/release.js +107 -0
  114. package/src/cli/commands/sdlc.js +168 -0
  115. package/src/cli/commands/setup.js +76 -0
  116. package/src/cli/commands/source.js +291 -0
  117. package/src/cli/commands/template/baseline.js +100 -0
  118. package/src/cli/commands/template/check.js +466 -0
  119. package/src/cli/commands/template/constants.js +8 -0
  120. package/src/cli/commands/template/diagnostics.js +26 -0
  121. package/src/cli/commands/template/help.js +28 -0
  122. package/src/cli/commands/template/lifecycle.js +404 -0
  123. package/src/cli/commands/template/list-show.js +287 -0
  124. package/src/cli/commands/template/policy.js +422 -0
  125. package/src/cli/commands/template/shared.js +127 -0
  126. package/src/cli/commands/template/updates.js +352 -0
  127. package/src/cli/commands/template-runner.js +198 -0
  128. package/src/cli/commands/template.js +43 -0
  129. package/src/cli/commands/trust.js +219 -0
  130. package/src/cli/commands/version.js +40 -0
  131. package/src/cli/commands/widget.js +168 -0
  132. package/src/cli/commands/workflow.js +63 -0
  133. package/src/cli/dispatcher.js +392 -0
  134. package/src/cli/help-dispatch.js +188 -0
  135. package/src/cli/help.js +296 -0
  136. package/src/cli/migration-guidance.js +59 -0
  137. package/src/cli/options.js +96 -0
  138. package/src/cli/output-safety.js +107 -0
  139. package/src/cli/path-normalization.js +29 -0
  140. package/src/cli.js +47 -11711
  141. package/src/example-implementation.d.ts +2 -0
  142. package/src/format.d.ts +1 -0
  143. package/src/generator/api/contracts.js +497 -0
  144. package/src/generator/api/metadata.js +221 -0
  145. package/src/generator/api/openapi.js +559 -0
  146. package/src/generator/api/schema.js +124 -0
  147. package/src/generator/api/types.d.ts +98 -0
  148. package/src/generator/api.js +3 -1195
  149. package/src/generator/check.d.ts +1 -0
  150. package/src/generator/context/bundle.d.ts +1 -0
  151. package/src/generator/context/shared/domain-sdlc.js +282 -0
  152. package/src/generator/context/shared/maintained-boundary.js +665 -0
  153. package/src/generator/context/shared/metrics.js +85 -0
  154. package/src/generator/context/shared/primitives.js +64 -0
  155. package/src/generator/context/shared/relationships.js +453 -0
  156. package/src/generator/context/shared/summaries.js +263 -0
  157. package/src/generator/context/shared/types.d.ts +207 -0
  158. package/src/generator/context/shared.d.ts +44 -0
  159. package/src/generator/context/shared.js +80 -1390
  160. package/src/generator/context/slice/core.js +397 -0
  161. package/src/generator/context/slice/sdlc.js +417 -0
  162. package/src/generator/context/slice/ui-packets.js +183 -0
  163. package/src/generator/context/slice.js +2 -859
  164. package/src/generator/native/parity-bundle.js +2 -1
  165. package/src/generator/registry/index.js +507 -0
  166. package/src/generator/registry.js +18 -504
  167. package/src/generator/runtime/environment/index.js +666 -0
  168. package/src/generator/runtime/environment.js +4 -666
  169. package/src/generator/runtime/runtime-check/index.js +554 -0
  170. package/src/generator/runtime/runtime-check.js +4 -554
  171. package/src/generator/runtime/shared/index.js +572 -0
  172. package/src/generator/runtime/shared.js +19 -570
  173. package/src/generator/shared.d.ts +2 -0
  174. package/src/generator/surfaces/shared.d.ts +3 -0
  175. package/src/generator/surfaces/web/html-escape.js +22 -0
  176. package/src/generator/surfaces/web/react.js +10 -8
  177. package/src/generator/surfaces/web/sveltekit.js +7 -5
  178. package/src/generator/surfaces/web/vanilla.js +8 -4
  179. package/src/generator/widget-conformance/behavior-report.js +258 -0
  180. package/src/generator/widget-conformance/checks.js +371 -0
  181. package/src/generator/widget-conformance/projection-context.js +200 -0
  182. package/src/generator/widget-conformance/report.js +166 -0
  183. package/src/generator/widget-conformance/types.d.ts +121 -0
  184. package/src/generator/widget-conformance.js +3 -824
  185. package/src/generator.d.ts +2 -0
  186. package/src/github-client.js +520 -0
  187. package/src/import/core/context.d.ts +3 -0
  188. package/src/import/core/contracts.d.ts +1 -0
  189. package/src/import/core/registry.d.ts +4 -0
  190. package/src/import/core/runner/candidates.js +217 -0
  191. package/src/import/core/runner/options.js +22 -0
  192. package/src/import/core/runner/reports.js +50 -0
  193. package/src/import/core/runner/run.js +79 -0
  194. package/src/import/core/runner/tracks.js +150 -0
  195. package/src/import/core/runner/ui-drafts.js +337 -0
  196. package/src/import/core/runner.js +3 -698
  197. package/src/import/core/shared/api-routes.js +221 -0
  198. package/src/import/core/shared/candidates.js +97 -0
  199. package/src/import/core/shared/files.js +177 -0
  200. package/src/import/core/shared/next-app.js +389 -0
  201. package/src/import/core/shared/types.d.ts +51 -0
  202. package/src/import/core/shared/ui-routes.js +230 -0
  203. package/src/import/core/shared.js +67 -910
  204. package/src/import/extractors/api/flutter-dio.js +4 -8
  205. package/src/import/extractors/api/react-native-repository.js +4 -8
  206. package/src/import/index.d.ts +4 -0
  207. package/src/import/provenance.d.ts +4 -0
  208. package/src/new-project/constants.js +128 -0
  209. package/src/new-project/create.js +83 -0
  210. package/src/new-project/json.js +28 -0
  211. package/src/new-project/metadata.js +96 -0
  212. package/src/new-project/package-spec.js +161 -0
  213. package/src/new-project/project-files.js +348 -0
  214. package/src/new-project/template-policy.js +269 -0
  215. package/src/new-project/template-resolution.js +368 -0
  216. package/src/new-project/template-snapshots.js +430 -0
  217. package/src/new-project/template-updates.js +512 -0
  218. package/src/new-project/types.d.ts +83 -0
  219. package/src/new-project.js +6 -2188
  220. package/src/npm-safety.js +79 -0
  221. package/src/parser.d.ts +87 -0
  222. package/src/parser.js +118 -0
  223. package/src/path-helpers.d.ts +1 -0
  224. package/src/path-helpers.js +20 -0
  225. package/src/policy/review-boundaries.d.ts +15 -0
  226. package/src/project-config/index.js +564 -0
  227. package/src/project-config.js +19 -560
  228. package/src/reconcile/docs.d.ts +8 -0
  229. package/src/reconcile/journeys.d.ts +1 -0
  230. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  231. package/src/resolver/enrich/bug.js +2 -0
  232. package/src/resolver/enrich/pitch.js +2 -0
  233. package/src/resolver/enrich/requirement.js +2 -0
  234. package/src/resolver/enrich/task.js +2 -0
  235. package/src/resolver/index.js +19 -2089
  236. package/src/resolver/normalize.js +384 -1
  237. package/src/resolver/plans.js +168 -0
  238. package/src/resolver/projections-api.js +494 -0
  239. package/src/resolver/projections-db.js +133 -0
  240. package/src/resolver/projections-ui.js +317 -0
  241. package/src/resolver/shapes.js +251 -0
  242. package/src/resolver/shared.js +278 -0
  243. package/src/resolver/widgets.js +132 -0
  244. package/src/resolver.d.ts +1 -0
  245. package/src/runtime-support.js +29 -0
  246. package/src/sdlc/adopt.d.ts +1 -0
  247. package/src/sdlc/check.d.ts +1 -0
  248. package/src/sdlc/explain.d.ts +1 -0
  249. package/src/sdlc/release.d.ts +1 -0
  250. package/src/sdlc/scaffold.d.ts +1 -0
  251. package/src/sdlc/transition.d.ts +1 -0
  252. package/src/template-trust/constants.js +62 -0
  253. package/src/template-trust/content.js +258 -0
  254. package/src/template-trust/diff.js +92 -0
  255. package/src/template-trust/policy.js +61 -0
  256. package/src/template-trust/record.js +90 -0
  257. package/src/template-trust/status.js +182 -0
  258. package/src/template-trust.js +24 -687
  259. package/src/text-helpers.d.ts +7 -0
  260. package/src/text-helpers.js +245 -0
  261. package/src/topogram-config.js +306 -0
  262. package/src/topogram-types.d.ts +69 -0
  263. package/src/validator/common.js +488 -0
  264. package/src/validator/data-model.js +237 -0
  265. package/src/validator/docs.js +167 -0
  266. package/src/validator/expressions.js +146 -1
  267. package/src/validator/index.d.ts +23 -0
  268. package/src/validator/index.js +32 -3585
  269. package/src/validator/kinds.d.ts +41 -0
  270. package/src/validator/kinds.js +2 -0
  271. package/src/validator/model-helpers.js +46 -0
  272. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  273. package/src/validator/per-kind/bug.js +6 -0
  274. package/src/validator/per-kind/domain.js +15 -2
  275. package/src/validator/per-kind/pitch.js +7 -0
  276. package/src/validator/per-kind/requirement.js +5 -0
  277. package/src/validator/per-kind/task.js +7 -0
  278. package/src/validator/per-kind/widget.js +14 -0
  279. package/src/validator/projections/api-http-async.js +410 -0
  280. package/src/validator/projections/api-http-authz.js +88 -0
  281. package/src/validator/projections/api-http-core.js +205 -0
  282. package/src/validator/projections/api-http-policies.js +339 -0
  283. package/src/validator/projections/api-http-responses.js +233 -0
  284. package/src/validator/projections/api-http.js +44 -0
  285. package/src/validator/projections/db.js +353 -0
  286. package/src/validator/projections/generator-defaults.js +45 -0
  287. package/src/validator/projections/helpers.js +87 -0
  288. package/src/validator/projections/ui-helpers.js +214 -0
  289. package/src/validator/projections/ui-navigation.js +344 -0
  290. package/src/validator/projections/ui-structure.js +364 -0
  291. package/src/validator/projections/ui-widgets.js +493 -0
  292. package/src/validator/projections/ui.js +46 -0
  293. package/src/validator/registry.js +48 -1
  294. package/src/validator/utils.d.ts +20 -0
  295. package/src/validator/utils.js +115 -12
  296. package/src/validator.d.ts +2 -0
  297. package/src/widget-behavior.d.ts +1 -0
  298. package/src/workflows/adoption/index.js +26 -0
  299. package/src/workflows/docs-generate.js +262 -0
  300. package/src/workflows/docs-scan.js +703 -0
  301. package/src/workflows/docs.js +15 -0
  302. package/src/workflows/import-app/api/collect.js +221 -0
  303. package/src/workflows/import-app/api/openapi.js +257 -0
  304. package/src/workflows/import-app/api/routes.js +327 -0
  305. package/src/workflows/import-app/api/sources.js +22 -0
  306. package/src/workflows/import-app/api.js +4 -0
  307. package/src/workflows/import-app/db.js +538 -0
  308. package/src/workflows/import-app/index.js +30 -0
  309. package/src/workflows/import-app/shared.js +218 -0
  310. package/src/workflows/import-app/ui.js +443 -0
  311. package/src/workflows/import-app/workflow.js +159 -0
  312. package/src/workflows/reconcile/adoption-plan/build.js +208 -0
  313. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  314. package/src/workflows/reconcile/adoption-plan/outputs.js +143 -0
  315. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  316. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  317. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  318. package/src/workflows/reconcile/adoption-plan.js +32 -0
  319. package/src/workflows/reconcile/auth/closures.js +115 -0
  320. package/src/workflows/reconcile/auth/formatters.js +142 -0
  321. package/src/workflows/reconcile/auth/inference.js +330 -0
  322. package/src/workflows/reconcile/auth/roles.js +122 -0
  323. package/src/workflows/reconcile/auth.js +37 -0
  324. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  325. package/src/workflows/reconcile/bundle-core.js +14 -0
  326. package/src/workflows/reconcile/bundle-shared.js +75 -0
  327. package/src/workflows/reconcile/candidate-model.js +477 -0
  328. package/src/workflows/reconcile/canonical-surface.js +264 -0
  329. package/src/workflows/reconcile/gap-report.js +333 -0
  330. package/src/workflows/reconcile/ids.js +6 -0
  331. package/src/workflows/reconcile/impacts/adoption-plan.js +192 -0
  332. package/src/workflows/reconcile/impacts/indexes.js +101 -0
  333. package/src/workflows/reconcile/impacts/patches.js +252 -0
  334. package/src/workflows/reconcile/impacts/reports.js +80 -0
  335. package/src/workflows/reconcile/impacts.js +16 -0
  336. package/src/workflows/reconcile/index.js +7 -0
  337. package/src/workflows/reconcile/renderers.js +461 -0
  338. package/src/workflows/reconcile/summary.js +90 -0
  339. package/src/workflows/reconcile/workflow.js +309 -0
  340. package/src/workflows/shared.js +189 -0
  341. package/src/workflows/types.d.ts +93 -0
  342. package/src/workflows.d.ts +1 -0
  343. package/src/workflows.js +10 -7652
  344. package/src/workspace-docs.d.ts +29 -0
@@ -0,0 +1,286 @@
1
+ import {
2
+ severityRank,
3
+ stableSortedStrings,
4
+ summarizeDiffArtifact
5
+ } from "../common.js";
6
+ import {
7
+ buildMaintainedOutputGroups,
8
+ normalizeProofStorySummary,
9
+ normalizeSeamSummary
10
+ } from "../maintained-shared.js";
11
+ import {
12
+ buildSeamProbeReport,
13
+ compactMaintainedSeamSummary,
14
+ conformanceStateFromSeamCheck,
15
+ verificationTargetsForOutput
16
+ } from "../maintained-risk.js";
17
+
18
+ export function buildMaintainedDriftPayload({ diffArtifact, maintainedBoundaryArtifact, verificationTargets, nextAction }) {
19
+ const diffMaintained = diffArtifact?.affected_maintained_surfaces || null;
20
+ const affectedSeams = (diffMaintained?.affected_seams || maintainedBoundaryArtifact?.seams || [])
21
+ .map((seam) => normalizeSeamSummary(seam))
22
+ .sort((a, b) => {
23
+ const severityCompare = severityRank(b.status) - severityRank(a.status);
24
+ return severityCompare !== 0 ? severityCompare : String(a.seam_id || "").localeCompare(String(b.seam_id || ""));
25
+ });
26
+
27
+ const statusCounts = {
28
+ aligned: affectedSeams.filter((seam) => seam.status === "aligned").length,
29
+ review_required: affectedSeams.filter((seam) => seam.status === "review_required").length,
30
+ manual_decision: affectedSeams.filter((seam) => seam.status === "manual_decision").length,
31
+ no_go: affectedSeams.filter((seam) => seam.status === "no_go").length
32
+ };
33
+ const highestSeverity = affectedSeams[0]?.status || "aligned";
34
+ const maintainedFiles = stableSortedStrings(diffMaintained?.maintained_files_in_scope || maintainedBoundaryArtifact?.maintained_files_in_scope || []);
35
+ const humanOwnedSeams = stableSortedStrings([
36
+ ...(maintainedBoundaryArtifact?.human_owned_seams || []),
37
+ ...affectedSeams.map((seam) => seam.label)
38
+ ]);
39
+ const outputs = buildMaintainedOutputGroups(
40
+ diffMaintained?.outputs || maintainedBoundaryArtifact?.outputs || [],
41
+ affectedSeams,
42
+ {
43
+ summaryField: "status",
44
+ severitySelector: severityRank,
45
+ verificationTargetsFallback: verificationTargets || null
46
+ }
47
+ ).map((output) => ({
48
+ output_id: output.output_id,
49
+ label: output.label,
50
+ kind: output.kind,
51
+ root_paths: output.root_paths,
52
+ ownership_boundary: output.ownership_boundary,
53
+ write_scope: output.write_scope,
54
+ verification_targets: output.verification_targets,
55
+ maintained_files_in_scope: output.maintained_files_in_scope,
56
+ human_owned_seams: output.human_owned_seams,
57
+ seam_families: output.seam_families,
58
+ affected_seams: output.seams,
59
+ proof_stories: output.proof_stories,
60
+ summary: output.summary
61
+ }));
62
+ const affectedSeamFamilies = stableSortedStrings(affectedSeams.map((seam) => seam.seam_family_id).filter(Boolean));
63
+
64
+ return {
65
+ type: "maintained_drift_query",
66
+ baseline_root: diffArtifact?.baseline_root || null,
67
+ diff_summary: summarizeDiffArtifact(diffArtifact),
68
+ ownership_interpretation: diffMaintained?.ownership_interpretation || {
69
+ generated_only_impact: affectedSeams.length === 0,
70
+ maintained_code_impact: affectedSeams.length > 0,
71
+ human_review_required_impact: highestSeverity !== "aligned"
72
+ },
73
+ summary: {
74
+ affected_seam_count: affectedSeams.length,
75
+ affected_seam_family_count: affectedSeamFamilies.length,
76
+ affected_output_count: outputs.length,
77
+ maintained_file_count: maintainedFiles.length,
78
+ highest_severity: highestSeverity,
79
+ status_counts: statusCounts,
80
+ affected_seam_families: affectedSeamFamilies
81
+ },
82
+ outputs,
83
+ maintained_files_in_scope: maintainedFiles,
84
+ human_owned_seams: humanOwnedSeams,
85
+ affected_seam_families: affectedSeamFamilies,
86
+ affected_seams: affectedSeams,
87
+ proof_stories: (diffMaintained?.proof_stories || maintainedBoundaryArtifact?.proof_stories || []).map((story) => normalizeProofStorySummary(story)),
88
+ verification_targets: verificationTargets || null,
89
+ recommended_next_action: nextAction || null
90
+ };
91
+ }
92
+
93
+ export function conformanceSeverityRank(state) {
94
+ if (state === "no_go") return 4;
95
+ if (state === "drift_suspected") return 3;
96
+ if (state === "review_required") return 2;
97
+ if (state === "unverifiable") return 1;
98
+ return 0;
99
+ }
100
+
101
+ export function seamConformanceState(seam, { diffBacked }) {
102
+ if ((seam?.status || null) === "no_go") {
103
+ return "no_go";
104
+ }
105
+ if (diffBacked && (seam?.status === "manual_decision" || seam?.status === "review_required")) {
106
+ return "drift_suspected";
107
+ }
108
+ if (!Array.isArray(seam?.proof_stories) || seam.proof_stories.length === 0 || !Array.isArray(seam?.maintained_modules) || seam.maintained_modules.length === 0) {
109
+ return "unverifiable";
110
+ }
111
+ if ((seam?.status || null) === "manual_decision" || (seam?.status || null) === "review_required") {
112
+ return "review_required";
113
+ }
114
+ return "aligned";
115
+ }
116
+
117
+ export function buildMaintainedConformancePayload({
118
+ graph,
119
+ diffArtifact,
120
+ maintainedBoundaryArtifact,
121
+ verificationTargets,
122
+ nextAction
123
+ }) {
124
+ const diffMaintained = diffArtifact?.affected_maintained_surfaces || null;
125
+ const diffBacked = Boolean(diffArtifact);
126
+ const sourceSeams = (diffMaintained?.affected_seams || []).length > 0
127
+ ? diffMaintained.affected_seams
128
+ : (maintainedBoundaryArtifact?.seams || []);
129
+ const seams = sourceSeams
130
+ .map((seam) => {
131
+ const seamChecks = buildSeamProbeReport(graph, seam, {
132
+ verificationTargets: verificationTargetsForOutput(seam.output_id, maintainedBoundaryArtifact, verificationTargets),
133
+ outputRecord: (maintainedBoundaryArtifact?.outputs || []).find((output) => output.output_id === seam.output_id) || null,
134
+ diffBacked
135
+ });
136
+ const outputVerificationTargets = verificationTargetsForOutput(seam.output_id, maintainedBoundaryArtifact, verificationTargets);
137
+ const conformanceState = conformanceStateFromSeamCheck(seam, seamChecks);
138
+ return {
139
+ ...normalizeSeamSummary(seam),
140
+ conformance_state: conformanceState,
141
+ seam_checks: seamChecks,
142
+ evidence: {
143
+ proof_story_count: (seam.proof_stories || []).length,
144
+ has_maintained_modules: Array.isArray(seam.maintained_modules) && seam.maintained_modules.length > 0,
145
+ has_emitted_dependencies: Array.isArray(seam.emitted_dependencies) && seam.emitted_dependencies.length > 0,
146
+ diff_pressure: diffBacked,
147
+ review_boundary_classes: stableSortedStrings((seam.proof_stories || []).map((story) => story.review_boundary?.automation_class).filter(Boolean)),
148
+ verification_target_types: [
149
+ ...((outputVerificationTargets?.generated_checks || []).length > 0 ? ["generated_checks"] : []),
150
+ ...((outputVerificationTargets?.maintained_app_checks || []).length > 0 ? ["maintained_app_checks"] : [])
151
+ ]
152
+ },
153
+ recommended_checks: {
154
+ generated_checks: outputVerificationTargets?.generated_checks || [],
155
+ maintained_app_checks: outputVerificationTargets?.maintained_app_checks || [],
156
+ verification_ids: outputVerificationTargets?.verification_ids || []
157
+ }
158
+ };
159
+ })
160
+ .sort((a, b) => {
161
+ const severityCompare = conformanceSeverityRank(b.conformance_state) - conformanceSeverityRank(a.conformance_state);
162
+ return severityCompare !== 0 ? severityCompare : String(a.seam_id || "").localeCompare(String(b.seam_id || ""));
163
+ });
164
+
165
+ const counts = {
166
+ aligned: seams.filter((seam) => seam.conformance_state === "aligned").length,
167
+ review_required: seams.filter((seam) => seam.conformance_state === "review_required").length,
168
+ drift_suspected: seams.filter((seam) => seam.conformance_state === "drift_suspected").length,
169
+ no_go: seams.filter((seam) => seam.conformance_state === "no_go").length,
170
+ unverifiable: seams.filter((seam) => seam.conformance_state === "unverifiable").length
171
+ };
172
+ const conformanceStatus = seams[0]?.conformance_state || "aligned";
173
+ const outputs = buildMaintainedOutputGroups(
174
+ diffMaintained?.outputs || maintainedBoundaryArtifact?.outputs || [],
175
+ seams,
176
+ {
177
+ summaryField: "conformance_state",
178
+ severitySelector: conformanceSeverityRank,
179
+ verificationTargetsFallback: verificationTargets || null
180
+ }
181
+ ).map((output) => ({
182
+ output_id: output.output_id,
183
+ label: output.label,
184
+ kind: output.kind,
185
+ root_paths: output.root_paths,
186
+ ownership_boundary: output.ownership_boundary,
187
+ write_scope: output.write_scope,
188
+ verification_targets: output.verification_targets,
189
+ maintained_files_in_scope: output.maintained_files_in_scope,
190
+ human_owned_seams: output.human_owned_seams,
191
+ seam_families: output.seam_families,
192
+ conformance_status: output.summary.highest_severity,
193
+ summary: {
194
+ governed_seam_count: output.seams.length,
195
+ affected_seam_family_count: output.summary.affected_seam_family_count || 0,
196
+ aligned_count: output.seams.filter((seam) => seam.conformance_state === "aligned").length,
197
+ review_required_count: output.seams.filter((seam) => seam.conformance_state === "review_required").length,
198
+ drift_suspected_count: output.seams.filter((seam) => seam.conformance_state === "drift_suspected").length,
199
+ no_go_count: output.seams.filter((seam) => seam.conformance_state === "no_go").length,
200
+ unverifiable_count: output.seams.filter((seam) => seam.conformance_state === "unverifiable").length,
201
+ highest_severity: output.summary.highest_severity,
202
+ affected_seam_families: output.summary.affected_seam_families || []
203
+ },
204
+ seams: output.seams
205
+ }));
206
+ const seamFamilies = stableSortedStrings(seams.map((seam) => seam.seam_family_id).filter(Boolean));
207
+
208
+ return {
209
+ type: "maintained_conformance_query",
210
+ baseline_root: diffArtifact?.baseline_root || null,
211
+ diff_summary: summarizeDiffArtifact(diffArtifact),
212
+ conformance_status: conformanceStatus,
213
+ summary: {
214
+ governed_seam_count: seams.length,
215
+ affected_seam_family_count: seamFamilies.length,
216
+ aligned_count: counts.aligned,
217
+ review_required_count: counts.review_required,
218
+ drift_suspected_count: counts.drift_suspected,
219
+ no_go_count: counts.no_go,
220
+ unverifiable_count: counts.unverifiable,
221
+ highest_severity: conformanceStatus,
222
+ affected_seam_families: seamFamilies
223
+ },
224
+ outputs,
225
+ seams,
226
+ verification_targets: verificationTargets || null,
227
+ recommended_next_action: nextAction || null
228
+ };
229
+ }
230
+
231
+ export function buildSeamCheckPayload({
232
+ graph,
233
+ maintainedBoundaryArtifact,
234
+ diffArtifact = null,
235
+ verificationTargets = null,
236
+ nextAction = null,
237
+ seamId = null
238
+ }) {
239
+ const diffBacked = Boolean(diffArtifact);
240
+ const sourceSeams = (diffArtifact?.affected_maintained_surfaces?.affected_seams || []).length > 0
241
+ ? diffArtifact.affected_maintained_surfaces.affected_seams
242
+ : (maintainedBoundaryArtifact?.seams || []);
243
+ const filteredSeams = seamId
244
+ ? sourceSeams.filter((seam) => seam.seam_id === seamId || seam.label === seamId)
245
+ : sourceSeams;
246
+ const seamChecks = filteredSeams
247
+ .map((seam) => {
248
+ const normalized = normalizeSeamSummary(seam);
249
+ const check = buildSeamProbeReport(graph, seam, {
250
+ verificationTargets: verificationTargetsForOutput(normalized.output_id, maintainedBoundaryArtifact, verificationTargets),
251
+ outputRecord: (maintainedBoundaryArtifact?.outputs || []).find((output) => output.output_id === normalized.output_id) || null,
252
+ diffBacked
253
+ });
254
+ return {
255
+ ...compactMaintainedSeamSummary(normalized),
256
+ label: normalized.label,
257
+ check_status: check.check_status,
258
+ probes: check.probes,
259
+ verification_targets: verificationTargetsForOutput(normalized.output_id, maintainedBoundaryArtifact, verificationTargets)
260
+ };
261
+ })
262
+ .sort((a, b) => {
263
+ const rank = { no_go: 4, stale: 3, guarded: 2, unverifiable: 1, aligned: 0 };
264
+ const severityCompare = (rank[b.check_status] ?? 0) - (rank[a.check_status] ?? 0);
265
+ return severityCompare !== 0 ? severityCompare : String(a.seam_id || "").localeCompare(String(b.seam_id || ""));
266
+ });
267
+ const summary = {
268
+ seam_count: seamChecks.length,
269
+ seam_family_count: stableSortedStrings(seamChecks.map((item) => item.seam_family_id).filter(Boolean)).length,
270
+ aligned_count: seamChecks.filter((item) => item.check_status === "aligned").length,
271
+ guarded_count: seamChecks.filter((item) => item.check_status === "guarded").length,
272
+ stale_count: seamChecks.filter((item) => item.check_status === "stale").length,
273
+ no_go_count: seamChecks.filter((item) => item.check_status === "no_go").length,
274
+ unverifiable_count: seamChecks.filter((item) => item.check_status === "unverifiable").length,
275
+ highest_status: seamChecks[0]?.check_status || "aligned"
276
+ };
277
+
278
+ return {
279
+ type: "seam_check_query",
280
+ baseline_root: diffArtifact?.baseline_root || null,
281
+ diff_summary: summarizeDiffArtifact(diffArtifact),
282
+ summary,
283
+ seams: seamChecks,
284
+ recommended_next_action: nextAction || null
285
+ };
286
+ }
@@ -0,0 +1,123 @@
1
+ import {
2
+ canonicalWriteCandidatesFromWriteScope
3
+ } from "../common.js";
4
+ import {
5
+ buildMaintainedRiskSummary
6
+ } from "../maintained-risk.js";
7
+ import {
8
+ buildOperatorLoopSummary,
9
+ recommendedQueryFamilyForAction
10
+ } from "../workflow-context-shared.js";
11
+ import { buildPresetGuidanceSummary } from "./risk.js";
12
+
13
+ export function buildCanonicalWritesPayloadForImportPlan(proposalSurfaces = []) {
14
+ return {
15
+ type: "canonical_writes_query",
16
+ source: "import-plan",
17
+ canonical_writes: proposalSurfaces
18
+ .filter((surface) => surface.canonical_rel_path)
19
+ .map((surface) => ({
20
+ id: surface.id,
21
+ current_state: surface.current_state,
22
+ recommended_state: surface.recommended_state,
23
+ canonical_rel_path: surface.canonical_rel_path,
24
+ canonical_path: `topogram/${surface.canonical_rel_path}`
25
+ }))
26
+ };
27
+ }
28
+
29
+ export function buildCanonicalWritesPayloadForChangePlan(writeScope) {
30
+ return {
31
+ type: "canonical_writes_query",
32
+ source: "change-plan",
33
+ canonical_writes: canonicalWriteCandidatesFromWriteScope(writeScope).map((entry) => ({
34
+ path: entry
35
+ }))
36
+ };
37
+ }
38
+
39
+ export function buildReviewPacketPayloadForImportPlan({ importPlan, risk }) {
40
+ const presetGuidanceSummary = buildPresetGuidanceSummary(importPlan.workflow_presets || null, null);
41
+ return {
42
+ type: "review_packet_query",
43
+ source: "import-plan",
44
+ summary: importPlan.summary || null,
45
+ risk_summary: {
46
+ overall_risk: risk.overall_risk,
47
+ risk_reasons: risk.risk_reasons,
48
+ blocking_factors: risk.blocking_factors,
49
+ maintained_risk: importPlan.maintained_risk || null
50
+ },
51
+ next_action: importPlan.next_action || null,
52
+ recommended_query_family: recommendedQueryFamilyForAction(importPlan.next_action, "import-adopt"),
53
+ canonical_writes: (importPlan.proposal_surfaces || [])
54
+ .filter((surface) => surface.canonical_rel_path)
55
+ .map((surface) => ({
56
+ id: surface.id,
57
+ canonical_rel_path: surface.canonical_rel_path,
58
+ canonical_path: `topogram/${surface.canonical_rel_path}`
59
+ })),
60
+ review_groups: importPlan.review_groups || [],
61
+ write_scope: importPlan.write_scope || null,
62
+ verification_targets: importPlan.verification_targets || null,
63
+ proposal_surfaces: importPlan.proposal_surfaces || [],
64
+ maintained_risk: importPlan.maintained_risk || null,
65
+ maintained_seam_review_summary: importPlan.maintained_seam_review_summary || null,
66
+ operator_loop: buildOperatorLoopSummary({
67
+ mode: "import-adopt",
68
+ nextAction: importPlan.next_action || null,
69
+ primaryArtifacts: ["import-plan", "adoption-plan.agent.json"],
70
+ verificationTargets: importPlan.verification_targets || null,
71
+ currentSurface: "review-packet"
72
+ }),
73
+ output_verification_targets: importPlan.maintained_risk?.output_verification_targets || [],
74
+ preset_guidance_summary: presetGuidanceSummary,
75
+ active_preset_ids: presetGuidanceSummary.active_preset_ids,
76
+ preset_blockers: presetGuidanceSummary.preset_blockers,
77
+ recommended_preset_action: presetGuidanceSummary.recommended_preset_action,
78
+ workflow_presets: importPlan.workflow_presets || null,
79
+ workflow_preset_surfaces: importPlan.workflow_presets?.workflow_preset_surfaces || [],
80
+ workflow_preset_refresh_summary: importPlan.workflow_presets?.workflow_preset_refresh_summary || null
81
+ };
82
+ }
83
+
84
+ export function buildReviewPacketPayloadForChangePlan({ changePlan, risk }) {
85
+ const maintainedRisk = buildMaintainedRiskSummary({
86
+ maintainedImpacts: changePlan.maintained_impacts,
87
+ maintainedBoundary: changePlan.maintained_boundary,
88
+ diffSummary: changePlan.diff_summary
89
+ });
90
+ return {
91
+ type: "review_packet_query",
92
+ source: "change-plan",
93
+ summary: changePlan.summary || null,
94
+ change_summary: changePlan.change_summary || null,
95
+ risk_summary: {
96
+ overall_risk: risk.overall_risk,
97
+ risk_reasons: risk.risk_reasons,
98
+ blocking_factors: risk.blocking_factors,
99
+ maintained_risk: maintainedRisk
100
+ },
101
+ next_action: changePlan.next_action || null,
102
+ recommended_query_family: recommendedQueryFamilyForAction(changePlan.next_action, changePlan.mode || null),
103
+ canonical_writes: canonicalWriteCandidatesFromWriteScope(changePlan.write_scope).map((entry) => ({
104
+ path: entry
105
+ })),
106
+ review_boundary: changePlan.review_boundary || null,
107
+ maintained_boundary: changePlan.maintained_boundary || null,
108
+ maintained_impacts: changePlan.maintained_impacts || null,
109
+ diff_summary: changePlan.diff_summary || null,
110
+ write_scope: changePlan.write_scope || null,
111
+ verification_targets: changePlan.verification_targets || null,
112
+ generator_targets: changePlan.generator_targets || [],
113
+ operator_loop: buildOperatorLoopSummary({
114
+ mode: changePlan.mode || null,
115
+ nextAction: changePlan.next_action || null,
116
+ primaryArtifacts: changePlan.context_artifacts || [],
117
+ verificationTargets: changePlan.verification_targets || null,
118
+ currentSurface: "review-packet"
119
+ }),
120
+ alignment_recommendations: changePlan.alignment_recommendations || [],
121
+ output_verification_targets: maintainedRisk.output_verification_targets || []
122
+ };
123
+ }
@@ -0,0 +1,189 @@
1
+ import {
2
+ stableSortedStrings
3
+ } from "../common.js";
4
+ import {
5
+ buildMaintainedRiskSummary
6
+ } from "../maintained-risk.js";
7
+ import {
8
+ buildOperatorLoopSummary,
9
+ recommendedQueryFamilyForAction
10
+ } from "../workflow-context-shared.js";
11
+
12
+ export function classifyRisk({ reviewBoundary, maintainedBoundary, diffSummary, verificationTargets, importPlan, maintainedRisk = null }) {
13
+ const reasons = [];
14
+ const blockingFactors = [];
15
+ const normalizedMaintainedRisk = maintainedRisk || buildMaintainedRiskSummary({
16
+ maintainedBoundary,
17
+ diffSummary
18
+ });
19
+ const workflowPresets = importPlan?.workflow_presets || null;
20
+ const workflowPresetEntries = [
21
+ ...(workflowPresets?.provider || []),
22
+ ...(workflowPresets?.team || [])
23
+ ];
24
+ const activeWorkflowPresets = workflowPresetEntries.filter((preset) =>
25
+ preset.active_for_context &&
26
+ (
27
+ (preset.kind === "provider_workflow_preset" && ["accept", "accepted"].includes(preset.adoption_state)) ||
28
+ (preset.kind === "team_workflow_preset" && !["reject", "rejected", "stage", "staged"].includes(preset.adoption_state))
29
+ )
30
+ );
31
+ const manualDecisionPreset = activeWorkflowPresets.find((preset) => preset.review_class === "manual_decision");
32
+ const reviewRequiredPreset = activeWorkflowPresets.find((preset) => preset.review_class === "review_required");
33
+ const presetRefreshSummary = workflowPresets?.workflow_preset_refresh_summary?.summary || null;
34
+
35
+ if (normalizedMaintainedRisk.highest_severity === "no_go") {
36
+ reasons.push("maintained_no_go_seam");
37
+ blockingFactors.push("Maintained-app proof boundaries include no-go changes.");
38
+ }
39
+ if ((reviewBoundary?.automation_class || null) === "no_go") {
40
+ reasons.push("review_boundary_no_go");
41
+ blockingFactors.push("Selected surface is classified as no-go for automation.");
42
+ }
43
+ if ((diffSummary?.review_boundary_change_count || 0) > 0) {
44
+ reasons.push("review_boundary_changes_detected");
45
+ blockingFactors.push("Semantic diff changes existing automation/review boundaries.");
46
+ }
47
+ if ((importPlan?.requires_human_review || []).length > 0) {
48
+ reasons.push("import_requires_human_review");
49
+ blockingFactors.push("Imported proposal surfaces still require human review or mapping decisions.");
50
+ }
51
+ if ((presetRefreshSummary?.requires_fresh_review_count || 0) > 0) {
52
+ reasons.push("workflow_preset_refresh_review_required");
53
+ blockingFactors.push("Provider workflow preset refresh changes require fresh review.");
54
+ }
55
+ if (manualDecisionPreset) {
56
+ reasons.push("provider_workflow_preset_manual_decision");
57
+ blockingFactors.push(`Workflow preset ${manualDecisionPreset.id} escalates provider-sensitive review categories.`);
58
+ }
59
+ if (reviewRequiredPreset) {
60
+ reasons.push("provider_workflow_preset_review_required");
61
+ }
62
+ if (normalizedMaintainedRisk.affected_output_count > 1) {
63
+ reasons.push("maintained_multi_output_impact");
64
+ }
65
+ if ((reviewBoundary?.automation_class || null) === "manual_decision") {
66
+ reasons.push("manual_decision_surface");
67
+ }
68
+ if (normalizedMaintainedRisk.highest_severity === "manual_decision") {
69
+ reasons.push("maintained_manual_decision_seam");
70
+ }
71
+ if (normalizedMaintainedRisk.highest_severity === "review_required") {
72
+ reasons.push("maintained_review_required_seam");
73
+ }
74
+ if ((reviewBoundary?.automation_class || null) === "review_required") {
75
+ reasons.push("review_required_surface");
76
+ }
77
+ if ((verificationTargets?.maintained_app_checks || []).length > 0) {
78
+ reasons.push("maintained_proof_gates");
79
+ }
80
+
81
+ let overallRisk = "safe";
82
+ if (reasons.includes("maintained_no_go_seam") || reasons.includes("review_boundary_no_go")) {
83
+ overallRisk = "no_go";
84
+ } else if (
85
+ reasons.includes("review_boundary_changes_detected") ||
86
+ reasons.includes("import_requires_human_review") ||
87
+ reasons.includes("manual_decision_surface") ||
88
+ reasons.includes("maintained_manual_decision_seam") ||
89
+ reasons.includes("provider_workflow_preset_manual_decision") ||
90
+ reasons.includes("workflow_preset_refresh_review_required")
91
+ ) {
92
+ overallRisk = "manual_decision";
93
+ } else if (
94
+ reasons.includes("review_required_surface") ||
95
+ reasons.includes("maintained_review_required_seam") ||
96
+ reasons.includes("maintained_proof_gates") ||
97
+ reasons.includes("provider_workflow_preset_review_required")
98
+ ) {
99
+ overallRisk = "review_required";
100
+ }
101
+
102
+ return {
103
+ overall_risk: overallRisk,
104
+ risk_reasons: reasons,
105
+ blocking_factors: blockingFactors,
106
+ recommended_human_review: overallRisk !== "safe"
107
+ };
108
+ }
109
+
110
+ export function buildRiskSummaryPayload({ source, risk, nextAction, maintainedRisk = null }) {
111
+ return {
112
+ type: "risk_summary_query",
113
+ source,
114
+ ...risk,
115
+ maintained_risk: maintainedRisk,
116
+ recommended_next_action: nextAction || null
117
+ };
118
+ }
119
+
120
+ export function proceedDecisionFromRisk(risk, nextAction, writeScope, verificationTargets, maintainedRisk = null, workflowPresets = null, resolvedWorkflowContext = null) {
121
+ let decision = "proceed";
122
+ let reason = "No explicit review or safety blockers were detected.";
123
+
124
+ if (risk.overall_risk === "no_go") {
125
+ decision = "stop_no_go";
126
+ reason = "At least one no-go boundary blocks automated progress.";
127
+ } else if (risk.overall_risk === "manual_decision") {
128
+ decision = "stage_only";
129
+ reason = "This change should be staged or reviewed rather than applied directly.";
130
+ } else if (risk.overall_risk === "review_required") {
131
+ decision = "proceed_with_review";
132
+ reason = "The change is possible, but it should proceed with explicit human review.";
133
+ }
134
+
135
+ const presetGuidanceSummary = buildPresetGuidanceSummary(workflowPresets, resolvedWorkflowContext);
136
+ return {
137
+ type: "proceed_decision_query",
138
+ decision,
139
+ reason,
140
+ blocking_factors: risk.blocking_factors || [],
141
+ required_human_review: Boolean(risk.recommended_human_review),
142
+ recommended_next_action: nextAction || null,
143
+ recommended_query_family: recommendedQueryFamilyForAction(nextAction, resolvedWorkflowContext?.resolved_task_mode || null),
144
+ recommended_write_scope: writeScope || null,
145
+ recommended_verification_targets: verificationTargets || null,
146
+ operator_loop: buildOperatorLoopSummary({
147
+ mode: resolvedWorkflowContext?.resolved_task_mode || null,
148
+ nextAction,
149
+ primaryArtifacts: resolvedWorkflowContext?.artifact_load_order || [],
150
+ verificationTargets,
151
+ currentSurface: "proceed-decision"
152
+ }),
153
+ maintained_risk: maintainedRisk,
154
+ maintained_seam_review_summary: maintainedRisk?.maintained_seam_review_summary || null,
155
+ output_verification_targets: maintainedRisk?.output_verification_targets || [],
156
+ preset_guidance_summary: presetGuidanceSummary,
157
+ active_preset_ids: presetGuidanceSummary.active_preset_ids
158
+ };
159
+ }
160
+
161
+ export function buildPresetGuidanceSummary(workflowPresets = null, resolvedWorkflowContext = null) {
162
+ const activePresetIds = [
163
+ ...(resolvedWorkflowContext?.applied_presets || []).map((preset) => preset.id),
164
+ ...((workflowPresets?.provider || []).filter((preset) => preset.active_for_context && ["accept", "accepted"].includes(preset.adoption_state)).map((preset) => preset.id)),
165
+ ...((workflowPresets?.team || []).filter((preset) => preset.active_for_context && !["reject", "rejected", "stage", "staged"].includes(preset.adoption_state)).map((preset) => preset.id))
166
+ ];
167
+ const refreshSummary = workflowPresets?.workflow_preset_refresh_summary?.summary || null;
168
+ const recommendedPresetAction = (workflowPresets?.workflow_preset_surfaces || [])
169
+ .map((surface) => surface.recommended_customization_action)
170
+ .find(Boolean)
171
+ || ((workflowPresets?.provider_manifest_summary?.missing_declared_workflow_preset_count || 0) > 0 ? "import_declared_workflow_preset" : null);
172
+ const presetBlockers = stableSortedStrings([
173
+ ...(resolvedWorkflowContext?.effective_review_policy?.block_on || []),
174
+ ...((refreshSummary?.requires_fresh_review_count || 0) > 0 ? ["workflow_preset_refresh_review_required"] : []),
175
+ ...((workflowPresets?.provider_manifest_summary?.invalid_declared_workflow_preset_count || 0) > 0 ? ["invalid_manifest_declared_workflow_preset"] : [])
176
+ ]);
177
+ return {
178
+ active_preset_ids: stableSortedStrings(activePresetIds),
179
+ preset_blockers: presetBlockers,
180
+ recommended_preset_action: recommendedPresetAction,
181
+ summary: {
182
+ active_provider_count: workflowPresets?.active_provider_count || 0,
183
+ active_team_count: workflowPresets?.active_team_count || 0,
184
+ skipped_count: (resolvedWorkflowContext?.skipped_presets || []).length,
185
+ manifest_declared_count: workflowPresets?.provider_manifest_summary?.declared_workflow_preset_count || 0,
186
+ missing_declared_count: workflowPresets?.provider_manifest_summary?.missing_declared_workflow_preset_count || 0
187
+ }
188
+ };
189
+ }
@@ -0,0 +1,25 @@
1
+ export { buildImportPlanPayload } from "./change-risk/import-plan.js";
2
+ export {
3
+ buildAlignmentRecommendations,
4
+ buildChangePlanPayload,
5
+ classifyChangePlan
6
+ } from "./change-risk/change-plan.js";
7
+ export {
8
+ buildMaintainedConformancePayload,
9
+ buildMaintainedDriftPayload,
10
+ buildSeamCheckPayload,
11
+ conformanceSeverityRank,
12
+ seamConformanceState
13
+ } from "./change-risk/maintained.js";
14
+ export {
15
+ buildPresetGuidanceSummary,
16
+ buildRiskSummaryPayload,
17
+ classifyRisk,
18
+ proceedDecisionFromRisk
19
+ } from "./change-risk/risk.js";
20
+ export {
21
+ buildCanonicalWritesPayloadForChangePlan,
22
+ buildCanonicalWritesPayloadForImportPlan,
23
+ buildReviewPacketPayloadForChangePlan,
24
+ buildReviewPacketPayloadForImportPlan
25
+ } from "./change-risk/review-packets.js";