@1aboveio/skills 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (633) hide show
  1. package/README.md +30 -2
  2. package/bin/cli.mjs +14 -0
  3. package/bin/select-core.mjs +172 -0
  4. package/package.json +146 -4
  5. package/skills/app-dev/airflow/LICENSE +3 -0
  6. package/skills/app-dev/airflow/SKILL.md +199 -0
  7. package/skills/app-dev/airflow/release-check.mjs +93 -0
  8. package/skills/app-dev/android-foundation/LICENSE +3 -0
  9. package/skills/app-dev/android-foundation/SKILL.md +192 -0
  10. package/skills/app-dev/android-foundation/assets/android-ci-job.yml +217 -0
  11. package/skills/app-dev/android-foundation/references/ci.md +87 -0
  12. package/skills/app-dev/android-foundation/references/gotchas.md +221 -0
  13. package/skills/app-dev/android-foundation/references/setup.md +164 -0
  14. package/skills/app-dev/android-foundation/release-check.mjs +93 -0
  15. package/skills/app-dev/android-foundation/scripts/device-run.sh +176 -0
  16. package/skills/app-dev/android-foundation/scripts/device-run.test.mjs +172 -0
  17. package/skills/app-dev/app-debug/LICENSE +3 -0
  18. package/skills/app-dev/app-debug/SKILL.md +110 -0
  19. package/skills/app-dev/app-debug/references/common-errors.md +128 -0
  20. package/skills/app-dev/app-debug/release-check.mjs +93 -0
  21. package/skills/app-dev/better-auth/LICENSE +3 -0
  22. package/skills/app-dev/better-auth/SKILL.md +598 -0
  23. package/skills/app-dev/better-auth/references/feishu-api.md +270 -0
  24. package/skills/app-dev/better-auth/release-check.mjs +93 -0
  25. package/skills/app-dev/data-catalog/LICENSE +3 -0
  26. package/skills/app-dev/data-catalog/SKILL.md +204 -0
  27. package/skills/app-dev/data-catalog/agents/openai.yaml +3 -0
  28. package/skills/app-dev/data-catalog/references/data-catalog-conventions.md +75 -0
  29. package/skills/app-dev/data-catalog/references/field-definitions.md +116 -0
  30. package/skills/app-dev/data-catalog/references/format.md +121 -0
  31. package/skills/app-dev/data-catalog/release-check.mjs +93 -0
  32. package/skills/app-dev/data-catalog/scripts/data-catalog.test.mjs +36 -0
  33. package/skills/app-dev/data-catalog/scripts/data_catalog.py +1392 -0
  34. package/skills/app-dev/data-catalog/scripts/persist-conventions-core.mjs +117 -0
  35. package/skills/app-dev/data-catalog/scripts/persist-conventions.mjs +17 -0
  36. package/skills/app-dev/data-catalog/scripts/test_data_catalog.py +571 -0
  37. package/skills/app-dev/ios-foundation/LICENSE +3 -0
  38. package/skills/app-dev/ios-foundation/SKILL.md +184 -0
  39. package/skills/app-dev/ios-foundation/references/setup.md +243 -0
  40. package/skills/app-dev/ios-foundation/release-check.mjs +93 -0
  41. package/skills/app-dev/monorepo/LICENSE +3 -0
  42. package/skills/app-dev/monorepo/SKILL.md +462 -0
  43. package/skills/app-dev/monorepo/release-check.mjs +93 -0
  44. package/skills/app-dev/nextjs-fullstack/LICENSE +3 -0
  45. package/skills/app-dev/nextjs-fullstack/SKILL.md +211 -0
  46. package/skills/app-dev/nextjs-fullstack/conventions.md +318 -0
  47. package/skills/app-dev/nextjs-fullstack/frontend-conventions.md +61 -0
  48. package/skills/app-dev/nextjs-fullstack/nextjs16.md +287 -0
  49. package/skills/app-dev/nextjs-fullstack/release-check.mjs +93 -0
  50. package/skills/app-dev/nextjs-fullstack/server-actions.md +409 -0
  51. package/skills/app-dev/prisma-setup/LICENSE +3 -0
  52. package/skills/app-dev/prisma-setup/SKILL.md +181 -0
  53. package/skills/app-dev/prisma-setup/nextjs.md +258 -0
  54. package/skills/app-dev/prisma-setup/release-check.mjs +93 -0
  55. package/skills/app-dev/prisma-setup/turborepo.md +301 -0
  56. package/skills/app-dev/pyspark/LICENSE +3 -0
  57. package/skills/app-dev/pyspark/SKILL.md +127 -0
  58. package/skills/app-dev/pyspark/assets/templates/etl.py +748 -0
  59. package/skills/app-dev/pyspark/assets/templates/utils/__init__.py +1 -0
  60. package/skills/app-dev/pyspark/assets/templates/utils/hudi_metadata.py +14 -0
  61. package/skills/app-dev/pyspark/references/diagnosis-and-profiling.md +169 -0
  62. package/skills/app-dev/pyspark/references/etl-contract.md +129 -0
  63. package/skills/app-dev/pyspark/references/production-validation.md +131 -0
  64. package/skills/app-dev/pyspark/references/reconciliation.md +38 -0
  65. package/skills/app-dev/pyspark/references/transformation-design.md +190 -0
  66. package/skills/app-dev/pyspark/references/velocity-feature-calculation.md +193 -0
  67. package/skills/app-dev/pyspark/release-check.mjs +93 -0
  68. package/skills/app-dev/pyspark/scripts/spark_eventlog_summary.py +223 -0
  69. package/skills/app-dev/python-backend/LICENSE +3 -0
  70. package/skills/app-dev/python-backend/SKILL.md +325 -0
  71. package/skills/app-dev/python-backend/assets/uv-install.sh +48 -0
  72. package/skills/app-dev/python-backend/references/uv-installs.md +83 -0
  73. package/skills/app-dev/python-backend/release-check.mjs +93 -0
  74. package/skills/app-dev/shadcn/LICENSE +3 -0
  75. package/skills/app-dev/shadcn/SKILL.md +120 -0
  76. package/skills/app-dev/shadcn/assets/shadcn-small.png +0 -0
  77. package/skills/app-dev/shadcn/assets/shadcn.png +0 -0
  78. package/skills/app-dev/shadcn/cli.md +411 -0
  79. package/skills/app-dev/shadcn/customization.md +224 -0
  80. package/skills/app-dev/shadcn/mcp.md +101 -0
  81. package/skills/app-dev/shadcn/release-check.mjs +93 -0
  82. package/skills/app-dev/shadcn/rules/base-vs-radix.md +323 -0
  83. package/skills/app-dev/shadcn/rules/component-selection.md +67 -0
  84. package/skills/app-dev/shadcn/rules/composition.md +195 -0
  85. package/skills/app-dev/shadcn/rules/data-table.md +201 -0
  86. package/skills/app-dev/shadcn/rules/forms.md +255 -0
  87. package/skills/app-dev/shadcn/rules/icons.md +103 -0
  88. package/skills/app-dev/shadcn/rules/styling.md +167 -0
  89. package/skills/app-dev/zod-v4/LICENSE +3 -0
  90. package/skills/app-dev/zod-v4/SKILL.md +286 -0
  91. package/skills/app-dev/zod-v4/release-check.mjs +93 -0
  92. package/skills/cicd/cloud-build/LICENSE +3 -0
  93. package/skills/cicd/cloud-build/SKILL.md +707 -0
  94. package/skills/cicd/cloud-build/release-check.mjs +93 -0
  95. package/skills/cicd/cloud-debug/LICENSE +3 -0
  96. package/skills/cicd/cloud-debug/SKILL.md +315 -0
  97. package/skills/cicd/cloud-debug/references/build-failures.md +238 -0
  98. package/skills/cicd/cloud-debug/references/deploy-failures.md +376 -0
  99. package/skills/cicd/cloud-debug/references/pipeline-failures.md +378 -0
  100. package/skills/cicd/cloud-debug/release-check.mjs +93 -0
  101. package/skills/cicd/cloud-deploy/LICENSE +3 -0
  102. package/skills/cicd/cloud-deploy/SKILL.md +230 -0
  103. package/skills/cicd/cloud-deploy/references/config-templates.md +257 -0
  104. package/skills/cicd/cloud-deploy/release-check.mjs +93 -0
  105. package/skills/cicd/docker/LICENSE +3 -0
  106. package/skills/cicd/docker/SKILL.md +151 -0
  107. package/skills/cicd/docker/release-check.mjs +93 -0
  108. package/skills/cicd/github-actions/LICENSE +3 -0
  109. package/skills/cicd/github-actions/SKILL.md +111 -0
  110. package/skills/cicd/github-actions/references/audit-profile-optimize.md +150 -0
  111. package/skills/cicd/github-actions/references/ci-case-studies.md +141 -0
  112. package/skills/cicd/github-actions/references/conditional-ci.md +214 -0
  113. package/skills/cicd/github-actions/references/debugging.md +13 -0
  114. package/skills/cicd/github-actions/references/pipeline.md +87 -0
  115. package/skills/cicd/github-actions/references/post-deploy-and-publishing.md +33 -0
  116. package/skills/cicd/github-actions/references/runners.md +253 -0
  117. package/skills/cicd/github-actions/references/security.md +29 -0
  118. package/skills/cicd/github-actions/references/speed-and-audit.md +115 -0
  119. package/skills/cicd/github-actions/references/two-pass-reading.md +92 -0
  120. package/skills/cicd/github-actions/release-check.mjs +93 -0
  121. package/skills/cicd/github-actions/scripts/ci-run-audit-core.mjs +612 -0
  122. package/skills/cicd/github-actions/scripts/ci-run-audit.mjs +4 -0
  123. package/skills/cicd/github-actions/scripts/ci-run-audit.test.mjs +637 -0
  124. package/skills/cicd/github-flow/LICENSE +3 -0
  125. package/skills/cicd/github-flow/SKILL.md +123 -0
  126. package/skills/cicd/github-flow/references/ci-conventions.md +14 -0
  127. package/skills/cicd/github-flow/release-check.mjs +93 -0
  128. package/skills/cicd/github-flow/scripts/flow-core.mjs +105 -0
  129. package/skills/cicd/github-flow/scripts/flow.mjs +81 -0
  130. package/skills/cicd/github-flow/scripts/flow.test.mjs +114 -0
  131. package/skills/cicd/github-flow/scripts/persist-conventions-core.mjs +117 -0
  132. package/skills/cicd/github-flow/scripts/persist-conventions.mjs +49 -0
  133. package/skills/cicd/github-flow/scripts/persist-conventions.test.mjs +108 -0
  134. package/skills/cicd/google-cloud/LICENSE +3 -0
  135. package/skills/cicd/google-cloud/SKILL.md +119 -0
  136. package/skills/cicd/google-cloud/references/gcs.md +469 -0
  137. package/skills/cicd/google-cloud/references/iam.md +451 -0
  138. package/skills/cicd/google-cloud/references/project.md +349 -0
  139. package/skills/cicd/google-cloud/references/secrets.md +336 -0
  140. package/skills/cicd/google-cloud/references/vpc.md +312 -0
  141. package/skills/cicd/google-cloud/release-check.mjs +93 -0
  142. package/skills/cicd/google-cloud/scripts/create-sa.sh +36 -0
  143. package/skills/cicd/google-cloud/scripts/gcp-config.sh +31 -0
  144. package/skills/cicd/google-cloud/scripts/grant-iap.sh +41 -0
  145. package/skills/cicd/google-cloud/scripts/setup-secrets.sh +48 -0
  146. package/skills/cicd/mergify/LICENSE +3 -0
  147. package/skills/cicd/mergify/SKILL.md +102 -0
  148. package/skills/cicd/mergify/assets/templates/mergify.yml +215 -0
  149. package/skills/cicd/mergify/assets/templates/ruleset.json +46 -0
  150. package/skills/cicd/mergify/references/branch-protection.md +282 -0
  151. package/skills/cicd/mergify/references/configuration.md +274 -0
  152. package/skills/cicd/mergify/references/diagnosis.md +109 -0
  153. package/skills/cicd/mergify/references/stacks.md +84 -0
  154. package/skills/cicd/mergify/references/traps.md +119 -0
  155. package/skills/cicd/mergify/references/watch-contract.md +274 -0
  156. package/skills/cicd/mergify/release-check.mjs +93 -0
  157. package/skills/cicd/mergify/scripts/audit-core.mjs +208 -0
  158. package/skills/cicd/mergify/scripts/audit.mjs +4 -0
  159. package/skills/cicd/mergify/scripts/audit.test.mjs +201 -0
  160. package/skills/cicd/mergify/scripts/entrypoints.test.mjs +106 -0
  161. package/skills/cicd/mergify/scripts/pr-620-mergify-comments.fixture.json +30 -0
  162. package/skills/cicd/mergify/scripts/stack-push-core.mjs +258 -0
  163. package/skills/cicd/mergify/scripts/stack-push.mjs +4 -0
  164. package/skills/cicd/mergify/scripts/stack-push.test.mjs +233 -0
  165. package/skills/cicd/mergify/scripts/watch-pr-delivery-core.mjs +1065 -0
  166. package/skills/cicd/mergify/scripts/watch-pr-delivery.mjs +4 -0
  167. package/skills/cicd/mergify/scripts/watch-pr-delivery.test.mjs +1826 -0
  168. package/skills/cicd/podman/LICENSE +3 -0
  169. package/skills/cicd/podman/SKILL.md +71 -0
  170. package/skills/cicd/podman/agents/openai.yaml +4 -0
  171. package/skills/cicd/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
  172. package/skills/cicd/podman/assets/templates/podman-service-override.conf +3 -0
  173. package/skills/cicd/podman/references/compose-compatibility.md +70 -0
  174. package/skills/cicd/podman/references/networking-and-ports.md +74 -0
  175. package/skills/cicd/podman/references/rootless-services-and-sockets.md +156 -0
  176. package/skills/cicd/podman/references/troubleshooting.md +98 -0
  177. package/skills/cicd/podman/release-check.mjs +93 -0
  178. package/skills/content/article-review/LICENSE +3 -0
  179. package/skills/content/article-review/SKILL.md +66 -0
  180. package/skills/content/article-review/references/report-format.md +68 -0
  181. package/skills/content/article-review/references/template-guide.md +79 -0
  182. package/skills/content/article-review/references/template-wechat-payments.md +125 -0
  183. package/skills/content/article-review/release-check.mjs +93 -0
  184. package/skills/content/article-to-image/LICENSE +3 -0
  185. package/skills/content/article-to-image/SKILL.md +91 -0
  186. package/skills/content/article-to-image/references/formats.md +53 -0
  187. package/skills/content/article-to-image/release-check.mjs +93 -0
  188. package/skills/content/flowchart-svg/LICENSE +3 -0
  189. package/skills/content/flowchart-svg/SKILL.md +43 -0
  190. package/skills/content/flowchart-svg/release-check.mjs +93 -0
  191. package/skills/content/flowchart-svg/scripts/export_png.sh +8 -0
  192. package/skills/content/image-gen/LICENSE +3 -0
  193. package/skills/content/image-gen/SKILL.md +192 -0
  194. package/skills/content/image-gen/release-check.mjs +93 -0
  195. package/skills/content/image-gen/scripts/credentials.mjs +217 -0
  196. package/skills/content/image-gen/scripts/credentials.test.mjs +212 -0
  197. package/skills/content/image-gen/scripts/generate.mjs +240 -0
  198. package/skills/content/image-gen/scripts/options.mjs +293 -0
  199. package/skills/content/image-gen/scripts/options.test.mjs +245 -0
  200. package/skills/content/mermaid/LICENSE +3 -0
  201. package/skills/content/mermaid/SKILL.md +635 -0
  202. package/skills/content/mermaid/release-check.mjs +93 -0
  203. package/skills/content/wechat-article-writer/LICENSE +3 -0
  204. package/skills/content/wechat-article-writer/SKILL.md +92 -0
  205. package/skills/content/wechat-article-writer/references/style-selector.md +133 -0
  206. package/skills/content/wechat-article-writer/references/writing-rules.md +152 -0
  207. package/skills/content/wechat-article-writer/release-check.mjs +93 -0
  208. package/skills/content/wechat-article-writer/templates/wechat-comparison.md +52 -0
  209. package/skills/content/wechat-article-writer/templates/wechat-howto.md +51 -0
  210. package/skills/content/wechat-article-writer/templates/wechat-insight.md +50 -0
  211. package/skills/content/wechat-article-writer/templates/wechat-pitfall.md +52 -0
  212. package/skills/content/wechat-publisher/LICENSE +3 -0
  213. package/skills/content/wechat-publisher/SKILL.md +171 -0
  214. package/skills/content/wechat-publisher/references/api.md +105 -0
  215. package/skills/content/wechat-publisher/references/layout-rules.md +57 -0
  216. package/skills/content/wechat-publisher/references/wechat-safe-template.html +86 -0
  217. package/skills/content/wechat-publisher/release-check.mjs +93 -0
  218. package/skills/content/wechat-publisher/scripts/md_to_wechat_html.py +194 -0
  219. package/skills/content/wechat-publisher/scripts/publish.py +239 -0
  220. package/skills/content/wechat-search/LICENSE +3 -0
  221. package/skills/content/wechat-search/SKILL.md +211 -0
  222. package/skills/content/wechat-search/release-check.mjs +93 -0
  223. package/skills/content/wechat-search/scripts/start-chrome.sh +83 -0
  224. package/skills/content/xai-search/LICENSE +3 -0
  225. package/skills/content/xai-search/SKILL.md +79 -0
  226. package/skills/content/xai-search/release-check.mjs +93 -0
  227. package/skills/content/xai-search/scripts/xai_search.sh +187 -0
  228. package/skills/content/xai-search/tests/smoke_test.sh +36 -0
  229. package/skills/core/distill-writing/LICENSE +3 -0
  230. package/skills/core/distill-writing/SKILL.md +74 -0
  231. package/skills/core/distill-writing/references/extraction.md +95 -0
  232. package/skills/core/distill-writing/references/updating.md +46 -0
  233. package/skills/core/distill-writing/release-check.mjs +93 -0
  234. package/skills/core/doc-to-md/LICENSE +3 -0
  235. package/skills/core/doc-to-md/SKILL.md +78 -0
  236. package/skills/core/doc-to-md/release-check.mjs +93 -0
  237. package/skills/core/doc-to-md/scripts/convert.py +157 -0
  238. package/skills/core/editorial-review/LICENSE +3 -0
  239. package/skills/core/editorial-review/SKILL.md +79 -0
  240. package/skills/core/editorial-review/references/checklist.md +94 -0
  241. package/skills/core/editorial-review/release-check.mjs +93 -0
  242. package/skills/core/house-style/LICENSE +3 -0
  243. package/skills/core/house-style/SKILL.md +33 -0
  244. package/skills/core/house-style/references/defaults.md +66 -0
  245. package/skills/core/house-style/references/rules.md +267 -0
  246. package/skills/core/house-style/references/sources.md +27 -0
  247. package/skills/core/house-style/references/style-en.md +131 -0
  248. package/skills/core/house-style/references/style-zh.md +141 -0
  249. package/skills/core/house-style/references/terminology-zh.md +223 -0
  250. package/skills/core/house-style/release-check.mjs +93 -0
  251. package/skills/core/house-style/templates/brd.md +103 -0
  252. package/skills/core/house-style/templates/commercial-proposal.md +93 -0
  253. package/skills/core/house-style/templates/compliance-policy.md +109 -0
  254. package/skills/core/house-style/templates/gap-analysis.md +105 -0
  255. package/skills/core/house-style/templates/general.md +63 -0
  256. package/skills/core/house-style/templates/integration-guide.md +98 -0
  257. package/skills/core/house-style/templates/prd.md +81 -0
  258. package/skills/core/house-style/templates/risk-operations-procedure.md +94 -0
  259. package/skills/core/house-style/templates/technical-spec.md +96 -0
  260. package/skills/core/polish-cn/LICENSE +3 -0
  261. package/skills/core/polish-cn/SKILL.md +102 -0
  262. package/skills/core/polish-cn/references/brief.md +93 -0
  263. package/skills/core/polish-cn/references/models.md +76 -0
  264. package/skills/core/polish-cn/release-check.mjs +93 -0
  265. package/skills/core/polish-cn/scripts/polish-cn.test.mjs +244 -0
  266. package/skills/core/polish-cn/scripts/polish_blocks.py +489 -0
  267. package/skills/core/reg-parser/LICENSE +3 -0
  268. package/skills/core/reg-parser/SKILL.md +212 -0
  269. package/skills/core/reg-parser/references/checklist-schema.md +223 -0
  270. package/skills/core/reg-parser/references/checklists/hk-amlo-checklist.json +1306 -0
  271. package/skills/core/reg-parser/references/checklists/hk-amlo-checklist.md +469 -0
  272. package/skills/core/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.json +634 -0
  273. package/skills/core/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.md +233 -0
  274. package/skills/core/reg-parser/references/checklists/hk-mso-guideline-checklist.json +2194 -0
  275. package/skills/core/reg-parser/references/checklists/hk-mso-guideline-checklist.md +771 -0
  276. package/skills/core/reg-parser/references/checklists/kyc-aml-checklist.md +258 -0
  277. package/skills/core/reg-parser/references/checklists/visa-vars-checklist.md +1058 -0
  278. package/skills/core/reg-parser/references/mandates/hk-amlo-cap615.md +389 -0
  279. package/skills/core/reg-parser/references/mandates/visa-vars.md +205 -0
  280. package/skills/core/reg-parser/release-check.mjs +93 -0
  281. package/skills/core/reg-parser/scripts/compare_checklist.py +230 -0
  282. package/skills/core/reg-parser/scripts/dump_checklist.py +361 -0
  283. package/skills/core/reg-parser/scripts/preprocess-mandate.sh +187 -0
  284. package/skills/core/reg-parser/scripts/reg-parser.test.mjs +165 -0
  285. package/skills/core/reg-parser/scripts/test_quarantine.sh +105 -0
  286. package/skills/core/reg-parser/scripts/validate_checklist.py +563 -0
  287. package/skills/core/reg-parser/scripts/validate_mandate.py +273 -0
  288. package/skills/core/terminology/LICENSE +3 -0
  289. package/skills/core/terminology/SKILL.md +62 -0
  290. package/skills/core/terminology/references/format.md +50 -0
  291. package/skills/core/terminology/references/init.md +32 -0
  292. package/skills/core/terminology/release-check.mjs +93 -0
  293. package/skills/core/write-doc/LICENSE +3 -0
  294. package/skills/core/write-doc/SKILL.md +141 -0
  295. package/skills/core/write-doc/references/bilingual.md +60 -0
  296. package/skills/core/write-doc/release-check.mjs +93 -0
  297. package/skills/engineering/better-review/LICENSE +3 -0
  298. package/skills/engineering/better-review/SKILL.md +249 -0
  299. package/skills/engineering/better-review/agents/openai.yaml +9 -0
  300. package/skills/engineering/better-review/references/domain-hazards.md +53 -0
  301. package/skills/engineering/better-review/references/passes.md +147 -0
  302. package/skills/engineering/better-review/references/result.md +151 -0
  303. package/skills/engineering/better-review/release-check.mjs +93 -0
  304. package/skills/engineering/better-review/scripts/pr-context.mjs +212 -0
  305. package/skills/engineering/better-review/scripts/pr-context.test.mjs +168 -0
  306. package/skills/engineering/better-review/scripts/rereview-scope.mjs +503 -0
  307. package/skills/engineering/better-review/scripts/rereview-scope.test.mjs +587 -0
  308. package/skills/engineering/better-review/scripts/scan-diff.mjs +365 -0
  309. package/skills/engineering/better-review/scripts/scan-diff.test.mjs +414 -0
  310. package/skills/engineering/better-review/scripts/vendor-sync.test.mjs +96 -0
  311. package/skills/engineering/e2e-test/LICENSE +3 -0
  312. package/skills/engineering/e2e-test/SKILL.md +98 -0
  313. package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +24 -0
  314. package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
  315. package/skills/engineering/e2e-test/references/authoring/playwright-config.md +73 -0
  316. package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +144 -0
  317. package/skills/engineering/e2e-test/references/ci-integration.md +25 -0
  318. package/skills/engineering/e2e-test/references/ci-playwright-container.md +290 -0
  319. package/skills/engineering/e2e-test/references/presentation-sweep.md +104 -0
  320. package/skills/engineering/e2e-test/references/reviewing.md +41 -0
  321. package/skills/engineering/e2e-test/references/route-manifest.md +51 -0
  322. package/skills/engineering/e2e-test/release-check.mjs +93 -0
  323. package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
  324. package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
  325. package/skills/engineering/e2e-test/scripts/presentation-checks.test.mjs +106 -0
  326. package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
  327. package/skills/engineering/e2e-test/scripts/presentation-perceivability.test.mjs +117 -0
  328. package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
  329. package/skills/engineering/e2e-test/scripts/presentation-reachability.test.mjs +69 -0
  330. package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
  331. package/skills/engineering/e2e-test/scripts/presentation-render-health.test.mjs +98 -0
  332. package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +147 -0
  333. package/skills/engineering/e2e-test/scripts/presentation-sweep.test.mjs +71 -0
  334. package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
  335. package/skills/engineering/e2e-test/scripts/presentation-temporal.test.mjs +59 -0
  336. package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +82 -0
  337. package/skills/engineering/e2e-test/scripts/project-route-manifest.test.mjs +76 -0
  338. package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
  339. package/skills/engineering/engineering-runtime/LICENSE +3 -0
  340. package/skills/engineering/engineering-runtime/SKILL.md +11 -0
  341. package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
  342. package/skills/engineering/engineering-runtime/coherence/workflow.json +597 -0
  343. package/skills/engineering/engineering-runtime/engineering-runtime.test.mjs +68 -0
  344. package/skills/engineering/engineering-runtime/release-check.mjs +93 -0
  345. package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
  346. package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
  347. package/skills/engineering/engineering-runtime/scripts/invocation-policy.mjs +187 -0
  348. package/skills/engineering/engineering-runtime/scripts/invocation-policy.test.mjs +95 -0
  349. package/skills/engineering/engineering-runtime/scripts/main-module.mjs +79 -0
  350. package/skills/engineering/engineering-runtime/scripts/main-module.test.mjs +288 -0
  351. package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
  352. package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
  353. package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
  354. package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
  355. package/skills/engineering/engineering-runtime/scripts/required-check-plan.test.mjs +96 -0
  356. package/skills/engineering/engineering-runtime/scripts/review-completion.mjs +56 -0
  357. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +595 -0
  358. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +189 -0
  359. package/skills/engineering/engineering-runtime/scripts/yaml-mapping.mjs +18 -0
  360. package/skills/engineering/ensure-coverage/LICENSE +3 -0
  361. package/skills/engineering/ensure-coverage/SKILL.md +129 -0
  362. package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +92 -0
  363. package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +85 -0
  364. package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
  365. package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
  366. package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
  367. package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +19 -0
  368. package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
  369. package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +57 -0
  370. package/skills/engineering/ensure-coverage/references/depth/test-smells.md +39 -0
  371. package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +44 -0
  372. package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +110 -0
  373. package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +35 -0
  374. package/skills/engineering/ensure-coverage/references/presentation/axis.md +64 -0
  375. package/skills/engineering/ensure-coverage/references/process/audit-mode.md +27 -0
  376. package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
  377. package/skills/engineering/ensure-coverage/references/process/test-strategy.md +56 -0
  378. package/skills/engineering/ensure-coverage/release-check.mjs +93 -0
  379. package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +67 -0
  380. package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +140 -0
  381. package/skills/engineering/ensure-coverage/scripts/README.md +99 -0
  382. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +182 -0
  383. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.test.mjs +96 -0
  384. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +105 -0
  385. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.test.mjs +47 -0
  386. package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +137 -0
  387. package/skills/engineering/ensure-coverage/scripts/ci-audit.test.mjs +86 -0
  388. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +674 -0
  389. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.test.mjs +447 -0
  390. package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
  391. package/skills/engineering/ensure-coverage/scripts/design-parity.test.mjs +552 -0
  392. package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +282 -0
  393. package/skills/engineering/ensure-coverage/scripts/lint-tests.test.mjs +289 -0
  394. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
  395. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.test.mjs +119 -0
  396. package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
  397. package/skills/engineering/golden-path/LICENSE +3 -0
  398. package/skills/engineering/golden-path/SKILL.md +230 -0
  399. package/skills/engineering/golden-path/agents/openai.yaml +3 -0
  400. package/skills/engineering/golden-path/assets/golden-paths.example.json +57 -0
  401. package/skills/engineering/golden-path/references/contract.md +239 -0
  402. package/skills/engineering/golden-path/references/migration.md +111 -0
  403. package/skills/engineering/golden-path/release-check.mjs +93 -0
  404. package/skills/engineering/golden-path/scripts/golden-path-core.mjs +1779 -0
  405. package/skills/engineering/golden-path/scripts/golden-path.mjs +6 -0
  406. package/skills/engineering/golden-path/scripts/golden-path.test.mjs +1457 -0
  407. package/skills/engineering/harness-runtime/LICENSE +3 -0
  408. package/skills/engineering/harness-runtime/SKILL.md +19 -0
  409. package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
  410. package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
  411. package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
  412. package/skills/engineering/harness-runtime/contracts.md +15 -0
  413. package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
  414. package/skills/engineering/harness-runtime/discover-models.test.mjs +363 -0
  415. package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
  416. package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
  417. package/skills/engineering/harness-runtime/harness-runtime.test.mjs +967 -0
  418. package/skills/engineering/harness-runtime/index.mjs +767 -0
  419. package/skills/engineering/harness-runtime/model-catalog-seed.test.mjs +829 -0
  420. package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
  421. package/skills/engineering/harness-runtime/model-catalog.test.mjs +366 -0
  422. package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
  423. package/skills/engineering/harness-runtime/references/model-catalog-seed.json +408 -0
  424. package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
  425. package/skills/engineering/harness-runtime/release-check.mjs +93 -0
  426. package/skills/engineering/resolve-issues/LICENSE +3 -0
  427. package/skills/engineering/resolve-issues/SKILL.md +250 -0
  428. package/skills/engineering/resolve-issues/agents/openai.yaml +9 -0
  429. package/skills/engineering/resolve-issues/plugin-hooks.json +17 -0
  430. package/skills/engineering/resolve-issues/references/canary.md +28 -0
  431. package/skills/engineering/resolve-issues/references/ci.md +105 -0
  432. package/skills/engineering/resolve-issues/references/done.md +25 -0
  433. package/skills/engineering/resolve-issues/references/dropbox.md +90 -0
  434. package/skills/engineering/resolve-issues/references/expire.md +318 -0
  435. package/skills/engineering/resolve-issues/references/exploration.md +202 -0
  436. package/skills/engineering/resolve-issues/references/implementation.md +303 -0
  437. package/skills/engineering/resolve-issues/references/preflight.md +445 -0
  438. package/skills/engineering/resolve-issues/references/review.md +228 -0
  439. package/skills/engineering/resolve-issues/references/shared-modules.md +44 -0
  440. package/skills/engineering/resolve-issues/references/task-plan.md +264 -0
  441. package/skills/engineering/resolve-issues/release-check.mjs +93 -0
  442. package/skills/engineering/resolve-issues/scripts/cleanup-runs.mjs +364 -0
  443. package/skills/engineering/resolve-issues/scripts/cleanup-runs.test.mjs +280 -0
  444. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
  445. package/skills/engineering/resolve-issues/scripts/dropbox.mjs +473 -0
  446. package/skills/engineering/resolve-issues/scripts/dropbox.test.mjs +346 -0
  447. package/skills/engineering/resolve-issues/scripts/findings-reuse.mjs +98 -0
  448. package/skills/engineering/resolve-issues/scripts/findings-reuse.test.mjs +88 -0
  449. package/skills/engineering/resolve-issues/scripts/github-reviews.mjs +384 -0
  450. package/skills/engineering/resolve-issues/scripts/github-reviews.test.mjs +264 -0
  451. package/skills/engineering/resolve-issues/scripts/install-hooks.mjs +135 -0
  452. package/skills/engineering/resolve-issues/scripts/install-hooks.test.mjs +79 -0
  453. package/skills/engineering/resolve-issues/scripts/issue-tree.mjs +162 -0
  454. package/skills/engineering/resolve-issues/scripts/issue-tree.test.mjs +107 -0
  455. package/skills/engineering/resolve-issues/scripts/manual-invocation.test.mjs +14 -0
  456. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
  457. package/skills/engineering/resolve-issues/scripts/next-actions-capacity.test.mjs +149 -0
  458. package/skills/engineering/resolve-issues/scripts/next-actions.mjs +856 -0
  459. package/skills/engineering/resolve-issues/scripts/next-actions.test.mjs +915 -0
  460. package/skills/engineering/resolve-issues/scripts/plan-sync.mjs +269 -0
  461. package/skills/engineering/resolve-issues/scripts/plan-sync.test.mjs +156 -0
  462. package/skills/engineering/resolve-issues/scripts/preflight-models.mjs +736 -0
  463. package/skills/engineering/resolve-issues/scripts/preflight-models.test.mjs +448 -0
  464. package/skills/engineering/resolve-issues/scripts/ready-check.mjs +185 -0
  465. package/skills/engineering/resolve-issues/scripts/ready-check.test.mjs +217 -0
  466. package/skills/engineering/resolve-issues/scripts/rehydrate.mjs +98 -0
  467. package/skills/engineering/resolve-issues/scripts/rehydrate.test.mjs +91 -0
  468. package/skills/engineering/resolve-issues/scripts/review-verdict.mjs +509 -0
  469. package/skills/engineering/resolve-issues/scripts/review-verdict.test.mjs +1060 -0
  470. package/skills/engineering/resolve-issues/scripts/size-check.mjs +492 -0
  471. package/skills/engineering/resolve-issues/scripts/size-check.test.mjs +458 -0
  472. package/skills/engineering/resolve-release/LICENSE +3 -0
  473. package/skills/engineering/resolve-release/SKILL.md +215 -0
  474. package/skills/engineering/resolve-release/agents/openai.yaml +8 -0
  475. package/skills/engineering/resolve-release/flows/cloud-run-canary.md +13 -0
  476. package/skills/engineering/resolve-release/flows/cloud-run.md +7 -0
  477. package/skills/engineering/resolve-release/flows/root-tag-npm.md +13 -0
  478. package/skills/engineering/resolve-release/flows/workspace-npm.md +22 -0
  479. package/skills/engineering/resolve-release/references/canary.md +51 -0
  480. package/skills/engineering/resolve-release/references/candidate.md +41 -0
  481. package/skills/engineering/resolve-release/references/cut.md +131 -0
  482. package/skills/engineering/resolve-release/references/dark-launch.md +66 -0
  483. package/skills/engineering/resolve-release/references/flows.md +150 -0
  484. package/skills/engineering/resolve-release/references/preflight.md +154 -0
  485. package/skills/engineering/resolve-release/references/prepared-metadata.md +260 -0
  486. package/skills/engineering/resolve-release/references/promotion.md +82 -0
  487. package/skills/engineering/resolve-release/references/publish.md +232 -0
  488. package/skills/engineering/resolve-release/references/workspace-npm.md +103 -0
  489. package/skills/engineering/resolve-release/release-check.mjs +93 -0
  490. package/skills/engineering/resolve-release/scripts/apply.mjs +212 -0
  491. package/skills/engineering/resolve-release/scripts/apply.test.mjs +99 -0
  492. package/skills/engineering/resolve-release/scripts/dark-flags.mjs +134 -0
  493. package/skills/engineering/resolve-release/scripts/dark-flags.test.mjs +100 -0
  494. package/skills/engineering/resolve-release/scripts/flow.mjs +500 -0
  495. package/skills/engineering/resolve-release/scripts/flow.test.mjs +340 -0
  496. package/skills/engineering/resolve-release/scripts/green-head.mjs +231 -0
  497. package/skills/engineering/resolve-release/scripts/green-head.test.mjs +101 -0
  498. package/skills/engineering/resolve-release/scripts/npm-version-absence.mjs +138 -0
  499. package/skills/engineering/resolve-release/scripts/npm-version-absence.test.mjs +426 -0
  500. package/skills/engineering/resolve-release/scripts/plan-npm.test.mjs +659 -0
  501. package/skills/engineering/resolve-release/scripts/plan-toml-boundary.test.mjs +317 -0
  502. package/skills/engineering/resolve-release/scripts/plan-uv.test.mjs +291 -0
  503. package/skills/engineering/resolve-release/scripts/plan.mjs +806 -0
  504. package/skills/engineering/resolve-release/scripts/plan.test.mjs +428 -0
  505. package/skills/engineering/rush-issues/LICENSE +3 -0
  506. package/skills/engineering/rush-issues/SKILL.md +58 -0
  507. package/skills/engineering/rush-issues/agents/openai.yaml +8 -0
  508. package/skills/engineering/rush-issues/rehydrate.mjs +10 -0
  509. package/skills/engineering/rush-issues/release-check.mjs +93 -0
  510. package/skills/engineering/rush-release/LICENSE +3 -0
  511. package/skills/engineering/rush-release/SKILL.md +35 -0
  512. package/skills/engineering/rush-release/agents/openai.yaml +8 -0
  513. package/skills/engineering/rush-release/release-check.mjs +93 -0
  514. package/skills/engineering/test-quality/LICENSE +3 -0
  515. package/skills/engineering/test-quality/SKILL.md +79 -0
  516. package/skills/engineering/test-quality/references/audit.md +80 -0
  517. package/skills/engineering/test-quality/references/lint.md +24 -0
  518. package/skills/engineering/test-quality/references/principles.md +143 -0
  519. package/skills/engineering/test-quality/references/testing-conventions.md +9 -0
  520. package/skills/engineering/test-quality/release-check.mjs +93 -0
  521. package/skills/engineering/test-quality/scripts/lint-tests.mjs +574 -0
  522. package/skills/engineering/test-quality/scripts/lint-tests.test.mjs +591 -0
  523. package/skills/engineering/test-quality/scripts/mock-policy-config.mjs +176 -0
  524. package/skills/engineering/test-quality/scripts/mock-policy-config.test.mjs +119 -0
  525. package/skills/engineering/test-quality/scripts/persist-conventions-core.mjs +117 -0
  526. package/skills/engineering/test-quality/scripts/persist-conventions.mjs +17 -0
  527. package/skills/engineering/test-quality/scripts/persist-conventions.test.mjs +104 -0
  528. package/skills/risk-compliance/compliance-audit/LICENSE +3 -0
  529. package/skills/risk-compliance/compliance-audit/SKILL.md +439 -0
  530. package/skills/risk-compliance/compliance-audit/references/findings-schema.md +293 -0
  531. package/skills/risk-compliance/compliance-audit/references/normalization-rules.md +45 -0
  532. package/skills/risk-compliance/compliance-audit/references/vars-checklist.md +1068 -0
  533. package/skills/risk-compliance/compliance-audit/references/vars-findings-schema.md +398 -0
  534. package/skills/risk-compliance/compliance-audit/release-check.mjs +93 -0
  535. package/skills/risk-compliance/compliance-audit/scripts/compliance-audit.test.mjs +14 -0
  536. package/skills/risk-compliance/compliance-audit/scripts/export_tracker_xlsx.py +221 -0
  537. package/skills/risk-compliance/compliance-audit/scripts/reconcile_tracker.py +458 -0
  538. package/skills/risk-compliance/compliance-audit/scripts/test_export_tracker_xlsx.py +97 -0
  539. package/skills/risk-compliance/compliance-audit/scripts/test_validate_tracker.py +157 -0
  540. package/skills/risk-compliance/compliance-audit/scripts/validate_tracker.py +829 -0
  541. package/skills/risk-compliance/contract-compare/LICENSE +3 -0
  542. package/skills/risk-compliance/contract-compare/SKILL.md +199 -0
  543. package/skills/risk-compliance/contract-compare/references/comparison-dimensions.md +209 -0
  544. package/skills/risk-compliance/contract-compare/release-check.mjs +93 -0
  545. package/skills/risk-compliance/contract-review/LICENSE +3 -0
  546. package/skills/risk-compliance/contract-review/SKILL.md +240 -0
  547. package/skills/risk-compliance/contract-review/references/review-criteria.md +223 -0
  548. package/skills/risk-compliance/contract-review/release-check.mjs +93 -0
  549. package/skills/risk-compliance/doc-authenticity/LICENSE +3 -0
  550. package/skills/risk-compliance/doc-authenticity/SKILL.md +160 -0
  551. package/skills/risk-compliance/doc-authenticity/agents/openai.yaml +8 -0
  552. package/skills/risk-compliance/doc-authenticity/manual-invocation.test.mjs +12 -0
  553. package/skills/risk-compliance/doc-authenticity/references/agreement.md +66 -0
  554. package/skills/risk-compliance/doc-authenticity/references/bank-statement.md +150 -0
  555. package/skills/risk-compliance/doc-authenticity/references/forensic-signals.md +157 -0
  556. package/skills/risk-compliance/doc-authenticity/references/image-signals.md +114 -0
  557. package/skills/risk-compliance/doc-authenticity/references/invoice.md +66 -0
  558. package/skills/risk-compliance/doc-authenticity/references/issuer-profiles.md +86 -0
  559. package/skills/risk-compliance/doc-authenticity/references/verdict-and-report.md +95 -0
  560. package/skills/risk-compliance/doc-authenticity/references/verdict.schema.json +81 -0
  561. package/skills/risk-compliance/doc-authenticity/release-check.mjs +93 -0
  562. package/skills/risk-compliance/doc-authenticity/scripts/image_forensics.py +294 -0
  563. package/skills/risk-compliance/doc-authenticity/scripts/pdf_forensics.py +401 -0
  564. package/skills/risk-compliance/doc-authenticity/scripts/validate_codes.py +224 -0
  565. package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.py +308 -0
  566. package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.test.mjs +212 -0
  567. package/skills/risk-compliance/fraud-analysis/LICENSE +3 -0
  568. package/skills/risk-compliance/fraud-analysis/SKILL.md +114 -0
  569. package/skills/risk-compliance/fraud-analysis/references/archetypes/authorized-payment-scam.md +41 -0
  570. package/skills/risk-compliance/fraud-analysis/references/archetypes/first-party-fraud.md +44 -0
  571. package/skills/risk-compliance/fraud-analysis/references/archetypes/third-party-fraud.md +27 -0
  572. package/skills/risk-compliance/fraud-analysis/references/contexts/bank-transfer.md +24 -0
  573. package/skills/risk-compliance/fraud-analysis/references/contexts/card-payment.md +30 -0
  574. package/skills/risk-compliance/fraud-analysis/references/contexts/payment-collection.md +20 -0
  575. package/skills/risk-compliance/fraud-analysis/references/contexts/payout.md +20 -0
  576. package/skills/risk-compliance/fraud-analysis/references/feature-engineering.md +158 -0
  577. package/skills/risk-compliance/fraud-analysis/references/mechanisms/account-takeover.md +36 -0
  578. package/skills/risk-compliance/fraud-analysis/references/report-rationale.md +45 -0
  579. package/skills/risk-compliance/fraud-analysis/references/report-template.md +190 -0
  580. package/skills/risk-compliance/fraud-analysis/references/review-checklist.md +175 -0
  581. package/skills/risk-compliance/fraud-analysis/references/taxonomy.md +79 -0
  582. package/skills/risk-compliance/fraud-analysis/references/terminology.md +108 -0
  583. package/skills/risk-compliance/fraud-analysis/references/workflow.md +175 -0
  584. package/skills/risk-compliance/fraud-analysis/release-check.mjs +93 -0
  585. package/skills/risk-compliance/payment-analysis/LICENSE +3 -0
  586. package/skills/risk-compliance/payment-analysis/SKILL.md +180 -0
  587. package/skills/risk-compliance/payment-analysis/references/auth-rate-actions.md +30 -0
  588. package/skills/risk-compliance/payment-analysis/references/chargebacks.md +208 -0
  589. package/skills/risk-compliance/payment-analysis/references/chinese-polish.md +51 -0
  590. package/skills/risk-compliance/payment-analysis/references/event-layers.md +127 -0
  591. package/skills/risk-compliance/payment-analysis/references/fx.md +59 -0
  592. package/skills/risk-compliance/payment-analysis/references/journey.md +79 -0
  593. package/skills/risk-compliance/payment-analysis/references/metrics.md +67 -0
  594. package/skills/risk-compliance/payment-analysis/references/report-template.md +119 -0
  595. package/skills/risk-compliance/payment-analysis/references/terminology.md +95 -0
  596. package/skills/risk-compliance/payment-analysis/references/visualization.md +56 -0
  597. package/skills/risk-compliance/payment-analysis/release-check.mjs +93 -0
  598. package/skills/risk-compliance/report-writing/LICENSE +3 -0
  599. package/skills/risk-compliance/report-writing/SKILL.md +220 -0
  600. package/skills/risk-compliance/report-writing/references/audit-report-template.md +121 -0
  601. package/skills/risk-compliance/report-writing/references/external-assessment-template.md +167 -0
  602. package/skills/risk-compliance/report-writing/references/management-report-template.md +145 -0
  603. package/skills/risk-compliance/report-writing/references/vars-report-template.md +224 -0
  604. package/skills/risk-compliance/report-writing/release-check.mjs +93 -0
  605. package/skills/risk-compliance/similar-domain/LICENSE +3 -0
  606. package/skills/risk-compliance/similar-domain/SKILL.md +203 -0
  607. package/skills/risk-compliance/similar-domain/references/entities.md +67 -0
  608. package/skills/risk-compliance/similar-domain/references/fingerprints.md +134 -0
  609. package/skills/risk-compliance/similar-domain/references/pivots.md +82 -0
  610. package/skills/risk-compliance/similar-domain/references/report-template.md +93 -0
  611. package/skills/risk-compliance/similar-domain/references/scoring.md +130 -0
  612. package/skills/risk-compliance/similar-domain/references/terminology.md +41 -0
  613. package/skills/risk-compliance/similar-domain/references/workflow.md +85 -0
  614. package/skills/risk-compliance/similar-domain/release-check.mjs +93 -0
  615. package/skills/risk-compliance/tld-detection/LICENSE +3 -0
  616. package/skills/risk-compliance/tld-detection/SKILL.md +245 -0
  617. package/skills/risk-compliance/tld-detection/agents/openai.yaml +9 -0
  618. package/skills/risk-compliance/tld-detection/references/chinese-polish.md +55 -0
  619. package/skills/risk-compliance/tld-detection/references/clean.md +51 -0
  620. package/skills/risk-compliance/tld-detection/references/clustering.md +235 -0
  621. package/skills/risk-compliance/tld-detection/references/decision.md +189 -0
  622. package/skills/risk-compliance/tld-detection/references/fx-conversion.md +232 -0
  623. package/skills/risk-compliance/tld-detection/references/report-template.md +272 -0
  624. package/skills/risk-compliance/tld-detection/references/streams.md +141 -0
  625. package/skills/risk-compliance/tld-detection/references/terminology.md +95 -0
  626. package/skills/risk-compliance/tld-detection/references/workflow.md +95 -0
  627. package/skills/risk-compliance/tld-detection/release-check.mjs +93 -0
  628. package/skills/risk-compliance/tld-detection/scripts/detect_ladders.py +390 -0
  629. package/skills/risk-compliance/tld-detection/scripts/detect_ladders.test.mjs +14 -0
  630. package/skills/risk-compliance/tld-detection/scripts/detect_streams.py +650 -0
  631. package/skills/risk-compliance/tld-detection/scripts/detect_streams.test.mjs +14 -0
  632. package/skills/risk-compliance/tld-detection/tests/test_detect_ladders.py +134 -0
  633. package/skills/risk-compliance/tld-detection/tests/test_detect_streams.py +520 -0
