@msn-control/liftoff 0.10.4 → 0.11.2

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 (700) hide show
  1. package/DEVELOPER.md +238 -77
  2. package/README.md +38 -33
  3. package/assets/supported-stack.json +3 -136
  4. package/dist/adapters/azure/governance-assessment.d.ts +2 -0
  5. package/dist/adapters/azure/governance-assessment.js +21 -0
  6. package/dist/adapters/azure/governance-assessment.js.map +1 -0
  7. package/dist/adapters/filesystem/atomic-write.d.ts +2 -0
  8. package/dist/adapters/filesystem/atomic-write.js +74 -0
  9. package/dist/adapters/filesystem/atomic-write.js.map +1 -0
  10. package/dist/adapters/filesystem/errors.d.ts +2 -0
  11. package/dist/adapters/filesystem/errors.js +8 -0
  12. package/dist/adapters/filesystem/errors.js.map +1 -0
  13. package/dist/adapters/filesystem/manifest-file.d.ts +1 -0
  14. package/dist/adapters/filesystem/manifest-file.js +21 -0
  15. package/dist/adapters/filesystem/manifest-file.js.map +1 -0
  16. package/dist/adapters/filesystem/project-config.d.ts +4 -0
  17. package/dist/adapters/filesystem/project-config.js +157 -0
  18. package/dist/adapters/filesystem/project-config.js.map +1 -0
  19. package/dist/adapters/filesystem/project-discovery.d.ts +2 -0
  20. package/dist/adapters/filesystem/project-discovery.js +30 -0
  21. package/dist/adapters/filesystem/project-discovery.js.map +1 -0
  22. package/dist/adapters/filesystem/project-files.d.ts +6 -0
  23. package/dist/adapters/filesystem/project-files.js +68 -0
  24. package/dist/adapters/filesystem/project-files.js.map +1 -0
  25. package/dist/adapters/filesystem/project-lock.d.ts +8 -0
  26. package/dist/adapters/filesystem/project-lock.js +164 -0
  27. package/dist/adapters/filesystem/project-lock.js.map +1 -0
  28. package/dist/adapters/filesystem/project-paths.d.ts +2 -0
  29. package/dist/adapters/filesystem/project-paths.js +60 -0
  30. package/dist/adapters/filesystem/project-paths.js.map +1 -0
  31. package/dist/adapters/filesystem/project-transaction.d.ts +24 -0
  32. package/dist/adapters/filesystem/project-transaction.js +177 -0
  33. package/dist/adapters/filesystem/project-transaction.js.map +1 -0
  34. package/dist/adapters/filesystem/reviewed-update-transaction.d.ts +53 -0
  35. package/dist/adapters/filesystem/reviewed-update-transaction.js +864 -0
  36. package/dist/adapters/filesystem/reviewed-update-transaction.js.map +1 -0
  37. package/dist/adapters/filesystem/update-previews.d.ts +50 -0
  38. package/dist/adapters/filesystem/update-previews.js +613 -0
  39. package/dist/adapters/filesystem/update-previews.js.map +1 -0
  40. package/dist/adapters/git/governance-assessment.d.ts +22 -0
  41. package/dist/adapters/git/governance-assessment.js +161 -0
  42. package/dist/adapters/git/governance-assessment.js.map +1 -0
  43. package/dist/adapters/github/governance-assessment.d.ts +2 -0
  44. package/dist/adapters/github/governance-assessment.js +18 -0
  45. package/dist/adapters/github/governance-assessment.js.map +1 -0
  46. package/dist/adapters/packaged-assets/package-root.d.ts +3 -0
  47. package/dist/adapters/packaged-assets/package-root.js +21 -0
  48. package/dist/adapters/packaged-assets/package-root.js.map +1 -0
  49. package/dist/adapters/packaged-assets/supported-stack.d.ts +4 -0
  50. package/dist/adapters/packaged-assets/supported-stack.js +18 -0
  51. package/dist/adapters/packaged-assets/supported-stack.js.map +1 -0
  52. package/dist/adapters/packaged-assets/template-assets.d.ts +23 -0
  53. package/dist/adapters/packaged-assets/template-assets.js +36 -0
  54. package/dist/adapters/packaged-assets/template-assets.js.map +1 -0
  55. package/dist/adapters/process/shell-command.d.ts +6 -0
  56. package/dist/adapters/process/shell-command.js +27 -0
  57. package/dist/adapters/process/shell-command.js.map +1 -0
  58. package/dist/application/context.d.ts +25 -0
  59. package/dist/application/context.js +2 -0
  60. package/dist/application/context.js.map +1 -0
  61. package/dist/application/diagnose/doctor.d.ts +21 -0
  62. package/dist/application/diagnose/doctor.js +580 -0
  63. package/dist/application/diagnose/doctor.js.map +1 -0
  64. package/dist/application/diagnose/generated-project.d.ts +1 -0
  65. package/dist/application/diagnose/generated-project.js +105 -0
  66. package/dist/application/diagnose/generated-project.js.map +1 -0
  67. package/dist/application/diagnose/validate.d.ts +6 -0
  68. package/dist/application/diagnose/validate.js +27 -0
  69. package/dist/application/diagnose/validate.js.map +1 -0
  70. package/dist/application/initialize/fixture.d.ts +2 -0
  71. package/dist/application/initialize/fixture.js +39 -0
  72. package/dist/application/initialize/fixture.js.map +1 -0
  73. package/dist/application/initialize/inputs.d.ts +3 -0
  74. package/dist/application/initialize/inputs.js +35 -0
  75. package/dist/application/initialize/inputs.js.map +1 -0
  76. package/dist/application/initialize/use-case.d.ts +23 -0
  77. package/dist/application/initialize/use-case.js +360 -0
  78. package/dist/application/initialize/use-case.js.map +1 -0
  79. package/dist/application/migrate/use-case.d.ts +7 -0
  80. package/dist/application/migrate/use-case.js +378 -0
  81. package/dist/application/migrate/use-case.js.map +1 -0
  82. package/dist/application/project/catalog.d.ts +46 -0
  83. package/dist/application/project/catalog.js +12 -0
  84. package/dist/application/project/catalog.js.map +1 -0
  85. package/dist/application/project/manifest.d.ts +2 -0
  86. package/dist/application/project/manifest.js +29 -0
  87. package/dist/application/project/manifest.js.map +1 -0
  88. package/dist/application/project/planning.d.ts +6 -0
  89. package/dist/application/project/planning.js +12 -0
  90. package/dist/application/project/planning.js.map +1 -0
  91. package/dist/application/update/approval.d.ts +39 -0
  92. package/dist/application/update/approval.js +54 -0
  93. package/dist/application/update/approval.js.map +1 -0
  94. package/dist/application/update/command-guidance.d.ts +2 -0
  95. package/dist/application/update/command-guidance.js +14 -0
  96. package/dist/application/update/command-guidance.js.map +1 -0
  97. package/dist/application/update/inspection.d.ts +37 -0
  98. package/dist/application/update/inspection.js +235 -0
  99. package/dist/application/update/inspection.js.map +1 -0
  100. package/dist/application/update/migration-runtime.d.ts +14 -0
  101. package/dist/application/update/migration-runtime.js +178 -0
  102. package/dist/application/update/migration-runtime.js.map +1 -0
  103. package/dist/application/update/output.d.ts +134 -0
  104. package/dist/application/update/output.js +182 -0
  105. package/dist/application/update/output.js.map +1 -0
  106. package/dist/application/update/planning.d.ts +40 -0
  107. package/dist/application/update/planning.js +293 -0
  108. package/dist/application/update/planning.js.map +1 -0
  109. package/dist/application/update/preview.d.ts +49 -0
  110. package/dist/application/update/preview.js +220 -0
  111. package/dist/application/update/preview.js.map +1 -0
  112. package/dist/application/update/protected-source.d.ts +25 -0
  113. package/dist/application/update/protected-source.js +81 -0
  114. package/dist/application/update/protected-source.js.map +1 -0
  115. package/dist/application/update/reporting.d.ts +42 -0
  116. package/dist/application/update/reporting.js +326 -0
  117. package/dist/application/update/reporting.js.map +1 -0
  118. package/dist/application/update/revalidation-plan.d.ts +22 -0
  119. package/dist/application/update/revalidation-plan.js +108 -0
  120. package/dist/application/update/revalidation-plan.js.map +1 -0
  121. package/dist/application/update/revalidation.d.ts +70 -0
  122. package/dist/application/update/revalidation.js +337 -0
  123. package/dist/application/update/revalidation.js.map +1 -0
  124. package/dist/application/update/review-plan.d.ts +25 -0
  125. package/dist/application/update/review-plan.js +89 -0
  126. package/dist/application/update/review-plan.js.map +1 -0
  127. package/dist/application/update/transaction-approval.d.ts +29 -0
  128. package/dist/application/update/transaction-approval.js +82 -0
  129. package/dist/application/update/transaction-approval.js.map +1 -0
  130. package/dist/application/update/use-case.d.ts +9 -0
  131. package/dist/application/update/use-case.js +271 -0
  132. package/dist/application/update/use-case.js.map +1 -0
  133. package/dist/application/update/write-plan.d.ts +15 -0
  134. package/dist/application/update/write-plan.js +115 -0
  135. package/dist/application/update/write-plan.js.map +1 -0
  136. package/dist/application/upgrade/use-case.d.ts +6 -0
  137. package/dist/application/upgrade/use-case.js +82 -0
  138. package/dist/application/upgrade/use-case.js.map +1 -0
  139. package/dist/args.d.ts +5 -65
  140. package/dist/args.js +4 -472
  141. package/dist/args.js.map +1 -1
  142. package/dist/artifact-lifecycle.d.ts +1 -21
  143. package/dist/artifact-lifecycle.js +1 -75
  144. package/dist/artifact-lifecycle.js.map +1 -1
  145. package/dist/catalogs.d.ts +1 -50
  146. package/dist/catalogs.js +1 -472
  147. package/dist/catalogs.js.map +1 -1
  148. package/dist/cli/args/contracts.d.ts +51 -0
  149. package/dist/cli/args/contracts.js +2 -0
  150. package/dist/cli/args/contracts.js.map +1 -0
  151. package/dist/cli/args/definitions.d.ts +6 -0
  152. package/dist/cli/args/definitions.js +188 -0
  153. package/dist/cli/args/definitions.js.map +1 -0
  154. package/dist/cli/args/help.d.ts +5 -0
  155. package/dist/cli/args/help.js +142 -0
  156. package/dist/cli/args/help.js.map +1 -0
  157. package/dist/cli/args/parser.d.ts +5 -0
  158. package/dist/cli/args/parser.js +160 -0
  159. package/dist/cli/args/parser.js.map +1 -0
  160. package/dist/cli/args/readers.d.ts +4 -0
  161. package/dist/cli/args/readers.js +19 -0
  162. package/dist/cli/args/readers.js.map +1 -0
  163. package/dist/cli/commands/diagnose.d.ts +4 -0
  164. package/dist/cli/commands/diagnose.js +12 -0
  165. package/dist/cli/commands/diagnose.js.map +1 -0
  166. package/dist/cli/commands/dispatch.d.ts +3 -0
  167. package/dist/cli/commands/dispatch.js +94 -0
  168. package/dist/cli/commands/dispatch.js.map +1 -0
  169. package/dist/cli/commands/help.d.ts +3 -0
  170. package/dist/cli/commands/help.js +32 -0
  171. package/dist/cli/commands/help.js.map +1 -0
  172. package/dist/cli/commands/helpers.d.ts +8 -0
  173. package/dist/cli/commands/helpers.js +97 -0
  174. package/dist/cli/commands/helpers.js.map +1 -0
  175. package/dist/cli/commands/initialize.d.ts +3 -0
  176. package/dist/cli/commands/initialize.js +7 -0
  177. package/dist/cli/commands/initialize.js.map +1 -0
  178. package/dist/cli/commands/migrate.d.ts +3 -0
  179. package/dist/cli/commands/migrate.js +8 -0
  180. package/dist/cli/commands/migrate.js.map +1 -0
  181. package/dist/cli/commands/plan.d.ts +3 -0
  182. package/dist/cli/commands/plan.js +34 -0
  183. package/dist/cli/commands/plan.js.map +1 -0
  184. package/dist/cli/commands/reference.d.ts +5 -0
  185. package/dist/cli/commands/reference.js +43 -0
  186. package/dist/cli/commands/reference.js.map +1 -0
  187. package/dist/cli/commands/update.d.ts +3 -0
  188. package/dist/cli/commands/update.js +10 -0
  189. package/dist/cli/commands/update.js.map +1 -0
  190. package/dist/cli/commands/upgrade.d.ts +3 -0
  191. package/dist/cli/commands/upgrade.js +7 -0
  192. package/dist/cli/commands/upgrade.js.map +1 -0
  193. package/dist/cli/context.d.ts +1 -0
  194. package/dist/cli/context.js +2 -0
  195. package/dist/cli/context.js.map +1 -0
  196. package/dist/cli/project-options.d.ts +3 -0
  197. package/dist/cli/project-options.js +41 -0
  198. package/dist/cli/project-options.js.map +1 -0
  199. package/dist/cli.d.ts +3 -3
  200. package/dist/cli.js +2 -2
  201. package/dist/cli.js.map +1 -1
  202. package/dist/commands.d.ts +4 -35
  203. package/dist/commands.js +3 -2969
  204. package/dist/commands.js.map +1 -1
  205. package/dist/container-validation.d.ts +1 -1
  206. package/dist/domain/governance/activation/approvals.d.ts +351 -0
  207. package/dist/domain/governance/activation/approvals.js +528 -0
  208. package/dist/domain/governance/activation/approvals.js.map +1 -0
  209. package/dist/domain/governance/activation/canonical-json.d.ts +4 -0
  210. package/dist/domain/governance/activation/canonical-json.js +39 -0
  211. package/dist/domain/governance/activation/canonical-json.js.map +1 -0
  212. package/dist/domain/governance/activation/capabilities.d.ts +7 -0
  213. package/dist/domain/governance/activation/capabilities.js +33 -0
  214. package/dist/domain/governance/activation/capabilities.js.map +1 -0
  215. package/dist/domain/governance/activation/evidence.d.ts +63 -0
  216. package/dist/domain/governance/activation/evidence.js +444 -0
  217. package/dist/domain/governance/activation/evidence.js.map +1 -0
  218. package/dist/domain/governance/activation/graph.d.ts +397 -0
  219. package/dist/domain/governance/activation/graph.js +441 -0
  220. package/dist/domain/governance/activation/graph.js.map +1 -0
  221. package/dist/domain/governance/activation/inputs.d.ts +25 -0
  222. package/dist/domain/governance/activation/inputs.js +63 -0
  223. package/dist/domain/governance/activation/inputs.js.map +1 -0
  224. package/dist/domain/governance/activation/operations.d.ts +19 -0
  225. package/dist/domain/governance/activation/operations.js +181 -0
  226. package/dist/domain/governance/activation/operations.js.map +1 -0
  227. package/dist/domain/governance/activation/readiness.d.ts +27 -0
  228. package/dist/domain/governance/activation/readiness.js +269 -0
  229. package/dist/domain/governance/activation/readiness.js.map +1 -0
  230. package/dist/domain/governance/activation/types.d.ts +399 -0
  231. package/dist/domain/governance/activation/types.js +109 -0
  232. package/dist/domain/governance/activation/types.js.map +1 -0
  233. package/dist/domain/governance/activation/validators.d.ts +22 -0
  234. package/dist/domain/governance/activation/validators.js +1347 -0
  235. package/dist/domain/governance/activation/validators.js.map +1 -0
  236. package/dist/domain/governance/assessment/catalog.d.ts +14 -0
  237. package/dist/domain/governance/assessment/catalog.js +105 -0
  238. package/dist/domain/governance/assessment/catalog.js.map +1 -0
  239. package/dist/domain/governance/assessment/errors.d.ts +10 -0
  240. package/dist/domain/governance/assessment/errors.js +22 -0
  241. package/dist/domain/governance/assessment/errors.js.map +1 -0
  242. package/dist/domain/governance/assessment/index.d.ts +8 -0
  243. package/dist/domain/governance/assessment/index.js +9 -0
  244. package/dist/domain/governance/assessment/index.js.map +1 -0
  245. package/dist/domain/governance/assessment/live-normalize.d.ts +19 -0
  246. package/dist/domain/governance/assessment/live-normalize.js +403 -0
  247. package/dist/domain/governance/assessment/live-normalize.js.map +1 -0
  248. package/dist/domain/governance/assessment/predicates.d.ts +36 -0
  249. package/dist/domain/governance/assessment/predicates.js +545 -0
  250. package/dist/domain/governance/assessment/predicates.js.map +1 -0
  251. package/dist/domain/governance/assessment/report.d.ts +23 -0
  252. package/dist/domain/governance/assessment/report.js +266 -0
  253. package/dist/domain/governance/assessment/report.js.map +1 -0
  254. package/dist/domain/governance/assessment/sanitize.d.ts +8 -0
  255. package/dist/domain/governance/assessment/sanitize.js +60 -0
  256. package/dist/domain/governance/assessment/sanitize.js.map +1 -0
  257. package/dist/domain/governance/assessment/types.d.ts +174 -0
  258. package/dist/domain/governance/assessment/types.js +13 -0
  259. package/dist/domain/governance/assessment/types.js.map +1 -0
  260. package/dist/domain/governance/assessment/yaml.d.ts +6 -0
  261. package/dist/domain/governance/assessment/yaml.js +30 -0
  262. package/dist/domain/governance/assessment/yaml.js.map +1 -0
  263. package/dist/domain/governance/policy/identity.d.ts +64 -0
  264. package/dist/domain/governance/policy/identity.js +112 -0
  265. package/dist/domain/governance/policy/identity.js.map +1 -0
  266. package/dist/domain/migration/dependencies.d.ts +7 -0
  267. package/dist/domain/migration/dependencies.js +221 -0
  268. package/dist/domain/migration/dependencies.js.map +1 -0
  269. package/dist/domain/migration/inventory.d.ts +3 -0
  270. package/dist/domain/migration/inventory.js +15 -0
  271. package/dist/domain/migration/inventory.js.map +1 -0
  272. package/dist/domain/project/artifact-lifecycle.d.ts +69 -0
  273. package/dist/domain/project/artifact-lifecycle.js +137 -0
  274. package/dist/domain/project/artifact-lifecycle.js.map +1 -0
  275. package/dist/domain/project/catalog.d.ts +48 -0
  276. package/dist/domain/project/catalog.js +507 -0
  277. package/dist/domain/project/catalog.js.map +1 -0
  278. package/dist/domain/project/contracts.d.ts +247 -0
  279. package/dist/domain/project/contracts.js +2 -0
  280. package/dist/domain/project/contracts.js.map +1 -0
  281. package/dist/domain/project/errors.d.ts +3 -0
  282. package/dist/domain/project/errors.js +7 -0
  283. package/dist/domain/project/errors.js.map +1 -0
  284. package/dist/domain/project/infrastructure-layout.d.ts +26 -0
  285. package/dist/domain/project/infrastructure-layout.js +125 -0
  286. package/dist/domain/project/infrastructure-layout.js.map +1 -0
  287. package/dist/domain/project/inputs.d.ts +21 -0
  288. package/dist/domain/project/inputs.js +41 -0
  289. package/dist/domain/project/inputs.js.map +1 -0
  290. package/dist/domain/project/manifest/artifacts.d.ts +8 -0
  291. package/dist/domain/project/manifest/artifacts.js +150 -0
  292. package/dist/domain/project/manifest/artifacts.js.map +1 -0
  293. package/dist/domain/project/manifest/context.d.ts +13 -0
  294. package/dist/domain/project/manifest/context.js +2 -0
  295. package/dist/domain/project/manifest/context.js.map +1 -0
  296. package/dist/domain/project/manifest/fields.d.ts +6 -0
  297. package/dist/domain/project/manifest/fields.js +36 -0
  298. package/dist/domain/project/manifest/fields.js.map +1 -0
  299. package/dist/domain/project/manifest/governance.d.ts +8 -0
  300. package/dist/domain/project/manifest/governance.js +161 -0
  301. package/dist/domain/project/manifest/governance.js.map +1 -0
  302. package/dist/domain/project/manifest/project-identity.d.ts +6 -0
  303. package/dist/domain/project/manifest/project-identity.js +273 -0
  304. package/dist/domain/project/manifest/project-identity.js.map +1 -0
  305. package/dist/domain/project/manifest/reader.d.ts +9 -0
  306. package/dist/domain/project/manifest/reader.js +141 -0
  307. package/dist/domain/project/manifest/reader.js.map +1 -0
  308. package/dist/domain/project/paths.d.ts +2 -0
  309. package/dist/domain/project/paths.js +29 -0
  310. package/dist/domain/project/paths.js.map +1 -0
  311. package/dist/domain/project/planning.d.ts +19 -0
  312. package/dist/domain/project/planning.js +329 -0
  313. package/dist/domain/project/planning.js.map +1 -0
  314. package/dist/domain/project/retired-workload.d.ts +4 -0
  315. package/dist/domain/project/retired-workload.js +18 -0
  316. package/dist/domain/project/retired-workload.js.map +1 -0
  317. package/dist/domain/project/reviewed-update-artifacts.d.ts +2 -0
  318. package/dist/domain/project/reviewed-update-artifacts.js +3 -0
  319. package/dist/domain/project/reviewed-update-artifacts.js.map +1 -0
  320. package/dist/domain/project/supported-stack.d.ts +113 -0
  321. package/dist/domain/project/supported-stack.js +426 -0
  322. package/dist/domain/project/supported-stack.js.map +1 -0
  323. package/dist/domain/workstation/constraints.d.ts +6 -0
  324. package/dist/domain/workstation/constraints.js +8 -0
  325. package/dist/domain/workstation/constraints.js.map +1 -0
  326. package/dist/file-system.d.ts +10 -44
  327. package/dist/file-system.js +9 -1245
  328. package/dist/file-system.js.map +1 -1
  329. package/dist/framework-adapters.d.ts +1 -1
  330. package/dist/framework-validation.d.ts +1 -1
  331. package/dist/framework-validation.js +1 -1
  332. package/dist/framework-validation.js.map +1 -1
  333. package/dist/genai-templates.d.ts +2 -9
  334. package/dist/genai-templates.js +4 -5
  335. package/dist/genai-templates.js.map +1 -1
  336. package/dist/generators/common/artifacts.d.ts +6 -0
  337. package/dist/generators/common/artifacts.js +30 -0
  338. package/dist/generators/common/artifacts.js.map +1 -0
  339. package/dist/generators/common/base.d.ts +17 -0
  340. package/dist/generators/common/base.js +425 -0
  341. package/dist/generators/common/base.js.map +1 -0
  342. package/dist/generators/common/dotenv-validation.d.ts +2 -0
  343. package/dist/generators/common/dotenv-validation.js +80 -0
  344. package/dist/generators/common/dotenv-validation.js.map +1 -0
  345. package/dist/generators/common/environments.d.ts +3 -0
  346. package/dist/generators/common/environments.js +15 -0
  347. package/dist/generators/common/environments.js.map +1 -0
  348. package/dist/generators/common/frontend.d.ts +15 -0
  349. package/dist/generators/common/frontend.js +166 -0
  350. package/dist/generators/common/frontend.js.map +1 -0
  351. package/dist/generators/common/python-settings.d.ts +2 -0
  352. package/dist/generators/common/python-settings.js +70 -0
  353. package/dist/generators/common/python-settings.js.map +1 -0
  354. package/dist/generators/common/spec-workflow.d.ts +28 -0
  355. package/dist/generators/common/spec-workflow.js +567 -0
  356. package/dist/generators/common/spec-workflow.js.map +1 -0
  357. package/dist/generators/common/values.d.ts +13 -0
  358. package/dist/generators/common/values.js +16 -0
  359. package/dist/generators/common/values.js.map +1 -0
  360. package/dist/generators/containers/compose.d.ts +7 -0
  361. package/dist/generators/containers/compose.js +196 -0
  362. package/dist/generators/containers/compose.js.map +1 -0
  363. package/dist/generators/containers/context.d.ts +1 -0
  364. package/dist/generators/containers/context.js +43 -0
  365. package/dist/generators/containers/context.js.map +1 -0
  366. package/dist/generators/containers/images.d.ts +7 -0
  367. package/dist/generators/containers/images.js +119 -0
  368. package/dist/generators/containers/images.js.map +1 -0
  369. package/dist/generators/context.d.ts +42 -0
  370. package/dist/generators/context.js +38 -0
  371. package/dist/generators/context.js.map +1 -0
  372. package/dist/generators/genai/backend.d.ts +20 -0
  373. package/dist/generators/genai/backend.js +667 -0
  374. package/dist/generators/genai/backend.js.map +1 -0
  375. package/dist/generators/genai/configuration.d.ts +3 -0
  376. package/dist/generators/genai/configuration.js +43 -0
  377. package/dist/generators/genai/configuration.js.map +1 -0
  378. package/dist/generators/genai/database.d.ts +7 -0
  379. package/dist/generators/genai/database.js +71 -0
  380. package/dist/generators/genai/database.js.map +1 -0
  381. package/dist/generators/genai/functions.d.ts +15 -0
  382. package/dist/generators/genai/functions.js +156 -0
  383. package/dist/generators/genai/functions.js.map +1 -0
  384. package/dist/generators/genai/index.d.ts +8 -0
  385. package/dist/generators/genai/index.js +11 -0
  386. package/dist/generators/genai/index.js.map +1 -0
  387. package/dist/generators/genai/patterns.d.ts +9 -0
  388. package/dist/generators/genai/patterns.js +309 -0
  389. package/dist/generators/genai/patterns.js.map +1 -0
  390. package/dist/generators/infrastructure/azure.d.ts +18 -0
  391. package/dist/generators/infrastructure/azure.js +655 -0
  392. package/dist/generators/infrastructure/azure.js.map +1 -0
  393. package/dist/generators/infrastructure/names.d.ts +23 -0
  394. package/dist/generators/infrastructure/names.js +51 -0
  395. package/dist/generators/infrastructure/names.js.map +1 -0
  396. package/dist/generators/standard/configuration.d.ts +3 -0
  397. package/dist/generators/standard/configuration.js +26 -0
  398. package/dist/generators/standard/configuration.js.map +1 -0
  399. package/dist/generators/standard/go.d.ts +17 -0
  400. package/dist/generators/standard/go.js +338 -0
  401. package/dist/generators/standard/go.js.map +1 -0
  402. package/dist/generators/standard/index.d.ts +12 -0
  403. package/dist/generators/standard/index.js +12 -0
  404. package/dist/generators/standard/index.js.map +1 -0
  405. package/dist/generators/standard/node.d.ts +20 -0
  406. package/dist/generators/standard/node.js +314 -0
  407. package/dist/generators/standard/node.js.map +1 -0
  408. package/dist/generators/standard/python.d.ts +18 -0
  409. package/dist/generators/standard/python.js +191 -0
  410. package/dist/generators/standard/python.js.map +1 -0
  411. package/dist/go-template-assets.js +3 -3
  412. package/dist/go-template-assets.js.map +1 -1
  413. package/dist/governance-activation/activation-state.d.ts +1 -1
  414. package/dist/governance-activation/activation-state.js +49 -9
  415. package/dist/governance-activation/activation-state.js.map +1 -1
  416. package/dist/governance-activation/approvals.d.ts +1 -188
  417. package/dist/governance-activation/approvals.js +1 -507
  418. package/dist/governance-activation/approvals.js.map +1 -1
  419. package/dist/governance-activation/canonical-json.d.ts +1 -3
  420. package/dist/governance-activation/canonical-json.js +1 -35
  421. package/dist/governance-activation/canonical-json.js.map +1 -1
  422. package/dist/governance-activation/commands.d.ts +6 -1
  423. package/dist/governance-activation/commands.js +135 -107
  424. package/dist/governance-activation/commands.js.map +1 -1
  425. package/dist/governance-activation/compatibility.d.ts +30 -5
  426. package/dist/governance-activation/compatibility.js +74 -8
  427. package/dist/governance-activation/compatibility.js.map +1 -1
  428. package/dist/governance-activation/credentials.d.ts +3 -3
  429. package/dist/governance-activation/credentials.js +5 -5
  430. package/dist/governance-activation/credentials.js.map +1 -1
  431. package/dist/governance-activation/doctor.d.ts +1 -1
  432. package/dist/governance-activation/doctor.js +59 -100
  433. package/dist/governance-activation/doctor.js.map +1 -1
  434. package/dist/governance-activation/evidence.d.ts +1 -49
  435. package/dist/governance-activation/evidence.js +1 -245
  436. package/dist/governance-activation/evidence.js.map +1 -1
  437. package/dist/governance-activation/git-ignore.d.ts +9 -0
  438. package/dist/governance-activation/git-ignore.js +76 -0
  439. package/dist/governance-activation/git-ignore.js.map +1 -0
  440. package/dist/governance-activation/graph.d.ts +1 -397
  441. package/dist/governance-activation/graph.js +1 -440
  442. package/dist/governance-activation/graph.js.map +1 -1
  443. package/dist/governance-activation/historical-state.d.ts +81 -0
  444. package/dist/governance-activation/historical-state.js +817 -0
  445. package/dist/governance-activation/historical-state.js.map +1 -0
  446. package/dist/governance-activation/history-contracts.d.ts +109 -0
  447. package/dist/governance-activation/history-contracts.js +303 -0
  448. package/dist/governance-activation/history-contracts.js.map +1 -0
  449. package/dist/governance-activation/identity.d.ts +1 -35
  450. package/dist/governance-activation/identity.js +1 -88
  451. package/dist/governance-activation/identity.js.map +1 -1
  452. package/dist/governance-activation/index.d.ts +3 -0
  453. package/dist/governance-activation/index.js +3 -0
  454. package/dist/governance-activation/index.js.map +1 -1
  455. package/dist/governance-activation/inputs.d.ts +10 -0
  456. package/dist/governance-activation/inputs.js +158 -0
  457. package/dist/governance-activation/inputs.js.map +1 -0
  458. package/dist/governance-activation/migration-history.d.ts +97 -0
  459. package/dist/governance-activation/migration-history.js +388 -0
  460. package/dist/governance-activation/migration-history.js.map +1 -0
  461. package/dist/governance-activation/migration.d.ts +4 -3
  462. package/dist/governance-activation/migration.js +14 -6
  463. package/dist/governance-activation/migration.js.map +1 -1
  464. package/dist/governance-activation/phase-bootstrap-state.d.ts +3 -0
  465. package/dist/governance-activation/phase-bootstrap-state.js +128 -0
  466. package/dist/governance-activation/phase-bootstrap-state.js.map +1 -0
  467. package/dist/governance-activation/phase-discovery.d.ts +2 -0
  468. package/dist/governance-activation/phase-discovery.js +88 -0
  469. package/dist/governance-activation/phase-discovery.js.map +1 -0
  470. package/dist/governance-activation/phase-governance.d.ts +4 -0
  471. package/dist/governance-activation/phase-governance.js +141 -0
  472. package/dist/governance-activation/phase-governance.js.map +1 -0
  473. package/dist/governance-activation/phase-publication.d.ts +8 -0
  474. package/dist/governance-activation/phase-publication.js +318 -0
  475. package/dist/governance-activation/phase-publication.js.map +1 -0
  476. package/dist/governance-activation/proof-records.d.ts +3 -0
  477. package/dist/governance-activation/proof-records.js +78 -0
  478. package/dist/governance-activation/proof-records.js.map +1 -0
  479. package/dist/governance-activation/read-only.d.ts +30 -0
  480. package/dist/governance-activation/read-only.js +33 -0
  481. package/dist/governance-activation/read-only.js.map +1 -0
  482. package/dist/governance-activation/readiness.d.ts +1 -25
  483. package/dist/governance-activation/readiness.js +1 -222
  484. package/dist/governance-activation/readiness.js.map +1 -1
  485. package/dist/governance-activation/reconciliation.d.ts +1 -1
  486. package/dist/governance-activation/reconciliation.js +3 -3
  487. package/dist/governance-activation/reconciliation.js.map +1 -1
  488. package/dist/governance-activation/release-integrity.d.ts +1 -1
  489. package/dist/governance-activation/release-integrity.js +2 -2
  490. package/dist/governance-activation/release-integrity.js.map +1 -1
  491. package/dist/governance-activation/seed-lifecycle.d.ts +36 -6
  492. package/dist/governance-activation/seed-lifecycle.js +444 -77
  493. package/dist/governance-activation/seed-lifecycle.js.map +1 -1
  494. package/dist/governance-activation/source-of-truth.d.ts +5 -3
  495. package/dist/governance-activation/source-of-truth.js +32 -52
  496. package/dist/governance-activation/source-of-truth.js.map +1 -1
  497. package/dist/governance-activation/spec-kit-seed.d.ts +9 -0
  498. package/dist/governance-activation/spec-kit-seed.js +43 -0
  499. package/dist/governance-activation/spec-kit-seed.js.map +1 -0
  500. package/dist/governance-activation/task-projection.d.ts +1 -1
  501. package/dist/governance-activation/transition-planning.d.ts +17 -0
  502. package/dist/governance-activation/transition-planning.js +259 -0
  503. package/dist/governance-activation/transition-planning.js.map +1 -0
  504. package/dist/governance-activation/transition-ports.d.ts +150 -0
  505. package/dist/governance-activation/transition-ports.js +2 -0
  506. package/dist/governance-activation/transition-ports.js.map +1 -0
  507. package/dist/governance-activation/transition-process.d.ts +7 -0
  508. package/dist/governance-activation/transition-process.js +21 -0
  509. package/dist/governance-activation/transition-process.js.map +1 -0
  510. package/dist/governance-activation/transition-records.d.ts +56 -0
  511. package/dist/governance-activation/transition-records.js +208 -0
  512. package/dist/governance-activation/transition-records.js.map +1 -0
  513. package/dist/governance-activation/transitions.d.ts +14 -167
  514. package/dist/governance-activation/transitions.js +173 -2061
  515. package/dist/governance-activation/transitions.js.map +1 -1
  516. package/dist/governance-activation/types.d.ts +1 -390
  517. package/dist/governance-activation/types.js +1 -107
  518. package/dist/governance-activation/types.js.map +1 -1
  519. package/dist/governance-activation/validators.d.ts +1 -17
  520. package/dist/governance-activation/validators.js +1 -1304
  521. package/dist/governance-activation/validators.js.map +1 -1
  522. package/dist/governance-assessment/catalog.d.ts +1 -2
  523. package/dist/governance-assessment/catalog.js +18 -85
  524. package/dist/governance-assessment/catalog.js.map +1 -1
  525. package/dist/governance-assessment/command.d.ts +1 -1
  526. package/dist/governance-assessment/command.js +8 -12
  527. package/dist/governance-assessment/command.js.map +1 -1
  528. package/dist/governance-assessment/engine.d.ts +6 -11
  529. package/dist/governance-assessment/engine.js +490 -114
  530. package/dist/governance-assessment/engine.js.map +1 -1
  531. package/dist/governance-assessment/live-normalize.d.ts +1 -19
  532. package/dist/governance-assessment/live-normalize.js +1 -402
  533. package/dist/governance-assessment/live-normalize.js.map +1 -1
  534. package/dist/governance-assessment/live-transport.d.ts +2 -6
  535. package/dist/governance-assessment/live-transport.js +10 -22
  536. package/dist/governance-assessment/live-transport.js.map +1 -1
  537. package/dist/governance-assessment/live.js +55 -5
  538. package/dist/governance-assessment/live.js.map +1 -1
  539. package/dist/governance-assessment/predicates.d.ts +1 -27
  540. package/dist/governance-assessment/predicates.js +1 -329
  541. package/dist/governance-assessment/predicates.js.map +1 -1
  542. package/dist/governance-assessment/project.d.ts +20 -17
  543. package/dist/governance-assessment/project.js +101 -151
  544. package/dist/governance-assessment/project.js.map +1 -1
  545. package/dist/governance-assessment/readers.d.ts +1 -5
  546. package/dist/governance-assessment/readers.js +5 -13
  547. package/dist/governance-assessment/readers.js.map +1 -1
  548. package/dist/governance-assessment/report.d.ts +1 -23
  549. package/dist/governance-assessment/report.js +1 -265
  550. package/dist/governance-assessment/report.js.map +1 -1
  551. package/dist/governance-assessment/sanitize.d.ts +1 -8
  552. package/dist/governance-assessment/sanitize.js +1 -56
  553. package/dist/governance-assessment/sanitize.js.map +1 -1
  554. package/dist/governance-assessment/types.d.ts +1 -173
  555. package/dist/governance-assessment/types.js +1 -12
  556. package/dist/governance-assessment/types.js.map +1 -1
  557. package/dist/governance-assessment/yaml.d.ts +1 -6
  558. package/dist/governance-assessment/yaml.js +1 -29
  559. package/dist/governance-assessment/yaml.js.map +1 -1
  560. package/dist/init-filesystem.d.ts +1 -1
  561. package/dist/init-filesystem.js +126 -174
  562. package/dist/init-filesystem.js.map +1 -1
  563. package/dist/interactive.d.ts +2 -2
  564. package/dist/interactive.js +42 -41
  565. package/dist/interactive.js.map +1 -1
  566. package/dist/migrate-plan.d.ts +1 -1
  567. package/dist/migrate-plan.js +14 -8
  568. package/dist/migrate-plan.js.map +1 -1
  569. package/dist/npm-template-assets.js +5 -4
  570. package/dist/npm-template-assets.js.map +1 -1
  571. package/dist/openspec-profile.d.ts +1 -1
  572. package/dist/opentofu-template-assets.js +3 -3
  573. package/dist/opentofu-template-assets.js.map +1 -1
  574. package/dist/package-identity.d.ts +3 -0
  575. package/dist/package-identity.js +13 -2
  576. package/dist/package-identity.js.map +1 -1
  577. package/dist/planner.d.ts +1 -19
  578. package/dist/planner.js +1 -565
  579. package/dist/planner.js.map +1 -1
  580. package/dist/process-runner.d.ts +1 -1
  581. package/dist/project-dependencies.d.ts +5 -3
  582. package/dist/project-dependencies.js +74 -63
  583. package/dist/project-dependencies.js.map +1 -1
  584. package/dist/published-verifier.js +61 -30
  585. package/dist/published-verifier.js.map +1 -1
  586. package/dist/python-template-assets.js +6 -9
  587. package/dist/python-template-assets.js.map +1 -1
  588. package/dist/reconcile.d.ts +1 -1
  589. package/dist/reconcile.js +2 -2
  590. package/dist/reconcile.js.map +1 -1
  591. package/dist/repository-governance.d.ts +5 -2
  592. package/dist/repository-governance.js +140 -113
  593. package/dist/repository-governance.js.map +1 -1
  594. package/dist/runtime.js +1 -1
  595. package/dist/runtime.js.map +1 -1
  596. package/dist/scan.d.ts +6 -2
  597. package/dist/scan.js +78 -30
  598. package/dist/scan.js.map +1 -1
  599. package/dist/self-upgrade.d.ts +1 -1
  600. package/dist/self-upgrade.js +20 -7
  601. package/dist/self-upgrade.js.map +1 -1
  602. package/dist/stable-release.js +7 -1
  603. package/dist/stable-release.js.map +1 -1
  604. package/dist/standard-templates.d.ts +2 -2
  605. package/dist/standard-templates.js +6 -841
  606. package/dist/standard-templates.js.map +1 -1
  607. package/dist/supported-stack.d.ts +3 -115
  608. package/dist/supported-stack.js +4 -438
  609. package/dist/supported-stack.js.map +1 -1
  610. package/dist/telemetry/index.d.ts +1 -1
  611. package/dist/templates.d.ts +10 -20
  612. package/dist/templates.js +52 -3261
  613. package/dist/templates.js.map +1 -1
  614. package/dist/types.d.ts +1 -263
  615. package/dist/types.js +1 -1
  616. package/dist/types.js.map +1 -1
  617. package/dist/version.js +2 -6
  618. package/dist/version.js.map +1 -1
  619. package/dist/workstation-catalog.d.ts +5 -2
  620. package/dist/workstation-catalog.js +33 -2
  621. package/dist/workstation-catalog.js.map +1 -1
  622. package/dist/workstation.d.ts +4 -3
  623. package/dist/workstation.js +86 -32
  624. package/dist/workstation.js.map +1 -1
  625. package/docs/assets/liftoff-terminal.svg +3 -3
  626. package/docs/azure-deployment.md +107 -10
  627. package/docs/cli-reference.md +144 -35
  628. package/docs/configuration-and-manifests.md +152 -35
  629. package/docs/existing-repositories.md +48 -12
  630. package/docs/getting-started.md +44 -31
  631. package/docs/prerequisites.md +34 -35
  632. package/docs/project-structure.md +39 -46
  633. package/docs/repository-governance.md +96 -26
  634. package/docs/safety-and-consent.md +90 -28
  635. package/docs/spec-workflows-and-agents.md +31 -28
  636. package/docs/supported-stack.md +11 -9
  637. package/docs/troubleshooting.md +114 -54
  638. package/docs/workloads.md +52 -67
  639. package/package.json +4 -7
  640. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/UPSTREAM_LICENSE.txt +0 -21
  641. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/catalog.json +0 -520
  642. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/packaged/gitignore +0 -27
  643. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/README.md +0 -25
  644. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/components.json +0 -22
  645. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/eslint.config.js +0 -23
  646. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/index.html +0 -13
  647. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package-lock.json +0 -6156
  648. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package.json +0 -60
  649. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/public/power-apps.svg +0 -55
  650. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/App.tsx +0 -17
  651. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/assets/react.svg +0 -1
  652. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/mode-toggle.tsx +0 -37
  653. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/badge.tsx +0 -46
  654. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/button.tsx +0 -60
  655. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/calendar.tsx +0 -211
  656. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/card.tsx +0 -92
  657. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/chart.tsx +0 -355
  658. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/checkbox.tsx +0 -32
  659. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/command.tsx +0 -184
  660. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dialog.tsx +0 -141
  661. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dropdown-menu.tsx +0 -257
  662. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/input.tsx +0 -21
  663. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/label.tsx +0 -22
  664. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/popover.tsx +0 -46
  665. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/progress.tsx +0 -29
  666. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/select.tsx +0 -185
  667. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/separator.tsx +0 -26
  668. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/skeleton.tsx +0 -13
  669. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/table.tsx +0 -114
  670. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tabs.tsx +0 -66
  671. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/textarea.tsx +0 -18
  672. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tooltip.tsx +0 -61
  673. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/hooks/use-theme.ts +0 -11
  674. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/index.css +0 -131
  675. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/lib/utils.ts +0 -6
  676. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/main.tsx +0 -10
  677. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/_layout.tsx +0 -31
  678. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/home.tsx +0 -59
  679. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/not-found.tsx +0 -14
  680. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/query-provider.tsx +0 -26
  681. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/sonner-provider.tsx +0 -23
  682. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/theme-provider.tsx +0 -64
  683. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/router.tsx +0 -24
  684. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.app.json +0 -34
  685. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.json +0 -13
  686. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.node.json +0 -26
  687. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/vite.config.ts +0 -19
  688. package/assets/power-apps-code-app/README.md +0 -27
  689. package/dist/code-apps-plugin.d.ts +0 -13
  690. package/dist/code-apps-plugin.js +0 -69
  691. package/dist/code-apps-plugin.js.map +0 -1
  692. package/dist/power-apps-assets.d.ts +0 -30
  693. package/dist/power-apps-assets.js +0 -131
  694. package/dist/power-apps-assets.js.map +0 -1
  695. package/dist/power-apps-templates.d.ts +0 -3
  696. package/dist/power-apps-templates.js +0 -177
  697. package/dist/power-apps-templates.js.map +0 -1
  698. package/dist/power-apps-validation.d.ts +0 -1
  699. package/dist/power-apps-validation.js +0 -79
  700. package/dist/power-apps-validation.js.map +0 -1
