@1aboveio/skills 0.19.2 → 0.20.1

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 (203) hide show
  1. package/README.md +9 -4
  2. package/package.json +1 -1
  3. package/runtime/skills/distribution/generated/recipes.json +54 -48
  4. package/runtime/skills/distribution/scripts/bundles.mjs +113 -7
  5. package/runtime/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +4 -6
  6. package/runtime/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +3 -36
  7. package/skills/cicd-pipeline/mergify/SKILL.md +1 -1
  8. package/skills/engineering/engineering-runtime/coherence/workflow.json +14 -83
  9. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +4 -6
  10. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +3 -36
  11. package/skills/engineering/smoke/SKILL.md +1 -1
  12. package/skills/payment/payment-analysis/SKILL.md +13 -7
  13. package/skills/payment/payment-analysis/references/chargebacks.md +43 -18
  14. package/skills/payment/payment-analysis/references/event-layers.md +4 -0
  15. package/skills/payment/payment-analysis/references/metrics.md +9 -7
  16. package/skills/payment/payment-analysis/references/report-template.md +3 -3
  17. package/skills/payment/payment-analysis/references/terminology.md +6 -1
  18. package/skills/payment/payment-analysis/references/visualization.md +1 -1
  19. package/skills/payment/tld-detection/SKILL.md +163 -0
  20. package/skills/payment/tld-detection/agents/openai.yaml +9 -0
  21. package/skills/payment/tld-detection/evals/evals.json +107 -0
  22. package/skills/payment/tld-detection/references/clean.md +51 -0
  23. package/skills/payment/tld-detection/references/clustering.md +219 -0
  24. package/skills/payment/tld-detection/references/decision.md +85 -0
  25. package/skills/payment/tld-detection/references/report-template.md +169 -0
  26. package/skills/payment/tld-detection/references/terminology.md +69 -0
  27. package/skills/payment/tld-detection/references/workflow.md +78 -0
  28. package/skills/payment/tld-detection/scripts/detect_ladders.py +390 -0
  29. package/skills/payment/tld-detection/tests/test_detect_ladders.py +132 -0
  30. package/skills/engineering/resolve-issues/SKILL.md +0 -168
  31. package/skills/engineering/resolve-issues/agents/openai.yaml +0 -9
  32. package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +0 -499
  33. package/skills/engineering/resolve-issues/references/breaker.md +0 -82
  34. package/skills/engineering/resolve-issues/references/deliverables.md +0 -27
  35. package/skills/engineering/resolve-issues/references/delivery.md +0 -108
  36. package/skills/engineering/resolve-issues/references/evidence-lane.md +0 -21
  37. package/skills/engineering/resolve-issues/references/exact-head-ci.md +0 -287
  38. package/skills/engineering/resolve-issues/references/fan-out.md +0 -33
  39. package/skills/engineering/resolve-issues/references/finalization.md +0 -68
  40. package/skills/engineering/resolve-issues/references/guarantees.md +0 -10
  41. package/skills/engineering/resolve-issues/references/high-risk.md +0 -29
  42. package/skills/engineering/resolve-issues/references/incidents/848/README.md +0 -156
  43. package/skills/engineering/resolve-issues/references/intake.md +0 -86
  44. package/skills/engineering/resolve-issues/references/integration-gate.md +0 -53
  45. package/skills/engineering/resolve-issues/references/interference.md +0 -87
  46. package/skills/engineering/resolve-issues/references/loop.md +0 -134
  47. package/skills/engineering/resolve-issues/references/model-catalog.md +0 -9
  48. package/skills/engineering/resolve-issues/references/postmortem.md +0 -27
  49. package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +0 -41
  50. package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +0 -48
  51. package/skills/engineering/resolve-issues/references/pre-flight.md +0 -41
  52. package/skills/engineering/resolve-issues/references/regression-checklist.md +0 -26
  53. package/skills/engineering/resolve-issues/references/run-state.md +0 -288
  54. package/skills/engineering/resolve-issues/references/sandboxed-testing.md +0 -48
  55. package/skills/engineering/resolve-issues/references/spawn-contract.md +0 -96
  56. package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +0 -40
  57. package/skills/engineering/resolve-issues/references/why.md +0 -653
  58. package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +0 -49
  59. package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +0 -721
  60. package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +0 -962
  61. package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +0 -220
  62. package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +0 -420
  63. package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +0 -256
  64. package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +0 -168
  65. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +0 -9
  66. package/skills/engineering/resolve-issues/scripts/doctrine.mjs +0 -62
  67. package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +0 -191
  68. package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +0 -413
  69. package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +0 -332
  70. package/skills/engineering/resolve-issues/scripts/finalize.mjs +0 -488
  71. package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +0 -3307
  72. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +0 -16
  73. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +0 -51
  74. package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +0 -17
  75. package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +0 -166
  76. package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +0 -92
  77. package/skills/engineering/resolve-issues/scripts/guide-index.mjs +0 -73
  78. package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +0 -159
  79. package/skills/engineering/resolve-issues/scripts/interference.mjs +0 -427
  80. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +0 -9
  81. package/skills/engineering/resolve-issues/scripts/next-operations.mjs +0 -419
  82. package/skills/engineering/resolve-issues/scripts/postmortem.mjs +0 -909
  83. package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +0 -345
  84. package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +0 -415
  85. package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +0 -697
  86. package/skills/engineering/resolve-issues/scripts/report.mjs +0 -494
  87. package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +0 -172
  88. package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +0 -79
  89. package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +0 -334
  90. package/skills/engineering/resolve-issues/scripts/run-state.mjs +0 -4792
  91. package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +0 -395
  92. package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +0 -290
  93. package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +0 -170
  94. package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +0 -293
  95. package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +0 -197
  96. package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +0 -127
  97. package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +0 -893
  98. package/skills/engineering/resolve-issues/scripts/workspaces.mjs +0 -829
  99. package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +0 -290
  100. package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +0 -80
  101. package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +0 -102
  102. package/skills/engineering/resolve-release/LICENSE +0 -3
  103. package/skills/engineering/resolve-release/SKILL.md +0 -113
  104. package/skills/engineering/resolve-release/agents/openai.yaml +0 -9
  105. package/skills/engineering/resolve-release/references/assembly.md +0 -137
  106. package/skills/engineering/resolve-release/references/auto-when-green.md +0 -56
  107. package/skills/engineering/resolve-release/references/candidate.md +0 -167
  108. package/skills/engineering/resolve-release/references/exposure.md +0 -178
  109. package/skills/engineering/resolve-release/references/handoff.md +0 -24
  110. package/skills/engineering/resolve-release/references/postmortem.md +0 -230
  111. package/skills/engineering/resolve-release/references/preflight.md +0 -208
  112. package/skills/engineering/resolve-release/references/principles.md +0 -94
  113. package/skills/engineering/resolve-release/references/regression-checklist.md +0 -36
  114. package/skills/engineering/resolve-release/references/related-skills.md +0 -13
  115. package/skills/engineering/resolve-release/references/routing.md +0 -149
  116. package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +0 -285
  117. package/skills/engineering/resolve-release/references/versioning.md +0 -202
  118. package/skills/engineering/resolve-release/references/why.md +0 -53
  119. package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +0 -389
  120. package/skills/engineering/resolve-release/scripts/build-changes.mjs +0 -209
  121. package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +0 -407
  122. package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +0 -904
  123. package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +0 -81
  124. package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +0 -612
  125. package/skills/engineering/resolve-release/scripts/close-attempt.mjs +0 -135
  126. package/skills/engineering/resolve-release/scripts/closeout-release.mjs +0 -161
  127. package/skills/engineering/resolve-release/scripts/doctrine.mjs +0 -106
  128. package/skills/engineering/resolve-release/scripts/durable-processing.mjs +0 -522
  129. package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +0 -659
  130. package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +0 -1014
  131. package/skills/engineering/resolve-release/scripts/finalize-release.mjs +0 -526
  132. package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +0 -169
  133. package/skills/engineering/resolve-release/scripts/green-gate.mjs +0 -599
  134. package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +0 -752
  135. package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +0 -56
  136. package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +0 -1538
  137. package/skills/engineering/resolve-release/scripts/postmortem.mjs +0 -381
  138. package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +0 -510
  139. package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +0 -326
  140. package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +0 -272
  141. package/skills/engineering/resolve-release/scripts/report.mjs +0 -417
  142. package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +0 -114
  143. package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +0 -238
  144. package/skills/engineering/resolve-release/scripts/review-packet.mjs +0 -503
  145. package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +0 -263
  146. package/skills/engineering/resolve-release/scripts/version-assert.mjs +0 -339
  147. package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +0 -485
  148. package/skills/engineering/resolve-release/scripts/version.mjs +0 -1199
  149. package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +0 -449
  150. package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +0 -21
  151. package/skills/engineering/resolve-release/vendor/README.md +0 -60
  152. package/skills/engineering/resolve-release/vendor/acorn.mjs +0 -6233
  153. package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +0 -21
  154. package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +0 -341
  155. package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +0 -70
  156. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +0 -2
  157. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +0 -1
  158. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +0 -7
  159. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +0 -1
  160. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +0 -2033
  161. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +0 -2033
  162. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +0 -7
  163. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +0 -1
  164. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +0 -2
  165. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +0 -1
  166. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +0 -2
  167. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +0 -1
  168. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +0 -2
  169. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +0 -1
  170. package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +0 -49
  171. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +0 -21
  172. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +0 -5
  173. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +0 -549
  174. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +0 -549
  175. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +0 -2
  176. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +0 -1
  177. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +0 -2
  178. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +0 -1
  179. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +0 -36
  180. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +0 -47
  181. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +0 -82
  182. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +0 -11
  183. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +0 -22
  184. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +0 -21
  185. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +0 -21
  186. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +0 -11
  187. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +0 -11
  188. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +0 -25
  189. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
  190. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +0 -85
  191. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +0 -85
  192. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +0 -2
  193. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +0 -1
  194. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +0 -2
  195. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +0 -1
  196. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +0 -20
  197. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +0 -20
  198. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +0 -2
  199. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +0 -1
  200. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +0 -2
  201. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +0 -1
  202. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +0 -61
  203. /package/skills/{engineering/resolve-issues → payment/tld-detection}/LICENSE +0 -0
