@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,767 @@
1
+ const HARNESSES = new Set(['pi', 'codex', 'claude-code']);
2
+ const COMPLETENESS = new Set(['partial', 'full']);
3
+ const RUNTIME_MODEL_SOURCES = new Set(['current-turn', 'runtime-enumeration']);
4
+
5
+ export const HARNESS_RUNTIME_ERROR_CODES = Object.freeze({
6
+ INVALID_CAPABILITIES: 'invalid-capabilities',
7
+ INVALID_QUESTION: 'invalid-question',
8
+ INVALID_ANSWERS: 'invalid-answers',
9
+ INVALID_MODEL_AVAILABILITY: 'invalid-model-availability',
10
+ CAPABILITY_UNAVAILABLE: 'capability-unavailable',
11
+ UNSUPPORTED_QUESTION: 'unsupported-question',
12
+ FALLBACK_FORBIDDEN: 'fallback-forbidden',
13
+ });
14
+
15
+ function deepFreeze(value) {
16
+ if (value && typeof value === 'object' && !Object.isFrozen(value)) {
17
+ for (const child of Object.values(value)) deepFreeze(child);
18
+ Object.freeze(value);
19
+ }
20
+ return value;
21
+ }
22
+
23
+ function clone(value) {
24
+ return structuredClone(value);
25
+ }
26
+
27
+ export class HarnessRuntimeError extends Error {
28
+ constructor(code, message, details = {}) {
29
+ super(message);
30
+ this.name = 'HarnessRuntimeError';
31
+ this.code = code;
32
+ this.details = deepFreeze(clone(details));
33
+ }
34
+ }
35
+
36
+ export class CapabilityUnavailableError extends HarnessRuntimeError {
37
+ constructor(capability, details = {}) {
38
+ super(
39
+ HARNESS_RUNTIME_ERROR_CODES.CAPABILITY_UNAVAILABLE,
40
+ `Required harness capability is unavailable: ${capability}`,
41
+ { ...details, capability },
42
+ );
43
+ this.name = 'CapabilityUnavailableError';
44
+ this.capability = capability;
45
+ }
46
+ }
47
+
48
+ export class UnsupportedQuestionError extends HarnessRuntimeError {
49
+ constructor(reason, details = {}) {
50
+ super(
51
+ HARNESS_RUNTIME_ERROR_CODES.UNSUPPORTED_QUESTION,
52
+ `Question cannot be represented by the selected native adapter: ${reason}`,
53
+ { ...details, reason },
54
+ );
55
+ this.name = 'UnsupportedQuestionError';
56
+ this.reason = reason;
57
+ }
58
+ }
59
+
60
+ export const QUESTION_ADAPTER_PRIORITY = Object.freeze([
61
+ 'ask_user_question',
62
+ 'request_user_input',
63
+ 'AskUserQuestion',
64
+ ]);
65
+
66
+ export const QUESTION_FALLBACK_POLICY = deepFreeze({
67
+ noNativeQuestionTool: {
68
+ freeText: 'concise-free-text-only',
69
+ multipleChoice: 'forbidden',
70
+ },
71
+ unsupportedMultiSelect: 'error',
72
+ secretInput: 'error',
73
+ });
74
+
75
+ function isRecord(value) {
76
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
77
+ }
78
+
79
+ function hasExactFields(value, required, optional = []) {
80
+ if (!isRecord(value)) return false;
81
+ const allowed = new Set([...required, ...optional]);
82
+ return required.every((field) => Object.hasOwn(value, field))
83
+ && Object.keys(value).every((field) => allowed.has(field));
84
+ }
85
+
86
+ function nonEmptyString(value) {
87
+ return typeof value === 'string' && value.trim().length > 0;
88
+ }
89
+
90
+ function stringList(value, { allowEmpty = true } = {}) {
91
+ return Array.isArray(value)
92
+ && (allowEmpty || value.length > 0)
93
+ && value.every(nonEmptyString)
94
+ && new Set(value).size === value.length;
95
+ }
96
+
97
+ function invalid(code, label, details = {}) {
98
+ throw new HarnessRuntimeError(code, `Invalid harness runtime ${label}.`, details);
99
+ }
100
+
101
+ export function defineCurrentTurnCapabilities(value) {
102
+ if (!hasExactFields(value, ['nativeTools', 'spawnModelIds'])
103
+ || !stringList(value.nativeTools)
104
+ || !stringList(value.spawnModelIds)) {
105
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_CAPABILITIES, 'current-turn capabilities');
106
+ }
107
+ return deepFreeze(clone(value));
108
+ }
109
+
110
+ function validOption(option) {
111
+ return hasExactFields(option, ['id', 'label'], ['description'])
112
+ && nonEmptyString(option.id)
113
+ && nonEmptyString(option.label)
114
+ && (option.description === undefined || nonEmptyString(option.description));
115
+ }
116
+
117
+ export function defineQuestionSpec(value) {
118
+ if (!hasExactFields(
119
+ value,
120
+ ['id', 'header', 'prompt'],
121
+ ['options', 'recommendationOrder', 'multiSelect', 'secret'],
122
+ ) || !nonEmptyString(value.id)
123
+ || !nonEmptyString(value.header)
124
+ || !nonEmptyString(value.prompt)) {
125
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question');
126
+ }
127
+
128
+ const options = value.options ?? [];
129
+ const optionIds = options.map((option) => option?.id);
130
+ const recommendationOrder = value.recommendationOrder ?? [];
131
+ if (!Array.isArray(options)
132
+ || !options.every(validOption)
133
+ || new Set(optionIds).size !== optionIds.length
134
+ || !stringList(recommendationOrder)
135
+ || recommendationOrder.some((id) => !optionIds.includes(id))
136
+ || (value.multiSelect !== undefined && typeof value.multiSelect !== 'boolean')
137
+ || (value.secret !== undefined && typeof value.secret !== 'boolean')) {
138
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', { questionId: value.id });
139
+ }
140
+
141
+ return deepFreeze({
142
+ id: value.id,
143
+ header: value.header,
144
+ prompt: value.prompt,
145
+ options: clone(options),
146
+ recommendationOrder: clone(recommendationOrder),
147
+ multiSelect: value.multiSelect ?? false,
148
+ secret: value.secret ?? false,
149
+ });
150
+ }
151
+
152
+ function orderedQuestionOptions(question) {
153
+ const byId = new Map(question.options.map((option) => [option.id, option]));
154
+ return [
155
+ ...question.recommendationOrder.map((id) => byId.get(id)),
156
+ ...question.options.filter((option) => !question.recommendationOrder.includes(option.id)),
157
+ ];
158
+ }
159
+
160
+ function answerMappings(batch, optionLabel = (_question, option) => option.label) {
161
+ return batch.map((question) => ({
162
+ questionId: question.id,
163
+ prompt: question.prompt,
164
+ multiSelect: question.multiSelect,
165
+ options: orderedQuestionOptions(question).map((option) => ({
166
+ id: option.id,
167
+ label: optionLabel(question, option),
168
+ })),
169
+ }));
170
+ }
171
+
172
+ function validateNativeOptionLabels(question, adapter, optionLabel = (_question, option) => option.label) {
173
+ const nativeOptions = orderedQuestionOptions(question).map((option) => ({
174
+ id: option.id,
175
+ label: optionLabel(question, option),
176
+ }));
177
+ const labels = new Map();
178
+ for (const option of nativeOptions) {
179
+ const existingId = labels.get(option.label);
180
+ if (existingId !== undefined) {
181
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
182
+ reason: 'native-option-label-collision',
183
+ adapter,
184
+ questionId: question.id,
185
+ label: option.label,
186
+ optionIds: [existingId, option.id],
187
+ });
188
+ }
189
+ labels.set(option.label, option.id);
190
+ }
191
+ return nativeOptions;
192
+ }
193
+
194
+ function claudeMultiAnswerMappings(options) {
195
+ const mappings = [];
196
+ for (let mask = 1; mask < (1 << options.length); mask += 1) {
197
+ const subset = options.filter((_, index) => mask & (1 << index));
198
+ for (const candidate of permutations(subset)) {
199
+ mappings.push({
200
+ answer: candidate.map((option) => option.label).join(', '),
201
+ optionIds: candidate.map((option) => option.id),
202
+ });
203
+ }
204
+ }
205
+ return mappings;
206
+ }
207
+
208
+ function validateClaudeMultiAnswerFormats(question, nativeOptions) {
209
+ if (!question.multiSelect) return;
210
+ const formats = new Map();
211
+ for (const mapping of claudeMultiAnswerMappings(nativeOptions)) {
212
+ const existing = formats.get(mapping.answer);
213
+ if (existing !== undefined
214
+ && JSON.stringify(existing) !== JSON.stringify(mapping.optionIds)) {
215
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
216
+ reason: 'native-answer-format-collision',
217
+ adapter: 'claude-code',
218
+ questionId: question.id,
219
+ answer: mapping.answer,
220
+ optionIdSets: [existing, mapping.optionIds],
221
+ });
222
+ }
223
+ formats.set(mapping.answer, mapping.optionIds);
224
+ }
225
+ }
226
+
227
+ function validateQuestionBatch(values) {
228
+ if (!Array.isArray(values) || values.length === 0) {
229
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question batch', {
230
+ reason: 'empty-question-batch',
231
+ });
232
+ }
233
+ const questions = values.map(defineQuestionSpec);
234
+ const duplicateId = questions.find((question, index) =>
235
+ questions.findIndex((candidate) => candidate.id === question.id) !== index);
236
+ if (duplicateId) {
237
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question batch', {
238
+ reason: 'duplicate-question-id',
239
+ questionId: duplicateId.id,
240
+ });
241
+ }
242
+ const duplicatePrompt = questions.find((question, index) =>
243
+ questions.findIndex((candidate) => candidate.prompt === question.prompt) !== index);
244
+ if (duplicatePrompt) {
245
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question batch', {
246
+ reason: 'duplicate-question-prompt',
247
+ questionId: duplicatePrompt.id,
248
+ });
249
+ }
250
+ return questions;
251
+ }
252
+
253
+ function validatePiQuestion(question) {
254
+ if (question.secret) {
255
+ throw new UnsupportedQuestionError('secret-input', { adapter: 'pi', questionId: question.id });
256
+ }
257
+ if (question.header.length > 16) {
258
+ throw new UnsupportedQuestionError('header-too-long', {
259
+ adapter: 'pi',
260
+ questionId: question.id,
261
+ maximum: 16,
262
+ });
263
+ }
264
+ if (question.options.length < 2 || question.options.length > 4) {
265
+ throw new UnsupportedQuestionError('option-count', {
266
+ adapter: 'pi',
267
+ questionId: question.id,
268
+ minimum: 2,
269
+ maximum: 4,
270
+ });
271
+ }
272
+ const duplicateLabel = question.options.find((option, index) =>
273
+ question.options.findIndex((candidate) => candidate.label === option.label) !== index);
274
+ if (duplicateLabel) {
275
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
276
+ reason: 'duplicate-option-label',
277
+ questionId: question.id,
278
+ label: duplicateLabel.label,
279
+ });
280
+ }
281
+ validateNativeOptionLabels(question, 'pi');
282
+ for (const option of question.options) {
283
+ if (['Other', 'Type something.', 'Next'].includes(option.label)) {
284
+ throw new UnsupportedQuestionError('reserved-option-label', {
285
+ adapter: 'pi',
286
+ questionId: question.id,
287
+ optionId: option.id,
288
+ label: option.label,
289
+ });
290
+ }
291
+ if (option.description === undefined) {
292
+ throw new UnsupportedQuestionError('option-description-required', {
293
+ adapter: 'pi',
294
+ questionId: question.id,
295
+ optionId: option.id,
296
+ });
297
+ }
298
+ if (option.label.length > 60) {
299
+ throw new UnsupportedQuestionError('option-label-too-long', {
300
+ adapter: 'pi',
301
+ questionId: question.id,
302
+ optionId: option.id,
303
+ maximum: 60,
304
+ });
305
+ }
306
+ }
307
+ }
308
+
309
+ function chunk(values, size) {
310
+ const batches = [];
311
+ for (let index = 0; index < values.length; index += size) {
312
+ batches.push(values.slice(index, index + size));
313
+ }
314
+ return batches;
315
+ }
316
+
317
+ function batchingResult(calls) {
318
+ return {
319
+ required: calls.length > 1,
320
+ reason: calls.length > 1 ? 'adapter-capacity' : null,
321
+ callCount: calls.length,
322
+ };
323
+ }
324
+
325
+ function planPiQuestions(questions) {
326
+ for (const question of questions) validatePiQuestion(question);
327
+ const calls = chunk(questions, 4).map((batch, index) => ({
328
+ index,
329
+ questionIds: batch.map((question) => question.id),
330
+ answerMappings: answerMappings(batch),
331
+ payload: {
332
+ questions: batch.map((question) => ({
333
+ question: question.prompt,
334
+ header: question.header,
335
+ options: orderedQuestionOptions(question).map((option) => ({
336
+ label: option.label,
337
+ description: option.description,
338
+ })),
339
+ multiSelect: question.multiSelect,
340
+ })),
341
+ },
342
+ }));
343
+ return deepFreeze({
344
+ kind: 'native',
345
+ adapter: 'pi',
346
+ toolName: 'ask_user_question',
347
+ capacity: 4,
348
+ requiresMultipleCalls: calls.length > 1,
349
+ batching: batchingResult(calls),
350
+ calls,
351
+ });
352
+ }
353
+
354
+ function validateNativeOptions(question, adapter, maximum) {
355
+ if (question.options.length < 2 || question.options.length > maximum) {
356
+ throw new UnsupportedQuestionError('option-count', {
357
+ adapter,
358
+ questionId: question.id,
359
+ minimum: 2,
360
+ maximum,
361
+ });
362
+ }
363
+ const duplicateLabel = question.options.find((option, index) =>
364
+ question.options.findIndex((candidate) => candidate.label === option.label) !== index);
365
+ if (duplicateLabel) {
366
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
367
+ reason: 'duplicate-option-label',
368
+ questionId: question.id,
369
+ label: duplicateLabel.label,
370
+ });
371
+ }
372
+ const missingDescription = question.options.find((option) => option.description === undefined);
373
+ if (missingDescription) {
374
+ throw new UnsupportedQuestionError('option-description-required', {
375
+ adapter,
376
+ questionId: question.id,
377
+ optionId: missingDescription.id,
378
+ });
379
+ }
380
+ }
381
+
382
+ function codexOptionLabel(question, option) {
383
+ return question.recommendationOrder[0] === option.id
384
+ ? `${option.label} (Recommended)`
385
+ : option.label;
386
+ }
387
+
388
+ function planCodexQuestions(questions) {
389
+ for (const question of questions) {
390
+ if (question.secret) {
391
+ throw new UnsupportedQuestionError('secret-input', {
392
+ adapter: 'codex',
393
+ questionId: question.id,
394
+ });
395
+ }
396
+ if (question.multiSelect) {
397
+ throw new UnsupportedQuestionError('multi-select', {
398
+ adapter: 'codex',
399
+ questionId: question.id,
400
+ });
401
+ }
402
+ if (!/^[a-z][a-z0-9_]*$/.test(question.id)) {
403
+ throw new UnsupportedQuestionError('invalid-question-id', {
404
+ adapter: 'codex',
405
+ questionId: question.id,
406
+ format: 'snake_case',
407
+ });
408
+ }
409
+ if (question.header.length > 12) {
410
+ throw new UnsupportedQuestionError('header-too-long', {
411
+ adapter: 'codex',
412
+ questionId: question.id,
413
+ maximum: 12,
414
+ });
415
+ }
416
+ validateNativeOptions(question, 'codex', 3);
417
+ validateNativeOptionLabels(question, 'codex', codexOptionLabel);
418
+ }
419
+ const calls = chunk(questions, 3).map((batch, index) => ({
420
+ index,
421
+ questionIds: batch.map((question) => question.id),
422
+ answerMappings: answerMappings(batch, codexOptionLabel),
423
+ payload: {
424
+ questions: batch.map((question) => ({
425
+ id: question.id,
426
+ header: question.header,
427
+ question: question.prompt,
428
+ options: orderedQuestionOptions(question).map((option) => ({
429
+ label: codexOptionLabel(question, option),
430
+ description: option.description,
431
+ })),
432
+ })),
433
+ },
434
+ }));
435
+ return deepFreeze({
436
+ kind: 'native',
437
+ adapter: 'codex',
438
+ toolName: 'request_user_input',
439
+ capacity: 3,
440
+ requiresMultipleCalls: calls.length > 1,
441
+ batching: batchingResult(calls),
442
+ calls,
443
+ });
444
+ }
445
+
446
+ function planClaudeQuestions(questions) {
447
+ for (const question of questions) {
448
+ if (question.secret) {
449
+ throw new UnsupportedQuestionError('secret-input', {
450
+ adapter: 'claude-code',
451
+ questionId: question.id,
452
+ });
453
+ }
454
+ if (question.header.length > 12) {
455
+ throw new UnsupportedQuestionError('header-too-long', {
456
+ adapter: 'claude-code',
457
+ questionId: question.id,
458
+ maximum: 12,
459
+ });
460
+ }
461
+ validateNativeOptions(question, 'claude-code', 4);
462
+ const nativeOptions = validateNativeOptionLabels(question, 'claude-code');
463
+ validateClaudeMultiAnswerFormats(question, nativeOptions);
464
+ }
465
+ const calls = chunk(questions, 4).map((batch, index) => ({
466
+ index,
467
+ questionIds: batch.map((question) => question.id),
468
+ answerMappings: answerMappings(batch),
469
+ payload: {
470
+ questions: batch.map((question) => ({
471
+ question: question.prompt,
472
+ header: question.header,
473
+ options: orderedQuestionOptions(question).map((option) => ({
474
+ label: option.label,
475
+ description: option.description,
476
+ })),
477
+ multiSelect: question.multiSelect,
478
+ })),
479
+ },
480
+ }));
481
+ return deepFreeze({
482
+ kind: 'native',
483
+ adapter: 'claude-code',
484
+ toolName: 'AskUserQuestion',
485
+ capacity: 4,
486
+ requiresMultipleCalls: calls.length > 1,
487
+ batching: batchingResult(calls),
488
+ calls,
489
+ });
490
+ }
491
+
492
+ function planQuestionFallback(capabilities, questions) {
493
+ const secret = questions.find((question) => question.secret);
494
+ if (secret) {
495
+ throw new UnsupportedQuestionError('secret-input', {
496
+ adapter: null,
497
+ questionId: secret.id,
498
+ });
499
+ }
500
+ const multiSelect = questions.find((question) => question.multiSelect);
501
+ if (multiSelect) {
502
+ throw new UnsupportedQuestionError('multi-select', {
503
+ adapter: null,
504
+ questionId: multiSelect.id,
505
+ });
506
+ }
507
+ const hasOptions = questions.some((question) => question.options.length > 0);
508
+ const oneFreeTextQuestion = questions.length === 1 && !hasOptions;
509
+ return deepFreeze({
510
+ kind: 'fallback',
511
+ adapter: null,
512
+ reason: 'no-supported-native-question-tool',
513
+ decision: oneFreeTextQuestion
514
+ ? 'concise-free-text'
515
+ : 'textual-multiple-choice-forbidden',
516
+ freeText: oneFreeTextQuestion
517
+ ? {
518
+ allowed: true,
519
+ questionId: questions[0].id,
520
+ prompt: questions[0].prompt,
521
+ }
522
+ : {
523
+ allowed: false,
524
+ reason: hasOptions ? 'logical-question-has-options' : 'multiple-questions',
525
+ },
526
+ textualMultipleChoice: {
527
+ allowed: false,
528
+ reason: QUESTION_FALLBACK_POLICY.noNativeQuestionTool.multipleChoice,
529
+ },
530
+ availableTools: clone(capabilities.nativeTools),
531
+ });
532
+ }
533
+
534
+ export function planStructuredQuestions(capabilitiesValue, questionValues) {
535
+ const capabilities = defineCurrentTurnCapabilities(capabilitiesValue);
536
+ const questions = validateQuestionBatch(questionValues);
537
+ if (capabilities.nativeTools.includes('ask_user_question')) {
538
+ return planPiQuestions(questions);
539
+ }
540
+ if (capabilities.nativeTools.includes('request_user_input')) {
541
+ return planCodexQuestions(questions);
542
+ }
543
+ if (capabilities.nativeTools.includes('AskUserQuestion')) {
544
+ return planClaudeQuestions(questions);
545
+ }
546
+ return planQuestionFallback(capabilities, questions);
547
+ }
548
+
549
+ function invalidAnswers(reason, details = {}) {
550
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_ANSWERS, 'question answers', {
551
+ reason,
552
+ ...details,
553
+ });
554
+ }
555
+
556
+ function mappedOption(mapping, label) {
557
+ const matches = mapping.options.filter((option) => option.label === label);
558
+ if (matches.length > 1) {
559
+ invalidAnswers('ambiguous-option-label', {
560
+ questionId: mapping.questionId,
561
+ answer: label,
562
+ optionIds: matches.map((option) => option.id),
563
+ });
564
+ }
565
+ return matches[0];
566
+ }
567
+
568
+ function mapSingleAnswer(mapping, value, { custom = true } = {}) {
569
+ if (!nonEmptyString(value)) invalidAnswers('empty-answer', { questionId: mapping.questionId });
570
+ const option = mappedOption(mapping, value);
571
+ if (option) return option.id;
572
+ if (custom) return value;
573
+ invalidAnswers('unknown-option-label', { questionId: mapping.questionId, answer: value });
574
+ }
575
+
576
+ function requireCompleteAnswers(call, answers) {
577
+ const missingQuestionIds = call.answerMappings
578
+ .map((mapping) => mapping.questionId)
579
+ .filter((questionId) => !Object.hasOwn(answers, questionId));
580
+ if (missingQuestionIds.length > 0) {
581
+ invalidAnswers('incomplete-native-response', {
582
+ callIndex: call.index,
583
+ missingQuestionIds,
584
+ });
585
+ }
586
+ return answers;
587
+ }
588
+
589
+ function normalizePiResponse(call, response) {
590
+ if (!isRecord(response) || !isRecord(response.details)
591
+ || !Array.isArray(response.details.answers)
592
+ || response.details.cancelled !== false) {
593
+ invalidAnswers('malformed-pi-response', { callIndex: call.index });
594
+ }
595
+ const answers = {};
596
+ const seenIndexes = new Set();
597
+ for (const nativeAnswer of response.details.answers) {
598
+ if (!isRecord(nativeAnswer)
599
+ || !Number.isInteger(nativeAnswer.questionIndex)
600
+ || seenIndexes.has(nativeAnswer.questionIndex)) {
601
+ invalidAnswers('malformed-pi-answer', { callIndex: call.index });
602
+ }
603
+ const mapping = call.answerMappings[nativeAnswer.questionIndex];
604
+ if (!mapping || nativeAnswer.question !== mapping.prompt) {
605
+ invalidAnswers('unknown-pi-question', { callIndex: call.index });
606
+ }
607
+ seenIndexes.add(nativeAnswer.questionIndex);
608
+ if (nativeAnswer.kind === 'multi') {
609
+ if (!mapping.multiSelect
610
+ || !Array.isArray(nativeAnswer.selected)
611
+ || nativeAnswer.selected.length === 0
612
+ || !nativeAnswer.selected.every(nonEmptyString)) {
613
+ invalidAnswers('malformed-pi-multi-answer', { questionId: mapping.questionId });
614
+ }
615
+ answers[mapping.questionId] = nativeAnswer.selected.map((label) =>
616
+ mapSingleAnswer(mapping, label, { custom: false }));
617
+ } else if (nativeAnswer.kind === 'option') {
618
+ answers[mapping.questionId] = [
619
+ mapSingleAnswer(mapping, nativeAnswer.answer, { custom: false }),
620
+ ];
621
+ } else if (nativeAnswer.kind === 'custom') {
622
+ if (!nonEmptyString(nativeAnswer.answer)) {
623
+ invalidAnswers('empty-answer', { questionId: mapping.questionId });
624
+ }
625
+ answers[mapping.questionId] = [nativeAnswer.answer];
626
+ } else {
627
+ invalidAnswers('unknown-pi-answer-kind', { questionId: mapping.questionId });
628
+ }
629
+ }
630
+ return requireCompleteAnswers(call, answers);
631
+ }
632
+
633
+ function normalizeCodexResponse(call, response) {
634
+ if (!hasExactFields(response, ['answers']) || !isRecord(response.answers)) {
635
+ invalidAnswers('malformed-codex-response', { callIndex: call.index });
636
+ }
637
+ const mappings = new Map(call.answerMappings.map((mapping) => [mapping.questionId, mapping]));
638
+ const answers = {};
639
+ for (const [questionId, nativeAnswer] of Object.entries(response.answers)) {
640
+ const mapping = mappings.get(questionId);
641
+ if (!mapping || !hasExactFields(nativeAnswer, ['answers'])
642
+ || !stringList(nativeAnswer.answers, { allowEmpty: false })
643
+ || nativeAnswer.answers.length !== 1) {
644
+ invalidAnswers('malformed-codex-answer', { callIndex: call.index, questionId });
645
+ }
646
+ answers[questionId] = nativeAnswer.answers.map((value) => mapSingleAnswer(mapping, value));
647
+ }
648
+ return requireCompleteAnswers(call, answers);
649
+ }
650
+
651
+ function permutations(values) {
652
+ if (values.length === 0) return [[]];
653
+ return values.flatMap((value, index) =>
654
+ permutations(values.filter((_, candidateIndex) => candidateIndex !== index))
655
+ .map((rest) => [value, ...rest]));
656
+ }
657
+
658
+ function parseClaudeMultiAnswer(mapping, value) {
659
+ const matches = claudeMultiAnswerMappings(mapping.options)
660
+ .filter((candidate) => candidate.answer === value)
661
+ .map((candidate) => candidate.optionIds);
662
+ const unique = [...new Map(matches.map((match) => [JSON.stringify(match), match])).values()];
663
+ if (unique.length > 1) {
664
+ invalidAnswers('ambiguous-claude-multi-answer', { questionId: mapping.questionId });
665
+ }
666
+ return unique[0] ?? [value];
667
+ }
668
+
669
+ function normalizeClaudeResponse(call, response) {
670
+ if (!isRecord(response) || !isRecord(response.answers)) {
671
+ invalidAnswers('malformed-claude-response', { callIndex: call.index });
672
+ }
673
+ const mappings = new Map(call.answerMappings.map((mapping) => [mapping.prompt, mapping]));
674
+ const answers = {};
675
+ for (const [prompt, value] of Object.entries(response.answers)) {
676
+ const mapping = mappings.get(prompt);
677
+ if (!mapping || !nonEmptyString(value)) {
678
+ invalidAnswers('malformed-claude-answer', { callIndex: call.index, prompt });
679
+ }
680
+ answers[mapping.questionId] = mapping.multiSelect
681
+ ? parseClaudeMultiAnswer(mapping, value)
682
+ : [mapSingleAnswer(mapping, value)];
683
+ }
684
+ return requireCompleteAnswers(call, answers);
685
+ }
686
+
687
+ function responseCancelled(adapter, response) {
688
+ if (isRecord(response) && response.cancelled === true) return true;
689
+ return adapter === 'pi'
690
+ && isRecord(response)
691
+ && isRecord(response.details)
692
+ && response.details.cancelled === true;
693
+ }
694
+
695
+ export function normalizeQuestionResponses(plan, nativeResponses) {
696
+ if (!isRecord(plan) || plan.kind !== 'native'
697
+ || !['pi', 'codex', 'claude-code'].includes(plan.adapter)
698
+ || !Array.isArray(plan.calls)) {
699
+ invalidAnswers('invalid-question-plan');
700
+ }
701
+ if (!Array.isArray(nativeResponses) || nativeResponses.length !== plan.calls.length) {
702
+ invalidAnswers('response-count', {
703
+ expected: plan.calls.length,
704
+ actual: Array.isArray(nativeResponses) ? nativeResponses.length : null,
705
+ });
706
+ }
707
+ if (nativeResponses.some((response) => responseCancelled(plan.adapter, response))) {
708
+ return defineQuestionAnswers({});
709
+ }
710
+ const answers = {};
711
+ for (let index = 0; index < plan.calls.length; index += 1) {
712
+ const call = plan.calls[index];
713
+ const response = nativeResponses[index];
714
+ const normalized = plan.adapter === 'pi'
715
+ ? normalizePiResponse(call, response)
716
+ : plan.adapter === 'codex'
717
+ ? normalizeCodexResponse(call, response)
718
+ : normalizeClaudeResponse(call, response);
719
+ for (const [questionId, values] of Object.entries(normalized)) {
720
+ if (Object.hasOwn(answers, questionId)) {
721
+ invalidAnswers('duplicate-question-answer', { questionId });
722
+ }
723
+ answers[questionId] = values;
724
+ }
725
+ }
726
+ return defineQuestionAnswers(answers);
727
+ }
728
+
729
+ export function defineQuestionAnswers(value) {
730
+ if (!isRecord(value)
731
+ || Object.entries(value).some(([questionId, answers]) =>
732
+ !nonEmptyString(questionId) || !stringList(answers, { allowEmpty: false }))) {
733
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_ANSWERS, 'question answers');
734
+ }
735
+ return deepFreeze(clone(value));
736
+ }
737
+
738
+ function validModel(model) {
739
+ return hasExactFields(model, ['id', 'sources'])
740
+ && nonEmptyString(model.id)
741
+ && stringList(model.sources, { allowEmpty: false });
742
+ }
743
+
744
+ export function defineModelAvailability(value) {
745
+ if (!hasExactFields(value, ['harness', 'completeness', 'models'])
746
+ || !HARNESSES.has(value.harness)
747
+ || !COMPLETENESS.has(value.completeness)
748
+ || !Array.isArray(value.models)
749
+ || !value.models.every(validModel)
750
+ || new Set(value.models.map((model) => model.id)).size !== value.models.length) {
751
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_MODEL_AVAILABILITY, 'model availability');
752
+ }
753
+
754
+ const runtimeEnumerated = value.models.some((model) =>
755
+ model.sources.some((source) => RUNTIME_MODEL_SOURCES.has(source)));
756
+ if (value.completeness === 'full'
757
+ && ['codex', 'claude-code'].includes(value.harness)
758
+ && !runtimeEnumerated) {
759
+ invalid(
760
+ HARNESS_RUNTIME_ERROR_CODES.INVALID_MODEL_AVAILABILITY,
761
+ 'model availability',
762
+ { reason: 'static-config-is-not-complete', harness: value.harness },
763
+ );
764
+ }
765
+
766
+ return deepFreeze(clone(value));
767
+ }