@@ -1,8 +1,15 @@
1
- import { readdir, readFile } from 'node:fs/promises';
1
+ import { lstat, readdir, readFile } from 'node:fs/promises';
2
2
  import { stripVTControlCharacters } from 'node:util';
3
- import { loadManifest, resolveProjectPath, writeProjectFile } from '../file-system.js';
4
- import { getPattern } from '../catalogs.js';
5
- import { toSafeProjectName } from '../planner.js';
3
+ import { loadManifest } from '../application/project/manifest.js';
4
+ import { readProjectFile, writeProjectFile } from '../adapters/filesystem/project-files.js';
5
+ import { resolveProjectPath } from '../adapters/filesystem/project-paths.js';
6
+ import { captureProjectFileSnapshot } from '../adapters/filesystem/project-transaction.js';
7
+ import { withProjectMutationLock } from '../adapters/filesystem/project-lock.js';
8
+ import { completedSpecKitTasks, inspectSpecKitBootstrap, specKitBootstrapId, specKitBootstrapPath } from './spec-kit-seed.js';
9
+ import { canonicalSha256 } from '../domain/governance/activation/canonical-json.js';
10
+ import { getPattern } from '../application/project/catalog.js';
11
+ import { toSafeProjectName } from '../domain/project/planning.js';
12
+ import { assessInfrastructureLayout } from '../domain/project/infrastructure-layout.js';
6
13
  import { formatCommand } from '../process-runner.js';
