@msn-control/liftoff 0.11.2 → 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 (339) hide show
  1. package/DEVELOPER.md +26 -24
  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 +45 -2
  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/process/shell-command.d.ts +1 -0
  23. package/dist/adapters/process/shell-command.js +5 -2
  24. package/dist/adapters/process/shell-command.js.map +1 -1
  25. package/dist/adapters/state/azure-blob.d.ts +43 -0
  26. package/dist/adapters/state/azure-blob.js +335 -0
  27. package/dist/adapters/state/azure-blob.js.map +1 -0
  28. package/dist/adapters/state/darwin-capabilities.d.ts +33 -0
  29. package/dist/adapters/state/darwin-capabilities.js +146 -0
  30. package/dist/adapters/state/darwin-capabilities.js.map +1 -0
  31. package/dist/adapters/state/darwin-native-host.d.ts +32 -0
  32. package/dist/adapters/state/darwin-native-host.js +294 -0
  33. package/dist/adapters/state/darwin-native-host.js.map +1 -0
  34. package/dist/adapters/state/darwin-profile.d.ts +6 -0
  35. package/dist/adapters/state/darwin-profile.js +56 -0
  36. package/dist/adapters/state/darwin-profile.js.map +1 -0
  37. package/dist/adapters/state/darwin-system-program.d.ts +1 -0
  38. package/dist/adapters/state/darwin-system-program.js +94 -0
  39. package/dist/adapters/state/darwin-system-program.js.map +1 -0
  40. package/dist/adapters/state/local-qualification.d.ts +16 -0
  41. package/dist/adapters/state/local-qualification.js +299 -0
  42. package/dist/adapters/state/local-qualification.js.map +1 -0
  43. package/dist/adapters/state/local.d.ts +25 -0
  44. package/dist/adapters/state/local.js +145 -0
  45. package/dist/adapters/state/local.js.map +1 -0
  46. package/dist/adapters/state/native-command.d.ts +21 -0
  47. package/dist/adapters/state/native-command.js +82 -0
  48. package/dist/adapters/state/native-command.js.map +1 -0
  49. package/dist/adapters/state/native-files.d.ts +2 -0
  50. package/dist/adapters/state/native-files.js +47 -0
  51. package/dist/adapters/state/native-files.js.map +1 -0
  52. package/dist/adapters/state/native-system.d.ts +38 -0
  53. package/dist/adapters/state/native-system.js +86 -0
  54. package/dist/adapters/state/native-system.js.map +1 -0
  55. package/dist/adapters/state/opentofu.d.ts +35 -0
  56. package/dist/adapters/state/opentofu.js +350 -0
  57. package/dist/adapters/state/opentofu.js.map +1 -0
  58. package/dist/adapters/state/owned-process.d.ts +43 -0
  59. package/dist/adapters/state/owned-process.js +252 -0
  60. package/dist/adapters/state/owned-process.js.map +1 -0
  61. package/dist/adapters/state/posix-lock-program.d.ts +1 -0
  62. package/dist/adapters/state/posix-lock-program.js +185 -0
  63. package/dist/adapters/state/posix-lock-program.js.map +1 -0
  64. package/dist/adapters/state/posix-native-lock.d.ts +15 -0
  65. package/dist/adapters/state/posix-native-lock.js +145 -0
  66. package/dist/adapters/state/posix-native-lock.js.map +1 -0
  67. package/dist/adapters/state/protected-workspace.d.ts +57 -0
  68. package/dist/adapters/state/protected-workspace.js +412 -0
  69. package/dist/adapters/state/protected-workspace.js.map +1 -0
  70. package/dist/application/context.d.ts +3 -0
  71. package/dist/application/diagnose/doctor.d.ts +5 -0
  72. package/dist/application/diagnose/doctor.js +21 -5
  73. package/dist/application/diagnose/doctor.js.map +1 -1
  74. package/dist/application/diagnose/generated-project.js +2 -7
  75. package/dist/application/diagnose/generated-project.js.map +1 -1
  76. package/dist/application/initialize/fixture.js +8 -1
  77. package/dist/application/initialize/fixture.js.map +1 -1
  78. package/dist/application/initialize/use-case.js +70 -36
  79. package/dist/application/initialize/use-case.js.map +1 -1
  80. package/dist/application/project/manifest.js +5 -4
  81. package/dist/application/project/manifest.js.map +1 -1
  82. package/dist/application/state-migration/execution.d.ts +32 -0
  83. package/dist/application/state-migration/execution.js +440 -0
  84. package/dist/application/state-migration/execution.js.map +1 -0
  85. package/dist/application/state-migration/index.d.ts +22 -0
  86. package/dist/application/state-migration/index.js +17 -0
  87. package/dist/application/state-migration/index.js.map +1 -0
  88. package/dist/application/state-migration/lifecycle.d.ts +3 -0
  89. package/dist/application/state-migration/lifecycle.js +149 -0
  90. package/dist/application/state-migration/lifecycle.js.map +1 -0
  91. package/dist/application/state-migration/planning.d.ts +7 -0
  92. package/dist/application/state-migration/planning.js +150 -0
  93. package/dist/application/state-migration/planning.js.map +1 -0
  94. package/dist/application/state-migration/recovery.d.ts +5 -0
  95. package/dist/application/state-migration/recovery.js +145 -0
  96. package/dist/application/state-migration/recovery.js.map +1 -0
  97. package/dist/application/state-migration/runtime.d.ts +32 -0
  98. package/dist/application/state-migration/runtime.js +188 -0
  99. package/dist/application/state-migration/runtime.js.map +1 -0
  100. package/dist/application/state-migration/service.d.ts +2 -0
  101. package/dist/application/state-migration/service.js +20 -0
  102. package/dist/application/state-migration/service.js.map +1 -0
  103. package/dist/application/update/command-guidance.d.ts +19 -2
  104. package/dist/application/update/command-guidance.js +20 -6
  105. package/dist/application/update/command-guidance.js.map +1 -1
  106. package/dist/application/update/guidance-context.d.ts +2 -0
  107. package/dist/application/update/guidance-context.js +35 -0
  108. package/dist/application/update/guidance-context.js.map +1 -0
  109. package/dist/application/update/inspection.d.ts +21 -4
  110. package/dist/application/update/inspection.js +88 -29
  111. package/dist/application/update/inspection.js.map +1 -1
  112. package/dist/application/update/migration-runtime.js +25 -13
  113. package/dist/application/update/migration-runtime.js.map +1 -1
  114. package/dist/application/update/output.d.ts +4 -1
  115. package/dist/application/update/output.js +14 -4
  116. package/dist/application/update/output.js.map +1 -1
  117. package/dist/application/update/preview.d.ts +10 -1
  118. package/dist/application/update/preview.js +26 -4
  119. package/dist/application/update/preview.js.map +1 -1
  120. package/dist/application/update/revalidation-plan.d.ts +1 -0
  121. package/dist/application/update/revalidation-plan.js +27 -15
  122. package/dist/application/update/revalidation-plan.js.map +1 -1
  123. package/dist/application/update/revalidation.d.ts +4 -1
  124. package/dist/application/update/revalidation.js +64 -23
  125. package/dist/application/update/revalidation.js.map +1 -1
  126. package/dist/application/update/use-case.js +50 -29
  127. package/dist/application/update/use-case.js.map +1 -1
  128. package/dist/cli/args/definitions.js +11 -3
  129. package/dist/cli/args/definitions.js.map +1 -1
  130. package/dist/cli/args/parser.js +29 -3
  131. package/dist/cli/args/parser.js.map +1 -1
  132. package/dist/domain/governance/activation/approvals.d.ts +264 -7
  133. package/dist/domain/governance/activation/approvals.js +166 -23
  134. package/dist/domain/governance/activation/approvals.js.map +1 -1
  135. package/dist/domain/governance/activation/capabilities.js +5 -2
  136. package/dist/domain/governance/activation/capabilities.js.map +1 -1
  137. package/dist/domain/governance/activation/evidence.d.ts +2 -1
  138. package/dist/domain/governance/activation/evidence.js +64 -11
  139. package/dist/domain/governance/activation/evidence.js.map +1 -1
  140. package/dist/domain/governance/activation/graph.d.ts +11 -384
  141. package/dist/domain/governance/activation/graph.js +424 -379
  142. package/dist/domain/governance/activation/graph.js.map +1 -1
  143. package/dist/domain/governance/activation/inputs.d.ts +3 -1
  144. package/dist/domain/governance/activation/inputs.js +47 -6
  145. package/dist/domain/governance/activation/inputs.js.map +1 -1
  146. package/dist/domain/governance/activation/operations.d.ts +4 -1
  147. package/dist/domain/governance/activation/operations.js +110 -22
  148. package/dist/domain/governance/activation/operations.js.map +1 -1
  149. package/dist/domain/governance/activation/readiness.d.ts +10 -0
  150. package/dist/domain/governance/activation/readiness.js +77 -38
  151. package/dist/domain/governance/activation/readiness.js.map +1 -1
  152. package/dist/domain/governance/activation/types.d.ts +151 -9
  153. package/dist/domain/governance/activation/types.js +23 -1
  154. package/dist/domain/governance/activation/types.js.map +1 -1
  155. package/dist/domain/governance/activation/validators.d.ts +4 -1
  156. package/dist/domain/governance/activation/validators.js +419 -26
  157. package/dist/domain/governance/activation/validators.js.map +1 -1
  158. package/dist/domain/governance/policy/identity.d.ts +55 -13
  159. package/dist/domain/governance/policy/identity.js +28 -8
  160. package/dist/domain/governance/policy/identity.js.map +1 -1
  161. package/dist/domain/project/artifact-lifecycle.d.ts +2 -1
  162. package/dist/domain/project/artifact-lifecycle.js +7 -1
  163. package/dist/domain/project/artifact-lifecycle.js.map +1 -1
  164. package/dist/domain/project/catalog.d.ts +50 -1
  165. package/dist/domain/project/catalog.js +104 -4
  166. package/dist/domain/project/catalog.js.map +1 -1
  167. package/dist/domain/project/contracts.d.ts +9 -1
  168. package/dist/domain/project/infrastructure-layout.d.ts +1 -1
  169. package/dist/domain/project/infrastructure-layout.js +3 -1
  170. package/dist/domain/project/infrastructure-layout.js.map +1 -1
  171. package/dist/domain/project/manifest/governance.d.ts +1 -1
  172. package/dist/domain/project/manifest/governance.js +9 -10
  173. package/dist/domain/project/manifest/governance.js.map +1 -1
  174. package/dist/domain/project/planning.js +4 -5
  175. package/dist/domain/project/planning.js.map +1 -1
  176. package/dist/domain/repair/stateful-bounded.d.ts +1 -0
  177. package/dist/domain/repair/stateful-bounded.js +37 -0
  178. package/dist/domain/repair/stateful-bounded.js.map +1 -0
  179. package/dist/domain/repair/stateful-invariants.d.ts +28 -0
  180. package/dist/domain/repair/stateful-invariants.js +278 -0
  181. package/dist/domain/repair/stateful-invariants.js.map +1 -0
  182. package/dist/domain/repair/stateful.d.ts +690 -0
  183. package/dist/domain/repair/stateful.js +26 -0
  184. package/dist/domain/repair/stateful.js.map +1 -0
  185. package/dist/domain/workstation/constraints.d.ts +1 -0
  186. package/dist/domain/workstation/constraints.js.map +1 -1
  187. package/dist/domain/workstation/contracts.d.ts +42 -0
  188. package/dist/domain/workstation/contracts.js +2 -0
  189. package/dist/domain/workstation/contracts.js.map +1 -0
  190. package/dist/domain/workstation/executables.d.ts +19 -0
  191. package/dist/domain/workstation/executables.js +68 -0
  192. package/dist/domain/workstation/executables.js.map +1 -0
  193. package/dist/domain/workstation/versions.d.ts +8 -0
  194. package/dist/domain/workstation/versions.js +145 -0
  195. package/dist/domain/workstation/versions.js.map +1 -0
  196. package/dist/framework-adapters.d.ts +2 -0
  197. package/dist/framework-adapters.js +148 -22
  198. package/dist/framework-adapters.js.map +1 -1
  199. package/dist/framework-validation.d.ts +6 -0
  200. package/dist/framework-validation.js +89 -24
  201. package/dist/framework-validation.js.map +1 -1
  202. package/dist/generators/common/base.js +57 -17
  203. package/dist/generators/common/base.js.map +1 -1
  204. package/dist/governance-activation/activation-state.js +39 -7
  205. package/dist/governance-activation/activation-state.js.map +1 -1
  206. package/dist/governance-activation/authority-records.d.ts +4 -0
  207. package/dist/governance-activation/authority-records.js +24 -0
  208. package/dist/governance-activation/authority-records.js.map +1 -0
  209. package/dist/governance-activation/commands.d.ts +9 -1
  210. package/dist/governance-activation/commands.js +392 -97
  211. package/dist/governance-activation/commands.js.map +1 -1
  212. package/dist/governance-activation/compatibility.d.ts +11 -8
  213. package/dist/governance-activation/compatibility.js +37 -23
  214. package/dist/governance-activation/compatibility.js.map +1 -1
  215. package/dist/governance-activation/doctor.js +40 -16
  216. package/dist/governance-activation/doctor.js.map +1 -1
  217. package/dist/governance-activation/github-config.d.ts +17 -0
  218. package/dist/governance-activation/github-config.js +88 -0
  219. package/dist/governance-activation/github-config.js.map +1 -0
  220. package/dist/governance-activation/github-discovery.d.ts +18 -0
  221. package/dist/governance-activation/github-discovery.js +229 -0
  222. package/dist/governance-activation/github-discovery.js.map +1 -0
  223. package/dist/governance-activation/github-ports.d.ts +12 -0
  224. package/dist/governance-activation/github-ports.js +4 -0
  225. package/dist/governance-activation/github-ports.js.map +1 -0
  226. package/dist/governance-activation/github-publication.d.ts +3 -0
  227. package/dist/governance-activation/github-publication.js +190 -0
  228. package/dist/governance-activation/github-publication.js.map +1 -0
  229. package/dist/governance-activation/historical-common.d.ts +98 -0
  230. package/dist/governance-activation/historical-common.js +269 -0
  231. package/dist/governance-activation/historical-common.js.map +1 -0
  232. package/dist/governance-activation/historical-credential-policy.d.ts +3 -0
  233. package/dist/governance-activation/historical-credential-policy.js +91 -0
  234. package/dist/governance-activation/historical-credential-policy.js.map +1 -0
  235. package/dist/governance-activation/historical-inputs.d.ts +6 -0
  236. package/dist/governance-activation/historical-inputs.js +57 -0
  237. package/dist/governance-activation/historical-inputs.js.map +1 -0
  238. package/dist/governance-activation/historical-safety.d.ts +9 -0
  239. package/dist/governance-activation/historical-safety.js +102 -0
  240. package/dist/governance-activation/historical-safety.js.map +1 -0
  241. package/dist/governance-activation/historical-source-metadata.d.ts +31 -0
  242. package/dist/governance-activation/historical-source-metadata.js +55 -0
  243. package/dist/governance-activation/historical-source-metadata.js.map +1 -0
  244. package/dist/governance-activation/historical-state.d.ts +12 -50
  245. package/dist/governance-activation/historical-state.js +195 -308
  246. package/dist/governance-activation/historical-state.js.map +1 -1
  247. package/dist/governance-activation/historical-v1-auxiliary.d.ts +1 -0
  248. package/dist/governance-activation/historical-v1-auxiliary.js +43 -0
  249. package/dist/governance-activation/historical-v1-auxiliary.js.map +1 -0
  250. package/dist/governance-activation/historical-v1-phase-contracts.d.ts +31 -0
  251. package/dist/governance-activation/historical-v1-phase-contracts.js +46 -0
  252. package/dist/governance-activation/historical-v1-phase-contracts.js.map +1 -0
  253. package/dist/governance-activation/historical-v2.d.ts +53 -0
  254. package/dist/governance-activation/historical-v2.js +313 -0
  255. package/dist/governance-activation/historical-v2.js.map +1 -0
  256. package/dist/governance-activation/history-contracts.d.ts +21 -12
  257. package/dist/governance-activation/history-contracts.js +99 -27
  258. package/dist/governance-activation/history-contracts.js.map +1 -1
  259. package/dist/governance-activation/inputs.d.ts +8 -2
  260. package/dist/governance-activation/inputs.js +41 -6
  261. package/dist/governance-activation/inputs.js.map +1 -1
  262. package/dist/governance-activation/migration-history.d.ts +43 -5
  263. package/dist/governance-activation/migration-history.js +231 -50
  264. package/dist/governance-activation/migration-history.js.map +1 -1
  265. package/dist/governance-activation/migration.d.ts +7 -4
  266. package/dist/governance-activation/migration.js +53 -252
  267. package/dist/governance-activation/migration.js.map +1 -1
  268. package/dist/governance-activation/phase-azure.d.ts +3 -0
  269. package/dist/governance-activation/phase-azure.js +205 -0
  270. package/dist/governance-activation/phase-azure.js.map +1 -0
  271. package/dist/governance-activation/phase-bootstrap-state.js +3 -0
  272. package/dist/governance-activation/phase-bootstrap-state.js.map +1 -1
  273. package/dist/governance-activation/phase-github.d.ts +3 -0
  274. package/dist/governance-activation/phase-github.js +192 -0
  275. package/dist/governance-activation/phase-github.js.map +1 -0
  276. package/dist/governance-activation/phase-governance.js +8 -2
  277. package/dist/governance-activation/phase-governance.js.map +1 -1
  278. package/dist/governance-activation/public-plans.d.ts +36 -0
  279. package/dist/governance-activation/public-plans.js +100 -0
  280. package/dist/governance-activation/public-plans.js.map +1 -0
  281. package/dist/governance-activation/read-only.d.ts +3 -1
  282. package/dist/governance-activation/read-only.js +7 -3
  283. package/dist/governance-activation/read-only.js.map +1 -1
  284. package/dist/governance-activation/reconciliation.js +10 -0
  285. package/dist/governance-activation/reconciliation.js.map +1 -1
  286. package/dist/governance-activation/seed-lifecycle.js +14 -25
  287. package/dist/governance-activation/seed-lifecycle.js.map +1 -1
  288. package/dist/governance-activation/source-of-truth.d.ts +21 -5
  289. package/dist/governance-activation/source-of-truth.js +102 -13
  290. package/dist/governance-activation/source-of-truth.js.map +1 -1
  291. package/dist/governance-activation/task-projection.d.ts +4 -1
  292. package/dist/governance-activation/task-projection.js +32 -3
  293. package/dist/governance-activation/task-projection.js.map +1 -1
  294. package/dist/governance-activation/task-writes.d.ts +42 -0
  295. package/dist/governance-activation/task-writes.js +250 -0
  296. package/dist/governance-activation/task-writes.js.map +1 -0
  297. package/dist/governance-activation/transition-files.d.ts +12 -0
  298. package/dist/governance-activation/transition-files.js +109 -0
  299. package/dist/governance-activation/transition-files.js.map +1 -0
  300. package/dist/governance-activation/transition-planning.d.ts +3 -1
  301. package/dist/governance-activation/transition-planning.js +158 -20
  302. package/dist/governance-activation/transition-planning.js.map +1 -1
  303. package/dist/governance-activation/transition-ports.d.ts +31 -3
  304. package/dist/governance-activation/transition-records.d.ts +11 -1
  305. package/dist/governance-activation/transition-records.js +52 -6
  306. package/dist/governance-activation/transition-records.js.map +1 -1
  307. package/dist/governance-activation/transitions.d.ts +5 -0
  308. package/dist/governance-activation/transitions.js +271 -37
  309. package/dist/governance-activation/transitions.js.map +1 -1
  310. package/dist/governance-assessment/engine.js +22 -15
  311. package/dist/governance-assessment/engine.js.map +1 -1
  312. package/dist/governance-assessment/project.d.ts +2 -0
  313. package/dist/governance-assessment/project.js +2 -1
  314. package/dist/governance-assessment/project.js.map +1 -1
  315. package/dist/interactive.d.ts +0 -1
  316. package/dist/interactive.js +3 -22
  317. package/dist/interactive.js.map +1 -1
  318. package/dist/openspec-profile.d.ts +2 -1
  319. package/dist/openspec-profile.js +11 -41
  320. package/dist/openspec-profile.js.map +1 -1
  321. package/dist/repository-governance.d.ts +10 -5
  322. package/dist/repository-governance.js +178 -92
  323. package/dist/repository-governance.js.map +1 -1
  324. package/dist/telemetry/contract.d.ts +1 -1
  325. package/dist/telemetry/contract.js +3 -0
  326. package/dist/telemetry/contract.js.map +1 -1
  327. package/dist/workstation-catalog.d.ts +13 -1
  328. package/dist/workstation-catalog.js +122 -0
  329. package/dist/workstation-catalog.js.map +1 -1
  330. package/dist/workstation.d.ts +69 -14
  331. package/dist/workstation.js +600 -215
  332. package/dist/workstation.js.map +1 -1
  333. package/docs/cli-reference.md +94 -23
  334. package/docs/configuration-and-manifests.md +11 -10
  335. package/docs/prerequisites.md +93 -18
  336. package/docs/repository-governance.md +68 -40
  337. package/docs/spec-workflows-and-agents.md +132 -13
  338. package/docs/troubleshooting.md +28 -0
  339. package/package.json +1 -1
