@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,659 @@
1
+ import { test } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { createHash } from 'node:crypto'
4
+ import { mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs'
5
+ import { tmpdir } from 'node:os'
6
+ import { join } from 'node:path'
7
+ import { spawnSync } from 'node:child_process'
8
+ import { planRelease } from './plan.mjs'
9
+ import { probeNpmVersionAbsence } from './npm-version-absence.mjs'
10
+
11
+ const version = '1.3.0'
12
+ const now = new Date('2026-10-19T12:00:00Z')
13
+ const original = '## [1.3.0] - 2026-10-18\n\n- Original reviewed notes.\n'
14
+ const reviewed = '## [1.3.0] - 2026-10-18\n\n- Corrected reviewed notes.\n'
15
+ const digest = (bytes) => createHash('sha256').update(bytes).digest('hex')
16
+ const json = (value) => `${JSON.stringify(value, null, 2)}\n`
17
+
18
+ function fixture(t, { name = '@example/demo', format = 3, lock = true, preparedVersion = version, transform = (files) => files } = {}) {
19
+ const base = mkdtempSync(join(tmpdir(), 'prepared-npm-'))
20
+ t.after(() => rmSync(base, { recursive: true, force: true }))
21
+ const cwd = join(base, 'repo')
22
+ const remote = join(base, 'origin.git')
23
+ const home = join(base, 'home')
24
+ for (const directory of [cwd, remote, home]) mkdirSync(directory)
25
+ const env = {
26
+ PATH: process.env.PATH, HOME: home, TMPDIR: base, LC_ALL: 'C', TZ: 'UTC',
27
+ GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: '/dev/null', GIT_ATTR_NOSYSTEM: '1',
28
+ GIT_ALLOW_PROTOCOL: 'file', GIT_TERMINAL_PROMPT: '0',
29
+ GIT_CONFIG_COUNT: '1', GIT_CONFIG_KEY_0: 'core.hooksPath', GIT_CONFIG_VALUE_0: '/dev/null',
30
+ GIT_AUTHOR_DATE: now.toISOString(), GIT_COMMITTER_DATE: now.toISOString(),
31
+ }
32
+ const gitAt = (directory, ...args) => {
33
+ const result = spawnSync('git', args, { cwd: directory, env, timeout: 10_000, maxBuffer: 16 * 1024 * 1024 })
34
+ assert.equal(result.status, 0, result.stderr?.toString('utf8'))
35
+ return result.stdout
36
+ }
37
+ const bytes = (...args) => gitAt(cwd, ...args)
38
+ const git = (...args) => bytes(...args).toString('utf8').trim()
39
+ git('init', '--template=', '-b', 'main')
40
+ git('config', 'user.email', 'fixture@example.invalid')
41
+ git('config', 'user.name', 'Offline Fixture')
42
+ git('config', 'commit.gpgsign', 'false')
43
+ git('config', 'tag.gpgsign', 'false')
44
+ gitAt(remote, 'init', '--bare', '--template=')
45
+ git('remote', 'add', 'origin', 'https://github.com/example/demo.git')
46
+ git('config', `url.${remote}.insteadOf`, 'https://github.com/example/demo.git')
47
+ const snapshots = {}
48
+ const commit = (stage, releaseVersion) => {
49
+ const pkg = { name, version: releaseVersion, scripts: { test: 'node --test' }, dependencies: { dep: '^1.0.0' } }
50
+ const files = {
51
+ 'package.json': json(pkg), VERSION: `${releaseVersion}\n`,
52
+ 'CHANGELOG.md': `# Changelog\n\n${stage === 'target' ? reviewed : stage === 'parent' ? '## [1.2.0] - 2026-10-01\n\n- Old release.\n' : original}`,
53
+ 'index.js': stage === 'target' ? 'export const fixed = true\n' : 'export const fixed = false\n',
54
+ }
55
+ if (lock) files['package-lock.json'] = json({
56
+ name, version: releaseVersion, lockfileVersion: format,
57
+ packages: {
58
+ '': { name, version: releaseVersion, dependencies: { dep: '^1.0.0' } },
59
+ 'node_modules/dep': { version: '1.0.0', resolved: 'https://invalid.example/dep.tgz', integrity: 'sha512-fixture' },
60
+ },
61
+ })
62
+ files['CHANGELOG.md'] = files['CHANGELOG.md'].replaceAll(version, preparedVersion)
63
+ const changed = transform(files, stage)
64
+ for (const file of Object.keys(files)) if (!Object.hasOwn(changed, file)) rmSync(join(cwd, file), { force: true })
65
+ for (const [file, content] of Object.entries(changed)) writeFileSync(join(cwd, file), content)
66
+ git('add', '.')
67
+ git('commit', '--allow-empty', '-m', `chore: ${stage}`)
68
+ snapshots[stage] = Object.fromEntries(Object.keys(changed).map((file) => [file, readFileSync(join(cwd, file))]))
69
+ return git('rev-parse', 'HEAD')
70
+ }
71
+ const parentSha = commit('parent', '1.2.0')
72
+ git('tag', 'v1.2.0')
73
+ git('switch', '-c', 'metadata')
74
+ const cutSha = commit('cut', preparedVersion)
75
+ git('switch', 'main')
76
+ git('merge', '--no-ff', 'metadata', '-m', 'Merge reviewed metadata')
77
+ const mergeSha = git('rev-parse', 'HEAD')
78
+ const sourceSha = commit('previous', preparedVersion)
79
+ const sha = commit('target', preparedVersion)
80
+ git('push', 'origin', 'main', '--tags')
81
+ const receipt = join(cwd, '.git', 'resolve-release-authorization.json')
82
+ const receiptBytes = Buffer.from('historical receipt: no authority for this attempt\n')
83
+ writeFileSync(receipt, receiptBytes)
84
+ const preparedMetadata = {
85
+ schema: 'prepared-release-metadata/v2', repository: 'example/demo', version: preparedVersion, metadataPr: 42, cutSha, mergeSha,
86
+ previousAttempt: { kind: 'pre-tag', receiptId: 'failed-pre-tag-attempt', receiptSha256: digest(receiptBytes), sourceSha },
87
+ }
88
+ const plan = (options = {}) => {
89
+ const inherited = process.env
90
+ process.env = env
91
+ try { return planRelease({ cwd, sha, preparedMetadata, now, ...options }) } finally { process.env = inherited }
92
+ }
93
+ const cli = (options = {}) => {
94
+ const input = join(cwd, '.git', 'prepared.json')
95
+ writeFileSync(input, json(options.input ?? preparedMetadata))
96
+ return spawnSync(process.execPath, [join(import.meta.dirname, 'plan.mjs'), '--sha', options.sha ?? sha,
97
+ '--prepared-metadata', input, '--json', ...(options.args ?? [])], {
98
+ cwd, env: options.env ?? env, encoding: 'utf8', timeout: 20_000,
99
+ })
100
+ }
101
+ const unchanged = () => {
102
+ const refs = git('show-ref')
103
+ const remoteRefs = gitAt(remote, 'show-ref')
104
+ const status = git('status', '--porcelain')
105
+ const head = git('rev-parse', 'HEAD')
106
+ const files = Object.fromEntries(Object.keys(snapshots.target).map((file) => [file, readFileSync(join(cwd, file))]))
107
+ return () => {
108
+ assert.equal(git('show-ref'), refs)
109
+ assert.deepEqual(gitAt(remote, 'show-ref'), remoteRefs)
110
+ assert.equal(git('status', '--porcelain'), status)
111
+ assert.equal(git('rev-parse', 'HEAD'), head)
112
+ for (const [file, content] of Object.entries(files)) assert.deepEqual(readFileSync(join(cwd, file)), content)
113
+ assert.deepEqual(readFileSync(receipt), receiptBytes)
114
+ }
115
+ }
116
+ return { cwd, remote, env, git, bytes, gitAt, sha, sourceSha, parentSha, cutSha, mergeSha, snapshots,
117
+ receipt, receiptBytes, preparedMetadata, plan, cli, unchanged }
118
+ }
119
+
120
+ function editJson(files, file, change) {
121
+ const value = JSON.parse(files[file])
122
+ change(value)
123
+ return { ...files, [file]: json(value) }
124
+ }
125
+
126
+ test('genuine pre-tag npm reuse needs no RC and preserves frozen source, provenance and repository bytes via API and CLI', (t) => {
127
+ const f = fixture(t)
128
+ assert.equal(f.git('tag', '--list', '*-rc.*'), '')
129
+ assert.equal(f.gitAt(f.remote, 'tag', '--list', '*-rc.*').length, 0)
130
+ const verify = f.unchanged()
131
+ const plan = f.plan()
132
+ assert.equal(plan.sha, f.sha)
133
+ assert.equal(plan.releaseSourceSha, f.sha)
134
+ assert.equal(plan.bump, 'none')
135
+ assert.equal(plan.currentVersion, version)
136
+ assert.equal(plan.nextVersion, version)
137
+ assert.equal(plan.tag, `v${version}`)
138
+ assert.equal(plan.candidateTag, null)
139
+ assert.deepEqual(plan.artifact, { kind: 'npm', packageName: '@example/demo', version })
140
+ assert.deepEqual(plan.versionFiles, ['package.json', 'package-lock.json', 'VERSION'])
141
+ assert.equal(plan.changelogMarkdown, reviewed)
142
+ assert.equal(plan.metadata.originalSectionSha256, digest(original))
143
+ assert.equal(plan.metadata.preparedSectionSha256, digest(reviewed))
144
+ assert.equal(plan.metadata.mode, 'reuse-prepared')
145
+ assert.equal(plan.metadata.schema, f.preparedMetadata.schema)
146
+ assert.deepEqual(plan.metadata.previousAttempt, f.preparedMetadata.previousAttempt)
147
+ assert.deepEqual(plan.metadata.remoteInspection, {
148
+ remote: 'origin', finalTagAbsent: `v${version}`, candidateTagAbsent: null, inspectedAt: now.toISOString(),
149
+ })
150
+ assert.notEqual(plan.receiptId, f.preparedMetadata.previousAttempt.receiptId)
151
+ assert.notEqual(f.plan().receiptId, plan.receiptId)
152
+ const result = f.cli()
153
+ assert.equal(result.status, 0, result.stderr)
154
+ const output = JSON.parse(result.stdout)
155
+ assert.deepEqual(output.artifact, plan.artifact)
156
+ assert.deepEqual(output.metadata.previousAttempt, f.preparedMetadata.previousAttempt)
157
+ assert.equal(output.releaseSourceSha, f.sha)
158
+ assert.equal(output.candidateTag, null)
159
+ verify()
160
+ writeFileSync(join(f.cwd, 'package.json'), json({ name: 'dirty', version: '9.0.0' }))
161
+ f.git('add', '.')
162
+ f.git('commit', '-m', 'chore: later source must not replace frozen target')
163
+ assert.equal(f.plan().metadata.preparedSectionSha256, digest(reviewed))
164
+ assert.deepEqual(f.plan().artifact, plan.artifact)
165
+ })
166
+
167
+ for (const [name, format, lock] of [['demo', 2, true], ['@example/demo', 3, true], ['demo', 3, false], ['a'.repeat(214), 2, false]]) {
168
+ test(`npm pre-tag accepts ${name.slice(0, 24)} with ${lock ? `lock v${format}` : 'no lock'}`, (t) => {
169
+ const f = fixture(t, { name, format, lock, transform: (files) => editJson(files, 'package.json', (pkg) => { pkg.private = false }) })
170
+ assert.deepEqual(f.plan().artifact, { kind: 'npm', packageName: name, version })
171
+ assert.equal(f.plan({ sha: f.sourceSha }).releaseSourceSha, f.sourceSha)
172
+ const input = structuredClone(f.preparedMetadata)
173
+ input.previousAttempt.sourceSha = f.mergeSha
174
+ assert.equal(f.plan({ sha: f.mergeSha, preparedMetadata: input }).releaseSourceSha, f.mergeSha)
175
+ })
176
+ }
177
+
178
+ const invalidPackages = [
179
+ ['missing name', (pkg) => { delete pkg.name }, /package.json.*name/],
180
+ ...['Upper', '.dot', '_underscore', '@Scope/pkg', '@scope/.pkg', '@scope', 'a/b', 'has space', 'a%2fb', 'a?b', 'node_modules', 'favicon.ico', '', 'x'.repeat(215)]
181
+ .map((name) => [`unsafe name ${name.slice(0, 15)}`, (pkg) => { pkg.name = name }, /package.json.*name/]),
182
+ ['private true', (pkg) => { pkg.private = true }, /private/],
183
+ ['private null', (pkg) => { pkg.private = null }, /private/],
184
+ ['private string', (pkg) => { pkg.private = 'false' }, /private/],
185
+ ['empty workspaces', (pkg) => { pkg.workspaces = [] }, /workspaces/],
186
+ ['null workspaces', (pkg) => { pkg.workspaces = null }, /workspaces/],
187
+ ['workspace object', (pkg) => { pkg.workspaces = { packages: [] } }, /workspaces/],
188
+ ['stale package version', (pkg) => { pkg.version = '1.2.0' }, /package.json.*version/],
189
+ ['non-string version', (pkg) => { pkg.version = 1.3 }, /package.json.*version/],
190
+ ]
191
+
192
+ test('npm pre-tag refuses invalid or non-publishable package identities', async (t) => {
193
+ for (const [label, change, error] of invalidPackages) {
194
+ await t.test(label, (t) => {
195
+ const f = fixture(t, { transform: (files, stage) => stage === 'target' ? editJson(files, 'package.json', change) : files })
196
+ assert.throws(f.plan, error)
197
+ })
198
+ }
199
+ })
200
+
201
+ const invalidLocks = [
202
+ ['top name', (value) => { value.name = 'foreign' }, /lock.*name/],
203
+ ['missing top name', (value) => { delete value.name }, /lock.*name/],
204
+ ['stale top version', (value) => { value.version = '1.2.0' }, /lock.*version/],
205
+ ['stale root version', (value) => { value.packages[''].version = '1.2.0' }, /lock.*version/],
206
+ ['missing root version', (value) => { delete value.packages[''].version }, /lock.*version/],
207
+ ['foreign root name', (value) => { value.packages[''].name = 'foreign' }, /lock.*name/],
208
+ ['missing root name', (value) => { delete value.packages[''].name }, /lock.*name/],
209
+ ['missing root', (value) => { delete value.packages[''] }, /lock.*root/],
210
+ ['missing packages', (value) => { delete value.packages }, /lock.*root/],
211
+ ['null root', (value) => { value.packages[''] = null }, /lock.*root/],
212
+ ['array root', (value) => { value.packages[''] = [] }, /lock.*root/],
213
+ ['array packages', (value) => { value.packages = [] }, /lock.*root/],
214
+ ...[1, 4, '3', null, 2.5].map((format) => [`format ${format}`, (value) => { value.lockfileVersion = format }, /lock.*format/]),
215
+ ['missing format', (value) => { delete value.lockfileVersion }, /lock.*format/],
216
+ ]
217
+
218
+ test('npm pre-tag validates lock identity and supported integer formats at cut, previous source and target', async (t) => {
219
+ for (const stage of ['cut', 'previous', 'target']) {
220
+ for (const [label, change, error] of invalidLocks) {
221
+ await t.test(`${stage}: ${label}`, (t) => {
222
+ const f = fixture(t, { transform: (files, current) => current === stage ? editJson(files, 'package-lock.json', change) : files })
223
+ assert.throws(f.plan, error)
224
+ })
225
+ }
226
+ }
227
+ })
228
+
229
+ test('npm pre-tag rejects stale package and VERSION identities at historical and new sources', async (t) => {
230
+ for (const stage of ['cut', 'previous', 'target']) {
231
+ for (const file of ['package.json', 'VERSION']) {
232
+ await t.test(`${stage}: ${file}`, (t) => {
233
+ const f = fixture(t, { transform: (files, current) => current !== stage ? files : file === 'VERSION'
234
+ ? { ...files, VERSION: '1.2.0\n' } : editJson(files, file, (pkg) => { pkg.version = '1.2.0' }) })
235
+ assert.throws(f.plan, /version.*does not match/)
236
+ })
237
+ }
238
+ }
239
+ })
240
+
241
+ test('npm pre-tag refuses coordinated renames at previous source or target', async (t) => {
242
+ for (const stage of ['previous', 'target']) {
243
+ await t.test(stage, (t) => {
244
+ const f = fixture(t, { transform: (files, current) => {
245
+ if (current !== stage) return files
246
+ return editJson(editJson(files, 'package.json', (pkg) => { pkg.name = 'renamed' }), 'package-lock.json', (lock) => {
247
+ lock.name = 'renamed'; lock.packages[''].name = 'renamed'
248
+ })
249
+ } })
250
+ assert.throws(f.plan, /name.*prepared identity/)
251
+ })
252
+ }
253
+ })
254
+
255
+ test('metadata-only cut excludes only version positions, never scripts, dependencies, lock edges or integrity', async (t) => {
256
+ for (const [label, file, change] of [
257
+ ['scripts', 'package.json', (pkg) => { pkg.scripts.test = 'execute-unreviewed-code' }],
258
+ ['dependencies', 'package.json', (pkg) => { pkg.dependencies.dep = '^2.0.0' }],
259
+ ['lock integrity', 'package-lock.json', (lock) => { lock.packages['node_modules/dep'].integrity = 'changed' }],
260
+ ['lock dependency', 'package-lock.json', (lock) => { lock.packages['node_modules/dep'].version = '2.0.0' }],
261
+ ['lock root edge', 'package-lock.json', (lock) => { lock.packages[''].dependencies.dep = '^2.0.0' }],
262
+ ]) {
263
+ await t.test(label, (t) => {
264
+ const f = fixture(t, { transform: (files, stage) => stage === 'cut' ? editJson(files, file, change) : files })
265
+ assert.throws(f.plan, /metadata-only: .*changes more than version identity/)
266
+ })
267
+ }
268
+ await t.test('code hidden in original cut', (t) => {
269
+ const f = fixture(t, { transform: (files, stage) => stage === 'cut' ? { ...files, 'index.js': 'unreviewed\n' } : files })
270
+ assert.throws(f.plan, /original cut is not metadata-only/)
271
+ })
272
+ })
273
+
274
+ function legacyInput(f) {
275
+ return { ...f.preparedMetadata, schema: 'prepared-release-metadata/v1', previousAttempt: {
276
+ receiptId: 'previous-rc', receiptSha256: 'a'.repeat(64),
277
+ candidateTag: `v${f.preparedMetadata.version}-rc.1`, candidateSha: f.mergeSha,
278
+ } }
279
+ }
280
+
281
+ function withNumber(files, file, source) {
282
+ return { ...files, [file]: files[file].replace(/}\s*$/, `, "config": {"threshold": ${source}}}\n`) }
283
+ }
284
+
285
+ test('pre-tag numeric identity catches underflow and fraction rounding in both original-cut JSON files; v1 stays compatible', async (t) => {
286
+ for (const file of ['package.json', 'package-lock.json']) {
287
+ for (const [label, before, after] of [['underflow', '0', '1e-400'], ['fraction rounding', '0.1', '0.10000000000000001']]) {
288
+ await t.test(`${file}: ${label}`, (t) => {
289
+ const f = fixture(t, { transform: (files, stage) => withNumber(files, file, stage === 'parent' ? before : after) })
290
+ const verify = f.unchanged()
291
+ assert.throws(f.plan, new RegExp(`metadata-only: ${file} changes more than version identity`))
292
+ const result = f.cli()
293
+ assert.equal(result.status, 1)
294
+ assert.equal(result.stdout, '')
295
+ assert.match(result.stderr, /changes more than version identity/)
296
+ assert.equal(f.plan({ preparedMetadata: legacyInput(f) }).nextVersion, version)
297
+ verify()
298
+ })
299
+ }
300
+ }
301
+ })
302
+
303
+ test('pre-tag comparison permits unchanged ordinary floats and exact decimal/exponent equivalents with whitespace and key reordering', (t) => {
304
+ const f = fixture(t, { transform: (files, stage) => {
305
+ for (const file of ['package.json', 'package-lock.json']) {
306
+ const value = JSON.parse(files[file])
307
+ files[file] = JSON.stringify(Object.fromEntries(Object.entries(value).reverse()), null, stage === 'parent' ? 2 : 4)
308
+ files = withNumber(files, file, stage === 'parent'
309
+ ? '[0.1, 1e-7, 0.10, 1.25e+2, -0.0100, 1e-400, -0, 0e99999999999999999999, 1e-9007199254740992]'
310
+ : '[0.1, 1e-7, 1e-1, 125.0, -1e-2, 10e-401, -0.0, 0, 1e-9007199254740992]')
311
+ }
312
+ return files
313
+ } })
314
+ assert.deepEqual(f.plan().artifact, { kind: 'npm', packageName: '@example/demo', version })
315
+ })
316
+
317
+ test('pre-tag numeric canonical nodes cannot be impersonated by strings, containers or prototype keys', async (t) => {
318
+ for (const file of ['package.json', 'package-lock.json']) {
319
+ for (const [before, after] of [
320
+ ['0.1', '"0.1"'], ['0.1', '["number","1","-1"]'], ['0.1', '{"data":0.1,"canonical":["number","1","-1"]}'],
321
+ ['[0.1]', '{"0":0.1}'], ['false', '0'], ['null', '0'], ['-0', '0'],
322
+ ['{"__proto__":0.1}', '{"__proto__":0.10000000000000001}'],
323
+ ['{"constructor":{"version":0.1}}', '{"constructor":{"version":0.10000000000000001}}'],
324
+ ['{"version":0.1}', '{"version":0.10000000000000001}'],
325
+ ['1e-9007199254740992', '2e-9007199254740992'],
326
+ // Outside the normalization bound, even equal decimals require identical source tokens.
327
+ ['1e-9007199254740992', '10e-9007199254740993'],
328
+ ]) {
329
+ await t.test(`${file}: ${before} -> ${after}`, (t) => {
330
+ const f = fixture(t, { transform: (files, stage) => withNumber(files, file, stage === 'parent' ? before : after) })
331
+ assert.throws(f.plan, /changes more than version identity/)
332
+ })
333
+ }
334
+ }
335
+ })
336
+
337
+ test('pre-tag rejects unsafe canonical version components in input and consistent root identities while v1 remains compatible', async (t) => {
338
+ for (const preparedVersion of ['9007199254740992.0.0', '1.9007199254740992.0', '1.3.9007199254740992']) {
339
+ await t.test(preparedVersion, (t) => {
340
+ const f = fixture(t, { preparedVersion })
341
+ assert.throws(f.plan, /version.*safe integer/)
342
+ const result = f.cli()
343
+ assert.equal(result.status, 1)
344
+ assert.equal(result.stdout, '')
345
+ assert.match(result.stderr, /version.*safe integer/)
346
+ assert.equal(f.plan({ preparedMetadata: legacyInput(f) }).nextVersion, preparedVersion)
347
+ })
348
+ }
349
+ })
350
+
351
+ test('pre-tag rejects unsafe historical parent versions at every root version position', async (t) => {
352
+ for (const position of ['package.json', 'package-lock.json', 'lock root', 'VERSION']) {
353
+ await t.test(position, (t) => {
354
+ const f = fixture(t, { transform: (files, stage) => {
355
+ if (stage !== 'parent') return files
356
+ const huge = '9007199254740992.0.0'
357
+ if (position === 'VERSION') return { ...files, VERSION: `${huge}\n` }
358
+ const file = position === 'lock root' ? 'package-lock.json' : position
359
+ return editJson(files, file, (value) => {
360
+ if (position === 'lock root') value.packages[''].version = huge
361
+ else value.version = huge
362
+ })
363
+ } })
364
+ assert.throws(f.plan, /version.*safe integer/)
365
+ assert.equal(f.plan({ preparedMetadata: legacyInput(f) }).nextVersion, version)
366
+ })
367
+ }
368
+ })
369
+
370
+ test('a valid pre-tag plan artifact passes the real npm helper input boundary using only a fake external E404', (t) => {
371
+ const f = fixture(t, { preparedVersion: '9007199254740991.3.0' })
372
+ const artifact = f.plan().artifact
373
+ const bin = join(f.cwd, '.git', 'fake-npm')
374
+ const calls = join(bin, 'calls.json')
375
+ mkdirSync(bin)
376
+ writeFileSync(join(bin, 'npm'), `#!${process.execPath}
377
+ require('node:fs').writeFileSync(${JSON.stringify(calls)}, JSON.stringify(process.argv.slice(2)))
378
+ process.stderr.write('npm error code E404\\n')
379
+ process.exit(1)
380
+ `, { mode: 0o755 })
381
+ const inherited = process.env
382
+ let result
383
+ try {
384
+ process.env = { ...f.env, PATH: bin }
385
+ result = probeNpmVersionAbsence({ packageName: artifact.packageName, version: artifact.version,
386
+ registry: 'https://registry.example.invalid/custom/', cwd: f.cwd })
387
+ assert.throws(() => probeNpmVersionAbsence({ packageName: artifact.packageName, version: '9007199254740992.0.0',
388
+ registry: 'https://registry.example.invalid/custom/', cwd: f.cwd }), /invalid arguments/)
389
+ } finally { process.env = inherited }
390
+ assert.equal(result.status, 'absent')
391
+ assert.equal(result.reason, 'version-absent')
392
+ assert.deepEqual(JSON.parse(readFileSync(calls, 'utf8')), [
393
+ 'view', '@example/demo@9007199254740991.3.0', 'version', '--registry=https://registry.example.invalid/custom/', '--json',
394
+ ])
395
+ })
396
+
397
+ test('reviewed later dependency, script, lock and code edits remain eligible with constant root identities', (t) => {
398
+ const f = fixture(t, { transform: (files, stage) => {
399
+ if (!['previous', 'target'].includes(stage)) return files
400
+ return editJson(editJson(files, 'package.json', (pkg) => {
401
+ pkg.dependencies.dep = '^2.0.0'; pkg.scripts.test = 'node --test test'
402
+ }), 'package-lock.json', (lock) => {
403
+ lock.packages[''].dependencies.dep = '^2.0.0'
404
+ lock.packages['node_modules/dep'].version = '2.0.0'
405
+ lock.packages['node_modules/dep'].integrity = 'reviewed-integrity'
406
+ })
407
+ } })
408
+ assert.equal(f.plan().releaseSourceSha, f.sha)
409
+ assert.notEqual(f.git('rev-parse', `${f.mergeSha}^{tree}`), f.git('rev-parse', `${f.sha}^{tree}`))
410
+ })
411
+
412
+ test('npm pre-tag requires a real root package and an unchanged metadata file set', async (t) => {
413
+ for (const [label, stage, transform, error] of [
414
+ ['no package', null, (files) => { const copy = { ...files }; delete copy['package.json']; return copy }, /root package.json/],
415
+ ['target new identity file', 'target', (files) => ({ ...files, 'package-lock.json': json({}) }), /file set/],
416
+ ['previous missing identity file', 'previous', (files) => { const copy = { ...files }; delete copy.VERSION; return copy }, /file set/],
417
+ ['cut missing identity file', 'cut', (files) => { const copy = { ...files }; delete copy.VERSION; return copy }, /file set/],
418
+ ]) {
419
+ await t.test(label, (t) => {
420
+ const f = fixture(t, { lock: label !== 'target new identity file', transform: (files, current) => stage === null || current === stage ? transform(files) : files })
421
+ assert.throws(f.plan, error)
422
+ })
423
+ }
424
+ })
425
+
426
+ test('strict v2 union rejects unknown, missing, null and mixed fields without plan output or writes', (t) => {
427
+ const f = fixture(t)
428
+ const p = f.preparedMetadata
429
+ const previous = p.previousAttempt
430
+ const invalid = [
431
+ [{ ...p, schema: 'prepared-release-metadata/v3' }, /schema/],
432
+ [{ ...p, extra: true }, /unknown field/],
433
+ ...[null, [], {}, { ...previous, kind: null }, { ...previous, kind: 'other' },
434
+ { ...previous, candidateTag: null }, { ...previous, candidateSha: f.mergeSha }]
435
+ .map((previousAttempt) => [{ ...p, previousAttempt }, /previousAttempt|kind/]),
436
+ ...Object.keys(previous).map((key) => {
437
+ const value = { ...previous }; delete value[key]
438
+ return [{ ...p, previousAttempt: value }, /previousAttempt|kind/]
439
+ }),
440
+ ...['kind', 'receiptId', 'receiptSha256', 'sourceSha'].map((key) => [{ ...p, previousAttempt: { ...previous, [key]: null } }, /kind|receiptId|receiptSha256|sourceSha/]),
441
+ [{ ...p, previousAttempt: { ...previous, sourceSha: 'HEAD' } }, /sourceSha.*full/],
442
+ [{ ...p, previousAttempt: { ...previous, receiptId: '../unsafe' } }, /receiptId/],
443
+ [{ ...p, previousAttempt: { ...previous, receiptSha256: 'A'.repeat(64) } }, /receiptSha256/],
444
+ [{ ...p, previousAttempt: { ...previous, kind: 'cloudRunRC' } }, /previousAttempt/],
445
+ [{ ...p, previousAttempt: { kind: 'cloudRunRC', receiptId: 'rc', receiptSha256: 'a'.repeat(64), candidateTag: null, candidateSha: f.mergeSha } }, /candidateTag/],
446
+ ]
447
+ const verify = f.unchanged()
448
+ for (const [preparedMetadata, error] of invalid) assert.throws(() => f.plan({ preparedMetadata }), error)
449
+ assert.throws(() => f.plan({ cloudRun: true }), /pre-tag.*cloudRun|pre-tag.*Cloud Run/)
450
+ const result = f.cli({ args: ['--cloud-run'] })
451
+ assert.equal(result.status, 1)
452
+ assert.equal(result.stdout, '')
453
+ assert.match(result.stderr, /pre-tag.*cloudRun|pre-tag.*Cloud Run/)
454
+ verify()
455
+ })
456
+
457
+ test('previous source must resolve to a commit on merge -> previous -> frozen target ancestry', (t) => {
458
+ const f = fixture(t)
459
+ const withSource = (sourceSha) => ({ ...f.preparedMetadata, previousAttempt: { ...f.preparedMetadata.previousAttempt, sourceSha } })
460
+ assert.throws(() => f.plan({ preparedMetadata: withSource('f'.repeat(40)) }), /failed|object|revision/i)
461
+ assert.throws(() => f.plan({ preparedMetadata: withSource(f.parentSha) }), /historical merge to previous source.*ancestor/)
462
+ assert.throws(() => f.plan({ sha: f.mergeSha }), /previous source to target.*ancestor/)
463
+ f.git('tag', '-a', 'annotated-source', '-m', 'Not a commit')
464
+ const tagObject = f.git('rev-parse', 'annotated-source')
465
+ assert.throws(() => f.plan({ preparedMetadata: withSource(tagObject) }), /must identify a commit/)
466
+ f.git('switch', '--orphan', 'unrelated')
467
+ f.git('add', '.')
468
+ f.git('commit', '--allow-empty', '-m', 'unrelated root')
469
+ const unrelated = f.git('rev-parse', 'HEAD')
470
+ assert.throws(() => f.plan({ preparedMetadata: withSource(unrelated) }), /historical merge to previous source.*ancestor/)
471
+ assert.throws(() => f.plan({ sha: unrelated }), /ancestor/)
472
+ })
473
+
474
+ test('any existing final tag spends the version, including a tag on the old source; inspection failure refuses', async (t) => {
475
+ for (const annotated of [false, true]) {
476
+ await t.test(annotated ? 'annotated' : 'lightweight', (t) => {
477
+ const f = fixture(t)
478
+ f.git('tag', ...(annotated ? ['-a', `v${version}`, f.sourceSha, '-m', 'Spent version'] : [`v${version}`, f.sourceSha]))
479
+ f.git('push', 'origin', `refs/tags/v${version}`)
480
+ const verify = f.unchanged()
481
+ const result = f.cli()
482
+ assert.equal(result.status, 1)
483
+ assert.equal(result.stdout, '')
484
+ assert.match(result.stderr, /final tag already exists.*spent/)
485
+ verify()
486
+ })
487
+ }
488
+ await t.test('remote inspection unavailable', (t) => {
489
+ const f = fixture(t)
490
+ f.git('config', '--unset', `url.${f.remote}.insteadOf`)
491
+ f.git('config', `url.${join(f.remote, 'missing')}.insteadOf`, 'https://github.com/example/demo.git')
492
+ const verify = f.unchanged()
493
+ const result = f.cli()
494
+ assert.equal(result.status, 1)
495
+ assert.equal(result.stdout, '')
496
+ assert.match(result.stderr, /remote inspection failed.*absence is unproven/)
497
+ verify()
498
+ })
499
+ })
500
+
501
+ for (const file of ['package.json', 'package-lock.json']) {
502
+ for (const stage of ['parent', 'cut', 'previous', 'target']) {
503
+ test(`strict JSON rejects invalid UTF-8 ${file} at ${stage}`, (t) => {
504
+ const f = fixture(t, { transform: (files, current) => {
505
+ const value = JSON.parse(files[file]); value.description = '\uFFFD'
506
+ const [before, after] = json(value).split('\uFFFD')
507
+ files[file] = current === stage
508
+ ? Buffer.concat([Buffer.from(before), Buffer.from([0xfe]), Buffer.from(after)])
509
+ : json(value)
510
+ return files
511
+ } })
512
+ assert.throws(f.plan, new RegExp(`${file}.*(?:UTF.?8|JSON)`))
513
+ })
514
+ }
515
+ test(`strict JSON refuses non-object, malformed, nonfinite and oversized ${file} without output leakage`, async (t) => {
516
+ for (const [label, content, error] of [
517
+ ['null', 'null', /JSON.*object/], ['array', '[]', /JSON.*object/], ['string', '"value"', /JSON.*object/],
518
+ ['malformed', '{"private-marker":', /JSON/],
519
+ ['nonfinite number', '{"private-marker":1e400}', /JSON/],
520
+ ['unsafe integer', '{"private-marker":9007199254740993}', /JSON/],
521
+ ['oversize', `{"private-marker":"${'x'.repeat(8 * 1024 * 1024)}"}`, /bounded|limit|acquisition/],
522
+ ]) {
523
+ await t.test(label, (t) => {
524
+ const f = fixture(t, { transform: (files, stage) => stage === 'target' ? { ...files, [file]: content } : files })
525
+ const result = f.cli()
526
+ assert.equal(result.status, 1)
527
+ assert.equal(result.stdout, '')
528
+ assert.match(result.stderr, new RegExp(`${file}.*(?:${error.source})`))
529
+ assert.doesNotMatch(result.stderr, /private-marker/)
530
+ })
531
+ }
532
+ })
533
+ test(`strict JSON accepts an exact 8 MiB ${file} and valid Unicode`, (t) => {
534
+ const limit = 8 * 1024 * 1024
535
+ const f = fixture(t, { transform: (files, stage) => {
536
+ if (stage !== 'target') return files
537
+ const value = JSON.parse(files[file]); value.description = 'caf\u00e9 \u6771\u4eac'
538
+ const text = json(value)
539
+ return { ...files, [file]: `${text}${' '.repeat(limit - Buffer.byteLength(text))}` }
540
+ } })
541
+ assert.equal(f.bytes('show', `${f.sha}:${file}`).length, limit)
542
+ assert.equal(f.plan().releaseSourceSha, f.sha)
543
+ })
544
+ }
545
+
546
+ test('npm metadata acquisition fails closed on Git errors and timeouts without leaking blob or process output', async (t) => {
547
+ for (const file of ['package.json', 'package-lock.json']) {
548
+ for (const [label, action] of [
549
+ ['process error', 'process.stderr.write("private-git-error"); process.exit(1)'],
550
+ ['timeout', 'setTimeout(() => process.exit(0), 30_000)'],
551
+ ]) {
552
+ await t.test(`${file}: ${label}`, (t) => {
553
+ const f = fixture(t)
554
+ const realGit = spawnSync('which', ['git'], { env: f.env, encoding: 'utf8' }).stdout.trim()
555
+ const bin = join(f.cwd, '.git', 'git-bin')
556
+ mkdirSync(bin)
557
+ // Substitute only the external Git blob read; every other Git operation remains real.
558
+ writeFileSync(join(bin, 'git'), `#!${process.execPath}
559
+ const args = process.argv.slice(2)
560
+ if (args[0] === 'show' && args[1].endsWith(${JSON.stringify(`:${file}`)})) {
561
+ ${action}
562
+ } else {
563
+ const { spawnSync } = require('node:child_process')
564
+ const result = spawnSync(${JSON.stringify(realGit)}, args, { stdio: 'inherit' })
565
+ process.exit(result.status ?? 1)
566
+ }
567
+ `, { mode: 0o755 })
568
+ const verify = f.unchanged()
569
+ const result = f.cli({ env: { ...f.env, PATH: `${bin}:${f.env.PATH}` } })
570
+ assert.equal(result.status, 1)
571
+ assert.equal(result.stdout, '')
572
+ assert.match(result.stderr, new RegExp(`${file} Git blob acquisition failed.*bounded`))
573
+ assert.doesNotMatch(result.stderr, /private-git-error/)
574
+ verify()
575
+ })
576
+ }
577
+ }
578
+ })
579
+
580
+ test('npm identity files must remain regular non-executable Git blobs', async (t) => {
581
+ for (const file of ['package.json', 'package-lock.json']) {
582
+ for (const mode of ['symlink', 'executable']) {
583
+ await t.test(`${file}: ${mode}`, (t) => {
584
+ const f = fixture(t)
585
+ if (mode === 'symlink') {
586
+ rmSync(join(f.cwd, file))
587
+ symlinkSync('VERSION', join(f.cwd, file))
588
+ f.git('add', file)
589
+ } else {
590
+ f.git('update-index', '--chmod=+x', file)
591
+ }
592
+ f.git('commit', '-m', 'chore: unsafe metadata file mode')
593
+ const sha = f.git('rev-parse', 'HEAD')
594
+ const result = f.cli({ sha })
595
+ assert.equal(result.status, 1)
596
+ assert.equal(result.stdout, '')
597
+ assert.match(result.stderr, new RegExp(`regular metadata file: ${file}`))
598
+ })
599
+ }
600
+ }
601
+ })
602
+
603
+ test('Node-only CLI tripwires forbid npm/Python and RC construction or inspection while real Git handles final absence', (t) => {
604
+ const f = fixture(t)
605
+ const realGit = spawnSync('which', ['git'], { env: f.env, encoding: 'utf8' }).stdout.trim()
606
+ const bin = join(f.cwd, '.git', 'tripwires')
607
+ const calls = join(f.cwd, '.git', 'external-calls.jsonl')
608
+ mkdirSync(bin)
609
+ for (const command of ['npm', 'npx', 'python', 'python3']) {
610
+ writeFileSync(join(bin, command), `#!${process.execPath}\nrequire('node:fs').appendFileSync(${JSON.stringify(calls)}, ${JSON.stringify(`${command}\n`)})\nprocess.exit(99)\n`, { mode: 0o755 })
611
+ }
612
+ writeFileSync(join(bin, 'git'), `#!${process.execPath}
613
+ const { spawnSync } = require('node:child_process')
614
+ const { appendFileSync } = require('node:fs')
615
+ const args = process.argv.slice(2)
616
+ appendFileSync(${JSON.stringify(calls)}, JSON.stringify(args) + '\\n')
617
+ if (args.some(arg => arg.includes('-rc.'))) process.exit(98)
618
+ const result = spawnSync(${JSON.stringify(realGit)}, args, { stdio: 'inherit' })
619
+ process.exit(result.status ?? 1)
620
+ `, { mode: 0o755 })
621
+ const verify = f.unchanged()
622
+ const result = f.cli({ env: { ...f.env, PATH: `${bin}:${f.env.PATH}` } })
623
+ assert.equal(result.status, 0, result.stderr)
624
+ assert.deepEqual(JSON.parse(result.stdout).metadata.previousAttempt, f.preparedMetadata.previousAttempt)
625
+ const commands = readFileSync(calls, 'utf8').trim().split('\n').map((line) => JSON.parse(line))
626
+ assert.deepEqual(commands.filter((args) => args[0] === 'ls-remote'), [
627
+ ['ls-remote', '--tags', 'origin', `refs/tags/v${version}`, `refs/tags/v${version}^{}`],
628
+ ])
629
+ assert.equal(commands.some((args) => ['tag', 'update-ref', 'commit', 'switch'].includes(args[0])), false)
630
+ verify()
631
+ })
632
+
633
+ test('v2 cloudRunRC preserves RC binding, ordinals and immutability, without changing v1 shape or behavior', (t) => {
634
+ const f = fixture(t)
635
+ f.git('tag', '-a', `v${version}-rc.2`, f.mergeSha, '-m', 'Previous immutable RC')
636
+ f.git('push', 'origin', `refs/tags/v${version}-rc.2`)
637
+ f.git('tag', `v${version}-rc.4`, f.sha)
638
+ f.git('push', 'origin', `refs/tags/v${version}-rc.4`)
639
+ f.git('tag', '-d', `v${version}-rc.4`)
640
+ const previous = { receiptId: 'previous-rc', receiptSha256: 'a'.repeat(64), candidateTag: `v${version}-rc.2`, candidateSha: f.mergeSha }
641
+ const v1 = { ...f.preparedMetadata, schema: 'prepared-release-metadata/v1', previousAttempt: previous }
642
+ const v2 = { ...v1, schema: 'prepared-release-metadata/v2', previousAttempt: { kind: 'cloudRunRC', ...previous } }
643
+ const verify = f.unchanged()
644
+ for (const preparedMetadata of [v1, v2]) {
645
+ const plan = f.plan({ cloudRun: true, preparedMetadata })
646
+ assert.equal(plan.candidateTag, `v${version}-rc.5`)
647
+ assert.deepEqual(plan.metadata.previousAttempt, preparedMetadata.previousAttempt)
648
+ assert.equal(Object.hasOwn(plan, 'artifact'), false)
649
+ assert.throws(() => f.plan({ cloudRun: true, preparedMetadata: { ...preparedMetadata,
650
+ previousAttempt: { ...preparedMetadata.previousAttempt, candidateSha: f.sha } } }), /candidateSha.*historical mergeSha/)
651
+ assert.throws(() => f.plan({ cloudRun: true, preparedMetadata: { ...preparedMetadata,
652
+ previousAttempt: { ...preparedMetadata.previousAttempt, candidateTag: `v${version}-rc.9007199254740992` } } }), /ordinal/)
653
+ }
654
+ assert.throws(() => f.plan({ preparedMetadata: { ...v2, previousAttempt: { ...v2.previousAttempt, sourceSha: f.sourceSha } } }), /unknown field/)
655
+ assert.throws(() => f.plan({ preparedMetadata: { ...v1, previousAttempt: v2.previousAttempt } }), /unknown field/)
656
+ verify()
657
+ f.gitAt(f.remote, 'update-ref', `refs/tags/v${version}-rc.2`, f.sha)
658
+ assert.throws(() => f.plan({ preparedMetadata: v2, cloudRun: true }), /previous candidate remote tag SHA/)
659
+ })