@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,23 +1,41 @@
1
- import { canonicalJson, canonicalSha256, sha256Hex } from '../governance-activation/canonical-json.js';
2
- import { currentActivationIdentity, canonicalPhaseGraph } from '../governance-activation/graph.js';
3
- import { evidenceContextForPhase, requiredLiveReadbackProviders, selectLatestPhaseEvidence } from '../governance-activation/evidence.js';
4
- import { canonicalApprovalEnvelopeHash, evaluateApprovalForTransitionPlan, transitionPlanForPhase } from '../governance-activation/approvals.js';
5
- import { planDigestFor } from '../governance-activation/transitions.js';
1
+ import { canonicalJson, canonicalSha256, sha256Hex } from '../domain/governance/activation/canonical-json.js';
2
+ import { currentActivationIdentity, canonicalPhaseGraph } from '../domain/governance/activation/graph.js';
3
+ import { canonicalApprovalEnvelopeHash, evaluateApprovalForTransitionPlan, transitionPlanForPhase } from '../domain/governance/activation/approvals.js';
4
+ import { formatUpdateCommand } from '../application/update/command-guidance.js';
5
+ import { inspectCurrentActivationEvidence } from '../governance-activation/read-only.js';
6
6
  import { governanceChangeMetadataFileName, validateGovernanceChangeMetadata } from '../governance-activation/source-of-truth.js';
7
+ import { phaseIds } from '../domain/governance/activation/types.js';
7
8
  import { loadAssessmentCatalog } from './catalog.js';
8
- import { inspectAssessmentGit, inspectAssessmentProject, repositoryName } from './project.js';
9
+ import { inspectAssessmentHistoricalActivation, inspectAssessmentProject, ordinaryGitAssessmentProject } from './project.js';
10
+ import { inspectAssessmentGit, repositoryName } from '../adapters/git/governance-assessment.js';
9
11
  import { AssessmentFiles, AssessmentInputError, parseAssessmentJson } from './readers.js';
10
12
  import { parseAssessmentWorkflow } from './yaml.js';
11
13
  import { collectLiveAssessment } from './live.js';
12
- import { classifyFinding, assembleAssessmentReport } from './report.js';
13
- import { actionReferences, failOpenFlags, pinnedActions, protectedRefs, requiredCheckContexts, requiredContextBindings, securityPipeline, singleMaintainer, tagControls, workflowPermissions, observedRequiredContexts } from './predicates.js';
14
- import { isRecord, jsonValue, notObserved, observed, sanitizeAssessmentText, source } from './sanitize.js';
14
+ import { classifyFinding, assembleAssessmentReport } from '../domain/governance/assessment/report.js';
15
+ import { actionReferences, effectiveProtectedRefs, effectiveRequiredContextBindings, failOpenFlags, pinnedActions, protectedRefs, requiredCheckContexts, requiredContextBindings, runnerAlignment, securityPipeline, singleMaintainer, tagControls, workflowPermissions, observedRequiredContexts } from '../domain/governance/assessment/predicates.js';
16
+ import { isRecord, jsonValue, notObserved, observed, sanitizeAssessmentText, source } from '../domain/governance/assessment/sanitize.js';
15
17
  const documentationPaths = [
16
18
  ['CONTRIBUTING.md'], ['docs', 'operations', 'github-governance.md'],
17
19
  ['docs', 'security', 'scanning.md'], ['docs', 'operations', 'alerting.md'],
18
20
  ['docs', 'operations', 'service-health.md'], ['docs', 'security', 'audit-evidence.md'],
19
21
  ['docs', 'ai-acceptable-use.md']
20
22
  ];
23
+ function activationAuthorityFingerprint(inspection) {
24
+ if (inspection.status === 'not-started') {
25
+ return canonicalSha256({ status: inspection.status });
26
+ }
27
+ const firstContext = inspection.contexts[phaseIds[0]];
28
+ const stable = JSON.parse(JSON.stringify({
29
+ status: inspection.status,
30
+ state: inspection.state,
31
+ snapshot: inspection.snapshot,
32
+ migration: inspection.migration,
33
+ records: inspection.records,
34
+ reviewedPlans: firstContext.reviewedPlans ?? [],
35
+ selections: inspection.selections
36
+ }));
37
+ return canonicalSha256(stable);
38
+ }
21
39
  async function localFacts(files, project, capturedAt) {
22
40
  const workflowParts = await files.list(['.github', 'workflows'], ['.yml', '.yaml']);
23
41
  const workflows = [];
@@ -76,6 +94,15 @@ async function localFacts(files, project, capturedAt) {
76
94
  throw new Error('Active governance metadata does not match the recorded change and identity.');
77
95
  }
78
96
  baseline = metadata.baselineSha === '0'.repeat(64) ? null : metadata.baselineSha;
97
+ if (baseline && project.inputSnapshot && baseline !== project.inputSnapshot.baselineSha) {
98
+ project.diagnostics.push({
99
+ code: 'current-input-mismatch',
100
+ severity: 'warning',
101
+ source: parts.join('/'),
102
+ message: 'The recorded governance baseline does not match the independently recomputed current input snapshot; evidence-backed scope is withheld.'
103
+ });
104
+ baseline = null;
105
+ }
79
106
  }