@@ -0,0 +1,51 @@
1
+ import type { CommandRunner } from '../../process-runner.js';
2
+ import type { ActivationIdentity, CredentialPolicy } from '../../domain/governance/activation/types.js';
3
+ import { runnerPreflightSecretName } from '../../domain/governance/activation/types.js';
4
+ import type { ProtectedCredentialChannel } from './protected-input.js';
5
+ import { GitHubActivationClient, type GitHubActivationTransport } from '../github/activation-rest.js';
6
+ export type GitHubCredentialConfiguration = {
7
+ kind: 'github-app';
8
+ appId: number;
9
+ installationId: number;
10
+ } | {
11
+ kind: 'fine-grained-pat';
12
+ tokenId: number;
13
+ owner: string;
14
+ appUnavailableReason: string;
15
+ };
16
+ export declare const credentialApiPermissions: {
17
+ readonly metadata: 'read';
18
+ readonly organization_hosted_runners: 'read';
19
+ readonly organization_network_configurations: 'read';
20
+ };
21
+ export interface GitHubSecretWriter {
22
+ write(repository: string, name: typeof runnerPreflightSecretName, value: Uint8Array): Promise<void>;
23
+ }
24
+ export declare function githubCliSecretWriter(runner: CommandRunner, cwd: string): GitHubSecretWriter;
25
+ export declare function githubRestSecretWriter(client: GitHubActivationClient, seal: (value: Uint8Array, publicKey: Uint8Array) => Promise<Uint8Array>): GitHubSecretWriter;
26
+ export declare function parseGitHubCredentialConfiguration(value: unknown): GitHubCredentialConfiguration;
27
+ export declare function createAppJwt(key: Uint8Array, appId: number, now: Date): Buffer;
28
+ export interface CredentialEnrollmentResult {
29
+ policy: CredentialPolicy;
30
+ usage: {
31
+ repositoryId: number;
32
+ repository: string;
33
+ principal: string;
34
+ installationId: number | null;
35
+ probeEndpoints: readonly string[];
36
+ permissionsDigest: string;
37
+ secretUpdatedAt: string;
38
+ };
39
+ }
40
+ export declare function enrollGitHubCredential(input: {
41
+ repository: string;
42
+ repositoryId: number;
43
+ configuration: GitHubCredentialConfiguration;
44
+ identity: ActivationIdentity;
45
+ client: GitHubActivationClient;
46
+ channel: ProtectedCredentialChannel;
47
+ secretWriter: GitHubSecretWriter;
48
+ credentialTransport?: (value: Uint8Array) => GitHubActivationTransport;
49
+ now: Date;
50
+ assertAuthorized: () => Promise<void>;
51
+ }): Promise<CredentialEnrollmentResult>;
@@ -0,0 +1,226 @@
1
+ import { createPrivateKey, sign } from 'node:crypto';
2
+ import { runnerPreflightSecretName } from '../../domain/governance/activation/types.js';
3
+ import { canonicalSha256 } from '../../domain/governance/activation/canonical-json.js';
4
+ import { buildFineGrainedPatCredentialPolicy, buildGitHubAppCredentialPolicy, canonicalCredentialRepository } from '../../governance-activation/credentials.js';
5
+ import { GitHubActivationClient, GitHubActivationError, createAuthenticatedGitHubTransport, expectStatus, githubName, githubRepository, object, positiveId, text } from '../github/activation-rest.js';
6
+ export const credentialApiPermissions = {
7
+ metadata: 'read', organization_hosted_runners: 'read', organization_network_configurations: 'read'
8
+ };
9
+ export function githubCliSecretWriter(runner, cwd) {
10
+ return {
11
+ async write(repository, name, value) {
12
+ githubRepository(repository);
13
+ if (name !== runnerPreflightSecretName)
14
+ throw new GitHubActivationError('credential-scope', 'Only the reviewed runner preflight secret may be enrolled.');
15
+ // gh performs GitHub's public-key sealed-box encryption. Secret bytes are stdin, never argv.
16
+ const result = await runner.run({
17
+ executable: 'gh', args: ['secret', 'set', name, '--repo', repository, '--app', 'actions']
18
+ }, {
19
+ cwd, stdin: value, redactValues: [Buffer.from(value).toString('utf8')], stream: false,
20
+ timeoutMs: 30_000, maxOutputBytes: 32_768, env: { GH_DEBUG: '', GH_PROMPT_DISABLED: '1', GH_PAGER: 'cat' }
21
+ });
22
+ if (result.status !== 0 || result.errorCode || result.timedOut || result.outputLimitExceeded || result.aborted) {
23
+ throw new GitHubActivationError('secret-write', 'GitHub did not confirm encrypted Actions secret enrollment. Check the approved repository secrets-write permission.');
24
+ }
25
+ }
26
+ };
27
+ }
28
+ export function githubRestSecretWriter(client, seal) {
29
+ return {
30
+ async write(repository, name, value) {
31
+ githubRepository(repository);
32
+ if (name !== runnerPreflightSecretName)
33
+ throw new GitHubActivationError('credential-scope', 'The secret name is outside the reviewed enrollment policy.');
34
+ const key = await client.get(`/repos/${repository}/actions/secrets/public-key`);
35
+ const publicKey = Buffer.from(text(key.key, 'GitHub secret public key'), 'base64');
36
+ if (publicKey.length !== 32)
37
+ throw new GitHubActivationError('invalid-key', 'GitHub secret encryption key is not a 32-byte Curve25519 key.');
38
+ const encrypted = await seal(value, publicKey);
39
+ if (encrypted.length !== value.length + 48)
40
+ throw new GitHubActivationError('invalid-encryption', 'Secret encryption did not produce a libsodium sealed box.');
41
+ await client.write('PUT', `/repos/${repository}/actions/secrets/${name}`, {
42
+ key_id: text(key.key_id, 'GitHub key ID'), encrypted_value: Buffer.from(encrypted).toString('base64')
43
+ });
44
+ }
45
+ };
46
+ }
47
+ export function parseGitHubCredentialConfiguration(value) {
48
+ const config = object(value, 'credential-ready configuration');
49
+ const allowed = config.kind === 'github-app' ? ['kind', 'appId', 'installationId'] :
50
+ ['kind', 'tokenId', 'owner', 'appUnavailableReason'];
51
+ if (Object.keys(config).some((key) => !allowed.includes(key))) {
52
+ throw new GitHubActivationError('credential-config', 'Credential configuration contains unknown fields. Values, commands, and arbitrary permission grants are forbidden.');
53
+ }
54
+ if (config.kind === 'github-app') {
55
+ return { kind: 'github-app', appId: positiveId(config.appId, 'Approved App ID'),
56
+ installationId: positiveId(config.installationId, 'Approved installation ID') };
57
+ }
58
+ if (config.kind !== 'fine-grained-pat') {
59
+ throw new GitHubActivationError('credential-config', 'Select an existing approved scoped GitHub App, or explicitly justify its unavailable fine-grained PAT fallback.');
60
+ }
61
+ return { kind: 'fine-grained-pat', tokenId: positiveId(config.tokenId, 'Approved PAT ID'),
62
+ owner: githubName(config.owner, 'Credential owner'),
63
+ appUnavailableReason: text(config.appUnavailableReason, 'Reason an approved scoped App is unavailable') };
64
+ }
65
+ function samePermissions(actual) {
66
+ const permissions = object(actual, 'Credential permissions');
67
+ return canonicalSha256(permissions) === canonicalSha256(credentialApiPermissions);
68
+ }
69
+ export function createAppJwt(key, appId, now) {
70
+ try {
71
+ const privateKey = createPrivateKey(Buffer.from(key));
72
+ if (privateKey.asymmetricKeyType !== 'rsa' || (privateKey.asymmetricKeyDetails?.modulusLength ?? 0) < 2048) {
73
+ throw new Error('key type');
74
+ }
75
+ const issued = Math.floor(now.getTime() / 1000) - 60;
76
+ const unsigned = `${Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url')}.${Buffer.from(JSON.stringify({
77
+ iat: issued, exp: issued + 540, iss: String(positiveId(appId))
78
+ })).toString('base64url')}`;
79
+ return Buffer.from(`${unsigned}.${sign('RSA-SHA256', Buffer.from(unsigned), privateKey).toString('base64url')}`);
80
+ }
81
+ catch {
82
+ throw new GitHubActivationError('invalid-app-key', 'Protected input must be the approved GitHub App RSA private key (at least 2048 bits). Key bytes were withheld.');
83
+ }
84
+ }
85
+ export async function enrollGitHubCredential(input) {
86
+ const repository = githubRepository(input.repository);
87
+ const [owner, name] = repository.split('/');
88
+ const repoIdentity = canonicalCredentialRepository({ id: String(input.repositoryId), owner, name });
89
+ const makeTransport = input.credentialTransport ?? createAuthenticatedGitHubTransport;
90
+ const config = parseGitHubCredentialConfiguration(input.configuration);
91
+ await input.assertAuthorized();
92
+ const secret = await input.channel.read(config.kind === 'github-app' ? 'GitHub App private key' : 'fine-grained PAT');
93
+ let jwt;
94
+ let token;
95
+ let tokenClient;
96
+ let installation;
97
+ let pat;
98
+ let principal = '';
99
+ let tokenExpiresAt = '';
100
+ try {
101
+ if (!secret.length || secret.length > 32_768) {
102
+ throw new GitHubActivationError('invalid-credential', 'The protected credential is empty or exceeds the size bound.');
103
+ }
104
+ if (config.kind === 'github-app') {
105
+ jwt = createAppJwt(secret, config.appId, input.now);
106
+ const appClient = new GitHubActivationClient(makeTransport(jwt));
107
+ installation = await appClient.get(`/app/installations/${config.installationId}`);
108
+ if (installation.app_id !== config.appId || installation.id !== config.installationId ||
109
+ object(installation.account).login !== owner || installation.repository_selection !== 'selected' ||
110
+ installation.suspended_at !== null || !samePermissions(installation.permissions)) {
111
+ throw new GitHubActivationError('credential-scope', 'The approved App installation is suspended, over-scoped, or bound to another owner. No installation or grant will be created automatically.');
112
+ }
113
+ await input.assertAuthorized();
114
+ const issued = object(await appClient.write('POST', `/app/installations/${config.installationId}/access_tokens`, {
115
+ repository_ids: [input.repositoryId], permissions: credentialApiPermissions
116
+ }));
117
+ if (!samePermissions(issued.permissions))
118
+ throw new GitHubActivationError('credential-scope', 'GitHub minted a token with permissions different from the exact reviewed preflight scope.');
119
+ token = Buffer.from(text(issued.token, 'Installation credential'));
120
+ tokenExpiresAt = text(issued.expires_at, 'Installation expiry');
121
+ if (Date.parse(tokenExpiresAt) <= input.now.getTime() ||
122
+ Date.parse(tokenExpiresAt) > input.now.getTime() + 3_600_000) {
123
+ throw new GitHubActivationError('credential-expiry', 'Installation tokens must be current and expire within one hour.');
124
+ }
125
+ tokenClient = new GitHubActivationClient(makeTransport(token));
126
+ const selected = await tokenClient.list('/installation/repositories', 'repositories');
127
+ if (selected.length !== 1 || selected[0].id !== input.repositoryId || selected[0].full_name !== repository) {
128
+ throw new GitHubActivationError('credential-scope', 'The installation credential is not restricted to the exact selected repository.');
129
+ }
130
+ principal = `${text(installation.app_slug, 'App slug')}[bot]`;
131
+ }
132
+ else {
133
+ const raw = secret.toString('utf8').trim();
134
+ if (!/^github_pat_[A-Za-z0-9_]{40,250}$/u.test(raw)) {
135
+ throw new GitHubActivationError('credential-kind', 'The fallback must be a fine-grained PAT, never a classic PAT or an unrelated token.');
136
+ }
137
+ token = Buffer.from(raw);
138
+ tokenClient = new GitHubActivationClient(makeTransport(token));
139
+ const ownerResponse = expectStatus(await tokenClient.transport.request({ method: 'GET', path: '/user' }), [200], 'Verify enrolled PAT identity');
140
+ const actor = object(ownerResponse.data);
141
+ if (actor.login !== config.owner)
142
+ throw new GitHubActivationError('credential-owner', 'The enrolled PAT belongs to a different GitHub identity.');
143
+ principal = config.owner;
144
+ // The organization grant API is the authoritative scope/expiry reader, not user-entered metadata.
145
+ const grants = await input.client.list(`/orgs/${owner}/personal-access-tokens?owner[]=${config.owner}`);
146
+ const matching = grants.filter((grant) => grant.token_id === config.tokenId);
147
+ if (matching.length !== 1)
148
+ throw new GitHubActivationError('credential-metadata', 'An organization owner must make the approved fine-grained PAT grant metadata readable; its token ID is absent or ambiguous.');
149
+ pat = matching[0];
150
+ const permissions = object(pat.permissions);
151
+ const requiredPermissions = {
152
+ repository: { metadata: 'read' },
153
+ organization: { organization_hosted_runners: 'read', organization_network_configurations: 'read' },
154
+ other: {}
155
+ };
156
+ tokenExpiresAt = text(pat.token_expires_at, 'PAT expiry');
157
+ const headerExpiry = ownerResponse.headers['github-authentication-token-expiration'] ??
158
+ ownerResponse.headers['x-github-authentication-token-expiration'];
159
+ const createdAt = Date.parse(text(pat.created_at, 'PAT creation'));
160
+ if (pat.repository_selection !== 'subset' || pat.token_expired !== false || object(pat.owner).login !== config.owner ||
161
+ canonicalSha256(permissions) !== canonicalSha256(requiredPermissions) ||
162
+ pat.token_name !== `${name.toLowerCase()}-runner-preflight-read` ||
163
+ !headerExpiry || Date.parse(headerExpiry) !== Date.parse(tokenExpiresAt) ||
164
+ Date.parse(tokenExpiresAt) - createdAt !== 30 * 24 * 60 * 60 * 1000 ||
165
+ Date.parse(tokenExpiresAt) <= input.now.getTime() ||
166
+ grants.filter((grant) => object(grant.owner).login === config.owner && grant.token_expires_at === tokenExpiresAt).length !== 1) {
167
+ throw new GitHubActivationError('credential-scope', 'PAT grant/identity/unique provider expiry does not match the exact selected-repository, read-only, 30-day fallback policy.');
168
+ }
169
+ const selected = await input.client.list(`/orgs/${owner}/personal-access-tokens/${positiveId(pat.id, 'PAT grant ID')}/repositories`);
170
+ if (selected.length !== 1 || selected[0].id !== input.repositoryId || selected[0].full_name !== repository) {
171
+ throw new GitHubActivationError('credential-scope', 'PAT grant is not restricted to this single repository.');
172
+ }
173
+ }
174
+ const probeEndpoints = [
175
+ `/repos/${repository}`, `/orgs/${owner}/actions/hosted-runners`, `/orgs/${owner}/settings/network-configurations`
176
+ ];
177
+ const observed = await tokenClient.get(probeEndpoints[0]);
178
+ if (observed.id !== input.repositoryId || observed.full_name !== repository) {
179
+ throw new GitHubActivationError('credential-use', 'Actual credential use returned a different repository identity.');
180
+ }
181
+ await tokenClient.list(probeEndpoints[1], 'runners');
182
+ await tokenClient.list(probeEndpoints[2], 'network_configurations');
183
+ await input.assertAuthorized();
184
+ await input.secretWriter.write(repository, runnerPreflightSecretName, config.kind === 'github-app' ? secret : token);
185
+ const readback = await input.client.get(`/repos/${repository}/actions/secrets/${runnerPreflightSecretName}`);
186
+ const secretUpdatedAt = text(readback.updated_at, 'Secret update timestamp');
187
+ if (readback.name !== runnerPreflightSecretName || Date.parse(secretUpdatedAt) < input.now.getTime() - 1000) {
188
+ throw new GitHubActivationError('secret-readback', 'GitHub secret write has no independent current metadata readback. Enrollment remains unverified.');
189
+ }
190
+ const usage = {
191
+ repositoryId: input.repositoryId, repository, principal, installationId: config.kind === 'github-app' ? config.installationId : null,
192
+ probeEndpoints, permissionsDigest: canonicalSha256(credentialApiPermissions), secretUpdatedAt
193
+ };
194
+ const allowedWorkflows = [
195
+ { path: '.github/workflows/liftoff-bootstrap.yml', jobs: ['credential-use'] },
196
+ { path: '.github/workflows/liftoff-runner.yml', jobs: ['runner-preflight'] }
197
+ ];
198
+ const policy = config.kind === 'github-app' ? buildGitHubAppCredentialPolicy({
199
+ repository: repoIdentity, identity: input.identity, createdAt: input.now, allowedWorkflows,
200
+ installation: {
201
+ installationId: config.installationId, appSlug: text(installation.app_slug, 'App slug'),
202
+ approved: true, verified: true, selection: 'selected-repository', repositories: [repoIdentity],
203
+ permissions: { repository: ['metadata:read'], organization: ['hosted-runners:read', 'network-configurations:read'] },
204
+ permissionsVerifiedAt: input.now.toISOString(), readbackDigest: canonicalSha256(usage),
205
+ token: { canGenerate: true, ttlSeconds: Math.floor((Date.parse(tokenExpiresAt) - input.now.getTime()) / 1000) }
206
+ }
207
+ }) : buildFineGrainedPatCredentialPolicy({
208
+ repository: repoIdentity, identity: input.identity, createdAt: new Date(String(pat.created_at)), allowedWorkflows,
209
+ proof: { verifiedAt: input.now.toISOString(), readbackDigest: canonicalSha256(usage), readbackProvider: 'github-api', payloadFree: true }
210
+ });
211
+ return { policy, usage };
212
+ }
213
+ finally {
214
+ // Revoke only the ephemeral token minted here; never revoke the operator's pre-existing credential.
215
+ if (config.kind === 'github-app' && tokenClient) {
216
+ try {
217
+ await tokenClient.write('DELETE', '/installation/token');
218
+ }
219
+ catch { /* The token is bounded to one hour; no diagnostics may expose it. */ }
220
+ }
221
+ secret.fill(0);
222
+ jwt?.fill(0);
223
+ token?.fill(0);
224
+ }
225
+ }
226
+ //# sourceMappingURL=github-enrollment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-enrollment.js","sourceRoot":"","sources":["../../../src/adapters/credentials/github-enrollment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Readable } from 'node:stream';
2
+ export interface ProtectedCredentialChannel {
3
+ readonly kind: 'private-tty' | 'protected-stdin';
4
+ read(label: 'GitHub App private key' | 'fine-grained PAT'): Promise<Buffer>;
5
+ }
6
+ export declare function privateTtyCredentialChannel(): ProtectedCredentialChannel;
7
+ export declare function protectedStdinCredentialChannel(explicitSelection: boolean, input?: Readable, timeoutMs?: number): ProtectedCredentialChannel;
@@ -0,0 +1,68 @@
1
+ import { password } from '@inquirer/prompts';
2
+ import { GitHubActivationError } from '../github/activation-rest.js';
3
+ export function privateTtyCredentialChannel() {
4
+ return {
5
+ kind: 'private-tty',
6
+ async read(label) {
7
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
8
+ throw new GitHubActivationError('private-input-required', 'Credential enrollment requires a private TTY, or explicitly selected protected stdin. Never paste credentials into chat or argv.');
9
+ }
10
+ const value = await password({ message: `Private ${label} (never copied into output):`, mask: '' });
11
+ const bytes = Buffer.from(value, 'utf8');
12
+ if (!bytes.length || bytes.length > 32_768) {
13
+ bytes.fill(0);
14
+ throw new GitHubActivationError('invalid-credential', 'Protected credential input is empty or exceeds 32 KiB.');
15
+ }
16
+ return bytes;
17
+ }
18
+ };
19
+ }
20
+ export function protectedStdinCredentialChannel(explicitSelection, input = process.stdin, timeoutMs = 60_000) {
21
+ return {
22
+ kind: 'protected-stdin',
23
+ async read() {
24
+ if (!explicitSelection || input.isTTY) {
25
+ throw new GitHubActivationError('private-input-required', 'Protected stdin must be explicitly selected and supplied by an owner-controlled non-TTY secret channel.');
26
+ }
27
+ return new Promise((resolve, reject) => {
28
+ const chunks = [];
29
+ let size = 0;
30
+ const clean = () => {
31
+ clearTimeout(timer);
32
+ input.off('data', data);
33
+ input.off('end', end);
34
+ input.off('error', failure);
35
+ for (const bytes of chunks)
36
+ bytes.fill(0);
37
+ input.pause();
38
+ };
39
+ const failure = () => {
40
+ clean();
41
+ reject(new GitHubActivationError('protected-input-failed', 'Protected credential input was interrupted, empty, oversized, or timed out.'));
42
+ };
43
+ const data = (chunk) => {
44
+ const bytes = Buffer.from(chunk);
45
+ size += bytes.length;
46
+ chunks.push(bytes);
47
+ if (size > 32_768)
48
+ failure();
49
+ };
50
+ const end = () => {
51
+ if (!size) {
52
+ failure();
53
+ return;
54
+ }
55
+ const bytes = Buffer.concat(chunks);
56
+ clean();
57
+ resolve(bytes);
58
+ };
59
+ const timer = setTimeout(failure, timeoutMs);
60
+ input.on('data', data);
61
+ input.once('end', end);
62
+ input.once('error', failure);
63
+ input.resume();
64
+ });
65
+ }
66
+ };
67
+ }
68
+ //# sourceMappingURL=protected-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected-input.js","sourceRoot":"","sources":["../../../src/adapters/credentials/protected-input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type ExecutableObserver } from '../../domain/workstation/executables.js';
2
+ export declare const nativeExecutableObserver: ExecutableObserver;
@@ -0,0 +1,70 @@
1
+ import { constants } from 'node:fs';
2
+ import { access, open, realpath, stat } from 'node:fs/promises';
3
+ import { executableCandidates, hostPath, originFromPath, unavailable } from '../../domain/workstation/executables.js';
4
+ async function npmShim(candidate, packageId) {
5
+ const file = await open(candidate, 'r');
6
+ try {
7
+ const info = await file.stat();
8
+ if (!info.isFile() || info.size > 8_192)
9
+ return false;
10
+ const content = await file.readFile('utf8');
11
+ const normalized = content.replaceAll('\\', '/').toLowerCase();
12
+ return /^@echo off\b/i.test(content) &&
13
+ normalized.includes(`%dp0%/node_modules/${packageId.toLowerCase()}/`);
14
+ }
15
+ finally {
16
+ await file.close();
17
+ }
18
+ }
19
+ export const nativeExecutableObserver = {
20
+ async inspect(candidate, context) {
21
+ const nativePath = hostPath(context.platform);
22
+ const executable = nativePath.basename(candidate);
23
+ if (!nativePath.isAbsolute(candidate) || context.platform !== process.platform) {
24
+ return unavailable(executable, 'not-observable');
25
+ }
26
+ try {
27
+ const info = await stat(candidate);
28
+ if (!info.isFile())
29
+ return unavailable(executable, 'missing');
30
+ await access(candidate, context.platform === 'win32' ? constants.F_OK : constants.X_OK);
31
+ const target = await realpath(candidate);
32
+ const kind = /\.(?:cmd|bat)$/i.test(candidate) ? 'shim' : 'executable';
33
+ let origin = originFromPath(target, context);
34
+ if (origin === 'unknown' && kind === 'shim' && context.definition.packageIdentities?.npm) {
35
+ try {
36
+ if (await npmShim(candidate, context.definition.packageIdentities.npm))
37
+ origin = 'npm';
38
+ }
39
+ catch {
40
+ // A readable version probe does not imply permission to inspect its launcher.
41
+ }
42
+ }
43
+ return {
44
+ executable,
45
+ resolution: 'resolved',
46
+ resolvedPath: candidate,
47
+ realPath: target,
48
+ kind,
49
+ origin,
50
+ evidence: 'documented-location'
51
+ };
52
+ }
53
+ catch (error) {
54
+ const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
55
+ return unavailable(executable, code === 'ENOENT' || code === 'ENOTDIR' ? 'missing' : 'not-observable');
56
+ }
57
+ },
58
+ async resolve(executable, context) {
59
+ let unobservable = false;
60
+ for (const candidate of executableCandidates(executable, context)) {
61
+ const identity = await this.inspect(candidate, context);
62
+ if (identity.resolution === 'resolved')
63
+ return { ...identity, executable, evidence: 'path-search' };
64
+ if (identity.resolution === 'not-observable')
65
+ unobservable = true;
66
+ }
67
+ return unavailable(executable, unobservable ? 'not-observable' : 'missing');
68
+ }
69
+ };
70
+ //# sourceMappingURL=executables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executables.js","sourceRoot":"","sources":["../../../src/adapters/filesystem/executables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EACL,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,WAAW,EAGZ,MAAM,yCAAyC,CAAC;AAEjD,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,SAAiB;IACzD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK;YAAE,OAAO,KAAK,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/D,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;YAClC,UAAU,CAAC,QAAQ,CAAC,sBAAsB,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAC1E,CAAC;YAAS,CAAC;QACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAuB;IAC1D,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO;QAC9B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC/E,OAAO,WAAW,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBAAE,OAAO,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAC9D,MAAM,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACxF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;YACvE,IAAI,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC7C,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC;gBACzF,IAAI,CAAC;oBACH,IAAI,MAAM,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC;wBAAE,MAAM,GAAG,KAAK,CAAC;gBACzF,CAAC;gBAAC,MAAM,CAAC;oBACP,8EAA8E;gBAChF,CAAC;YACH,CAAC;YACD,OAAO;gBACL,UAAU;gBACV,UAAU,EAAE,UAAU;gBACtB,YAAY,EAAE,SAAS;gBACvB,QAAQ,EAAE,MAAM;gBAChB,IAAI;gBACJ,MAAM;gBACN,QAAQ,EAAE,qBAAqB;aAChC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5F,OAAO,WAAW,CAAC,UAAU,EAAE,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO;QAC/B,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,KAAK,MAAM,SAAS,IAAI,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;YAClE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACxD,IAAI,QAAQ,CAAC,UAAU,KAAK,UAAU;gBAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;YACpG,IAAI,QAAQ,CAAC,UAAU,KAAK,gBAAgB;gBAAE,YAAY,GAAG,IAAI,CAAC;QACpE,CAAC;QACD,OAAO,WAAW,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC;CACF,CAAC"}
@@ -48,3 +48,12 @@ export declare function loadUpdatePreviewReceipt(projectRoot: string, options?:
48
48
  export declare function issueUpdatePreviewReceipt(projectRoot: string, descriptors: readonly UpdatePreviewDescriptor[], options?: UpdatePreviewOptions): Promise<StoredUpdatePreview>;
49
49
  export declare function createUpdateTransactionApprovalStore(projectRoot: string, options?: UpdatePreviewOptions): UpdateTransactionApprovalStore;
50
50
  export declare function consumeUpdatePreviewReceipt(projectRoot: string, expectedReceipt: UpdatePreviewReceipt, options?: UpdatePreviewOptions): Promise<void>;
51
+ export interface ScopedUserLocalRecord {
52
+ projectRoot: string;
53
+ path: string;
54
+ value: unknown;
55
+ }
56
+ export declare function createScopedUserLocalRecordStore(projectRoot: string, namespace: 'governance-preview' | 'governance-approval' | 'workstation-remediation', options?: UpdatePreviewOptions): {
57
+ read(key: string): Promise<ScopedUserLocalRecord | null>;
58
+ write(key: string, value: unknown): Promise<ScopedUserLocalRecord>;
59
+ };
@@ -4,7 +4,6 @@ import { lstat, mkdir, open, realpath, rename, unlink } from 'node:fs/promises';
4
4
  import os from 'node:os';
5
5
  import path from 'node:path';
6
6
  import { createUpdatePreviewReceipt, normalizeUpdatePreviewProjectRoot, updatePreviewDirectoryParts, updatePreviewProjectKey, UpdatePreviewError, validateUpdatePreviewReceipt } from '../../application/update/preview.js';
7
- import { formatUpdateCommand } from '../../application/update/command-guidance.js';
8
7
  import { createUpdateTransactionApprovalSeal, updateTransactionApprovalKey, UpdateTransactionApprovalError, validateUpdateTransactionApprovalDigests, validateUpdateTransactionApprovalSeal } from '../../application/update/transaction-approval.js';
9
8
  import { canonicalJson } from '../../domain/governance/activation/canonical-json.js';
10
9
  import { errorCode, errorMessage } from './errors.js';
@@ -371,7 +370,7 @@ function parseReceipt(content, storage) {
371
370
  }
372
371
  function missing(storage) {
373
372
  const { location } = storage;
374
- throw new UpdatePreviewError('preview-missing', `No preview receipt exists for this project at ${location.receiptPath}. Run ${formatUpdateCommand(location.projectRoot, 'check', storage.platform)}.`);
373
+ throw new UpdatePreviewError('preview-missing', `No saved update preview was found for project ${location.projectRoot}. Expected receipt: ${location.receiptPath}.`, { projectRoot: location.projectRoot, platform: storage.platform });
375
374
  }
376
375
  export async function loadUpdatePreviewReceipt(projectRoot, options = {}) {
377
376
  const storage = await storageFor(projectRoot, options);
@@ -610,4 +609,48 @@ export async function consumeUpdatePreviewReceipt(projectRoot, expectedReceipt,
610
609
  await io('consume receipt', storage.location.receiptPath, () => storage.fs.removeFile(storage.location.receiptPath));
611
610
  });
612
611
  }
