@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,449 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // Bounded, observation-only watcher for an RC-triggered Cloud Run candidate delivery.
4
- // stdout is exactly one terminal JSON verdict; stderr is one NDJSON heartbeat per poll.
5
-
6
- import { execFileSync } from 'node:child_process'
7
- import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
8
- import { evaluateAttest, evaluateLocate, parseTraffic, shaMatches } from './candidate-identity.mjs'
9
-
10
- export const DEFAULT_INTERVAL_SECONDS = 30
11
- export const DEFAULT_MAX_MINUTES = 30
12
- export const MAX_MINUTES_CEILING = 60
13
- export const DEFAULT_READ_TIMEOUT_SECONDS = 30
14
-
15
- const RC_TAG_RE = /^v\d+\.\d+\.\d+-rc\.\d+$/
16
- const FULL_SHA_RE = /^[0-9a-f]{40}$/i
17
- const BUILD_ACTIVE = new Set(['QUEUED', 'PENDING', 'WORKING'])
18
- const BUILD_FAILED = new Set(['FAILURE', 'INTERNAL_ERROR', 'TIMEOUT', 'CANCELLED', 'EXPIRED'])
19
- const CANDIDATE_IDENTITY_CONTRADICTIONS = new Set([
20
- 'candidate-identity-refused',
21
- 'candidate-revision-mismatch',
22
- 'candidate-health-mismatch',
23
- 'candidate-image-mismatch',
24
- ])
25
-
26
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
27
- const nonEmpty = (value) => typeof value === 'string' && value.trim() !== ''
28
- const asArray = (value) => Array.isArray(value) ? value : []
29
-
30
- function parseJson(text) {
31
- try {
32
- return { value: JSON.parse(text) }
33
- } catch {
34
- return { error: 'provider returned invalid JSON' }
35
- }
36
- }
37
-
38
- export function runRead(command, args, timeoutMs) {
39
- try {
40
- const stdout = execFileSync(command, args, {
41
- encoding: 'utf8',
42
- stdio: ['ignore', 'pipe', 'pipe'],
43
- timeout: timeoutMs,
44
- })
45
- const parsed = parseJson(stdout)
46
- return parsed.error
47
- ? { readable: false, error: parsed.error }
48
- : { readable: true, value: parsed.value }
49
- } catch (error) {
50
- return {
51
- readable: false,
52
- error: error.stderr?.toString?.().trim() || error.message || `${command} failed`,
53
- }
54
- }
55
- }
56
-
57
- function buildIdentityValues(build) {
58
- const substitutions = build?.substitutions && typeof build.substitutions === 'object'
59
- ? build.substitutions
60
- : {}
61
- const resolved = build?.sourceProvenance?.resolvedRepoSource ?? {}
62
- const source = build?.source?.repoSource ?? {}
63
- return {
64
- tags: [
65
- substitutions.TAG_NAME,
66
- substitutions._TAG_NAME,
67
- resolved.tagName,
68
- source.tagName,
69
- ].filter(nonEmpty),
70
- shas: [
71
- substitutions.COMMIT_SHA,
72
- substitutions._COMMIT_SHA,
73
- resolved.commitSha,
74
- source.commitSha,
75
- ].filter(nonEmpty),
76
- }
77
- }
78
-
79
- function receipt(build) {
80
- return {
81
- id: build?.id ?? null,
82
- status: nonEmpty(build?.status) ? build.status.toUpperCase() : null,
83
- createTime: build?.createTime ?? null,
84
- finishTime: build?.finishTime ?? null,
85
- logUrl: build?.logUrl ?? null,
86
- }
87
- }
88
-
89
- export function inspectBuilds(value, { rcTag, selectedSha }) {
90
- if (!Array.isArray(value)) {
91
- return { readable: false, matchingReceipts: 0, receipt: null, error: 'build list is not an array' }
92
- }
93
- const matching = value
94
- .filter((build) => {
95
- const identity = buildIdentityValues(build)
96
- return identity.tags.includes(rcTag) && identity.shas.some((sha) => shaMatches(sha, selectedSha))
97
- })
98
- .sort((left, right) => String(right.createTime ?? '').localeCompare(String(left.createTime ?? '')))
99
-
100
- return {
101
- readable: true,
102
- listedReceipts: value.length,
103
- matchingReceipts: matching.length,
104
- receipt: matching.length > 0 ? receipt(matching[0]) : null,
105
- }
106
- }
107
-
108
- function readyCondition(revision) {
109
- const conditions = asArray(revision?.status?.conditions)
110
- const ready = conditions.find((condition) => condition?.type === 'Ready')
111
- return ready
112
- ? { status: ready.status ?? null, reason: ready.reason ?? null, message: ready.message ?? null }
113
- : { status: null, reason: null, message: null }
114
- }
115
-
116
- function healthUrl(candidateUrl, healthPath) {
117
- return `${candidateUrl.replace(/\/$/, '')}/${healthPath.replace(/^\//, '')}`
118
- }
119
-
120
- function baseCandidate(locate) {
121
- return {
122
- failed: locate.failed ?? [],
123
- tag: locate.evidence?.candidate?.tag ?? null,
124
- url: locate.evidence?.candidate?.url ?? null,
125
- revision: locate.evidence?.candidate?.revision ?? null,
126
- percent: locate.evidence?.candidate?.percent ?? null,
127
- identity: null,
128
- ready: null,
129
- }
130
- }
131
-
132
- export function observeCandidate({ serviceRead, revisionRead, healthRead, selectedSha }) {
133
- if (!serviceRead.readable) {
134
- return {
135
- state: 'ambiguous',
136
- terminal: true,
137
- reason: 'service-unreadable',
138
- candidate: { failed: ['e:service-unreadable'], error: serviceRead.error },
139
- }
140
- }
141
- const traffic = parseTraffic(JSON.stringify(serviceRead.value))
142
- if (traffic.error) {
143
- return {
144
- state: 'ambiguous',
145
- terminal: true,
146
- reason: 'service-traffic-unreadable',
147
- candidate: { failed: ['e:service-traffic-unreadable'], error: traffic.error },
148
- }
149
- }
150
- const locate = evaluateLocate({ sha: selectedSha, traffic })
151
- if (locate.failed?.length === 1 && locate.failed[0] === 'e:candidate-absent') {
152
- return { state: 'absent', terminal: false, reason: 'candidate-not-observed', candidate: baseCandidate(locate) }
153
- }
154
- if (locate.decision !== 'accept') {
155
- return {
156
- state: 'ambiguous',
157
- terminal: true,
158
- reason: 'candidate-identity-refused',
159
- candidate: baseCandidate(locate),
160
- }
161
- }
162
-
163
- const candidate = baseCandidate(locate)
164
- if (!revisionRead?.readable) {
165
- return {
166
- state: 'ambiguous',
167
- terminal: true,
168
- reason: 'candidate-revision-unreadable',
169
- candidate: { ...candidate, failed: ['e:candidate-revision-unreadable'], error: revisionRead?.error },
170
- }
171
- }
172
- if (revisionRead.value?.metadata?.name && revisionRead.value.metadata.name !== candidate.revision) {
173
- return {
174
- state: 'ambiguous',
175
- terminal: true,
176
- reason: 'candidate-revision-mismatch',
177
- candidate: { ...candidate, failed: ['e:candidate-revision-mismatch'] },
178
- }
179
- }
180
- candidate.ready = readyCondition(revisionRead.value)
181
- if (candidate.ready.status === 'False') {
182
- return { state: 'failed', terminal: true, reason: 'candidate-not-ready', candidate }
183
- }
184
- if (candidate.ready.status !== 'True') {
185
- return { state: 'building', terminal: false, reason: 'candidate-readiness-pending', candidate }
186
- }
187
-
188
- if (!healthRead?.readable) {
189
- return {
190
- state: 'ambiguous',
191
- terminal: true,
192
- reason: 'candidate-health-unreadable',
193
- candidate: { ...candidate, failed: ['e:candidate-health-unreadable'], error: healthRead?.error },
194
- }
195
- }
196
- const attested = evaluateAttest({
197
- sha: selectedSha,
198
- locate,
199
- health: healthRead.value,
200
- })
201
- if (attested.decision !== 'accept') {
202
- return {
203
- state: 'ambiguous',
204
- terminal: true,
205
- reason: 'candidate-health-mismatch',
206
- candidate: { ...candidate, failed: attested.failed ?? [] },
207
- }
208
- }
209
-
210
- const revisionDigest = revisionRead.value?.status?.imageDigest
211
- if (nonEmpty(revisionDigest) && revisionDigest.toLowerCase() !== attested.identity.imageDigest.toLowerCase()) {
212
- return {
213
- state: 'ambiguous',
214
- terminal: true,
215
- reason: 'candidate-image-mismatch',
216
- candidate: { ...candidate, failed: ['e:digest-mismatch'] },
217
- }
218
- }
219
- return {
220
- state: 'ready-at-0',
221
- terminal: true,
222
- reason: 'candidate-ready-and-attested',
223
- candidate: { ...candidate, failed: [], identity: attested.identity },
224
- }
225
- }
226
-
227
- function classifyPoll({ build, candidate }) {
228
- // Candidate delivery is authoritative success even when the build API omits identity fields.
229
- if (candidate.state === 'ready-at-0') return candidate
230
- // Definitive candidate failure and identity contradictions are stronger than build receipts.
231
- if (candidate.state === 'failed' || CANDIDATE_IDENTITY_CONTRADICTIONS.has(candidate.reason)) {
232
- return candidate
233
- }
234
-
235
- const status = build.receipt?.status ?? null
236
- // An exact terminal receipt is stronger than ambiguity caused only by unreadable provider data.
237
- if (BUILD_FAILED.has(status)) {
238
- return { state: 'failed', terminal: true, reason: 'build-failed', candidate: candidate.candidate }
239
- }
240
- if (candidate.terminal) return candidate
241
- if (!build.readable) {
242
- return {
243
- state: 'ambiguous',
244
- terminal: true,
245
- reason: 'build-and-candidate-inconclusive',
246
- candidate: candidate.candidate,
247
- }
248
- }
249
- if (build.receipt && status !== null && !BUILD_ACTIVE.has(status) && status !== 'SUCCESS') {
250
- return {
251
- state: 'ambiguous',
252
- terminal: true,
253
- reason: 'unknown-build-status',
254
- candidate: candidate.candidate,
255
- }
256
- }
257
- if (BUILD_ACTIVE.has(status) || status === 'SUCCESS' || candidate.state === 'building') {
258
- return { state: 'building', terminal: false, reason: 'delivery-in-progress', candidate: candidate.candidate }
259
- }
260
- return { state: 'not-triggered', terminal: false, reason: 'no-exact-build-or-candidate', candidate: candidate.candidate }
261
- }
262
-
263
- export function parseArgs(argv) {
264
- const args = {
265
- intervalSeconds: DEFAULT_INTERVAL_SECONDS,
266
- maxMinutes: DEFAULT_MAX_MINUTES,
267
- readTimeoutSeconds: DEFAULT_READ_TIMEOUT_SECONDS,
268
- healthPath: '/health',
269
- }
270
- for (let index = 0; index < argv.length; index += 1) {
271
- const arg = argv[index]
272
- if (arg === '--rc-tag') args.rcTag = argv[++index]
273
- else if (arg === '--sha') args.selectedSha = argv[++index]
274
- else if (arg === '--service') args.service = argv[++index]
275
- else if (arg === '--region') args.region = argv[++index]
276
- else if (arg === '--build-region') args.buildRegion = argv[++index]
277
- else if (arg === '--interval-seconds') args.intervalSeconds = Number(argv[++index])
278
- else if (arg === '--max-minutes') args.maxMinutes = Number(argv[++index])
279
- else if (arg === '--read-timeout-seconds') args.readTimeoutSeconds = Number(argv[++index])
280
- else if (arg === '--health-path') args.healthPath = argv[++index]
281
- else if (arg === '--help' || arg === '-h') args.help = true
282
- else args.unknown = arg
283
- }
284
- args.buildRegion ??= args.region
285
- return args
286
- }
287
-
288
- const USAGE = `watch-candidate-delivery --rc-tag <vX.Y.Z-rc.N> --sha <40-hex-sha> --service <name> --region <region> [options]
289
-
290
- Observe one RC-triggered candidate delivery. The immutable release identity is the exact RC tag
291
- plus selected SHA. Build receipts are matched locally when their identity fields are readable;
292
- an exactly SHA-keyed Cloud Run candidate at 0%, Ready, and health-attested is authoritative even
293
- when build substitutions are absent.
294
-
295
- Options:
296
- --build-region <region> Cloud Build region; defaults to --region
297
- --interval-seconds <n> Poll interval; default 30
298
- --max-minutes <n> Absolute watch bound; default 30, hard maximum 60
299
- --read-timeout-seconds <n> Per-provider-read timeout; default 30
300
- --health-path <path> Candidate identity health path; default /health
301
-
302
- States: not-triggered, building, ready-at-0, failed, timed-out, ambiguous.
303
-
304
- Output:
305
- stdout exactly one terminal JSON verdict
306
- stderr one NDJSON heartbeat per poll, including the terminal poll
307
-
308
- Exit codes: 0 ready-at-0; 4 failed, timed-out, or ambiguous; 2 usage error.
309
-
310
- The watcher observes only. It never creates or moves a tag, changes traffic, writes release
311
- state, closes an attempt lease, deploys, deletes, retries, or invokes a mutating provider API.`
312
-
313
- function validateArgs(args) {
314
- if (args.help) return null
315
- if (args.unknown) return `unknown option: ${args.unknown}`
316
- if (!RC_TAG_RE.test(args.rcTag ?? '')) return 'RC tag must match vX.Y.Z-rc.N'
317
- if (!FULL_SHA_RE.test(args.selectedSha ?? '')) return 'selected SHA must be 40 hexadecimal characters'
318
- for (const field of ['service', 'region', 'buildRegion', 'healthPath']) {
319
- if (!nonEmpty(args[field])) return `${field} is required`
320
- }
321
- for (const field of ['intervalSeconds', 'maxMinutes', 'readTimeoutSeconds']) {
322
- if (!Number.isFinite(args[field]) || args[field] <= 0) return `${field} must be a positive number`
323
- }
324
- if (args.maxMinutes > MAX_MINUTES_CEILING) {
325
- return `maxMinutes exceeds the ${MAX_MINUTES_CEILING}-minute hard ceiling`
326
- }
327
- return null
328
- }
329
-
330
- function heartbeat(payload) {
331
- return JSON.stringify({ ...payload, progress: true, terminal: false, at: new Date().toISOString() })
332
- }
333
-
334
- export async function runCli(argv) {
335
- const args = parseArgs(argv)
336
- if (args.help) {
337
- console.log(USAGE)
338
- return 0
339
- }
340
- const invalid = validateArgs(args)
341
- if (invalid) {
342
- console.error(`watch-candidate-delivery: ${invalid}\n\n${USAGE}`)
343
- return 2
344
- }
345
-
346
- const releaseIdentity = { rcTag: args.rcTag, selectedSha: args.selectedSha.toLowerCase() }
347
- const startedMs = Date.now()
348
- const deadlineMs = startedMs + args.maxMinutes * 60_000
349
- const configuredReadTimeoutMs = args.readTimeoutSeconds * 1000
350
- let observations = 0
351
- let lastPayload = null
352
-
353
- for (;;) {
354
- const remainingBeforePollMs = deadlineMs - Date.now()
355
- if (lastPayload && remainingBeforePollMs < 1_000) {
356
- console.log(JSON.stringify({
357
- ...lastPayload,
358
- state: 'timed-out',
359
- outcome: 'timed-out',
360
- terminal: true,
361
- reason: 'max-minutes',
362
- elapsedMs: Date.now() - startedMs,
363
- }, null, 2))
364
- return 4
365
- }
366
- observations += 1
367
- // A poll makes at most four external reads. Giving each only its share of the
368
- // remaining watch time keeps a hung child inside the absolute ceiling.
369
- let readsRemaining = 4
370
- const readTimeoutMs = () => Math.max(1, Math.min(
371
- configuredReadTimeoutMs,
372
- Math.floor(Math.max(1, deadlineMs - Date.now()) / readsRemaining--),
373
- ))
374
- const buildRead = runRead('gcloud', [
375
- 'builds', 'list', '--region', args.buildRegion,
376
- '--sort-by=~createTime', '--limit=50', '--format=json',
377
- ], readTimeoutMs())
378
- const build = buildRead.readable
379
- ? inspectBuilds(buildRead.value, releaseIdentity)
380
- : { readable: false, matchingReceipts: 0, receipt: null, error: buildRead.error }
381
-
382
- const serviceRead = runRead('gcloud', [
383
- 'run', 'services', 'describe', args.service,
384
- '--region', args.region, '--format=json',
385
- ], readTimeoutMs())
386
-
387
- let revisionRead = null
388
- let healthRead = null
389
- if (serviceRead.readable) {
390
- const traffic = parseTraffic(JSON.stringify(serviceRead.value))
391
- const locate = traffic.error ? null : evaluateLocate({ sha: releaseIdentity.selectedSha, traffic })
392
- const located = locate?.decision === 'accept' ? locate.evidence.candidate : null
393
- if (located) {
394
- revisionRead = runRead('gcloud', [
395
- 'run', 'revisions', 'describe', located.revision,
396
- '--region', args.region, '--format=json',
397
- ], readTimeoutMs())
398
- if (revisionRead.readable && readyCondition(revisionRead.value).status === 'True') {
399
- healthRead = runRead('curl', [
400
- '--fail', '--silent', '--show-error',
401
- '--max-time', String(args.readTimeoutSeconds),
402
- healthUrl(located.url, args.healthPath),
403
- ], readTimeoutMs())
404
- }
405
- }
406
- }
407
-
408
- const candidate = observeCandidate({
409
- serviceRead,
410
- revisionRead,
411
- healthRead,
412
- selectedSha: releaseIdentity.selectedSha,
413
- })
414
- const classified = classifyPoll({ build, candidate })
415
- const elapsedMs = Date.now() - startedMs
416
- const deadlineInconclusive = new Set([
417
- 'service-unreadable',
418
- 'candidate-revision-unreadable',
419
- 'candidate-health-unreadable',
420
- 'build-and-candidate-inconclusive',
421
- ])
422
- const effective = Date.now() >= deadlineMs &&
423
- (!classified.terminal || deadlineInconclusive.has(classified.reason))
424
- ? { ...classified, state: 'timed-out', terminal: true, reason: 'max-minutes' }
425
- : classified
426
- const payload = {
427
- state: effective.state,
428
- releaseIdentity,
429
- reason: effective.reason,
430
- observations,
431
- elapsedMs,
432
- build,
433
- candidate: effective.candidate,
434
- }
435
- lastPayload = payload
436
- console.error(heartbeat(payload))
437
-
438
- if (effective.terminal) {
439
- console.log(JSON.stringify({ ...payload, outcome: effective.state, terminal: true }, null, 2))
440
- return effective.state === 'ready-at-0' ? 0 : 4
441
- }
442
- const remainingMs = deadlineMs - Date.now()
443
- if (remainingMs > 0) await sleep(Math.min(args.intervalSeconds * 1000, remainingMs))
444
- }
445
- }
446
-
447
- if (isMainModule(import.meta.url)) {
448
- runCli(process.argv.slice(2)).then((code) => { process.exitCode = code })
449
- }
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (C) 2012-2022 by various contributors (see AUTHORS)
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
@@ -1,60 +0,0 @@
1
- # Vendored adapter dependencies
2
-
3
- Installed `resolve-release` skills have no package-install step, so the checked adapter
4
- loader ships exact reviewed distribution artifacts instead of resolving mutable runtime
5
- packages.
6
-
7
- ## Acorn
8
-
9
- `acorn.mjs` is the dependency-free ESM distribution artifact from Acorn 8.15.0.
10
-
11
- - Source package: `acorn@8.15.0`
12
- - Registry integrity: `sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==`
13
- - `acorn.mjs` SHA-256: `b4c8c70200e72bae33cf1085e0ecb1e792c1b6924ed50cab817caf14f51bb249`
14
- - License: MIT, retained in `ACORN-LICENSE`
15
-
16
- ## QuickJS-WASM
17
-
18
- The isolated evaluator ships the minimal release-sync package graph at version 0.32.0:
19
-
20
- | Package | Registry integrity | Shipped directory |
21
- |---|---|---|
22
- | `quickjs-emscripten-core@0.32.0` | `sha512-QFnPfjFey8EqknSrSxe1hZrf1/8z7/6s1QzGOmKo6++02r7QRRX7ZoyNaZh7JuVjWsVW87KnQrbZqnHkOAzUyg==` | `quickjs/core` |
23
- | `@jitl/quickjs-wasmfile-release-sync@0.32.0` | `sha512-BKNDI/TPBfGlLNGYpLrhcDGXmIk4xHm4MRAisOBnOzpXVn9HZWsfmMAc9WMBrAHjvvds6HOikKeaOBKdPdpVrg==` | `quickjs/release-sync` |
24
- | `@jitl/quickjs-ffi-types@0.32.0` | `sha512-v9T+GQpmk43VDJ7d72sf0Nexhk+ArvtUihW27dy7lqAl0zBObFKtSBBIm5RBjwIhE8VwsPPm9PNuvPvNqLWUEg==` | `quickjs/ffi-types` |
25
-
26
- Registry tarball SHA-512 values, in the same order, are:
27
-
28
- - `4059cf7e315ecbc12a9274ab4b17b5859adfd7ff33effeacd50cc63a62a8ebefb4dabed04515fb668c8d69987b26e5635ac556f3b2a742b6d9aa71e4380cd4ca`
29
- - `04a34323f4cf05f1a52cd198a4bae1703197988938c479b8311022b0e0673b3a57567f47656b1f98c01cf56301ac01e3bef76ce873a290a79a38129d3dda55ae`
30
- - `bfd4fe190a66938dd50c9eddef6b1fd0d7b1864f80aefb548a15b6eddcbb96a025d3304e6c52ad4810489b94418f022113c570b0f3e6f4f36ebcfbcda8b59412`
31
-
32
- The package distributions are retained intact except for three transparent ESM resolution
33
- rewrites required by the package-manager-free skill layout:
34
-
35
- - `core/dist/index.mjs`: `@jitl/quickjs-ffi-types` -> `../../ffi-types/dist/index.mjs`
36
- - `core/dist/chunk-V2S4ZYJR.mjs`: `@jitl/quickjs-ffi-types` -> `../../ffi-types/dist/index.mjs`
37
- - `release-sync/dist/index.mjs`: package export -> `./emscripten-module.mjs`
38
-
39
- Post-rewrite SHA-256 values:
40
-
41
- - `core/dist/index.mjs`: `6fd846a7804a3835825dc385f7ac5969a4ec1421cbefc7c007c3c4d3d1ec217e`
42
- - `core/dist/chunk-V2S4ZYJR.mjs`: `29b79919fd8e49ae690c7f31671d0921b800f8d5cf5623784a96ec9fe5103a6b`
43
- - `release-sync/dist/index.mjs`: `b01acd6fcc4af5c841f961f76f5ca8fec1b1778b42c7d257b7903fd2fe466f23`
44
- - `release-sync/dist/emscripten-module.wasm`: `105c3bed22d457e43e3d1c3c1c6959fda62a8fe06f0fc8a985303c3a2be72232`
45
-
46
- Licenses are retained with each package. The core/FFI MIT license SHA-256 is
47
- `3c6040aa318612a234cc951609b640c0c63d85ae5a98a9330d3116f1553a79db`; the
48
- release-sync notice, which includes both quickjs-emscripten MIT and upstream QuickJS MIT,
49
- is `446a69ae534aa8612d8b16d3bfc670c5a5050597dca3ce9820441a60d5d04fbb`.
50
-
51
- The release-sync wrapper reads only its adjacent pinned WASM artifact during module
52
- initialization. Adapter bytes run in a fresh QuickJS runtime/heap with no module loader,
53
- no guest-callable host function, and no Node/Bun/Deno, filesystem, environment, stdio,
54
- network, timer, crypto, URL, messaging, or WebAssembly global. The host/guest boundary is
55
- JSON text plus validated plain metadata/results and deferred bounded file intents.
56
-
57
- The runtime is bounded to 32 MiB heap, 256 KiB stack, 250 ms execution, 1,024 pending
58
- jobs, 256 KiB request/config payloads, 1 MiB results/files, 32 configured files, depth 32,
59
- and 10,000 serialized nodes. Every context, handle, and runtime is disposed after
60
- inspection or execution.