@@ -0,0 +1,736 @@
1
+ #!/usr/bin/env node
2
+ // resolve-issues fast path for model selection.
3
+ //
4
+ // One command: discover → tier (shared harness-runtime catalog) → recommend
5
+ // implementer + fill explorer + fill diagnoser + fill reviewer ≠ implementer. Prints a ready
6
+ // ask payload the orchestrator hands straight to the harness's native question
7
+ // tool (see references/shared-modules.md) without reading longer workflow
8
+ // doctrine before model selection.
9
+ //
10
+ // Maintenance (sync / bank) is deferred until AFTER the human answers — never
11
+ // block the picker on catalog writes.
12
+ //
13
+ // Usage:
14
+ // node preflight-models.mjs --harness <pi|codex|claude-code> [--risk routine|high]
15
+ // [--available id,id,...] [--human-named id,id,...] [--implementer id[@effort]] [--ask-only]
16
+ //
17
+ // --implementer pins the implementer: it is the only option, and the run never
18
+ // falls back to a recommended model when the pinned one is not available.
19
+ //
20
+ // Exit: 0 whenever it ran (a result with `ok: false` and a `code` of `no-slot-eligible` or
21
+ // `pinned-implementer-unavailable` is the answer, not a failure) · 2 usage or crash
22
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
23
+ import {
24
+ detectHarness,
25
+ discover,
26
+ } from '../../harness-runtime/discover-models.mjs'
27
+ import {
28
+ tierProposals,
29
+ pointsFromTiers,
30
+ isSlotEligible,
31
+ DEFAULT_EFFORT,
32
+ readCatalog,
33
+ pathForHarness,
34
+ readSeed,
35
+ defaultSeedPath,
36
+ findSeedEntry,
37
+ } from '../../harness-runtime/model-catalog.mjs'
38
+
39
+ export const RISK = Object.freeze(['routine', 'high'])
40
+
41
+ // Preferred fills when discovery actually yielded the id (resolve-issues defaults).
42
+ // Reviewer: the frontier band's home role is review (model-catalog.md). Since
43
+ // 2026-09-23 the primary is gpt-6-astra@medium and the fallback (when the
44
+ // implementer IS Astra — a human pick; resolve-issues never recommends frontier for
45
+ // implementation) is gpt-5.6-sol@medium. Both are synthesized below-catalog
46
+ // policy points (the catalog banks `high` per rule 6); the model ids are the
47
+ // two frontier points by the official DeepSWE v1.1 board at high (73.2%±3.4,
48
+ // 69.4%±1.4) and the *effort* comes from the local blinded review benchmark
49
+ // (docs/research/2026-09-23-reviewer-benchmark-astra-vs-sol.md): Astra-medium
50
+ // matched Sol-medium's useful-finding yield in under half the wall-clock time
51
+ // and beat Astra-high on yield; Sol-high found three more at 3.5x the time.
52
+ // Independence is by model id, never by effort.
53
+ export const TEAM_REVIEWER_POLICY = Object.freeze({
54
+ pi: {
55
+ primary: { id: 'openai/gpt-6-astra', family: 'openai', effort: 'medium', tier: 'frontier' },
56
+ fallback: { id: 'openai/gpt-5.6-sol', family: 'openai', effort: 'medium', tier: 'frontier' },
57
+ },
58
+ codex: {
59
+ primary: { id: 'gpt-6-astra', family: 'openai', effort: 'medium', tier: 'frontier' },
60
+ fallback: { id: 'gpt-5.6-sol', family: 'openai', effort: 'medium', tier: 'frontier' },
61
+ },
62
+ 'claude-code': {
63
+ primary: { id: 'gpt-6-astra', family: 'openai', effort: 'medium', tier: 'frontier' },
64
+ fallback: { id: 'gpt-5.6-sol', family: 'openai', effort: 'medium', tier: 'frontier' },
65
+ },
66
+ })
67
+
68
+ // Implementer ladders: ordered per risk and harness, first discovered point
69
+ // wins. Order set by the team on 2026-09-23 over the DeepSWE v1.1 evidence in
70
+ // the catalog notes (official board where a model has a run, vendor launch
71
+ // figure otherwise). A frontier point reaches the recommendation only through
72
+ // these ladders; the reviewer slot then switches to a distinct model id (an
73
+ // Astra implementation is reviewed by gpt-5.6-sol@medium; every other rung by
74
+ // gpt-6-astra@medium, a different family for the Grok/MiMo rungs).
75
+ //
76
+ // High risk (reordered 2026-09-30 by the team: gpt-6.1-sol@high first, 75.2
77
+ // vendor at about a fifth of Astra's cost per task, then the rest unchanged):
78
+ // gpt-6.1-sol@high → gpt-6-astra@high (73.2%±3.4 official, top of the board) →
79
+ // gpt-5.6-sol@high (69.4%±1.4 official; slowest point in the local review
80
+ // benchmark) → grok-4.7@high (71.0 vendor, $2/$6, not on the official board;
81
+ // kept behind the two official frontier points until Datacurve runs it), over
82
+ // gpt-5.5@high (64.4%±3.1, retiring from Codex 2026-10-14).
83
+ //
84
+ // Routine (reordered 2026-09-28 by the team: gpt-6-sol@high first, then
85
+ // luna, grok-4.6, mimo; the evidence notes below are unchanged): gpt-6-luna@high (balanced-coder by human classification — OpenAI
86
+ // published no high point, 66.6 vendor is at max; $0.10/$0.50. Pi smoke on one
87
+ // small tool task: high 30s vs max 62s vs Terra@high 29s at ~1/20 the cost, so
88
+ // high keeps Terra's latency at near-zero spend; max was too slow) →
89
+ // grok-4.6@high (deep-reasoner; 65.2%±1.5 official, $2/$6) → mimo-v2.6-pro@high
90
+ // (frontier; 71.9 vendor, $0.44/$0.87; MiMo's API has thinking on/off only, so
91
+ // `high` labels that single point — behind grok-4.6 until an official run and
92
+ // local trajectory evidence exist) → gpt-6-sol@high (deep-reasoner; 65.3 vendor;
93
+ // replaced gpt-5.6-terra@high on 2026-09-27, ADR 0009). On 2026-09-30 every
94
+ // gpt-6-sol rung became gpt-6.1-sol (75.2 vendor at high, frontier; Codex now
95
+ // lists gpt-6-sol as previous generation), in the same positions. Only the OpenAI rungs
96
+ // exist on Codex (it lists no Grok or MiMo ids). A rung discovery does not
97
+ // yield is skipped; past the ladder the tier order applies.
98
+ //
99
+ // Escalation fix workers (test-first, last-try) always take the high-risk ladder
100
+ // (gpt-6.1-sol@high first since 2026-09-30), whatever the run's risk (team
101
+ // decision 2026-09-28).
102
+ export const TEAM_IMPLEMENTER_PREFERENCE = Object.freeze({
103
+ routine: {
104
+ pi: [
105
+ { id: 'openai/gpt-6.1-sol', family: 'openai', effort: 'high', tier: 'frontier' },
106
+ { id: 'openai/gpt-6-luna', family: 'openai', effort: 'high', tier: 'balanced-coder' },
107
+ { id: 'xai/grok-4.6', family: 'xai', effort: 'high', tier: 'deep-reasoner' },
108
+ { id: 'xiaomi/mimo-v2.6-pro', family: 'xiaomi', effort: 'high', tier: 'frontier' },
109
+ ],
110
+ codex: [
111
+ { id: 'gpt-6.1-sol', family: 'openai', effort: 'high', tier: 'frontier' },
112
+ { id: 'gpt-6-luna', family: 'openai', effort: 'high', tier: 'balanced-coder' },
113
+ ],
114
+ 'claude-code': [
115
+ { id: 'gpt-6.1-sol', family: 'openai', effort: 'high', tier: 'frontier' },
116
+ { id: 'gpt-6-luna', family: 'openai', effort: 'high', tier: 'balanced-coder' },
117
+ { id: 'grok-4.6', family: 'xai', effort: 'high', tier: 'deep-reasoner' },
118
+ { id: 'mimo-v2.6-pro', family: 'xiaomi', effort: 'high', tier: 'frontier' },
119
+ ],
120
+ },
121
+ high: {
122
+ pi: [
123
+ { id: 'openai/gpt-6.1-sol', family: 'openai', effort: 'high', tier: 'frontier' },
124
+ { id: 'openai/gpt-6-astra', family: 'openai', effort: 'high', tier: 'frontier' },
125
+ { id: 'openai/gpt-5.6-sol', family: 'openai', effort: 'high', tier: 'frontier' },
126
+ { id: 'xai/grok-4.7', family: 'xai', effort: 'high', tier: 'frontier' },
127
+ ],
128
+ codex: [
129
+ { id: 'gpt-6.1-sol', family: 'openai', effort: 'high', tier: 'frontier' },
130
+ { id: 'gpt-6-astra', family: 'openai', effort: 'high', tier: 'frontier' },
131
+ { id: 'gpt-5.6-sol', family: 'openai', effort: 'high', tier: 'frontier' },
132
+ ],
133
+ 'claude-code': [
134
+ { id: 'gpt-6.1-sol', family: 'openai', effort: 'high', tier: 'frontier' },
135
+ { id: 'gpt-6-astra', family: 'openai', effort: 'high', tier: 'frontier' },
136
+ { id: 'gpt-5.6-sol', family: 'openai', effort: 'high', tier: 'frontier' },
137
+ { id: 'grok-4.7', family: 'xai', effort: 'high', tier: 'frontier' },
138
+ ],
139
+ },
140
+ })
141
+
142
+ // Explorer: gpt-6.1-sol@medium first (ADR 0009 named gpt-6-sol; replaced
143
+ // 2026-09-30; 73 vendor at medium), then the routine implementer ladder without
144
+ // its gpt-6.1-sol@high rung. The medium point is below the catalog's banked `high`, so it is a
145
+ // policy point synthesized from a discovered id, like the reviewer's; when
146
+ // discovery does not yield gpt-6.1-sol, the fill falls through to the routine
147
+ // ladder.
148
+ export const TEAM_EXPLORER_POLICY = Object.freeze({
149
+ pi: { id: 'openai/gpt-6.1-sol', family: 'openai', effort: 'medium', tier: 'frontier' },
150
+ codex: { id: 'gpt-6.1-sol', family: 'openai', effort: 'medium', tier: 'frontier' },
151
+ 'claude-code': { id: 'gpt-6.1-sol', family: 'openai', effort: 'medium', tier: 'frontier' },
152
+ })
153
+
154
+ export const TEAM_EXPLORER_DEFAULT = Object.freeze(
155
+ Object.fromEntries(
156
+ Object.entries(TEAM_IMPLEMENTER_PREFERENCE.routine).map(([harness, ladder]) => [
157
+ harness,
158
+ [TEAM_EXPLORER_POLICY[harness], ...ladder.filter((rung) => rung.id !== TEAM_EXPLORER_POLICY[harness].id)],
159
+ ]),
160
+ ),
161
+ )
162
+
163
+ const TIER_RANK = Object.freeze({
164
+ frontier: 0,
165
+ 'deep-reasoner': 1,
166
+ 'balanced-coder': 2,
167
+ })
168
+
169
+ function usage() {
170
+ return `preflight-models — discover + recommend implementer, fill explorer + reviewer (resolve-issues fast path)
171
+
172
+ Usage:
173
+ node preflight-models.mjs --harness <pi|codex|claude-code> [--risk routine|high]
174
+ [--available <id,id,...>] [--human-named <id,id,...>] [--implementer <id[@effort]>] [--ask-only]
175
+
176
+ Output JSON:
177
+ { harness, risk, discovery, models, implementer, explorer, diagnoser, reviewer, ask, deferred }
178
+
179
+ --ask-only prints only the ask block (for piping into a question UI).
180
+ --implementer pins the implementer (the only option); exit 4 when it is not an
181
+ available slot-eligible point. Never substitute another model.
182
+ Deferred: run catalog sync/bank AFTER the human answers — never before the ask.`
183
+ }
184
+
185
+ function parseList(value) {
186
+ return String(value || '')
187
+ .split(',')
188
+ .map((s) => s.trim())
189
+ .filter(Boolean)
190
+ }
191
+
192
+ export function parseArgs(argv) {
193
+ const out = {
194
+ harness: null,
195
+ risk: 'routine',
196
+ available: [],
197
+ humanNamed: [],
198
+ implementer: null,
199
+ askOnly: false,
200
+ help: false,
201
+ }
202
+ for (let i = 0; i < argv.length; i++) {
203
+ const a = argv[i]
204
+ if (a === '--help' || a === '-h' || a === 'help') out.help = true
205
+ else if (a === '--ask-only') out.askOnly = true
206
+ else if (a === '--harness') out.harness = argv[++i]
207
+ else if (a === '--risk') out.risk = argv[++i]
208
+ else if (a === '--available') out.available = parseList(argv[++i])
209
+ else if (a === '--human-named') out.humanNamed = parseList(argv[++i])
210
+ else if (a === '--implementer') out.implementer = argv[++i]
211
+ else if (a.startsWith('--harness=')) out.harness = a.slice('--harness='.length)
212
+ else if (a.startsWith('--risk=')) out.risk = a.slice('--risk='.length)
213
+ else if (a.startsWith('--available=')) out.available = parseList(a.slice('--available='.length))
214
+ else if (a.startsWith('--human-named=')) out.humanNamed = parseList(a.slice('--human-named='.length))
215
+ else if (a.startsWith('--implementer=')) out.implementer = a.slice('--implementer='.length)
216
+ else throw new Error(`unknown argument: ${a}`)
217
+ }
218
+ if (out.implementer !== null && (typeof out.implementer !== 'string' || !out.implementer.trim())) throw new Error('--implementer needs a model id')
219
+ return out
220
+ }
221
+
222
+ /**
223
+ * The point a pin names: `id@effort` matches that operating point exactly; a
224
+ * bare `id` takes the floor effort when banked, else the id's first point.
225
+ */
226
+ export function findPinnedPoint(points, pin) {
227
+ const text = String(pin || '').trim()
228
+ if (!text) return null
229
+ const at = text.lastIndexOf('@')
230
+ const id = at > 0 ? text.slice(0, at) : text
231
+ const effort = at > 0 ? text.slice(at + 1) : null
232
+ const same = points.filter((p) => p.id === id)
233
+ if (effort) return same.find((p) => p.effort === effort) || null
234
+ return same.find((p) => p.effort === DEFAULT_EFFORT) || same[0] || null
235
+ }
236
+
237
+ function familyOf(id, hinted) {
238
+ if (hinted) return hinted
239
+ if (id.includes('/')) return id.slice(0, id.indexOf('/'))
240
+ return 'unknown'
241
+ }
242
+
243
+ /** Prefer banked catalog family, then seed, then id prefix. */
244
+ export function resolveFamily(harness, id, { catalog = null, seed = null } = {}) {
245
+ const banked = (catalog?.models || []).find((m) => m && m.id === id)
246
+ if (banked?.family) return banked.family
247
+ const seeded = seed ? findSeedEntry(seed, harness, id) : null
248
+ if (seeded?.family) return seeded.family
249
+ return familyOf(id)
250
+ }
251
+
252
+ function pointKey(id, effort) {
253
+ return `${id}@${effort || DEFAULT_EFFORT}`
254
+ }
255
+
256
+ /** Expand tierProposals().models into slot-eligible operating points. */
257
+ export function slotPoints(tieredModels, { harness, catalog = null, seed = null } = {}) {
258
+ const points = []
259
+ for (const model of tieredModels) {
260
+ const entries = Object.keys(model.tiers || {}).length
261
+ ? pointsFromTiers(model.tiers)
262
+ : []
263
+ const family = resolveFamily(harness, model.id, { catalog, seed })
264
+ for (const p of entries) {
265
+ if (!isSlotEligible(p.tier)) continue
266
+ points.push({
267
+ id: model.id,
268
+ effort: p.effort || DEFAULT_EFFORT,
269
+ tier: p.tier,
270
+ family,
271
+ source: model.source,
272
+ citation: model.citation || null,
273
+ key: pointKey(model.id, p.effort || DEFAULT_EFFORT),
274
+ })
275
+ }
276
+ }
277
+ return points
278
+ }
279
+
280
+ function preferRisk(tier, risk) {
281
+ if (risk === 'high') {
282
+ if (tier === 'deep-reasoner') return 0
283
+ if (tier === 'balanced-coder') return 1
284
+ return 2 // frontier is never recommended by tier alone (only via the team ladder)
285
+ }
286
+ // routine
287
+ if (tier === 'balanced-coder') return 0
288
+ if (tier === 'deep-reasoner') return 1
289
+ return 2
290
+ }
291
+
292
+ /**
293
+ * Recommend implementer. The team ladder for the risk/harness is consulted
294
+ * first (high risk: gpt-6.1-sol, gpt-6-astra, gpt-5.6-sol, then grok-4.7, all
295
+ * @high — the ladder is the only way a frontier point becomes the
296
+ * recommendation; routine: gpt-6.1-sol@high, gpt-6-luna@high, grok-4.6@high,
297
+ * then mimo-v2.6-pro@high). Without a ladder hit
298
+ * the tier order applies: routine → balanced-coder; high → deep-reasoner;
299
+ * frontier is listed but never recommended by tier alone.
300
+ */
301
+ export function recommendImplementer(points, risk = 'routine', harness = null) {
302
+ if (!points.length) return null
303
+ const ladder = harness ? TEAM_IMPLEMENTER_PREFERENCE[risk]?.[harness] || [] : []
304
+ for (const preferred of ladder) {
305
+ const preferredPoint = findPreferredPoint(points, preferred)
306
+ if (preferredPoint && preferredPoint.tier === preferred.tier) return preferredPoint
307
+ }
308
+ const sorted = [...points].sort((a, b) => {
309
+ const ra = preferRisk(a.tier, risk)
310
+ const rb = preferRisk(b.tier, risk)
311
+ if (ra !== rb) return ra - rb
312
+ // Prefer the floor effort when tied; then stable id.
313
+ if (a.effort !== b.effort) {
314
+ if (a.effort === DEFAULT_EFFORT) return -1
315
+ if (b.effort === DEFAULT_EFFORT) return 1
316
+ return a.effort < b.effort ? -1 : 1
317
+ }
318
+ return a.id.localeCompare(b.id)
319
+ })
320
+ // First non-frontier if any; else first point (single-model / only-frontier harness)
321
+ return sorted.find((p) => p.tier !== 'frontier') || sorted[0]
322
+ }
323
+
324
+ /**
325
+ * Escalation fix-worker fill (test-first, last-try): the high-risk implementer ladder
326
+ * (gpt-6.1-sol, gpt-6-astra, gpt-5.6-sol, then grok-4.7, all @high), whatever
327
+ * the run's risk.
328
+ */
329
+ export function fillDiagnoser(points, harness) {
330
+ const fill = recommendImplementer(points, 'high', harness)
331
+ return { fill: fill || null, reason: fill ? 'high-risk-ladder' : 'none' }
332
+ }
333
+
334
+ function findPreferredPoint(points, preferred) {
335
+ if (!preferred) return null
336
+ return points.find(
337
+ (p) => p.id === preferred.id && (p.effort || DEFAULT_EFFORT) === (preferred.effort || DEFAULT_EFFORT),
338
+ ) || null
339
+ }
340
+
341
+ // Reviewer and explorer policy may deliberately use a below-catalog effort. The
342
+ // catalog continues to describe pushed capability points (high/xhigh/max);
343
+ // discovery of the model id is still required before this role-specific point
344
+ // exists.
345
+ function findPolicyPoint(points, preferred, { source, citation }) {
346
+ if (!preferred) return null
347
+ const discovered = points.find((p) => p.id === preferred.id)
348
+ if (!discovered) return null
349
+ if ((preferred.effort || DEFAULT_EFFORT) === DEFAULT_EFFORT) {
350
+ return findPreferredPoint(points, preferred)
351
+ }
352
+ return {
353
+ ...discovered,
354
+ effort: preferred.effort,
355
+ tier: preferred.tier,
356
+ source,
357
+ citation,
358
+ key: pointKey(preferred.id, preferred.effort),
359
+ }
360
+ }
361
+
362
+ const REVIEW_POLICY_SOURCE = Object.freeze({
363
+ source: 'team-review-policy',
364
+ citation: 'docs/research/2026-09-23-reviewer-benchmark-astra-vs-sol.md',
365
+ })
366
+ const EXPLORER_POLICY_SOURCE = Object.freeze({
367
+ source: 'team-explorer-policy',
368
+ citation: 'docs/adr/0009-orchestrator-coordinates-only.md',
369
+ })
370
+
371
+ function findReviewerPolicyPoint(points, preferred) {
372
+ return findPolicyPoint(points, preferred, REVIEW_POLICY_SOURCE)
373
+ }
374
+
375
+ /**
376
+ * Explorer fill: gpt-6.1-sol@medium when gpt-6.1-sol is discovered, then the
377
+ * routine implementer ladder without its gpt-6.1-sol@high rung (gpt-6-luna@high,
378
+ * grok-4.6@high, then mimo-v2.6-pro@high), first discovered rung wins;
379
+ * without a rung, the balanced-coder tier.
380
+ */
381
+ export function fillExplorer(points, harness) {
382
+ const ladder = TEAM_EXPLORER_DEFAULT[harness] || []
383
+ const policy = TEAM_EXPLORER_POLICY[harness]
384
+ let preferredPoint = null
385
+ for (const preferred of ladder) {
386
+ const candidate = preferred === policy
387
+ ? findPolicyPoint(points, preferred, EXPLORER_POLICY_SOURCE)
388
+ : findPreferredPoint(points, preferred)
389
+ if (candidate) {
390
+ preferredPoint = candidate
391
+ if (candidate.tier === preferred.tier) return { fill: candidate, reason: 'team-default' }
392
+ }
393
+ }
394
+ const balanced = points
395
+ .filter((p) => p.tier === 'balanced-coder')
396
+ .sort((a, b) => {
397
+ if (a.effort === DEFAULT_EFFORT && b.effort !== DEFAULT_EFFORT) return -1
398
+ if (b.effort === DEFAULT_EFFORT && a.effort !== DEFAULT_EFFORT) return 1
399
+ return a.id.localeCompare(b.id)
400
+ })
401
+ const fill = balanced[0] || null
402
+ return {
403
+ fill,
404
+ reason: fill ? (preferredPoint ? 'ladder' : 'balanced-coder') : 'none',
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Reviewer fill is implementer-aware and must differ by model id:
410
+ * Astra implementer -> gpt-5.6-sol@medium; otherwise -> gpt-6-astra@medium. If that
411
+ * policy point is unavailable, the existing diversity-first ladder applies.
412
+ */
413
+ export function rankReviewers(points, implementer, harness) {
414
+ const policy = TEAM_REVIEWER_POLICY[harness] || null
415
+ const deepPool = points.filter((p) => p.tier === 'deep-reasoner' || p.tier === 'frontier')
416
+ const pool = deepPool.length ? deepPool : points
417
+ const scored = pool.map((p) => {
418
+ const sameId = p.id === implementer.id
419
+ const sameFamily = p.family && implementer.family && p.family === implementer.family
420
+ let diversity
421
+ if (sameId) diversity = 5
422
+ else if (!sameFamily && p.tier === 'deep-reasoner') diversity = 0
423
+ else if (!sameFamily && p.tier === 'frontier') diversity = 1
424
+ else if (sameFamily && p.tier === 'deep-reasoner') diversity = 2
425
+ else if (!sameFamily) diversity = 3
426
+ else diversity = 4
427
+ return { ...p, diversity, tierRank: TIER_RANK[p.tier] ?? 9 }
428
+ })
429
+ scored.sort((a, b) => {
430
+ if (a.diversity !== b.diversity) return a.diversity - b.diversity
431
+ if (a.tierRank !== b.tierRank) return a.tierRank - b.tierRank
432
+ return a.id.localeCompare(b.id)
433
+ })
434
+
435
+ const primaryPoint = findReviewerPolicyPoint(points, policy?.primary)
436
+ const fallbackPoint = findReviewerPolicyPoint(points, policy?.fallback)
437
+
438
+ const ranking = []
439
+ const rankedIds = new Set()
440
+ for (const candidate of [primaryPoint, fallbackPoint, ...scored]) {
441
+ if (!candidate || rankedIds.has(candidate.id)) continue
442
+ rankedIds.add(candidate.id)
443
+ ranking.push(candidate)
444
+ }
445
+
446
+ const implementerIsPrimary = implementer.id === policy?.primary?.id
447
+ const policyFill = implementerIsPrimary ? fallbackPoint : primaryPoint
448
+ const fill = policyFill && policyFill.id !== implementer.id
449
+ ? policyFill
450
+ : scored.find((p) => p.id !== implementer.id) || scored[0]
451
+ let reason
452
+ if (fill?.id === primaryPoint?.id) reason = 'team-default'
453
+ else if (fill?.id === fallbackPoint?.id && implementerIsPrimary) reason = 'implementer-aware-default'
454
+ else reason = fill?.id === implementer.id ? 'no-distinct-candidate' : 'ladder'
455
+
456
+ return {
457
+ fill,
458
+ reason,
459
+ ranking,
460
+ teamDefaultApplied: reason === 'team-default' || reason === 'implementer-aware-default',
461
+ reducedDiversity: !!(fill && implementer && fill.family && fill.family === implementer.family && fill.id !== implementer.id),
462
+ notIndependent: !!(fill && implementer && fill.id === implementer.id),
463
+ }
464
+ }
465
+
466
+ function optionFromPoint(p, { recommended = false, role, ladderRung = 0 }) {
467
+ const why =
468
+ role === 'implementer'
469
+ ? ladderRung
470
+ ? `team ladder rung ${ladderRung}${recommended ? '' : ' — next discovered rung'}`
471
+ : p.tier === 'balanced-coder'
472
+ ? 'routine implementer band'
473
+ : p.tier === 'deep-reasoner'
474
+ ? 'deep-reasoner for risk-heavy work'
475
+ : p.tier === 'frontier'
476
+ ? recommended
477
+ ? 'frontier — team implementer ladder preference'
478
+ : 'frontier (alternate only — not the recommendation)'
479
+ : p.tier
480
+ : p.tier
481
+ return {
482
+ id: p.key, // operating point id for the picker; parse back to model+effort
483
+ modelId: p.id,
484
+ label: `${p.id} @ ${p.effort}`,
485
+ description: `${p.tier}${recommended ? ' · recommended' : ''} · ${why}`,
486
+ family: p.family,
487
+ effort: p.effort,
488
+ tier: p.tier,
489
+ }
490
+ }
491
+
492
+ /** Native question UIs typically allow 2–4 options. Keep the rest as `alternates`. */
493
+ export const ASK_OPTION_LIMIT = 4
494
+
495
+ function slotFillPayload(slot) {
496
+ if (!slot?.fill) return null
497
+ return {
498
+ id: slot.fill.key,
499
+ modelId: slot.fill.id,
500
+ effort: slot.fill.effort,
501
+ family: slot.fill.family,
502
+ tier: slot.fill.tier,
503
+ reason: slot.reason,
504
+ reducedDiversity: slot.reducedDiversity || false,
505
+ notIndependent: slot.notIndependent || false,
506
+ }
507
+ }
508
+
509
+ /**
510
+ * The ask's options are the team ladder for this risk/harness, in ladder order,
511
+ * limited to the rungs discovery actually yielded, then the remaining points by
512
+ * risk-matched band and id. The ladder is the policy; before 2026-09-23 the
513
+ * options were band-then-id, which pushed the ladder rungs (gpt-5.6-sol,
514
+ * grok-4.7, gpt-6-sol) into `alternates` behind whichever deep-reasoners sorted
515
+ * first by id, and native pickers never show alternates. One frontier point is
516
+ * kept visible only when none of the primary options is frontier already.
517
+ */
518
+ export function buildAsk(implementer, points, reviewer, { risk = 'routine', explorer = null, diagnoser = null, harness = null, pinned = false } = {}) {
519
+ if (pinned) {
520
+ return {
521
+ header: 'Implementer',
522
+ question: 'The implementer is pinned for this run; it is the only option. (Explorer + reviewer are filled automatically; reviewer ≠ implementer.)',
523
+ recommended: implementer.key,
524
+ pinned: true,
525
+ options: [{ ...optionFromPoint(implementer, { recommended: true, role: 'implementer' }), description: `${implementer.tier} · pinned` }],
526
+ alternates: [],
527
+ explorerFill: slotFillPayload(explorer),
528
+ diagnoserFill: slotFillPayload(diagnoser),
529
+ reviewerFill: slotFillPayload(reviewer),
530
+ }
531
+ }
532
+ const seen = new Set()
533
+ const ordered = []
534
+ const ladderRungByKey = new Map()
535
+ const push = (p) => {
536
+ if (!p || seen.has(p.key)) return
537
+ seen.add(p.key)
538
+ ordered.push(p)
539
+ }
540
+ push(implementer)
541
+ const ladder = harness ? TEAM_IMPLEMENTER_PREFERENCE[risk]?.[harness] || [] : []
542
+ ladder.forEach((preferred, index) => {
543
+ const point = findPreferredPoint(points, preferred)
544
+ if (point && point.tier === preferred.tier) {
545
+ ladderRungByKey.set(point.key, index + 1)
546
+ push(point)
547
+ }
548
+ })
549
+ // Then the remaining points by risk-matched band, then id.
550
+ const rest = [...points].sort((a, b) => preferRisk(a.tier, risk) - preferRisk(b.tier, risk) || a.id.localeCompare(b.id))
551
+ for (const p of rest) push(p)
552
+ let primary = ordered.slice(0, ASK_OPTION_LIMIT)
553
+ const frontier = ordered.find((p) => p.tier === 'frontier' && p.key !== implementer?.key)
554
+ if (frontier && !primary.some((p) => p.tier === 'frontier') && primary.length === ASK_OPTION_LIMIT) {
555
+ primary = [...primary.slice(0, ASK_OPTION_LIMIT - 1), frontier]
556
+ }
557
+ const primaryKeys = new Set(primary.map((p) => p.key))
558
+ const optionFor = (p, recommended) =>
559
+ optionFromPoint(p, { recommended, role: 'implementer', ladderRung: ladderRungByKey.get(p.key) || 0 })
560
+ const options = primary.map((p) => optionFor(p, p.key === implementer?.key))
561
+ const alternates = ordered.filter((p) => !primaryKeys.has(p.key)).map((p) => optionFor(p, false))
562
+
563
+ return {
564
+ header: 'Implementer',
565
+ question: 'Which model should implement every issue in this run? (Explorer + reviewer are filled automatically; reviewer ≠ implementer.)',
566
+ recommended: implementer?.key || null,
567
+ options,
568
+ alternates,
569
+ explorerFill: slotFillPayload(explorer),
570
+ diagnoserFill: slotFillPayload(diagnoser),
571
+ reviewerFill: slotFillPayload(reviewer),
572
+ }
573
+ }
574
+
575
+ export function buildPreflightModels({
576
+ harness,
577
+ risk = 'routine',
578
+ available = [],
579
+ humanNamed = [],
580
+ implementer: pin = null,
581
+ env = process.env,
582
+ discoverFn = discover,
583
+ tierFn = tierProposals,
584
+ } = {}) {
585
+ if (!harness) throw new Error('harness is required')
586
+ if (!RISK.includes(risk)) throw new Error(`risk must be one of ${RISK.join('|')}`)
587
+
588
+ const discovery = discoverFn(harness, env, {
589
+ spawnModelIds: available,
590
+ humanNamedModelIds: humanNamed,
591
+ })
592
+ const seenIds = discovery.discovered.map((d) => d.id)
593
+ const tiered = tierFn(harness, seenIds)
594
+ const catalog = readCatalog(pathForHarness(harness, env))
595
+ const seed = readSeed(defaultSeedPath())
596
+ const points = slotPoints(tiered.models, { harness, catalog, seed })
597
+ const implementer = pin ? findPinnedPoint(points, pin) : recommendImplementer(points, risk, harness)
598
+ if (pin && !implementer) {
599
+ return {
600
+ ok: false,
601
+ code: 'pinned-implementer-unavailable',
602
+ pinned: pin,
603
+ harness,
604
+ risk,
605
+ discovery,
606
+ models: tiered,
607
+ points: points.map((p) => p.key),
608
+ implementer: null,
609
+ explorer: null,
610
+ diagnoser: null,
611
+ reviewer: null,
612
+ ask: null,
613
+ reason: `${pin} is not an available slot-eligible model here; block the run, never substitute another implementer`,
614
+ }
615
+ }
616
+ if (!implementer) {
617
+ return {
618
+ ok: false,
619
+ code: 'no-slot-eligible',
620
+ harness,
621
+ risk,
622
+ discovery,
623
+ models: tiered,
624
+ points: [],
625
+ implementer: null,
626
+ explorer: null,
627
+ diagnoser: null,
628
+ reviewer: null,
629
+ ask: null,
630
+ deferred: {
631
+ afterConfirm: [
632
+ 'model-catalog.mjs sync --harness <h> --seen <ids>',
633
+ 'model-catalog.mjs bank / bank-from-seed for any human confirmation',
634
+ ],
635
+ },
636
+ }
637
+ }
638
+ const explorer = fillExplorer(points, harness)
639
+ const diagnoser = fillDiagnoser(points, harness)
640
+ const reviewer = rankReviewers(points, implementer, harness)
641
+ const ask = buildAsk(implementer, points, reviewer, { risk, explorer, diagnoser, harness, pinned: !!pin })
642
+ return {
643
+ ok: true,
644
+ ...(pin ? { pinned: pin } : {}),
645
+ harness,
646
+ risk,
647
+ discovery: {
648
+ completeness: discovery.completeness,
649
+ discovered: discovery.discovered,
650
+ notes: discovery.notes,
651
+ },
652
+ models: tiered,
653
+ points,
654
+ implementer,
655
+ explorer: {
656
+ fill: explorer.fill,
657
+ reason: explorer.reason,
658
+ },
659
+ diagnoser: {
660
+ fill: diagnoser.fill,
661
+ reason: diagnoser.reason,
662
+ },
663
+ reviewer: {
664
+ fill: reviewer.fill,
665
+ reason: reviewer.reason,
666
+ ranking: reviewer.ranking.map((p) => p.key),
667
+ teamDefaultApplied: reviewer.teamDefaultApplied,
668
+ reducedDiversity: reviewer.reducedDiversity,
669
+ notIndependent: reviewer.notIndependent,
670
+ },
671
+ ask,
672
+ deferred: {
673
+ afterConfirm: [
674
+ `model-catalog.mjs sync --harness ${harness} --seen ${seenIds.join(',')}`,
675
+ 'bank confirmations only after the human answers — never before the ask',
676
+ ],
677
+ doNotReadBeforeAsk: [
678
+ 'harness-runtime/references/model-catalog.md',
679
+ ],
680
+ },
681
+ }
682
+ }
683
+
684
+ export function runCli(argv, env = process.env) {
685
+ let args
686
+ try {
687
+ args = parseArgs(argv)
688
+ } catch (e) {
689
+ console.error(`preflight-models: ${e.message}`)
690
+ console.error(usage())
691
+ return 2
692
+ }
693
+ if (args.help) {
694
+ console.log(usage())
695
+ return 0
696
+ }
697
+ const harness = args.harness || detectHarness(env)
698
+ if (!harness) {
699
+ console.error('preflight-models: pass --harness <pi|codex|claude-code>')
700
+ return 2
701
+ }
702
+ if (!RISK.includes(args.risk)) {
703
+ console.error(`preflight-models: --risk must be ${RISK.join('|')}`)
704
+ return 2
705
+ }
706
+
707
+ let result
708
+ try {
709
+ result = buildPreflightModels({
710
+ harness,
711
+ risk: args.risk,
712
+ available: args.available,
713
+ humanNamed: args.humanNamed,
714
+ implementer: args.implementer,
715
+ env,
716
+ })
717
+ } catch (e) {
718
+ console.error(`preflight-models: ${e.message}`)
719
+ return 2
720
+ }
721
+
722
+ if (!result.ok) {
723
+ console.log(JSON.stringify(result, null, 2))
724
+ return 0
725
+ }
726
+ if (args.askOnly) {
727
+ console.log(JSON.stringify(result.ask, null, 2))
728
+ return 0
729
+ }
730
+ console.log(JSON.stringify(result, null, 2))
731
+ return 0
732
+ }
733
+
734
+ if (isMainModule(import.meta.url)) {
735
+ process.exit(runCli(process.argv.slice(2)))
736
+ }