612
+ export function createScopedUserLocalRecordStore(projectRoot, namespace, options = {}) {
613
+ const location = async (key) => {
614
+ if (!/^[a-f0-9]{64}$/u.test(key))
615
+ throw storageError('A scoped metadata key must be a complete lowercase SHA-256 digest.');
616
+ const storage = await storageFor(projectRoot, options);
617
+ const filePath = storage.paths.join(storage.location.directory, `${namespace}-${storage.location.projectKey}-${key}.json`);
618
+ return { storage, filePath };
619
+ };
620
+ return {
621
+ read: async (key) => {
622
+ const { storage, filePath } = await location(key);
623
+ const snapshot = await directories(storage, false);
624
+ if (!snapshot)
625
+ return null;
626
+ const content = await readText(storage, filePath, snapshot);
627
+ if (content === undefined)
628
+ return null;
629
+ let value;
630
+ try {
631
+ value = JSON.parse(content);
632
+ }
633
+ catch (error) {
634
+ throw storageError(`Malformed ${namespace} record at ${filePath}.`, error);
635
+ }
636
+ return { projectRoot: storage.location.projectRoot, path: filePath, value };
637
+ },
638
+ write: async (key, value) => {
639
+ const { storage, filePath } = await location(key);
640
+ const content = canonicalJson(value);
641
+ const snapshot = await directories(storage, true);
642
+ if (!snapshot)
643
+ throw storageError(`Unable to create ${namespace} storage.`);
644
+ return withStoreLock(storage, snapshot, async () => {
645
+ const before = await readText(storage, filePath, snapshot);
646
+ if (before !== undefined && before !== content) {
647
+ throw storageError(`Refusing to replace different ${namespace} metadata at ${filePath}.`);
648
+ }
649
+ if (before === undefined)
650
+ await writeAtomicMetadata(storage, snapshot, filePath, content, undefined, true);
651
+ return { projectRoot: storage.location.projectRoot, path: filePath, value };
652
+ });
653
+ }
654
+ };
655
+ }
613
656
  //# sourceMappingURL=update-previews.js.map