@mannyc1/ts-release 0.0.6 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (639) hide show
  1. package/ARCHITECTURE.md +124 -87
  2. package/CHANGELOG.md +115 -0
  3. package/LICENSE +21 -0
  4. package/README.md +272 -540
  5. package/SPEC.md +206 -305
  6. package/apps/release-ts/README.md +32 -0
  7. package/apps/release-ts/src/cli/command.ts +164 -0
  8. package/apps/release-ts/src/cli/commands.ts +351 -0
  9. package/apps/release-ts/src/cli/main.ts +43 -0
  10. package/apps/release-ts/src/cli/node-main.ts +49 -0
  11. package/apps/ts-release-agents/LICENSE +21 -0
  12. package/apps/ts-release-agents/README.md +21 -0
  13. package/apps/ts-release-agents/evals/cases.json +11 -0
  14. package/apps/ts-release-agents/manifests/claude.json +5 -0
  15. package/apps/ts-release-agents/manifests/codex.json +5 -0
  16. package/apps/ts-release-agents/package.json +11 -0
  17. package/apps/ts-release-agents/skills/release/SKILL.md +48 -0
  18. package/apps/ts-release-agents/skills/release/references/configuration.md +18 -0
  19. package/apps/ts-release-agents/skills/release/references/recovery.md +10 -0
  20. package/apps/ts-release-agents/skills/release/references/staged-workflow.md +12 -0
  21. package/apps/ts-release-agents/skills/release/references/target-selection.md +13 -0
  22. package/apps/ts-release-agents/skills/release/references/verification.md +14 -0
  23. package/apps/ts-release-agents/src/build.ts +105 -0
  24. package/apps/ts-release-agents/src/check.ts +117 -0
  25. package/apps/ts-release-agents/src/install.ts +121 -0
  26. package/apps/ts-release-agents/test/contract.test.ts +56 -0
  27. package/apps/ts-release-agents/tsconfig.json +5 -0
  28. package/dist/api/api.d.ts +15 -0
  29. package/dist/api/api.d.ts.map +1 -0
  30. package/dist/api/api.js +244 -0
  31. package/dist/api/api.js.map +1 -0
  32. package/dist/api/errors.d.ts +39 -0
  33. package/dist/api/errors.d.ts.map +1 -0
  34. package/dist/api/errors.js +32 -0
  35. package/dist/api/errors.js.map +1 -0
  36. package/dist/api/input.d.ts +10 -0
  37. package/dist/api/input.d.ts.map +1 -0
  38. package/dist/api/input.js +73 -0
  39. package/dist/api/input.js.map +1 -0
  40. package/dist/api/runtime.d.ts +18 -0
  41. package/dist/api/runtime.d.ts.map +1 -0
  42. package/dist/api/runtime.js +7 -0
  43. package/dist/api/runtime.js.map +1 -0
  44. package/dist/api/types.d.ts +76 -0
  45. package/dist/api/types.d.ts.map +1 -0
  46. package/dist/api/types.js +17 -0
  47. package/dist/api/types.js.map +1 -0
  48. package/dist/bin/ts-release.js +39239 -0
  49. package/dist/capabilities/bun-targets.d.ts +3 -0
  50. package/dist/capabilities/bun-targets.d.ts.map +1 -0
  51. package/dist/capabilities/bun-targets.js +3 -0
  52. package/dist/capabilities/bun-targets.js.map +1 -0
  53. package/dist/capabilities/field-ownership.d.ts +17 -0
  54. package/dist/capabilities/field-ownership.d.ts.map +1 -0
  55. package/dist/capabilities/field-ownership.js +40 -0
  56. package/dist/capabilities/field-ownership.js.map +1 -0
  57. package/dist/capabilities/module.d.ts +91 -0
  58. package/dist/capabilities/module.d.ts.map +1 -0
  59. package/dist/capabilities/module.js +2 -0
  60. package/dist/capabilities/module.js.map +1 -0
  61. package/dist/capabilities/registry.d.ts +829 -0
  62. package/dist/capabilities/registry.d.ts.map +1 -0
  63. package/dist/capabilities/registry.js +291 -0
  64. package/dist/capabilities/registry.js.map +1 -0
  65. package/dist/config/config.d.ts +6 -0
  66. package/dist/config/config.d.ts.map +1 -0
  67. package/dist/config/config.js +42 -0
  68. package/dist/config/config.js.map +1 -0
  69. package/dist/correction/coordinator.d.ts +248 -0
  70. package/dist/correction/coordinator.d.ts.map +1 -0
  71. package/dist/correction/coordinator.js +274 -0
  72. package/dist/correction/coordinator.js.map +1 -0
  73. package/dist/correction/index.d.ts +3 -0
  74. package/dist/correction/index.d.ts.map +1 -0
  75. package/dist/correction/index.js +3 -0
  76. package/dist/correction/index.js.map +1 -0
  77. package/dist/correction/intent.d.ts +111 -0
  78. package/dist/correction/intent.d.ts.map +1 -0
  79. package/dist/correction/intent.js +146 -0
  80. package/dist/correction/intent.js.map +1 -0
  81. package/dist/drivers/archive.d.ts +8 -0
  82. package/dist/drivers/archive.d.ts.map +1 -0
  83. package/dist/drivers/archive.js +101 -0
  84. package/dist/drivers/archive.js.map +1 -0
  85. package/dist/drivers/contain.d.ts +6 -0
  86. package/dist/drivers/contain.d.ts.map +1 -0
  87. package/dist/drivers/contain.js +17 -0
  88. package/dist/drivers/contain.js.map +1 -0
  89. package/dist/drivers/environment.d.ts +4 -0
  90. package/dist/drivers/environment.d.ts.map +1 -0
  91. package/dist/drivers/environment.js +18 -0
  92. package/dist/drivers/environment.js.map +1 -0
  93. package/dist/drivers/errors.d.ts +9 -0
  94. package/dist/drivers/errors.d.ts.map +1 -0
  95. package/dist/drivers/errors.js +6 -0
  96. package/dist/drivers/errors.js.map +1 -0
  97. package/dist/drivers/glob.d.ts +2 -0
  98. package/dist/drivers/glob.d.ts.map +1 -0
  99. package/dist/drivers/glob.js +162 -0
  100. package/dist/drivers/glob.js.map +1 -0
  101. package/dist/drivers/process.d.ts +48 -0
  102. package/dist/drivers/process.d.ts.map +1 -0
  103. package/dist/drivers/process.js +257 -0
  104. package/dist/drivers/process.js.map +1 -0
  105. package/dist/drivers/redact.d.ts +4 -0
  106. package/dist/drivers/redact.d.ts.map +1 -0
  107. package/dist/drivers/redact.js +24 -0
  108. package/dist/drivers/redact.js.map +1 -0
  109. package/dist/drivers/seccomp-helper-source.d.ts +7 -0
  110. package/dist/drivers/seccomp-helper-source.d.ts.map +1 -0
  111. package/dist/drivers/seccomp-helper-source.js +121 -0
  112. package/dist/drivers/seccomp-helper-source.js.map +1 -0
  113. package/dist/drivers/utils.d.ts +4 -0
  114. package/dist/drivers/utils.d.ts.map +1 -0
  115. package/dist/drivers/utils.js +5 -0
  116. package/dist/drivers/utils.js.map +1 -0
  117. package/dist/drivers/workspace.d.ts +6 -0
  118. package/dist/drivers/workspace.d.ts.map +1 -0
  119. package/dist/drivers/workspace.js +49 -0
  120. package/dist/drivers/workspace.js.map +1 -0
  121. package/dist/extensions/provider-adapter.d.ts +48 -0
  122. package/dist/extensions/provider-adapter.d.ts.map +1 -0
  123. package/dist/extensions/provider-adapter.js +64 -0
  124. package/dist/extensions/provider-adapter.js.map +1 -0
  125. package/dist/host.d.ts +33 -0
  126. package/dist/host.d.ts.map +1 -0
  127. package/dist/host.js +20 -0
  128. package/dist/host.js.map +1 -0
  129. package/dist/index.d.ts +19 -1
  130. package/dist/index.d.ts.map +1 -1
  131. package/dist/index.js +12 -1
  132. package/dist/index.js.map +1 -1
  133. package/dist/model/artifact-collection.d.ts +84 -0
  134. package/dist/model/artifact-collection.d.ts.map +1 -0
  135. package/dist/model/artifact-collection.js +185 -0
  136. package/dist/model/artifact-collection.js.map +1 -0
  137. package/dist/model/authority.d.ts +89 -0
  138. package/dist/model/authority.d.ts.map +1 -0
  139. package/dist/model/authority.js +80 -0
  140. package/dist/model/authority.js.map +1 -0
  141. package/dist/model/bun-targets.d.ts +34 -0
  142. package/dist/model/bun-targets.d.ts.map +1 -0
  143. package/dist/model/bun-targets.js +17 -0
  144. package/dist/model/bun-targets.js.map +1 -0
  145. package/dist/model/canonical.d.ts +8 -0
  146. package/dist/model/canonical.d.ts.map +1 -0
  147. package/dist/model/canonical.js +205 -0
  148. package/dist/model/canonical.js.map +1 -0
  149. package/dist/model/catalog.d.ts +76 -0
  150. package/dist/model/catalog.d.ts.map +1 -0
  151. package/dist/model/catalog.js +174 -0
  152. package/dist/model/catalog.js.map +1 -0
  153. package/dist/model/digest.d.ts +53 -0
  154. package/dist/model/digest.d.ts.map +1 -0
  155. package/dist/model/digest.js +127 -0
  156. package/dist/model/digest.js.map +1 -0
  157. package/dist/model/errors.d.ts +14 -0
  158. package/dist/model/errors.d.ts.map +1 -0
  159. package/dist/model/errors.js +8 -0
  160. package/dist/model/errors.js.map +1 -0
  161. package/dist/model/primitives.d.ts +19 -0
  162. package/dist/model/primitives.d.ts.map +1 -0
  163. package/dist/model/primitives.js +18 -0
  164. package/dist/model/primitives.js.map +1 -0
  165. package/dist/model/pypi.d.ts +12 -0
  166. package/dist/model/pypi.d.ts.map +1 -0
  167. package/dist/model/pypi.js +20 -0
  168. package/dist/model/pypi.js.map +1 -0
  169. package/dist/model/python-distribution.d.ts +33 -0
  170. package/dist/model/python-distribution.d.ts.map +1 -0
  171. package/dist/model/python-distribution.js +367 -0
  172. package/dist/model/python-distribution.js.map +1 -0
  173. package/dist/model/secret-patterns.d.ts +2 -0
  174. package/dist/model/secret-patterns.d.ts.map +1 -0
  175. package/dist/model/secret-patterns.js +12 -0
  176. package/dist/model/secret-patterns.js.map +1 -0
  177. package/dist/platform/bun.d.ts +7 -0
  178. package/dist/platform/bun.d.ts.map +1 -0
  179. package/dist/platform/bun.js +15 -0
  180. package/dist/platform/bun.js.map +1 -0
  181. package/dist/platform/credentials.d.ts +32 -0
  182. package/dist/platform/credentials.d.ts.map +1 -0
  183. package/dist/platform/credentials.js +772 -0
  184. package/dist/platform/credentials.js.map +1 -0
  185. package/dist/platform/host-support.d.ts +2 -0
  186. package/dist/platform/host-support.d.ts.map +1 -0
  187. package/dist/platform/host-support.js +4 -0
  188. package/dist/platform/host-support.js.map +1 -0
  189. package/dist/platform/node.d.ts +7 -0
  190. package/dist/platform/node.d.ts.map +1 -0
  191. package/dist/platform/node.js +15 -0
  192. package/dist/platform/node.js.map +1 -0
  193. package/dist/platform/release-runtime.d.ts +11 -0
  194. package/dist/platform/release-runtime.d.ts.map +1 -0
  195. package/dist/platform/release-runtime.js +34 -0
  196. package/dist/platform/release-runtime.js.map +1 -0
  197. package/dist/platform/services.d.ts +15 -0
  198. package/dist/platform/services.d.ts.map +1 -0
  199. package/dist/platform/services.js +30 -0
  200. package/dist/platform/services.js.map +1 -0
  201. package/dist/platform/source-observer.d.ts +5 -0
  202. package/dist/platform/source-observer.d.ts.map +1 -0
  203. package/dist/platform/source-observer.js +159 -0
  204. package/dist/platform/source-observer.js.map +1 -0
  205. package/dist/provider-sdk.d.ts +14 -0
  206. package/dist/provider-sdk.d.ts.map +1 -0
  207. package/dist/provider-sdk.js +10 -0
  208. package/dist/provider-sdk.js.map +1 -0
  209. package/dist/publication/adapter.d.ts +212 -0
  210. package/dist/publication/adapter.d.ts.map +1 -0
  211. package/dist/publication/adapter.js +83 -0
  212. package/dist/publication/adapter.js.map +1 -0
  213. package/dist/publication/authority.d.ts +137 -0
  214. package/dist/publication/authority.d.ts.map +1 -0
  215. package/dist/publication/authority.js +233 -0
  216. package/dist/publication/authority.js.map +1 -0
  217. package/dist/publication/catalog-git.d.ts +37 -0
  218. package/dist/publication/catalog-git.d.ts.map +1 -0
  219. package/dist/publication/catalog-git.js +451 -0
  220. package/dist/publication/catalog-git.js.map +1 -0
  221. package/dist/publication/claim.d.ts +39 -0
  222. package/dist/publication/claim.d.ts.map +1 -0
  223. package/dist/publication/claim.js +31 -0
  224. package/dist/publication/claim.js.map +1 -0
  225. package/dist/publication/coordinator.d.ts +246 -0
  226. package/dist/publication/coordinator.d.ts.map +1 -0
  227. package/dist/publication/coordinator.js +370 -0
  228. package/dist/publication/coordinator.js.map +1 -0
  229. package/dist/publication/github.d.ts +36 -0
  230. package/dist/publication/github.d.ts.map +1 -0
  231. package/dist/publication/github.js +644 -0
  232. package/dist/publication/github.js.map +1 -0
  233. package/dist/publication/http.d.ts +69 -0
  234. package/dist/publication/http.d.ts.map +1 -0
  235. package/dist/publication/http.js +29 -0
  236. package/dist/publication/http.js.map +1 -0
  237. package/dist/publication/index.d.ts +5 -0
  238. package/dist/publication/index.d.ts.map +1 -0
  239. package/dist/publication/index.js +5 -0
  240. package/dist/publication/index.js.map +1 -0
  241. package/dist/publication/npm.d.ts +40 -0
  242. package/dist/publication/npm.d.ts.map +1 -0
  243. package/dist/publication/npm.js +359 -0
  244. package/dist/publication/npm.js.map +1 -0
  245. package/dist/publication/profiles.d.ts +136 -0
  246. package/dist/publication/profiles.d.ts.map +1 -0
  247. package/dist/publication/profiles.js +90 -0
  248. package/dist/publication/profiles.js.map +1 -0
  249. package/dist/publication/publisher.d.ts +82 -0
  250. package/dist/publication/publisher.d.ts.map +1 -0
  251. package/dist/publication/publisher.js +53 -0
  252. package/dist/publication/publisher.js.map +1 -0
  253. package/dist/publication/pypi.d.ts +45 -0
  254. package/dist/publication/pypi.d.ts.map +1 -0
  255. package/dist/publication/pypi.js +369 -0
  256. package/dist/publication/pypi.js.map +1 -0
  257. package/dist/publication/recovery.d.ts +663 -0
  258. package/dist/publication/recovery.d.ts.map +1 -0
  259. package/dist/publication/recovery.js +252 -0
  260. package/dist/publication/recovery.js.map +1 -0
  261. package/dist/publication/report.d.ts +1061 -0
  262. package/dist/publication/report.d.ts.map +1 -0
  263. package/dist/publication/report.js +441 -0
  264. package/dist/publication/report.js.map +1 -0
  265. package/dist/recipes/config.d.ts +296 -0
  266. package/dist/recipes/config.d.ts.map +1 -0
  267. package/dist/recipes/config.js +325 -0
  268. package/dist/recipes/config.js.map +1 -0
  269. package/dist/release/capabilities.d.ts +12 -0
  270. package/dist/release/capabilities.d.ts.map +1 -0
  271. package/dist/release/capabilities.js +395 -0
  272. package/dist/release/capabilities.js.map +1 -0
  273. package/dist/release/compiler.d.ts +5 -0
  274. package/dist/release/compiler.d.ts.map +1 -0
  275. package/dist/release/compiler.js +19 -0
  276. package/dist/release/compiler.js.map +1 -0
  277. package/dist/release/config.d.ts +5 -0
  278. package/dist/release/config.d.ts.map +1 -0
  279. package/dist/release/config.js +10 -0
  280. package/dist/release/config.js.map +1 -0
  281. package/dist/release/context.d.ts +96 -0
  282. package/dist/release/context.d.ts.map +1 -0
  283. package/dist/release/context.js +168 -0
  284. package/dist/release/context.js.map +1 -0
  285. package/dist/release/graph.d.ts +271 -0
  286. package/dist/release/graph.d.ts.map +1 -0
  287. package/dist/release/graph.js +766 -0
  288. package/dist/release/graph.js.map +1 -0
  289. package/dist/release/inspect.d.ts +88 -0
  290. package/dist/release/inspect.d.ts.map +1 -0
  291. package/dist/release/inspect.js +75 -0
  292. package/dist/release/inspect.js.map +1 -0
  293. package/dist/release/prepare.d.ts +24 -0
  294. package/dist/release/prepare.d.ts.map +1 -0
  295. package/dist/release/prepare.js +1116 -0
  296. package/dist/release/prepare.js.map +1 -0
  297. package/dist/release/prepared-ref.d.ts +60 -0
  298. package/dist/release/prepared-ref.d.ts.map +1 -0
  299. package/dist/release/prepared-ref.js +131 -0
  300. package/dist/release/prepared-ref.js.map +1 -0
  301. package/dist/release/prepared-store.d.ts +90 -0
  302. package/dist/release/prepared-store.d.ts.map +1 -0
  303. package/dist/release/prepared-store.js +337 -0
  304. package/dist/release/prepared-store.js.map +1 -0
  305. package/dist/release/prepared.d.ts +172 -0
  306. package/dist/release/prepared.d.ts.map +1 -0
  307. package/dist/release/prepared.js +268 -0
  308. package/dist/release/prepared.js.map +1 -0
  309. package/dist/release/staging.d.ts +31 -0
  310. package/dist/release/staging.d.ts.map +1 -0
  311. package/dist/release/staging.js +218 -0
  312. package/dist/release/staging.js.map +1 -0
  313. package/dist/resolve/authored.d.ts +53 -0
  314. package/dist/resolve/authored.d.ts.map +1 -0
  315. package/dist/resolve/authored.js +55 -0
  316. package/dist/resolve/authored.js.map +1 -0
  317. package/dist/resolve/encode.d.ts +3 -0
  318. package/dist/resolve/encode.d.ts.map +1 -0
  319. package/dist/resolve/encode.js +21 -0
  320. package/dist/resolve/encode.js.map +1 -0
  321. package/dist/resolve/errors.d.ts +7 -0
  322. package/dist/resolve/errors.d.ts.map +1 -0
  323. package/dist/resolve/errors.js +17 -0
  324. package/dist/resolve/errors.js.map +1 -0
  325. package/dist/resolve/facts.d.ts +12 -0
  326. package/dist/resolve/facts.d.ts.map +1 -0
  327. package/dist/resolve/facts.js +18 -0
  328. package/dist/resolve/facts.js.map +1 -0
  329. package/dist/resolve/resolve.d.ts +10 -0
  330. package/dist/resolve/resolve.d.ts.map +1 -0
  331. package/dist/resolve/resolve.js +242 -0
  332. package/dist/resolve/resolve.js.map +1 -0
  333. package/dist/store.d.ts +11 -0
  334. package/dist/store.d.ts.map +1 -0
  335. package/dist/store.js +9 -0
  336. package/dist/store.js.map +1 -0
  337. package/examples/README.md +20 -30
  338. package/examples/github-release/release.config.json +11 -18
  339. package/examples/homebrew-tap/README.md +11 -0
  340. package/examples/homebrew-tap/release.config.json +40 -28
  341. package/examples/multi-target/release.config.json +28 -53
  342. package/examples/npm-first-publish/release.config.json +23 -25
  343. package/examples/npm-only/release.config.json +22 -30
  344. package/examples/portable-cli/README.md +17 -0
  345. package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-arm64 +1 -0
  346. package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-x64 +1 -0
  347. package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-arm64 +1 -0
  348. package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-x64 +1 -0
  349. package/examples/portable-cli/artifacts/portable-example-0.1.0-windows-x64.exe +1 -0
  350. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_10_15_x86_64.whl +1 -0
  351. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_11_0_arm64.whl +1 -0
  352. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_aarch64.whl +1 -0
  353. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_x86_64.whl +1 -0
  354. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-win_amd64.whl +1 -0
  355. package/examples/portable-cli/package.json +9 -0
  356. package/examples/portable-cli/release.config.json +53 -0
  357. package/examples/portable-cli/src/cli.ts +3 -0
  358. package/examples/pypi-registry/README.md +8 -0
  359. package/examples/scoop-bucket/README.md +10 -0
  360. package/examples/scoop-bucket/release.config.json +40 -30
  361. package/package.json +61 -154
  362. package/src/api/api.ts +365 -0
  363. package/src/api/errors.ts +36 -0
  364. package/src/api/input.ts +92 -0
  365. package/src/api/runtime.ts +14 -0
  366. package/src/api/types.ts +103 -0
  367. package/src/capabilities/bun-targets.ts +2 -0
  368. package/src/capabilities/field-ownership.ts +60 -0
  369. package/src/capabilities/module.ts +158 -0
  370. package/src/capabilities/registry.ts +333 -0
  371. package/src/config/config.ts +48 -0
  372. package/src/correction/coordinator.ts +336 -0
  373. package/src/correction/index.ts +2 -0
  374. package/src/correction/intent.ts +172 -0
  375. package/src/drivers/archive.ts +102 -0
  376. package/src/drivers/contain.ts +20 -0
  377. package/src/drivers/environment.ts +28 -0
  378. package/src/drivers/errors.ts +6 -0
  379. package/src/drivers/glob.ts +137 -0
  380. package/src/drivers/process.ts +340 -0
  381. package/src/drivers/redact.ts +31 -0
  382. package/src/drivers/seccomp-helper-source.ts +121 -0
  383. package/src/drivers/utils.ts +10 -0
  384. package/src/drivers/workspace.ts +40 -0
  385. package/src/extensions/provider-adapter.ts +99 -0
  386. package/src/host.ts +140 -0
  387. package/src/index.ts +64 -0
  388. package/src/model/artifact-collection.ts +237 -0
  389. package/src/model/authority.ts +116 -0
  390. package/src/model/bun-targets.ts +34 -0
  391. package/src/model/canonical.ts +205 -0
  392. package/src/model/catalog.ts +220 -0
  393. package/src/model/digest.ts +172 -0
  394. package/src/model/errors.ts +6 -0
  395. package/src/model/primitives.ts +37 -0
  396. package/src/model/pypi.ts +30 -0
  397. package/src/model/python-distribution.ts +360 -0
  398. package/src/model/secret-patterns.ts +11 -0
  399. package/src/platform/bun.ts +38 -0
  400. package/src/platform/credentials.ts +1083 -0
  401. package/src/platform/host-support.ts +4 -0
  402. package/src/platform/node.ts +38 -0
  403. package/src/platform/release-runtime.ts +47 -0
  404. package/src/platform/services.ts +57 -0
  405. package/src/platform/source-observer.ts +193 -0
  406. package/src/provider-sdk.ts +48 -0
  407. package/src/publication/adapter.ts +132 -0
  408. package/src/publication/authority.ts +397 -0
  409. package/src/publication/catalog-git.ts +603 -0
  410. package/src/publication/claim.ts +51 -0
  411. package/src/publication/coordinator.ts +578 -0
  412. package/src/publication/github.ts +954 -0
  413. package/src/publication/http.ts +101 -0
  414. package/src/publication/index.ts +4 -0
  415. package/src/publication/npm.ts +525 -0
  416. package/src/publication/profiles.ts +94 -0
  417. package/src/publication/publisher.ts +130 -0
  418. package/src/publication/pypi.ts +463 -0
  419. package/src/publication/recovery.ts +349 -0
  420. package/src/publication/report.ts +628 -0
  421. package/src/recipes/config.ts +395 -0
  422. package/src/release/capabilities.ts +459 -0
  423. package/src/release/compiler.ts +28 -0
  424. package/src/release/config.ts +12 -0
  425. package/src/release/context.ts +223 -0
  426. package/src/release/graph.ts +866 -0
  427. package/src/release/inspect.ts +83 -0
  428. package/src/release/prepare.ts +1331 -0
  429. package/src/release/prepared-ref.ts +193 -0
  430. package/src/release/prepared-store.ts +377 -0
  431. package/src/release/prepared.ts +299 -0
  432. package/src/release/staging.ts +257 -0
  433. package/src/resolve/authored.ts +64 -0
  434. package/src/resolve/encode.ts +22 -0
  435. package/src/resolve/errors.ts +15 -0
  436. package/src/resolve/facts.ts +18 -0
  437. package/src/resolve/resolve.ts +328 -0
  438. package/src/store.ts +28 -0
  439. package/templates/README.md +55 -59
  440. package/templates/bun-cli-github/README.md +12 -0
  441. package/templates/bun-cli-github/release.config.json +51 -0
  442. package/templates/github-actions/release.yml +57 -0
  443. package/templates/github-actions/reviewed-release.yml +80 -0
  444. package/templates/multi-target-homebrew/README.md +10 -0
  445. package/templates/multi-target-homebrew/release.config.json +43 -60
  446. package/templates/multi-target-scoop/README.md +10 -0
  447. package/templates/multi-target-scoop/release.config.json +43 -62
  448. package/templates/npm-github/release.config.json +25 -38
  449. package/templates/npm-github/reviewed-release.config.json +37 -0
  450. package/templates/npm-only/README.md +10 -0
  451. package/templates/npm-only/release.config.json +15 -30
  452. package/templates/portable-cli/README.md +13 -0
  453. package/templates/portable-cli/release.config.json +53 -0
  454. package/dist/config/errors.d.ts +0 -24
  455. package/dist/config/errors.d.ts.map +0 -1
  456. package/dist/config/errors.js +0 -19
  457. package/dist/config/errors.js.map +0 -1
  458. package/dist/config/load.d.ts +0 -9
  459. package/dist/config/load.d.ts.map +0 -1
  460. package/dist/config/load.js +0 -29
  461. package/dist/config/load.js.map +0 -1
  462. package/dist/config/schema.d.ts +0 -12
  463. package/dist/config/schema.d.ts.map +0 -1
  464. package/dist/config/schema.js +0 -19
  465. package/dist/config/schema.js.map +0 -1
  466. package/dist/domain/artifact.d.ts +0 -36
  467. package/dist/domain/artifact.d.ts.map +0 -1
  468. package/dist/domain/artifact.js +0 -29
  469. package/dist/domain/artifact.js.map +0 -1
  470. package/dist/domain/evidence.d.ts +0 -108
  471. package/dist/domain/evidence.d.ts.map +0 -1
  472. package/dist/domain/evidence.js +0 -96
  473. package/dist/domain/evidence.js.map +0 -1
  474. package/dist/domain/operation.d.ts +0 -153
  475. package/dist/domain/operation.d.ts.map +0 -1
  476. package/dist/domain/operation.js +0 -320
  477. package/dist/domain/operation.js.map +0 -1
  478. package/dist/domain/release.d.ts +0 -141
  479. package/dist/domain/release.d.ts.map +0 -1
  480. package/dist/domain/release.js +0 -127
  481. package/dist/domain/release.js.map +0 -1
  482. package/dist/domain/remote-state.d.ts +0 -85
  483. package/dist/domain/remote-state.d.ts.map +0 -1
  484. package/dist/domain/remote-state.js +0 -77
  485. package/dist/domain/remote-state.js.map +0 -1
  486. package/dist/domain/status.d.ts +0 -43
  487. package/dist/domain/status.d.ts.map +0 -1
  488. package/dist/domain/status.js +0 -51
  489. package/dist/domain/status.js.map +0 -1
  490. package/dist/domain/target.d.ts +0 -135
  491. package/dist/domain/target.d.ts.map +0 -1
  492. package/dist/domain/target.js +0 -137
  493. package/dist/domain/target.js.map +0 -1
  494. package/dist/host/host.d.ts +0 -32
  495. package/dist/host/host.d.ts.map +0 -1
  496. package/dist/host/host.js +0 -24
  497. package/dist/host/host.js.map +0 -1
  498. package/dist/host/http-live.d.ts +0 -6
  499. package/dist/host/http-live.d.ts.map +0 -1
  500. package/dist/host/http-live.js +0 -86
  501. package/dist/host/http-live.js.map +0 -1
  502. package/dist/host/http.d.ts +0 -43
  503. package/dist/host/http.d.ts.map +0 -1
  504. package/dist/host/http.js +0 -59
  505. package/dist/host/http.js.map +0 -1
  506. package/dist/host/platform.d.ts +0 -10
  507. package/dist/host/platform.d.ts.map +0 -1
  508. package/dist/host/platform.js +0 -114
  509. package/dist/host/platform.js.map +0 -1
  510. package/dist/host/test.d.ts +0 -23
  511. package/dist/host/test.d.ts.map +0 -1
  512. package/dist/host/test.js +0 -222
  513. package/dist/host/test.js.map +0 -1
  514. package/dist/internal/workflow-phases.d.ts +0 -3
  515. package/dist/internal/workflow-phases.d.ts.map +0 -1
  516. package/dist/internal/workflow-phases.js +0 -2
  517. package/dist/internal/workflow-phases.js.map +0 -1
  518. package/dist/internal/workspace-path.d.ts +0 -15
  519. package/dist/internal/workspace-path.d.ts.map +0 -1
  520. package/dist/internal/workspace-path.js +0 -36
  521. package/dist/internal/workspace-path.js.map +0 -1
  522. package/dist/planner/artifact-inventory.d.ts +0 -9
  523. package/dist/planner/artifact-inventory.d.ts.map +0 -1
  524. package/dist/planner/artifact-inventory.js +0 -84
  525. package/dist/planner/artifact-inventory.js.map +0 -1
  526. package/dist/planner/create-release-plan.d.ts +0 -5
  527. package/dist/planner/create-release-plan.d.ts.map +0 -1
  528. package/dist/planner/create-release-plan.js +0 -25
  529. package/dist/planner/create-release-plan.js.map +0 -1
  530. package/dist/planner/errors.d.ts +0 -81
  531. package/dist/planner/errors.d.ts.map +0 -1
  532. package/dist/planner/errors.js +0 -70
  533. package/dist/planner/errors.js.map +0 -1
  534. package/dist/planner/evidence-recorder.d.ts +0 -26
  535. package/dist/planner/evidence-recorder.d.ts.map +0 -1
  536. package/dist/planner/evidence-recorder.js +0 -330
  537. package/dist/planner/evidence-recorder.js.map +0 -1
  538. package/dist/planner/executor.d.ts +0 -58
  539. package/dist/planner/executor.d.ts.map +0 -1
  540. package/dist/planner/executor.js +0 -159
  541. package/dist/planner/executor.js.map +0 -1
  542. package/dist/planner/normalize-release.d.ts +0 -16
  543. package/dist/planner/normalize-release.d.ts.map +0 -1
  544. package/dist/planner/normalize-release.js +0 -218
  545. package/dist/planner/normalize-release.js.map +0 -1
  546. package/dist/planner/reconcile.d.ts +0 -17
  547. package/dist/planner/reconcile.d.ts.map +0 -1
  548. package/dist/planner/reconcile.js +0 -261
  549. package/dist/planner/reconcile.js.map +0 -1
  550. package/dist/planner/release-eligibility.d.ts +0 -39
  551. package/dist/planner/release-eligibility.d.ts.map +0 -1
  552. package/dist/planner/release-eligibility.js +0 -578
  553. package/dist/planner/release-eligibility.js.map +0 -1
  554. package/dist/planner/render-plan.d.ts +0 -15
  555. package/dist/planner/render-plan.d.ts.map +0 -1
  556. package/dist/planner/render-plan.js +0 -238
  557. package/dist/planner/render-plan.js.map +0 -1
  558. package/dist/planner/status.d.ts +0 -40
  559. package/dist/planner/status.d.ts.map +0 -1
  560. package/dist/planner/status.js +0 -313
  561. package/dist/planner/status.js.map +0 -1
  562. package/dist/targets/adapter-helpers.d.ts +0 -64
  563. package/dist/targets/adapter-helpers.d.ts.map +0 -1
  564. package/dist/targets/adapter-helpers.js +0 -124
  565. package/dist/targets/adapter-helpers.js.map +0 -1
  566. package/dist/targets/adapter.d.ts +0 -17
  567. package/dist/targets/adapter.d.ts.map +0 -1
  568. package/dist/targets/adapter.js +0 -2
  569. package/dist/targets/adapter.js.map +0 -1
  570. package/dist/targets/github-release.d.ts +0 -25
  571. package/dist/targets/github-release.d.ts.map +0 -1
  572. package/dist/targets/github-release.js +0 -82
  573. package/dist/targets/github-release.js.map +0 -1
  574. package/dist/targets/github.d.ts +0 -11
  575. package/dist/targets/github.d.ts.map +0 -1
  576. package/dist/targets/github.js +0 -125
  577. package/dist/targets/github.js.map +0 -1
  578. package/dist/targets/homebrew.d.ts +0 -11
  579. package/dist/targets/homebrew.d.ts.map +0 -1
  580. package/dist/targets/homebrew.js +0 -97
  581. package/dist/targets/homebrew.js.map +0 -1
  582. package/dist/targets/live.d.ts +0 -5
  583. package/dist/targets/live.d.ts.map +0 -1
  584. package/dist/targets/live.js +0 -50
  585. package/dist/targets/live.js.map +0 -1
  586. package/dist/targets/npm.d.ts +0 -10
  587. package/dist/targets/npm.d.ts.map +0 -1
  588. package/dist/targets/npm.js +0 -118
  589. package/dist/targets/npm.js.map +0 -1
  590. package/dist/targets/pypi.d.ts +0 -11
  591. package/dist/targets/pypi.d.ts.map +0 -1
  592. package/dist/targets/pypi.js +0 -103
  593. package/dist/targets/pypi.js.map +0 -1
  594. package/dist/targets/registry.d.ts +0 -25
  595. package/dist/targets/registry.d.ts.map +0 -1
  596. package/dist/targets/registry.js +0 -34
  597. package/dist/targets/registry.js.map +0 -1
  598. package/dist/targets/scoop.d.ts +0 -11
  599. package/dist/targets/scoop.d.ts.map +0 -1
  600. package/dist/targets/scoop.js +0 -78
  601. package/dist/targets/scoop.js.map +0 -1
  602. package/dist/types/effect-internal.d.ts +0 -5
  603. package/dist/types/effect-internal.d.ts.map +0 -1
  604. package/dist/types/effect-internal.js +0 -2
  605. package/dist/types/effect-internal.js.map +0 -1
  606. package/dist/workflows/config.d.ts +0 -252
  607. package/dist/workflows/config.d.ts.map +0 -1
  608. package/dist/workflows/config.js +0 -465
  609. package/dist/workflows/config.js.map +0 -1
  610. package/dist/workflows/diagnostics.d.ts +0 -62
  611. package/dist/workflows/diagnostics.d.ts.map +0 -1
  612. package/dist/workflows/diagnostics.js +0 -527
  613. package/dist/workflows/diagnostics.js.map +0 -1
  614. package/dist/workflows/evidence.d.ts +0 -26
  615. package/dist/workflows/evidence.d.ts.map +0 -1
  616. package/dist/workflows/evidence.js +0 -44
  617. package/dist/workflows/evidence.js.map +0 -1
  618. package/dist/workflows/index.d.ts +0 -7
  619. package/dist/workflows/index.d.ts.map +0 -1
  620. package/dist/workflows/index.js +0 -6
  621. package/dist/workflows/index.js.map +0 -1
  622. package/dist/workflows/init.d.ts +0 -84
  623. package/dist/workflows/init.d.ts.map +0 -1
  624. package/dist/workflows/init.js +0 -441
  625. package/dist/workflows/init.js.map +0 -1
  626. package/dist/workflows/live.d.ts +0 -9
  627. package/dist/workflows/live.d.ts.map +0 -1
  628. package/dist/workflows/live.js +0 -7
  629. package/dist/workflows/live.js.map +0 -1
  630. package/dist/workflows/options.d.ts +0 -30
  631. package/dist/workflows/options.d.ts.map +0 -1
  632. package/dist/workflows/options.js +0 -16
  633. package/dist/workflows/options.js.map +0 -1
  634. package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +0 -1
  635. package/examples/non-strict-skips/release.config.json +0 -31
  636. package/examples/pypi-registry/release.config.json +0 -31
  637. package/templates/github-actions/plan-and-approved-execute.yml +0 -58
  638. package/templates/github-actions/plan-only.yml +0 -33
  639. package/templates/github-actions/trusted-publishing.yml +0 -61
