@msn-control/liftoff 0.11.3 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/DEVELOPER.md +19 -18
  2. package/README.md +18 -18
  3. package/assets/governance/single-maintainer-gitflow/activation-v2-graph.json +1583 -0
  4. package/dist/adapters/credentials/github-enrollment.d.ts +51 -0
  5. package/dist/adapters/credentials/github-enrollment.js +226 -0
  6. package/dist/adapters/credentials/github-enrollment.js.map +1 -0
  7. package/dist/adapters/credentials/protected-input.d.ts +7 -0
  8. package/dist/adapters/credentials/protected-input.js +68 -0
  9. package/dist/adapters/credentials/protected-input.js.map +1 -0
  10. package/dist/adapters/filesystem/executables.d.ts +2 -0
  11. package/dist/adapters/filesystem/executables.js +70 -0
  12. package/dist/adapters/filesystem/executables.js.map +1 -0
  13. package/dist/adapters/filesystem/update-previews.d.ts +9 -0
  14. package/dist/adapters/filesystem/update-previews.js +44 -0
  15. package/dist/adapters/filesystem/update-previews.js.map +1 -1
  16. package/dist/adapters/filesystem/workstation-attempts.d.ts +13 -0
  17. package/dist/adapters/filesystem/workstation-attempts.js +78 -0
  18. package/dist/adapters/filesystem/workstation-attempts.js.map +1 -0
  19. package/dist/adapters/github/activation-rest.d.ts +40 -0
  20. package/dist/adapters/github/activation-rest.js +272 -0
  21. package/dist/adapters/github/activation-rest.js.map +1 -0
  22. package/dist/adapters/state/azure-blob.d.ts +43 -0
  23. package/dist/adapters/state/azure-blob.js +335 -0
  24. package/dist/adapters/state/azure-blob.js.map +1 -0
  25. package/dist/adapters/state/darwin-capabilities.d.ts +33 -0
  26. package/dist/adapters/state/darwin-capabilities.js +146 -0
  27. package/dist/adapters/state/darwin-capabilities.js.map +1 -0
  28. package/dist/adapters/state/darwin-native-host.d.ts +32 -0
  29. package/dist/adapters/state/darwin-native-host.js +294 -0
  30. package/dist/adapters/state/darwin-native-host.js.map +1 -0
  31. package/dist/adapters/state/darwin-profile.d.ts +6 -0
  32. package/dist/adapters/state/darwin-profile.js +56 -0
  33. package/dist/adapters/state/darwin-profile.js.map +1 -0
  34. package/dist/adapters/state/darwin-system-program.d.ts +1 -0
  35. package/dist/adapters/state/darwin-system-program.js +94 -0
  36. package/dist/adapters/state/darwin-system-program.js.map +1 -0
  37. package/dist/adapters/state/local-qualification.d.ts +16 -0
  38. package/dist/adapters/state/local-qualification.js +299 -0
  39. package/dist/adapters/state/local-qualification.js.map +1 -0
  40. package/dist/adapters/state/local.d.ts +25 -0
  41. package/dist/adapters/state/local.js +145 -0
  42. package/dist/adapters/state/local.js.map +1 -0
  43. package/dist/adapters/state/native-command.d.ts +21 -0
  44. package/dist/adapters/state/native-command.js +82 -0
  45. package/dist/adapters/state/native-command.js.map +1 -0
  46. package/dist/adapters/state/native-files.d.ts +2 -0
  47. package/dist/adapters/state/native-files.js +47 -0
  48. package/dist/adapters/state/native-files.js.map +1 -0
  49. package/dist/adapters/state/native-system.d.ts +38 -0
  50. package/dist/adapters/state/native-system.js +86 -0
  51. package/dist/adapters/state/native-system.js.map +1 -0
  52. package/dist/adapters/state/opentofu.d.ts +35 -0
  53. package/dist/adapters/state/opentofu.js +350 -0
  54. package/dist/adapters/state/opentofu.js.map +1 -0
  55. package/dist/adapters/state/owned-process.d.ts +43 -0
  56. package/dist/adapters/state/owned-process.js +252 -0
  57. package/dist/adapters/state/owned-process.js.map +1 -0
  58. package/dist/adapters/state/posix-lock-program.d.ts +1 -0
  59. package/dist/adapters/state/posix-lock-program.js +185 -0
  60. package/dist/adapters/state/posix-lock-program.js.map +1 -0
  61. package/dist/adapters/state/posix-native-lock.d.ts +15 -0
  62. package/dist/adapters/state/posix-native-lock.js +145 -0
  63. package/dist/adapters/state/posix-native-lock.js.map +1 -0
  64. package/dist/adapters/state/protected-workspace.d.ts +57 -0
  65. package/dist/adapters/state/protected-workspace.js +412 -0
  66. package/dist/adapters/state/protected-workspace.js.map +1 -0
  67. package/dist/application/context.d.ts +3 -0
  68. package/dist/application/diagnose/doctor.d.ts +5 -0
  69. package/dist/application/diagnose/doctor.js +21 -5
  70. package/dist/application/diagnose/doctor.js.map +1 -1
  71. package/dist/application/diagnose/generated-project.js +2 -7
  72. package/dist/application/diagnose/generated-project.js.map +1 -1
  73. package/dist/application/initialize/fixture.js +8 -1
  74. package/dist/application/initialize/fixture.js.map +1 -1
  75. package/dist/application/initialize/use-case.js +70 -36
  76. package/dist/application/initialize/use-case.js.map +1 -1
  77. package/dist/application/project/manifest.js +5 -4
  78. package/dist/application/project/manifest.js.map +1 -1
  79. package/dist/application/state-migration/execution.d.ts +32 -0
  80. package/dist/application/state-migration/execution.js +440 -0
  81. package/dist/application/state-migration/execution.js.map +1 -0
  82. package/dist/application/state-migration/index.d.ts +22 -0
  83. package/dist/application/state-migration/index.js +17 -0
  84. package/dist/application/state-migration/index.js.map +1 -0
  85. package/dist/application/state-migration/lifecycle.d.ts +3 -0
  86. package/dist/application/state-migration/lifecycle.js +149 -0
  87. package/dist/application/state-migration/lifecycle.js.map +1 -0
  88. package/dist/application/state-migration/planning.d.ts +7 -0
  89. package/dist/application/state-migration/planning.js +150 -0
  90. package/dist/application/state-migration/planning.js.map +1 -0
  91. package/dist/application/state-migration/recovery.d.ts +5 -0
  92. package/dist/application/state-migration/recovery.js +145 -0
  93. package/dist/application/state-migration/recovery.js.map +1 -0
  94. package/dist/application/state-migration/runtime.d.ts +32 -0
  95. package/dist/application/state-migration/runtime.js +188 -0
  96. package/dist/application/state-migration/runtime.js.map +1 -0
  97. package/dist/application/state-migration/service.d.ts +2 -0
  98. package/dist/application/state-migration/service.js +20 -0
  99. package/dist/application/state-migration/service.js.map +1 -0
  100. package/dist/application/update/inspection.d.ts +16 -2
  101. package/dist/application/update/inspection.js +76 -23
  102. package/dist/application/update/inspection.js.map +1 -1
  103. package/dist/application/update/migration-runtime.js +24 -11
  104. package/dist/application/update/migration-runtime.js.map +1 -1
  105. package/dist/application/update/output.d.ts +2 -0
  106. package/dist/application/update/output.js +11 -1
  107. package/dist/application/update/output.js.map +1 -1
  108. package/dist/application/update/revalidation-plan.d.ts +1 -0
  109. package/dist/application/update/revalidation-plan.js +25 -12
  110. package/dist/application/update/revalidation-plan.js.map +1 -1
  111. package/dist/application/update/revalidation.d.ts +4 -1
  112. package/dist/application/update/revalidation.js +62 -21
  113. package/dist/application/update/revalidation.js.map +1 -1
  114. package/dist/application/update/use-case.js +25 -17
  115. package/dist/application/update/use-case.js.map +1 -1
  116. package/dist/cli/args/definitions.js +11 -3
  117. package/dist/cli/args/definitions.js.map +1 -1
  118. package/dist/cli/args/parser.js +29 -3
  119. package/dist/cli/args/parser.js.map +1 -1
  120. package/dist/domain/governance/activation/approvals.d.ts +264 -7
  121. package/dist/domain/governance/activation/approvals.js +166 -23
  122. package/dist/domain/governance/activation/approvals.js.map +1 -1
  123. package/dist/domain/governance/activation/capabilities.js +5 -2
  124. package/dist/domain/governance/activation/capabilities.js.map +1 -1
  125. package/dist/domain/governance/activation/evidence.d.ts +2 -1
  126. package/dist/domain/governance/activation/evidence.js +64 -11
  127. package/dist/domain/governance/activation/evidence.js.map +1 -1
  128. package/dist/domain/governance/activation/graph.d.ts +11 -384
  129. package/dist/domain/governance/activation/graph.js +424 -379
  130. package/dist/domain/governance/activation/graph.js.map +1 -1
  131. package/dist/domain/governance/activation/inputs.d.ts +3 -1
  132. package/dist/domain/governance/activation/inputs.js +47 -6
  133. package/dist/domain/governance/activation/inputs.js.map +1 -1
  134. package/dist/domain/governance/activation/operations.d.ts +4 -1
  135. package/dist/domain/governance/activation/operations.js +110 -22
  136. package/dist/domain/governance/activation/operations.js.map +1 -1
  137. package/dist/domain/governance/activation/readiness.d.ts +10 -0
  138. package/dist/domain/governance/activation/readiness.js +77 -38
  139. package/dist/domain/governance/activation/readiness.js.map +1 -1
  140. package/dist/domain/governance/activation/types.d.ts +151 -9
  141. package/dist/domain/governance/activation/types.js +23 -1
  142. package/dist/domain/governance/activation/types.js.map +1 -1
  143. package/dist/domain/governance/activation/validators.d.ts +4 -1
  144. package/dist/domain/governance/activation/validators.js +419 -26
  145. package/dist/domain/governance/activation/validators.js.map +1 -1
  146. package/dist/domain/governance/policy/identity.d.ts +55 -13
  147. package/dist/domain/governance/policy/identity.js +28 -8
  148. package/dist/domain/governance/policy/identity.js.map +1 -1
  149. package/dist/domain/project/artifact-lifecycle.d.ts +2 -1
  150. package/dist/domain/project/artifact-lifecycle.js +7 -1
  151. package/dist/domain/project/artifact-lifecycle.js.map +1 -1
  152. package/dist/domain/project/catalog.d.ts +50 -1
  153. package/dist/domain/project/catalog.js +104 -4
  154. package/dist/domain/project/catalog.js.map +1 -1
  155. package/dist/domain/project/contracts.d.ts +9 -1
  156. package/dist/domain/project/infrastructure-layout.d.ts +1 -1
  157. package/dist/domain/project/infrastructure-layout.js +2 -1
  158. package/dist/domain/project/infrastructure-layout.js.map +1 -1
  159. package/dist/domain/project/manifest/governance.d.ts +1 -1
  160. package/dist/domain/project/manifest/governance.js +9 -10
  161. package/dist/domain/project/manifest/governance.js.map +1 -1
  162. package/dist/domain/project/planning.js +4 -5
  163. package/dist/domain/project/planning.js.map +1 -1
  164. package/dist/domain/repair/stateful-bounded.d.ts +1 -0
  165. package/dist/domain/repair/stateful-bounded.js +37 -0
  166. package/dist/domain/repair/stateful-bounded.js.map +1 -0
  167. package/dist/domain/repair/stateful-invariants.d.ts +28 -0
  168. package/dist/domain/repair/stateful-invariants.js +278 -0
  169. package/dist/domain/repair/stateful-invariants.js.map +1 -0
  170. package/dist/domain/repair/stateful.d.ts +690 -0
  171. package/dist/domain/repair/stateful.js +26 -0
  172. package/dist/domain/repair/stateful.js.map +1 -0
  173. package/dist/domain/workstation/constraints.d.ts +1 -0
  174. package/dist/domain/workstation/constraints.js.map +1 -1
  175. package/dist/domain/workstation/contracts.d.ts +42 -0
  176. package/dist/domain/workstation/contracts.js +2 -0
  177. package/dist/domain/workstation/contracts.js.map +1 -0
  178. package/dist/domain/workstation/executables.d.ts +19 -0
  179. package/dist/domain/workstation/executables.js +68 -0
  180. package/dist/domain/workstation/executables.js.map +1 -0
  181. package/dist/domain/workstation/versions.d.ts +8 -0
  182. package/dist/domain/workstation/versions.js +145 -0
  183. package/dist/domain/workstation/versions.js.map +1 -0
  184. package/dist/framework-adapters.d.ts +2 -0
  185. package/dist/framework-adapters.js +148 -22
  186. package/dist/framework-adapters.js.map +1 -1
  187. package/dist/framework-validation.d.ts +6 -0
  188. package/dist/framework-validation.js +89 -24
  189. package/dist/framework-validation.js.map +1 -1
  190. package/dist/generators/common/base.js +57 -17
  191. package/dist/generators/common/base.js.map +1 -1
  192. package/dist/governance-activation/activation-state.js +39 -7
  193. package/dist/governance-activation/activation-state.js.map +1 -1
  194. package/dist/governance-activation/authority-records.d.ts +4 -0
  195. package/dist/governance-activation/authority-records.js +24 -0
  196. package/dist/governance-activation/authority-records.js.map +1 -0
  197. package/dist/governance-activation/commands.d.ts +9 -1
  198. package/dist/governance-activation/commands.js +392 -97
  199. package/dist/governance-activation/commands.js.map +1 -1
  200. package/dist/governance-activation/compatibility.d.ts +11 -8
  201. package/dist/governance-activation/compatibility.js +37 -23
  202. package/dist/governance-activation/compatibility.js.map +1 -1
  203. package/dist/governance-activation/doctor.js +40 -16
  204. package/dist/governance-activation/doctor.js.map +1 -1
  205. package/dist/governance-activation/github-config.d.ts +17 -0
  206. package/dist/governance-activation/github-config.js +88 -0
  207. package/dist/governance-activation/github-config.js.map +1 -0
  208. package/dist/governance-activation/github-discovery.d.ts +18 -0
  209. package/dist/governance-activation/github-discovery.js +229 -0
  210. package/dist/governance-activation/github-discovery.js.map +1 -0
  211. package/dist/governance-activation/github-ports.d.ts +12 -0
  212. package/dist/governance-activation/github-ports.js +4 -0
  213. package/dist/governance-activation/github-ports.js.map +1 -0
  214. package/dist/governance-activation/github-publication.d.ts +3 -0
  215. package/dist/governance-activation/github-publication.js +190 -0
  216. package/dist/governance-activation/github-publication.js.map +1 -0
  217. package/dist/governance-activation/historical-common.d.ts +98 -0
  218. package/dist/governance-activation/historical-common.js +269 -0
  219. package/dist/governance-activation/historical-common.js.map +1 -0
  220. package/dist/governance-activation/historical-credential-policy.d.ts +3 -0
  221. package/dist/governance-activation/historical-credential-policy.js +91 -0
  222. package/dist/governance-activation/historical-credential-policy.js.map +1 -0
  223. package/dist/governance-activation/historical-inputs.d.ts +6 -0
  224. package/dist/governance-activation/historical-inputs.js +57 -0
  225. package/dist/governance-activation/historical-inputs.js.map +1 -0
  226. package/dist/governance-activation/historical-safety.d.ts +9 -0
  227. package/dist/governance-activation/historical-safety.js +102 -0
  228. package/dist/governance-activation/historical-safety.js.map +1 -0
  229. package/dist/governance-activation/historical-source-metadata.d.ts +31 -0
  230. package/dist/governance-activation/historical-source-metadata.js +55 -0
  231. package/dist/governance-activation/historical-source-metadata.js.map +1 -0
  232. package/dist/governance-activation/historical-state.d.ts +12 -50
  233. package/dist/governance-activation/historical-state.js +195 -308
  234. package/dist/governance-activation/historical-state.js.map +1 -1
  235. package/dist/governance-activation/historical-v1-auxiliary.d.ts +1 -0
  236. package/dist/governance-activation/historical-v1-auxiliary.js +43 -0
  237. package/dist/governance-activation/historical-v1-auxiliary.js.map +1 -0
  238. package/dist/governance-activation/historical-v1-phase-contracts.d.ts +31 -0
  239. package/dist/governance-activation/historical-v1-phase-contracts.js +46 -0
  240. package/dist/governance-activation/historical-v1-phase-contracts.js.map +1 -0
  241. package/dist/governance-activation/historical-v2.d.ts +53 -0
  242. package/dist/governance-activation/historical-v2.js +313 -0
  243. package/dist/governance-activation/historical-v2.js.map +1 -0
  244. package/dist/governance-activation/history-contracts.d.ts +21 -12
  245. package/dist/governance-activation/history-contracts.js +99 -27
  246. package/dist/governance-activation/history-contracts.js.map +1 -1
  247. package/dist/governance-activation/inputs.d.ts +8 -2
  248. package/dist/governance-activation/inputs.js +41 -6
  249. package/dist/governance-activation/inputs.js.map +1 -1
  250. package/dist/governance-activation/migration-history.d.ts +43 -5
  251. package/dist/governance-activation/migration-history.js +231 -50
  252. package/dist/governance-activation/migration-history.js.map +1 -1
  253. package/dist/governance-activation/migration.d.ts +7 -4
  254. package/dist/governance-activation/migration.js +53 -252
  255. package/dist/governance-activation/migration.js.map +1 -1
  256. package/dist/governance-activation/phase-azure.d.ts +3 -0
  257. package/dist/governance-activation/phase-azure.js +205 -0
  258. package/dist/governance-activation/phase-azure.js.map +1 -0
  259. package/dist/governance-activation/phase-bootstrap-state.js +3 -0
  260. package/dist/governance-activation/phase-bootstrap-state.js.map +1 -1
  261. package/dist/governance-activation/phase-github.d.ts +3 -0
  262. package/dist/governance-activation/phase-github.js +192 -0
  263. package/dist/governance-activation/phase-github.js.map +1 -0
  264. package/dist/governance-activation/phase-governance.js +8 -2
  265. package/dist/governance-activation/phase-governance.js.map +1 -1
  266. package/dist/governance-activation/public-plans.d.ts +36 -0
  267. package/dist/governance-activation/public-plans.js +100 -0
  268. package/dist/governance-activation/public-plans.js.map +1 -0
  269. package/dist/governance-activation/read-only.d.ts +3 -1
  270. package/dist/governance-activation/read-only.js +7 -3
  271. package/dist/governance-activation/read-only.js.map +1 -1
  272. package/dist/governance-activation/reconciliation.js +10 -0
  273. package/dist/governance-activation/reconciliation.js.map +1 -1
  274. package/dist/governance-activation/seed-lifecycle.js +14 -25
  275. package/dist/governance-activation/seed-lifecycle.js.map +1 -1
  276. package/dist/governance-activation/source-of-truth.d.ts +21 -5
  277. package/dist/governance-activation/source-of-truth.js +102 -13
  278. package/dist/governance-activation/source-of-truth.js.map +1 -1
  279. package/dist/governance-activation/task-projection.d.ts +4 -1
  280. package/dist/governance-activation/task-projection.js +32 -3
  281. package/dist/governance-activation/task-projection.js.map +1 -1
  282. package/dist/governance-activation/task-writes.d.ts +42 -0
  283. package/dist/governance-activation/task-writes.js +250 -0
  284. package/dist/governance-activation/task-writes.js.map +1 -0
  285. package/dist/governance-activation/transition-files.d.ts +12 -0
  286. package/dist/governance-activation/transition-files.js +109 -0
  287. package/dist/governance-activation/transition-files.js.map +1 -0
  288. package/dist/governance-activation/transition-planning.d.ts +3 -1
  289. package/dist/governance-activation/transition-planning.js +158 -20
  290. package/dist/governance-activation/transition-planning.js.map +1 -1
  291. package/dist/governance-activation/transition-ports.d.ts +31 -3
  292. package/dist/governance-activation/transition-records.d.ts +11 -1
  293. package/dist/governance-activation/transition-records.js +52 -6
  294. package/dist/governance-activation/transition-records.js.map +1 -1
  295. package/dist/governance-activation/transitions.d.ts +5 -0
  296. package/dist/governance-activation/transitions.js +271 -37
  297. package/dist/governance-activation/transitions.js.map +1 -1
  298. package/dist/governance-assessment/engine.js +22 -15
  299. package/dist/governance-assessment/engine.js.map +1 -1
  300. package/dist/governance-assessment/project.d.ts +2 -0
  301. package/dist/governance-assessment/project.js +2 -1
  302. package/dist/governance-assessment/project.js.map +1 -1
  303. package/dist/interactive.d.ts +0 -1
  304. package/dist/interactive.js +3 -22
  305. package/dist/interactive.js.map +1 -1
  306. package/dist/openspec-profile.d.ts +2 -1
  307. package/dist/openspec-profile.js +11 -41
  308. package/dist/openspec-profile.js.map +1 -1
  309. package/dist/repository-governance.d.ts +10 -5
  310. package/dist/repository-governance.js +178 -92
  311. package/dist/repository-governance.js.map +1 -1
  312. package/dist/telemetry/contract.d.ts +1 -1
  313. package/dist/telemetry/contract.js +3 -0
  314. package/dist/telemetry/contract.js.map +1 -1
  315. package/dist/workstation-catalog.d.ts +13 -1
  316. package/dist/workstation-catalog.js +122 -0
  317. package/dist/workstation-catalog.js.map +1 -1
  318. package/dist/workstation.d.ts +69 -14
  319. package/dist/workstation.js +600 -215
  320. package/dist/workstation.js.map +1 -1
  321. package/docs/cli-reference.md +59 -21
  322. package/docs/configuration-and-manifests.md +9 -8
  323. package/docs/prerequisites.md +93 -18
  324. package/docs/repository-governance.md +68 -40
  325. package/docs/spec-workflows-and-agents.md +132 -13
  326. package/package.json +1 -1
