@intentius/chant 0.80.0 → 0.81.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 (414) hide show
  1. package/dist/audit/discover.d.ts +8 -16
  2. package/dist/audit/discover.d.ts.map +1 -1
  3. package/dist/audit/report-html.d.ts +5 -0
  4. package/dist/audit/report-html.d.ts.map +1 -1
  5. package/dist/audit/report-model.d.ts +13 -0
  6. package/dist/audit/report-model.d.ts.map +1 -1
  7. package/dist/audit/terraform-state.d.ts +4 -5
  8. package/dist/audit/terraform-state.d.ts.map +1 -1
  9. package/dist/cli/commands/audit.d.ts +25 -9
  10. package/dist/cli/commands/audit.d.ts.map +1 -1
  11. package/dist/cli/commands/check-lexicon.d.ts +8 -0
  12. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  13. package/dist/cli/commands/doctor.d.ts.map +1 -1
  14. package/dist/cli/commands/import-agents.d.ts.map +1 -1
  15. package/dist/cli/commands/init.d.ts.map +1 -1
  16. package/dist/cli/commands/lint.d.ts.map +1 -1
  17. package/dist/cli/commands/update.d.ts +6 -0
  18. package/dist/cli/commands/update.d.ts.map +1 -1
  19. package/dist/cli/commands/vendor.d.ts +5 -0
  20. package/dist/cli/commands/vendor.d.ts.map +1 -1
  21. package/dist/cli/handlers/build.d.ts.map +1 -1
  22. package/dist/cli/handlers/components.d.ts.map +1 -1
  23. package/dist/cli/handlers/dev.d.ts.map +1 -1
  24. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  25. package/dist/cli/handlers/init.d.ts.map +1 -1
  26. package/dist/cli/handlers/operator.d.ts +7 -0
  27. package/dist/cli/handlers/operator.d.ts.map +1 -1
  28. package/dist/cli/handlers/promote.d.ts +7 -4
  29. package/dist/cli/handlers/promote.d.ts.map +1 -1
  30. package/dist/cli/handlers/run-generate.d.ts.map +1 -1
  31. package/dist/cli/handlers/run.d.ts +4 -1
  32. package/dist/cli/handlers/run.d.ts.map +1 -1
  33. package/dist/cli/handlers/vendor.d.ts +8 -3
  34. package/dist/cli/handlers/vendor.d.ts.map +1 -1
  35. package/dist/cli/main.d.ts +12 -0
  36. package/dist/cli/main.d.ts.map +1 -1
  37. package/dist/cli/plugins.d.ts +12 -7
  38. package/dist/cli/plugins.d.ts.map +1 -1
  39. package/dist/cli/registry.d.ts +32 -0
  40. package/dist/cli/registry.d.ts.map +1 -1
  41. package/dist/codegen/fetch.d.ts +10 -0
  42. package/dist/codegen/fetch.d.ts.map +1 -1
  43. package/dist/components/cli-support.d.ts +3 -1
  44. package/dist/components/cli-support.d.ts.map +1 -1
  45. package/dist/components/discover.d.ts.map +1 -1
  46. package/dist/components/driver.d.ts +16 -2
  47. package/dist/components/driver.d.ts.map +1 -1
  48. package/dist/components/gate-plan.d.ts +40 -0
  49. package/dist/components/gate-plan.d.ts.map +1 -0
  50. package/dist/components/promote.d.ts +60 -7
  51. package/dist/components/promote.d.ts.map +1 -1
  52. package/dist/components/sandbox/driver.d.ts.map +1 -1
  53. package/dist/components/sandbox/run.d.ts.map +1 -1
  54. package/dist/components/verbs/build-archive.d.ts +22 -11
  55. package/dist/components/verbs/build-archive.d.ts.map +1 -1
  56. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  57. package/dist/config-static.d.ts +59 -0
  58. package/dist/config-static.d.ts.map +1 -0
  59. package/dist/config.d.ts +32 -10
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/content-digest.d.ts +17 -0
  62. package/dist/content-digest.d.ts.map +1 -0
  63. package/dist/discovery/files.d.ts +10 -5
  64. package/dist/discovery/files.d.ts.map +1 -1
  65. package/dist/discovery/fold-import.d.ts +20 -4
  66. package/dist/discovery/fold-import.d.ts.map +1 -1
  67. package/dist/discovery/index.d.ts.map +1 -1
  68. package/dist/discovery/sandbox/driver.d.ts +20 -0
  69. package/dist/discovery/sandbox/driver.d.ts.map +1 -1
  70. package/dist/discovery/sandbox/fork.d.ts +20 -0
  71. package/dist/discovery/sandbox/fork.d.ts.map +1 -1
  72. package/dist/discovery/walk.d.ts +119 -0
  73. package/dist/discovery/walk.d.ts.map +1 -0
  74. package/dist/graph-ir.d.ts +4 -1
  75. package/dist/graph-ir.d.ts.map +1 -1
  76. package/dist/join-key.d.ts +31 -0
  77. package/dist/join-key.d.ts.map +1 -0
  78. package/dist/lexicon-module.d.ts +51 -6
  79. package/dist/lexicon-module.d.ts.map +1 -1
  80. package/dist/lexicon.d.ts +58 -1
  81. package/dist/lexicon.d.ts.map +1 -1
  82. package/dist/lifecycle/build-ledger-store.d.ts.map +1 -1
  83. package/dist/lifecycle/digest.d.ts +5 -1
  84. package/dist/lifecycle/digest.d.ts.map +1 -1
  85. package/dist/lifecycle/gate-ledger.d.ts +20 -5
  86. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  87. package/dist/lifecycle/git.d.ts +64 -0
  88. package/dist/lifecycle/git.d.ts.map +1 -1
  89. package/dist/lifecycle/lease.d.ts +8 -1
  90. package/dist/lifecycle/lease.d.ts.map +1 -1
  91. package/dist/lifecycle/legacy-digest.d.ts +41 -8
  92. package/dist/lifecycle/legacy-digest.d.ts.map +1 -1
  93. package/dist/lifecycle/member-ledger.d.ts +67 -0
  94. package/dist/lifecycle/member-ledger.d.ts.map +1 -0
  95. package/dist/lifecycle/plan-digest.d.ts +4 -3
  96. package/dist/lifecycle/plan-digest.d.ts.map +1 -1
  97. package/dist/lifecycle/release-ledger.d.ts +18 -2
  98. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  99. package/dist/lifecycle/status.d.ts +90 -5
  100. package/dist/lifecycle/status.d.ts.map +1 -1
  101. package/dist/op/activities/activity-contracts.d.ts +32 -0
  102. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  103. package/dist/op/activities/index.d.ts +2 -0
  104. package/dist/op/activities/index.d.ts.map +1 -1
  105. package/dist/op/activities/propose-upgrade.d.ts +75 -0
  106. package/dist/op/activities/propose-upgrade.d.ts.map +1 -0
  107. package/dist/op/discover.d.ts.map +1 -1
  108. package/dist/op/gate-name.d.ts +7 -0
  109. package/dist/op/gate-name.d.ts.map +1 -1
  110. package/dist/op/gate-summary.d.ts +16 -0
  111. package/dist/op/gate-summary.d.ts.map +1 -1
  112. package/dist/op/gate.d.ts +16 -2
  113. package/dist/op/gate.d.ts.map +1 -1
  114. package/dist/project-root.d.ts +26 -0
  115. package/dist/project-root.d.ts.map +1 -1
  116. package/dist/workspace/__fixtures__/contract-repo.d.ts +37 -0
  117. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -0
  118. package/dist/workspace/__fixtures__/two-member-workspace.d.ts +11 -0
  119. package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -0
  120. package/dist/workspace/checks/generated.d.ts +156 -0
  121. package/dist/workspace/checks/generated.d.ts.map +1 -0
  122. package/dist/workspace/checks/ledgers.d.ts +78 -0
  123. package/dist/workspace/checks/ledgers.d.ts.map +1 -0
  124. package/dist/workspace/checks/links.d.ts +25 -0
  125. package/dist/workspace/checks/links.d.ts.map +1 -0
  126. package/dist/workspace/checks/pipelines.d.ts +76 -0
  127. package/dist/workspace/checks/pipelines.d.ts.map +1 -0
  128. package/dist/workspace/checks.d.ts +161 -0
  129. package/dist/workspace/checks.d.ts.map +1 -0
  130. package/dist/workspace/compose-graph.d.ts +115 -0
  131. package/dist/workspace/compose-graph.d.ts.map +1 -0
  132. package/dist/workspace/compose-reports.d.ts +68 -0
  133. package/dist/workspace/compose-reports.d.ts.map +1 -0
  134. package/dist/workspace/declaration.d.ts +220 -0
  135. package/dist/workspace/declaration.d.ts.map +1 -0
  136. package/dist/workspace/declaration.schema.json +434 -0
  137. package/dist/workspace/generated-files.d.ts +65 -0
  138. package/dist/workspace/generated-files.d.ts.map +1 -0
  139. package/dist/workspace/glob.d.ts +13 -0
  140. package/dist/workspace/glob.d.ts.map +1 -0
  141. package/dist/workspace/graph-cli.d.ts +75 -0
  142. package/dist/workspace/graph-cli.d.ts.map +1 -0
  143. package/dist/workspace/init.d.ts +96 -0
  144. package/dist/workspace/init.d.ts.map +1 -0
  145. package/dist/workspace/jsonc.d.ts +38 -0
  146. package/dist/workspace/jsonc.d.ts.map +1 -0
  147. package/dist/workspace/kinds.d.ts +192 -0
  148. package/dist/workspace/kinds.d.ts.map +1 -0
  149. package/dist/workspace/lineage-check.d.ts +84 -0
  150. package/dist/workspace/lineage-check.d.ts.map +1 -0
  151. package/dist/workspace/lineage-cli.d.ts +31 -0
  152. package/dist/workspace/lineage-cli.d.ts.map +1 -0
  153. package/dist/workspace/lineage-init.d.ts +101 -0
  154. package/dist/workspace/lineage-init.d.ts.map +1 -0
  155. package/dist/workspace/lineage-lock.d.ts +258 -0
  156. package/dist/workspace/lineage-lock.d.ts.map +1 -0
  157. package/dist/workspace/lineage-merge.d.ts +14 -0
  158. package/dist/workspace/lineage-merge.d.ts.map +1 -0
  159. package/dist/workspace/lineage-migrations.d.ts +178 -0
  160. package/dist/workspace/lineage-migrations.d.ts.map +1 -0
  161. package/dist/workspace/lineage-update.d.ts +59 -0
  162. package/dist/workspace/lineage-update.d.ts.map +1 -0
  163. package/dist/workspace/lineage-upgrade-cli.d.ts +40 -0
  164. package/dist/workspace/lineage-upgrade-cli.d.ts.map +1 -0
  165. package/dist/workspace/lineage-upgrade.d.ts +146 -0
  166. package/dist/workspace/lineage-upgrade.d.ts.map +1 -0
  167. package/dist/workspace/lineage-vendor.d.ts +63 -0
  168. package/dist/workspace/lineage-vendor.d.ts.map +1 -0
  169. package/dist/workspace/lineage-version.d.ts +32 -0
  170. package/dist/workspace/lineage-version.d.ts.map +1 -0
  171. package/dist/workspace/links.d.ts +150 -0
  172. package/dist/workspace/links.d.ts.map +1 -0
  173. package/dist/workspace/ls.d.ts +99 -0
  174. package/dist/workspace/ls.d.ts.map +1 -0
  175. package/dist/workspace/member-commands.d.ts +139 -0
  176. package/dist/workspace/member-commands.d.ts.map +1 -0
  177. package/dist/workspace/member-handles.d.ts +54 -0
  178. package/dist/workspace/member-handles.d.ts.map +1 -0
  179. package/dist/workspace/member-pipeline.d.ts +143 -0
  180. package/dist/workspace/member-pipeline.d.ts.map +1 -0
  181. package/dist/workspace/member-run.d.ts +67 -0
  182. package/dist/workspace/member-run.d.ts.map +1 -0
  183. package/dist/workspace/reason-codes.d.ts +65 -0
  184. package/dist/workspace/reason-codes.d.ts.map +1 -0
  185. package/dist/workspace/records-cli.d.ts +28 -4
  186. package/dist/workspace/records-cli.d.ts.map +1 -1
  187. package/dist/workspace/records.d.ts.map +1 -1
  188. package/dist/workspace/root-refusal.d.ts +53 -0
  189. package/dist/workspace/root-refusal.d.ts.map +1 -0
  190. package/dist/workspace/status.d.ts +150 -0
  191. package/dist/workspace/status.d.ts.map +1 -0
  192. package/dist/workspace/template-manifest.d.ts +90 -0
  193. package/dist/workspace/template-manifest.d.ts.map +1 -0
  194. package/dist/workspace/tree.d.ts +36 -0
  195. package/dist/workspace/tree.d.ts.map +1 -0
  196. package/dist/workspace/trust/attestor.d.ts +67 -0
  197. package/dist/workspace/trust/attestor.d.ts.map +1 -0
  198. package/dist/workspace/trust/policy.d.ts +111 -0
  199. package/dist/workspace/trust/policy.d.ts.map +1 -0
  200. package/dist/workspace/trust/provenance.d.ts +67 -0
  201. package/dist/workspace/trust/provenance.d.ts.map +1 -0
  202. package/dist/workspace/trust/ssh-commit.d.ts +43 -0
  203. package/dist/workspace/trust/ssh-commit.d.ts.map +1 -0
  204. package/dist/workspace/trust/test-repo.d.ts +42 -0
  205. package/dist/workspace/trust/test-repo.d.ts.map +1 -0
  206. package/dist/workspace/trust/verify-cli.d.ts +9 -0
  207. package/dist/workspace/trust/verify-cli.d.ts.map +1 -0
  208. package/dist/workspace/trust/verify.d.ts +66 -0
  209. package/dist/workspace/trust/verify.d.ts.map +1 -0
  210. package/dist/workspace/which-chant.d.ts +58 -0
  211. package/dist/workspace/which-chant.d.ts.map +1 -0
  212. package/dist/workspace/workspace-kinds.schema.json +133 -0
  213. package/package.json +2 -1
  214. package/src/audit/discover.ts +66 -78
  215. package/src/audit/report-html.ts +3 -1
  216. package/src/audit/report-model.ts +14 -1
  217. package/src/audit/terraform-state.test.ts +4 -9
  218. package/src/audit/terraform-state.ts +4 -5
  219. package/src/cli/commands/audit-truncation.test.ts +167 -0
  220. package/src/cli/commands/audit.ts +89 -60
  221. package/src/cli/commands/check-lexicon.ts +24 -0
  222. package/src/cli/commands/doctor.test.ts +30 -0
  223. package/src/cli/commands/doctor.ts +18 -0
  224. package/src/cli/commands/import-agents.ts +6 -2
  225. package/src/cli/commands/init.ts +22 -3
  226. package/src/cli/commands/lint.test.ts +17 -23
  227. package/src/cli/commands/lint.ts +24 -84
  228. package/src/cli/commands/update.ts +13 -4
  229. package/src/cli/commands/vendor.ts +11 -6
  230. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +38 -0
  231. package/src/cli/handlers/build-member.test.ts +127 -0
  232. package/src/cli/handlers/build.ts +35 -1
  233. package/src/cli/handlers/components.test.ts +127 -0
  234. package/src/cli/handlers/components.ts +70 -8
  235. package/src/cli/handlers/dev.ts +5 -3
  236. package/src/cli/handlers/fan-out.ts +9 -2
  237. package/src/cli/handlers/init.ts +54 -1
  238. package/src/cli/handlers/operator.test.ts +68 -0
  239. package/src/cli/handlers/operator.ts +37 -9
  240. package/src/cli/handlers/promote.test.ts +118 -2
  241. package/src/cli/handlers/promote.ts +82 -16
  242. package/src/cli/handlers/run-generate-member.test.ts +83 -0
  243. package/src/cli/handlers/run-generate.test.ts +6 -8
  244. package/src/cli/handlers/run-generate.ts +36 -1
  245. package/src/cli/handlers/run.test.ts +47 -0
  246. package/src/cli/handlers/run.ts +28 -5
  247. package/src/cli/handlers/vendor.ts +147 -43
  248. package/src/cli/main.test.ts +105 -1
  249. package/src/cli/main.ts +230 -17
  250. package/src/cli/plugins.ts +17 -17
  251. package/src/cli/registry.ts +32 -0
  252. package/src/cli/static-config-read.test.ts +208 -0
  253. package/src/codegen/fetch.test.ts +63 -1
  254. package/src/codegen/fetch.ts +30 -1
  255. package/src/components/cli-support.ts +6 -1
  256. package/src/components/discover.test.ts +27 -57
  257. package/src/components/discover.ts +13 -68
  258. package/src/components/driver.test.ts +78 -1
  259. package/src/components/driver.ts +43 -7
  260. package/src/components/gate-plan.ts +53 -0
  261. package/src/components/promote.test.ts +276 -2
  262. package/src/components/promote.ts +119 -15
  263. package/src/components/sandbox/driver.ts +8 -8
  264. package/src/components/sandbox/run.ts +4 -1
  265. package/src/components/verbs/build-archive.ts +27 -21
  266. package/src/components/verbs/run-agent.ts +3 -5
  267. package/src/config-static.test.ts +136 -0
  268. package/src/config-static.ts +232 -0
  269. package/src/config.test.ts +2 -2
  270. package/src/config.ts +48 -15
  271. package/src/content-digest.test.ts +120 -0
  272. package/src/content-digest.ts +21 -0
  273. package/src/discovery/files.test.ts +10 -10
  274. package/src/discovery/files.ts +25 -81
  275. package/src/discovery/fold-import.ts +49 -5
  276. package/src/discovery/index.ts +1 -0
  277. package/src/discovery/sandbox/driver.ts +73 -35
  278. package/src/discovery/sandbox/fork-diagnostic.test.ts +136 -13
  279. package/src/discovery/sandbox/fork.ts +83 -43
  280. package/src/discovery/sandbox/path-lexicon-multifile.test.ts +285 -0
  281. package/src/discovery/walk.test.ts +263 -0
  282. package/src/discovery/walk.ts +334 -0
  283. package/src/effect-receipt.ts +2 -2
  284. package/src/graph-ir.ts +4 -1
  285. package/src/join-key.test.ts +25 -0
  286. package/src/join-key.ts +39 -0
  287. package/src/lexicon-module.ts +108 -10
  288. package/src/lexicon.ts +79 -1
  289. package/src/lifecycle/build-ledger-store.ts +11 -10
  290. package/src/lifecycle/digest.ts +9 -5
  291. package/src/lifecycle/gate-ledger.test.ts +20 -0
  292. package/src/lifecycle/gate-ledger.ts +28 -6
  293. package/src/lifecycle/git.test.ts +13 -1
  294. package/src/lifecycle/git.ts +221 -176
  295. package/src/lifecycle/lease.ts +25 -10
  296. package/src/lifecycle/legacy-digest.test.ts +115 -23
  297. package/src/lifecycle/legacy-digest.ts +60 -19
  298. package/src/lifecycle/member-ledger.test.ts +319 -0
  299. package/src/lifecycle/member-ledger.ts +145 -0
  300. package/src/lifecycle/plan-digest.ts +7 -7
  301. package/src/lifecycle/release-ledger.test.ts +20 -0
  302. package/src/lifecycle/release-ledger.ts +23 -7
  303. package/src/lifecycle/status.test.ts +151 -1
  304. package/src/lifecycle/status.ts +228 -7
  305. package/src/op/activities/activity-contracts.ts +37 -0
  306. package/src/op/activities/index.ts +10 -0
  307. package/src/op/activities/propose-upgrade.ts +206 -0
  308. package/src/op/discover.test.ts +14 -4
  309. package/src/op/discover.ts +19 -27
  310. package/src/op/gate-name.ts +8 -0
  311. package/src/op/gate-summary.test.ts +14 -0
  312. package/src/op/gate-summary.ts +25 -2
  313. package/src/op/gate.ts +36 -7
  314. package/src/op/generate-pipeline.test.ts +14 -5
  315. package/src/project-root.test.ts +66 -1
  316. package/src/project-root.ts +48 -0
  317. package/src/workspace/__fixtures__/contract-repo.ts +100 -0
  318. package/src/workspace/__fixtures__/two-member-workspace.ts +35 -0
  319. package/src/workspace/behold-kinds.test.ts +162 -0
  320. package/src/workspace/check-contract.test.ts +127 -0
  321. package/src/workspace/check.schema.json +347 -0
  322. package/src/workspace/checks/generated.test.ts +287 -0
  323. package/src/workspace/checks/generated.ts +475 -0
  324. package/src/workspace/checks/ledgers.test.ts +139 -0
  325. package/src/workspace/checks/ledgers.ts +246 -0
  326. package/src/workspace/checks/links.ts +183 -0
  327. package/src/workspace/checks/pipelines.test.ts +133 -0
  328. package/src/workspace/checks/pipelines.ts +225 -0
  329. package/src/workspace/checks-repo.test.ts +71 -0
  330. package/src/workspace/checks.test.ts +450 -0
  331. package/src/workspace/checks.ts +461 -0
  332. package/src/workspace/compose-graph.test.ts +146 -0
  333. package/src/workspace/compose-graph.ts +228 -0
  334. package/src/workspace/compose-reports.test.ts +109 -0
  335. package/src/workspace/compose-reports.ts +186 -0
  336. package/src/workspace/declaration.schema.json +434 -0
  337. package/src/workspace/declaration.test.ts +347 -0
  338. package/src/workspace/declaration.ts +623 -0
  339. package/src/workspace/generated-files.test.ts +114 -0
  340. package/src/workspace/generated-files.ts +94 -0
  341. package/src/workspace/glob.ts +49 -0
  342. package/src/workspace/graph-cli.ts +220 -0
  343. package/src/workspace/graph-contract.test.ts +204 -0
  344. package/src/workspace/graph.schema.json +662 -0
  345. package/src/workspace/init.test.ts +223 -0
  346. package/src/workspace/init.ts +585 -0
  347. package/src/workspace/jsonc.test.ts +65 -0
  348. package/src/workspace/jsonc.ts +231 -0
  349. package/src/workspace/kinds.test.ts +288 -0
  350. package/src/workspace/kinds.ts +506 -0
  351. package/src/workspace/lineage-check.ts +264 -0
  352. package/src/workspace/lineage-cli.ts +114 -0
  353. package/src/workspace/lineage-init.test.ts +231 -0
  354. package/src/workspace/lineage-init.ts +365 -0
  355. package/src/workspace/lineage-lock.test.ts +224 -0
  356. package/src/workspace/lineage-lock.ts +357 -0
  357. package/src/workspace/lineage-merge.ts +44 -0
  358. package/src/workspace/lineage-migrations.test.ts +178 -0
  359. package/src/workspace/lineage-migrations.ts +343 -0
  360. package/src/workspace/lineage-update.ts +160 -0
  361. package/src/workspace/lineage-upgrade-cli.ts +151 -0
  362. package/src/workspace/lineage-upgrade.test.ts +474 -0
  363. package/src/workspace/lineage-upgrade.ts +624 -0
  364. package/src/workspace/lineage-vendor.test.ts +126 -0
  365. package/src/workspace/lineage-vendor.ts +215 -0
  366. package/src/workspace/lineage-version.ts +127 -0
  367. package/src/workspace/links.test.ts +344 -0
  368. package/src/workspace/links.ts +331 -0
  369. package/src/workspace/ls-contract.test.ts +200 -0
  370. package/src/workspace/ls.schema.json +190 -0
  371. package/src/workspace/ls.ts +254 -0
  372. package/src/workspace/member-commands.e2e.test.ts +244 -0
  373. package/src/workspace/member-commands.test.ts +217 -0
  374. package/src/workspace/member-commands.ts +540 -0
  375. package/src/workspace/member-handles.test.ts +76 -0
  376. package/src/workspace/member-handles.ts +228 -0
  377. package/src/workspace/member-pipeline.test.ts +135 -0
  378. package/src/workspace/member-pipeline.ts +317 -0
  379. package/src/workspace/member-run.ts +146 -0
  380. package/src/workspace/read-contract.test.ts +129 -0
  381. package/src/workspace/reason-codes.test.ts +113 -0
  382. package/src/workspace/reason-codes.ts +81 -0
  383. package/src/workspace/records-cli.ts +86 -14
  384. package/src/workspace/records-contract.test.ts +5 -0
  385. package/src/workspace/records.schema.json +32 -2
  386. package/src/workspace/records.ts +3 -2
  387. package/src/workspace/root-refusal.ts +97 -0
  388. package/src/workspace/status-contract.test.ts +308 -0
  389. package/src/workspace/status.schema.json +210 -0
  390. package/src/workspace/status.ts +412 -0
  391. package/src/workspace/template-manifest.test.ts +79 -0
  392. package/src/workspace/template-manifest.ts +221 -0
  393. package/src/workspace/tree.ts +132 -0
  394. package/src/workspace/trust/attestor.ts +93 -0
  395. package/src/workspace/trust/policy.ts +306 -0
  396. package/src/workspace/trust/provenance.ts +181 -0
  397. package/src/workspace/trust/ssh-commit.ts +138 -0
  398. package/src/workspace/trust/test-repo.ts +138 -0
  399. package/src/workspace/trust/trust.test.ts +397 -0
  400. package/src/workspace/trust/verify-cli.ts +56 -0
  401. package/src/workspace/trust/verify.ts +194 -0
  402. package/src/workspace/which-chant.test.ts +117 -0
  403. package/src/workspace/which-chant.ts +151 -0
  404. package/src/workspace/workspace-kinds.schema.json +133 -0
  405. package/dist/components/unbound-gate-approval.d.ts +0 -24
  406. package/dist/components/unbound-gate-approval.d.ts.map +0 -1
  407. package/dist/discovery/convergence.d.ts +0 -97
  408. package/dist/discovery/convergence.d.ts.map +0 -1
  409. package/src/cli/commands/audit-walk-warnings.test.ts +0 -156
  410. package/src/components/unbound-gate-approval.test.ts +0 -82
  411. package/src/components/unbound-gate-approval.ts +0 -51
  412. package/src/discovery/convergence.test.ts +0 -231
  413. package/src/discovery/convergence.ts +0 -399
  414. package/src/op/discover-convergence.test.ts +0 -70