@@ -0,0 +1,336 @@
1
+ import * as Effect from "effect/Effect"
2
+ import * as Schema from "effect/Schema"
3
+ import { encodeCanonicalJson } from "../model/canonical.js"
4
+ import { digestEquals, parseSha256Hex, sha256Digest, sha512Digest } from "../model/digest.js"
5
+ import {
6
+ CatalogManagedState,
7
+ PreparedCatalogDownload,
8
+ compareCatalogVersions,
9
+ decodeCatalogManagedState,
10
+ encodeCatalogManagedState,
11
+ renderCatalog
12
+ } from "../model/catalog.js"
13
+ import { SubjectId } from "../model/authority.js"
14
+ import type { CredentialProviderShape } from "../publication/authority.js"
15
+ import { CredentialProvider } from "../publication/authority.js"
16
+ import { publishReleaseSubjects } from "../publication/coordinator.js"
17
+ import type { AuthorizedMutationHttpShape, HttpAuthorizerShape } from "../publication/http.js"
18
+ import { makeCatalogSubject } from "../publication/catalog-git.js"
19
+ import type { ReleaseReport } from "../publication/report.js"
20
+ import {
21
+ PreparedPublication,
22
+ encodePreparedRelease,
23
+ type PreparedPublication as PreparedPublicationType
24
+ } from "../release/prepared.js"
25
+ import type { PreparedBundle } from "../release/prepared-store.js"
26
+ import {
27
+ type AuthoredCorrection,
28
+ CorrectionIntentV2,
29
+ encodeCorrectionIntent,
30
+ makeCorrectionIntent,
31
+ type CorrectionIntent,
32
+ type CatalogForwardCorrection,
33
+ type GithubReleaseCorrection,
34
+ type NpmDeprecationCorrection
35
+ } from "./intent.js"
36
+
37
+ export class CorrectionValidationError
38
+ extends Schema.TaggedErrorClass<CorrectionValidationError>()("CorrectionValidationError", {
39
+ reason: Schema.String
40
+ }) {}
41
+
42
+ export class CorrectionUnsupported extends Schema.TaggedClass<CorrectionUnsupported>()("CorrectionUnsupported", {
43
+ provider: Schema.Literals(["npm", "github", "catalog-git"]), reason: Schema.String, evidence: Schema.NonEmptyString,
44
+ proposal: Schema.optionalKey(Schema.String)
45
+ }) {}
46
+
47
+ export interface CorrectionExecuted {
48
+ readonly _tag: "CorrectionExecuted"
49
+ readonly provider: "catalog-git"
50
+ readonly report: ReleaseReport
51
+ readonly reason: string
52
+ readonly evidence: string
53
+ readonly proposal: string
54
+ }
55
+
56
+ export type CorrectionOutcome = typeof CorrectionUnsupported.Type | CorrectionExecuted
57
+
58
+ const preparedDigest = (bundle: PreparedBundle) => sha256Digest(encodePreparedRelease(bundle.manifest))
59
+ const publicationBaselineDigest = (publication: PreparedPublicationType) => sha256Digest(
60
+ new TextEncoder().encode(encodeCanonicalJson(Schema.encodeSync(PreparedPublication)(publication)))
61
+ )
62
+ const findPublication = (bundle: PreparedBundle, id: string) => bundle.manifest.publications.find((publication) => publication.id.toString() === id)
63
+
64
+ const choosePublication = <Tag extends "PreparedNpmPublication" | "PreparedGitHubPublication" | "PreparedCatalogPublication">(
65
+ bundle: PreparedBundle,
66
+ tag: Tag,
67
+ publicationId?: { readonly toString: () => string }
68
+ ): Extract<PreparedBundle["manifest"]["publications"][number], { readonly _tag: Tag }> => {
69
+ const candidates = bundle.manifest.publications.filter((publication): publication is Extract<
70
+ PreparedBundle["manifest"]["publications"][number],
71
+ { readonly _tag: Tag }
72
+ > => publication._tag === tag && (
73
+ publicationId === undefined || publication.id.toString() === publicationId.toString()
74
+ ))
75
+ if (candidates.length !== 1) {
76
+ throw new Error(publicationId === undefined
77
+ ? `Authored correction requires exactly one ${tag === "PreparedNpmPublication" ? "npm" : tag === "PreparedGitHubPublication" ? "GitHub" : "catalog Git"} publication; specify publicationId when more than one exists.`
78
+ : `Authored correction publicationId ${publicationId} does not identify exactly one prepared ${tag === "PreparedNpmPublication" ? "npm" : tag === "PreparedGitHubPublication" ? "GitHub" : "catalog Git"} publication.`)
79
+ }
80
+ return candidates[0]!
81
+ }
82
+
83
+ /** Resolve human intent only after the exact prepared bundle has been loaded. */
84
+ export const bindAuthoredCorrection = (
85
+ bundle: PreparedBundle,
86
+ authored: AuthoredCorrection
87
+ ): CorrectionIntent => {
88
+ const digest = preparedDigest(bundle)
89
+ if (authored.provider === "npm") {
90
+ const publication = choosePublication(bundle, "PreparedNpmPublication", authored.publicationId)
91
+ const artifact = bundle.manifest.artifacts.find((candidate) => candidate.id === publication.artifactId)
92
+ const bytes = artifact === undefined ? undefined : bundle.blobs.get(artifact.id.toString())
93
+ if (bytes === undefined) throw new Error("Prepared npm correction subject has no verified tarball bytes.")
94
+ return makeCorrectionIntent({
95
+ schemaVersion: "correction-intent/v2",
96
+ preparedDigest: digest,
97
+ correction: {
98
+ _tag: "NpmDeprecationCorrection",
99
+ provider: "npm",
100
+ publicationId: publication.id,
101
+ registryUrl: publication.registryUrl,
102
+ packageName: publication.packageName,
103
+ version: publication.version,
104
+ baselineDigest: publicationBaselineDigest(publication),
105
+ tarballIntegrity: sha512Digest(bytes),
106
+ message: authored.message,
107
+ ...(authored.replacement === undefined ? {} : { replacement: authored.replacement })
108
+ }
109
+ })
110
+ }
111
+ if (authored.provider === "catalog-git") {
112
+ const publication = choosePublication(bundle, "PreparedCatalogPublication", authored.publicationId)
113
+ if (compareCatalogVersions(publication.version.toString(), authored.replacementVersion.toString()) >= 0) {
114
+ throw new Error("Catalog correction replacementVersion must be SemVer-greater than the prepared generation.")
115
+ }
116
+ const expectedArchitectures = publication.renderer.downloads.map((download) => download.architecture).sort()
117
+ const observedArchitectures = authored.downloads.map((download) => download.architecture).sort()
118
+ if (new Set(observedArchitectures).size !== observedArchitectures.length ||
119
+ expectedArchitectures.join("\n") !== observedArchitectures.join("\n")) {
120
+ throw new Error("Catalog correction downloads must replace the exact prepared architecture set.")
121
+ }
122
+ const downloads = authored.downloads.map((download) => {
123
+ const expectedUrl = `https://github.com/${publication.sourceRepository}/releases/download/${encodeURIComponent(authored.replacementTag)}/${encodeURIComponent(download.filename)}`
124
+ if (download.url !== expectedUrl) {
125
+ throw new Error("Catalog correction download URL must be the exact replacement GitHub release asset coordinate.")
126
+ }
127
+ return PreparedCatalogDownload.make({
128
+ architecture: download.architecture,
129
+ url: download.url,
130
+ filename: download.filename,
131
+ sha256: parseSha256Hex(download.sha256)
132
+ })
133
+ }) as [PreparedCatalogDownload, ...Array<PreparedCatalogDownload>]
134
+ const target = bundle.blobs.get(publication.targetArtifactId.toString())
135
+ const state = bundle.blobs.get(publication.stateArtifactId.toString())
136
+ if (target === undefined || state === undefined ||
137
+ !digestEquals(sha256Digest(target), publication.targetDigest) ||
138
+ !digestEquals(sha256Digest(state), publication.stateDigest)) {
139
+ throw new Error("Prepared catalog correction subject has no exact target/state baseline bytes.")
140
+ }
141
+ const managed = decodeCatalogManagedState(state)
142
+ if (managed === undefined || managed.status !== "active" || managed.generation !== publication.version ||
143
+ !digestEquals(managed.targetDigest, publication.targetDigest)) {
144
+ throw new Error("Prepared catalog correction baseline is not one canonical active managed pair.")
145
+ }
146
+ return makeCorrectionIntent({
147
+ schemaVersion: "correction-intent/v2",
148
+ preparedDigest: digest,
149
+ correction: {
150
+ _tag: "CatalogForwardCorrection",
151
+ provider: "catalog-git",
152
+ publicationId: publication.id,
153
+ baselineDigest: publicationBaselineDigest(publication),
154
+ baselineTargetDigest: publication.targetDigest,
155
+ baselineStateDigest: publication.stateDigest,
156
+ replacementVersion: authored.replacementVersion,
157
+ replacementTag: authored.replacementTag,
158
+ downloads,
159
+ reason: authored.reason
160
+ }
161
+ })
162
+ }
163
+ const publication = choosePublication(bundle, "PreparedGitHubPublication", authored.publicationId)
164
+ return makeCorrectionIntent({
165
+ schemaVersion: "correction-intent/v2",
166
+ preparedDigest: digest,
167
+ correction: {
168
+ _tag: "GithubReleaseCorrection",
169
+ provider: "github",
170
+ publicationId: publication.id,
171
+ repository: publication.repository,
172
+ tag: publication.tag,
173
+ baselineDigest: publicationBaselineDigest(publication),
174
+ marker: authored.message,
175
+ ...(authored.replacement === undefined ? {} : { replacement: authored.replacement })
176
+ }
177
+ })
178
+ }
179
+
180
+ const verifyNpm = (bundle: PreparedBundle, correction: NpmDeprecationCorrection): void => {
181
+ const publication = findPublication(bundle, correction.publicationId.toString())
182
+ if (publication?._tag !== "PreparedNpmPublication" || publication.registryUrl !== correction.registryUrl ||
183
+ publication.packageName !== correction.packageName || publication.version !== correction.version) {
184
+ throw new Error("npm correction subject is not the exact npm publication in the prepared manifest.")
185
+ }
186
+ if (!digestEquals(publicationBaselineDigest(publication), correction.baselineDigest)) {
187
+ throw new Error("npm correction baseline digest is not the exact prepared publication digest.")
188
+ }
189
+ const artifact = bundle.manifest.artifacts.find((candidate) => candidate.id === publication.artifactId)
190
+ const bytes = artifact === undefined ? undefined : bundle.blobs.get(artifact.id.toString())
191
+ if (bytes === undefined) throw new Error("npm correction subject has no verified prepared tarball.")
192
+ const integrity = sha512Digest(bytes)
193
+ if (!digestEquals(integrity, correction.tarballIntegrity)) {
194
+ throw new Error("npm correction tarball integrity is not the prepared artifact integrity.")
195
+ }
196
+ }
197
+
198
+ const verifyGithub = (bundle: PreparedBundle, correction: GithubReleaseCorrection): void => {
199
+ const publication = findPublication(bundle, correction.publicationId.toString())
200
+ if (publication?._tag !== "PreparedGitHubPublication" || publication.repository !== correction.repository || publication.tag !== correction.tag) {
201
+ throw new Error("GitHub correction subject is not the exact GitHub publication in the prepared manifest.")
202
+ }
203
+ if (!digestEquals(publicationBaselineDigest(publication), correction.baselineDigest)) {
204
+ throw new Error("GitHub correction baseline digest is not the exact prepared publication digest.")
205
+ }
206
+ }
207
+
208
+ const verifyCatalog = (bundle: PreparedBundle, correction: CatalogForwardCorrection): void => {
209
+ const publication = findPublication(bundle, correction.publicationId.toString())
210
+ if (publication?._tag !== "PreparedCatalogPublication") {
211
+ throw new Error("Catalog correction subject is not the exact catalog publication in the prepared manifest.")
212
+ }
213
+ if (!digestEquals(publicationBaselineDigest(publication), correction.baselineDigest) ||
214
+ !digestEquals(publication.targetDigest, correction.baselineTargetDigest) ||
215
+ !digestEquals(publication.stateDigest, correction.baselineStateDigest)) {
216
+ throw new Error("Catalog correction baseline digest is not the exact prepared target/state publication.")
217
+ }
218
+ if (compareCatalogVersions(publication.version.toString(), correction.replacementVersion.toString()) >= 0) {
219
+ throw new Error("Catalog correction is not a SemVer-forward replacement.")
220
+ }
221
+ const expectedArchitectures = publication.renderer.downloads.map((download) => download.architecture).sort().join("\n")
222
+ const replacementArchitectures = correction.downloads.map((download) => download.architecture).sort().join("\n")
223
+ if (expectedArchitectures !== replacementArchitectures) {
224
+ throw new Error("Catalog correction replacement architecture set differs from the prepared renderer.")
225
+ }
226
+ for (const download of correction.downloads) {
227
+ const expected = `https://github.com/${publication.sourceRepository}/releases/download/${encodeURIComponent(correction.replacementTag)}/${encodeURIComponent(download.filename)}`
228
+ if (download.url !== expected) throw new Error("Catalog correction carries a foreign replacement download coordinate.")
229
+ }
230
+ }
231
+
232
+ export const verifyCorrectionIntent = (bundle: PreparedBundle, intent: CorrectionIntent): void => {
233
+ encodeCorrectionIntent(intent)
234
+ if (!digestEquals(preparedDigest(bundle), intent.preparedDigest)) {
235
+ throw new Error("Correction intent is bound to a different prepared release.")
236
+ }
237
+ switch (intent.correction._tag) {
238
+ case "NpmDeprecationCorrection": return verifyNpm(bundle, intent.correction)
239
+ case "GithubReleaseCorrection": return verifyGithub(bundle, intent.correction)
240
+ case "CatalogForwardCorrection": return verifyCatalog(bundle, intent.correction)
241
+ }
242
+ }
243
+
244
+ const providerOf = (intent: CorrectionIntent): "npm" | "github" | "catalog-git" => intent.correction.provider
245
+
246
+ /**
247
+ * The only correction entry point. Provider adapters are built at the host
248
+ * boundary. Neither admitted provider currently exposes a conditional write
249
+ * that protects the exact observed generation, so a validated intent becomes
250
+ * an external proposal and never a read-then-unconditional mutation.
251
+ */
252
+ export const correctPreparedRelease = Effect.fn("correctPreparedRelease")(function*(input: {
253
+ readonly bundle: PreparedBundle
254
+ readonly intent: CorrectionIntent
255
+ readonly services?: {
256
+ readonly credentials: CredentialProviderShape
257
+ readonly http: HttpAuthorizerShape
258
+ readonly mutationHttp: AuthorizedMutationHttpShape
259
+ }
260
+ }) {
261
+ try {
262
+ verifyCorrectionIntent(input.bundle, input.intent)
263
+ } catch (cause) {
264
+ return yield* Effect.fail(new CorrectionValidationError({ reason: cause instanceof Error ? cause.message : String(cause) }))
265
+ }
266
+ const provider = providerOf(input.intent)
267
+ if (input.intent.correction._tag === "CatalogForwardCorrection") {
268
+ if (input.services === undefined) return CorrectionUnsupported.make({
269
+ provider,
270
+ reason: "Catalog correction requires the host-owned credential and GitHub HTTP authority boundary.",
271
+ evidence: "docs/release-program/remediation/231-catalog-delivery.md",
272
+ proposal: new TextDecoder().decode(encodeCorrectionIntent(input.intent))
273
+ })
274
+ const correction = input.intent.correction
275
+ const publication = findPublication(input.bundle, correction.publicationId.toString())
276
+ if (publication?._tag !== "PreparedCatalogPublication") {
277
+ return yield* new CorrectionValidationError({ reason: "Verified catalog correction publication disappeared." })
278
+ }
279
+ const baselineTarget = input.bundle.blobs.get(publication.targetArtifactId.toString())
280
+ const baselineState = input.bundle.blobs.get(publication.stateArtifactId.toString())
281
+ if (baselineTarget === undefined || baselineState === undefined) {
282
+ return yield* new CorrectionValidationError({ reason: "Verified catalog correction baseline bytes disappeared." })
283
+ }
284
+ const target = renderCatalog(correction.replacementVersion, publication.renderer.renderer, correction.downloads)
285
+ const state = encodeCatalogManagedState(CatalogManagedState.make({
286
+ schemaVersion: "ts-release/catalog-state/v2",
287
+ catalogId: publication.catalogId,
288
+ renderer: publication.renderer.renderer._tag,
289
+ generation: correction.replacementVersion,
290
+ status: "corrected",
291
+ targetDigest: sha256Digest(target),
292
+ sourceRepository: publication.sourceRepository,
293
+ sourceTag: correction.replacementTag,
294
+ correctionId: input.intent.correctionId,
295
+ reason: correction.reason,
296
+ replacementVersion: correction.replacementVersion
297
+ }))
298
+ const subject = makeCatalogSubject(publication, input.services.http, input.services.mutationHttp, {
299
+ id: SubjectId.make(`${publication.authority.subject}#correction-${input.intent.correctionId.hex}`),
300
+ purpose: "correct",
301
+ target,
302
+ state,
303
+ baselineTarget,
304
+ baselineState
305
+ })
306
+ const report = yield* publishReleaseSubjects({
307
+ prepared: SubjectId.make(`correction:sha256-${input.intent.correctionId.hex}`),
308
+ subjects: [subject]
309
+ }).pipe(Effect.provideService(CredentialProvider, input.services.credentials))
310
+ return {
311
+ _tag: "CorrectionExecuted",
312
+ provider: "catalog-git",
313
+ report,
314
+ reason: "Catalog correction ran through the exact conditional Git-data subject.",
315
+ evidence: "docs/release-program/remediation/231-catalog-delivery.md",
316
+ proposal: ""
317
+ } as const
318
+ }
319
+ return CorrectionUnsupported.make({
320
+ provider,
321
+ reason: provider === "npm"
322
+ ? "npm exposes no proved conditional deprecation write for the observed package generation; use the exact external proposal instead."
323
+ : "GitHub exposes no proved conditional release-metadata write for the observed release generation.",
324
+ evidence: "docs/release-program/remediation/229-provider-recovery.md",
325
+ proposal: new TextDecoder().decode(encodeCorrectionIntent(input.intent))
326
+ })
327
+ })
328
+
329
+ export const correctionEvidenceProjection = (intent: CorrectionIntent): string => {
330
+ const encoded = Schema.encodeSync(CorrectionIntentV2)(intent)
331
+ return encodeCanonicalJson({
332
+ correctionId: encoded.correctionId,
333
+ preparedDigest: encoded.preparedDigest,
334
+ provider: providerOf(intent)
335
+ })
336
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./intent.js"
2
+ export * from "./coordinator.js"
@@ -0,0 +1,172 @@
1
+ import * as Schema from "effect/Schema"
2
+ import { encodeCanonicalJson, parseStrictJson } from "../model/canonical.js"
3
+ import {
4
+ Sha256Digest,
5
+ Sha256Hex,
6
+ Sha512Digest,
7
+ digestEquals,
8
+ sha256Digest
9
+ } from "../model/digest.js"
10
+ import { NonEmptyName, Version } from "../model/primitives.js"
11
+ import { CatalogArchitecture, PreparedCatalogDownload } from "../model/catalog.js"
12
+
13
+ const optional = Schema.optionalKey
14
+ const boundedText = Schema.String.check(Schema.makeFilter((value: string) =>
15
+ [...value].length <= 2048 && [...value].every((character) => {
16
+ const codePoint = character.codePointAt(0) ?? 0
17
+ return codePoint === 9 || codePoint === 10 || codePoint === 13 || codePoint >= 0x20
18
+ }) ? undefined : "Correction text must be bounded and contain no control characters."))
19
+ const publicMessage = boundedText.pipe(Schema.check(Schema.makeFilter((value: string) =>
20
+ value.length > 0 ? undefined : "Correction message must be nonempty.")))
21
+
22
+ export class ReplacementCoordinate extends Schema.Class<ReplacementCoordinate>("ReplacementCoordinate")({
23
+ provider: Schema.Literals(["npm", "github"]), coordinate: publicMessage
24
+ }) {}
25
+
26
+ export class NpmDeprecationCorrection extends Schema.TaggedClass<NpmDeprecationCorrection>()("NpmDeprecationCorrection", {
27
+ provider: Schema.Literal("npm"), publicationId: NonEmptyName, registryUrl: Schema.NonEmptyString,
28
+ packageName: NonEmptyName, version: Version, baselineDigest: Sha256Digest, tarballIntegrity: Sha512Digest,
29
+ message: publicMessage, replacement: optional(ReplacementCoordinate)
30
+ }) {}
31
+
32
+ export class GithubReleaseCorrection extends Schema.TaggedClass<GithubReleaseCorrection>()("GithubReleaseCorrection", {
33
+ provider: Schema.Literal("github"), publicationId: NonEmptyName, repository: Schema.NonEmptyString,
34
+ tag: NonEmptyName, baselineDigest: Sha256Digest, marker: publicMessage,
35
+ replacement: optional(ReplacementCoordinate)
36
+ }) {}
37
+
38
+ export class CatalogForwardCorrection extends Schema.TaggedClass<CatalogForwardCorrection>()("CatalogForwardCorrection", {
39
+ provider: Schema.Literal("catalog-git"),
40
+ publicationId: NonEmptyName,
41
+ baselineDigest: Sha256Digest,
42
+ baselineTargetDigest: Sha256Digest,
43
+ baselineStateDigest: Sha256Digest,
44
+ replacementVersion: Version,
45
+ replacementTag: NonEmptyName,
46
+ downloads: Schema.NonEmptyArray(PreparedCatalogDownload),
47
+ reason: publicMessage
48
+ }) {}
49
+
50
+ /** Human-authored correction request. Destination and immutable subject facts
51
+ * are deliberately absent: they are derived from the loaded prepared bundle. */
52
+ export class AuthoredNpmDeprecation
53
+ extends Schema.Class<AuthoredNpmDeprecation>("AuthoredNpmDeprecation")({
54
+ provider: Schema.Literal("npm"),
55
+ kind: Schema.Literal("deprecate"),
56
+ publicationId: optional(NonEmptyName),
57
+ message: publicMessage,
58
+ replacement: optional(ReplacementCoordinate)
59
+ }) {}
60
+
61
+ export class AuthoredGithubReleaseAmendment
62
+ extends Schema.Class<AuthoredGithubReleaseAmendment>("AuthoredGithubReleaseAmendment")({
63
+ provider: Schema.Literal("github"),
64
+ kind: Schema.Literal("amend-release-metadata"),
65
+ publicationId: optional(NonEmptyName),
66
+ message: publicMessage,
67
+ replacement: optional(ReplacementCoordinate)
68
+ }) {}
69
+
70
+ export class AuthoredCatalogDownload extends Schema.Class<AuthoredCatalogDownload>("AuthoredCatalogDownload")({
71
+ architecture: CatalogArchitecture,
72
+ url: Schema.NonEmptyString,
73
+ filename: NonEmptyName,
74
+ sha256: Sha256Hex
75
+ }) {}
76
+
77
+ export class AuthoredCatalogForwardCorrection
78
+ extends Schema.Class<AuthoredCatalogForwardCorrection>("AuthoredCatalogForwardCorrection")({
79
+ provider: Schema.Literal("catalog-git"),
80
+ kind: Schema.Literal("forward-catalog-state"),
81
+ publicationId: optional(NonEmptyName),
82
+ replacementVersion: Version,
83
+ replacementTag: NonEmptyName,
84
+ downloads: Schema.NonEmptyArray(AuthoredCatalogDownload),
85
+ reason: publicMessage
86
+ }) {}
87
+
88
+ export const AuthoredCorrection = Schema.Union([
89
+ AuthoredNpmDeprecation,
90
+ AuthoredGithubReleaseAmendment,
91
+ AuthoredCatalogForwardCorrection
92
+ ])
93
+ export type AuthoredCorrection = typeof AuthoredCorrection.Type
94
+
95
+ export const decodeAuthoredCorrection = Schema.decodeUnknownSync(AuthoredCorrection, {
96
+ onExcessProperty: "error"
97
+ })
98
+
99
+ export const CorrectionVariant = Schema.Union([
100
+ NpmDeprecationCorrection, GithubReleaseCorrection, CatalogForwardCorrection
101
+ ])
102
+ export type CorrectionVariant = typeof CorrectionVariant.Type
103
+
104
+ const CorrectionIntentUnsignedV2 = Schema.Struct({
105
+ schemaVersion: Schema.Literal("correction-intent/v2"),
106
+ preparedDigest: Sha256Digest,
107
+ correction: CorrectionVariant
108
+ })
109
+
110
+ export class CorrectionIntentV2 extends Schema.Class<CorrectionIntentV2>("CorrectionIntentV2")({
111
+ schemaVersion: Schema.Literal("correction-intent/v2"), preparedDigest: Sha256Digest,
112
+ correction: CorrectionVariant, correctionId: Sha256Digest
113
+ }) {}
114
+ export type CorrectionIntent = typeof CorrectionIntentV2.Type
115
+ export type CorrectionIntentInput = Omit<CorrectionIntent, "correctionId">
116
+
117
+ export class CorrectionIntentError
118
+ extends Schema.TaggedErrorClass<CorrectionIntentError>()("CorrectionIntentError", {
119
+ reason: Schema.String
120
+ }) {}
121
+
122
+ const normalizeCorrection = (value: unknown): CorrectionVariant => Schema.decodeUnknownSync(CorrectionVariant)(value)
123
+ const normalizeUnsigned = (value: CorrectionIntentInput): CorrectionIntentInput =>
124
+ Schema.decodeUnknownSync(CorrectionIntentUnsignedV2, { onExcessProperty: "error" })({
125
+ schemaVersion: value.schemaVersion,
126
+ preparedDigest: value.preparedDigest,
127
+ correction: normalizeCorrection(value.correction)
128
+ })
129
+
130
+ const unsignedBytes = (value: CorrectionIntentInput): Uint8Array => {
131
+ const normalized = normalizeUnsigned(value)
132
+ const encoded = Schema.encodeSync(CorrectionIntentUnsignedV2)(normalized)
133
+ return new TextEncoder().encode(encodeCanonicalJson(encoded))
134
+ }
135
+
136
+ export const correctionIdFor = (value: CorrectionIntentInput): Sha256Digest =>
137
+ sha256Digest(unsignedBytes(value))
138
+
139
+ export const makeCorrectionIntent = (value: CorrectionIntentInput): CorrectionIntent => {
140
+ const normalized = normalizeUnsigned(value)
141
+ const correctionId = correctionIdFor(normalized)
142
+ return CorrectionIntentV2.make({ ...normalized, correctionId })
143
+ }
144
+
145
+ const equal = (left: Uint8Array, right: Uint8Array): boolean =>
146
+ left.length === right.length && left.every((byte, index) => byte === right[index])
147
+
148
+ export const encodeCorrectionIntent = (value: CorrectionIntent): Uint8Array => {
149
+ try {
150
+ const normalized = Schema.decodeUnknownSync(CorrectionIntentV2, { onExcessProperty: "error" })(value)
151
+ const expected = correctionIdFor(normalized)
152
+ if (!digestEquals(expected, normalized.correctionId)) {
153
+ throw new Error("Correction id does not match canonical unsigned V2 intent bytes.")
154
+ }
155
+ return new TextEncoder().encode(encodeCanonicalJson(Schema.encodeSync(CorrectionIntentV2)(normalized)))
156
+ } catch (cause) {
157
+ throw CorrectionIntentError.make({ reason: cause instanceof Error ? cause.message : String(cause) })
158
+ }
159
+ }
160
+
161
+ export const decodeCorrectionIntent = (bytes: Uint8Array): CorrectionIntent => {
162
+ try {
163
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes)
164
+ const value = Schema.decodeUnknownSync(CorrectionIntentV2, { onExcessProperty: "error" })(parseStrictJson(text))
165
+ const canonical = encodeCorrectionIntent(value)
166
+ if (!equal(canonical, bytes)) throw new Error("Correction intent bytes are not canonical.")
167
+ return value
168
+ } catch (cause) {
169
+ if (cause instanceof CorrectionIntentError) throw cause
170
+ throw CorrectionIntentError.make({ reason: cause instanceof Error ? cause.message : String(cause) })
171
+ }
172
+ }
@@ -0,0 +1,102 @@
1
+ import { gzipSync } from "node:zlib"
2
+
3
+ export interface ArchiveEntry {
4
+ readonly path: string
5
+ readonly data: Uint8Array
6
+ readonly mode: number
7
+ }
8
+ const text = (value: string) => new TextEncoder().encode(value)
9
+ const concat = (parts: ReadonlyArray<Uint8Array>): Uint8Array => {
10
+ const output = new Uint8Array(parts.reduce((total, part) => total + part.length, 0))
11
+ let offset = 0
12
+ for (const part of parts) {
13
+ output.set(part, offset)
14
+ offset += part.length
15
+ }
16
+ return output
17
+ }
18
+ const integer = (bytes: number, value: number): Uint8Array => {
19
+ const output = new Uint8Array(bytes)
20
+ const view = new DataView(output.buffer)
21
+ if (bytes === 2) view.setUint16(0, value, true)
22
+ else view.setUint32(0, value, true)
23
+ return output
24
+ }
25
+ const crcTable = Array.from({ length: 256 }, (_, value) => {
26
+ let crc = value
27
+ for (const bit of Array.from({ length: 8 }, (_, index) => index)) {
28
+ crc = (crc & 1) === 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1
29
+ }
30
+ return crc >>> 0
31
+ })
32
+ const crc32 = (data: Uint8Array): number => {
33
+ let crc = 0xffffffff
34
+ for (const byte of data) crc = (crc >>> 8) ^ crcTable[(crc ^ byte) & 0xff]!
35
+ return (crc ^ 0xffffffff) >>> 0
36
+ }
37
+ export const zip = (entries: ReadonlyArray<ArchiveEntry>): Uint8Array => {
38
+ const bodies: Array<Uint8Array> = []
39
+ const central: Array<Uint8Array> = []
40
+ let offset = 0
41
+ for (const entry of entries) {
42
+ const name = text(entry.path)
43
+ const crc = crc32(entry.data)
44
+ const local = concat([
45
+ integer(4, 0x04034b50), integer(2, 20), integer(2, 0x0800), integer(2, 0),
46
+ integer(2, 0), integer(2, 0), integer(4, crc), integer(4, entry.data.length),
47
+ integer(4, entry.data.length), integer(2, name.length), integer(2, 0), name
48
+ ])
49
+ bodies.push(local, entry.data)
50
+ central.push(concat([
51
+ integer(4, 0x02014b50), integer(2, 0x0314), integer(2, 20), integer(2, 0x0800),
52
+ integer(2, 0), integer(2, 0), integer(2, 0), integer(4, crc),
53
+ integer(4, entry.data.length), integer(4, entry.data.length), integer(2, name.length),
54
+ integer(2, 0), integer(2, 0), integer(2, 0), integer(2, 0),
55
+ integer(4, entry.mode << 16), integer(4, offset), name
56
+ ]))
57
+ offset += local.length + entry.data.length
58
+ }
59
+ const directory = concat(central)
60
+ return concat([
61
+ ...bodies, directory, integer(4, 0x06054b50), integer(2, 0), integer(2, 0),
62
+ integer(2, entries.length), integer(2, entries.length), integer(4, directory.length),
63
+ integer(4, offset), integer(2, 0)
64
+ ])
65
+ }
66
+ const ascii = (output: Uint8Array, offset: number, length: number, value: string): void => {
67
+ const bytes = text(value)
68
+ if (bytes.length > length) throw new Error(`Archive path is too long: ${value}`)
69
+ output.set(bytes, offset)
70
+ }
71
+ const octal = (output: Uint8Array, offset: number, length: number, value: number): void => {
72
+ ascii(output, offset, length - 2, value.toString(8).padStart(length - 2, "0"))
73
+ output[offset + length - 2] = 0
74
+ output[offset + length - 1] = 0x20
75
+ }
76
+ const tarHeader = (entry: ArchiveEntry): Uint8Array => {
77
+ const header = new Uint8Array(512)
78
+ ascii(header, 0, 100, entry.path)
79
+ octal(header, 100, 8, entry.mode & 0o777)
80
+ octal(header, 108, 8, 0)
81
+ octal(header, 116, 8, 0)
82
+ octal(header, 124, 12, entry.data.length)
83
+ octal(header, 136, 12, 0)
84
+ header.fill(0x20, 148, 156)
85
+ header[156] = 0x30
86
+ ascii(header, 257, 6, "ustar")
87
+ ascii(header, 263, 2, "00")
88
+ octal(header, 148, 8, header.reduce((sum, byte) => sum + byte, 0))
89
+ return header
90
+ }
91
+ // Level 9 is explicit because it is the level at which every zlib we ship on
92
+ // emits identical deflate bytes; the 10-byte header is then overwritten so no
93
+ // clock (MTIME) or platform (OS) leaks into an artifact.
94
+ export const tarGz = (entries: ReadonlyArray<ArchiveEntry>): Uint8Array => {
95
+ const packed = new Uint8Array(gzipSync(concat(entries.flatMap((entry) => [
96
+ tarHeader(entry), entry.data,
97
+ new Uint8Array(entry.data.length % 512 === 0 ? 0 : 512 - entry.data.length % 512)
98
+ ]).concat([new Uint8Array(1024)])), { level: 9 }))
99
+ packed.fill(0, 4, 8)
100
+ packed[9] = 0xff
101
+ return packed
102
+ }
@@ -0,0 +1,20 @@
1
+ import { realpathSync } from "node:fs"
2
+ import { isAbsolute, relative, sep } from "node:path"
3
+
4
+ // Lexical: is `path` at or beneath `root`? Both must already be in the same
5
+ // canonical form (use assertContained with realpath when symlinks may be
6
+ // present).
7
+ export const contained = (root: string, path: string): boolean => {
8
+ const value = relative(root, path)
9
+ return value === "" || (value !== ".." && !value.startsWith(`..${sep}`) && !isAbsolute(value))
10
+ }
11
+ export const assertContained = (
12
+ root: string, path: string,
13
+ options: { readonly realpath: boolean, readonly what: string }
14
+ ): string => {
15
+ const candidate = options.realpath ? realpathSync(path) : path
16
+ if (!contained(options.realpath ? realpathSync(root) : root, candidate)) {
17
+ throw new Error(`${options.what} escapes the workspace root.`)
18
+ }
19
+ return candidate
20
+ }
@@ -0,0 +1,28 @@
1
+ import * as Config from "effect/Config"
2
+ import * as Effect from "effect/Effect"
3
+ import * as Option from "effect/Option"
4
+
5
+ // Environment is a host capability, so it is read through effect/Config rather
6
+ // than process.env. The default ConfigProvider reads the host environment; a
7
+ // test or an embedding host substitutes one with ConfigProvider.layer.
8
+ export const readOptionalEnv = (name: string): Effect.Effect<string | undefined> =>
9
+ Config.option(Config.string(name)).pipe(
10
+ Effect.map(Option.getOrUndefined),
11
+ Effect.orElseSucceed(() => undefined)
12
+ )
13
+
14
+ // Exec and command publish run with a closed environment: PATH plus the
15
+ // operation's named variables and nothing else. The parent environment is
16
+ // never inherited, so a plan states every variable a command can observe.
17
+ export const readEnvironment = (
18
+ names: ReadonlyArray<string>
19
+ ): Effect.Effect<Record<string, string>> =>
20
+ Effect.forEach(["PATH", ...names], (name) =>
21
+ readOptionalEnv(name).pipe(Effect.map((value) => [name, value] as const))).pipe(
22
+ Effect.map((entries) => ({
23
+ ...Object.fromEntries(entries.flatMap(([name, value]) => value === undefined ? [] : [[name, value]])),
24
+ TZ: "UTC",
25
+ LC_ALL: "C",
26
+ LANG: "C",
27
+ SOURCE_DATE_EPOCH: "0"
28
+ })))
@@ -0,0 +1,6 @@
1
+ import * as Schema from "effect/Schema"
2
+
3
+ export class DriverError
4
+ extends Schema.TaggedErrorClass<DriverError>()("DriverError", {
5
+ reason: Schema.String, commitment: Schema.Literals(["before-commit", "unknown"])
6
+ }) {}