7
14
  import { detectCredentialLeaks } from './credentials.js';
8
15
  const seedChangePathParts = (changeName) => ['openspec', 'changes', changeName];
@@ -17,12 +24,11 @@ function errorMessage(error) {
17
24
  return error instanceof Error ? error.message : String(error);
18
25
  }
19
26
  export function generatedSeedChangeName(manifest) {
27
+ if (manifest.project.specWorkflow === 'spec-kit')
28
+ return specKitBootstrapId;
20
29
  return `bootstrap-${toSafeProjectName(manifest.project.name)}`;
21
30
  }
22
31
  export function generatedSeedCapabilityId(workload) {
23
- if (workload.kind === 'power-apps-code-app') {
24
- return 'power-apps-code-app-baseline';
25
- }
26
32
  if (workload.kind === 'standard') {
27
33
  return `${workload.apiStack}-application-baseline`;
28
34
  }
@@ -31,7 +37,16 @@ export function generatedSeedCapabilityId(workload) {
31
37
  function isWorkerWorkload(workload) {
32
38
  return workload.kind === 'genai' && getPattern(workload.pattern)?.worker === true;
33
39
  }
34
- export function selectSeedBaselineChecks(manifest, changeName = generatedSeedChangeName(manifest), seedState = 'active') {
40
+ export function seedInfrastructureBaselineBlocker(manifest) {
41
+ const layout = assessInfrastructureLayout(manifest);
42
+ return layout.kind === 'independent' ? undefined :
43
+ `Infrastructure layout migration-required (${layout.kind}): ${layout.reason} ` +
44
+ 'No baseline infrastructure recipe is available; existing roots and state are not moved or initialized.';
45
+ }
46
+ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedChangeName(manifest), seedState = 'active', options = {}) {
47
+ const layoutBlocker = seedInfrastructureBaselineBlocker(manifest);
48
+ if (layoutBlocker)
49
+ throw new Error(layoutBlocker);
35
50
  const workload = manifest.project.workload;
36
51
  const checks = [
37
52
  {
@@ -45,18 +60,7 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
45
60
  }
46
61
  }
47
62
  ];
48
- if (workload.kind === 'power-apps-code-app') {
49
- checks.push({
50
- id: 'backend-tests',
51
- taskId: '2.2',
52
- label: 'Record backend tests as inapplicable',
53
- applicability: {
54
- applicable: false,
55
- reason: 'no Liftoff backend is generated for Power Apps code apps'
56
- }
57
- });
58
- }
59
- else if (workload.kind === 'genai' || workload.apiStack === 'python-fastapi') {
63
+ if (workload.kind === 'genai' || workload.apiStack === 'python-fastapi') {
60
64
  checks.push({
61
65
  id: 'backend-tests',
62
66
  taskId: '2.2',
@@ -115,19 +119,7 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
115
119
  }
116
120
  });
117
121
  }
118
- if (workload.kind === 'power-apps-code-app') {
119
- checks.push({
120
- id: 'frontend-build',
121
- taskId: '2.4',
122
- label: 'Run frontend build',
123
- applicability: {
124
- applicable: true,
125
- command: { executable: 'npm', args: ['run', 'build'] },
126
- cwdPathParts: []
127
- }
128
- });
129
- }
130
- else if (workload.frontend) {
122
+ if (workload.frontend) {
131
123
  checks.push({
132
124
  id: 'frontend-build',
133
125
  taskId: '2.4',
@@ -150,27 +142,7 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
150
142
  }
151
143
  });
152
144
  }
153
- if (workload.kind === 'power-apps-code-app') {
154
- for (const [id, taskId, label] of [
155
- ['docker-compose-config', '2.5', 'Record Docker Compose validation as inapplicable'],
156
- ['tofu-fmt', '2.6', 'Record OpenTofu formatting as inapplicable'],
157
- ['tofu-init', '2.7', 'Record OpenTofu initialization as inapplicable'],
158
- ['tofu-validate', '2.8', 'Record OpenTofu validation as inapplicable']
159
- ]) {
160
- checks.push({
161
- id,
162
- taskId,
163
- label,
164
- applicability: {
165
- applicable: false,
166
- reason: id === 'docker-compose-config'
167
- ? 'no generated Docker Compose boundary is present'
168
- : 'no generated OpenTofu boundary is present'
169
- }
170
- });
171
- }
172
- }
173
- else {
145
+ {
174
146
  checks.push({
175
147
  id: 'docker-compose-config',
176
148
  taskId: '2.5',
@@ -213,7 +185,10 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
213
185
  id: 'openspec-strict',
214
186
  taskId: '2.9',
215
187
  label: 'Run strict OpenSpec validation',
216
- applicability: {
188
+ applicability: manifest.project.specWorkflow === 'spec-kit' ? {
189
+ applicable: false,
190
+ reason: 'Spec Kit validates its real bootstrap bundle and official markers locally; OpenSpec is inapplicable.'
191
+ } : {
217
192
  applicable: true,
218
193
  command: {
219
194
  executable: 'openspec',
@@ -224,7 +199,183 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
224
199
  cwdPathParts: []
225
200
  }
226
201
  });
227
- return checks;
202
+ const environmentChecks = manifest.project.workload.environments.flatMap((environment, index) => {
203
+ const cwdPathParts = ['infrastructure', 'opentofu', 'azure', 'environments', environment];
204
+ return [
205
+ { id: 'tofu-init', taskId: `2.7.${index + 1}`, label: `Initialize ${environment} OpenTofu without a backend`, applicability: {
206
+ applicable: true, command: { executable: 'tofu', args: ['init', '-backend=false'] }, cwdPathParts
207
+ } },
208
+ { id: 'tofu-validate', taskId: `2.8.${index + 1}`, label: `Validate ${environment} OpenTofu without plan or apply`, applicability: {
209
+ applicable: true, command: { executable: 'tofu', args: ['validate'] }, cwdPathParts
210
+ } }
211
+ ];
212
+ });
213
+ const firstInit = checks.findIndex((check) => check.id === 'tofu-init');
214
+ const selected = [...checks.slice(0, firstInit), ...environmentChecks, ...checks.slice(firstInit + 2)];
215
+ if (!options.localRevalidation)
216
+ return selected;
217
+ return selected.filter((check) => check.id !== 'tofu-init').map((check) => {
218
+ if (!check.applicability.applicable)
219
+ return check;
220
+ const applicability = check.applicability;
221
+ const command = applicability.command;
222
+ if (command.executable === 'uv')
223
+ return {
224
+ ...check,
225
+ applicability: {
226
+ ...applicability,
227
+ command: { executable: 'uv', args: ['run', '--no-sync', '--offline', ...command.args.slice(1)] },
228
+ env: { UV_PYTHON_DOWNLOADS: 'never' }
229
+ }
230
+ };
231
+ if (command.executable === 'go')
232
+ return {
233
+ ...check,
234
+ applicability: {
235
+ ...applicability,
236
+ command: { executable: 'go', args: ['test', '-mod=readonly', './...'] },
237
+ env: { GOPROXY: 'off', GOSUMDB: 'off', GOTOOLCHAIN: 'local', GONOPROXY: 'none', GOVCS: '*:off', GOFLAGS: '', GOWORK: 'off' }
238
+ }
239
+ };
240
+ if (command.executable === 'npm')
241
+ return {
242
+ ...check,
243
+ applicability: {
244
+ ...applicability,
245
+ command: { executable: 'npm', args: ['--offline', '--ignore-scripts', '--no-audit', '--no-fund', ...command.args] },
246
+ env: { npm_config_offline: 'true', npm_config_ignore_scripts: 'true', npm_config_update_notifier: 'false' }
247
+ }
248
+ };
249
+ if (command.executable === 'tofu')
250
+ return {
251
+ ...check,
252
+ label: check.id === 'tofu-validate'
253
+ ? `Observe already initialized OpenTofu at ${applicability.cwdPathParts.join('/')} with validate (no init)`
254
+ : check.label,
255
+ applicability: {
256
+ ...applicability,
257
+ env: { TF_CLI_ARGS: '', TF_CLI_ARGS_validate: '', TF_CLI_ARGS_fmt: '', TF_DATA_DIR: '.terraform', TF_INPUT: '0', CHECKPOINT_DISABLE: '1' }
258
+ }
259
+ };
260
+ return check;
261
+ });
262
+ }
263
+ export async function previewLocalSeedPhase(projectRoot, manifest, phaseId) {
264
+ const discovery = await discoverGeneratedSeed(projectRoot, manifest);
265
+ const blockers = discovery.state === 'blocked' ? [...discovery.issues] : [];
266
+ const changeName = generatedSeedChangeName(manifest);
267
+ const commands = [];
268
+ const observations = [];
269
+ let checks = [];
270
+ if (discovery.state === 'archived') {
271
+ const integrity = await inspectArchivedSeedIntegrity(projectRoot, manifest);
272
+ if (integrity.status !== 'valid')
273
+ blockers.push(...(integrity.status === 'invalid'
274
+ ? integrity.issues : ['The archived seed is no longer independently observable.']));
275
+ const archiveRoot = ['openspec', 'changes', 'archive'];
276
+ const archives = (await readdir(await resolveProjectPath(projectRoot, archiveRoot), { withFileTypes: true }))
277
+ .filter((entry) => entry.isDirectory() && (entry.name === changeName || entry.name.endsWith(`-${changeName}`)));
278
+ if (archives.length !== 1)
279
+ blockers.push('The exact archived seed location changed during inspection.');
280
+ else {
281
+ const archived = [...archiveRoot, archives[0].name];
282
+ const capability = generatedSeedCapabilityId(manifest.project.workload);
283
+ const artifacts = [
284
+ ['.openspec.yaml'], ['proposal.md'], ['design.md'], ['tasks.md'], ['specs', capability, 'spec.md']
285
+ ].map((parts) => [...archived, ...parts]);
286
+ observations.push(...artifacts, ['openspec', 'specs', capability, 'spec.md']);
287
+ for (const parts of artifacts) {
288
+ if (!(await readRequiredProjectText(projectRoot, parts)).trim())
289
+ blockers.push(`Archived seed artifact ${parts.join('/')} is empty.`);
290
+ }
291
+ const declared = extractDeclaredCapabilities(await readRequiredProjectText(projectRoot, [...archived, 'proposal.md']));
292
+ if (declared.length !== 1 || declared[0] !== capability)
293
+ blockers.push(`Archived seed proposal must declare exactly the generated capability ${capability}.`);
294
+ }
295
+ }
296
+ else if (discovery.state === 'active') {
297
+ observations.push(discovery.changePathParts);
298
+ }
299
+ if (phaseId === 'seed-verified') {
300
+ const infrastructureBlocker = seedInfrastructureBaselineBlocker(manifest);
301
+ if (infrastructureBlocker)
302
+ blockers.push(infrastructureBlocker);
303
+ else
304
+ checks = selectSeedBaselineChecks(manifest, changeName, discovery.state === 'archived' ? 'archived' : 'active', { localRevalidation: true });
305
+ for (const check of checks) {
306
+ if (!check.applicability.applicable)
307
+ continue;
308
+ const { command, cwdPathParts, env } = check.applicability;
309
+ commands.push({ command, cwdPathParts, env: env ?? {} });
310
+ }
311
+ for (const environment of manifest.project.workload.environments) {
312
+ const root = ['infrastructure', 'opentofu', 'azure', 'environments', environment];
313
+ if (await readProjectFile(projectRoot, [...root, 'main.tf']) === undefined) {
314
+ blockers.push(`Missing selected OpenTofu environment root ${[...root, 'main.tf'].join('/')}.`);
315
+ }
316
+ await requireInstalledDirectory([...root, '.terraform'], 'OpenTofu initialization');
317
+ }
318
+ if (manifest.project.workload.kind === 'genai' || manifest.project.workload.apiStack === 'python-fastapi') {
319
+ await requireInstalledDirectory(['backend', '.venv'], 'Python environment');
320
+ }
321
+ else if (manifest.project.workload.apiStack === 'node-fastify') {
322
+ await requireInstalledDirectory(['backend', 'node_modules'], 'Backend dependencies');
323
+ }
324
+ if (manifest.project.workload.frontend)
325
+ await requireInstalledDirectory(['frontend', 'node_modules'], 'Frontend dependencies');
326
+ }
327
+ else if (manifest.project.specWorkflow === 'openspec') {
328
+ if (phaseId === 'seed-archived' && discovery.state !== 'archived') {
329
+ blockers.push('The seed is not already archived. Review liftoff governance plan and complete its separate setup/archive transition; update revalidation never archives or edits seed files.');
330
+ }
331
+ else {
332
+ commands.push({
333
+ command: { executable: 'openspec', args: discovery.state === 'archived'
334
+ ? ['validate', '--all', '--strict'] : ['validate', changeName, '--strict'] },
335
+ cwdPathParts: [], env: {}
336
+ });
337
+ }
338
+ }
339
+ if (manifest.project.specWorkflow === 'spec-kit' && phaseId !== 'seed-valid') {
340
+ const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
341
+ if (bundle.tasks !== undefined && completedSpecKitTasks(bundle.tasks) !== bundle.tasks) {
342
+ blockers.push('Spec Kit bootstrap tasks are not already the completed matching projection. Review the separate governance setup transition; update revalidation does not write tasks.');
343
+ }
344
+ }
345
+ const actionId = phaseId === 'seed-valid' ? 'openspec.seed.validate'
346
+ : phaseId === 'seed-verified' ? 'openspec.seed.baseline-verify' : 'openspec.seed.archive';
347
+ const operation = {
348
+ adapter: 'selected-spec-workflow', actionId, mutationClass: 'read-worktree', phaseId,
349
+ inputs: {
350
+ changeName, localRevalidation: true, workflow: manifest.project.specWorkflow,
351
+ seedState: discovery.state, observations, commands,
352
+ ...(phaseId === 'seed-verified' ? {
353
+ checks: checks.map((check) => ({
354
+ id: check.id, taskId: check.taskId, label: check.label,
355
+ applicable: check.applicability.applicable,
356
+ ...(check.applicability.applicable ? {
357
+ command: check.applicability.command, cwdPathParts: check.applicability.cwdPathParts,
358
+ env: check.applicability.env ?? {}
359
+ } : { reason: check.applicability.reason })
360
+ }))
361
+ } : {})
362
+ },
363
+ destination: { type: 'local', identity: projectRoot },
364
+ remote: false, destructive: false
365
+ };
366
+ return { phaseId, operation, commands, blockers };
367
+ async function requireInstalledDirectory(parts, label) {
368
+ const target = await resolveProjectPath(projectRoot, parts);
369
+ try {
370
+ if (!(await lstat(target)).isDirectory())
371
+ throw new Error(`${parts.join('/')} must be an existing regular directory.`);
372
+ }
373
+ catch (error) {
374
+ if (errorCode(error) !== 'ENOENT')
375
+ throw error;
376
+ blockers.push(`${label} is unavailable at ${parts.join('/')}. Install or initialize it separately, then run liftoff update --check; revalidation never installs dependencies or runs tofu init.`);
377
+ }
378
+ }
228
379
  }
229
380
  function extractDeclaredCapabilities(proposal) {
230
381
  const capabilities = [];
@@ -331,21 +482,44 @@ export async function inspectArchivedSeedIntegrity(projectRoot, suppliedManifest
331
482
  ]
332
483
  };
333
484
  }
334
- return { status: 'valid', changeName, capabilityId, issues: [] };
485
+ return { status: 'valid', changeName, capabilityId, contentDigest: canonicalSha256(spec.replace(/\r\n/g, '\n')), issues: [] };
335
486
  }
336
- export async function discoverGeneratedSeed(projectRoot) {
337
- const manifest = await loadManifest(projectRoot);
487
+ export async function discoverGeneratedSeed(projectRoot, suppliedManifest) {
488
+ const manifest = suppliedManifest ?? await loadManifest(projectRoot);
338
489
  const changeName = generatedSeedChangeName(manifest);
339
490
  if (manifest.project.specWorkflow !== 'openspec') {
340
- return {
341
- state: 'blocked',
342
- changeName,
343
- issues: ['The generated project does not use OpenSpec, so no OpenSpec bootstrap seed can be completed.']
491
+ const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
492
+ return bundle.issues.length ? { state: 'blocked', changeName, issues: bundle.issues } : {
493
+ state: 'active', changeName, changePathParts: specKitBootstrapPath,
494
+ capabilityId: generatedSeedCapabilityId(manifest.project.workload)
344
495
  };
345
496
  }
346
497
  const active = await activeBootstrapChanges(projectRoot);
347
498
  if (active.length === 0) {
348
499
  if (await archivedBootstrapChangeExists(projectRoot, changeName)) {
500
+ const archiveRoot = await resolveProjectPath(projectRoot, ['openspec', 'changes', 'archive']);
501
+ const archives = (await readdir(archiveRoot, { withFileTypes: true }))
502
+ .filter((entry) => entry.isDirectory() && (entry.name === changeName || entry.name.endsWith(`-${changeName}`)));
503
+ const issues = [];
504
+ if (archives.length !== 1) {
505
+ issues.push(`Expected exactly one archived generated seed ${changeName}; found ${archives.length}.`);
506
+ }
507
+ else {
508
+ const archived = ['openspec', 'changes', 'archive', archives[0].name];
509
+ for (const parts of [
510
+ ['.openspec.yaml'], ['proposal.md'], ['design.md'], ['tasks.md'],
511
+ ['specs', generatedSeedCapabilityId(manifest.project.workload), 'spec.md']
512
+ ]) {
513
+ try {
514
+ await readRequiredProjectText(projectRoot, [...archived, ...parts]);
515
+ }
516
+ catch (error) {
517
+ issues.push(errorMessage(error));
518
+ }
519
+ }
520
+ }
521
+ if (issues.length)
522
+ return { state: 'blocked', changeName, issues };
349
523
  return {
350
524
  state: 'archived',
351
525
  changeName,
@@ -365,6 +539,9 @@ export async function discoverGeneratedSeed(projectRoot) {
365
539
  issues: [`Expected exactly active generated seed ${changeName}; found ${active.join(', ')}.`]
366
540
  };
367
541
  }
542
+ if (await archivedBootstrapChangeExists(projectRoot, changeName)) {
543
+ return { state: 'blocked', changeName, issues: [`Generated seed ${changeName} has both active and archived copies; resolve ownership explicitly without deleting or inventing history.`] };
544
+ }
368
545
  const changePathParts = seedChangePathParts(changeName);
369
546
  const issues = [];
370
547
  let proposal = '';
@@ -411,11 +588,28 @@ function checkFailureDetail(result) {
411
588
  if (result.timedOut) {
412
589
  return 'command timed out';
413
590
  }
591
+ if (result.aborted)
592
+ return 'command was interrupted or cancelled';
593
+ if (result.outputLimitExceeded)
594
+ return 'command output exceeded the supported limit';
595
+ if (result.signal)
596
+ return `command terminated by ${result.signal}`;
414
597
  if (result.errorCode || result.errorMessage) {
415
598
  return [result.errorCode, result.errorMessage].filter(Boolean).join(': ');
416
599
  }
417
600
  return `exit status ${result.status ?? 'unknown'}`;
418
601
  }
602
+ function commandSucceeded(result) {
603
+ return result.status === 0 && !result.signal && !result.timedOut && !result.errorCode &&
604
+ !result.errorMessage && !result.aborted && !result.outputLimitExceeded;
605
+ }
606
+ function localValidationObservation(result) {
607
+ return {
608
+ command: result.command,
609
+ exitStatus: result.status,
610
+ outputDigest: canonicalSha256({ stdout: result.stdout, stderr: result.stderr })
611
+ };
612
+ }
419
613
  function sanitizeOpenSpecDiagnostic(output) {
420
614
  const plain = stripVTControlCharacters(output)
421
615
  .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/gu, '')
@@ -438,7 +632,7 @@ async function validateAllOpenSpecAfterArchive(projectRoot, runner, changeName)
438
632
  args: ['validate', '--all', '--strict']
439
633
  };
440
634
  const result = await runner.run(command, { cwd: projectRoot });
441
- if (result.status !== 0 || result.timedOut || result.errorCode) {
635
+ if (!commandSucceeded(result)) {
442
636
  return {
443
637
  status: 'blocked',
444
638
  issues: [
@@ -463,8 +657,10 @@ async function runSeedBaselineCheck(projectRoot, runner, check) {
463
657
  const cwd = check.applicability.cwdPathParts.length === 0
464
658
  ? projectRoot
465
659
  : await resolveProjectPath(projectRoot, [...check.applicability.cwdPathParts]);
466
- const result = await runner.run(check.applicability.command, { cwd });
467
- if (result.status === 0 && !result.timedOut && !result.errorCode) {
660
+ const result = await runner.run(check.applicability.command, {
661
+ cwd, ...(check.applicability.env ? { env: check.applicability.env } : {})
662
+ });
663
+ if (commandSucceeded(result)) {
468
664
  return {
469
665
  id: check.id,
470
666
  taskId: check.taskId,
@@ -472,6 +668,7 @@ async function runSeedBaselineCheck(projectRoot, runner, check) {
472
668
  status: 'passed',
473
669
  command: check.applicability.command,
474
670
  cwdPathParts: check.applicability.cwdPathParts,
671
+ ...(check.applicability.env ? { env: check.applicability.env } : {}),
475
672
  result
476
673
  };
477
674
  }
@@ -482,6 +679,7 @@ async function runSeedBaselineCheck(projectRoot, runner, check) {
482
679
  status: 'failed',
483
680
  command: check.applicability.command,
484
681
  cwdPathParts: check.applicability.cwdPathParts,
682
+ ...(check.applicability.env ? { env: check.applicability.env } : {}),
485
683
  result,
486
684
  detail: checkFailureDetail(result)
487
685
  };
@@ -532,6 +730,12 @@ export function markAllSeedTasksForArchive(markdown) {
532
730
  '2.6',
533
731
  '2.7',
534
732
  '2.8',
733
+ '2.7.1',
734
+ '2.7.2',
735
+ '2.7.3',
736
+ '2.8.1',
737
+ '2.8.2',
738
+ '2.8.3',
535
739
  '2.9',
536
740
  '3.1'
537
741
  ];
@@ -552,9 +756,22 @@ export function markAllSeedTasksForArchive(markdown) {
552
756
  }
553
757
  return lines.join('\n');
554
758
  }
555
- export async function validateGeneratedSeedForPhase(projectRoot, runner) {
759
+ export async function validateGeneratedSeedForPhase(projectRoot, runner, options = {}) {
556
760
  const discovery = await discoverGeneratedSeed(projectRoot);
557
761
  if (discovery.state === 'archived') {
762
+ if (options.localRevalidation) {
763
+ const integrity = await inspectArchivedSeedIntegrity(projectRoot);
764
+ if (integrity.status !== 'valid')
765
+ return {
766
+ status: 'blocked', changeName: discovery.changeName,
767
+ issues: integrity.status === 'invalid' ? integrity.issues : ['The archived seed is no longer independently observable.']
768
+ };
769
+ const validation = await validateAllOpenSpecAfterArchive(projectRoot, runner, discovery.changeName);
770
+ if (validation.status === 'blocked')
771
+ return { status: 'blocked', changeName: discovery.changeName, issues: validation.issues };
772
+ return { status: 'passed', changeName: discovery.changeName, command: validation.command,
773
+ detail: 'Existing archived seed artifacts are present and synchronized main specifications are strict-valid; no archive was replayed.' };
774
+ }
558
775
  return {
559
776
  status: 'passed',
560
777
  changeName: discovery.changeName,
@@ -568,9 +785,13 @@ export async function validateGeneratedSeedForPhase(projectRoot, runner) {
568
785
  issues: discovery.issues
569
786
  };
570
787
  }
788
+ const manifest = await loadManifest(projectRoot);
789
+ if (manifest.project.specWorkflow === 'spec-kit') {
790
+ return { status: 'passed', changeName: discovery.changeName, detail: 'Real Spec Kit bootstrap bundle and independent official initialization markers are valid.' };
791
+ }
571
792
  const command = { executable: 'openspec', args: ['validate', discovery.changeName, '--strict'] };
572
793
  const result = await runner.run(command, { cwd: projectRoot });
573
- if (result.status !== 0 || result.timedOut || result.errorCode) {
794
+ if (!commandSucceeded(result)) {
574
795
  return {
575
796
  status: 'blocked',
576
797
  changeName: discovery.changeName,
@@ -587,7 +808,7 @@ export async function validateGeneratedSeedForPhase(projectRoot, runner) {
587
808
  detail: 'Generated seed artifacts are present and strict-valid.'
588
809
  };
589
810
  }
590
- export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner) {
811
+ export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner, options = {}) {
591
812
  const manifest = await loadManifest(projectRoot);
592
813
  const discovery = await discoverGeneratedSeed(projectRoot);
593
814
  if (discovery.state === 'blocked') {
@@ -611,7 +832,21 @@ export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner) {
611
832
  };
612
833
  }
613
834
  }
614
- const checks = selectSeedBaselineChecks(manifest, discovery.changeName, discovery.state);
835
+ const layoutBlocker = seedInfrastructureBaselineBlocker(manifest);
836
+ if (layoutBlocker)
837
+ return { status: 'blocked', changeName: discovery.changeName, checks: [], issues: [layoutBlocker] };
838
+ if (options.localRevalidation) {
839
+ const preview = await previewLocalSeedPhase(projectRoot, manifest, 'seed-verified');
840
+ if (preview.blockers.length)
841
+ return { status: 'blocked', changeName: discovery.changeName, checks: [], issues: preview.blockers };
842
+ }
843
+ const checks = selectSeedBaselineChecks(manifest, discovery.changeName, discovery.state, options);
844
+ for (const environment of manifest.project.workload.environments) {
845
+ const parts = ['infrastructure', 'opentofu', 'azure', 'environments', environment, 'main.tf'];
846
+ if (await readProjectFile(projectRoot, parts) === undefined) {
847
+ return { status: 'blocked', changeName: discovery.changeName, checks: [], issues: [`Missing selected OpenTofu environment root ${parts.join('/')}.`] };
848
+ }
849
+ }
615
850
  const outcomes = await runSeedBaselineChecks(projectRoot, runner, checks);
616
851
  const failures = outcomes.filter((outcome) => outcome.status === 'failed');
617
852
  if (failures.length > 0) {
@@ -622,17 +857,46 @@ export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner) {
622
857
  checks: outcomes
623
858
  };
624
859
  }
860
+ if (manifest.project.specWorkflow === 'spec-kit') {
861
+ const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
862
+ if (bundle.issues.length || bundle.tasks === undefined)
863
+ return { status: 'blocked', changeName: discovery.changeName, checks: outcomes, issues: bundle.issues };
864
+ const snapshot = await captureProjectFileSnapshot(projectRoot, [...specKitBootstrapPath, 'tasks.md']);
865
+ if (snapshot.content?.toString('utf8') !== bundle.tasks)
866
+ return {
867
+ status: 'blocked', changeName: discovery.changeName, checks: outcomes, issues: ['Spec Kit tasks changed during baseline finalization; concurrent bytes were preserved.']
868
+ };
869
+ return {
870
+ status: 'passed', changeName: discovery.changeName, checks: outcomes,
871
+ fileMutations: [{ type: 'write', pathParts: [...specKitBootstrapPath, 'tasks.md'], content: completedSpecKitTasks(bundle.tasks) }],
872
+ filePreconditions: [snapshot]
873
+ };
874
+ }
625
875
  return { status: 'passed', changeName: discovery.changeName, checks: outcomes };
626
876
  }
627
- export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
877
+ export async function archiveGeneratedSeedForPhase(projectRoot, runner, options = {}) {
878
+ return withProjectMutationLock(projectRoot, (lease) => archiveGeneratedSeedForPhaseLocked(projectRoot, runner, lease, options));
879
+ }
880
+ async function archiveGeneratedSeedForPhaseLocked(projectRoot, runner, lease, options) {
881
+ const manifest = await loadManifest(projectRoot);
882
+ if (manifest.project.specWorkflow === 'spec-kit') {
883
+ const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
884
+ if (bundle.issues.length || !bundle.tasks || /^\s*- \[ \] B00[1-6] /m.test(bundle.tasks)) {
885
+ return { status: 'blocked', changeName: specKitBootstrapId, issues: [
886
+ ...bundle.issues, 'The explicit Spec Kit local baseline task projection must be finalized by successful baseline execution.'
887
+ ] };
888
+ }
889
+ return { status: 'already-archived', changeName: specKitBootstrapId,
890
+ detail: 'Spec Kit local bootstrap handoff is finalized; no OpenSpec archive or Git branch was created.' };
891
+ }
628
892
  const discovery = await discoverGeneratedSeed(projectRoot);
629
893
  if (discovery.state === 'archived') {
630
894
  const integrity = await inspectArchivedSeedIntegrity(projectRoot);
631
- if (integrity.status === 'invalid') {
895
+ if (integrity.status === 'invalid' || options.localRevalidation && integrity.status !== 'valid') {
632
896
  return {
633
897
  status: 'blocked',
634
898
  changeName: discovery.changeName,
635
- issues: integrity.issues,
899
+ issues: integrity.status === 'invalid' ? integrity.issues : ['The archived seed is no longer independently observable.'],
636
900
  retryableAfterRepair: true
637
901
  };
638
902
  }
@@ -648,6 +912,8 @@ export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
648
912
  return {
649
913
  status: 'already-archived',
650
914
  changeName: discovery.changeName,
915
+ ...(integrity.status === 'valid' ? { synchronizedSpecDigest: integrity.contentDigest } : {}),
916
+ ...(options.localRevalidation ? { validation: validation.command } : {}),
651
917
  detail: `${discovery.detail} The synchronized main specs remain strict-valid.`
652
918
  };
653
919
  }
@@ -658,29 +924,43 @@ export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
658
924
  issues: discovery.issues
659
925
  };
660
926
  }
927
+ if (options.localRevalidation)
928
+ return {
929
+ status: 'blocked', changeName: discovery.changeName,
930
+ issues: ['The seed is not already archived. Review the separate governance setup/archive transition; update revalidation never archives or edits seed files.']
931
+ };
661
932
  const taskPathParts = [...discovery.changePathParts, 'tasks.md'];
662
933
  const originalTasks = await readRequiredProjectText(projectRoot, taskPathParts);
663
934
  const completedTasks = markAllSeedTasksForArchive(originalTasks);
664
935
  await writeProjectFile(projectRoot, taskPathParts, completedTasks);
665
936
  const archiveCommand = { executable: 'openspec', args: ['archive', discovery.changeName, '--yes', '--json'] };
937
+ await lease.assertHeld();
666
938
  const archive = await runner.run(archiveCommand, { cwd: projectRoot });
667
939
  if (archive.status !== 0 || archive.timedOut || archive.errorCode) {
668
- await writeProjectFile(projectRoot, taskPathParts, originalTasks);
940
+ const remaining = await readProjectFile(projectRoot, taskPathParts);
941
+ const archiveCompleted = remaining === undefined && await archivedBootstrapChangeExists(projectRoot, discovery.changeName);
942
+ const restored = remaining?.toString('utf8') === completedTasks;
943
+ if (restored)
944
+ await writeProjectFile(projectRoot, taskPathParts, originalTasks);
669
945
  return {
670
946
  status: 'blocked',
671
947
  changeName: discovery.changeName,
948
+ retryableAfterRepair: true,
949
+ archiveCompleted,
672
950
  issues: [
673
951
  `OpenSpec archive failed: ${formatCommand(archiveCommand)} (${checkFailureDetail(archive)}). ` +
674
- 'Seed tasks were restored and the seed remains active.'
952
+ (archiveCompleted ? 'The seed was already moved to the archive; explicit retry revalidates it without recreating an active seed.' :
953
+ restored ? 'Seed tasks were restored and the seed remains active.' :
954
+ 'Concurrent or uncertain seed task changes were preserved; no original task bytes were written over them.')
675
955
  ]
676
956
  };
677
957
  }
678
958
  const integrity = await inspectArchivedSeedIntegrity(projectRoot);
679
- if (integrity.status === 'invalid') {
959
+ if (integrity.status !== 'valid') {
680
960
  return {
681
961
  status: 'blocked',
682
962
  changeName: discovery.changeName,
683
- issues: integrity.issues,
963
+ issues: integrity.status === 'invalid' ? integrity.issues : ['Archive success was not independently observed; the seed handoff remains incomplete.'],
684
964
  retryableAfterRepair: true,
685
965
  archiveCompleted: true
686
966
  };
@@ -698,13 +978,100 @@ export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
698
978
  return {
699
979
  status: 'archived',
700
980
  changeName: discovery.changeName,
981
+ synchronizedSpecDigest: integrity.contentDigest,
701
982
  capabilityId: discovery.capabilityId,
702
983
  archive,
703
984
  archiveSyncBehavior: 'OpenSpec archive updates main specs as part of archive; the lifecycle engine intentionally never passes --skip-specs.',
704
985
  detail: 'Generated seed was archived and the synchronized main specs passed strict validation.'
705
986
  };
706
987
  }
988
+ export async function executeSeedOperations(input, options = {}) {
989
+ if (!input.phase.id.startsWith('seed-'))
990
+ return null;
991
+ if (input.phase.id === 'seed-valid') {
992
+ const result = await validateGeneratedSeedForPhase(input.inspection.projectRoot, input.runner, options);
993
+ if (result.status === 'blocked') {
994
+ return { status: 'blocked', blocker: result.issues[0] ?? 'Seed validation failed.', completedOperations: [] };
995
+ }
996
+ return {
997
+ status: 'completed',
998
+ resultState: 'verified',
999
+ evidencePayload: {
1000
+ kind: 'seed-valid.v1', changeName: result.changeName, detail: result.detail,
1001
+ ...(options.localRevalidation && result.command ? { validation: localValidationObservation(result.command) } : {})
1002
+ },
1003
+ completedOperations: input.plan.operations.filter((op) => op.actionId === 'openspec.seed.validate')
1004
+ };
1005
+ }
1006
+ if (input.phase.id === 'seed-verified') {
1007
+ const result = await verifyGeneratedSeedBaselineForPhase(input.inspection.projectRoot, input.runner, options);
1008
+ if (result.status === 'blocked') {
1009
+ return { status: 'blocked', blocker: result.issues[0] ?? 'Seed baseline verification failed.', completedOperations: [] };
1010
+ }
1011
+ if (options.localRevalidation) {
1012
+ for (const mutation of result.fileMutations ?? []) {
1013
+ const current = await readProjectFile(input.inspection.projectRoot, mutation.pathParts);
1014
+ if (mutation.type !== 'write' || current?.toString('utf8') !== mutation.content)
1015
+ return {
1016
+ status: 'blocked',
1017
+ blocker: 'The baseline requires a differing Spec Kit task projection. Review the separate setup transition; revalidation preserved the existing tasks.',
1018
+ completedOperations: []
1019
+ };
1020
+ }
1021
+ }
1022
+ return {
1023
+ status: 'completed',
1024
+ resultState: 'verified',
1025
+ evidencePayload: {
1026
+ kind: 'seed-verified.v1',
1027
+ checks: result.checks.map((check) => ({
1028
+ id: check.id, taskId: check.taskId, status: check.status,
1029
+ ...(options.localRevalidation && check.status === 'passed' ? {
1030
+ label: check.label, cwdPathParts: check.cwdPathParts, env: check.env ?? {},
1031
+ ...localValidationObservation(check.result)
1032
+ } : {})
1033
+ }))
1034
+ },
1035
+ completedOperations: input.plan.operations.filter((op) => op.actionId === 'openspec.seed.baseline-verify' || op.actionId === 'seed.tasks.project'),
1036
+ fileMutations: options.localRevalidation ? undefined : result.fileMutations,
1037
+ filePreconditions: result.filePreconditions
1038
+ };
1039
+ }
1040
+ const result = await archiveGeneratedSeedForPhase(input.inspection.projectRoot, input.runner, options);
1041
+ if (result.status === 'blocked') {
1042
+ return {
1043
+ status: 'blocked',
1044
+ blocker: result.issues[0] ?? 'Seed archive failed.',
1045
+ completedOperations: result.archiveCompleted ? input.plan.operations.filter((op) => op.actionId === 'openspec.seed.archive') : [],
1046
+ retryableWithoutStateMutation: result.retryableAfterRepair
1047
+ };
1048
+ }
1049
+ return {
1050
+ status: 'completed',
1051
+ resultState: 'verified',
1052
+ evidencePayload: {
1053
+ kind: 'seed-archived.v1',
1054
+ ...(result.synchronizedSpecDigest ? { synchronizedSpecDigest: result.synchronizedSpecDigest } : {}),
1055
+ archiveSyncBehavior: result.archiveSyncBehavior ?? null,
1056
+ ...(options.localRevalidation ? {
1057
+ observation: result.detail,
1058
+ ...(result.validation ? { validation: localValidationObservation(result.validation) } : {})
1059
+ } : {})
1060
+ },
1061
+ completedOperations: input.plan.operations.filter((op) => op.actionId === 'openspec.seed.archive')
1062
+ };
1063
+ }
707
1064
  export async function completeGeneratedSeedLifecycle(projectRoot, runner) {
1065
+ return withProjectMutationLock(projectRoot, () => completeGeneratedSeedLifecycleLocked(projectRoot, runner));
1066
+ }
1067
+ async function completeGeneratedSeedLifecycleLocked(projectRoot, runner) {
1068
+ const manifest = await loadManifest(projectRoot);
1069
+ if (manifest.project.specWorkflow === 'spec-kit') {
1070
+ return {
1071
+ status: 'blocked', changeName: specKitBootstrapId, checks: [],
1072
+ issues: ['Spec Kit local completion requires the explicitly planned governance apply-next --execute phases so task projection and the body-bound baseline receipt are persisted together. No standalone archive is supported.']
1073
+ };
1074
+ }
708
1075
  const discovery = await discoverGeneratedSeed(projectRoot);
709
1076
  if (discovery.state === 'archived') {
710
1077
  const archive = await archiveGeneratedSeedForPhase(projectRoot, runner);