@@ -0,0 +1,150 @@
1
+ /**
2
+ * `chant workspace status <env> [--compare-to <env>] [--json]` (#2544): a
3
+ * read-only view of each member's latest release in an environment, and
4
+ * optionally a second environment beside it (#2524 D19, ws-043).
5
+ *
6
+ * Releases stay per member: a release is an artifact digest plus a git SHA in
7
+ * the member's own ledger on the `chant/lifecycle` branch. Member ledgers
8
+ * live under `_members/<member>/<env>/releases.jsonl` (#2524 D7, #2538), and
9
+ * the root member `.` keeps the flat `<env>/releases.jsonl`. A member whose
10
+ * `_members/<member>/` directory doesn't exist yet is read from the flat
11
+ * ledger, which is where a chant from before #2538, or below the floor,
12
+ * still writes it. Several members read that way share one ledger, and the
13
+ * output says so.
14
+ *
15
+ * The command reads the local `chant/lifecycle` branch and never fetches it.
16
+ * The output names the branch tip it read, so a stale copy is visible.
17
+ *
18
+ * A member whose ledger can't be read is still listed, with a reason code,
19
+ * and the command still exits 0 (#2524 D15, ws-020), as `ls` does. Only a
20
+ * declaration that can't be read, or an environment name that can't be one,
21
+ * exits 1. The `--json` output is part of the read contract and is described
22
+ * by `status.schema.json` beside this file.
23
+ */
24
+ import type { CommandContext } from "../cli/registry.js";
25
+ import { type ReleaseRecord } from "../lifecycle/release-ledger.js";
26
+ import { type ErrorLocation } from "./declaration.js";
27
+ /** The version of the `status` output this chant writes. */
28
+ export declare const STATUS_CONTRACT_VERSION = 1;
29
+ /** `$id` of the JSON Schema for the `--json` output, shipped beside this file. */
30
+ export declare const STATUS_OUTPUT_SCHEMA_ID = "https://intentius.io/chant/schemas/workspace/status/v1/status.schema.json";
31
+ /** The branch every ledger lives on. */
32
+ export declare const LIFECYCLE_REF = "chant/lifecycle";
33
+ /** The directory on {@link LIFECYCLE_REF} that holds member ledgers (#2538). */
34
+ export declare const MEMBERS_DIR = "_members";
35
+ /**
36
+ * Why a member's ledger for one environment can't be fully read. Closed: a
37
+ * new code is a contract change.
38
+ */
39
+ export declare const STATUS_REASON_CODES: readonly ["ledger-unreadable", "ledger-malformed"];
40
+ export type StatusReasonCode = (typeof STATUS_REASON_CODES)[number];
41
+ /**
42
+ * Why the status couldn't be read at all. The declaration's own codes, except
43
+ * the two that only `--at` returns, and one for the environment name.
44
+ */
45
+ export declare const STATUS_ERROR_CODES: readonly ["declaration-missing", "declaration-ambiguous", "declaration-unparseable", "declaration-invalid", "placement-invalid", "reader-too-old", "root-chant-required", "not-a-git-repository", "environment-invalid"];
46
+ export type StatusErrorCode = (typeof STATUS_ERROR_CODES)[number];
47
+ export interface StatusRelease {
48
+ component: string;
49
+ digest: string;
50
+ gitSha: string;
51
+ /** The input-side digest, when `digest` is a rendered one (a pinned helm deploy). Compare joins on it. */
52
+ inputDigest: string | null;
53
+ runId: string;
54
+ timestamp: string;
55
+ actor: string;
56
+ /** Read flags, such as `legacy-digest` (#2514). */
57
+ flags: string[];
58
+ }
59
+ export interface StatusLedger {
60
+ /** `members` for `_members/<member>/<env>/releases.jsonl`, `flat` for `<env>/releases.jsonl`. */
61
+ layout: "members" | "flat";
62
+ /** The ledger's path on the branch. */
63
+ path: string;
64
+ /** True when more than one member in this output reads this same flat ledger. */
65
+ shared: boolean;
66
+ }
67
+ export interface StatusEnvironment {
68
+ env: string;
69
+ ledger: StatusLedger;
70
+ /** The latest release of each component in the ledger, sorted by component. */
71
+ releases: StatusRelease[];
72
+ reason: {
73
+ code: StatusReasonCode;
74
+ message: string;
75
+ } | null;
76
+ }
77
+ export type CompareState = "same" | "differs" | "only-env" | "only-compare";
78
+ export interface StatusCompare {
79
+ /** True when any component is not `same`. */
80
+ differs: boolean;
81
+ components: {
82
+ component: string;
83
+ state: CompareState;
84
+ digest: string | null;
85
+ compareDigest: string | null;
86
+ }[];
87
+ }
88
+ export interface StatusMember {
89
+ name: string;
90
+ dir: string;
91
+ kind: string;
92
+ /** The environment asked for first, then the one compared to, if any. */
93
+ environments: StatusEnvironment[];
94
+ /** Null without `--compare-to`. */
95
+ compare: StatusCompare | null;
96
+ readable: boolean;
97
+ }
98
+ export type StatusDocument = {
99
+ $schema: string;
100
+ contract: number;
101
+ chant: string;
102
+ env: string;
103
+ compareTo: string | null;
104
+ lifecycle: {
105
+ ref: string;
106
+ commit: string | null;
107
+ };
108
+ workspace: {
109
+ name: string;
110
+ root: string;
111
+ file: string;
112
+ };
113
+ members: StatusMember[];
114
+ summary: {
115
+ members: number;
116
+ released: number;
117
+ unreadable: number;
118
+ differing: number | null;
119
+ };
120
+ } | {
121
+ $schema: string;
122
+ contract: number;
123
+ chant: string;
124
+ error: {
125
+ code: StatusErrorCode;
126
+ message: string;
127
+ location: ErrorLocation | null;
128
+ };
129
+ };
130
+ type LedgerReader = (path: string, cwd: string) => Promise<{
131
+ records: ReleaseRecord[];
132
+ malformed: number;
133
+ }>;
134
+ export interface StatusQuery {
135
+ /** Where the walk up to the declaration starts. */
136
+ cwd: string;
137
+ env: string;
138
+ compareTo?: string;
139
+ /** Reads one ledger; the lifecycle reader unless a test swaps it. */
140
+ readLedger?: LedgerReader;
141
+ }
142
+ export declare function compareEnvironments(a: StatusEnvironment, b: StatusEnvironment): StatusCompare;
143
+ /** Find the workspace, read every member's ledger and build the document `--json` prints. */
144
+ export declare function workspaceStatus(query: StatusQuery): Promise<StatusDocument>;
145
+ export declare function runWorkspaceStatus(ctx: CommandContext): Promise<number>;
146
+ export declare function formatStatus(doc: Extract<StatusDocument, {
147
+ members: unknown;
148
+ }>): string;
149
+ export {};
150
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/workspace/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Template parameters (#2627, #2524 D9): `chant.template.json` at a
3
+ * template's root declares the parameters `chant init --from` takes and the
4
+ * files they are substituted into.
5
+ *
6
+ * ```json
7
+ * {
8
+ * "parameters": {
9
+ * "name": { "type": "string", "default": "Reference app", "pattern": "^[A-Za-z0-9][A-Za-z0-9 ._-]*$" }
10
+ * },
11
+ * "files": ["app/src/server.mjs"]
12
+ * }
13
+ * ```
14
+ *
15
+ * A listed file carries `{{chant:<name>}}` where the value goes. The `chant:`
16
+ * prefix keeps the placeholder apart from TypeScript template literals
17
+ * (`${x}`), GitHub and Forgejo expressions (`${{ x }}`) and Handlebars or
18
+ * Mustache (`{{x}}`), so a template can hold any of those in a listed file.
19
+ * Only listed files are substituted, the value is inserted as written, and a
20
+ * placeholder naming an undeclared parameter is an error in the template.
21
+ *
22
+ * The manifest is JSON and read as data: no template code runs at init or
23
+ * upgrade. It is template metadata, like `.chant/migrations/`, so it is not
24
+ * copied into the project. The values used are recorded in the lineage's
25
+ * `parameters`, and `chant workspace upgrade` substitutes them again into both
26
+ * the merge base and the target version, so an unedited file carrying a value
27
+ * still has its recorded hash.
28
+ *
29
+ * `hostBound` is declared and validated but not acted on yet: recording a
30
+ * value per host belongs to export and import (#2552). A host-bound value is
31
+ * recorded in `parameters` like any other until then.
32
+ */
33
+ import { z } from "zod";
34
+ import { LockError } from "./lineage-lock.js";
35
+ /** The manifest's path, relative to the template's root (the `#<member>` directory, when one is given). */
36
+ export declare const TEMPLATE_MANIFEST = "chant.template.json";
37
+ export declare function placeholder(name: string): string;
38
+ declare const ParameterSchema: z.ZodObject<{
39
+ type: z.ZodLiteral<"string">;
40
+ default: z.ZodOptional<z.ZodString>;
41
+ pattern: z.ZodOptional<z.ZodString>;
42
+ hostBound: z.ZodOptional<z.ZodBoolean>;
43
+ description: z.ZodOptional<z.ZodString>;
44
+ }, z.core.$strict>;
45
+ export type TemplateParameter = z.infer<typeof ParameterSchema>;
46
+ declare const ManifestSchema: z.ZodObject<{
47
+ $comment: z.ZodOptional<z.ZodString>;
48
+ parameters: z.ZodRecord<z.ZodString, z.ZodObject<{
49
+ type: z.ZodLiteral<"string">;
50
+ default: z.ZodOptional<z.ZodString>;
51
+ pattern: z.ZodOptional<z.ZodString>;
52
+ hostBound: z.ZodOptional<z.ZodBoolean>;
53
+ description: z.ZodOptional<z.ZodString>;
54
+ }, z.core.$strict>>;
55
+ files: z.ZodArray<z.ZodString>;
56
+ }, z.core.$strict>;
57
+ export type TemplateManifest = z.infer<typeof ManifestSchema>;
58
+ export declare class TemplateParameterError extends LockError {
59
+ name: string;
60
+ }
61
+ /**
62
+ * Read the manifest from a template's files, or null when it has none.
63
+ * Throws on a manifest that is not valid JSON or does not match the schema.
64
+ */
65
+ export declare function readManifest(files: Map<string, Buffer>): TemplateManifest | null;
66
+ /**
67
+ * Parse `--param name=value` arguments (split at the first `=`). A name given
68
+ * twice is refused rather than silently taking the last value.
69
+ */
70
+ export declare function parseParamArgs(args: readonly string[]): Record<string, string>;
71
+ /**
72
+ * The value of every declared parameter: the given value, or the default.
73
+ * Refuses an undeclared name (listing the declared ones), a parameter with no
74
+ * value and no default, and a value that does not match its pattern.
75
+ */
76
+ export declare function resolveParameters(manifest: TemplateManifest | null, given: Record<string, string>): Record<string, string>;
77
+ /**
78
+ * The template's files as the project gets them: the manifest removed, and
79
+ * each listed file with its placeholders replaced. A listed file that is
80
+ * missing, or a placeholder naming no declared parameter, is refused.
81
+ */
82
+ export declare function substituteParameters(files: Map<string, Buffer>, manifest: TemplateManifest | null, values: Record<string, string>): Map<string, Buffer>;
83
+ /**
84
+ * The values an upgrade substitutes into a version of the template: the
85
+ * recorded value of every parameter that version declares, and the default of
86
+ * one it adds. A recorded parameter the version no longer declares is dropped.
87
+ */
88
+ export declare function carryParameters(manifest: TemplateManifest | null, recorded: Record<string, unknown>): Record<string, string>;
89
+ export {};
90
+ //# sourceMappingURL=template-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-manifest.d.ts","sourceRoot":"","sources":["../../src/workspace/template-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,2GAA2G;AAC3G,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAOvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,QAAA,MAAM,eAAe;;;;;;kBAUV,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAEhE,QAAA,MAAM,cAAc;;;;;;;;;;kBAMT,CAAC;AACZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAM9D,qBAAa,sBAAuB,SAAQ,SAAS;IAC1C,IAAI,SAA4B;CAC1C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,gBAAgB,GAAG,IAAI,CAoChF;AAQD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU9E;AAOD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwB1H;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1B,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBrB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO5H"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The files a workspace read looks at: the working tree, or one commit's git
3
+ * objects (`--at <rev>`, #2524 D15). Reading a revision needs no checkout and
4
+ * no network; the whole tree is listed once from the local object store.
5
+ *
6
+ * Paths are relative to the tree's root, `/`-separated, and `""` is the root.
7
+ */
8
+ export interface WorkspaceTree {
9
+ /** Appended to messages, such as " at 91c7547e". Empty for the working tree. */
10
+ label: string;
11
+ /** Whether `path` is a file, a directory, or missing. */
12
+ stat(path: string): "file" | "dir" | undefined;
13
+ /** The names of the entries directly inside directory `path`, or undefined when it is missing. */
14
+ list(path: string): {
15
+ name: string;
16
+ type: "file" | "dir";
17
+ }[] | undefined;
18
+ /** The text of the file at `path`. Throws when it can't be read. */
19
+ read(path: string): string;
20
+ }
21
+ /** Join tree-relative path parts, leaving out `""` and `"."`. */
22
+ export declare function joinPath(...parts: string[]): string;
23
+ /** The working tree under `root`. */
24
+ export declare function workingTree(root: string): WorkspaceTree;
25
+ /** The top of the git repository holding `cwd`, or undefined outside one. */
26
+ export declare function gitTop(cwd: string): string | undefined;
27
+ /** The full commit id `rev` names in the repository at `top`, or undefined. */
28
+ export declare function resolveCommit(top: string, rev: string): string | undefined;
29
+ /**
30
+ * The tree of `commit` in the repository at `top`, rooted at `prefix` (a
31
+ * directory relative to `top`, `""` for the top itself).
32
+ */
33
+ export declare function gitTree(top: string, commit: string, prefix?: string): WorkspaceTree;
34
+ /** Directory names a workspace walk never enters. */
35
+ export declare function skippedDir(name: string): boolean;
36
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/workspace/tree.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/C,kGAAkG;IAClG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAA;KAAE,EAAE,GAAG,SAAS,CAAC;IACzE,oEAAoE;IACpE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnD;AAED,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAqCvD;AAMD,6EAA6E;AAC7E,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMtD;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO1E;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,aAAa,CA+B/E;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Attestors and provenance levels (#2524 D5).
3
+ *
4
+ * An attestor answers one question about a commit: does it carry an
5
+ * attestation that the policy read at base accepts? Concrete attestors are
6
+ * plugins. Core ships the contract and the first one, ssh-signed commits
7
+ * (./ssh-commit.ts). Plugin attestors will arrive the way kinds do, through
8
+ * `workspaceKinds` (#2525 rule 5), once the declaration can name them (#2534,
9
+ * #2535); until then {@link registerAttestor} is the entry point.
10
+ *
11
+ * What counts as proof: a signature the attestor checked against a key the
12
+ * base policy lists. Never a trailer, a typed-in name, an author field or an
13
+ * environment variable.
14
+ */
15
+ import type { TrustPolicy } from "./policy.js";
16
+ /**
17
+ * How far a record's authorship is established. The list is closed and
18
+ * ordered from strongest to weakest; a gate may require `attested`.
19
+ *
20
+ * - `attested`: an attestor verified a signature by a signer the base policy lists.
21
+ * - `attested-unverifiable-here`: there is a signature, but nothing here can
22
+ * check it (a signature format no attestor handles, or a missing tool).
23
+ * - `adopted`: not attested, but inside a commit range the base policy admits.
24
+ * - `unattested`: none of the above. The same word, with the same meaning, as
25
+ * the approver a gate resolution records when its channel cannot attest to a
26
+ * name (#2384, {@link UNATTESTED_APPROVER}); D5 keeps that meaning.
27
+ */
28
+ export declare const PROVENANCE_LEVELS: readonly ["attested", "attested-unverifiable-here", "adopted", "unattested"];
29
+ export type ProvenanceLevel = (typeof PROVENANCE_LEVELS)[number];
30
+ /** What one attestor says about one commit. */
31
+ export interface CommitAttestation {
32
+ level: "attested" | "attested-unverifiable-here" | "unattested";
33
+ /** The attestor that gave this answer. */
34
+ attestor: string;
35
+ /** The principal whose key verified, when `attested`. */
36
+ principal?: string;
37
+ /** The key's fingerprint, when known. */
38
+ key?: string;
39
+ /** Why the level is what it is, in a sentence. */
40
+ reason: string;
41
+ }
42
+ /** Read access to the repository an attestor checks. */
43
+ export interface AttestorContext {
44
+ /** The repository's top directory. */
45
+ repo: string;
46
+ /** The policy read at base. */
47
+ policy: TrustPolicy;
48
+ }
49
+ /** A commit attestor. Plugins implement this. */
50
+ export interface CommitAttestor {
51
+ /** A stable name, such as `ssh-commit`. */
52
+ readonly name: string;
53
+ attestCommit(ctx: AttestorContext, commit: string): CommitAttestation;
54
+ }
55
+ /** Add an attestor. Later registrations are asked after earlier ones. */
56
+ export declare function registerAttestor(attestor: CommitAttestor): void;
57
+ /** Remove every attestor registered by {@link registerAttestor}. For tests. */
58
+ export declare function resetAttestors(): void;
59
+ /**
60
+ * Ask each attestor in turn. The first `attested` answer wins; otherwise
61
+ * `attested-unverifiable-here` beats `unattested`, so a signature nobody here
62
+ * can check is still reported as there.
63
+ */
64
+ export declare function attestCommit(ctx: AttestorContext, commit: string, attestors: readonly CommitAttestor[]): CommitAttestation;
65
+ /** The attestors in use: the built-in ones first, then any registered. */
66
+ export declare function activeAttestors(): Promise<CommitAttestor[]>;
67
+ //# sourceMappingURL=attestor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attestor.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/attestor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,8EAAsF,CAAC;AACrH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,GAAG,4BAA4B,GAAG,YAAY,CAAC;IAChE,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAAC;CACvE;AAID,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAE/D;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,cAAc,EAAE,GAAG,iBAAiB,CAQ1H;AAED,0EAA0E;AAC1E,wBAAsB,eAAe,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAGjE"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Trust policy, always read from the base revision (#2524 D5, Threat model;
3
+ * ws-001, ws-002).
4
+ *
5
+ * A check reads who may sign, and who holds which role, from the target
6
+ * branch tip or `--base <rev>`, never from the change under review. A change
7
+ * can edit its own copy of these files, and those edits have no effect until
8
+ * they are merged: the change is still judged by the policy at base. Editing
9
+ * the policy is itself a protected write (see ./verify.ts).
10
+ *
11
+ * Two files, both optional:
12
+ *
13
+ * - `.chant/allowed_signers` holds the signers, in ssh-keygen's
14
+ * allowed_signers format, so `git log --show-signature` can use the same
15
+ * file. `trust.json` may name another path.
16
+ * - `.chant/trust.json` holds the override for the signers path, the role
17
+ * grants and the adopted commit ranges. Role grants move into
18
+ * `chant.workspace.json` once the declaration exists (#2534).
19
+ *
20
+ * Attestation is opt-in (#2525 rule 6). Without a signers file at base,
21
+ * nothing is verified and every record is `unattested`.
22
+ */
23
+ import { z } from "zod";
24
+ import type { RecordSource } from "../record-source.js";
25
+ /** The trust config, relative to the repository root. Fixed: it is how the signers path is overridden. */
26
+ export declare const TRUST_CONFIG_PATH = ".chant/trust.json";
27
+ /** Where the signers are when `trust.json` names no other path. */
28
+ export declare const DEFAULT_SIGNERS_PATH = ".chant/allowed_signers";
29
+ /** One usable signer: a principal and the public key it signs with. */
30
+ export interface Signer {
31
+ principal: string;
32
+ /** `<type> <base64>`, with no comment. */
33
+ key: string;
34
+ /** The `namespaces="..."` option as written, or undefined when the key may sign any namespace. */
35
+ namespaces?: string;
36
+ /** 1-based line in the signers file. */
37
+ line: number;
38
+ }
39
+ /** A line of the signers file that is not used, and why. */
40
+ export interface ExcludedSigner {
41
+ line: number;
42
+ reason: string;
43
+ }
44
+ export interface SignerSet {
45
+ signers: Signer[];
46
+ excluded: ExcludedSigner[];
47
+ }
48
+ /**
49
+ * Parse an allowed_signers file, keeping only lines whose meaning does not
50
+ * depend on anything the signer controls.
51
+ *
52
+ * Refused, each with a reason, rather than passed to ssh-keygen:
53
+ *
54
+ * - `valid-after` and `valid-before`. git checks them against the commit's own
55
+ * date, which whoever makes the commit sets. A backdated commit would pass a
56
+ * window its key has left. Revocation is by position in history (#2553),
57
+ * never by date.
58
+ * - `cert-authority`. A certificate's validity is also a date, and a CA key
59
+ * vouches for keys this file never names.
60
+ * - Principal patterns (`*`, `?`, `!`). A signer is named by one exact
61
+ * principal, so role grants can name it.
62
+ */
63
+ export declare function parseAllowedSigners(text: string): SignerSet;
64
+ /** The signers as an allowed_signers file ssh-keygen reads, holding only the usable lines. */
65
+ export declare function renderAllowedSigners(signers: Signer[]): string;
66
+ export declare const trustConfigSchema: z.ZodObject<{
67
+ schema: z.ZodLiteral<1>;
68
+ signers: z.ZodOptional<z.ZodString>;
69
+ roles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
70
+ adopted: z.ZodOptional<z.ZodArray<z.ZodObject<{
71
+ from: z.ZodOptional<z.ZodString>;
72
+ to: z.ZodString;
73
+ note: z.ZodOptional<z.ZodString>;
74
+ }, z.core.$strict>>>;
75
+ }, z.core.$strict>;
76
+ export type TrustConfig = z.infer<typeof trustConfigSchema>;
77
+ /** The role whose holders may change the policy. Without any grant of it, every signer may. */
78
+ export declare const ADMIN_ROLE = "admin";
79
+ /** The policy a check applies, as read at base. */
80
+ export interface TrustPolicy {
81
+ /** The full commit id the policy was read at, or null when there is no base. */
82
+ base: string | null;
83
+ /** The signers path used. */
84
+ signersPath: string;
85
+ /** Whether a signers file exists at base. False means attestation is off. */
86
+ active: boolean;
87
+ signers: Signer[];
88
+ excluded: ExcludedSigner[];
89
+ roles: Record<string, string[]>;
90
+ adopted: Array<{
91
+ from?: string;
92
+ to: string;
93
+ }>;
94
+ /** Why the policy could not be read, when it could not. Nothing verifies then. */
95
+ problems: string[];
96
+ }
97
+ /** Paths whose change is a protected write under `policy`. */
98
+ export declare function protectedPaths(policy: TrustPolicy): string[];
99
+ /** Principals allowed to change the policy: the admins when any are granted, otherwise every signer. */
100
+ export declare function policyWriters(policy: TrustPolicy): Set<string>;
101
+ /** A policy with nothing in it: attestation off. */
102
+ export declare function emptyPolicy(base: string | null, problems?: string[]): TrustPolicy;
103
+ /**
104
+ * Read the policy through `source`, which must read the base revision.
105
+ * Never throws: a policy that cannot be read yields an inactive policy with
106
+ * its problems listed, so nothing is attested (fail closed).
107
+ */
108
+ export declare function readTrustPolicy(source: RecordSource, base: string | null): TrustPolicy;
109
+ /** A file's text through `source`, or undefined when it is not there. */
110
+ export declare function readOptional(source: RecordSource, path: string): string | undefined;
111
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,0GAA0G;AAC1G,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,mEAAmE;AACnE,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAe7D,uEAAuE;AACvE,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,kGAAkG;IAClG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAmDD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAkD3D;AAED,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAM9D;AAcD,eAAO,MAAM,iBAAiB;;;;;;;;;kBAiBnB,CAAC;AAEZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,+FAA+F;AAC/F,eAAO,MAAM,UAAU,UAAU,CAAC;AAElC,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,kFAAkF;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAE5D;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAI9D;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,GAAE,MAAM,EAAO,GAAG,WAAW,CAErF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CA8BtF;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnF"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The provenance level of each record (#2524 D5, Threat model).
3
+ *
4
+ * A record's content comes from the last commit that changed its file. That
5
+ * commit is asked of each attestor, with the policy read at base. A file with
6
+ * uncommitted changes is `unattested`: its bytes are in no commit, so nothing
7
+ * vouches for them.
8
+ *
9
+ * On a developer machine this detects; it does not enforce (ws-002). An agent
10
+ * running as the developer can use an unlocked signing agent or skip the check.
11
+ * Enforcement is CI running the same check against base.
12
+ */
13
+ import { type CommitAttestor, type ProvenanceLevel } from "./attestor.js";
14
+ import { type TrustPolicy } from "./policy.js";
15
+ /** What `records` reports for one record. */
16
+ export interface RecordProvenance {
17
+ level: ProvenanceLevel;
18
+ /** The commit the record's content comes from, or null for uncommitted content. */
19
+ commit: string | null;
20
+ attestor?: string;
21
+ principal?: string;
22
+ key?: string;
23
+ reason: string;
24
+ }
25
+ /** Where the base revision came from. */
26
+ export type BaseSource = "flag" | "origin/HEAD" | "main" | "master";
27
+ export interface ResolvedBase {
28
+ commit: string | null;
29
+ from: BaseSource | null;
30
+ /** Why there is no base, when there is none. */
31
+ problem?: string;
32
+ }
33
+ /**
34
+ * The base revision: `--base <rev>` when given, otherwise the target branch
35
+ * tip, taken as `origin/HEAD`, then a local `main`, then `master`. Never
36
+ * `HEAD`, which is the change under review.
37
+ */
38
+ export declare function resolveBase(repo: string, explicit?: string): ResolvedBase;
39
+ /** The policy at `base`, or an inactive one when there is no base. */
40
+ export declare function policyAtBase(repo: string, base: ResolvedBase): TrustPolicy;
41
+ /**
42
+ * The last commit reachable from `rev` that changed each path. Merges are
43
+ * diffed against all their parents (`-c`), so a merge that changes a file
44
+ * beyond what either side brought is the commit that file comes from, and a
45
+ * merge that only takes one side's version is passed through to that side.
46
+ */
47
+ export declare function lastCommits(repo: string, rev: string, paths: string[]): Map<string, string>;
48
+ /** Paths with staged, unstaged or untracked changes in the working tree. */
49
+ export declare function dirtyPaths(repo: string, paths: string[]): Set<string>;
50
+ /** Whether `commit` lies in a range the policy adopts (`from..to`, exact). */
51
+ export declare function isAdopted(repo: string, policy: TrustPolicy, commit: string): boolean;
52
+ /** A commit's provenance level under `policy`. */
53
+ export declare function commitProvenance(repo: string, policy: TrustPolicy, commit: string, attestors: readonly CommitAttestor[]): RecordProvenance;
54
+ export interface ProvenanceQuery {
55
+ repo: string | undefined;
56
+ policy: TrustPolicy;
57
+ /** The commit records were read at, or null for the working tree. */
58
+ at: string | null;
59
+ paths: string[];
60
+ attestors: readonly CommitAttestor[];
61
+ }
62
+ /**
63
+ * The provenance of each path. With attestation off (no signers file at
64
+ * base) nothing is checked and every path is `unattested`.
65
+ */
66
+ export declare function recordProvenance(q: ProvenanceQuery): Map<string, RecordProvenance>;
67
+ //# sourceMappingURL=provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAgB,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAgC,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE1E,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,CAAC;IACvB,mFAAmF;IACnF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAcD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,CAczE;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,WAAW,CAG1E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAW3F;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAYrE;AAWD,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpF;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,cAAc,EAAE,GAAG,gBAAgB,CAa1I;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,qEAAqE;IACrE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAyBlF"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The first attestor: ssh-signed commits, checked against the signers the
3
+ * base policy lists (#2524 D5, ws-001).
4
+ *
5
+ * It does not ask `git verify-commit`. That would read `gpg.ssh.program`,
6
+ * `gpg.ssh.allowedSignersFile` and the rest from git config, which whoever
7
+ * controls the machine can set, and it passes the commit's own date to
8
+ * ssh-keygen as the verification time. Instead it takes the signature and the
9
+ * signed payload out of the commit object itself and hands them to
10
+ * `ssh-keygen -Y verify` with a signers file built from the base policy, in
11
+ * the `git` namespace.
12
+ */
13
+ import type { CommitAttestor } from "./attestor.js";
14
+ import { type Signer } from "./policy.js";
15
+ /** A commit object split into its signed payload and its signature. */
16
+ export interface SignedCommit {
17
+ /** The bytes the signature covers: the commit object without its signature header. */
18
+ payload: Buffer;
19
+ /** The armored signature, or undefined when the commit is unsigned. */
20
+ signature?: string;
21
+ }
22
+ /**
23
+ * Split a raw commit object. `header` is `gpgsig` in a SHA-1 repository and
24
+ * `gpgsig-sha256` in a SHA-256 one; git removes exactly that header, with its
25
+ * continuation lines, to get the bytes it signed.
26
+ */
27
+ export declare function splitSignedCommit(raw: Buffer, header?: string): SignedCommit;
28
+ /**
29
+ * Check a detached ssh signature over `payload` in `namespace` against
30
+ * `signers`. Shared with the rotation check (#2553), which signs signer sets
31
+ * in their own namespace so a commit signature can never stand in for one.
32
+ */
33
+ export declare function verifySshSignature(signers: Signer[], payload: Buffer, signature: string, namespace: string): {
34
+ ok: true;
35
+ principal: string;
36
+ key?: string;
37
+ } | {
38
+ ok: false;
39
+ missing: boolean;
40
+ reason: string;
41
+ };
42
+ export declare const sshCommitAttestor: CommitAttestor;
43
+ //# sourceMappingURL=ssh-commit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh-commit.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/ssh-commit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAsC,cAAc,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAwB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAI7D,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,YAAY,CAsB9E;AAmBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAuBjG;AAED,eAAO,MAAM,iBAAiB,EAAE,cAW/B,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Test support for the trust modules: throwaway git repositories whose commits
3
+ * are signed with throwaway ssh keys. Isolated from the user's git config, so a
4
+ * developer's own signing setup never leaks into a test.
5
+ */
6
+ export declare const hasSshKeygen: boolean;
7
+ export interface Key {
8
+ name: string;
9
+ /** Private key file. */
10
+ file: string;
11
+ /** `ssh-ed25519 AAAA...`, no comment. */
12
+ pub: string;
13
+ }
14
+ export declare class TestRepo {
15
+ readonly dir: string;
16
+ private readonly home;
17
+ private readonly scratch;
18
+ constructor(label: string);
19
+ env(extra?: Record<string, string>): NodeJS.ProcessEnv;
20
+ git(args: string[], opts?: {
21
+ env?: Record<string, string>;
22
+ input?: string | Buffer;
23
+ }): string;
24
+ key(name: string): Key;
25
+ write(path: string, text: string): void;
26
+ /** Stage everything and commit, signed with `key` when given. Returns the commit id. */
27
+ commit(message: string, key?: Key, env?: Record<string, string>): string;
28
+ head(): string;
29
+ /**
30
+ * Write a commit object by hand: the current index's tree, `HEAD` as parent,
31
+ * and `signature` spliced in as the gpgsig header. Returns the new commit,
32
+ * which HEAD then points at.
33
+ */
34
+ forgeCommit(message: string, sign: (payload: Buffer) => string): string;
35
+ /** An ssh signature over `payload` in `namespace`, by `key`. */
36
+ sshSign(key: Key, payload: Buffer, namespace: string): string;
37
+ cleanup(): void;
38
+ }
39
+ /** A record kind reading `records/*.md`, and its schema, written into `repo`. */
40
+ export declare function writeRecordKind(repo: TestRepo): string;
41
+ export declare function note(id: string, body?: string): string;
42
+ //# sourceMappingURL=test-repo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-repo.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/test-repo.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,eAAO,MAAM,YAAY,SAA2E,CAAC;AAErG,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,QAAQ;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,KAAK,EAAE,MAAM;IASzB,GAAG,CAAC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAAC,UAAU;IAc1D,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAO,GAAG,MAAM;IAIjG,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG;IAOtB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKvC,wFAAwF;IACxF,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM;IAO5E,IAAI,IAAI,MAAM;IAId;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM;IAgBvE,gEAAgE;IAChE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAO7D,OAAO,IAAI,IAAI;CAGhB;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAqBtD;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM,CAElD"}