@@ -1,135 +0,0 @@
1
- #!/usr/bin/env node
2
- // close-attempt — ordered terminal release closeout with durable evidence.
3
- //
4
- // The released path has finalize-release.mjs because it needs a larger verification transaction.
5
- // This command owns the corresponding failed pre-candidate path: validate the bundle and lease
6
- // transition, emit the immutable top-level record, then commit the manifest close. A malformed or
7
- // conflicting bundle leaves the attempt open, so the rc circuit breaker can never depend on an
8
- // operator remembering a separate emit command after recording a failure.
9
-
10
- import fs from 'node:fs'
11
-
12
- import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
13
- import {
14
- ATTEMPT_CLOSE_CAUSES,
15
- readManifest,
16
- recordReleaseAttemptState,
17
- writeManifest,
18
- } from '../../resolve-issues/scripts/run-state.mjs'
19
- import { bundleKey, emitBundle, validateBundle } from './evidence-bundle.mjs'
20
-
21
- const FAILED_PRE_CANDIDATE = 'failed-pre-promotion'
22
- const nonEmpty = (value) => typeof value === 'string' && value.trim() !== ''
23
- const isObject = (value) => value != null && typeof value === 'object' && !Array.isArray(value)
24
-
25
- const USAGE = `close-attempt — close a failed pre-candidate release attempt and emit its durable bundle.
26
-
27
- Usage:
28
- close-attempt.mjs <run-manifest.json> --bundle <release-evidence.json>
29
- --dir <durable-evidence-dir> --state failed-pre-promotion --evidence <verified-cleanup>
30
-
31
- The command validates that the bundle belongs to the manifest's open attempt, validates the
32
- release-attempt close, emits the immutable top-level bundle, then writes the terminal attempt
33
- state. It refuses before the manifest write when the bundle is incomplete, fabricated, stale, or
34
- conflicts with an existing bundle for the same (attempt id, terminal state).
35
-
36
- Candidate delivery failures that end before a candidate exists use this command after the
37
- verified no-candidate/cleanup observation. The emitted bundle has failurePhase pre-candidate and
38
- is discoverable by version-postmortem.mjs and rc-circuit-breaker.mjs.`
39
-
40
- function parseArgs(argv) {
41
- const positional = []
42
- const options = { bundle: null, dir: null, state: null, evidence: null }
43
- for (let index = 0; index < argv.length; index += 1) {
44
- const arg = argv[index]
45
- if (arg === '--help' || arg === '-h') return { help: true, positional, options }
46
- if (arg.startsWith('--')) {
47
- const key = arg.slice(2)
48
- if (!Object.hasOwn(options, key)) throw new Error(`unknown argument ${arg}`)
49
- const value = argv[++index]
50
- if (value === undefined || value.startsWith('--')) throw new Error(`${arg} needs a value`)
51
- options[key] = value
52
- } else {
53
- positional.push(arg)
54
- }
55
- }
56
- return { help: false, positional, options }
57
- }
58
-
59
- function readJson(file, label) {
60
- if (!nonEmpty(file)) throw new Error(`${label} is required`)
61
- try {
62
- return JSON.parse(fs.readFileSync(file, 'utf8'))
63
- } catch (error) {
64
- throw new Error(`${label} is not readable JSON: ${file} (${error.message})`)
65
- }
66
- }
67
-
68
- export function closeAttempt({ manifest, bundle, dir, state, evidence }) {
69
- if (!isObject(manifest) || manifest.skill !== 'resolve-release') {
70
- throw new Error('run manifest must be a resolve-release manifest')
71
- }
72
- if (state !== FAILED_PRE_CANDIDATE) {
73
- throw new Error(`close-attempt only closes ${FAILED_PRE_CANDIDATE}; got ${JSON.stringify(state)}`)
74
- }
75
- if (!nonEmpty(dir) || !nonEmpty(evidence)) throw new Error('--dir and --evidence are required')
76
-
77
- const attempt = manifest.release?.attempt
78
- if (!isObject(attempt) || !nonEmpty(attempt.id)) throw new Error('release.attempt with an immutable id is required')
79
- if (bundleKey(bundle) !== attempt.id) {
80
- throw new Error(`bundle attempt id ${JSON.stringify(bundleKey(bundle))} does not match manifest attempt ${JSON.stringify(attempt.id)}`)
81
- }
82
- if (bundle.terminalState !== state || bundle.closedBy !== ATTEMPT_CLOSE_CAUSES[state]) {
83
- throw new Error(`bundle must declare ${state}/${ATTEMPT_CLOSE_CAUSES[state]}`)
84
- }
85
- if (attempt.rcTag != null && bundle.rcTag !== attempt.rcTag) {
86
- throw new Error('bundle rcTag does not match the manifest attempt rcTag')
87
- }
88
- if (manifest.envelope?.deployTrigger != null && bundle.deployTrigger !== manifest.envelope.deployTrigger) {
89
- throw new Error('bundle deployTrigger does not match the manifest envelope')
90
- }
91
- if (manifest.release?.candidateSha != null && bundle.sha !== manifest.release.candidateSha) {
92
- throw new Error('bundle sha does not match release.candidateSha')
93
- }
94
-
95
- const validation = validateBundle(bundle)
96
- if (!validation.valid) throw new Error(`invalid bundle: ${validation.failed.join(', ')}`)
97
- const nextManifest = recordReleaseAttemptState(manifest, { state, closedBy: ATTEMPT_CLOSE_CAUSES[state], evidence })
98
- const emitted = emitBundle({ bundle, dir })
99
- return { manifest: nextManifest, bundle: emitted }
100
- }
101
-
102
- export function main(argv) {
103
- let parsed
104
- try {
105
- parsed = parseArgs(argv)
106
- if (parsed.help) {
107
- console.log(USAGE)
108
- return 0
109
- }
110
- if (parsed.positional.length !== 1) throw new Error('exactly one run-manifest path is required')
111
- const { bundle, dir, state, evidence } = parsed.options
112
- const manifestPath = parsed.positional[0]
113
- const result = closeAttempt({
114
- manifest: readJson(manifestPath, 'run manifest'),
115
- bundle: readJson(bundle, 'bundle'),
116
- dir,
117
- state,
118
- evidence,
119
- })
120
- writeManifest(manifestPath, result.manifest)
121
- process.stdout.write(JSON.stringify({
122
- attemptId: result.manifest.release.attempt.id,
123
- state: result.manifest.release.attempt.state,
124
- bundle: result.bundle,
125
- }, null, 2) + '\n')
126
- return 0
127
- } catch (error) {
128
- console.error(`close-attempt: ${error.message}\n\n${USAGE}`)
129
- return 1
130
- }
131
- }
132
-
133
- if (isMainModule(import.meta.url)) {
134
- process.exitCode = main(process.argv.slice(2))
135
- }
@@ -1,161 +0,0 @@
1
- #!/usr/bin/env node
2
- // closeout-release — the one released-path closeout command (#1025).
3
- //
4
- // A release cannot report success until every durable record is present: the finalizer writes the
5
- // terminal manifest state, this command emits then re-validates its immutable bundle, copies the
6
- // aggregate artifact, and persists both post-mortems. The normal path assembles the bundle from
7
- // manifest observations plus build/approval receipts; it never accepts a hand-authored bundle.
8
-
9
- import fs from 'node:fs'
10
-
11
- import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
12
- import { readManifest, writeManifest } from '../../resolve-issues/scripts/run-state.mjs'
13
- import { finalizeRelease } from './finalize-release.mjs'
14
- import { emitBundle, validateBundle } from './evidence-bundle.mjs'
15
- import { releaseVersion, saveReleasePostmortem } from './postmortem.mjs'
16
- import { saveVersionPostmortem, versionPostmortem } from './version-postmortem.mjs'
17
-
18
- const nonEmpty = (value) => typeof value === 'string' && value.trim() !== ''
19
-
20
- const USAGE = `closeout-release — finalize one verified release and write every terminal artifact.
21
-
22
- Usage:
23
- closeout-release.mjs --manifest <run-manifest.json>
24
- --adapter-completion-artifact <immutable-completion.json>
25
- --adapter-component-head <40-hex-component-head>
26
- --adapter-completion-sha256 <64-hex-sha256>
27
- --build-identity <build-identity.json> --approval <approval.json>
28
- [--durable-processing <durable-processing-receipts.json>]
29
- --aggregate-bundle <release-evidence.json> --postmortem-dir <dir> [--now <iso>]
30
-
31
- Sequence: finalize manifest -> emit bundle -> validate bundle -> copy aggregate bundle -> save
32
- run + version post-mortems. Any failed step exits nonzero and prints no success response. The
33
- normal path assembles the bundle from recorded observations; hand-written bundles are recovery
34
- artifacts only and must be validated with evidence-bundle.mjs before use.`
35
-
36
- function readJson(file, label) {
37
- if (!nonEmpty(file)) throw new Error(`--${label} is required`)
38
- try {
39
- return JSON.parse(fs.readFileSync(file, 'utf8'))
40
- } catch (error) {
41
- throw new Error(`${label} is not readable JSON: ${file} (${error.message})`)
42
- }
43
- }
44
-
45
- function parse(argv) {
46
- const options = {}
47
- for (let index = 0; index < argv.length; index += 1) {
48
- const arg = argv[index]
49
- if (arg === '--help' || arg === '-h') return { help: true }
50
- if (!arg.startsWith('--')) throw new Error(`unexpected positional argument ${arg}`)
51
- const key = arg.slice(2)
52
- if (!['manifest', 'adapter-completion-artifact', 'adapter-component-head', 'adapter-completion-sha256',
53
- 'build-identity', 'approval', 'durable-processing', 'aggregate-bundle', 'postmortem-dir', 'now'].includes(key)) {
54
- throw new Error(`unknown argument ${arg}`)
55
- }
56
- const value = argv[++index]
57
- if (!nonEmpty(value) || value.startsWith('--')) throw new Error(`${arg} needs a value`)
58
- options[key] = value
59
- }
60
- for (const key of ['manifest', 'adapter-completion-artifact', 'adapter-component-head',
61
- 'adapter-completion-sha256', 'build-identity', 'approval', 'aggregate-bundle', 'postmortem-dir']) {
62
- if (!nonEmpty(options[key])) throw new Error(`--${key} is required`)
63
- }
64
- return { options }
65
- }
66
-
67
- function releaseBundle(manifest, buildIdentity, approval, durableProcessing) {
68
- const release = manifest.release ?? {}
69
- const attempt = release.attempt ?? {}
70
- const candidate = release.candidateIdentity
71
- const declaredDurableProcessing = manifest.envelope?.durableProcessing
72
- if (declaredDurableProcessing?.present === true && !durableProcessing) {
73
- throw new Error('durable-processing receipts are required when the release declares durable processing')
74
- }
75
- return {
76
- attemptId: attempt.id,
77
- rcTag: release.rcTag ?? attempt.rcTag,
78
- deployTrigger: manifest.envelope?.deployTrigger,
79
- sha: manifest.shippedSha,
80
- buildIdentity,
81
- terminalState: 'released',
82
- closedBy: 'verified-release',
83
- candidateReceipt: candidate,
84
- candidateVerdict: release.candidateVerdict,
85
- approval,
86
- trafficTransition: {
87
- from: release.previousRevision,
88
- to: candidate?.revision,
89
- fromPercent: release.servingConfirmation?.previousRevisionPercent,
90
- toPercent: release.servingConfirmation?.candidatePercent,
91
- },
92
- liveVerdict: release.liveVerdict,
93
- durableProcessing: durableProcessing ?? { present: false },
94
- }
95
- }
96
-
97
- function savePostmortems(manifest, postmortemDir) {
98
- const env = { ...process.env, RESOLVER_POSTMORTEM_DIR: postmortemDir }
99
- const run = saveReleasePostmortem(manifest, env)
100
- if (!run.saved) throw new Error(`run post-mortem was not saved: ${run.error ?? 'unknown error'}`)
101
-
102
- const version = releaseVersion(manifest)
103
- if (!nonEmpty(version) || !nonEmpty(manifest.durableEvidenceDir)) {
104
- throw new Error('version post-mortem requires a release version and durableEvidenceDir')
105
- }
106
- const profile = versionPostmortem({ dir: manifest.durableEvidenceDir, version, runSlug: manifest.runSlug })
107
- if (profile.attempts.length === 0) throw new Error('version post-mortem found no durable bundles after emission')
108
- const aggregate = saveVersionPostmortem(profile, env)
109
- if (!aggregate.saved) throw new Error(`version post-mortem was not saved: ${aggregate.error ?? 'unknown error'}`)
110
- return { run: run.paths, version: aggregate.paths }
111
- }
112
-
113
- export function closeoutRelease(options) {
114
- const before = readManifest(options.manifest)
115
- const result = finalizeRelease(before, {
116
- now: options.now ?? new Date().toISOString(),
117
- adapterCompletionArtifact: options['adapter-completion-artifact'],
118
- adapterComponentHead: options['adapter-component-head'],
119
- adapterCompletionSha256: options['adapter-completion-sha256'],
120
- })
121
- if (!result.resumed) writeManifest(options.manifest, result.manifest)
122
-
123
- const buildIdentity = readJson(options['build-identity'], 'build-identity')
124
- const approval = readJson(options.approval, 'approval')
125
- const durableProcessing = options['durable-processing']
126
- ? readJson(options['durable-processing'], 'durable-processing')
127
- : null
128
- const bundle = releaseBundle(result.manifest, buildIdentity, approval, durableProcessing)
129
- const emitted = emitBundle({ bundle, dir: result.manifest.durableEvidenceDir })
130
- const written = readJson(emitted.path, 'emitted bundle')
131
- const validation = validateBundle(written)
132
- if (!validation.valid) throw new Error(`emitted bundle did not validate: ${validation.failed.join(', ')}`)
133
-
134
- fs.copyFileSync(emitted.path, options['aggregate-bundle'])
135
- const postmortems = savePostmortems(result.manifest, options['postmortem-dir'])
136
- return {
137
- ok: true,
138
- manifest: options.manifest,
139
- bundle: emitted.path,
140
- aggregateBundle: options['aggregate-bundle'],
141
- postmortems,
142
- steps: { finalize: 'passed', emit: 'passed', validate: 'passed', aggregateCopy: 'passed', postmortems: 'passed' },
143
- }
144
- }
145
-
146
- export function main(argv) {
147
- try {
148
- const parsed = parse(argv)
149
- if (parsed.help) {
150
- console.log(USAGE)
151
- return 0
152
- }
153
- console.log(JSON.stringify(closeoutRelease(parsed.options), null, 2))
154
- return 0
155
- } catch (error) {
156
- console.error(`closeout-release: ${error.message}`)
157
- return 1
158
- }
159
- }
160
-
161
- if (isMainModule(import.meta.url)) process.exitCode = main(process.argv.slice(2))
@@ -1,106 +0,0 @@
1
- // The release doctrine as ONE document, however it happens to be split across files.
2
- //
3
- // Why this exists: SKILL.md used to be the whole doctrine — 490 lines, 129KB — and the
4
- // doctrine tests in this directory read it directly and slice it by heading. Then a real
5
- // failure showed up: an agent harness loaded the skill and got lines 1-260 of 491, which cut
6
- // off step 4 (the traffic shift), step 5 (rollback routing), and the Reference Map that would
7
- // have told it where to look. Nothing warned anyone; the model simply never received the
8
- // second half of a production-release procedure.
9
- //
10
- // The fix was to make SKILL.md an index and move each phase into `references/`. That kept
11
- // every word (the sections were extracted verbatim), but it broke the premise the tests were
12
- // written on — that "the doctrine" and "SKILL.md" are the same string.
13
- //
14
- // They were never the same thing, and that is the point. These tests grade the *doctrine*:
15
- // that a passage exists, that two rules appear in a required order, that a slice stops at its
16
- // sibling. All of that is preserved by a move; none of it is a claim about which file the prose
17
- // sits in. So the doctrine is reassembled here, in its original document order, and the tests
18
- // read it from this module instead of from a path.
19
- //
20
- // The reassembly is faithful rather than approximate: each phase file was extracted as a
21
- // contiguous line range, in order, so concatenating them in that order reproduces the original
22
- // document. Two details make it exact:
23
- //
24
- // 1. Each reference file opens with a NEW `# Title` and orientation paragraph that did not
25
- // exist in the original. Those are stripped — the body resumes at the first heading that
26
- // came from the original document, which is why each entry below names it.
27
- // 2. SKILL.md now carries a `## Non-negotiable principles` heading of its own, holding the
28
- // 14 rules as a one-line index. Concatenating SKILL.md whole would put that index ahead of
29
- // the real section and every principle-body slice would land in the index instead. So
30
- // SKILL.md contributes only its head (frontmatter → Related skills) and its tail
31
- // (Definition of done onward); the principles section comes from `principles.md`.
32
- //
33
- // If a future split moves a section again, update the ORDER table below in the same commit.
34
- // A test that fails because prose moved is this module being out of date, not doctrine being
35
- // lost — but do confirm which of the two it is before editing anything here.
36
- import fs from 'node:fs'
37
- import path from 'node:path'
38
- import { fileURLToPath } from 'node:url'
39
-
40
- const skillDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
41
- const read = (rel) => fs.readFileSync(path.join(skillDir, rel), 'utf8')
42
-
43
- // Each phase file, and the first heading in it that came from the original SKILL.md. Everything
44
- // above that heading is this-file-only orientation and is dropped.
45
- const ORDER = [
46
- { file: 'references/principles.md', resumeAt: '## Non-negotiable principles' },
47
- { file: 'references/preflight.md', resumeAt: '## Pre-flight gate: confirm the authorization envelope' },
48
- { file: 'references/assembly.md', resumeAt: '### 0 — Intake' },
49
- { file: 'references/candidate.md', resumeAt: '### 3 — Promote' },
50
- { file: 'references/exposure.md', resumeAt: '### 4 — Validate' },
51
- { file: 'references/routing.md', resumeAt: '### 5 — Route' },
52
- // The handoff report moved off SKILL.md (2026-08-17); the doctrine follows it.
53
- { file: 'references/handoff.md', resumeAt: '## Every item' },
54
- ]
55
-
56
- function bodyFrom({ file, resumeAt }) {
57
- const text = read(file)
58
- const idx = text.indexOf(`\n${resumeAt}`)
59
- if (idx < 0) {
60
- throw new Error(
61
- `doctrine.mjs: ${file} no longer contains "${resumeAt}". Either the heading was reworded ` +
62
- '(update ORDER in this file, same commit) or the section was moved again (update ORDER, ' +
63
- 'and check the section still exists somewhere before assuming it is only a rename).',
64
- )
65
- }
66
- return text.slice(idx + 1)
67
- }
68
-
69
- // SKILL.md's own contribution: its head, and its tail from Definition of done onward. The
70
- // sections between those two — the routing index, the principles INDEX, the loop table — are
71
- // navigation this module deliberately excludes, because the doctrine they point at is included
72
- // in full from the files above and a duplicate heading would capture every slice.
73
- function skillHeadAndTail() {
74
- const text = read('SKILL.md')
75
- const headEnd = text.indexOf('\n## Routing')
76
- const tailStart = text.indexOf('\n## Definition of done')
77
- if (headEnd < 0 || tailStart < 0) {
78
- throw new Error(
79
- 'doctrine.mjs: SKILL.md is missing "## Routing" or "## Definition of done". Both are ' +
80
- 'structural — Routing is the index that has to survive a truncated load, and Definition ' +
81
- 'of done is graded prose. Restore the heading, or update this loader in the same commit.',
82
- )
83
- }
84
- return { head: text.slice(0, headEnd), tail: text.slice(tailStart) }
85
- }
86
-
87
- // `## The release loop` opened the step sequence in the original document and now lives only in
88
- // SKILL.md's navigation table, so it is reinserted at its original position — before step 0, not
89
- // after step 5. Order is load-bearing here: several tests assert that one rule appears before
90
- // another, and they would read a shuffled reassembly as a doctrine defect.
91
- const LOOP_HEADING_BEFORE = 'references/assembly.md'
92
-
93
- export function loadDoctrine() {
94
- const { head, tail } = skillHeadAndTail()
95
- const parts = [head]
96
- for (const entry of ORDER) {
97
- if (entry.file === LOOP_HEADING_BEFORE) parts.push('## The release loop')
98
- parts.push(bodyFrom(entry))
99
- }
100
- parts.push(tail)
101
- return parts.join('\n')
102
- }
103
-
104
- // The assembled doctrine. Named `SKILL` at the call sites for continuity with the tests that
105
- // already sliced a variable by that name — the string is what they were always asserting about.
106
- export const DOCTRINE = loadDoctrine()