@@ -0,0 +1,4 @@
1
+ export function githubPorts(input) {
2
+ return input.adapters?.githubActivation ?? {};
3
+ }
4
+ //# sourceMappingURL=github-ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-ports.js","sourceRoot":"","sources":["../../src/governance-activation/github-ports.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,WAAW,CAAC,KAAsD;IAChF,OAAQ,KAEN,CAAC,QAAQ,EAAE,gBAAgB,IAAI,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PhaseAdapterExecutionInput, PhaseAdapterOutcome, PhasePlanBuild, PhasePlanningInput } from './transition-ports.js';
2
+ export declare function planGitHubPublication(input: PhasePlanningInput): Promise<PhasePlanBuild>;
3
+ export declare function executeGitHubPublication(input: PhaseAdapterExecutionInput): Promise<PhaseAdapterOutcome>;
@@ -0,0 +1,190 @@
1
+ import { inspectGitRepository, reviewedPushUrl } from './phase-publication.js';
2
+ import { commandSucceeded, runGit } from './transition-process.js';
3
+ import { cloneState, readbackProof } from './transition-records.js';
4
+ import { GitHubActivationError, githubRepository, object, positiveId } from '../adapters/github/activation-rest.js';
5
+ import { assertGitHubAuthorized, clientFor, githubOperation, repositoryConfiguration, sourceSha } from './github-config.js';
6
+ export async function planGitHubPublication(input) {
7
+ const config = repositoryConfiguration(input.inspection);
8
+ const client = clientFor(input);
9
+ const git = await inspectGitRepository(input.inspection.projectRoot, input.runner);
10
+ if (git.issues.length || !git.insideWorkTree || !git.head || git.branch !== config.defaultBranch || git.status.length) {
11
+ throw new GitHubActivationError('publication-prerequisite', 'Publication requires a clean reviewed local commit on develop at this exact project root; no reset, rebase, or arbitrary staging is permitted.');
12
+ }
13
+ const pushUrl = `https://github.com/${config.name}.git`;
14
+ if (git.remotes.length) {
15
+ const reviewed = reviewedPushUrl(git);
16
+ const accepted = [pushUrl, `git@github.com:${config.name}.git`, `ssh://git@github.com/${config.name}.git`];
17
+ if (!accepted.includes(reviewed))
18
+ throw new GitHubActivationError('remote-drift', 'The existing origin differs from the explicitly approved github.com destination. It will not be replaced.');
19
+ }
20
+ const repository = await client.optional(`/repos/${config.name}`);
21
+ if (!repository && !config.create) {
22
+ throw new GitHubActivationError('repository-prerequisite', 'The approved repository is absent or unreadable. Grant access, or explicitly approve repository.create for this exact destination.');
23
+ }
24
+ const [owner, name] = config.name.split('/');
25
+ let ownerKind = 'organization';
26
+ if (!repository) {
27
+ const ownerInfo = await client.get(`/users/${owner}`);
28
+ if (ownerInfo.type === 'User') {
29
+ const actor = await client.get('/user');
30
+ if (actor.login !== owner)
31
+ throw new GitHubActivationError('owner-prerequisite', 'A personal repository can only be created for the authenticated approved owner.');
32
+ ownerKind = 'user';
33
+ }
34
+ else if (ownerInfo.type === 'Organization') {
35
+ const membership = await client.get(`/user/memberships/orgs/${owner}`);
36
+ if (membership.state !== 'active')
37
+ throw new GitHubActivationError('owner-prerequisite', 'An active approved organization identity with repository-create permission is required.');
38
+ }
39
+ else
40
+ throw new GitHubActivationError('owner-prerequisite', 'The approved repository owner is not a supported user or organization.');
41
+ }
42
+ else {
43
+ assertRepositoryBinding(repository, config.name, config.visibility);
44
+ if (repository.default_branch !== config.defaultBranch) {
45
+ throw new GitHubActivationError('default-branch-prerequisite', 'An existing repository default branch must be reconciled to develop through a separately reviewed operation; publication will not silently change it.');
46
+ }
47
+ }
48
+ const remote = repository ? await client.optional(`/repos/${config.name}/git/ref/heads/${config.defaultBranch}`) : null;
49
+ const remoteHead = remote ? sourceSha(object(remote.object).sha) : null;
50
+ if (remoteHead && remoteHead !== git.head) {
51
+ const ancestor = await runGit(input.runner, input.inspection.projectRoot, ['merge-base', '--is-ancestor', remoteHead, git.head]);
52
+ if (!commandSucceeded(ancestor)) {
53
+ throw new GitHubActivationError('non-fast-forward', 'The remote branch is not a verified ancestor of the reviewed local commit. Fetch/reconcile under owner control; force-push is forbidden.');
54
+ }
55
+ }
56
+ const operations = [
57
+ githubOperation(input, 'github.repository.ensure', repository ? 'github-read' : 'github-repository-create', {
58
+ repository: config.name, name, owner, ownerKind, visibility: config.visibility, create: !repository,
59
+ repositoryId: repository ? positiveId(repository.id) : null, defaultBranch: config.defaultBranch
60
+ }),
61
+ ...(!git.remotes.length ? [{
62
+ adapter: 'git', actionId: 'git.remote.bind', mutationClass: 'git-remote-bind', phaseId: input.phase.id,
63
+ inputs: { name: 'origin', pushUrl }, destination: { type: 'local', identity: '.git/config' },
64
+ remote: false, destructive: false
65
+ }] : []),
66
+ {
67
+ adapter: 'git', actionId: remoteHead === git.head ? 'git.verify-existing-push' : 'git.push-approved-ref',
68
+ mutationClass: remoteHead === git.head ? 'github-read' : 'git-push', phaseId: input.phase.id,
69
+ inputs: {
70
+ repository: config.name, branch: config.defaultBranch, localHead: git.head, remoteHead,
71
+ pushUrl: git.remotes.length ? reviewedPushUrl(git) : pushUrl
72
+ },
73
+ destination: { type: 'repository', identity: pushUrl, repository: config.name, ref: `refs/heads/${config.defaultBranch}` },
74
+ remote: true, destructive: false
75
+ }
76
+ ];
77
+ if (!repository)
78
+ operations.push(githubOperation(input, 'github.repository.default-branch', 'github-write', {
79
+ repository: config.name, defaultBranch: config.defaultBranch
80
+ }));
81
+ return { operations };
82
+ }
83
+ function assertRepositoryBinding(repository, expected, visibility) {
84
+ if (githubRepository(repository.full_name).toLowerCase() !== expected.toLowerCase() ||
85
+ repository.private !== (visibility === 'private') || repository.archived !== false ||
86
+ repository.disabled === true || repository.fork === true) {
87
+ throw new GitHubActivationError('repository-binding', 'Repository identity, visibility, or ownership differs from the reviewed non-archived, non-fork destination.');
88
+ }
89
+ positiveId(repository.id);
90
+ }
91
+ export async function executeGitHubPublication(input) {
92
+ const config = repositoryConfiguration(input.inspection);
93
+ const client = clientFor(input);
94
+ const completed = [];
95
+ try {
96
+ const ensure = input.plan.operations.find((entry) => entry.actionId === 'github.repository.ensure');
97
+ if (!ensure)
98
+ throw new GitHubActivationError('publication-inventory', 'The reviewed repository binding operation is missing.');
99
+ await assertGitHubAuthorized(input, ensure);
100
+ let repository = await client.optional(`/repos/${config.name}`);
101
+ if (!repository) {
102
+ if (ensure.inputs.create !== true)
103
+ throw new GitHubActivationError('repository-missing', 'The reviewed existing repository is no longer visible; refusing to create a replacement.');
104
+ repository = await client.write('POST', ensure.inputs.ownerKind === 'user' ? '/user/repos' : `/orgs/${config.name.split('/')[0]}/repos`, {
105
+ name: config.name.split('/')[1], private: config.visibility === 'private', auto_init: false, has_issues: true, has_projects: false
106
+ });
107
+ completed.push(ensure);
108
+ }
109
+ if (!repository)
110
+ throw new GitHubActivationError('repository-readback', 'Repository creation returned no provider identity.');
111
+ assertRepositoryBinding(repository, config.name, config.visibility);
112
+ if (ensure.inputs.repositoryId !== null && repository.id !== ensure.inputs.repositoryId) {
113
+ throw new GitHubActivationError('repository-drift', 'The repository ID changed after review.');
114
+ }
115
+ if (!completed.includes(ensure))
116
+ completed.push(ensure);
117
+ for (const op of input.plan.operations.filter((entry) => entry.adapter === 'git')) {
118
+ await assertGitHubAuthorized(input, op);
119
+ const git = await inspectGitRepository(input.inspection.projectRoot, input.runner);
120
+ if (git.issues.length || git.status.length || git.branch !== config.defaultBranch) {
121
+ throw new GitHubActivationError('publication-drift', 'Local Git inputs changed after publication review.');
122
+ }
123
+ if (op.actionId === 'git.remote.bind') {
124
+ if (!git.remotes.length) {
125
+ const result = await runGit(input.runner, input.inspection.projectRoot, ['remote', 'add', 'origin', String(op.inputs.pushUrl)]);
126
+ if (!commandSucceeded(result))
127
+ throw new GitHubActivationError('remote-bind', 'Git could not bind the approved origin; no existing remote was replaced.');
128
+ }
129
+ else if (reviewedPushUrl(git) !== op.inputs.pushUrl)
130
+ throw new GitHubActivationError('remote-drift', 'Origin changed before approved binding.');
131
+ completed.push(op);
132
+ }
133
+ else if (op.actionId === 'git.push-approved-ref' || op.actionId === 'git.verify-existing-push') {
134
+ if (git.head !== op.inputs.localHead || reviewedPushUrl(git) !== op.inputs.pushUrl) {
135
+ throw new GitHubActivationError('publication-drift', 'Git HEAD or push URL changed after review.');
136
+ }
137
+ const remote = await client.optional(`/repos/${config.name}/git/ref/heads/${config.defaultBranch}`);
138
+ const sha = remote ? sourceSha(object(remote.object).sha) : null;
139
+ if (sha !== op.inputs.localHead) {
140
+ if (op.actionId !== 'git.push-approved-ref' || sha !== op.inputs.remoteHead) {
141
+ throw new GitHubActivationError('remote-drift', 'Remote branch changed concurrently; no force/update was attempted.');
142
+ }
143
+ const result = await runGit(input.runner, input.inspection.projectRoot, [
144
+ 'push', String(op.inputs.pushUrl), `${sourceSha(op.inputs.localHead)}:refs/heads/${config.defaultBranch}`
145
+ ]);
146
+ if (!commandSucceeded(result))
147
+ throw new GitHubActivationError('publication-rejected', 'GitHub rejected publication; inspect protected-branch policy and the exact ref. No bypass was attempted.');
148
+ }
149
+ completed.push(op);
150
+ }
151
+ }
152
+ const defaultOp = input.plan.operations.find((entry) => entry.actionId === 'github.repository.default-branch');
153
+ if (defaultOp) {
154
+ const live = await client.get(`/repos/${config.name}`);
155
+ if (live.default_branch !== config.defaultBranch) {
156
+ await assertGitHubAuthorized(input, defaultOp);
157
+ await client.write('PATCH', `/repos/${config.name}`, { default_branch: config.defaultBranch });
158
+ }
159
+ completed.push(defaultOp);
160
+ }
161
+ const current = await client.get(`/repos/${config.name}`);
162
+ assertRepositoryBinding(current, config.name, config.visibility);
163
+ const ref = await client.get(`/repos/${config.name}/git/ref/heads/${config.defaultBranch}`);
164
+ const head = sourceSha(object(ref.object).sha);
165
+ const git = await inspectGitRepository(input.inspection.projectRoot, input.runner);
166
+ if (head !== git.head || current.id !== repository.id || current.default_branch !== config.defaultBranch) {
167
+ throw new GitHubActivationError('publication-readback', 'Independent repository/ref readback differs from the reviewed local publication.');
168
+ }
169
+ const state = cloneState(input.inspection.state);
170
+ state.remoteBinding = {
171
+ id: String(current.id), name: config.name, defaultBranch: config.defaultBranch,
172
+ pushUrl: reviewedPushUrl(git), verifiedAt: input.now.toISOString()
173
+ };
174
+ const resourceId = `/repos/${config.name}`;
175
+ return {
176
+ status: 'completed', resultState: 'verified', stateOverride: state, completedOperations: completed,
177
+ evidencePayload: { kind: 'pushed.v1', head, pushUrl: reviewedPushUrl(git), repositoryId: current.id },
178
+ outputs: { values: { sourceSha: head, repositoryId: positiveId(current.id), repository: config.name },
179
+ resources: [{ provider: 'github', resourceType: 'repository', resourceId }] },
180
+ liveReadback: [readbackProof(input, 'github', 'repository', resourceId, {
181
+ id: current.id, name: config.name, head, defaultBranch: config.defaultBranch, visibility: config.visibility
182
+ })]
183
+ };
184
+ }
185
+ catch (error) {
186
+ return { status: 'blocked', completedOperations: completed,
187
+ blocker: error instanceof GitHubActivationError ? error.message : 'Publication could not be verified; raw Git/provider diagnostics were withheld.' };
188
+ }
189
+ }
190
+ //# sourceMappingURL=github-publication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-publication.js","sourceRoot":"","sources":["../../src/governance-activation/github-publication.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import type { ApprovalEnvelope, ApprovalEvaluation, BootstrapStateRetention, EvidenceHeader, EvidenceReference, LiveReadbackProof, PhaseExecutionState, SavedTransitionPlan, TransitionOperation, TransitionOperationDestination, TransitionRollbackPlan } from '../domain/governance/activation/types.js';
2
+ import type { HistoricalActivationIdentity } from '../domain/governance/policy/identity.js';
3
+ import { historicalIdentity } from './history-contracts.js';
4
+ import { historicalPhaseIds, type HistoricalPhaseId } from './historical-v1-phase-contracts.js';
5
+ export { historicalPhaseIds, type HistoricalPhaseId };
6
+ export declare const historicalPhaseStates: readonly ['pending', 'blocked', 'ready', 'approved', 'running', 'verified', 'failed', 'inapplicable', 'retained', 'disposed'];
7
+ export declare const historicalResults: readonly ['verified', 'failed', 'inapplicable', 'retained', 'disposed'];
8
+ export declare const historicalMutationClasses: readonly ['none', 'read-worktree', 'write-activation-state', 'write-evidence', 'write-openspec-seed', 'write-openspec-governance', 'write-local-state', 'delete-local-state', 'write-workflows', 'write-ruleset-source', 'git-commit', 'git-push', 'github-read', 'github-write', 'github-secret-write', 'azure-read', 'azure-provider-register', 'azure-network-provision', 'azure-state-import', 'azure-resource-provision', 'github-ruleset-write'];
9
+ export declare const historicalGateKinds: readonly ['none', 'repository-publish', 'activation-plan', 'credential-enrollment', 'infrastructure-cost', 'enforcement', 'destructive-disposal', 'external-blocker'];
10
+ export declare const historicalQuestionKinds: readonly ['repository-creation-initial-commit-push', 'credential-enrollment', 'billed-infrastructure-policy-exception-cost-ceiling', 'final-enforcement', 'destructive-operation', 'external-blocker'];
11
+ export declare const destinationTypes: readonly ['local', 'repository', 'subscription', 'environment', 'tenant', 'external'];
12
+ export declare const adapterIds: readonly ['local-evidence', 'selected-spec-workflow', 'git', 'github', 'azure-opentofu', 'local-state'];
13
+ export declare const historicalPhaseGates: {
14
+ readonly 'seed-valid': 'none';
15
+ readonly 'seed-verified': 'none';
16
+ readonly 'seed-archived': 'none';
17
+ readonly committed: 'repository-publish';
18
+ readonly pushed: 'repository-publish';
19
+ readonly 'phase-0-complete': 'none';
20
+ readonly 'activation-approved': 'activation-plan';
21
+ readonly 'credential-ready': 'credential-enrollment';
22
+ readonly 'provider-ready': 'infrastructure-cost';
23
+ readonly 'state-path-selected': 'infrastructure-cost';
24
+ readonly 'existing-private-path': 'none';
25
+ readonly 'bootstrap-local': 'infrastructure-cost';
26
+ readonly 'runner-ready': 'infrastructure-cost';
27
+ readonly 'private-backend-proof': 'none';
28
+ readonly 'remote-import-verified': 'infrastructure-cost';
29
+ readonly 'remote-ready': 'none';
30
+ readonly 'application-foundation': 'infrastructure-cost';
31
+ readonly 'workflow-source-ready': 'none';
32
+ readonly 'dev-proof': 'none';
33
+ readonly 'staging-qualified': 'none';
34
+ readonly 'production-rehearsed': 'none';
35
+ readonly 'green-red-proof': 'none';
36
+ readonly 'enforcement-approved': 'enforcement';
37
+ readonly 'rulesets-applied': 'enforcement';
38
+ readonly 'live-readback': 'none';
39
+ readonly 'bootstrap-state-disposed': 'destructive-disposal';
40
+ };
41
+ export interface HistoricalActivationState {
42
+ schemaVersion: 1;
43
+ identity: HistoricalActivationIdentity;
44
+ repository: {
45
+ id: string;
46
+ name: string;
47
+ defaultBranch: string;
48
+ };
49
+ activeChange: {
50
+ id: string;
51
+ kind: 'openspec' | 'spec-kit';
52
+ } | null;
53
+ applicability: {
54
+ statePath: 'existing-private' | 'bootstrap-local' | 'none';
55
+ privateStagingDast: boolean;
56
+ credentialRequired: boolean;
57
+ };
58
+ bootstrapState?: BootstrapStateRetention;
59
+ phases: Record<HistoricalPhaseId, PhaseExecutionState>;
60
+ createdAt: string;
61
+ updatedAt: string;
62
+ }
63
+ export type HistoricalEvidenceHeader = Pick<EvidenceHeader, 'repositoryId' | 'phaseGraphHash' | 'phaseId' | 'phaseContractDigest' | 'inputDigest' | 'baselineSha' | 'transition' | 'producedAt' | 'producer' | 'result'> & {
64
+ schemaVersion: 1;
65
+ identity: HistoricalActivationIdentity;
66
+ };
67
+ export type HistoricalLiveReadbackProof = Omit<LiveReadbackProof, 'schemaVersion' | 'identity'> & {
68
+ schemaVersion: 1;
69
+ identity: HistoricalActivationIdentity;
70
+ };
71
+ export interface HistoricalEvidenceRecord {
72
+ evidenceId: string;
73
+ header: HistoricalEvidenceHeader;
74
+ payload?: unknown;
75
+ liveReadback?: HistoricalLiveReadbackProof[];
76
+ }
77
+ export type HistoricalApprovalEnvelope = Pick<ApprovalEnvelope, 'id' | 'phaseId' | 'gateKind' | 'baselineSha' | 'planDigest' | 'resources' | 'destinations' | 'permissions' | 'costCeiling' | 'policyExceptions' | 'destructiveScope' | 'expiresAt' | 'approvedAt' | 'approver'> & {
78
+ schemaVersion: 1;
79
+ identity: HistoricalActivationIdentity;
80
+ };
81
+ export type HistoricalSavedTransitionPlan = Pick<SavedTransitionPlan, 'phaseId' | 'createdAt' | 'expiresAt' | 'graphHash' | 'stateHash' | 'baselineDigest' | 'inputDigest' | 'transitionDigest' | 'planDigest' | 'mutationClasses' | 'operations' | 'approval' | 'rollbackPlan' | 'noSecrets'> & {
82
+ schemaVersion: 1;
83
+ identity: HistoricalActivationIdentity;
84
+ };
85
+ export declare function phaseId(value: unknown, label: string): HistoricalPhaseId;
86
+ export declare function assertHistoricalPhasesComplete<T>(phases: Partial<Record<HistoricalPhaseId, T>>): asserts phases is Record<HistoricalPhaseId, T>;
87
+ export declare function readHistoricalEvidenceReference(value: unknown, label: string): EvidenceReference;
88
+ export declare function validateHistoricalBootstrapState(value: unknown, label: string): BootstrapStateRetention;
89
+ export declare function readHistoricalEvidenceTransition(value: unknown, label: string): EvidenceHeader['transition'];
90
+ export declare function validateHistoricalEmbeddedPaths(value: unknown, label: string): void;
91
+ export declare function uniqueSorted<T>(values: T[], key: (value: T) => string, label: string): T[];
92
+ export declare function nullableString(value: unknown, label: string): string | null;
93
+ export declare function readHistoricalApprovalFields(value: unknown): Omit<HistoricalApprovalEnvelope, 'schemaVersion' | 'identity'>;
94
+ export declare function operationDestination(value: unknown, label: string): TransitionOperationDestination;
95
+ export declare function operation(value: unknown, label: string, mutationClasses?: readonly TransitionOperation['mutationClass'][]): TransitionOperation;
96
+ export declare function evaluation(value: unknown, label: string): ApprovalEvaluation;
97
+ export declare function rollbackPlan(value: unknown, label: string, mutationClasses?: readonly TransitionOperation['mutationClass'][]): TransitionRollbackPlan;
98
+ export declare function readHistoricalSavedTransitionPlan(value: unknown, identityReader: typeof historicalIdentity): HistoricalSavedTransitionPlan;
@@ -0,0 +1,269 @@
1
+ import { isRecord } from '../domain/governance/activation/canonical-json.js';
2
+ import { historyArray, historyBoolean, historyDigest, historyEnum, historyExact, historyFail, historyLiteral, historyPathParts, historyRecord, historyRecordId, historyString, historyStrings, historyTimestamp } from './history-contracts.js';
3
+ import { assertSafeHistoricalRecord } from './historical-safety.js';
4
+ import { historicalPhaseIds } from './historical-v1-phase-contracts.js';
5
+ export { historicalPhaseIds };
6
+ export const historicalPhaseStates = [
7
+ 'pending', 'blocked', 'ready', 'approved', 'running', 'verified', 'failed', 'inapplicable', 'retained', 'disposed'
8
+ ];
9
+ export const historicalResults = ['verified', 'failed', 'inapplicable', 'retained', 'disposed'];
10
+ export const historicalMutationClasses = [
11
+ 'none', 'read-worktree', 'write-activation-state', 'write-evidence', 'write-openspec-seed',
12
+ 'write-openspec-governance', 'write-local-state', 'delete-local-state', 'write-workflows',
13
+ 'write-ruleset-source', 'git-commit', 'git-push', 'github-read', 'github-write',
14
+ 'github-secret-write', 'azure-read', 'azure-provider-register', 'azure-network-provision',
15
+ 'azure-state-import', 'azure-resource-provision', 'github-ruleset-write'
16
+ ];
17
+ export const historicalGateKinds = [
18
+ 'none', 'repository-publish', 'activation-plan', 'credential-enrollment', 'infrastructure-cost',
19
+ 'enforcement', 'destructive-disposal', 'external-blocker'
20
+ ];
21
+ export const historicalQuestionKinds = [
22
+ 'repository-creation-initial-commit-push', 'credential-enrollment',
23
+ 'billed-infrastructure-policy-exception-cost-ceiling', 'final-enforcement',
24
+ 'destructive-operation', 'external-blocker'
25
+ ];
26
+ export const destinationTypes = ['local', 'repository', 'subscription', 'environment', 'tenant', 'external'];
27
+ export const adapterIds = ['local-evidence', 'selected-spec-workflow', 'git', 'github', 'azure-opentofu', 'local-state'];
28
+ export const historicalPhaseGates = {
29
+ 'seed-valid': 'none', 'seed-verified': 'none', 'seed-archived': 'none',
30
+ committed: 'repository-publish', pushed: 'repository-publish', 'phase-0-complete': 'none',
31
+ 'activation-approved': 'activation-plan', 'credential-ready': 'credential-enrollment',
32
+ 'provider-ready': 'infrastructure-cost', 'state-path-selected': 'infrastructure-cost',
33
+ 'existing-private-path': 'none', 'bootstrap-local': 'infrastructure-cost',
34
+ 'runner-ready': 'infrastructure-cost', 'private-backend-proof': 'none',
35
+ 'remote-import-verified': 'infrastructure-cost', 'remote-ready': 'none',
36
+ 'application-foundation': 'infrastructure-cost', 'workflow-source-ready': 'none',
37
+ 'dev-proof': 'none', 'staging-qualified': 'none', 'production-rehearsed': 'none',
38
+ 'green-red-proof': 'none', 'enforcement-approved': 'enforcement', 'rulesets-applied': 'enforcement',
39
+ 'live-readback': 'none', 'bootstrap-state-disposed': 'destructive-disposal'
40
+ };
41
+ export function phaseId(value, label) {
42
+ return historyEnum(value, historicalPhaseIds, label);
43
+ }
44
+ export function assertHistoricalPhasesComplete(phases) {
45
+ for (const id of historicalPhaseIds) {
46
+ if (phases[id] === undefined)
47
+ historyFail(`phases.${id}`, 'is required.');
48
+ }
49
+ }
50
+ export function readHistoricalEvidenceReference(value, label) {
51
+ const item = historyExact(value, ['phaseId', 'evidenceId', 'headerDigest', 'result'], label);
52
+ return {
53
+ phaseId: phaseId(item.phaseId, `${label}.phaseId`),
54
+ evidenceId: historyRecordId(item.evidenceId, `${label}.evidenceId`),
55
+ headerDigest: historyDigest(item.headerDigest, `${label}.headerDigest`),
56
+ result: historyEnum(item.result, historicalResults, `${label}.result`)
57
+ };
58
+ }
59
+ export function validateHistoricalBootstrapState(value, label) {
60
+ const item = historyExact(value, [
61
+ 'status', 'remoteImportEvidenceId', 'remoteImportEvidenceDigest', 'retainedAt', 'disposeAfter',
62
+ 'encryptedStatePathParts', 'encryptionKeyPathParts'
63
+ ], label, ['disposedAt', 'deletionEvidenceId', 'incompleteCleanup']);
64
+ const status = historyEnum(item.status, ['retained', 'disposed'], `${label}.status`);
65
+ const retainedAt = historyTimestamp(item.retainedAt, `${label}.retainedAt`);
66
+ const disposeAfter = historyTimestamp(item.disposeAfter, `${label}.disposeAfter`);
67
+ if (Date.parse(disposeAfter) - Date.parse(retainedAt) !== 30 * 24 * 60 * 60 * 1000) {
68
+ historyFail(label, 'disposeAfter must be exactly 30 days after retainedAt.');
69
+ }
70
+ if (status === 'disposed' && !Object.hasOwn(item, 'disposedAt'))
71
+ historyFail(label, 'disposedAt is required for disposed state.');
72
+ return {
73
+ status,
74
+ remoteImportEvidenceId: historyRecordId(item.remoteImportEvidenceId, `${label}.remoteImportEvidenceId`),
75
+ remoteImportEvidenceDigest: historyDigest(item.remoteImportEvidenceDigest, `${label}.remoteImportEvidenceDigest`),
76
+ retainedAt, disposeAfter,
77
+ encryptedStatePathParts: historyArray(item.encryptedStatePathParts, `${label}.encryptedStatePathParts`)
78
+ .map((entry) => historyPathParts(entry, `${label}.encryptedStatePathParts`)),
79
+ encryptionKeyPathParts: historyArray(item.encryptionKeyPathParts, `${label}.encryptionKeyPathParts`)
80
+ .map((entry) => historyPathParts(entry, `${label}.encryptionKeyPathParts`)),
81
+ ...(Object.hasOwn(item, 'disposedAt') ? { disposedAt: historyTimestamp(item.disposedAt, `${label}.disposedAt`) } : {}),
82
+ ...(Object.hasOwn(item, 'deletionEvidenceId') ? { deletionEvidenceId: historyRecordId(item.deletionEvidenceId, `${label}.deletionEvidenceId`) } : {}),
83
+ ...(Object.hasOwn(item, 'incompleteCleanup') ? { incompleteCleanup: historyStrings(item.incompleteCleanup, `${label}.incompleteCleanup`) } : {})
84
+ };
85
+ }
86
+ export function readHistoricalEvidenceTransition(value, label) {
87
+ const item = historyExact(value, ['phaseId', 'baselineSha', 'inputDigest', 'transitionDigest'], label);
88
+ return {
89
+ phaseId: phaseId(item.phaseId, `${label}.phaseId`),
90
+ baselineSha: historyDigest(item.baselineSha, `${label}.baselineSha`),
91
+ inputDigest: historyDigest(item.inputDigest, `${label}.inputDigest`),
92
+ transitionDigest: historyDigest(item.transitionDigest, `${label}.transitionDigest`)
93
+ };
94
+ }
95
+ export function validateHistoricalEmbeddedPaths(value, label) {
96
+ if (Array.isArray(value)) {
97
+ value.forEach((entry, index) => validateHistoricalEmbeddedPaths(entry, `${label}[${index}]`));
98
+ }
99
+ else if (isRecord(value)) {
100
+ for (const [key, entry] of Object.entries(value)) {
101
+ if (key === 'pathParts' || key.endsWith('PathParts')) {
102
+ const parts = historyArray(entry, `${label}.${key}`);
103
+ if (parts.length === 0 && ['cwdPathParts', 'encryptedStatePathParts', 'encryptionKeyPathParts', 'deletedPathParts'].includes(key))
104
+ continue;
105
+ if (parts.length > 0 && Array.isArray(parts[0]))
106
+ parts.forEach((item) => historyPathParts(item, `${label}.${key}`));
107
+ else
108
+ historyPathParts(parts, `${label}.${key}`);
109
+ }
110
+ else
111
+ validateHistoricalEmbeddedPaths(entry, `${label}.${key}`);
112
+ }
113
+ }
114
+ }
115
+ export function uniqueSorted(values, key, label) {
116
+ if (new Set(values.map(key)).size !== values.length)
117
+ historyFail(label, 'contains duplicate scope entries.');
118
+ return values.sort((a, b) => key(a).localeCompare(key(b), 'en'));
119
+ }
120
+ export function nullableString(value, label) {
121
+ return value === null ? null : historyString(value, label);
122
+ }
123
+ export function readHistoricalApprovalFields(value) {
124
+ const label = 'historicalApprovalEnvelope';
125
+ assertSafeHistoricalRecord(value, label);
126
+ const item = historyExact(value, [
127
+ 'schemaVersion', 'id', 'phaseId', 'gateKind', 'identity', 'baselineSha', 'planDigest', 'resources',
128
+ 'destinations', 'permissions', 'costCeiling', 'policyExceptions', 'destructiveScope', 'expiresAt', 'approvedAt', 'approver'
129
+ ], label);
130
+ const id = phaseId(item.phaseId, `${label}.phaseId`);
131
+ const gateKind = historyEnum(item.gateKind, historicalGateKinds, `${label}.gateKind`);
132
+ if (gateKind !== historicalPhaseGates[id])
133
+ historyFail(label, 'approval gate does not match the historical phase.');
134
+ const cost = historyExact(item.costCeiling, ['currency', 'fixedMonthlyCents', 'usageMonthlyCents'], `${label}.costCeiling`);
135
+ const resources = historyArray(item.resources, `${label}.resources`).map((entry, index) => {
136
+ const resource = historyExact(entry, ['type', 'identity'], `${label}.resources[${index}]`);
137
+ return { type: historyString(resource.type, `${label}.resources[${index}].type`).toLowerCase(), identity: historyString(resource.identity, `${label}.resources[${index}].identity`) };
138
+ });
139
+ const destinations = historyArray(item.destinations, `${label}.destinations`).map((entry, index) => {
140
+ const destination = historyExact(entry, ['type', 'identity', 'repository', 'subscriptionId'], `${label}.destinations[${index}]`);
141
+ return {
142
+ type: historyEnum(destination.type, destinationTypes, `${label}.destinations[${index}].type`),
143
+ identity: historyString(destination.identity, `${label}.destinations[${index}].identity`),
144
+ repository: nullableString(destination.repository, `${label}.destinations[${index}].repository`),
145
+ subscriptionId: nullableString(destination.subscriptionId, `${label}.destinations[${index}].subscriptionId`)
146
+ };
147
+ });
148
+ return {
149
+ id: historyRecordId(item.id, `${label}.id`), phaseId: id, gateKind,
150
+ baselineSha: historyDigest(item.baselineSha, `${label}.baselineSha`),
151
+ planDigest: historyDigest(item.planDigest, `${label}.planDigest`),
152
+ resources: uniqueSorted(resources, (entry) => `${entry.type}:${entry.identity}`, `${label}.resources`),
153
+ destinations: uniqueSorted(destinations, (entry) => `${entry.type}:${entry.identity}`, `${label}.destinations`),
154
+ permissions: uniqueSorted(historyStrings(item.permissions, `${label}.permissions`).map((entry) => entry.toLowerCase()), (entry) => entry, `${label}.permissions`),
155
+ costCeiling: {
156
+ currency: historyString(cost.currency, `${label}.costCeiling.currency`),
157
+ fixedMonthlyCents: Math.max(0, Math.trunc(Number(cost.fixedMonthlyCents))),
158
+ usageMonthlyCents: Math.max(0, Math.trunc(Number(cost.usageMonthlyCents)))
159
+ },
160
+ policyExceptions: uniqueSorted(historyStrings(item.policyExceptions, `${label}.policyExceptions`), (entry) => entry, `${label}.policyExceptions`),
161
+ destructiveScope: uniqueSorted(historyStrings(item.destructiveScope, `${label}.destructiveScope`), (entry) => entry, `${label}.destructiveScope`),
162
+ expiresAt: historyTimestamp(item.expiresAt, `${label}.expiresAt`),
163
+ approvedAt: historyTimestamp(item.approvedAt, `${label}.approvedAt`),
164
+ approver: historyString(item.approver, `${label}.approver`)
165
+ };
166
+ }
167
+ export function operationDestination(value, label) {
168
+ const item = historyExact(value, ['type', 'identity'], label, ['pathParts', 'repository', 'subscriptionId', 'ref']);
169
+ return {
170
+ type: historyEnum(item.type, destinationTypes, `${label}.type`),
171
+ identity: historyString(item.identity, `${label}.identity`),
172
+ ...(Object.hasOwn(item, 'pathParts') ? { pathParts: historyPathParts(item.pathParts, `${label}.pathParts`) } : {}),
173
+ ...(Object.hasOwn(item, 'repository') ? { repository: historyString(item.repository, `${label}.repository`) } : {}),
174
+ ...(Object.hasOwn(item, 'subscriptionId') ? { subscriptionId: historyString(item.subscriptionId, `${label}.subscriptionId`) } : {}),
175
+ ...(Object.hasOwn(item, 'ref') ? { ref: historyString(item.ref, `${label}.ref`) } : {})
176
+ };
177
+ }
178
+ export function operation(value, label, mutationClasses = historicalMutationClasses) {
179
+ const item = historyExact(value, ['adapter', 'actionId', 'mutationClass', 'phaseId', 'inputs', 'destination', 'remote', 'destructive'], label);
180
+ const inputs = historyRecord(item.inputs, `${label}.inputs`);
181
+ validateHistoricalEmbeddedPaths(inputs, `${label}.inputs`);
182
+ return {
183
+ adapter: historyEnum(item.adapter, adapterIds, `${label}.adapter`),
184
+ actionId: historyString(item.actionId, `${label}.actionId`),
185
+ mutationClass: historyEnum(item.mutationClass, mutationClasses, `${label}.mutationClass`),
186
+ phaseId: phaseId(item.phaseId, `${label}.phaseId`), inputs,
187
+ destination: operationDestination(item.destination, `${label}.destination`),
188
+ remote: historyBoolean(item.remote, `${label}.remote`), destructive: historyBoolean(item.destructive, `${label}.destructive`)
189
+ };
190
+ }
191
+ export function evaluation(value, label) {
192
+ const item = historyExact(value, [
193
+ 'phaseId', 'gateKind', 'questionKind', 'approvalRequired', 'status', 'envelopeId', 'envelopeHash', 'reasons', 'expansionReasons'
194
+ ], label);
195
+ return {
196
+ phaseId: phaseId(item.phaseId, `${label}.phaseId`),
197
+ gateKind: historyEnum(item.gateKind, historicalGateKinds, `${label}.gateKind`),
198
+ questionKind: item.questionKind === null ? null : historyEnum(item.questionKind, historicalQuestionKinds, `${label}.questionKind`),
199
+ approvalRequired: historyBoolean(item.approvalRequired, `${label}.approvalRequired`),
200
+ status: historyEnum(item.status, ['not-required', 'approval-required', 'reused', 'expired', 'invalidated'], `${label}.status`),
201
+ envelopeId: item.envelopeId === null ? null : historyRecordId(item.envelopeId, `${label}.envelopeId`),
202
+ envelopeHash: item.envelopeHash === null ? null : historyDigest(item.envelopeHash, `${label}.envelopeHash`),
203
+ reasons: historyStrings(item.reasons, `${label}.reasons`), expansionReasons: historyStrings(item.expansionReasons, `${label}.expansionReasons`)
204
+ };
205
+ }
206
+ export function rollbackPlan(value, label, mutationClasses = historicalMutationClasses) {
207
+ const item = historyExact(value, ['phaseId', 'strategy', 'target', 'operations', 'retained', 'cleanupWarnings'], label);
208
+ return {
209
+ phaseId: phaseId(item.phaseId, `${label}.phaseId`),
210
+ strategy: historyEnum(item.strategy, ['none', 'retain', 'reverse-to', 'dispose'], `${label}.strategy`),
211
+ target: item.target === null ? null : phaseId(item.target, `${label}.target`),
212
+ operations: historyArray(item.operations, `${label}.operations`).map((entry, index) => operation(entry, `${label}.operations[${index}]`, mutationClasses)),
213
+ retained: historyStrings(item.retained, `${label}.retained`), cleanupWarnings: historyStrings(item.cleanupWarnings, `${label}.cleanupWarnings`)
214
+ };
215
+ }
216
+ export function readHistoricalSavedTransitionPlan(value, identityReader) {
217
+ const label = 'historicalTransitionPlan';
218
+ assertSafeHistoricalRecord(value, label);
219
+ const item = historyExact(value, [
220
+ 'schemaVersion', 'phaseId', 'createdAt', 'expiresAt', 'identity', 'graphHash', 'stateHash',
221
+ 'baselineDigest', 'inputDigest', 'transitionDigest', 'planDigest', 'mutationClasses', 'operations',
222
+ 'approval', 'rollbackPlan', 'noSecrets'
223
+ ], label);
224
+ const identity = identityReader(item.identity, `${label}.identity`);
225
+ const allowedMutationClasses = identity.activationContractVersion === 1
226
+ ? historicalMutationClasses : [...historicalMutationClasses, 'write-seed-tasks'];
227
+ const graphHash = historyDigest(item.graphHash, `${label}.graphHash`);
228
+ if (graphHash !== identity.phaseGraphHash)
229
+ historyFail(label, 'graphHash contradicts the historical identity.');
230
+ const id = phaseId(item.phaseId, `${label}.phaseId`);
231
+ const operations = historyArray(item.operations, `${label}.operations`).map((entry, index) => operation(entry, `${label}.operations[${index}]`, allowedMutationClasses));
232
+ if (operations.some((entry) => entry.phaseId !== id))
233
+ historyFail(label, 'operation phase differs from its plan.');
234
+ const mutations = historyExact(item.mutationClasses, ['local', 'remote'], `${label}.mutationClasses`);
235
+ const approval = historyExact(item.approval, ['gateKind', 'required', 'evaluation', 'envelopeId', 'envelopeHash'], `${label}.approval`);
236
+ const approvalEvaluation = evaluation(approval.evaluation, `${label}.approval.evaluation`);
237
+ const gateKind = historyEnum(approval.gateKind, historicalGateKinds, `${label}.approval.gateKind`);
238
+ const required = historyBoolean(approval.required, `${label}.approval.required`);
239
+ const envelopeId = approval.envelopeId === null ? null : historyRecordId(approval.envelopeId, `${label}.approval.envelopeId`);
240
+ const envelopeHash = approval.envelopeHash === null ? null : historyDigest(approval.envelopeHash, `${label}.approval.envelopeHash`);
241
+ if (gateKind !== historicalPhaseGates[id] || required !== (gateKind !== 'none') ||
242
+ approvalEvaluation.phaseId !== id || approvalEvaluation.gateKind !== gateKind ||
243
+ approvalEvaluation.envelopeId !== envelopeId || approvalEvaluation.envelopeHash !== envelopeHash ||
244
+ (envelopeId === null) !== (envelopeHash === null)) {
245
+ historyFail(label, 'approval references or gate contradict the historical phase.');
246
+ }
247
+ const rollback = rollbackPlan(item.rollbackPlan, `${label}.rollbackPlan`, allowedMutationClasses);
248
+ if (rollback.phaseId !== id)
249
+ historyFail(label, 'rollback names another phase.');
250
+ return {
251
+ schemaVersion: historyLiteral(item.schemaVersion, 1, `${label}.schemaVersion`), phaseId: id,
252
+ createdAt: historyTimestamp(item.createdAt, `${label}.createdAt`),
253
+ expiresAt: historyTimestamp(item.expiresAt, `${label}.expiresAt`), identity, graphHash,
254
+ stateHash: item.stateHash === null ? null : historyDigest(item.stateHash, `${label}.stateHash`),
255
+ baselineDigest: historyDigest(item.baselineDigest, `${label}.baselineDigest`),
256
+ inputDigest: historyDigest(item.inputDigest, `${label}.inputDigest`),
257
+ transitionDigest: historyDigest(item.transitionDigest, `${label}.transitionDigest`),
258
+ planDigest: historyDigest(item.planDigest, `${label}.planDigest`),
259
+ mutationClasses: {
260
+ local: historyStrings(mutations.local, `${label}.mutationClasses.local`).map((entry) => historyEnum(entry, allowedMutationClasses, `${label}.mutationClasses.local`)),
261
+ remote: historyStrings(mutations.remote, `${label}.mutationClasses.remote`).map((entry) => historyEnum(entry, allowedMutationClasses, `${label}.mutationClasses.remote`))
262
+ },
263
+ operations,
264
+ approval: { gateKind, required, evaluation: approvalEvaluation, envelopeId, envelopeHash },
265
+ rollbackPlan: rollback,
266
+ noSecrets: historyLiteral(item.noSecrets, true, `${label}.noSecrets`)
267
+ };
268
+ }
269
+ //# sourceMappingURL=historical-common.js.map