@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,345 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
-
3
- import {
4
- defineCurrentTurnCapabilities,
5
- defineQuestionAnswers,
6
- defineQuestionSpec,
7
- normalizeQuestionResponses,
8
- planStructuredQuestions,
9
- } from '../../harness-runtime/index.mjs'
10
- import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
11
-
12
- const AUTONOMY_OPTIONS = Object.freeze([
13
- Object.freeze({
14
- id: 'autonomous',
15
- label: 'Autonomous',
16
- description: 'Pre-authorize reversible parks and delivery to the target branch.',
17
- }),
18
- Object.freeze({
19
- id: 'supervised',
20
- label: 'Supervised',
21
- description: 'Stop for each decision that requires human authorization.',
22
- }),
23
- ])
24
-
25
- function isRecord(value) {
26
- return value !== null && typeof value === 'object' && !Array.isArray(value)
27
- }
28
-
29
- function nonEmptyString(value) {
30
- return typeof value === 'string' && value.trim().length > 0
31
- }
32
-
33
- function invalid(message) {
34
- throw new TypeError(`Invalid Resolve Issues pre-flight: ${message}`)
35
- }
36
-
37
- function defineOption(option, label) {
38
- if (!isRecord(option)
39
- || !nonEmptyString(option.id)
40
- || !nonEmptyString(option.label)
41
- || !nonEmptyString(option.description)) {
42
- invalid(`${label} contains a malformed option`)
43
- }
44
- return Object.freeze({
45
- id: option.id,
46
- label: option.label,
47
- description: option.description,
48
- ...(nonEmptyString(option.family) ? { family: option.family } : {}),
49
- ...(nonEmptyString(option.effort) ? { effort: option.effort } : {}),
50
- })
51
- }
52
-
53
- function defineChoiceSet(value, label) {
54
- if (!isRecord(value) || !Array.isArray(value.options) || !nonEmptyString(value.recommended)) {
55
- invalid(`${label} choices require options and a recommended id`)
56
- }
57
- const ids = new Set()
58
- const options = value.options.map((option) => {
59
- if (isRecord(option) && ids.has(option.id)) invalid(`${label} choices contain a duplicate option`)
60
- const defined = defineOption(option, `${label} choices`)
61
- ids.add(defined.id)
62
- return defined
63
- })
64
- if (!ids.has(value.recommended)) invalid(`${label} recommendation is not an option`)
65
- return Object.freeze({ recommended: value.recommended, options: Object.freeze(options) })
66
- }
67
-
68
- // The reviewer slot is never asked (pre-flight.md step 2): it is FILLED from a
69
- // ranking the caller supplies -- the team default first, then the diversity
70
- // ladder -- and resolved against the answered implementer, because "reviewer !=
71
- // implementer" is the only thing that can collide and it is decidable without a
72
- // human. Accepts { default }, { candidates: [...] }, both, or the legacy asked
73
- // shape { recommended, options }, which ranks the recommendation first.
74
- function defineReviewRanking(value, label) {
75
- if (!isRecord(value)) invalid(`${label} requires a default and/or ranked candidates`)
76
- const teamDefault = value.default === undefined ? null : defineOption(value.default, `${label} default`)
77
- const supplied = []
78
- if (Array.isArray(value.candidates)) {
79
- for (const candidate of value.candidates) supplied.push(defineOption(candidate, `${label} candidates`))
80
- } else if (value.options !== undefined || value.recommended !== undefined) {
81
- const choices = defineChoiceSet(value, label)
82
- const recommended = choices.options.find((option) => option.id === choices.recommended)
83
- supplied.push(recommended, ...choices.options.filter((option) => option.id !== choices.recommended))
84
- }
85
-
86
- const ranked = []
87
- const ids = new Set()
88
- for (const option of [...(teamDefault ? [teamDefault] : []), ...supplied]) {
89
- if (ids.has(option.id)) continue
90
- ids.add(option.id)
91
- ranked.push(option)
92
- }
93
- if (ranked.length === 0) invalid(`${label} requires a default and/or ranked candidates`)
94
- return Object.freeze({ default: teamDefault, candidates: Object.freeze(ranked) })
95
- }
96
-
97
- function question(id, header, prompt, choiceSet) {
98
- return defineQuestionSpec({
99
- id,
100
- header,
101
- prompt,
102
- options: choiceSet.options.map(({ id: optionId, label, description }) => ({
103
- id: optionId,
104
- label,
105
- description,
106
- })),
107
- recommendationOrder: [choiceSet.recommended],
108
- })
109
- }
110
-
111
- function metadataEntries(choiceSet) {
112
- return choiceSet.options.map((option) => [option.id, option])
113
- }
114
-
115
- export function planPreflightQuestions(value) {
116
- if (!isRecord(value)) invalid('input must be an object')
117
- const capabilities = defineCurrentTurnCapabilities(value.capabilities)
118
- const implementation = defineChoiceSet(value.implementation, 'implementation')
119
- const target = defineChoiceSet(value.target, 'target branch')
120
- const review = defineReviewRanking(value.review, 'review')
121
- // Autonomy is FILLED, not asked — same shape as the reviewer slot. Completing
122
- // pre-flight records `autonomous` (and therefore mergeShippable-on) unless the
123
- // human overrides in the answer batch or prompt. An unset field on a manifest
124
- // that never ran pre-flight still resolves to supervised elsewhere; this fill
125
- // is what makes a completed pre-flight a recorded authorization.
126
- const autonomy = Object.freeze({ recommended: 'autonomous', options: AUTONOMY_OPTIONS })
127
-
128
- const questions = [
129
- question('implementation', 'Implement', 'Which model should implement every unit in this run?', implementation),
130
- question('target_branch', 'Target', 'Which fetched remote branch should every unit target?', target),
131
- ]
132
- const interaction = planStructuredQuestions(capabilities, questions)
133
- const metadata = Object.freeze(Object.fromEntries([
134
- ...metadataEntries(implementation),
135
- ...review.candidates.map((option) => [option.id, option]),
136
- ]))
137
-
138
- return Object.freeze({
139
- capabilities,
140
- questions: Object.freeze(questions),
141
- interaction,
142
- // Filled slots stated in the pre-flight summary; `record` may honour overrides.
143
- defaulted: Object.freeze({
144
- review: review.candidates[0].id,
145
- autonomy: autonomy.recommended,
146
- }),
147
- reviewRanking: Object.freeze(review.candidates.map((option) => option.id)),
148
- freeTextQuestions: Object.freeze(interaction.kind === 'fallback'
149
- ? questions.map(({ id, prompt }) => Object.freeze({ questionId: id, prompt }))
150
- : []),
151
- selections: Object.freeze({
152
- implementation,
153
- review,
154
- target,
155
- autonomy,
156
- }),
157
- modelMetadata: metadata,
158
- })
159
- }
160
-
161
- function singleAnswer(answers, questionId) {
162
- const values = answers[questionId]
163
- if (!Array.isArray(values) || values.length !== 1 || !nonEmptyString(values[0])) {
164
- invalid(`${questionId} requires exactly one answer`)
165
- }
166
- return values[0]
167
- }
168
-
169
- function selectedOption(choiceSet, id, { allowCustom = false } = {}) {
170
- const option = choiceSet.options?.find((candidate) => candidate.id === id)
171
- if (option) return option
172
- if (allowCustom) return Object.freeze({ id, label: id, description: 'Human-named value.' })
173
- invalid(`answer ${JSON.stringify(id)} is not available for its question`)
174
- }
175
-
176
- function modelPoint(models, slot, option) {
177
- models[slot] = option.id
178
- if (nonEmptyString(option.family)) models[`${slot}Family`] = option.family
179
- if (nonEmptyString(option.effort) && option.effort !== 'high') models[`${slot}Effort`] = option.effort
180
- }
181
-
182
- // Resolve the reviewer fill now that the implementer is answered. Order: the
183
- // human's own override (they named it in the prompt), then the ranking's first
184
- // candidate that is not the implementer. Only a ranking with no distinct
185
- // candidate at all -- a single-model harness -- yields the implementer's own id,
186
- // and that is recorded as NOT INDEPENDENT rather than asked, because there is
187
- // nothing for a human to pick.
188
- function resolveReviewer(session, answers, implementation, customAllowed) {
189
- const { default: teamDefault, candidates } = session.selections.review
190
- if (Object.hasOwn(answers, 'review')) {
191
- const named = singleAnswer(answers, 'review')
192
- const option = selectedOption({ options: candidates }, named, { allowCustom: customAllowed })
193
- return Object.freeze({ option, reason: 'human-named' })
194
- }
195
- const distinct = candidates.find((candidate) => candidate.id !== implementation.id)
196
- if (!distinct) {
197
- return Object.freeze({ option: candidates[0], reason: 'no-distinct-candidate' })
198
- }
199
- const reason = teamDefault && distinct.id === teamDefault.id ? 'team-default' : 'ladder'
200
- return Object.freeze({ option: distinct, reason })
201
- }
202
-
203
- export function modelDiversity(implementation, review) {
204
- if (implementation.id === review.id) {
205
- return Object.freeze({
206
- status: 'not-independent',
207
- independent: false,
208
- reason: 'identical-model-ids',
209
- })
210
- }
211
- if (nonEmptyString(implementation.family)
212
- && nonEmptyString(review.family)
213
- && implementation.family === review.family) {
214
- return Object.freeze({
215
- status: 'reduced-diversity',
216
- independent: true,
217
- reason: 'same-family-different-model-ids',
218
- })
219
- }
220
- return Object.freeze({ status: 'independent', independent: true, reason: null })
221
- }
222
-
223
- export function recordPreflightResponses(session, nativeResponses, options = {}) {
224
- if (session?.interaction?.kind !== 'native') {
225
- invalid('native responses require a native question plan')
226
- }
227
- const answers = normalizeQuestionResponses(session.interaction, nativeResponses)
228
- return recordPreflightAnswers(session, answers, options)
229
- }
230
-
231
- export function recordPreflightAnswers(session, answerValue, { allowHumanNamed = false } = {}) {
232
- if (!isRecord(session) || !isRecord(session.selections)) invalid('question session is malformed')
233
- const answers = defineQuestionAnswers(answerValue)
234
- if (Object.keys(answers).length === 0) {
235
- return Object.freeze({
236
- cancelled: true,
237
- manifestPatch: null,
238
- diversity: null,
239
- reviewFill: null,
240
- autonomyFill: null,
241
- })
242
- }
243
-
244
- const expectedIds = session.questions.map((item) => item.id)
245
- // `review` and `autonomy` are never planned questions; a human who names either
246
- // outright is honoured as an override rather than bounced.
247
- const acceptedIds = [...expectedIds, 'review', 'autonomy']
248
- if (expectedIds.some((id) => !Object.hasOwn(answers, id))
249
- || Object.keys(answers).some((id) => !acceptedIds.includes(id))) {
250
- invalid('answers must complete exactly the planned question batch')
251
- }
252
-
253
- const customAllowed = allowHumanNamed || session.interaction.kind === 'fallback'
254
- const implementationId = singleAnswer(answers, 'implementation')
255
- let implementation = selectedOption(session.selections.implementation, implementationId, {
256
- allowCustom: customAllowed,
257
- })
258
- implementation = session.modelMetadata[implementation.id] ?? implementation
259
-
260
- const reviewFill = resolveReviewer(session, answers, implementation, customAllowed)
261
- const review = session.modelMetadata[reviewFill.option.id] ?? reviewFill.option
262
-
263
- const targetId = singleAnswer(answers, 'target_branch')
264
- selectedOption(session.selections.target, targetId, { allowCustom: customAllowed })
265
-
266
- let autonomy
267
- let autonomyFill
268
- if (Object.hasOwn(answers, 'autonomy')) {
269
- autonomy = singleAnswer(answers, 'autonomy')
270
- selectedOption(session.selections.autonomy, autonomy)
271
- autonomyFill = Object.freeze({ id: autonomy, reason: 'human-named' })
272
- } else {
273
- autonomy = session.defaulted?.autonomy || session.selections.autonomy.recommended
274
- selectedOption(session.selections.autonomy, autonomy)
275
- autonomyFill = Object.freeze({ id: autonomy, reason: 'default' })
276
- }
277
-
278
- const models = {}
279
- modelPoint(models, 'implementation', implementation)
280
- modelPoint(models, 'review', review)
281
- const diversity = modelDiversity(implementation, review)
282
- return Object.freeze({
283
- cancelled: false,
284
- manifestPatch: Object.freeze({
285
- currentTurnCapabilities: session.capabilities,
286
- models: Object.freeze(models),
287
- targetBranch: targetId,
288
- autonomy,
289
- }),
290
- diversity,
291
- reviewFill: Object.freeze({ id: review.id, reason: reviewFill.reason }),
292
- autonomyFill,
293
- })
294
- }
295
-
296
- const CLI_USAGE = `preflight-questions <plan|record|record-native>
297
-
298
- Reads one JSON object from stdin and writes JSON to stdout.
299
- plan pre-flight input -> neutral questions + planned native/fallback interaction
300
- record { preflight, answers, allowHumanNamed? } -> complete manifest patch
301
- record-native { preflight, responses, allowHumanNamed? } -> normalized complete manifest patch
302
-
303
- Exit 0 = result emitted; 1 = invalid input/contract; 2 = usage error.`
304
-
305
- export function runCli(argv, {
306
- input = () => readFileSync(0, 'utf8'),
307
- output = (text) => process.stdout.write(text),
308
- error = (text) => process.stderr.write(text),
309
- } = {}) {
310
- const command = argv[0]
311
- if (command === '--help' || command === '-h' || command === 'help') {
312
- output(`${CLI_USAGE}\n`)
313
- return 0
314
- }
315
- if (!['plan', 'record', 'record-native'].includes(command) || argv.length !== 1) {
316
- error(`${CLI_USAGE}\n`)
317
- return 2
318
- }
319
-
320
- try {
321
- const value = JSON.parse(input())
322
- const result = command === 'plan'
323
- ? planPreflightQuestions(value)
324
- : command === 'record'
325
- ? recordPreflightAnswers(
326
- planPreflightQuestions(value.preflight),
327
- value.answers,
328
- { allowHumanNamed: value.allowHumanNamed === true },
329
- )
330
- : recordPreflightResponses(
331
- planPreflightQuestions(value.preflight),
332
- value.responses,
333
- { allowHumanNamed: value.allowHumanNamed === true },
334
- )
335
- output(`${JSON.stringify(result, null, 2)}\n`)
336
- return 0
337
- } catch (cause) {
338
- error(`preflight-questions: ${cause.message}\n`)
339
- return 1
340
- }
341
- }
342
-
343
- if (isMainModule(import.meta.url)) {
344
- process.exitCode = runCli(process.argv.slice(2))
345
- }