@mannyc1/ts-release 0.0.7 → 0.3.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 (695) hide show
  1. package/ARCHITECTURE.md +184 -92
  2. package/CHANGELOG.md +197 -0
  3. package/LICENSE +21 -0
  4. package/README.md +404 -327
  5. package/SPEC.md +257 -310
  6. package/apps/release-ts/README.md +39 -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 +122 -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 +39346 -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 +9 -0
  82. package/dist/drivers/archive.d.ts.map +1 -0
  83. package/dist/drivers/archive.js +105 -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/python-wheel.d.ts +21 -0
  106. package/dist/drivers/python-wheel.d.ts.map +1 -0
  107. package/dist/drivers/python-wheel.js +109 -0
  108. package/dist/drivers/python-wheel.js.map +1 -0
  109. package/dist/drivers/redact.d.ts +4 -0
  110. package/dist/drivers/redact.d.ts.map +1 -0
  111. package/dist/drivers/redact.js +24 -0
  112. package/dist/drivers/redact.js.map +1 -0
  113. package/dist/drivers/seccomp-helper-source.d.ts +7 -0
  114. package/dist/drivers/seccomp-helper-source.d.ts.map +1 -0
  115. package/dist/drivers/seccomp-helper-source.js +121 -0
  116. package/dist/drivers/seccomp-helper-source.js.map +1 -0
  117. package/dist/drivers/utils.d.ts +4 -0
  118. package/dist/drivers/utils.d.ts.map +1 -0
  119. package/dist/drivers/utils.js +5 -0
  120. package/dist/drivers/utils.js.map +1 -0
  121. package/dist/drivers/workspace.d.ts +9 -0
  122. package/dist/drivers/workspace.d.ts.map +1 -0
  123. package/dist/drivers/workspace.js +53 -0
  124. package/dist/drivers/workspace.js.map +1 -0
  125. package/dist/extensions/provider-adapter.d.ts +48 -0
  126. package/dist/extensions/provider-adapter.d.ts.map +1 -0
  127. package/dist/extensions/provider-adapter.js +64 -0
  128. package/dist/extensions/provider-adapter.js.map +1 -0
  129. package/dist/host.d.ts +33 -0
  130. package/dist/host.d.ts.map +1 -0
  131. package/dist/host.js +20 -0
  132. package/dist/host.js.map +1 -0
  133. package/dist/index.d.ts +19 -1
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +12 -1
  136. package/dist/index.js.map +1 -1
  137. package/dist/model/artifact-collection.d.ts +84 -0
  138. package/dist/model/artifact-collection.d.ts.map +1 -0
  139. package/dist/model/artifact-collection.js +185 -0
  140. package/dist/model/artifact-collection.js.map +1 -0
  141. package/dist/model/authority.d.ts +89 -0
  142. package/dist/model/authority.d.ts.map +1 -0
  143. package/dist/model/authority.js +80 -0
  144. package/dist/model/authority.js.map +1 -0
  145. package/dist/model/bun-targets.d.ts +34 -0
  146. package/dist/model/bun-targets.d.ts.map +1 -0
  147. package/dist/model/bun-targets.js +17 -0
  148. package/dist/model/bun-targets.js.map +1 -0
  149. package/dist/model/canonical.d.ts +8 -0
  150. package/dist/model/canonical.d.ts.map +1 -0
  151. package/dist/model/canonical.js +205 -0
  152. package/dist/model/canonical.js.map +1 -0
  153. package/dist/model/catalog.d.ts +76 -0
  154. package/dist/model/catalog.d.ts.map +1 -0
  155. package/dist/model/catalog.js +174 -0
  156. package/dist/model/catalog.js.map +1 -0
  157. package/dist/model/digest.d.ts +53 -0
  158. package/dist/model/digest.d.ts.map +1 -0
  159. package/dist/model/digest.js +127 -0
  160. package/dist/model/digest.js.map +1 -0
  161. package/dist/model/errors.d.ts +14 -0
  162. package/dist/model/errors.d.ts.map +1 -0
  163. package/dist/model/errors.js +8 -0
  164. package/dist/model/errors.js.map +1 -0
  165. package/dist/model/primitives.d.ts +19 -0
  166. package/dist/model/primitives.d.ts.map +1 -0
  167. package/dist/model/primitives.js +18 -0
  168. package/dist/model/primitives.js.map +1 -0
  169. package/dist/model/pypi.d.ts +12 -0
  170. package/dist/model/pypi.d.ts.map +1 -0
  171. package/dist/model/pypi.js +20 -0
  172. package/dist/model/pypi.js.map +1 -0
  173. package/dist/model/python-distribution.d.ts +33 -0
  174. package/dist/model/python-distribution.d.ts.map +1 -0
  175. package/dist/model/python-distribution.js +367 -0
  176. package/dist/model/python-distribution.js.map +1 -0
  177. package/dist/model/secret-patterns.d.ts +2 -0
  178. package/dist/model/secret-patterns.d.ts.map +1 -0
  179. package/dist/model/secret-patterns.js +12 -0
  180. package/dist/model/secret-patterns.js.map +1 -0
  181. package/dist/operation-journal/authority.d.ts +3 -0
  182. package/dist/operation-journal/authority.d.ts.map +1 -0
  183. package/dist/operation-journal/authority.js +147 -0
  184. package/dist/operation-journal/authority.js.map +1 -0
  185. package/dist/operation-journal/aws/deadline.d.ts +12 -0
  186. package/dist/operation-journal/aws/deadline.d.ts.map +1 -0
  187. package/dist/operation-journal/aws/deadline.js +38 -0
  188. package/dist/operation-journal/aws/deadline.js.map +1 -0
  189. package/dist/operation-journal/aws/oidc.d.ts +27 -0
  190. package/dist/operation-journal/aws/oidc.d.ts.map +1 -0
  191. package/dist/operation-journal/aws/oidc.js +361 -0
  192. package/dist/operation-journal/aws/oidc.js.map +1 -0
  193. package/dist/operation-journal/aws/policy.d.ts +42 -0
  194. package/dist/operation-journal/aws/policy.d.ts.map +1 -0
  195. package/dist/operation-journal/aws/policy.js +404 -0
  196. package/dist/operation-journal/aws/policy.js.map +1 -0
  197. package/dist/operation-journal/aws/s3-boundary.d.ts +17 -0
  198. package/dist/operation-journal/aws/s3-boundary.d.ts.map +1 -0
  199. package/dist/operation-journal/aws/s3-boundary.js +417 -0
  200. package/dist/operation-journal/aws/s3-boundary.js.map +1 -0
  201. package/dist/operation-journal/aws.d.ts +11 -0
  202. package/dist/operation-journal/aws.d.ts.map +1 -0
  203. package/dist/operation-journal/aws.js +50 -0
  204. package/dist/operation-journal/aws.js.map +1 -0
  205. package/dist/operation-journal/canonical.d.ts +52 -0
  206. package/dist/operation-journal/canonical.d.ts.map +1 -0
  207. package/dist/operation-journal/canonical.js +282 -0
  208. package/dist/operation-journal/canonical.js.map +1 -0
  209. package/dist/operation-journal/model.d.ts +251 -0
  210. package/dist/operation-journal/model.d.ts.map +1 -0
  211. package/dist/operation-journal/model.js +56 -0
  212. package/dist/operation-journal/model.js.map +1 -0
  213. package/dist/operation-journal/reducer.d.ts +28 -0
  214. package/dist/operation-journal/reducer.d.ts.map +1 -0
  215. package/dist/operation-journal/reducer.js +73 -0
  216. package/dist/operation-journal/reducer.js.map +1 -0
  217. package/dist/operation-journal/s3.d.ts +7 -0
  218. package/dist/operation-journal/s3.d.ts.map +1 -0
  219. package/dist/operation-journal/s3.js +667 -0
  220. package/dist/operation-journal/s3.js.map +1 -0
  221. package/dist/operation-journal.d.ts +14 -0
  222. package/dist/operation-journal.d.ts.map +1 -0
  223. package/dist/operation-journal.js +12 -0
  224. package/dist/operation-journal.js.map +1 -0
  225. package/dist/platform/bun.d.ts +7 -0
  226. package/dist/platform/bun.d.ts.map +1 -0
  227. package/dist/platform/bun.js +15 -0
  228. package/dist/platform/bun.js.map +1 -0
  229. package/dist/platform/credentials.d.ts +32 -0
  230. package/dist/platform/credentials.d.ts.map +1 -0
  231. package/dist/platform/credentials.js +834 -0
  232. package/dist/platform/credentials.js.map +1 -0
  233. package/dist/platform/host-support.d.ts +2 -0
  234. package/dist/platform/host-support.d.ts.map +1 -0
  235. package/dist/platform/host-support.js +4 -0
  236. package/dist/platform/host-support.js.map +1 -0
  237. package/dist/platform/node.d.ts +7 -0
  238. package/dist/platform/node.d.ts.map +1 -0
  239. package/dist/platform/node.js +15 -0
  240. package/dist/platform/node.js.map +1 -0
  241. package/dist/platform/release-runtime.d.ts +11 -0
  242. package/dist/platform/release-runtime.d.ts.map +1 -0
  243. package/dist/platform/release-runtime.js +34 -0
  244. package/dist/platform/release-runtime.js.map +1 -0
  245. package/dist/platform/services.d.ts +15 -0
  246. package/dist/platform/services.d.ts.map +1 -0
  247. package/dist/platform/services.js +30 -0
  248. package/dist/platform/services.js.map +1 -0
  249. package/dist/platform/source-observer.d.ts +5 -0
  250. package/dist/platform/source-observer.d.ts.map +1 -0
  251. package/dist/platform/source-observer.js +159 -0
  252. package/dist/platform/source-observer.js.map +1 -0
  253. package/dist/provider-sdk.d.ts +14 -0
  254. package/dist/provider-sdk.d.ts.map +1 -0
  255. package/dist/provider-sdk.js +10 -0
  256. package/dist/provider-sdk.js.map +1 -0
  257. package/dist/publication/adapter.d.ts +212 -0
  258. package/dist/publication/adapter.d.ts.map +1 -0
  259. package/dist/publication/adapter.js +83 -0
  260. package/dist/publication/adapter.js.map +1 -0
  261. package/dist/publication/authority.d.ts +137 -0
  262. package/dist/publication/authority.d.ts.map +1 -0
  263. package/dist/publication/authority.js +233 -0
  264. package/dist/publication/authority.js.map +1 -0
  265. package/dist/publication/catalog-git.d.ts +37 -0
  266. package/dist/publication/catalog-git.d.ts.map +1 -0
  267. package/dist/publication/catalog-git.js +451 -0
  268. package/dist/publication/catalog-git.js.map +1 -0
  269. package/dist/publication/claim.d.ts +39 -0
  270. package/dist/publication/claim.d.ts.map +1 -0
  271. package/dist/publication/claim.js +31 -0
  272. package/dist/publication/claim.js.map +1 -0
  273. package/dist/publication/coordinator.d.ts +246 -0
  274. package/dist/publication/coordinator.d.ts.map +1 -0
  275. package/dist/publication/coordinator.js +370 -0
  276. package/dist/publication/coordinator.js.map +1 -0
  277. package/dist/publication/github.d.ts +36 -0
  278. package/dist/publication/github.d.ts.map +1 -0
  279. package/dist/publication/github.js +695 -0
  280. package/dist/publication/github.js.map +1 -0
  281. package/dist/publication/http.d.ts +69 -0
  282. package/dist/publication/http.d.ts.map +1 -0
  283. package/dist/publication/http.js +29 -0
  284. package/dist/publication/http.js.map +1 -0
  285. package/dist/publication/index.d.ts +5 -0
  286. package/dist/publication/index.d.ts.map +1 -0
  287. package/dist/publication/index.js +5 -0
  288. package/dist/publication/index.js.map +1 -0
  289. package/dist/publication/npm.d.ts +40 -0
  290. package/dist/publication/npm.d.ts.map +1 -0
  291. package/dist/publication/npm.js +359 -0
  292. package/dist/publication/npm.js.map +1 -0
  293. package/dist/publication/profiles.d.ts +136 -0
  294. package/dist/publication/profiles.d.ts.map +1 -0
  295. package/dist/publication/profiles.js +90 -0
  296. package/dist/publication/profiles.js.map +1 -0
  297. package/dist/publication/publisher.d.ts +82 -0
  298. package/dist/publication/publisher.d.ts.map +1 -0
  299. package/dist/publication/publisher.js +53 -0
  300. package/dist/publication/publisher.js.map +1 -0
  301. package/dist/publication/pypi.d.ts +45 -0
  302. package/dist/publication/pypi.d.ts.map +1 -0
  303. package/dist/publication/pypi.js +369 -0
  304. package/dist/publication/pypi.js.map +1 -0
  305. package/dist/publication/recovery.d.ts +663 -0
  306. package/dist/publication/recovery.d.ts.map +1 -0
  307. package/dist/publication/recovery.js +252 -0
  308. package/dist/publication/recovery.js.map +1 -0
  309. package/dist/publication/report.d.ts +1061 -0
  310. package/dist/publication/report.d.ts.map +1 -0
  311. package/dist/publication/report.js +441 -0
  312. package/dist/publication/report.js.map +1 -0
  313. package/dist/recipes/config.d.ts +296 -0
  314. package/dist/recipes/config.d.ts.map +1 -0
  315. package/dist/recipes/config.js +325 -0
  316. package/dist/recipes/config.js.map +1 -0
  317. package/dist/release/capabilities.d.ts +12 -0
  318. package/dist/release/capabilities.d.ts.map +1 -0
  319. package/dist/release/capabilities.js +395 -0
  320. package/dist/release/capabilities.js.map +1 -0
  321. package/dist/release/compiler.d.ts +5 -0
  322. package/dist/release/compiler.d.ts.map +1 -0
  323. package/dist/release/compiler.js +19 -0
  324. package/dist/release/compiler.js.map +1 -0
  325. package/dist/release/config.d.ts +5 -0
  326. package/dist/release/config.d.ts.map +1 -0
  327. package/dist/release/config.js +10 -0
  328. package/dist/release/config.js.map +1 -0
  329. package/dist/release/context.d.ts +96 -0
  330. package/dist/release/context.d.ts.map +1 -0
  331. package/dist/release/context.js +168 -0
  332. package/dist/release/context.js.map +1 -0
  333. package/dist/release/graph.d.ts +271 -0
  334. package/dist/release/graph.d.ts.map +1 -0
  335. package/dist/release/graph.js +766 -0
  336. package/dist/release/graph.js.map +1 -0
  337. package/dist/release/inspect.d.ts +88 -0
  338. package/dist/release/inspect.d.ts.map +1 -0
  339. package/dist/release/inspect.js +75 -0
  340. package/dist/release/inspect.js.map +1 -0
  341. package/dist/release/prepare.d.ts +24 -0
  342. package/dist/release/prepare.d.ts.map +1 -0
  343. package/dist/release/prepare.js +1115 -0
  344. package/dist/release/prepare.js.map +1 -0
  345. package/dist/release/prepared-ref.d.ts +60 -0
  346. package/dist/release/prepared-ref.d.ts.map +1 -0
  347. package/dist/release/prepared-ref.js +131 -0
  348. package/dist/release/prepared-ref.js.map +1 -0
  349. package/dist/release/prepared-store.d.ts +90 -0
  350. package/dist/release/prepared-store.d.ts.map +1 -0
  351. package/dist/release/prepared-store.js +339 -0
  352. package/dist/release/prepared-store.js.map +1 -0
  353. package/dist/release/prepared.d.ts +172 -0
  354. package/dist/release/prepared.d.ts.map +1 -0
  355. package/dist/release/prepared.js +268 -0
  356. package/dist/release/prepared.js.map +1 -0
  357. package/dist/release/staging.d.ts +31 -0
  358. package/dist/release/staging.d.ts.map +1 -0
  359. package/dist/release/staging.js +218 -0
  360. package/dist/release/staging.js.map +1 -0
  361. package/dist/resolve/authored.d.ts +53 -0
  362. package/dist/resolve/authored.d.ts.map +1 -0
  363. package/dist/resolve/authored.js +55 -0
  364. package/dist/resolve/authored.js.map +1 -0
  365. package/dist/resolve/encode.d.ts +3 -0
  366. package/dist/resolve/encode.d.ts.map +1 -0
  367. package/dist/resolve/encode.js +21 -0
  368. package/dist/resolve/encode.js.map +1 -0
  369. package/dist/resolve/errors.d.ts +7 -0
  370. package/dist/resolve/errors.d.ts.map +1 -0
  371. package/dist/resolve/errors.js +17 -0
  372. package/dist/resolve/errors.js.map +1 -0
  373. package/dist/resolve/facts.d.ts +12 -0
  374. package/dist/resolve/facts.d.ts.map +1 -0
  375. package/dist/resolve/facts.js +18 -0
  376. package/dist/resolve/facts.js.map +1 -0
  377. package/dist/resolve/resolve.d.ts +10 -0
  378. package/dist/resolve/resolve.d.ts.map +1 -0
  379. package/dist/resolve/resolve.js +242 -0
  380. package/dist/resolve/resolve.js.map +1 -0
  381. package/dist/store.d.ts +11 -0
  382. package/dist/store.d.ts.map +1 -0
  383. package/dist/store.js +9 -0
  384. package/dist/store.js.map +1 -0
  385. package/examples/README.md +20 -30
  386. package/examples/github-release/release.config.json +11 -18
  387. package/examples/homebrew-tap/README.md +11 -0
  388. package/examples/homebrew-tap/release.config.json +40 -28
  389. package/examples/multi-target/release.config.json +28 -53
  390. package/examples/npm-first-publish/release.config.json +23 -25
  391. package/examples/npm-only/release.config.json +22 -30
  392. package/examples/portable-cli/README.md +17 -0
  393. package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-arm64 +1 -0
  394. package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-x64 +1 -0
  395. package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-arm64 +1 -0
  396. package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-x64 +1 -0
  397. package/examples/portable-cli/artifacts/portable-example-0.1.0-windows-x64.exe +1 -0
  398. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_10_15_x86_64.whl +1 -0
  399. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_11_0_arm64.whl +1 -0
  400. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_aarch64.whl +1 -0
  401. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_x86_64.whl +1 -0
  402. package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-win_amd64.whl +1 -0
  403. package/examples/portable-cli/package.json +9 -0
  404. package/examples/portable-cli/release.config.json +53 -0
  405. package/examples/portable-cli/src/cli.ts +3 -0
  406. package/examples/pypi-registry/README.md +8 -0
  407. package/examples/scoop-bucket/README.md +10 -0
  408. package/examples/scoop-bucket/release.config.json +40 -30
  409. package/package.json +73 -154
  410. package/src/api/api.ts +365 -0
  411. package/src/api/errors.ts +36 -0
  412. package/src/api/input.ts +92 -0
  413. package/src/api/runtime.ts +14 -0
  414. package/src/api/types.ts +103 -0
  415. package/src/capabilities/bun-targets.ts +2 -0
  416. package/src/capabilities/field-ownership.ts +60 -0
  417. package/src/capabilities/module.ts +158 -0
  418. package/src/capabilities/registry.ts +333 -0
  419. package/src/config/config.ts +48 -0
  420. package/src/correction/coordinator.ts +336 -0
  421. package/src/correction/index.ts +2 -0
  422. package/src/correction/intent.ts +172 -0
  423. package/src/drivers/archive.ts +111 -0
  424. package/src/drivers/contain.ts +20 -0
  425. package/src/drivers/environment.ts +28 -0
  426. package/src/drivers/errors.ts +6 -0
  427. package/src/drivers/glob.ts +137 -0
  428. package/src/drivers/process.ts +339 -0
  429. package/src/drivers/python-wheel.ts +145 -0
  430. package/src/drivers/redact.ts +31 -0
  431. package/src/drivers/seccomp-helper-source.ts +121 -0
  432. package/src/drivers/utils.ts +10 -0
  433. package/src/drivers/workspace.ts +46 -0
  434. package/src/extensions/provider-adapter.ts +99 -0
  435. package/src/host.ts +140 -0
  436. package/src/index.ts +64 -0
  437. package/src/model/artifact-collection.ts +237 -0
  438. package/src/model/authority.ts +116 -0
  439. package/src/model/bun-targets.ts +34 -0
  440. package/src/model/canonical.ts +205 -0
  441. package/src/model/catalog.ts +220 -0
  442. package/src/model/digest.ts +172 -0
  443. package/src/model/errors.ts +6 -0
  444. package/src/model/primitives.ts +37 -0
  445. package/src/model/pypi.ts +30 -0
  446. package/src/model/python-distribution.ts +360 -0
  447. package/src/model/secret-patterns.ts +11 -0
  448. package/src/operation-journal/authority.ts +162 -0
  449. package/src/operation-journal/aws/deadline.ts +41 -0
  450. package/src/operation-journal/aws/oidc.ts +439 -0
  451. package/src/operation-journal/aws/policy.ts +491 -0
  452. package/src/operation-journal/aws/s3-boundary.ts +562 -0
  453. package/src/operation-journal/aws.ts +60 -0
  454. package/src/operation-journal/canonical.ts +373 -0
  455. package/src/operation-journal/model.ts +301 -0
  456. package/src/operation-journal/reducer.ts +112 -0
  457. package/src/operation-journal/s3.ts +884 -0
  458. package/src/operation-journal.ts +51 -0
  459. package/src/platform/bun.ts +38 -0
  460. package/src/platform/credentials.ts +1151 -0
  461. package/src/platform/host-support.ts +4 -0
  462. package/src/platform/node.ts +38 -0
  463. package/src/platform/release-runtime.ts +47 -0
  464. package/src/platform/services.ts +57 -0
  465. package/src/platform/source-observer.ts +193 -0
  466. package/src/provider-sdk.ts +48 -0
  467. package/src/publication/adapter.ts +132 -0
  468. package/src/publication/authority.ts +397 -0
  469. package/src/publication/catalog-git.ts +603 -0
  470. package/src/publication/claim.ts +51 -0
  471. package/src/publication/coordinator.ts +578 -0
  472. package/src/publication/github.ts +1022 -0
  473. package/src/publication/http.ts +101 -0
  474. package/src/publication/index.ts +4 -0
  475. package/src/publication/npm.ts +525 -0
  476. package/src/publication/profiles.ts +94 -0
  477. package/src/publication/publisher.ts +130 -0
  478. package/src/publication/pypi.ts +463 -0
  479. package/src/publication/recovery.ts +349 -0
  480. package/src/publication/report.ts +628 -0
  481. package/src/recipes/config.ts +395 -0
  482. package/src/release/capabilities.ts +460 -0
  483. package/src/release/compiler.ts +28 -0
  484. package/src/release/config.ts +12 -0
  485. package/src/release/context.ts +223 -0
  486. package/src/release/graph.ts +866 -0
  487. package/src/release/inspect.ts +83 -0
  488. package/src/release/prepare.ts +1329 -0
  489. package/src/release/prepared-ref.ts +193 -0
  490. package/src/release/prepared-store.ts +378 -0
  491. package/src/release/prepared.ts +299 -0
  492. package/src/release/staging.ts +257 -0
  493. package/src/resolve/authored.ts +64 -0
  494. package/src/resolve/encode.ts +22 -0
  495. package/src/resolve/errors.ts +15 -0
  496. package/src/resolve/facts.ts +18 -0
  497. package/src/resolve/resolve.ts +328 -0
  498. package/src/store.ts +28 -0
  499. package/templates/README.md +55 -72
  500. package/templates/bun-cli-github/README.md +7 -9
  501. package/templates/bun-cli-github/release.config.json +35 -73
  502. package/templates/github-actions/release.yml +74 -0
  503. package/templates/github-actions/reviewed-release.yml +115 -0
  504. package/templates/multi-target-homebrew/README.md +10 -0
  505. package/templates/multi-target-homebrew/release.config.json +43 -60
  506. package/templates/multi-target-scoop/README.md +10 -0
  507. package/templates/multi-target-scoop/release.config.json +43 -62
  508. package/templates/npm-github/release.config.json +25 -38
  509. package/templates/npm-github/reviewed-release.config.json +37 -0
  510. package/templates/npm-only/README.md +10 -0
  511. package/templates/npm-only/release.config.json +15 -30
  512. package/templates/portable-cli/README.md +13 -0
  513. package/templates/portable-cli/release.config.json +53 -0
  514. package/dist/artifacts/adapter.d.ts +0 -39
  515. package/dist/artifacts/adapter.d.ts.map +0 -1
  516. package/dist/artifacts/adapter.js +0 -23
  517. package/dist/artifacts/adapter.js.map +0 -1
  518. package/dist/artifacts/registry.d.ts +0 -21
  519. package/dist/artifacts/registry.d.ts.map +0 -1
  520. package/dist/artifacts/registry.js +0 -21
  521. package/dist/artifacts/registry.js.map +0 -1
  522. package/dist/config/errors.d.ts +0 -24
  523. package/dist/config/errors.d.ts.map +0 -1
  524. package/dist/config/errors.js +0 -19
  525. package/dist/config/errors.js.map +0 -1
  526. package/dist/config/load.d.ts +0 -9
  527. package/dist/config/load.d.ts.map +0 -1
  528. package/dist/config/load.js +0 -29
  529. package/dist/config/load.js.map +0 -1
  530. package/dist/config/schema.d.ts +0 -12
  531. package/dist/config/schema.d.ts.map +0 -1
  532. package/dist/config/schema.js +0 -19
  533. package/dist/config/schema.js.map +0 -1
  534. package/dist/domain/artifact.d.ts +0 -118
  535. package/dist/domain/artifact.d.ts.map +0 -1
  536. package/dist/domain/artifact.js +0 -197
  537. package/dist/domain/artifact.js.map +0 -1
  538. package/dist/domain/evidence.d.ts +0 -59
  539. package/dist/domain/evidence.d.ts.map +0 -1
  540. package/dist/domain/evidence.js +0 -51
  541. package/dist/domain/evidence.js.map +0 -1
  542. package/dist/domain/operation.d.ts +0 -143
  543. package/dist/domain/operation.d.ts.map +0 -1
  544. package/dist/domain/operation.js +0 -198
  545. package/dist/domain/operation.js.map +0 -1
  546. package/dist/domain/release.d.ts +0 -93
  547. package/dist/domain/release.d.ts.map +0 -1
  548. package/dist/domain/release.js +0 -82
  549. package/dist/domain/release.js.map +0 -1
  550. package/dist/domain/remote-state.d.ts +0 -58
  551. package/dist/domain/remote-state.d.ts.map +0 -1
  552. package/dist/domain/remote-state.js +0 -55
  553. package/dist/domain/remote-state.js.map +0 -1
  554. package/dist/domain/target.d.ts +0 -148
  555. package/dist/domain/target.d.ts.map +0 -1
  556. package/dist/domain/target.js +0 -151
  557. package/dist/domain/target.js.map +0 -1
  558. package/dist/host/host.d.ts +0 -32
  559. package/dist/host/host.d.ts.map +0 -1
  560. package/dist/host/host.js +0 -24
  561. package/dist/host/host.js.map +0 -1
  562. package/dist/host/http-live.d.ts +0 -6
  563. package/dist/host/http-live.d.ts.map +0 -1
  564. package/dist/host/http-live.js +0 -86
  565. package/dist/host/http-live.js.map +0 -1
  566. package/dist/host/http.d.ts +0 -43
  567. package/dist/host/http.d.ts.map +0 -1
  568. package/dist/host/http.js +0 -59
  569. package/dist/host/http.js.map +0 -1
  570. package/dist/host/platform.d.ts +0 -10
  571. package/dist/host/platform.d.ts.map +0 -1
  572. package/dist/host/platform.js +0 -114
  573. package/dist/host/platform.js.map +0 -1
  574. package/dist/host/test.d.ts +0 -23
  575. package/dist/host/test.d.ts.map +0 -1
  576. package/dist/host/test.js +0 -222
  577. package/dist/host/test.js.map +0 -1
  578. package/dist/internal/workspace-path.d.ts +0 -15
  579. package/dist/internal/workspace-path.d.ts.map +0 -1
  580. package/dist/internal/workspace-path.js +0 -36
  581. package/dist/internal/workspace-path.js.map +0 -1
  582. package/dist/planner/artifact-inventory.d.ts +0 -9
  583. package/dist/planner/artifact-inventory.d.ts.map +0 -1
  584. package/dist/planner/artifact-inventory.js +0 -86
  585. package/dist/planner/artifact-inventory.js.map +0 -1
  586. package/dist/planner/create-release-plan.d.ts +0 -5
  587. package/dist/planner/create-release-plan.d.ts.map +0 -1
  588. package/dist/planner/create-release-plan.js +0 -25
  589. package/dist/planner/create-release-plan.js.map +0 -1
  590. package/dist/planner/errors.d.ts +0 -67
  591. package/dist/planner/errors.d.ts.map +0 -1
  592. package/dist/planner/errors.js +0 -58
  593. package/dist/planner/errors.js.map +0 -1
  594. package/dist/planner/evidence-recorder.d.ts +0 -28
  595. package/dist/planner/evidence-recorder.d.ts.map +0 -1
  596. package/dist/planner/evidence-recorder.js +0 -362
  597. package/dist/planner/evidence-recorder.js.map +0 -1
  598. package/dist/planner/executor.d.ts +0 -58
  599. package/dist/planner/executor.d.ts.map +0 -1
  600. package/dist/planner/executor.js +0 -147
  601. package/dist/planner/executor.js.map +0 -1
  602. package/dist/planner/normalize-release.d.ts +0 -19
  603. package/dist/planner/normalize-release.d.ts.map +0 -1
  604. package/dist/planner/normalize-release.js +0 -342
  605. package/dist/planner/normalize-release.js.map +0 -1
  606. package/dist/planner/reconcile.d.ts +0 -17
  607. package/dist/planner/reconcile.d.ts.map +0 -1
  608. package/dist/planner/reconcile.js +0 -259
  609. package/dist/planner/reconcile.js.map +0 -1
  610. package/dist/planner/render-plan.d.ts +0 -15
  611. package/dist/planner/render-plan.d.ts.map +0 -1
  612. package/dist/planner/render-plan.js +0 -231
  613. package/dist/planner/render-plan.js.map +0 -1
  614. package/dist/targets/adapter-helpers.d.ts +0 -79
  615. package/dist/targets/adapter-helpers.d.ts.map +0 -1
  616. package/dist/targets/adapter-helpers.js +0 -194
  617. package/dist/targets/adapter-helpers.js.map +0 -1
  618. package/dist/targets/adapter.d.ts +0 -17
  619. package/dist/targets/adapter.d.ts.map +0 -1
  620. package/dist/targets/adapter.js +0 -2
  621. package/dist/targets/adapter.js.map +0 -1
  622. package/dist/targets/github-release.d.ts +0 -25
  623. package/dist/targets/github-release.d.ts.map +0 -1
  624. package/dist/targets/github-release.js +0 -82
  625. package/dist/targets/github-release.js.map +0 -1
  626. package/dist/targets/github.d.ts +0 -11
  627. package/dist/targets/github.d.ts.map +0 -1
  628. package/dist/targets/github.js +0 -117
  629. package/dist/targets/github.js.map +0 -1
  630. package/dist/targets/homebrew.d.ts +0 -11
  631. package/dist/targets/homebrew.d.ts.map +0 -1
  632. package/dist/targets/homebrew.js +0 -210
  633. package/dist/targets/homebrew.js.map +0 -1
  634. package/dist/targets/live.d.ts +0 -5
  635. package/dist/targets/live.d.ts.map +0 -1
  636. package/dist/targets/live.js +0 -50
  637. package/dist/targets/live.js.map +0 -1
  638. package/dist/targets/npm.d.ts +0 -10
  639. package/dist/targets/npm.d.ts.map +0 -1
  640. package/dist/targets/npm.js +0 -112
  641. package/dist/targets/npm.js.map +0 -1
  642. package/dist/targets/pypi.d.ts +0 -11
  643. package/dist/targets/pypi.d.ts.map +0 -1
  644. package/dist/targets/pypi.js +0 -141
  645. package/dist/targets/pypi.js.map +0 -1
  646. package/dist/targets/registry.d.ts +0 -25
  647. package/dist/targets/registry.d.ts.map +0 -1
  648. package/dist/targets/registry.js +0 -34
  649. package/dist/targets/registry.js.map +0 -1
  650. package/dist/targets/scoop.d.ts +0 -11
  651. package/dist/targets/scoop.d.ts.map +0 -1
  652. package/dist/targets/scoop.js +0 -88
  653. package/dist/targets/scoop.js.map +0 -1
  654. package/dist/types/effect-internal.d.ts +0 -5
  655. package/dist/types/effect-internal.d.ts.map +0 -1
  656. package/dist/types/effect-internal.js +0 -2
  657. package/dist/types/effect-internal.js.map +0 -1
  658. package/dist/workflows/config.d.ts +0 -202
  659. package/dist/workflows/config.d.ts.map +0 -1
  660. package/dist/workflows/config.js +0 -420
  661. package/dist/workflows/config.js.map +0 -1
  662. package/dist/workflows/diagnostics.d.ts +0 -62
  663. package/dist/workflows/diagnostics.d.ts.map +0 -1
  664. package/dist/workflows/diagnostics.js +0 -530
  665. package/dist/workflows/diagnostics.js.map +0 -1
  666. package/dist/workflows/distribution.d.ts +0 -25
  667. package/dist/workflows/distribution.d.ts.map +0 -1
  668. package/dist/workflows/distribution.js +0 -24
  669. package/dist/workflows/distribution.js.map +0 -1
  670. package/dist/workflows/evidence.d.ts +0 -17
  671. package/dist/workflows/evidence.d.ts.map +0 -1
  672. package/dist/workflows/evidence.js +0 -32
  673. package/dist/workflows/evidence.js.map +0 -1
  674. package/dist/workflows/index.d.ts +0 -8
  675. package/dist/workflows/index.d.ts.map +0 -1
  676. package/dist/workflows/index.js +0 -7
  677. package/dist/workflows/index.js.map +0 -1
  678. package/dist/workflows/init.d.ts +0 -84
  679. package/dist/workflows/init.d.ts.map +0 -1
  680. package/dist/workflows/init.js +0 -487
  681. package/dist/workflows/init.js.map +0 -1
  682. package/dist/workflows/live.d.ts +0 -9
  683. package/dist/workflows/live.d.ts.map +0 -1
  684. package/dist/workflows/live.js +0 -7
  685. package/dist/workflows/live.js.map +0 -1
  686. package/dist/workflows/options.d.ts +0 -30
  687. package/dist/workflows/options.d.ts.map +0 -1
  688. package/dist/workflows/options.js +0 -16
  689. package/dist/workflows/options.js.map +0 -1
  690. package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +0 -1
  691. package/examples/non-strict-skips/release.config.json +0 -31
  692. package/examples/pypi-registry/release.config.json +0 -31
  693. package/templates/github-actions/plan-and-approved-execute.yml +0 -58
  694. package/templates/github-actions/plan-only.yml +0 -33
  695. package/templates/github-actions/trusted-publishing.yml +0 -61
