@clossys/launcher 0.3.1 → 0.4.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 (285) hide show
  1. package/README.md +1324 -60
  2. package/contracts/conversation-contract.md +2 -2
  3. package/contracts/product-ci-workflow.yml +74 -0
  4. package/contracts/repository-inventory.json +53 -0
  5. package/dist/admission-fixture.d.ts +168 -0
  6. package/dist/admission-fixture.d.ts.map +1 -0
  7. package/dist/admission-fixture.js +453 -0
  8. package/dist/admission-fixture.js.map +1 -0
  9. package/dist/admission.d.ts +124 -0
  10. package/dist/admission.d.ts.map +1 -0
  11. package/dist/admission.js +799 -0
  12. package/dist/admission.js.map +1 -0
  13. package/dist/agents-guide.d.ts +9 -0
  14. package/dist/agents-guide.d.ts.map +1 -0
  15. package/dist/agents-guide.js +26 -0
  16. package/dist/agents-guide.js.map +1 -0
  17. package/dist/apply-command-options.check.d.ts +12 -0
  18. package/dist/apply-command-options.check.d.ts.map +1 -0
  19. package/dist/apply-command-options.check.js +20 -0
  20. package/dist/apply-command-options.check.js.map +1 -0
  21. package/dist/apply-plan-cli.d.ts +39 -1
  22. package/dist/apply-plan-cli.d.ts.map +1 -1
  23. package/dist/apply-plan-cli.js +432 -15
  24. package/dist/apply-plan-cli.js.map +1 -1
  25. package/dist/apply-plan.d.ts +46 -59
  26. package/dist/apply-plan.d.ts.map +1 -1
  27. package/dist/apply-plan.js +112 -97
  28. package/dist/apply-plan.js.map +1 -1
  29. package/dist/apply-step-fixture.d.ts +87 -0
  30. package/dist/apply-step-fixture.d.ts.map +1 -0
  31. package/dist/apply-step-fixture.js +199 -0
  32. package/dist/apply-step-fixture.js.map +1 -0
  33. package/dist/apply-store.d.ts +93 -0
  34. package/dist/apply-store.d.ts.map +1 -0
  35. package/dist/apply-store.js +625 -0
  36. package/dist/apply-store.js.map +1 -0
  37. package/dist/approval-sheet.d.ts +21 -0
  38. package/dist/approval-sheet.d.ts.map +1 -0
  39. package/dist/approval-sheet.js +157 -0
  40. package/dist/approval-sheet.js.map +1 -0
  41. package/dist/body-command.d.ts +42 -0
  42. package/dist/body-command.d.ts.map +1 -0
  43. package/dist/body-command.js +143 -0
  44. package/dist/body-command.js.map +1 -0
  45. package/dist/change-set-contract.d.ts +381 -0
  46. package/dist/change-set-contract.d.ts.map +1 -0
  47. package/dist/change-set-contract.js +738 -0
  48. package/dist/change-set-contract.js.map +1 -0
  49. package/dist/change-set-digest.d.ts +28 -0
  50. package/dist/change-set-digest.d.ts.map +1 -0
  51. package/dist/change-set-digest.js +65 -0
  52. package/dist/change-set-digest.js.map +1 -0
  53. package/dist/check-cli.d.ts.map +1 -1
  54. package/dist/check-cli.js +14 -3
  55. package/dist/check-cli.js.map +1 -1
  56. package/dist/cli.d.ts +17 -6
  57. package/dist/cli.d.ts.map +1 -1
  58. package/dist/cli.js +84 -23
  59. package/dist/cli.js.map +1 -1
  60. package/dist/core.d.ts +79 -22
  61. package/dist/core.d.ts.map +1 -1
  62. package/dist/core.js +843 -268
  63. package/dist/core.js.map +1 -1
  64. package/dist/dry-materialize.d.ts +63 -0
  65. package/dist/dry-materialize.d.ts.map +1 -0
  66. package/dist/dry-materialize.js +330 -0
  67. package/dist/dry-materialize.js.map +1 -0
  68. package/dist/generated/contract-schema.generated.d.ts +97 -0
  69. package/dist/generated/contract-schema.generated.d.ts.map +1 -0
  70. package/dist/generated/contract-schema.generated.js +496 -0
  71. package/dist/generated/contract-schema.generated.js.map +1 -0
  72. package/dist/generated/package-scope.generated.d.ts +6 -0
  73. package/dist/generated/package-scope.generated.d.ts.map +1 -0
  74. package/dist/generated/package-scope.generated.js +10 -0
  75. package/dist/generated/package-scope.generated.js.map +1 -0
  76. package/dist/generated/plan-contracts.generated.d.ts +3 -0
  77. package/dist/generated/plan-contracts.generated.d.ts.map +1 -0
  78. package/dist/generated/plan-contracts.generated.js +2840 -0
  79. package/dist/generated/plan-contracts.generated.js.map +1 -0
  80. package/dist/host.d.ts.map +1 -1
  81. package/dist/host.js +11 -0
  82. package/dist/host.js.map +1 -1
  83. package/dist/identity.d.ts +15 -0
  84. package/dist/identity.d.ts.map +1 -0
  85. package/dist/identity.js +48 -0
  86. package/dist/identity.js.map +1 -0
  87. package/dist/index.d.ts +34 -5
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +19 -2
  90. package/dist/index.js.map +1 -1
  91. package/dist/inventory-adoption.d.ts +24 -5
  92. package/dist/inventory-adoption.d.ts.map +1 -1
  93. package/dist/inventory-adoption.js +70 -25
  94. package/dist/inventory-adoption.js.map +1 -1
  95. package/dist/inventory-choice.d.ts +40 -0
  96. package/dist/inventory-choice.d.ts.map +1 -0
  97. package/dist/inventory-choice.js +156 -0
  98. package/dist/inventory-choice.js.map +1 -0
  99. package/dist/inventory-contract.d.ts +89 -0
  100. package/dist/inventory-contract.d.ts.map +1 -0
  101. package/dist/inventory-contract.js +121 -0
  102. package/dist/inventory-contract.js.map +1 -0
  103. package/dist/key-editor.d.ts +30 -0
  104. package/dist/key-editor.d.ts.map +1 -0
  105. package/dist/key-editor.js +445 -0
  106. package/dist/key-editor.js.map +1 -0
  107. package/dist/ledger-contract.d.ts +187 -0
  108. package/dist/ledger-contract.d.ts.map +1 -0
  109. package/dist/ledger-contract.js +532 -0
  110. package/dist/ledger-contract.js.map +1 -0
  111. package/dist/ledger-trust.d.ts +90 -0
  112. package/dist/ledger-trust.d.ts.map +1 -0
  113. package/dist/ledger-trust.js +198 -0
  114. package/dist/ledger-trust.js.map +1 -0
  115. package/dist/lockfile-invariants.d.ts +48 -0
  116. package/dist/lockfile-invariants.d.ts.map +1 -0
  117. package/dist/lockfile-invariants.js +375 -0
  118. package/dist/lockfile-invariants.js.map +1 -0
  119. package/dist/lockfile-readers.d.ts +72 -0
  120. package/dist/lockfile-readers.d.ts.map +1 -0
  121. package/dist/lockfile-readers.js +713 -0
  122. package/dist/lockfile-readers.js.map +1 -0
  123. package/dist/lockfile-regen.d.ts +106 -0
  124. package/dist/lockfile-regen.d.ts.map +1 -0
  125. package/dist/lockfile-regen.js +760 -0
  126. package/dist/lockfile-regen.js.map +1 -0
  127. package/dist/lockfile-tool-env.d.ts +29 -0
  128. package/dist/lockfile-tool-env.d.ts.map +1 -0
  129. package/dist/lockfile-tool-env.js +111 -0
  130. package/dist/lockfile-tool-env.js.map +1 -0
  131. package/dist/materialize.d.ts +113 -0
  132. package/dist/materialize.d.ts.map +1 -0
  133. package/dist/materialize.js +840 -0
  134. package/dist/materialize.js.map +1 -0
  135. package/dist/observe-repository.d.ts +90 -0
  136. package/dist/observe-repository.d.ts.map +1 -0
  137. package/dist/observe-repository.js +1367 -0
  138. package/dist/observe-repository.js.map +1 -0
  139. package/dist/plan-bundle-setup-fixture.d.ts +68 -0
  140. package/dist/plan-bundle-setup-fixture.d.ts.map +1 -0
  141. package/dist/plan-bundle-setup-fixture.js +167 -0
  142. package/dist/plan-bundle-setup-fixture.js.map +1 -0
  143. package/dist/plan-bundle.d.ts +250 -0
  144. package/dist/plan-bundle.d.ts.map +1 -0
  145. package/dist/plan-bundle.js +827 -0
  146. package/dist/plan-bundle.js.map +1 -0
  147. package/dist/plan-command.d.ts +29 -0
  148. package/dist/plan-command.d.ts.map +1 -0
  149. package/dist/plan-command.js +493 -0
  150. package/dist/plan-command.js.map +1 -0
  151. package/dist/plan-contract.d.ts +153 -0
  152. package/dist/plan-contract.d.ts.map +1 -0
  153. package/dist/plan-contract.js +61 -0
  154. package/dist/plan-contract.js.map +1 -0
  155. package/dist/plan-digest.d.ts +25 -0
  156. package/dist/plan-digest.d.ts.map +1 -0
  157. package/dist/plan-digest.js +106 -0
  158. package/dist/plan-digest.js.map +1 -0
  159. package/dist/plan-rules.d.ts +23 -0
  160. package/dist/plan-rules.d.ts.map +1 -0
  161. package/dist/plan-rules.js +177 -0
  162. package/dist/plan-rules.js.map +1 -0
  163. package/dist/planned-bundle.d.ts +20 -0
  164. package/dist/planned-bundle.d.ts.map +1 -0
  165. package/dist/planned-bundle.js +191 -0
  166. package/dist/planned-bundle.js.map +1 -0
  167. package/dist/product-repository.d.ts +4 -0
  168. package/dist/product-repository.d.ts.map +1 -1
  169. package/dist/product-repository.js +9 -1
  170. package/dist/product-repository.js.map +1 -1
  171. package/dist/provenance-gate.d.ts +48 -0
  172. package/dist/provenance-gate.d.ts.map +1 -0
  173. package/dist/provenance-gate.js +324 -0
  174. package/dist/provenance-gate.js.map +1 -0
  175. package/dist/pull-request-body.d.ts +45 -0
  176. package/dist/pull-request-body.d.ts.map +1 -0
  177. package/dist/pull-request-body.js +232 -0
  178. package/dist/pull-request-body.js.map +1 -0
  179. package/dist/registry-snapshot.d.ts +141 -0
  180. package/dist/registry-snapshot.d.ts.map +1 -0
  181. package/dist/registry-snapshot.js +483 -0
  182. package/dist/registry-snapshot.js.map +1 -0
  183. package/dist/release-age-edit.d.ts +52 -0
  184. package/dist/release-age-edit.d.ts.map +1 -0
  185. package/dist/release-age-edit.js +413 -0
  186. package/dist/release-age-edit.js.map +1 -0
  187. package/dist/root-entries.d.ts +36 -0
  188. package/dist/root-entries.d.ts.map +1 -0
  189. package/dist/root-entries.js +80 -0
  190. package/dist/root-entries.js.map +1 -0
  191. package/dist/setup-template-scripts.d.ts +34 -0
  192. package/dist/setup-template-scripts.d.ts.map +1 -0
  193. package/dist/setup-template-scripts.js +557 -0
  194. package/dist/setup-template-scripts.js.map +1 -0
  195. package/dist/setup-templates.d.ts +54 -0
  196. package/dist/setup-templates.d.ts.map +1 -0
  197. package/dist/setup-templates.js +427 -0
  198. package/dist/setup-templates.js.map +1 -0
  199. package/dist/skills.d.ts +34 -1
  200. package/dist/skills.d.ts.map +1 -1
  201. package/dist/skills.js +129 -17
  202. package/dist/skills.js.map +1 -1
  203. package/dist/status.d.ts +63 -0
  204. package/dist/status.d.ts.map +1 -0
  205. package/dist/status.js +539 -0
  206. package/dist/status.js.map +1 -0
  207. package/dist/types.d.ts +151 -13
  208. package/dist/types.d.ts.map +1 -1
  209. package/package.json +4 -4
  210. package/skeleton/README.md +14 -9
  211. package/skeleton/package.json +2 -1
  212. package/skill/SKILL.md +23 -7
  213. package/skill-catalogue/advisor/SKILL.md +59 -6
  214. package/skill-catalogue/architect/SKILL.md +2 -2
  215. package/skill-catalogue/bouncer/SKILL.md +2 -2
  216. package/skill-catalogue/builder/SKILL.md +2 -2
  217. package/skill-catalogue/butler/SKILL.md +2 -2
  218. package/skill-catalogue/controller/SKILL.md +2 -2
  219. package/skill-catalogue/customer/SKILL.md +2 -2
  220. package/skill-catalogue/designer/SKILL.md +4 -2
  221. package/skill-catalogue/giver/SKILL.md +2 -2
  222. package/skill-catalogue/influencer/SKILL.md +2 -2
  223. package/skill-catalogue/inspector/SKILL.md +2 -2
  224. package/skill-catalogue/integrator/SKILL.md +2 -2
  225. package/skill-catalogue/keeper/SKILL.md +2 -2
  226. package/skill-catalogue/launcher/SKILL.md +23 -7
  227. package/skill-catalogue/locksmith/SKILL.md +2 -2
  228. package/skill-catalogue/messenger/SKILL.md +2 -2
  229. package/skill-catalogue/observer/SKILL.md +2 -2
  230. package/skill-catalogue/publisher/SKILL.md +2 -2
  231. package/skill-catalogue/starter/SKILL.md +3 -2
  232. package/skill-catalogue/strategist/SKILL.md +12 -4
  233. package/skill-catalogue/writer/SKILL.md +2 -2
  234. package/src/admission-fixture.ts +572 -0
  235. package/src/admission.ts +816 -0
  236. package/src/agents-guide.ts +29 -0
  237. package/src/apply-command-options.check.ts +27 -0
  238. package/src/apply-plan-cli.ts +454 -14
  239. package/src/apply-plan.ts +112 -124
  240. package/src/apply-step-fixture.ts +236 -0
  241. package/src/apply-store.ts +584 -0
  242. package/src/approval-sheet.ts +164 -0
  243. package/src/body-command.ts +162 -0
  244. package/src/change-set-contract.ts +937 -0
  245. package/src/change-set-digest.ts +70 -0
  246. package/src/check-cli.ts +14 -3
  247. package/src/cli.ts +90 -22
  248. package/src/core.ts +973 -275
  249. package/src/dry-materialize.ts +353 -0
  250. package/src/generated/contract-schema.generated.ts +520 -0
  251. package/src/generated/package-scope.generated.ts +10 -0
  252. package/src/generated/plan-contracts.generated.ts +2840 -0
  253. package/src/host.ts +10 -0
  254. package/src/identity.ts +51 -0
  255. package/src/index.ts +72 -3
  256. package/src/inventory-adoption.ts +107 -29
  257. package/src/inventory-choice.ts +172 -0
  258. package/src/inventory-contract.ts +166 -0
  259. package/src/key-editor.ts +446 -0
  260. package/src/ledger-contract.ts +637 -0
  261. package/src/ledger-trust.ts +267 -0
  262. package/src/lockfile-invariants.ts +421 -0
  263. package/src/lockfile-readers.ts +749 -0
  264. package/src/lockfile-regen.ts +851 -0
  265. package/src/lockfile-tool-env.ts +131 -0
  266. package/src/materialize.ts +886 -0
  267. package/src/observe-repository.ts +1365 -0
  268. package/src/plan-bundle-setup-fixture.ts +200 -0
  269. package/src/plan-bundle.ts +964 -0
  270. package/src/plan-command.ts +509 -0
  271. package/src/plan-contract.ts +179 -0
  272. package/src/plan-digest.ts +102 -0
  273. package/src/plan-rules.ts +188 -0
  274. package/src/planned-bundle.ts +211 -0
  275. package/src/product-repository.ts +10 -1
  276. package/src/provenance-gate.ts +352 -0
  277. package/src/pull-request-body.ts +261 -0
  278. package/src/registry-snapshot.ts +534 -0
  279. package/src/release-age-edit.ts +430 -0
  280. package/src/root-entries.ts +81 -0
  281. package/src/setup-template-scripts.ts +571 -0
  282. package/src/setup-templates.ts +471 -0
  283. package/src/skills.ts +161 -18
  284. package/src/status.ts +557 -0
  285. package/src/types.ts +148 -13