80
107
  catch (error) {
81
108
  project.diagnostics.push({
@@ -97,58 +124,45 @@ async function localFacts(files, project, capturedAt) {
97
124
  };
98
125
  }
99
126
  function boundPlan(project, phaseId, now) {
100
- if (!project.state || !project.bindingBaseline || project.identity.availability !== 'known')
127
+ const currentContext = project.evidenceContexts?.[phaseId];
128
+ const selection = project.activationSelections?.[phaseId];
129
+ const selected = selection?.issues.length === 0 ? selection.selected : null;
130
+ const payload = selected?.payload;
131
+ if (!project.state || !currentContext || !selected ||
132
+ !isRecord(payload) || typeof payload.planDigest !== 'string' ||
133
+ typeof payload.savedPlanDigest !== 'string' ||
134
+ project.identity.availability !== 'known')
101
135
  return null;
102
- const candidates = project.plans.filter((plan) => plan.phaseId === phaseId && plan.baselineDigest === project.bindingBaseline &&
136
+ const candidates = (currentContext.reviewedPlans ?? []).filter((plan) => plan.phaseId === phaseId &&
137
+ plan.planDigest === payload.planDigest &&
138
+ canonicalSha256(plan) === payload.savedPlanDigest &&
139
+ plan.baselineDigest === currentContext.baselineSha &&
103
140
  canonicalJson(plan.identity) === canonicalJson(currentActivationIdentity) &&
104
141
  Date.parse(plan.createdAt) <= now.getTime() &&
105
142
  Date.parse(plan.createdAt) <= Date.parse(project.state.phases[phaseId].updatedAt)).sort((a, b) => Date.parse(b.createdAt) - Date.parse(a.createdAt));
106
143
  const plan = candidates[0];
107
144
  if (!plan || plan.baselineDigest === '0'.repeat(64) || plan.inputDigest === '1'.repeat(64) ||
145
+ plan.baselineDigest !== currentContext.baselineSha ||
146
+ plan.inputDigest !== currentContext.inputDigest ||
147
+ plan.transitionDigest !== currentContext.transition.transitionDigest ||
108
148
  candidates.some((candidate) => candidate.createdAt === plan.createdAt && candidate.planDigest !== plan.planDigest))
109
149
  return null;
110
- const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === phaseId);
111
- if (!phase)
112
- return null;
113
- const authority = transitionPlanForPhase(phase, project.state, {
114
- phaseId, baselineSha: plan.baselineDigest, inputDigest: plan.inputDigest, transitionDigest: plan.transitionDigest
115
- });
116
- if (plan.planDigest !== planDigestFor({
117
- phase, transitionDigest: plan.transitionDigest, operations: plan.operations, approvalPlanDigest: authority.planDigest
118
- }))
119
- return null;
120
150
  return plan;
121
151
  }
122
152
  export function selectBoundAssessmentEvidence(project, phaseId, now) {
123
153
  const plan = boundPlan(project, phaseId, now);
124
- if (!plan || !project.state)
154
+ const selection = project.activationSelections?.[phaseId];
155
+ const selected = selection?.issues.length === 0 ? selection.selected : null;
156
+ if (!plan || !project.state || !selected ||
157
+ selected.header.result !== project.state.phases[phaseId].state)
125
158
  return null;
126
- if (new Set(project.evidence.map((record) => record.evidenceId)).size !== project.evidence.length)
127
- return null;
128
- const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === phaseId);
129
- const references = project.state.phases[phaseId].evidence;
130
- const candidates = project.evidence.filter((record) => record.header.phaseId === phaseId &&
131
- references.some((reference) => reference.phaseId === phaseId && reference.evidenceId === record.evidenceId &&
132
- reference.headerDigest === canonicalSha256(record.header) && reference.result === record.header.result));
133
- const selected = selectLatestPhaseEvidence(candidates, evidenceContextForPhase(phaseId, {
134
- repositoryId: project.state.repository.id, identity: currentActivationIdentity,
135
- phaseGraphHash: currentActivationIdentity.phaseGraphHash, now,
136
- baselineSha: plan.baselineDigest, inputDigest: plan.inputDigest, transitionDigest: plan.transitionDigest,
137
- liveReadbackProviders: phase ? requiredLiveReadbackProviders(phase) : []
138
- })).selected;
139
- if (!selected || selected.header.result !== project.state.phases[phaseId].state)
140
- return null;
141
- const record = candidates.find((entry) => entry.evidenceId === selected.evidenceId &&
142
- canonicalSha256(entry.header) === selected.headerDigest);
143
- return record ? { ...selected, record } : null;
159
+ return selected;
144
160
  }
145
161
  function applicability(control, project, now) {
146
162
  if (control.applicability === 'always')
147
163
  return 'applicable';
148
- if (project.project.workload.kind === 'power-apps-code-app')
149
- return 'inapplicable';
150
164
  if (control.applicability === 'api')
151
- return 'applicable';
165
+ return project.kind === 'liftoff' ? 'applicable' : 'unknown';
152
166
  const discovery = selectBoundAssessmentEvidence(project, 'phase-0-complete', now);
153
167
  if (!project.state || discovery?.header.result !== 'verified')
154
168
  return 'unknown';
@@ -156,41 +170,81 @@ function applicability(control, project, now) {
156
170
  ? project.state.applicability.privateStagingDast
157
171
  : project.state.applicability.statePath === 'bootstrap-local') ? 'applicable' : 'inapplicable';
158
172
  }
173
+ function approvalBindsRepository(project, approval, repository, now) {
174
+ const currentBaseline = project.inputSnapshot?.baselineSha ??
175
+ project.bindingBaseline;
176
+ if (!project.state || !currentBaseline)
177
+ return false;
178
+ const plan = boundPlan(project, approval.phaseId, now);
179
+ const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === approval.phaseId);
180
+ const authority = plan && phase ? transitionPlanForPhase(phase, project.state, {
181
+ phaseId: phase.id,
182
+ baselineSha: plan.baselineDigest,
183
+ inputDigest: plan.inputDigest,
184
+ transitionDigest: plan.transitionDigest
185
+ }) : null;
186
+ return approval.baselineSha === currentBaseline &&
187
+ project.identity.availability === 'known' &&
188
+ Date.parse(approval.approvedAt) <= now.getTime() &&
189
+ Date.parse(approval.expiresAt) > now.getTime() &&
190
+ project.state.phases[approval.phaseId].approvals.includes(approval.id) &&
191
+ Boolean(plan && authority && phase?.approvalGate.required) &&
192
+ authority?.planDigest === approval.planDigest &&
193
+ !evaluateApprovalForTransitionPlan(authority, [approval], { now }).approvalRequired &&
194
+ plan.approval.envelopeId === approval.id &&
195
+ plan.approval.envelopeHash === canonicalApprovalEnvelopeHash(approval) &&
196
+ approval.destinations.some((destination) => destination.type === 'repository' &&
197
+ (destination.repository ?? destination.identity).toLowerCase() === repository.toLowerCase());
198
+ }
159
199
  export function resolveAssessmentLiveScope(project, git, now) {
160
- const stateRepo = project.state ? repositoryName(project.state.repository.name, project.state.repository.id) : null;
161
- let repository = git.originState === 'unavailable' ? null : git.repository ?? stateRepo;
162
- if (git.repository && stateRepo) {
163
- if (`${git.repository.owner}/${git.repository.name}`.toLowerCase() !== `${stateRepo.owner}/${stateRepo.name}`.toLowerCase()) {
164
- repository = null;
165
- project.diagnostics.push({ code: 'repository-binding-conflict', severity: 'warning', source: 'Git/activation state', message: 'Git origin and recorded repository disagree; live collection is withheld.' });
200
+ let repository = git.originState === 'verified' ? git.repository : null;
201
+ let remoteBindingVerified = false;
202
+ if (git.repository && project.state?.remoteBinding) {
203
+ const remote = project.state.remoteBinding;
204
+ const bound = repositoryName(remote.name, remote.id);
205
+ const matchingPush = git.pushUrls.length === 1 &&
206
+ git.pushUrls[0] === remote.pushUrl &&
207
+ project.inputSnapshot?.git.pushUrls.length === 1 &&
208
+ project.inputSnapshot.git.pushUrls[0] === remote.pushUrl;
209
+ if (!bound ||
210
+ `${git.repository.owner}/${git.repository.name}`.toLowerCase() !==
211
+ `${bound.owner}/${bound.name}`.toLowerCase() ||
212
+ !matchingPush) {
213
+ project.diagnostics.push({
214
+ code: 'repository-binding-conflict',
215
+ severity: 'warning',
216
+ source: 'Git/activation state',
217
+ message: 'Git fetch/push origin and the verified remote repository binding disagree; evidence-backed provider scope is withheld.'
218
+ });
219
+ }
220
+ else {
221
+ repository = { ...git.repository, id: bound.id };
222
+ remoteBindingVerified = true;
166
223
  }
167
- else
168
- repository = { ...git.repository, id: stateRepo.id };
169
224
  }
170
225
  const scope = {
171
- repository, refs: ['develop', 'main'],
172
- environments: project.project.workload.kind === 'power-apps-code-app' ? [] : [...project.project.workload.environments],
226
+ repository,
227
+ refs: repository ? ['develop', 'main'] : [],
228
+ ...(repository ? { refPrefixes: ['release/', 'hotfix/'] } : {}),
229
+ environments: project.project ? [...project.project.workload.environments] : [],
173
230
  runner: null, azure: []
174
231
  };
175
232
  if (!repository || !project.state)
176
233
  return scope;
234
+ if (!remoteBindingVerified) {
235
+ project.diagnostics.push({
236
+ code: 'remote-binding-unavailable',
237
+ severity: 'warning',
238
+ source: 'activation state',
239
+ message: 'No matching verified remote repository binding is available; evidence-backed runner and Azure reads are withheld.'
240
+ });
241
+ return scope;
242
+ }
177
243
  const fullName = `${repository.owner}/${repository.name}`;
244
+ const azureBindings = new Map();
245
+ const conflictingAzureBindings = new Set();
178
246
  for (const approval of project.approvals) {
179
- const plan = boundPlan(project, approval.phaseId, now);
180
- const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === approval.phaseId);
181
- const authority = plan && phase ? transitionPlanForPhase(phase, project.state, {
182
- phaseId: phase.id, baselineSha: plan.baselineDigest, inputDigest: plan.inputDigest, transitionDigest: plan.transitionDigest
183
- }) : null;
184
- if (!project.bindingBaseline || approval.baselineSha !== project.bindingBaseline ||
185
- project.identity.availability !== 'known' ||
186
- Date.parse(approval.approvedAt) > now.getTime() ||
187
- Date.parse(approval.expiresAt) <= now.getTime() ||
188
- !project.state.phases[approval.phaseId].approvals.includes(approval.id) ||
189
- !plan || !authority || !phase?.approvalGate.required || authority.planDigest !== approval.planDigest ||
190
- evaluateApprovalForTransitionPlan(authority, [approval], { now }).approvalRequired ||
191
- plan.approval.envelopeId !== approval.id ||
192
- plan.approval.envelopeHash !== canonicalApprovalEnvelopeHash(approval) ||
193
- !approval.destinations.some((destination) => destination.type === 'repository' && (destination.repository ?? destination.identity).toLowerCase() === fullName.toLowerCase()))
247
+ if (!approvalBindsRepository(project, approval, fullName, now))
194
248
  continue;
195
249
  const environments = approval.destinations.filter((destination) => destination.type === 'environment' &&
196
250
  ['dev', 'staging', 'prod'].includes(destination.identity)).map((destination) => destination.identity);
@@ -199,22 +253,79 @@ export function resolveAssessmentLiveScope(project, git, now) {
199
253
  const environment = environments[0];
200
254
  if (environment !== 'dev' && environment !== 'staging' && environment !== 'prod')
201
255
  continue;
202
- for (const resource of approval.resources) {
203
- const match = resource.identity.match(/^\/subscriptions\/([a-f0-9-]{36})\/resourceGroups\/[^/]+\/providers\/([A-Za-z0-9.]+)\/([A-Za-z0-9]+)\/[^/]+(?:\/[A-Za-z0-9]+\/[^/]+)*$/iu);
204
- if (!match || !approval.destinations.some((destination) => destination.type === 'subscription' && (destination.subscriptionId ?? destination.identity).toLowerCase() === match[1].toLowerCase()))
256
+ const selected = selectBoundAssessmentEvidence(project, approval.phaseId, now);
257
+ const payload = selected?.payload;
258
+ const assessmentScope = isRecord(payload) && isRecord(payload.assessmentScope)
259
+ ? payload.assessmentScope
260
+ : null;
261
+ if (!assessmentScope || !Array.isArray(assessmentScope.azure)) {
262
+ if (approval.resources.some((resource) => resource.identity.startsWith('/subscriptions/')) &&
263
+ !project.diagnostics.some((entry) => entry.code === 'unbound-resource-role' && entry.source === approval.phaseId)) {
264
+ project.diagnostics.push({
265
+ code: 'unbound-resource-role',
266
+ severity: 'warning',
267
+ source: approval.phaseId,
268
+ message: 'Approved ARM resources lacked a current body-committed evidence payload with explicit assessment environment and role; Azure reads were withheld.'
269
+ });
270
+ }
271
+ continue;
272
+ }
273
+ for (const value of assessmentScope.azure) {
274
+ if (!isRecord(value) ||
275
+ Object.keys(value).some((key) => ![
276
+ 'subscriptionId', 'environment', 'resourceId', 'resourceType', 'role'
277
+ ].includes(key)) ||
278
+ typeof value.subscriptionId !== 'string' ||
279
+ value.environment !== environment ||
280
+ typeof value.resourceId !== 'string' ||
281
+ typeof value.resourceType !== 'string' ||
282
+ !['state', 'application', 'runner-network'].includes(String(value.role))) {
205
283
  continue;
206
- const role = ['remote-ready', 'remote-import-verified'].includes(approval.phaseId) ? 'state'
207
- : ['bootstrap-local', 'runner-ready', 'private-backend-proof'].includes(approval.phaseId) ? 'runner-network' : 'application';
208
- const resourceSegments = resource.identity.split('/').slice(6);
209
- scope.azure.push({
210
- subscriptionId: match[1], environment, resourceId: resource.identity,
211
- resourceType: [resourceSegments[0], ...resourceSegments.slice(1).filter((_, index) => index % 2 === 0)].join('/'), role
212
- });
284
+ }
285
+ const subscriptionId = value.subscriptionId;
286
+ const resourceId = value.resourceId;
287
+ const resourceType = value.resourceType;
288
+ const match = resourceId.match(/^\/subscriptions\/([a-f0-9-]{36})\/resourceGroups\/[^/]+\/providers\/([A-Za-z0-9.]+)\/([A-Za-z0-9]+)\/[^/]+(?:\/[A-Za-z0-9]+\/[^/]+)*$/iu);
289
+ if (!match ||
290
+ match[1].toLowerCase() !== subscriptionId.toLowerCase() ||
291
+ !approval.resources.some((resource) => resource.identity.toLowerCase() === resourceId.toLowerCase()) ||
292
+ !approval.destinations.some((destination) => destination.type === 'subscription' &&
293
+ (destination.subscriptionId ?? destination.identity).toLowerCase() === subscriptionId.toLowerCase())) {
294
+ continue;
295
+ }
296
+ const binding = {
297
+ subscriptionId,
298
+ environment: environment,
299
+ resourceId,
300
+ resourceType,
301
+ role: value.role
302
+ };
303
+ const key = binding.resourceId.toLowerCase();
304
+ const previous = azureBindings.get(key);
305
+ if (conflictingAzureBindings.has(key) ||
306
+ previous && (previous.environment !== binding.environment ||
307
+ previous.role !== binding.role ||
308
+ previous.resourceType.toLowerCase() !== binding.resourceType.toLowerCase())) {
309
+ azureBindings.delete(key);
310
+ conflictingAzureBindings.add(key);
311
+ project.diagnostics.push({
312
+ code: 'conflicting-resource-binding',
313
+ severity: 'warning',
314
+ source: binding.resourceId,
315
+ message: 'Conflicting body-committed ARM environment, role, or resource-type bindings were excluded before live scope deduplication.'
316
+ });
317
+ continue;
318
+ }
319
+ if (!previous)
320
+ azureBindings.set(key, binding);
213
321
  }
214
322
  }
215
323
  const runnerRecord = selectBoundAssessmentEvidence(project, 'runner-ready', now);
216
- const rawRunner = runnerRecord?.record.payload;
217
- if (runnerRecord?.header.result === 'verified' && isRecord(rawRunner) && rawRunner.kind === 'runner-ready.v1' &&
324
+ const rawRunner = runnerRecord?.payload;
325
+ const runnerApproval = project.approvals.some((approval) => approval.phaseId === 'runner-ready' &&
326
+ approvalBindsRepository(project, approval, fullName, now));
327
+ if (runnerApproval && runnerRecord?.header.result === 'verified' &&
328
+ isRecord(rawRunner) && rawRunner.kind === 'runner-ready.v1' &&
218
329
  rawRunner.organization === repository.owner && Number.isInteger(rawRunner.runnerId) && Number(rawRunner.runnerId) > 0 &&
219
330
  (rawRunner.groupId === null || Number.isInteger(rawRunner.groupId)) &&
220
331
  (rawRunner.networkConfigurationId === null || typeof rawRunner.networkConfigurationId === 'string')) {
@@ -224,7 +335,7 @@ export function resolveAssessmentLiveScope(project, git, now) {
224
335
  networkConfigurationId: typeof rawRunner.networkConfigurationId === 'string' ? rawRunner.networkConfigurationId : null
225
336
  };
226
337
  }
227
- scope.azure = [...new Map(scope.azure.map((binding) => [binding.resourceId.toLowerCase(), binding])).values()]
338
+ scope.azure = [...azureBindings.values()]
228
339
  .sort((a, b) => a.resourceId.localeCompare(b.resourceId, 'en'));
229
340
  return scope;
230
341
  }
@@ -252,6 +363,34 @@ function livePredicate(live, key, evaluate) {
252
363
  converted.facts = observation.value;
253
364
  return converted;
254
365
  }
366
+ function partialLivePredicate(live, key, evaluate) {
367
+ const observation = live.observations[key];
368
+ if (!observation) {
369
+ return {
370
+ observation: notObserved(`Live ${key} was not collected.`),
371
+ provenDifference: false
372
+ };
373
+ }
374
+ if (observation.availability === 'observed') {
375
+ return {
376
+ observation: livePredicate(live, key, evaluate),
377
+ provenDifference: false
378
+ };
379
+ }
380
+ if (observation.facts !== undefined) {
381
+ const evaluated = evaluate(observation.facts);
382
+ if (evaluated.value === false) {
383
+ return {
384
+ observation: {
385
+ ...observation,
386
+ reason: `${observation.reason ?? 'Live collection was incomplete.'} Independently observed facts prove a difference: ${evaluated.reason}`
387
+ },
388
+ provenDifference: true
389
+ };
390
+ }
391
+ }
392
+ return { observation, provenDifference: false };
393
+ }
255
394
  function bool(value, reason) { return { value, reason }; }
256
395
  function rows(value) {
257
396
  return Array.isArray(value) && value.every(isRecord) ? value : null;
@@ -268,6 +407,18 @@ export function findAssessmentException(control, approvals, scope, baseline, res
268
407
  (scope.environment === null || approval.destinations.some((entry) => entry.type === 'environment' && entry.identity === scope.environment)));
269
408
  return found ? { id: found.id, expiresAt: found.expiresAt, envelopeDigest: canonicalApprovalEnvelopeHash(found) } : null;
270
409
  }
410
+ export function rejectedAssessmentExceptionDiagnostic(control, approvals, exception) {
411
+ if (exception !== null ||
412
+ !approvals.some((approval) => approval.policyExceptions.includes(control.id))) {
413
+ return null;
414
+ }
415
+ return {
416
+ code: 'rejected-exception',
417
+ severity: 'warning',
418
+ source: control.id,
419
+ message: 'A recorded exception was rejected because its current identity, baseline, scope, resource, approval time, or expiry did not match this finding.'
420
+ };
421
+ }
271
422
  function evidenceObservation(project, git, capturedAt) {
272
423
  if (!project.state)
273
424
  return notObserved('No compatible activation state is available.');
@@ -288,14 +439,78 @@ function evidenceObservation(project, git, capturedAt) {
288
439
  return notObserved('Baseline/setup progress, approvals, applicability and current readback are not all established.');
289
440
  return observed(true, source('evidence', 'governance/evidence', capturedAt, project.evidence.map((record) => record.header.phaseId)));
290
441
  }
442
+ function invalidateUnstableObservations(findings, kinds, reason) {
443
+ for (const finding of findings) {
444
+ if (finding.applicability === 'inapplicable')
445
+ continue;
446
+ let invalidated = false;
447
+ for (const layer of finding.requiredProof) {
448
+ const observation = finding.observations[layer];
449
+ if (observation?.source && kinds.has(observation.source.kind)) {
450
+ finding.observations[layer] = notObserved(reason);
451
+ invalidated = true;
452
+ }
453
+ }
454
+ if (!invalidated)
455
+ continue;
456
+ finding.exception = null;
457
+ finding.missingProof = finding.requiredProof.filter((layer) => finding.observations[layer]?.availability === 'not-observed');
458
+ const remaining = finding.requiredProof
459
+ .map((layer) => finding.observations[layer])
460
+ .filter((observation) => observation !== undefined);
461
+ const absent = remaining.some((observation) => observation.availability === 'missing');
462
+ const differs = remaining.some((observation) => observation.availability === 'observed' &&
463
+ canonicalJson(observation.value) !== canonicalJson(finding.expected));
464
+ finding.classification = differs
465
+ ? 'conflicting'
466
+ : absent
467
+ ? 'missing'
468
+ : 'not-observed';
469
+ finding.reasons.push(reason);
470
+ }
471
+ }
472
+ function invalidateChangedActivationAuthority(findings, controls) {
473
+ const controlsById = new Map(controls.map((control) => [
474
+ control.id,
475
+ control
476
+ ]));
477
+ for (const finding of findings) {
478
+ const control = controlsById.get(finding.controlId);
479
+ const evidenceDerivedApplicability = control?.applicability === 'private-dast' ||
480
+ control?.applicability === 'state-path';
481
+ if (finding.applicability === 'inapplicable' &&
482
+ !evidenceDerivedApplicability ||
483
+ !(evidenceDerivedApplicability ||
484
+ finding.requiredProof.includes('evidence') ||
485
+ finding.controlId.startsWith('azure.') ||
486
+ finding.controlId.startsWith('runner.') ||
487
+ finding.controlId.startsWith('evidence.'))) {
488
+ continue;
489
+ }
490
+ if (evidenceDerivedApplicability) {
491
+ finding.applicability = 'unknown';
492
+ }
493
+ finding.classification = 'not-observed';
494
+ finding.exception = null;
495
+ finding.missingProof = [...finding.requiredProof];
496
+ finding.reasons.push('Current activation inputs, evidence references, evidence bodies, or reviewed plans changed during collection; evidence-backed scope and results were withheld.');
497
+ for (const layer of finding.requiredProof) {
498
+ finding.observations[layer] = notObserved('Activation authority changed during collection.');
499
+ }
500
+ }
501
+ }
291
502
  async function managedFindings(control, project, files, scope, capturedAt) {
292
503
  const findings = [];
293
504
  if (project.renderedCore.length === 0) {
294
505
  return [classifyFinding({
295
506
  control, scope, applicability: 'applicable',
296
507
  observations: {
297
- recorded: notObserved('Historical agent selection is not recorded.'),
298
- declared: notObserved('The current handoff cannot be rendered without inferring agent configuration.')
508
+ recorded: notObserved(project.kind === 'git'
509
+ ? 'Ordinary Git repositories have no recorded Liftoff ownership inventory.'
510
+ : 'Historical agent selection is not recorded.'),
511
+ declared: notObserved(project.kind === 'git'
512
+ ? 'No Liftoff managed handoff is inferred for an ordinary Git repository.'
513
+ : 'The current handoff cannot be rendered without inferring agent configuration.')
299
514
  }
300
515
  })];
301
516
  }
@@ -349,7 +564,22 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
349
564
  const branch = repository?.availability === 'observed' && isRecord(repository.value) && typeof repository.value.defaultBranch === 'string'
350
565
  ? repository.value.defaultBranch : null;
351
566
  observations.declared = declaredRules((value) => protectedRefs(value, project.state?.repository.defaultBranch ?? null));
352
- observations.live = livePredicate(live, 'github.rulesets', (value) => protectedRefs(value, branch));
567
+ const rules = live.observations['github.rulesets'];
568
+ const branches = live.observations['github.branches'];
569
+ const families = live.observations['github.ref-families'];
570
+ if (rules?.availability === 'observed' &&
571
+ branches?.availability === 'observed' &&
572
+ families?.availability === 'observed') {
573
+ observations.live = predicateObservation(effectiveProtectedRefs(rules.value, branches.value, families.value, branch), rules.source);
574
+ observations.live.facts = jsonValue({
575
+ rulesets: rules.value,
576
+ branches: branches.value,
577
+ refFamilies: families.value
578
+ });
579
+ }
580
+ else {
581
+ observations.live = notObserved('Complete repository/inherited rulesets, classic/effective branch protection, and bounded release/hotfix enumeration are required.');
582
+ }
353
583
  break;
354
584
  }
355
585
  case 'single-maintainer':
@@ -381,14 +611,27 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
381
611
  : contexts.length ? predicateObservation(bool(true, `Declared contexts: ${contexts.map((entry) => entry.name).join(', ')}`), facts.ruleSource)
382
612
  : absent('No required status check contexts were declared.', facts.ruleSource);
383
613
  const rules = live.observations['github.rulesets'];
614
+ const branches = live.observations['github.branches'];
615
+ const families = live.observations['github.ref-families'];
384
616
  const repository = live.observations['github.repository'];
385
617
  const branch = repository?.availability === 'observed' && isRecord(repository.value) && typeof repository.value.defaultBranch === 'string'
386
618
  ? repository.value.defaultBranch : null;
387
- const declaredBindings = requiredContextBindings(facts.rulesets, liveScope.refs, branch);
388
- const enforcedBindings = rules?.availability === 'observed' ? requiredContextBindings(rules.value, liveScope.refs, branch) : null;
619
+ const familyRefs = families?.availability === 'observed' && isRecord(families.value) &&
620
+ Array.isArray(families.value.refs)
621
+ ? families.value.refs.filter((value) => typeof value === 'string')
622
+ : [];
623
+ const assessedRefs = [...new Set([...liveScope.refs, ...familyRefs])].sort();
624
+ const comparisonRefs = assessedRefs.length ? assessedRefs : ['develop', 'main'];
625
+ const declaredBindings = requiredContextBindings(facts.rulesets, comparisonRefs, branch);
626
+ const rulesetBindings = rules?.availability === 'observed'
627
+ ? requiredContextBindings(rules.value, comparisonRefs, branch)
628
+ : null;
629
+ const enforcedBindings = rules?.availability === 'observed' && branches?.availability === 'observed'
630
+ ? effectiveRequiredContextBindings(rules.value, branches.value, comparisonRefs, branch)
631
+ : rulesetBindings;
389
632
  observations.declared.facts = jsonValue(declaredBindings);
390
- const bindingsDiffer = Boolean(contexts?.length && declaredBindings && enforcedBindings &&
391
- canonicalJson(declaredBindings) !== canonicalJson(enforcedBindings));
633
+ const bindingsDiffer = Boolean(contexts?.length && declaredBindings && rulesetBindings &&
634
+ canonicalJson(declaredBindings) !== canonicalJson(rulesetBindings));
392
635
  if (bindingsDiffer) {
393
636
  difference = 'conflicting';
394
637
  const checks = live.observations['github.checks'];
@@ -398,8 +641,11 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
398
641
  : notObserved(`${reason} Check-run proof remains unobserved: ${checks?.reason ?? 'not collected'}`, rules?.source ?? null);
399
642
  }
400
643
  else {
401
- observations.live = rules?.availability === 'observed' && declaredBindings && enforcedBindings
402
- ? livePredicate(live, 'github.checks', (value) => observedRequiredContexts(rules.value, value, branch))
644
+ observations.live = rules?.availability === 'observed' &&
645
+ families?.availability === 'observed' &&
646
+ declaredBindings &&
647
+ enforcedBindings
648
+ ? livePredicate(live, 'github.checks', (value) => observedRequiredContexts(rules.value, value, branch, branches?.value))
403
649
  : notObserved('Live rule and exact commit-bound check observations are required.');
404
650
  }
405
651
  observations.live.facts = jsonValue({
@@ -457,19 +703,22 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
457
703
  break;
458
704
  case 'runner': {
459
705
  observations.recorded = liveScope.runner ? observed(true, source('evidence', 'runner-ready repository binding', capturedAt, jsonValue(liveScope.runner))) : notObserved('No current, exact runner/group/network binding is available.');
460
- observations.live = livePredicate(live, 'github.runner', (value) => bool(isRecord(value) && value.repositoryAssigned === true
461
- && value.groupId === liveScope.runner?.groupId && value.runnerId === liveScope.runner?.runnerId ? true : null, 'Exact repository/group/network assignment, labels and runner capacity must be observed.'));
706
+ observations.live = livePredicate(live, 'github.runner', (value) => runnerAlignment(value, scope.repository));
462
707
  break;
463
708
  }
464
- case 'providers':
465
- observations.live = livePredicate(live, 'azure.providers', (value) => {
709
+ case 'providers': {
710
+ const evaluation = partialLivePredicate(live, 'azure.providers', (value) => {
466
711
  const providers = rows(value);
467
712
  return bool(!providers?.length ? null : providers.every((entry) => entry.registrationState === 'Registered'), 'Every explicitly required namespace must have terminal Registered readback.');
468
713
  });
714
+ observations.live = evaluation.observation;
715
+ if (evaluation.provenDifference)
716
+ difference = 'conflicting';
469
717
  expected = true;
470
718
  break;
471
- case 'storage':
472
- observations.live = livePredicate(live, 'azure.resources', (value) => {
719
+ }
720
+ case 'storage': {
721
+ const evaluation = partialLivePredicate(live, 'azure.resources', (value) => {
473
722
  const storage = rows(value)?.filter((entry) => String(entry.resourceType).toLowerCase() === 'microsoft.storage/storageaccounts');
474
723
  if (!storage?.length)
475
724
  return bool(null, 'No explicit environment/role-bound storage observation is available.');
@@ -481,11 +730,15 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
481
730
  });
482
731
  return bool(values.includes(false) ? false : values.includes(null) ? null : true, 'State storage requires ZRS; application storage uses Dev LRS and Staging/Production ZRS.');
483
732
  });
733
+ observations.live = evaluation.observation;
734
+ if (evaluation.provenDifference)
735
+ difference = 'conflicting';
484
736
  expected = true;
485
737
  break;
486
- case 'network':
738
+ }
739
+ case 'network': {
487
740
  observations.recorded = liveScope.azure.some((entry) => entry.role === 'runner-network') ? observed(true, source('evidence', 'approved Staging network bindings', capturedAt, jsonValue(liveScope.azure))) : notObserved('No approved Staging network bindings were available.');
488
- observations.live = livePredicate(live, 'azure.resources', (value) => {
741
+ const evaluation = partialLivePredicate(live, 'azure.resources', (value) => {
489
742
  const network = rows(value)?.filter((entry) => entry.role === 'runner-network');
490
743
  if (!network?.length)
491
744
  return bool(null, 'No bound runner-network readback is available.');
@@ -494,7 +747,11 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
494
747
  return bool(false, 'A runner subnet still enables implicit default outbound access.');
495
748
  return bool(null, 'Full subnet, route, DNS and exclusive NAT/Firewall proof is required; observed metadata alone is insufficient.');
496
749
  });
750
+ observations.live = evaluation.observation;
751
+ if (evaluation.provenDifference)
752
+ difference = 'conflicting';
497
753
  break;
754
+ }
498
755
  case 'evidence':
499
756
  observations.evidence = evidenceObservation(project, git, capturedAt);
500
757
  break;
@@ -505,9 +762,15 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
505
762
  for (const layer of control.proofLayers)
506
763
  observations[layer] = notObserved(`No supported evaluator exists for ${control.id}; the required proof is not inferred.`);
507
764
  }
765
+ const exception = findAssessmentException(control, project.approvals, scope, facts.baseline, exceptionResource, now);
766
+ const exceptionDiagnostic = rejectedAssessmentExceptionDiagnostic(control, project.approvals, exception);
767
+ if (exceptionDiagnostic &&
768
+ !project.diagnostics.some((entry) => entry.code === 'rejected-exception' && entry.source === control.id)) {
769
+ project.diagnostics.push(exceptionDiagnostic);
770
+ }
508
771
  return classifyFinding({
509
772
  control, scope, expected, applicability: applicability(control, project, now), observations, difference,
510
- exception: findAssessmentException(control, project.approvals, scope, facts.baseline, exceptionResource, now)
773
+ exception
511
774
  });
512
775
  }
513
776
  export async function assessGovernance(projectRoot, options = {}) {
@@ -522,7 +785,88 @@ export async function assessGovernance(projectRoot, options = {}) {
522
785
  try {
523
786
  const loaded = loadAssessmentCatalog();
524
787
  target = loaded.target;
525
- const project = await inspectAssessmentProject(files);
788
+ let project;
789
+ let git;
790
+ let initialActivationInspection = null;
791
+ let initialActivationFingerprint = null;
792
+ try {
793
+ project = await inspectAssessmentProject(files);
794
+ git = await inspectAssessmentGit(projectRoot, options.runner);
795
+ }
796
+ catch (error) {
797
+ if (!(error instanceof AssessmentInputError) || error.code !== 'project-not-found') {
798
+ throw error;
799
+ }
800
+ git = await inspectAssessmentGit(projectRoot, options.runner);
801
+ if (!git.isRepository) {
802
+ throw new AssessmentInputError('project-not-found', 'No Liftoff manifest or valid Git worktree was found at the selected boundary.');
803
+ }
804
+ project = ordinaryGitAssessmentProject();
805
+ }
806
+ if (project.manifest && project.identity.availability === 'known') {
807
+ try {
808
+ const activation = await inspectCurrentActivationEvidence(projectRoot, project.manifest, {
809
+ ...(options.runner ? { runner: options.runner } : {}),
810
+ now: captured
811
+ });
812
+ initialActivationInspection = activation;
813
+ initialActivationFingerprint = activationAuthorityFingerprint(activation);
814
+ if (activation.status === 'inspected') {
815
+ project.state = activation.state;
816
+ project.stateIdentity = jsonValue(activation.state.identity);
817
+ project.identity.stateSource = 'user';
818
+ project.inputSnapshot = activation.snapshot;
819
+ project.evidenceContexts = activation.contexts;
820
+ project.evidence = activation.records;
821
+ project.plans = activation.contexts[phaseIds[0]].reviewedPlans
822
+ ? [...activation.contexts[phaseIds[0]].reviewedPlans]
823
+ : [];
824
+ project.activationSelections = activation.selections;
825
+ if (activation.migration) {
826
+ const complete = activation.migration.revalidation.status === 'complete';
827
+ project.diagnostics.push({
828
+ code: complete ? 'activation-migration-committed' : 'activation-revalidation-blocked',
829
+ severity: complete ? 'info' : 'warning',
830
+ source: 'governance/migration-state.json',
831
+ message: sanitizeAssessmentText(complete
832
+ ? 'Local v2 migration and approved local revalidation are complete. Preserved v1 history is informational, not live enforcement proof.'
833
+ : `Local v2 migration committed; revalidation is ${activation.migration.revalidation.status}. ${activation.migration.revalidation.nextAction} Run ${formatUpdateCommand(projectRoot, 'check')} after repairing the named blocker.`)
834
+ });
835
+ }
836
+ for (const [phaseId, selection] of Object.entries(activation.selections)) {
837
+ if (selection.selected && selection.historicalIssues?.length) {
838
+ project.diagnostics.push({
839
+ code: 'historical-evidence-ignored',
840
+ severity: 'info',
841
+ source: phaseId,
842
+ message: sanitizeAssessmentText(selection.historicalIssues.map((issue) => issue.message).join('; '))
843
+ });
844
+ }
845
+ if (selection.issues.length === 0)
846
+ continue;
847
+ project.invalidEvidence = true;
848
+ project.diagnostics.push({
849
+ code: 'invalid-current-evidence',
850
+ severity: 'warning',
851
+ source: phaseId,
852
+ message: sanitizeAssessmentText(selection.issues.map((issue) => issue.message).join('; '))
853
+ });
854
+ }
855
+ }
856
+ }
857
+ catch (error) {
858
+ project.identity.availability = 'unsupported';
859
+ project.identity.stateSource = 'unsupported';
860
+ project.diagnostics.push({
861
+ code: 'activation-history-diagnostic-only',
862
+ severity: 'warning',
863
+ source: 'activation read-only inspection',
864
+ message: sanitizeAssessmentText(error instanceof Error
865
+ ? error.message
866
+ : 'Activation history could not be interpreted as current executable proof.')
867
+ });
868
+ }
869
+ }
526
870
  projectIdentity = project.identity;
527
871
  const disabled = project.identity.profile === 'none';
528
872
  if (disabled)
@@ -531,7 +875,6 @@ export async function assessGovernance(projectRoot, options = {}) {
531
875
  snapshot: { capturedAt: captured.toISOString(), repository: null, localHead: null, worktreeDigest: files.digest(), inputsStable: await files.stable() },
532
876
  findings: [], diagnostics: project.diagnostics, disabled: true
533
877
  });
534
- const git = await inspectAssessmentGit(projectRoot, options.runner);
535
878
  project.diagnostics.push(...git.issues.map((message) => ({
536
879
  code: 'git-not-observed', severity: 'warning', message, source: 'Git metadata'
537
880
  })));
@@ -549,21 +892,54 @@ export async function assessGovernance(projectRoot, options = {}) {
549
892
  findings.push(evaluateControl(control, project, facts, live, git, scope, captured));
550
893
  }
551
894
  const worktreeDigest = files.digest();
552
- const finalGit = await inspectAssessmentGit(projectRoot, options.runner);
553
- const inputsStable = await files.stable() && live.refsStable &&
554
- canonicalJson(git) === canonicalJson(finalGit);
555
- if (!inputsStable) {
556
- for (const finding of findings) {
557
- if (finding.applicability === 'inapplicable')
558
- continue;
559
- finding.classification = 'not-observed';
560
- finding.exception = null;
561
- finding.missingProof = [...finding.requiredProof];
562
- finding.reasons.push('Relevant files or refs changed during collection; rerun assessment for a consistent snapshot.');
563
- for (const layer of finding.requiredProof)
564
- finding.observations[layer] = notObserved('Inputs changed during collection.');
895
+ let activationStable = true;
896
+ if (project.manifest && initialActivationInspection && initialActivationFingerprint) {
897
+ try {
898
+ const finalActivation = await inspectCurrentActivationEvidence(projectRoot, project.manifest, {
899
+ ...(options.runner ? { runner: options.runner } : {}),
900
+ now: captured
901
+ });
902
+ activationStable =
903
+ activationAuthorityFingerprint(finalActivation) ===
904
+ initialActivationFingerprint;
905
+ }
906
+ catch {
907
+ activationStable = false;
908
+ }
909
+ }
910
+ let historicalActivationStable = true;
911
+ if (project.historicalActivation) {
912
+ const finalHistorical = await inspectAssessmentHistoricalActivation(projectRoot);
913
+ historicalActivationStable = finalHistorical.fingerprint === project.historicalActivation.fingerprint;
914
+ if (!historicalActivationStable) {
915
+ project.diagnostics = project.diagnostics.filter((entry) => entry !== project.historicalActivation?.diagnostic);
916
+ project.diagnostics.push({
917
+ code: 'activation-history-changed',
918
+ severity: 'warning',
919
+ source: 'activation read-only inspection',
920
+ message: sanitizeAssessmentText(`Historical activation inputs changed during collection; migration eligibility was withheld. Rerun assessment, then use ${formatUpdateCommand(projectRoot, 'check')} to review a stable source.`)
921
+ });
565
922
  }
566
923
  }
924
+ const finalGit = await inspectAssessmentGit(projectRoot, options.runner);
925
+ const filesStable = await files.stable();
926
+ const gitStable = canonicalJson(git) === canonicalJson(finalGit);
927
+ const inputsStable = filesStable && gitStable && activationStable && historicalActivationStable;
928
+ if (!filesStable) {
929
+ invalidateUnstableObservations(findings, new Set(['file', 'evidence']), 'Relevant local files changed during collection; rerun assessment for current local proof.');
930
+ }
931
+ if (!gitStable) {
932
+ invalidateUnstableObservations(findings, new Set(['git']), 'Relevant Git metadata changed during collection; rerun assessment for current Git proof.');
933
+ }
934
+ if (!activationStable) {
935
+ invalidateChangedActivationAuthority(findings, loaded.catalog.controls);
936
+ project.diagnostics.push({
937
+ code: 'activation-authority-changed',
938
+ severity: 'warning',
939
+ source: 'activation read-only inspection',
940
+ message: 'Current activation inputs, evidence, state references, or reviewed plans changed during collection; dependent proof was withheld.'
941
+ });
942
+ }
567
943
  return assembleAssessmentReport({
568
944
  projectRoot, mode: options.live ? 'live' : 'local', target, projectIdentity,
569
945
  snapshot: { capturedAt: captured.toISOString(), repository, localHead: git.head, worktreeDigest, inputsStable },