@@ -0,0 +1,373 @@
1
+ import { Buffer } from "node:buffer"
2
+ import { sha256Digest } from "../model/digest.js"
3
+ import {
4
+ encodeCanonicalJson,
5
+ parseStrictJson,
6
+ type Json
7
+ } from "../model/canonical.js"
8
+ import {
9
+ JournalInputError,
10
+ JournalIntegrityError,
11
+ journalRecordTags,
12
+ operationJournalByteLimits,
13
+ type JournalOperation,
14
+ type JournalRecord,
15
+ type JournalRecordTag,
16
+ type JournalWorkflowCoordinate
17
+ } from "./model.js"
18
+
19
+ const encoder = new TextEncoder()
20
+ const decoder = new TextDecoder("utf-8", { fatal: true })
21
+
22
+ const releasePointPattern = /^[a-f0-9]{40}$/u
23
+ const operationKeyPattern = /^[a-f0-9]{64}$/u
24
+ const digestPattern = /^sha256:[a-f0-9]{64}$/u
25
+ const transactionIdPattern = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u
26
+ const positiveDecimalPattern = /^[1-9][0-9]*$/u
27
+ const codecIdPattern = /^[A-Za-z0-9][A-Za-z0-9._/@-]{0,127}$/u
28
+ const etagPattern = /^"[!#-~]{1,1024}"$/u
29
+
30
+ const canonicalDigest = (bytes: Uint8Array): string => `sha256:${sha256Digest(bytes).hex}`
31
+
32
+ const failInput = (reason: string): never => {
33
+ throw JournalInputError.make({ reason })
34
+ }
35
+
36
+ const failIntegrity = (reason: string): never => {
37
+ throw JournalIntegrityError.make({ reason })
38
+ }
39
+
40
+ const isObject = (value: Json): value is { readonly [key: string]: Json } =>
41
+ typeof value === "object" && value !== null && !Array.isArray(value)
42
+
43
+ const exactObject = (
44
+ value: Json,
45
+ fields: ReadonlyArray<string>,
46
+ label: string
47
+ ): { readonly [key: string]: Json } => {
48
+ if (!isObject(value)) failIntegrity(`${label} must be an object.`)
49
+ const object = value as { readonly [key: string]: Json }
50
+ const actual = Object.keys(object).sort()
51
+ const expected = [...fields].sort()
52
+ if (actual.length !== expected.length || actual.some((field, index) => field !== expected[index])) {
53
+ failIntegrity(`${label} fields are not the exact canonical set.`)
54
+ }
55
+ return object
56
+ }
57
+
58
+ const stringField = (
59
+ object: { readonly [key: string]: Json },
60
+ field: string,
61
+ label: string
62
+ ): string => {
63
+ const value = object[field]
64
+ if (typeof value !== "string") failIntegrity(`${label}.${field} must be a string.`)
65
+ return value as string
66
+ }
67
+
68
+ const integerField = (
69
+ object: { readonly [key: string]: Json },
70
+ field: string,
71
+ label: string
72
+ ): number => {
73
+ const value = object[field]
74
+ if (typeof value !== "number" || !Number.isSafeInteger(value)) {
75
+ failIntegrity(`${label}.${field} must be a safe integer.`)
76
+ }
77
+ return value as number
78
+ }
79
+
80
+ const assertPattern = (value: string, pattern: RegExp, label: string): string => {
81
+ if (!pattern.test(value)) failIntegrity(`${label} is not canonical.`)
82
+ return value
83
+ }
84
+
85
+ const assertInputPattern = (value: string, pattern: RegExp, label: string): string => {
86
+ if (!pattern.test(value)) failInput(`${label} is not canonical.`)
87
+ return value
88
+ }
89
+
90
+ export const isCanonicalS3VersionId = (value: string): boolean => {
91
+ const bytes = encoder.encode(value)
92
+ return value !== "null" && bytes.length >= 1 && bytes.length <= 1024 && decoder.decode(bytes) === value
93
+ }
94
+
95
+ const assertVersionId = (value: string, label: string): string => {
96
+ if (!isCanonicalS3VersionId(value)) failIntegrity(`${label} is not a canonical retained S3 VersionId.`)
97
+ return value
98
+ }
99
+
100
+ const decodeCanonical = (bytes: Uint8Array, label: string): Json => {
101
+ if (!(bytes instanceof Uint8Array)) {
102
+ failIntegrity(`${label} must be one Uint8Array.`)
103
+ }
104
+ if (bytes.length === 0 || bytes.length > operationJournalByteLimits.object) {
105
+ failIntegrity(`${label} exceeds the admitted object byte bound.`)
106
+ }
107
+ let text: string
108
+ let parsed: Json
109
+ try {
110
+ text = decoder.decode(bytes)
111
+ parsed = parseStrictJson(text)
112
+ } catch {
113
+ return failIntegrity(`${label} is not strict UTF-8 canonical JSON.`)
114
+ }
115
+ if (encodeCanonicalJson(parsed) !== text) {
116
+ failIntegrity(`${label} is not the canonical encoding of its value.`)
117
+ }
118
+ return parsed
119
+ }
120
+
121
+ const decodeBase64 = (value: string, label: string): Uint8Array => {
122
+ const maximumEncodedLength = Math.ceil(operationJournalByteLimits.payload / 3) * 4
123
+ if (value.length > maximumEncodedLength) {
124
+ failIntegrity(`${label} exceeds the admitted payload byte bound.`)
125
+ }
126
+ if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u.test(value)) {
127
+ failIntegrity(`${label} is not canonical base64.`)
128
+ }
129
+ const bytes = new Uint8Array(Buffer.from(value, "base64"))
130
+ if (bytes.length > operationJournalByteLimits.payload || Buffer.from(bytes).toString("base64") !== value) {
131
+ failIntegrity(`${label} is not canonical base64.`)
132
+ }
133
+ return bytes
134
+ }
135
+
136
+ export interface CanonicalJournalRecord {
137
+ readonly tag: JournalRecordTag
138
+ readonly codecId: string
139
+ readonly payloadBase64: string
140
+ readonly payloadDigest: string
141
+ }
142
+
143
+ export interface CanonicalJournalPredecessor {
144
+ readonly eventDigest: string
145
+ readonly headVersionId: string
146
+ readonly headEtag: string
147
+ }
148
+
149
+ export interface CanonicalJournalEvent extends JournalOperation {
150
+ readonly schemaVersion: "ts-release-operation-journal-event/v1"
151
+ readonly sequence: number
152
+ readonly transactionId: string
153
+ readonly previous: CanonicalJournalPredecessor | null
154
+ readonly workflow: JournalWorkflowCoordinate
155
+ readonly record: CanonicalJournalRecord
156
+ }
157
+
158
+ export interface CanonicalJournalHead extends JournalOperation {
159
+ readonly schemaVersion: "ts-release-operation-journal-head/v1"
160
+ readonly sequence: number
161
+ readonly transactionId: string
162
+ readonly eventKey: string
163
+ readonly eventVersionId: string
164
+ readonly eventChecksumSha256: string
165
+ readonly eventDigest: string
166
+ readonly previousHeadVersionId: string | null
167
+ readonly previousHeadEtag: string | null
168
+ }
169
+
170
+ export const validateJournalOperation = (operation: JournalOperation): JournalOperation => ({
171
+ releasePoint: assertInputPattern(operation.releasePoint, releasePointPattern, "releasePoint"),
172
+ operationKey: assertInputPattern(operation.operationKey, operationKeyPattern, "operationKey")
173
+ })
174
+
175
+ export const validateJournalWorkflow = (
176
+ workflow: JournalWorkflowCoordinate
177
+ ): JournalWorkflowCoordinate => ({
178
+ repositoryId: assertInputPattern(workflow.repositoryId, positiveDecimalPattern, "workflow.repositoryId"),
179
+ runId: assertInputPattern(workflow.runId, positiveDecimalPattern, "workflow.runId"),
180
+ runAttempt: assertInputPattern(workflow.runAttempt, positiveDecimalPattern, "workflow.runAttempt")
181
+ })
182
+
183
+ export const validateTransactionId = (transactionId: string): string =>
184
+ assertInputPattern(transactionId, transactionIdPattern, "transactionId")
185
+
186
+ export const deriveOperationKey = (canonicalOperationIdentity: Uint8Array): string => {
187
+ if (!(canonicalOperationIdentity instanceof Uint8Array)) {
188
+ failInput("Canonical operation identity must be one Uint8Array.")
189
+ }
190
+ if (canonicalOperationIdentity.length === 0 ||
191
+ canonicalOperationIdentity.length > operationJournalByteLimits.operationIdentity) {
192
+ failInput("Canonical operation identity exceeds its admitted byte bound.")
193
+ }
194
+ return sha256Digest(canonicalOperationIdentity).hex
195
+ }
196
+
197
+ export const journalNamespace = (
198
+ operation: JournalOperation,
199
+ prefix = "operation-journal/v1"
200
+ ): string => {
201
+ const valid = validateJournalOperation(operation)
202
+ if (prefix !== "operation-journal/v1") failInput("Journal prefix must be operation-journal/v1.")
203
+ return `${prefix}/${valid.releasePoint}/${valid.operationKey}/`
204
+ }
205
+
206
+ export const journalHeadKey = (operation: JournalOperation): string =>
207
+ `${journalNamespace(operation)}head.bin`
208
+
209
+ export const journalEventKey = (
210
+ operation: JournalOperation,
211
+ sequence: number,
212
+ transactionId: string
213
+ ): string => {
214
+ if (!Number.isSafeInteger(sequence) || sequence < 1 || sequence > 99_999_999) {
215
+ failInput("Journal sequence must be an integer from 1 through 99999999.")
216
+ }
217
+ return `${journalNamespace(operation)}events/${String(sequence).padStart(8, "0")}/${validateTransactionId(transactionId)}.bin`
218
+ }
219
+
220
+ export const makeCanonicalJournalRecord = (input: {
221
+ readonly tag: JournalRecordTag
222
+ readonly codecId: string
223
+ readonly payload: Uint8Array
224
+ }): CanonicalJournalRecord => {
225
+ if (!journalRecordTags.includes(input.tag)) failInput("Journal record tag is not admitted.")
226
+ if (!(input.payload instanceof Uint8Array)) {
227
+ failInput("Journal payload must be one Uint8Array.")
228
+ }
229
+ if (input.payload.length > operationJournalByteLimits.payload) {
230
+ failInput("Journal payload exceeds the admitted byte bound.")
231
+ }
232
+ const codecId = assertInputPattern(input.codecId, codecIdPattern, "codecId")
233
+ const payload = new Uint8Array(input.payload)
234
+ return {
235
+ tag: input.tag,
236
+ codecId,
237
+ payloadBase64: Buffer.from(payload).toString("base64"),
238
+ payloadDigest: canonicalDigest(payload)
239
+ }
240
+ }
241
+
242
+ export const encodeJournalEvent = (event: CanonicalJournalEvent): Uint8Array =>
243
+ encoder.encode(encodeCanonicalJson(event))
244
+
245
+ export const encodeJournalHead = (head: CanonicalJournalHead): Uint8Array =>
246
+ encoder.encode(encodeCanonicalJson(head))
247
+
248
+ const decodeWorkflow = (value: Json): JournalWorkflowCoordinate => {
249
+ const object = exactObject(value, ["repositoryId", "runAttempt", "runId"], "event.workflow")
250
+ return {
251
+ repositoryId: assertPattern(stringField(object, "repositoryId", "event.workflow"), positiveDecimalPattern, "event.workflow.repositoryId"),
252
+ runId: assertPattern(stringField(object, "runId", "event.workflow"), positiveDecimalPattern, "event.workflow.runId"),
253
+ runAttempt: assertPattern(stringField(object, "runAttempt", "event.workflow"), positiveDecimalPattern, "event.workflow.runAttempt")
254
+ }
255
+ }
256
+
257
+ const decodeRecord = (value: Json): CanonicalJournalRecord => {
258
+ const object = exactObject(value, ["codecId", "payloadBase64", "payloadDigest", "tag"], "event.record")
259
+ const tag = stringField(object, "tag", "event.record")
260
+ if (!journalRecordTags.includes(tag as JournalRecordTag)) failIntegrity("event.record.tag is not admitted.")
261
+ const codecId = assertPattern(stringField(object, "codecId", "event.record"), codecIdPattern, "event.record.codecId")
262
+ const payloadBase64 = stringField(object, "payloadBase64", "event.record")
263
+ const payload = decodeBase64(payloadBase64, "event.record.payloadBase64")
264
+ const payloadDigest = assertPattern(stringField(object, "payloadDigest", "event.record"), digestPattern, "event.record.payloadDigest")
265
+ if (canonicalDigest(payload) !== payloadDigest) failIntegrity("event.record payload digest does not match its bytes.")
266
+ return { tag: tag as JournalRecordTag, codecId, payloadBase64, payloadDigest }
267
+ }
268
+
269
+ const decodePredecessor = (value: Json): CanonicalJournalPredecessor | null => {
270
+ if (value === null) return null
271
+ const object = exactObject(value, ["eventDigest", "headEtag", "headVersionId"], "event.previous")
272
+ return {
273
+ eventDigest: assertPattern(stringField(object, "eventDigest", "event.previous"), digestPattern, "event.previous.eventDigest"),
274
+ headVersionId: assertVersionId(stringField(object, "headVersionId", "event.previous"), "event.previous.headVersionId"),
275
+ headEtag: assertPattern(stringField(object, "headEtag", "event.previous"), etagPattern, "event.previous.headEtag")
276
+ }
277
+ }
278
+
279
+ export const decodeJournalEvent = (bytes: Uint8Array): CanonicalJournalEvent => {
280
+ const object = exactObject(decodeCanonical(bytes, "Journal event"), [
281
+ "operationKey",
282
+ "previous",
283
+ "record",
284
+ "releasePoint",
285
+ "schemaVersion",
286
+ "sequence",
287
+ "transactionId",
288
+ "workflow"
289
+ ], "event")
290
+ if (stringField(object, "schemaVersion", "event") !== "ts-release-operation-journal-event/v1") {
291
+ failIntegrity("Journal event schema version is unsupported.")
292
+ }
293
+ const schemaVersion = "ts-release-operation-journal-event/v1" as const
294
+ const sequence = integerField(object, "sequence", "event")
295
+ if (sequence < 1 || sequence > 99_999_999) failIntegrity("event.sequence is outside the admitted range.")
296
+ return {
297
+ schemaVersion,
298
+ releasePoint: assertPattern(stringField(object, "releasePoint", "event"), releasePointPattern, "event.releasePoint"),
299
+ operationKey: assertPattern(stringField(object, "operationKey", "event"), operationKeyPattern, "event.operationKey"),
300
+ sequence,
301
+ transactionId: assertPattern(stringField(object, "transactionId", "event"), transactionIdPattern, "event.transactionId"),
302
+ previous: decodePredecessor(object.previous!),
303
+ workflow: decodeWorkflow(object.workflow!),
304
+ record: decodeRecord(object.record!)
305
+ }
306
+ }
307
+
308
+ export const decodeJournalHead = (bytes: Uint8Array): CanonicalJournalHead => {
309
+ const object = exactObject(decodeCanonical(bytes, "Journal head"), [
310
+ "eventChecksumSha256",
311
+ "eventDigest",
312
+ "eventKey",
313
+ "eventVersionId",
314
+ "operationKey",
315
+ "previousHeadEtag",
316
+ "previousHeadVersionId",
317
+ "releasePoint",
318
+ "schemaVersion",
319
+ "sequence",
320
+ "transactionId"
321
+ ], "head")
322
+ if (stringField(object, "schemaVersion", "head") !== "ts-release-operation-journal-head/v1") {
323
+ failIntegrity("Journal head schema version is unsupported.")
324
+ }
325
+ const schemaVersion = "ts-release-operation-journal-head/v1" as const
326
+ const sequence = integerField(object, "sequence", "head")
327
+ if (sequence < 1 || sequence > 99_999_999) failIntegrity("head.sequence is outside the admitted range.")
328
+ const nullable = (field: "previousHeadVersionId" | "previousHeadEtag", pattern: RegExp): string | null => {
329
+ const value = object[field]
330
+ if (value === null) return null
331
+ if (typeof value !== "string") failIntegrity(`head.${field} must be a string or null.`)
332
+ return assertPattern(value as string, pattern, `head.${field}`)
333
+ }
334
+ return {
335
+ schemaVersion,
336
+ releasePoint: assertPattern(stringField(object, "releasePoint", "head"), releasePointPattern, "head.releasePoint"),
337
+ operationKey: assertPattern(stringField(object, "operationKey", "head"), operationKeyPattern, "head.operationKey"),
338
+ sequence,
339
+ transactionId: assertPattern(stringField(object, "transactionId", "head"), transactionIdPattern, "head.transactionId"),
340
+ eventKey: stringField(object, "eventKey", "head"),
341
+ eventVersionId: assertVersionId(stringField(object, "eventVersionId", "head"), "head.eventVersionId"),
342
+ eventChecksumSha256: assertPattern(stringField(object, "eventChecksumSha256", "head"), digestPattern, "head.eventChecksumSha256"),
343
+ eventDigest: assertPattern(stringField(object, "eventDigest", "head"), digestPattern, "head.eventDigest"),
344
+ previousHeadVersionId: (() => {
345
+ const value = object.previousHeadVersionId
346
+ if (value === null) return null
347
+ if (typeof value !== "string") failIntegrity("head.previousHeadVersionId must be a string or null.")
348
+ return assertVersionId(value as string, "head.previousHeadVersionId")
349
+ })(),
350
+ previousHeadEtag: nullable("previousHeadEtag", etagPattern)
351
+ }
352
+ }
353
+
354
+ const canonicalObjectDigest = (bytes: Uint8Array, label: string): string => {
355
+ if (!(bytes instanceof Uint8Array)) failIntegrity(`${label} must be one Uint8Array.`)
356
+ if (bytes.length < 1 || bytes.length > operationJournalByteLimits.object) {
357
+ failIntegrity(`${label} exceeds the admitted object byte bound.`)
358
+ }
359
+ return canonicalDigest(bytes)
360
+ }
361
+
362
+ export const eventDigest = (bytes: Uint8Array): string => canonicalObjectDigest(bytes, "Journal event")
363
+ export const objectChecksum = (bytes: Uint8Array): string => canonicalObjectDigest(bytes, "Journal object")
364
+
365
+ export const journalRecordFromEvent = (event: CanonicalJournalEvent): JournalRecord => ({
366
+ tag: event.record.tag,
367
+ codecId: event.record.codecId,
368
+ payload: decodeBase64(event.record.payloadBase64, "event.record.payloadBase64"),
369
+ payloadDigest: event.record.payloadDigest,
370
+ sequence: event.sequence,
371
+ transactionId: event.transactionId,
372
+ workflow: event.workflow
373
+ })
@@ -0,0 +1,301 @@
1
+ import * as Effect from "effect/Effect"
2
+ import * as Schema from "effect/Schema"
3
+
4
+ export const journalRecordTags = [
5
+ "IntentRecorded",
6
+ "ReceiptRecorded",
7
+ "ObservationRecorded",
8
+ "TerminalRecorded",
9
+ "OutcomeUnknown"
10
+ ] as const
11
+
12
+ /** Fixed hashing/allocation limits for identities, payloads, and retained objects. */
13
+ export const operationJournalByteLimits = {
14
+ operationIdentity: 65_536,
15
+ payload: 1_048_576,
16
+ object: 1_500_000
17
+ } as const
18
+
19
+ export type JournalRecordTag = typeof journalRecordTags[number]
20
+ export type JournalStateTag = "Empty" | JournalRecordTag
21
+
22
+ export interface JournalOperation {
23
+ readonly releasePoint: string
24
+ readonly operationKey: string
25
+ }
26
+
27
+ export interface JournalWorkflowCoordinate {
28
+ readonly repositoryId: string
29
+ readonly runId: string
30
+ readonly runAttempt: string
31
+ }
32
+
33
+ /**
34
+ * The payload is consumer-owned canonical data. The journal binds and returns
35
+ * the bytes without decoding provider fields.
36
+ */
37
+ export interface JournalAppendRequest extends JournalOperation {
38
+ readonly tag: JournalRecordTag
39
+ readonly codecId: string
40
+ readonly payload: Uint8Array
41
+ }
42
+
43
+ export interface JournalRecord {
44
+ readonly tag: JournalRecordTag
45
+ readonly codecId: string
46
+ readonly payload: Uint8Array
47
+ readonly payloadDigest: string
48
+ readonly sequence: number
49
+ readonly transactionId: string
50
+ readonly workflow: JournalWorkflowCoordinate
51
+ }
52
+
53
+ export interface JournalAcknowledgement extends JournalOperation {
54
+ readonly bucketArn: string
55
+ readonly prefix: string
56
+ readonly eventKey: string
57
+ readonly eventVersionId: string
58
+ readonly eventChecksumSha256: string
59
+ readonly headKey: string
60
+ readonly headVersionId: string
61
+ readonly headEtag: string
62
+ readonly headChecksumSha256: string
63
+ readonly recordDigest: string
64
+ readonly sequence: number
65
+ readonly transactionId: string
66
+ readonly previousHeadVersionId: string | null
67
+ readonly previousHeadEtag: string | null
68
+ }
69
+
70
+ export interface JournalSnapshot extends JournalOperation {
71
+ readonly state: JournalStateTag
72
+ readonly records: ReadonlyArray<JournalRecord>
73
+ readonly acknowledgement: JournalAcknowledgement | null
74
+ }
75
+
76
+ export interface CanonicalOperationJournalShape {
77
+ /** Re-observe governance and validate the complete reachable chain. */
78
+ readonly read: (
79
+ operation: JournalOperation
80
+ ) => Effect.Effect<JournalSnapshot, JournalReadError>
81
+
82
+ /**
83
+ * Append one transition. A returned acknowledgment has already survived an
84
+ * exact version re-read and complete-chain validation.
85
+ */
86
+ readonly append: (
87
+ request: JournalAppendRequest
88
+ ) => Effect.Effect<JournalAcknowledgement, JournalAppendError>
89
+
90
+ /**
91
+ * Finish the one unacknowledged canonical event left by a killed writer.
92
+ * Multiple or semantically incompatible orphan transactions stop.
93
+ */
94
+ readonly reconcile: (
95
+ operation: JournalOperation
96
+ ) => Effect.Effect<JournalSnapshot, JournalAppendError>
97
+ }
98
+
99
+ export class JournalInputError
100
+ extends Schema.TaggedErrorClass<JournalInputError>()("JournalInputError", {
101
+ reason: Schema.NonEmptyString
102
+ }) {}
103
+
104
+ export class JournalTransitionError
105
+ extends Schema.TaggedErrorClass<JournalTransitionError>()("JournalTransitionError", {
106
+ reason: Schema.NonEmptyString
107
+ }) {}
108
+
109
+ export class JournalIntegrityError
110
+ extends Schema.TaggedErrorClass<JournalIntegrityError>()("JournalIntegrityError", {
111
+ reason: Schema.NonEmptyString
112
+ }) {}
113
+
114
+ export class JournalAuthorityMismatch
115
+ extends Schema.TaggedErrorClass<JournalAuthorityMismatch>()("JournalAuthorityMismatch", {
116
+ reason: Schema.NonEmptyString
117
+ }) {}
118
+
119
+ export class JournalStorageUnavailable
120
+ extends Schema.TaggedErrorClass<JournalStorageUnavailable>()("JournalStorageUnavailable", {
121
+ reason: Schema.NonEmptyString
122
+ }) {}
123
+
124
+ export class JournalStorageOutcomeUnknown
125
+ extends Schema.TaggedErrorClass<JournalStorageOutcomeUnknown>()("JournalStorageOutcomeUnknown", {
126
+ reason: Schema.NonEmptyString
127
+ }) {}
128
+
129
+ export class JournalConflict
130
+ extends Schema.TaggedErrorClass<JournalConflict>()("JournalConflict", {
131
+ reason: Schema.NonEmptyString
132
+ }) {}
133
+
134
+ export type JournalReadError =
135
+ | JournalInputError
136
+ | JournalIntegrityError
137
+ | JournalAuthorityMismatch
138
+ | JournalStorageUnavailable
139
+
140
+ export type JournalAppendError =
141
+ | JournalReadError
142
+ | JournalTransitionError
143
+ | JournalStorageOutcomeUnknown
144
+ | JournalConflict
145
+
146
+ export const S3JournalRequestOperations = Schema.Literals([
147
+ "observe-authority",
148
+ "list-namespace",
149
+ "get-object-version",
150
+ "put-event",
151
+ "put-head"
152
+ ])
153
+ export type S3JournalRequestOperation = typeof S3JournalRequestOperations.Type
154
+
155
+ export class S3JournalBoundaryError
156
+ extends Schema.TaggedErrorClass<S3JournalBoundaryError>()("S3JournalBoundaryError", {
157
+ operation: S3JournalRequestOperations,
158
+ commitment: Schema.Literals(["not-applicable", "not-committed", "unknown"]),
159
+ reason: Schema.NonEmptyString
160
+ }) {}
161
+
162
+ export interface S3JournalOidcClaims {
163
+ readonly issuer: "https://token.actions.githubusercontent.com"
164
+ readonly audience: "sts.amazonaws.com"
165
+ readonly subject: string
166
+ /** Standard GitHub claims describe the caller workflow. */
167
+ readonly repository: string
168
+ readonly repositoryId: string
169
+ readonly repositoryOwnerId: string
170
+ readonly repositoryVisibility: "public"
171
+ readonly eventName: "workflow_dispatch"
172
+ readonly ref: string
173
+ readonly refType: "branch"
174
+ readonly sha: string
175
+ readonly environment: string
176
+ readonly runnerEnvironment: "github-hosted"
177
+ readonly runId: string
178
+ readonly runAttempt: string
179
+ readonly workflow: string
180
+ readonly workflowRef: string
181
+ readonly workflowSha: string
182
+ /** `job_workflow_*` claims describe the called reusable workflow. */
183
+ readonly jobWorkflowRef: string
184
+ readonly jobWorkflowSha: string
185
+ }
186
+
187
+ /** Exact values parsed from the AWS role's GitHub OIDC trust conditions. */
188
+ export interface S3JournalOidcTrustConditions {
189
+ readonly audience: "sts.amazonaws.com"
190
+ readonly subject: string
191
+ readonly repository: string
192
+ readonly repositoryId: string
193
+ readonly repositoryOwnerId: string
194
+ readonly workflow: string
195
+ readonly ref: string
196
+ readonly environment: string
197
+ readonly jobWorkflowRef: string
198
+ }
199
+
200
+ export interface S3JournalAuthority {
201
+ readonly accountId: string
202
+ readonly bucketName: string
203
+ readonly bucketArn: string
204
+ readonly region: string
205
+ readonly roleArn: string
206
+ readonly prefix: "operation-journal/v1"
207
+ readonly expectedBucketOwner: string
208
+ readonly versioning: "Enabled"
209
+ readonly objectLock: "Enabled"
210
+ readonly retentionMode: "COMPLIANCE"
211
+ readonly retentionYears: 10
212
+ readonly bucketOwnerEnforced: true
213
+ readonly publicAccessBlocked: true
214
+ readonly deleteDenied: true
215
+ readonly multipartDenied: true
216
+ readonly conditionalWritesEnforced: true
217
+ readonly bucketPolicyDigest: string
218
+ readonly rolePolicyDigest: string
219
+ readonly oidcTrustPolicyDigest: string
220
+ readonly oidc: S3JournalOidcClaims
221
+ readonly oidcTrust: S3JournalOidcTrustConditions
222
+ }
223
+
224
+ export interface S3JournalObjectVersion {
225
+ readonly key: string
226
+ readonly versionId: string
227
+ readonly etag: string
228
+ readonly checksumSha256: string
229
+ readonly bytes: Uint8Array
230
+ readonly lastModified: string
231
+ readonly retentionMode: "COMPLIANCE"
232
+ readonly retainUntil: string
233
+ }
234
+
235
+ export interface S3JournalDeleteMarker {
236
+ readonly key: string
237
+ readonly versionId: string
238
+ }
239
+
240
+ export interface S3JournalNamespaceListing {
241
+ readonly versions: ReadonlyArray<{
242
+ readonly key: string
243
+ readonly versionId: string
244
+ readonly etag: string
245
+ readonly isLatest: boolean
246
+ }>
247
+ readonly deleteMarkers: ReadonlyArray<S3JournalDeleteMarker>
248
+ readonly truncated: boolean
249
+ }
250
+
251
+ export type S3JournalPutCondition =
252
+ | { readonly _tag: "IfNoneMatch" }
253
+ | { readonly _tag: "IfMatch", readonly etag: string }
254
+
255
+ export interface S3JournalPutRequest {
256
+ readonly bucketName: string
257
+ readonly expectedBucketOwner: string
258
+ readonly region: string
259
+ readonly key: string
260
+ readonly bytes: Uint8Array
261
+ readonly checksumSha256: string
262
+ readonly condition: S3JournalPutCondition
263
+ }
264
+
265
+ export type S3JournalPutResult =
266
+ | {
267
+ readonly _tag: "Committed"
268
+ readonly versionId: string
269
+ readonly etag: string
270
+ readonly checksumSha256: string
271
+ }
272
+ | { readonly _tag: "PreconditionFailed" }
273
+
274
+ /**
275
+ * Credential acquisition and SigV4 stay outside this structural boundary.
276
+ * A live adapter must close over one already-issued, purpose-scoped session;
277
+ * callers cannot supply endpoints, profiles, or credentials per request.
278
+ */
279
+ export interface S3JournalBoundaryShape {
280
+ readonly observeAuthority: () => Effect.Effect<S3JournalAuthority, S3JournalBoundaryError>
281
+ readonly listNamespace: (input: {
282
+ readonly bucketName: string
283
+ readonly expectedBucketOwner: string
284
+ readonly region: string
285
+ readonly prefix: string
286
+ readonly maximum: number
287
+ }) => Effect.Effect<S3JournalNamespaceListing, S3JournalBoundaryError>
288
+ readonly getObjectVersion: (input: {
289
+ readonly bucketName: string
290
+ readonly expectedBucketOwner: string
291
+ readonly region: string
292
+ readonly key: string
293
+ readonly versionId: string
294
+ }) => Effect.Effect<S3JournalObjectVersion, S3JournalBoundaryError>
295
+ readonly putEvent: (
296
+ input: S3JournalPutRequest
297
+ ) => Effect.Effect<S3JournalPutResult, S3JournalBoundaryError>
298
+ readonly putHead: (
299
+ input: S3JournalPutRequest
300
+ ) => Effect.Effect<S3JournalPutResult, S3JournalBoundaryError>
301
+ }