@@ -1 +1 @@
1
- {"version":3,"file":"apply-plan.d.ts","sourceRoot":"","sources":["../src/apply-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply-plan.d.ts","sourceRoot":"","sources":["../src/apply-plan.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAgB,MAAM,oBAAoB,CAAC;AAErF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAClF,YAAY,EACV,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAC7K,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,GACxD,MAAM,oBAAoB,CAAC;AAoB5B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAOhE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAGzD;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACjF;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,aAAa,EACnB,mBAAmB,EAAE,MAAM,EAC3B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,MAAM,GACnB,gBAAgB,CA2BlB"}
@@ -1,129 +1,144 @@
1
1
  // Apply an approved plan (#1178): writes clossys/brief.json into a staffed
2
- // repository from the exact EngagementBrief shape and plan.json contract
3
- // recorded on issue #1175 ("Plan file contract", posted 2026-09-22).
2
+ // repository once clossys/advisor/plan.json is approved, both validated
3
+ // against the shared plan and brief contracts (#1175, #1475).
4
4
  //
5
5
  // SCOPE OF THIS MODULE (see the wave-2 PR body for the full explanation):
6
6
  // this lands the mechanical, auditable core the landed contract fully
7
7
  // specifies -- reading clossys/advisor/plan.json, confirming it is
8
8
  // approved, validating an EngagementBrief, and writing clossys/brief.json
9
- // byte-identically. Multi-repository orchestration (branch creation, exact
10
- // package installs, Starter's caller workflow, opening one pull request
11
- // per repository) is deferred: the landed contract does not yet specify
12
- // how a plan's approved roles map to inventory repository ids or to
13
- // install/remove/relocate work items, and building that mapping now would
14
- // mean inventing an interface Advisor's still-open PR (#1193) might define
15
- // differently.
9
+ // byte-identically. The plan contract now says which roles work in which
10
+ // inventory repository (`staffing`) and which exact package acts are
11
+ // authorized (`packages`), and approvedSubject() below says what an
12
+ // approval binds (#1178). Multi-repository orchestration (computing each
13
+ // repository's change, branch creation, exact package installs, Starter's
14
+ // caller workflow, opening one pull request per repository) is not built
15
+ // yet, and this module does not act on those fields.
16
16
  //
17
17
  // clossys/brief.json's shape is NOT re-derived here -- @clossys/advisor's
18
- // EngagementBrief export (landing in #1193) is the one owner of that
19
- // computation. This module receives an already-computed brief (as a file
20
- // path today; a direct call once #1193 lands and a caller can import the
21
- // package) and only validates its shape and writes it, exactly the split
22
- // #1187's governing principle draws between package-owned definition and
23
- // judgment versus Launcher's deterministic mechanics.
24
- function isRecord(value) {
25
- return typeof value === "object" && value !== null && !Array.isArray(value);
26
- }
27
- function nonEmptyString(value) {
28
- return typeof value === "string" && value.trim() !== "";
29
- }
30
- function stringArray(value) {
31
- return Array.isArray(value) && value.every((item) => typeof item === "string");
32
- }
33
- /** Validates an EngagementBrief's shape exactly against the #1175 contract. Never mutates, never re-derives content. */
34
- export function validateEngagementBrief(value) {
35
- if (!isRecord(value))
36
- return { valid: false, reason: "brief must be an object" };
37
- if (value.schemaVersion !== 1)
38
- return { valid: false, reason: "brief.schemaVersion must be 1" };
39
- if (!nonEmptyString(value.problem))
40
- return { valid: false, reason: "brief.problem must be a non-empty string" };
41
- if (!Array.isArray(value.roles) || value.roles.length === 0)
42
- return { valid: false, reason: "brief.roles must be a non-empty array" };
43
- for (const [index, role] of value.roles.entries()) {
44
- if (!isRecord(role))
45
- return { valid: false, reason: `brief.roles[${index}] must be an object` };
46
- if (!nonEmptyString(role.role))
47
- return { valid: false, reason: `brief.roles[${index}].role must be a non-empty string` };
48
- if (!nonEmptyString(role.why))
49
- return { valid: false, reason: `brief.roles[${index}].why must be a non-empty string` };
50
- if (!isRecord(role.goal) || !nonEmptyString(role.goal.metric) || (role.goal.direction !== "increase" && role.goal.direction !== "decrease")) {
51
- return { valid: false, reason: `brief.roles[${index}].goal must have a metric and a direction of increase or decrease` };
52
- }
53
- if (!stringArray(role.inputsFrom))
54
- return { valid: false, reason: `brief.roles[${index}].inputsFrom must be a string array` };
55
- if (!stringArray(role.outputsTo))
56
- return { valid: false, reason: `brief.roles[${index}].outputsTo must be a string array` };
57
- }
58
- if (!stringArray(value.sequence) || value.sequence.length === 0)
59
- return { valid: false, reason: "brief.sequence must be a non-empty string array" };
60
- if (!stringArray(value.deliverables))
61
- return { valid: false, reason: "brief.deliverables must be a string array" };
62
- return { valid: true };
18
+ // toEngagementBrief() is the one owner of that computation. This module
19
+ // receives an already-computed brief and only validates it and writes it,
20
+ // exactly the split #1187's governing principle draws between
21
+ // package-owned definition and judgment versus Launcher's deterministic
22
+ // mechanics.
23
+ //
24
+ // VALIDATION (issue #1475): see plan-contract.ts. There is no second,
25
+ // hand-written shape check here to drift from Advisor's: a plan or brief
26
+ // Advisor accepts, Launcher accepts, and every object in them is closed, so
27
+ // an unknown field is refused. This package still has no runtime
28
+ // dependency on @clossys/advisor.
29
+ import { validateAdvisorPlan, validateEngagementBrief } from "./plan-contract.js";
30
+ import { planDigest } from "./plan-digest.js";
31
+ export { validateAdvisorPlan, validateEngagementBrief } from "./plan-contract.js";
32
+ /**
33
+ * The decisions made at the latest instant, by `at` -- never by array
34
+ * position -- or null when there are none, or when any decision's `at` does
35
+ * not parse to a finite time (the plan contract already refuses one; this
36
+ * does not rely on that), because then time cannot say which is latest.
37
+ */
38
+ function latestDecisions(plan) {
39
+ if (plan.decisions.length === 0)
40
+ return null;
41
+ const times = plan.decisions.map((decision) => Date.parse(decision.at));
42
+ if (!times.every(Number.isFinite))
43
+ return null;
44
+ // A reduce, not Math.max(...times): spreading a very long list into
45
+ // arguments throws a RangeError.
46
+ const latest = times.reduce((highest, time) => (time > highest ? time : highest), Number.NEGATIVE_INFINITY);
47
+ return plan.decisions.filter((_, index) => times[index] === latest);
63
48
  }
64
- const BLOCKER_KINDS = new Set(["missing-input", "missing-authority", "failing-evidence", "unavailable-environment", "contradiction"]);
65
- /** Validates an AdvisorPlan's shape exactly against the #1175 contract. */
66
- export function validateAdvisorPlan(value) {
67
- if (!isRecord(value))
68
- return { valid: false, reason: "plan must be an object" };
69
- if (value.schemaVersion !== 1)
70
- return { valid: false, reason: "plan.schemaVersion must be 1" };
71
- if (!nonEmptyString(value.asOf))
72
- return { valid: false, reason: "plan.asOf must be a non-empty string" };
73
- if (!isRecord(value.mandate) || !nonEmptyString(value.mandate.problem) || !nonEmptyString(value.mandate.primaryProblemId) || !stringArray(value.mandate.roles)) {
74
- return { valid: false, reason: "plan.mandate must have problem, primaryProblemId, and a roles string array" };
75
- }
76
- if (!stringArray(value.whereWeAre))
77
- return { valid: false, reason: "plan.whereWeAre must be a string array" };
78
- if (value.recommendedNext !== null) {
79
- if (!isRecord(value.recommendedNext) || !nonEmptyString(value.recommendedNext.action) || !nonEmptyString(value.recommendedNext.owner) || !nonEmptyString(value.recommendedNext.due)) {
80
- return { valid: false, reason: "plan.recommendedNext must be null or have action, owner, and due" };
81
- }
82
- }
83
- if (!Array.isArray(value.decisions))
84
- return { valid: false, reason: "plan.decisions must be an array" };
85
- for (const [index, decision] of value.decisions.entries()) {
86
- if (!isRecord(decision) || !nonEmptyString(decision.at) || !nonEmptyString(decision.recommended) || !nonEmptyString(decision.chosen) || !nonEmptyString(decision.by)) {
87
- return { valid: false, reason: `plan.decisions[${index}] must have at, recommended, chosen, and by` };
88
- }
89
- }
90
- if (!Array.isArray(value.blockers))
91
- return { valid: false, reason: "plan.blockers must be an array" };
92
- for (const [index, blocker] of value.blockers.entries()) {
93
- if (!isRecord(blocker) || !BLOCKER_KINDS.has(blocker.kind) || !nonEmptyString(blocker.description) || !nonEmptyString(blocker.owner)) {
94
- return { valid: false, reason: `plan.blockers[${index}] must have a valid kind, description, and owner` };
95
- }
96
- }
97
- return { valid: true };
49
+ const SUBJECT_DIGEST = /^sha256:[0-9a-f]{64}$/;
50
+ /**
51
+ * What an approval binds (#1178): the `subjectDigest` of the plan's latest
52
+ * decision, by `at`, when that decision has chosen "approved" -- the digest of
53
+ * the exact change the approver was shown. Otherwise null, and null binds
54
+ * nothing. Fails closed:
55
+ *
56
+ * - a plan that does not validate against the plan contract, rules
57
+ * included: null. It checks this itself rather than trusting its caller,
58
+ * because on an unchecked plan a time with no offset parses as local time,
59
+ * so the machine's time zone could decide which decision is latest;
60
+ * - no decisions, or any decision time that does not parse: null;
61
+ * - a latest decision that is not "approved": null;
62
+ * - an approval with no `subjectDigest`, or one that is not a sha256 digest:
63
+ * null -- an approval that names no bytes approves no bytes;
64
+ * - several decisions at the latest instant: their subject only when every
65
+ * one of them is "approved" with the same `subjectDigest`, else null.
66
+ *
67
+ * It says what was approved, not whether that is what is about to be applied:
68
+ * the caller recomputes the digest of the change it holds and refuses unless
69
+ * the two are equal.
70
+ */
71
+ export function approvedSubject(plan) {
72
+ if (!validateAdvisorPlan(plan).valid)
73
+ return null;
74
+ const latest = latestDecisions(plan);
75
+ if (latest === null || !latest.every((decision) => decision.chosen === "approved"))
76
+ return null;
77
+ const subject = latest[0].subjectDigest;
78
+ if (typeof subject !== "string" || !SUBJECT_DIGEST.test(subject))
79
+ return null;
80
+ return latest.every((decision) => decision.subjectDigest === subject) ? subject : null;
98
81
  }
99
82
  /**
100
83
  * The plan is approved when its most recent decision (by `at`) records
101
84
  * chosen === "approved". No decisions, or a most-recent decision that
102
85
  * isn't "approved", is not approved -- this never assumes approval from
103
- * absence.
86
+ * absence. Fails closed on anything that would let array order decide
87
+ * instead of time: a decision whose `at` does not parse to a finite time
88
+ * (the plan contract already refuses one; this does not rely on that), or
89
+ * two decisions at the same latest instant that do not all say "approved".
90
+ *
91
+ * It binds no bytes (#1178): it does not look at `subjectDigest`, so it is
92
+ * true for an approval that names no change at all. It says only that the
93
+ * latest decision is an approval. Anything that applies a plan must use
94
+ * `approvedSubject()` instead, and compare the subject it returns with the
95
+ * digest of the change it holds. The one stated exception is the legacy
96
+ * brief-only path, `applyEngagementBrief()`, which predates the binding.
104
97
  */
105
98
  export function isPlanApproved(plan) {
106
- if (plan.decisions.length === 0)
107
- return false;
108
- const mostRecent = [...plan.decisions].sort((left, right) => Date.parse(left.at) - Date.parse(right.at)).at(-1);
109
- return mostRecent?.chosen === "approved";
99
+ const latest = latestDecisions(plan);
100
+ return latest !== null && latest.every((decision) => decision.chosen === "approved");
110
101
  }
111
102
  /**
112
103
  * Writes clossys/brief.json into `repositoryDirectory`, byte-identically
113
104
  * from the validated brief -- never re-authors its prose. Refuses (does
114
- * not write) unless both the plan is approved and the brief validates.
105
+ * not write) unless the plan validates and is approved and the brief,
106
+ * including its context snapshot, validates. Reports the canonical digest
107
+ * of the plan it applied.
108
+ *
109
+ * LEGACY (#1178): this path predates the approval binding. It accepts an
110
+ * approval whether or not it carries a `subjectDigest` and checks no
111
+ * binding (it uses `isPlanApproved()`), exactly as before; it is kept
112
+ * working, not extended. Anything that must know what an approval binds uses
113
+ * `approvedSubject()`.
115
114
  */
116
115
  export function applyEngagementBrief(host, repositoryDirectory, plan, brief, briefRelPath) {
116
+ const planValidation = validateAdvisorPlan(plan);
117
+ if (!planValidation.valid) {
118
+ return { state: "refused", reason: `plan does not validate: ${planValidation.reason}` };
119
+ }
117
120
  if (!isPlanApproved(plan)) {
118
- return { state: "refused", reason: "the plan's most recent decision is not \"approved\"" };
121
+ return { state: "refused", reason: "the plan's most recent decision is not \"approved\", or decisions made at that same time disagree" };
119
122
  }
120
123
  const validation = validateEngagementBrief(brief);
121
124
  if (!validation.valid) {
122
125
  return { state: "refused", reason: `brief does not validate: ${validation.reason}` };
123
126
  }
127
+ // Everything that can refuse runs before the first write, so a refusal
128
+ // never leaves a brief behind. A plan that validates always has a digest
129
+ // (the contract refuses what canonical JSON cannot carry); this catch is
130
+ // the backstop that keeps that a refusal rather than a throw after writing.
131
+ let digest;
132
+ try {
133
+ digest = planDigest(plan);
134
+ }
135
+ catch (cause) {
136
+ return { state: "refused", reason: `plan has no canonical digest: ${cause instanceof Error ? cause.message : String(cause)}` };
137
+ }
138
+ const contents = `${JSON.stringify(brief, null, 2)}\n`;
124
139
  const path = `${repositoryDirectory}/${briefRelPath}`;
125
140
  host.mkdirp(path.slice(0, path.lastIndexOf("/")));
126
- host.writeText(path, `${JSON.stringify(brief, null, 2)}\n`);
127
- return { state: "applied", path };
141
+ host.writeText(path, contents);
142
+ return { state: "applied", path, planDigest: digest };
128
143
  }
129
144
  //# sourceMappingURL=apply-plan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apply-plan.js","sourceRoot":"","sources":["../src/apply-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply-plan.js","sourceRoot":"","sources":["../src/apply-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import { reseal } from "./admission-fixture.js";
2
+ import type { HubOptions, World, WorldOptions } from "./admission-fixture.js";
3
+ import type { ApplyBundle, RepositoryChangeSet } from "./change-set-contract.js";
4
+ import type { LockfileSpawn } from "./lockfile-regen.js";
5
+ import type { AdvisorPlan } from "./plan-contract.js";
6
+ export { reseal };
7
+ type Loose = Record<string, any>;
8
+ export interface MaterializedFixtureOptions {
9
+ /** Overrides for the hub: options, or a function of what the fixture built (its plan, its approved bundle and its set). */
10
+ readonly hub?: Partial<HubOptions> | ((built: {
11
+ plan: AdvisorPlan;
12
+ bundle: ApplyBundle;
13
+ set: RepositoryChangeSet;
14
+ }) => Partial<HubOptions>);
15
+ /** Store the set, with its whole-file texts, in the hub's change-set store, where the command line finds it. Default false. */
16
+ readonly storeSet?: boolean;
17
+ }
18
+ /**
19
+ * A setup change set whose whole-file bytes are known, with the pin already
20
+ * satisfied and no lockfile to regenerate, checked out from a local clone, and
21
+ * a hub that approved it: a git repository whose HEAD holds a plan (its latest
22
+ * decision approves the bundle that holds the set) and an execution
23
+ * authorization, with the bundle stored and the hub's readiness executable
24
+ * installed. `binding` is the binding admission is expected to compute; it is
25
+ * never an input to materialize or verify.
26
+ */
27
+ export declare function buildMaterializedFixture(roots: string[], options?: MaterializedFixtureOptions): {
28
+ clone: string;
29
+ hub: string;
30
+ set: RepositoryChangeSet;
31
+ texts: Record<string, string>;
32
+ binding: {
33
+ kind: "approved";
34
+ subjectDigest: string;
35
+ };
36
+ planPackages: {
37
+ planItem: string;
38
+ act: "install" | "pin-starter";
39
+ name: string;
40
+ version: string;
41
+ integrity: string;
42
+ placement: "dependencies" | "devDependencies";
43
+ }[];
44
+ plan: AdvisorPlan;
45
+ bundle: ApplyBundle;
46
+ origin: string;
47
+ };
48
+ export interface AdmittedFixtureOptions {
49
+ readonly world?: WorldOptions;
50
+ readonly hub?: Partial<HubOptions> | ((world: World) => Partial<HubOptions>);
51
+ /** How the setup set reached the default branch. Default `squash`: no ancestor of the setup branch. */
52
+ readonly mergeStyle?: "direct" | "squash";
53
+ /** Edits the base tree before it is committed. */
54
+ readonly tree?: (tree: World["tree"]) => void;
55
+ /** Store the apply set in the hub too. Default false. */
56
+ readonly storeApplySet?: boolean;
57
+ }
58
+ /**
59
+ * The two phases of one plan. The setup set was approved (the plan's latest
60
+ * decision approves the bundle that holds it), materialized and merged into
61
+ * the clone's default branch (by squash by default), and the apply set was
62
+ * then computed against the merged base and is held by a later run's bundle,
63
+ * which the hub stores. `spawn` stands in for the package manager: it
64
+ * regenerates the lockfile the apply set's installs write.
65
+ */
66
+ export declare function buildAdmittedFixture(roots: string[], options?: AdmittedFixtureOptions): {
67
+ world: World;
68
+ hub: string;
69
+ clone: string;
70
+ baseCommit: string;
71
+ sideTip: string | null;
72
+ set: RepositoryChangeSet;
73
+ setup: RepositoryChangeSet;
74
+ texts: Record<string, string>;
75
+ spawn: LockfileSpawn;
76
+ };
77
+ /**
78
+ * Everything a refused materialize must leave alone: the clone's refs, HEAD,
79
+ * index, status and every file outside .git, and every file the hub keeps
80
+ * under clossys/.state. Two snapshots are equal only when nothing moved.
81
+ */
82
+ export declare function writeSnapshot(clone: string, hub: string): string;
83
+ /** Whether the clone holds a local branch of this name. */
84
+ export declare function branchExists(clone: string, branch: string): boolean;
85
+ /** The ledger a clone holds at clossys/.state/installed.json, parsed, or null when it holds none. */
86
+ export declare function readCloneLedger(clone: string): Loose | null;
87
+ //# sourceMappingURL=apply-step-fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-step-fixture.d.ts","sourceRoot":"","sources":["../src/apply-step-fixture.ts"],"names":[],"mappings":"AAKA,OAAO,EASL,MAAM,EAEP,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,CAAC;AAKlB,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAsBjC,MAAM,WAAW,0BAA0B;IACzC,2HAA2H;IAC3H,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,WAAW,CAAC;QAAC,GAAG,EAAE,mBAAmB,CAAA;KAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5I,+HAA+H;IAC/H,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,0BAA+B;;;;;;;;;;;;;;;;;;;;EAuDjG;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7E,uGAAuG;IACvG,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1C,kDAAkD;IAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAC9C,yDAAyD;IACzD,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,sBAA2B;;;;;;;;;;EAsCzF;AAmBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAchE;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOnE;AAED,qGAAqG;AACrG,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAG3D"}
@@ -0,0 +1,199 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, realpathSync, writeFileSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { dirname, join } from "node:path";
6
+ import { SITE_ID, approvedPlan, basePlan, buildWorld, bundleOf, committedPlanPackages, hubRepo, lockfileText, reseal, siteRepo, } from "./admission-fixture.js";
7
+ import { contentDigest, discoveryLinkRole, discoveryLinkTarget } from "./change-set-contract.js";
8
+ import { planDigest } from "./plan-digest.js";
9
+ export { reseal };
10
+ const REPO = new URL("../../../", import.meta.url);
11
+ const read = (path) => readFileSync(new URL(path, REPO), "utf8");
12
+ const gitEnv = {
13
+ ...process.env,
14
+ PATH: process.env.PATH ?? "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
15
+ GIT_CONFIG_GLOBAL: "/dev/null",
16
+ GIT_CONFIG_NOSYSTEM: "1",
17
+ GIT_AUTHOR_NAME: "Example Author",
18
+ GIT_AUTHOR_EMAIL: "author@example.com",
19
+ GIT_COMMITTER_NAME: "Example Author",
20
+ GIT_COMMITTER_EMAIL: "author@example.com",
21
+ };
22
+ function git(cwd, ...args) {
23
+ return execFileSync("git", ["-c", "commit.gpgsign=false", "-c", "core.hooksPath=/dev/null", ...args], {
24
+ cwd,
25
+ env: gitEnv,
26
+ encoding: "utf8",
27
+ stdio: ["ignore", "pipe", "pipe"],
28
+ });
29
+ }
30
+ /**
31
+ * A setup change set whose whole-file bytes are known, with the pin already
32
+ * satisfied and no lockfile to regenerate, checked out from a local clone, and
33
+ * a hub that approved it: a git repository whose HEAD holds a plan (its latest
34
+ * decision approves the bundle that holds the set) and an execution
35
+ * authorization, with the bundle stored and the hub's readiness executable
36
+ * installed. `binding` is the binding admission is expected to compute; it is
37
+ * never an input to materialize or verify.
38
+ */
39
+ export function buildMaterializedFixture(roots, options = {}) {
40
+ const parent = mkdtempSync(join(tmpdir(), "launcher-apply-step-"));
41
+ roots.push(parent);
42
+ const origin = join(parent, "origin.git");
43
+ const clone = join(parent, "site");
44
+ mkdirSync(clone, { recursive: true });
45
+ git(clone, "init", "-b", "main");
46
+ git(clone, "config", "core.autocrlf", "false");
47
+ writeFileSync(join(clone, "README.md"), "# Site\n");
48
+ git(clone, "add", "README.md");
49
+ git(clone, "commit", "-m", "init");
50
+ execFileSync("git", ["init", "--bare", origin], { env: gitEnv, stdio: "ignore" });
51
+ git(clone, "remote", "add", "origin", origin);
52
+ git(clone, "push", "-u", "origin", "HEAD");
53
+ const baseCommit = git(clone, "rev-parse", "HEAD").trim();
54
+ const corpus = JSON.parse(read("docs/contracts/apply-change-set-digest.fixture.json"));
55
+ const set = structuredClone(corpus.changeSets.find((entry) => entry.name === "setup-site").changeSet);
56
+ set.repository.baseCommit = baseCommit;
57
+ set.keys = [];
58
+ set.deferred = [];
59
+ set.files = set.files.filter((file) => file.path !== "package-lock.json");
60
+ for (const item of set.items) {
61
+ if (item.act === "pin-starter" || item.act === "install")
62
+ item.satisfiedInBase = true;
63
+ }
64
+ const plan0 = basePlan();
65
+ set.planDigest = planDigest(plan0);
66
+ const texts = {};
67
+ for (const file of set.files) {
68
+ if (file.derived === true)
69
+ continue;
70
+ if (file.mode === "120000") {
71
+ const role = discoveryLinkRole(file.path);
72
+ const target = discoveryLinkTarget(role);
73
+ texts[file.path] = target;
74
+ file.before = null;
75
+ file.after = contentDigest(target);
76
+ }
77
+ else {
78
+ const text = `fixture ${file.path}\n`;
79
+ texts[file.path] = text;
80
+ file.before = null;
81
+ file.after = contentDigest(text);
82
+ }
83
+ }
84
+ const sealed = reseal(set);
85
+ const bundle = bundleOf(plan0, [{ id: SITE_ID, set: sealed }]);
86
+ const built = { ...sealed, bundle: bundle.bundleDigest };
87
+ const plan = approvedPlan(bundle.bundleDigest, plan0);
88
+ const override = typeof options.hub === "function" ? options.hub({ plan, bundle, set: built }) : (options.hub ?? {});
89
+ // What the planner stores carries the whole-file texts, so the command line can write from the store alone.
90
+ const stored = { ...built, texts: Object.entries(texts).map(([path, text]) => ({ path, text })).sort((left, right) => left.path.localeCompare(right.path)) };
91
+ const hub = hubRepo(roots, { plans: [plan], sets: options.storeSet === true ? [stored] : [], bundles: [bundle], ...override });
92
+ const binding = { kind: "approved", subjectDigest: bundle.bundleDigest };
93
+ return { clone: realpathSync(clone), hub: hub.hub, set: built, texts, binding, planPackages: committedPlanPackages(plan, SITE_ID), plan, bundle, origin };
94
+ }
95
+ /**
96
+ * The two phases of one plan. The setup set was approved (the plan's latest
97
+ * decision approves the bundle that holds it), materialized and merged into
98
+ * the clone's default branch (by squash by default), and the apply set was
99
+ * then computed against the merged base and is held by a later run's bundle,
100
+ * which the hub stores. `spawn` stands in for the package manager: it
101
+ * regenerates the lockfile the apply set's installs write.
102
+ */
103
+ export function buildAdmittedFixture(roots, options = {}) {
104
+ let site;
105
+ const world = buildWorld({
106
+ ...options.world,
107
+ commitBase: (tree) => {
108
+ options.tree?.(tree);
109
+ site = siteRepo(roots, tree, { mergeStyle: options.mergeStyle ?? "squash" });
110
+ const origin = join(dirname(site.clone), "origin.git");
111
+ execFileSync("git", ["init", "--bare", origin], { env: gitEnv, stdio: "ignore" });
112
+ git(site.clone, "remote", "add", "origin", origin);
113
+ git(site.clone, "push", "-u", "origin", "main");
114
+ return site.baseCommit;
115
+ },
116
+ });
117
+ const override = typeof options.hub === "function" ? options.hub(world) : (options.hub ?? {});
118
+ const hub = hubRepo(roots, {
119
+ plans: [world.plan],
120
+ sets: options.storeApplySet === true ? [world.setup, world.apply] : [world.setup],
121
+ bundles: [world.approvedBundle, world.applyBundle],
122
+ ...override,
123
+ });
124
+ const packages = committedPlanPackages(world.plan, SITE_ID);
125
+ const spawn = async (request) => {
126
+ if (request.args.includes("--version"))
127
+ return { status: 0, stdout: "10.9.0\n", stderr: "" };
128
+ writeFileSync(join(request.cwd, "package-lock.json"), lockfileText(packages));
129
+ return { status: 0, stdout: "", stderr: "" };
130
+ };
131
+ return {
132
+ world,
133
+ hub: hub.hub,
134
+ clone: site.clone,
135
+ baseCommit: site.baseCommit,
136
+ sideTip: site.sideTip,
137
+ set: world.apply,
138
+ setup: world.setup,
139
+ texts: world.texts,
140
+ spawn,
141
+ };
142
+ }
143
+ function walk(root, skip, into, relative = "") {
144
+ let names;
145
+ try {
146
+ names = readdirSync(join(root, relative)).sort();
147
+ }
148
+ catch {
149
+ return;
150
+ }
151
+ for (const name of names) {
152
+ const path = relative === "" ? name : `${relative}/${name}`;
153
+ if (skip(path))
154
+ continue;
155
+ const stat = lstatSync(join(root, path));
156
+ if (stat.isDirectory())
157
+ walk(root, skip, into, path);
158
+ else if (stat.isSymbolicLink())
159
+ into.push(`${path} -> ${readlinkSync(join(root, path))}`);
160
+ else
161
+ into.push(`${path} ${createHash("sha256").update(readFileSync(join(root, path))).digest("hex")} ${stat.mode & 0o777}`);
162
+ }
163
+ }
164
+ /**
165
+ * Everything a refused materialize must leave alone: the clone's refs, HEAD,
166
+ * index, status and every file outside .git, and every file the hub keeps
167
+ * under clossys/.state. Two snapshots are equal only when nothing moved.
168
+ */
169
+ export function writeSnapshot(clone, hub) {
170
+ const files = [];
171
+ walk(clone, (path) => path === ".git", files);
172
+ const hubFiles = [];
173
+ walk(join(hub, "clossys", ".state"), () => false, hubFiles);
174
+ return JSON.stringify({
175
+ refs: git(clone, "for-each-ref").trim(),
176
+ head: git(clone, "rev-parse", "HEAD").trim(),
177
+ branch: git(clone, "rev-parse", "--abbrev-ref", "HEAD").trim(),
178
+ index: git(clone, "ls-files", "-s").trim(),
179
+ status: git(clone, "status", "--porcelain", "--untracked-files=all").trim(),
180
+ files,
181
+ hub: hubFiles,
182
+ });
183
+ }
184
+ /** Whether the clone holds a local branch of this name. */
185
+ export function branchExists(clone, branch) {
186
+ try {
187
+ git(clone, "show-ref", "--verify", "--quiet", `refs/heads/${branch}`);
188
+ return true;
189
+ }
190
+ catch {
191
+ return false;
192
+ }
193
+ }
194
+ /** The ledger a clone holds at clossys/.state/installed.json, parsed, or null when it holds none. */
195
+ export function readCloneLedger(clone) {
196
+ const path = join(clone, "clossys/.state/installed.json");
197
+ return existsSync(path) ? JSON.parse(readFileSync(path, "utf8")) : null;
198
+ }
199
+ //# sourceMappingURL=apply-step-fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-step-fixture.js","sourceRoot":"","sources":["../src/apply-step-fixture.ts"],"names":[],"mappings":"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"}