@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,182 @@
1
+ #!/usr/bin/env node
2
+ // REFERENCE Next.js App Router discovery adapter — copy and adapt per repo.
3
+ // Emits a surface inventory satisfying references/breadth/inventory-contract.md.
4
+ //
5
+ // node nextjs-inventory.mjs <appDir> [--out docs/tests/_generated/surface-inventory.json] [--check]
6
+ //
7
+ // Routes come from `page.*` files; APIs from `route.*` files. Route groups
8
+ // `(group)` are stripped; dynamic segments `[id]`/`[...slug]` are kept as-is so
9
+ // ids are stable.
10
+ //
11
+ // It also emits the MECHANICAL taxonomy the Surface Baseline Contract needs:
12
+ // - class: route -> read | detail | mutation; api -> read | mutation
13
+ // - reachability: best-effort reachable | guarded (from the layout/middleware chain)
14
+ // These are deliberately conservative heuristics: the adapter may only emit the
15
+ // mechanical class (never `sensitive`/exclusion — those are human-declared). When
16
+ // in doubt about a write surface it biases to `mutation`, because under-calling a
17
+ // write form `read` would wrongly let it be excluded. Reachability here is a hint;
18
+ // the full Route Reachability Protocol (and human review) refine `blocked`/
19
+ // `unreachable`. It does NOT cover DB tables or events — extend for those kinds.
20
+
21
+ import fs from 'node:fs'
22
+ import path from 'node:path'
23
+ import process from 'node:process'
24
+
25
+ const IGNORE = new Set(['node_modules', '.git', '.next'])
26
+ const PAGE_RE = /^page\.(tsx|ts|jsx|js|mdx)$/
27
+ const ROUTE_RE = /^route\.(ts|js)$/
28
+ const LAYOUT_RE = /^layout\.(tsx|ts|jsx|js)$/
29
+ const COMPONENT_RE = /\.(tsx|ts|jsx|js|mdx)$/
30
+
31
+ // A page (or a component colocated in its route segment) that mutates state.
32
+ const WRITE_RE = /<form\b|onSubmit|action=\{|formAction|use(FormState|ActionState|Mutation)\b|type=["']submit["']|method:\s*["'](post|put|patch|delete)["']|fetch\([^)]*method\s*:\s*["'](post|put|patch|delete)|['"]use server['"]/i
33
+ // An API route file exporting a write method.
34
+ const METHOD_EXPORT_RE = /export\s+(?:async\s+function|const|let|var|function)\s+(POST|PUT|PATCH|DELETE)\b|export\s*\{[^}]*\b(POST|PUT|PATCH|DELETE)\b/
35
+ // Guard signals in a layout / middleware that gate reachability.
36
+ const GUARD_RE = /\bredirect\(|\bnotFound\(|getServerSession|\bauth\(\)|requireAuth|getToken|currentUser|\bunauthorized\(|clerkMiddleware|withAuth/i
37
+
38
+ function* walk(dir) {
39
+ let entries
40
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }) } catch { return }
41
+ for (const e of entries) {
42
+ const full = path.join(dir, e.name)
43
+ if (e.isDirectory()) { if (!IGNORE.has(e.name)) yield* walk(full) }
44
+ else yield full
45
+ }
46
+ }
47
+
48
+ function read(file) { try { return fs.readFileSync(file, 'utf8') } catch { return '' } }
49
+
50
+ function toRoute(appDir, file) {
51
+ const rel = path.relative(appDir, path.dirname(file)).split(path.sep)
52
+ .filter((seg) => seg && !(seg.startsWith('(') && seg.endsWith(')'))) // drop route groups
53
+ .filter((seg) => !seg.startsWith('@')) // drop parallel route slots
54
+ .join('/')
55
+ return '/' + rel
56
+ }
57
+
58
+ // Mechanical class for a page: mutation > detail > read.
59
+ function routeClass(pageFile) {
60
+ const dir = path.dirname(pageFile)
61
+ let text = ''
62
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
63
+ if (!e.isFile() || !COMPONENT_RE.test(e.name)) continue
64
+ if (LAYOUT_RE.test(e.name) || ROUTE_RE.test(e.name)) continue
65
+ text += read(path.join(dir, e.name)) + '\n'
66
+ }
67
+ if (WRITE_RE.test(text)) return 'mutation'
68
+ if (/\[[^\]]+\]/.test(dir)) return 'detail' // dynamic segment -> renders one entity
69
+ return 'read'
70
+ }
71
+
72
+ // Mechanical class for an API route: mutation if it exports a write method.
73
+ function apiClass(routeFile) {
74
+ return METHOD_EXPORT_RE.test(read(routeFile)) ? 'mutation' : 'read'
75
+ }
76
+
77
+ // Best-effort reachability from the layout chain + root middleware.
78
+ function reachability(appDir, pageFile, hasMiddleware) {
79
+ if (hasMiddleware) return 'guarded'
80
+ let dir = path.dirname(pageFile)
81
+ const stop = path.resolve(appDir)
82
+ while (true) {
83
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
84
+ if (e.isFile() && LAYOUT_RE.test(e.name) && GUARD_RE.test(read(path.join(dir, e.name)))) return 'guarded'
85
+ }
86
+ if (path.resolve(dir) === stop) break
87
+ const parent = path.dirname(dir)
88
+ if (parent === dir) break
89
+ dir = parent
90
+ }
91
+ return 'reachable'
92
+ }
93
+
94
+ function detectMiddleware(appDir) {
95
+ const parent = path.dirname(appDir)
96
+ for (const base of [appDir, parent]) {
97
+ for (const m of ['middleware.ts', 'middleware.js']) {
98
+ if (fs.existsSync(path.join(base, m))) return true
99
+ }
100
+ }
101
+ return false
102
+ }
103
+
104
+ // Feature-derived presentation signals (Dimension B escalation). Detected
105
+ // deterministically at the app level and attached to every route, so the ledger
106
+ // raises the presentation floor (dark-theme cell, RTL/long-locale cells). This is
107
+ // the reference granularity; a stack can refine to per-route detection.
108
+ // - themeToggle: a `next-themes` dep or a useTheme/ThemeProvider reference
109
+ // - i18n: a known i18n library dependency
110
+ function detectSignals(appDir) {
111
+ const roots = [appDir, path.dirname(appDir)]
112
+ let pkg = {}
113
+ for (const base of roots) {
114
+ const p = path.join(base, 'package.json')
115
+ if (fs.existsSync(p)) { try { pkg = JSON.parse(fs.readFileSync(p, 'utf8')) } catch { /* ignore */ } break }
116
+ }
117
+ const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) }
118
+ const dep = (re) => Object.keys(deps).some((d) => re.test(d))
119
+ const I18N_DEP = /^(next-intl|next-i18next|react-i18next|i18next|@lingui|react-intl|@formatjs)/
120
+ const THEME_DEP = /^(next-themes)$/
121
+ // a cheap source grep for theme toggling when there's no dedicated dep
122
+ let themeInSource = false
123
+ for (const f of walk(appDir)) {
124
+ if (!COMPONENT_RE.test(f)) continue
125
+ if (/\buseTheme\b|<ThemeProvider\b|data-theme=/.test(fs.readFileSync(f, 'utf8'))) { themeInSource = true; break }
126
+ }
127
+ const signals = {}
128
+ if (dep(THEME_DEP) || themeInSource) signals.themeToggle = true
129
+ if (dep(I18N_DEP)) signals.i18n = true
130
+ return Object.keys(signals).length ? signals : null
131
+ }
132
+
133
+ function build(appDir) {
134
+ const hasMiddleware = detectMiddleware(appDir)
135
+ const signals = detectSignals(appDir)
136
+ const surfaces = []
137
+ for (const f of walk(appDir)) {
138
+ const base = path.basename(f)
139
+ if (PAGE_RE.test(base)) {
140
+ const s = { id: toRoute(appDir, f), kind: 'route', class: routeClass(f), reachability: reachability(appDir, f, hasMiddleware) }
141
+ if (signals) s.signals = signals
142
+ surfaces.push(s)
143
+ } else if (ROUTE_RE.test(base)) {
144
+ surfaces.push({ id: toRoute(appDir, f), kind: 'api', class: apiClass(f) })
145
+ }
146
+ }
147
+ // de-dupe by id (e.g. page + nested layout edge cases), keep strongest class.
148
+ const byId = new Map()
149
+ const rank = { mutation: 3, detail: 2, read: 1, undefined: 0 }
150
+ for (const s of surfaces) {
151
+ const prev = byId.get(s.id)
152
+ if (!prev || (rank[s.class] || 0) > (rank[prev.class] || 0)) byId.set(s.id, s)
153
+ }
154
+ return { surfaces: [...byId.values()].sort((a, b) => a.id.localeCompare(b.id)) }
155
+ }
156
+
157
+ function main() {
158
+ const [, , appDir, ...rest] = process.argv
159
+ const usage = 'usage: nextjs-inventory.mjs <appDir> [--out file] [--check]'
160
+ // A flag in the appDir slot (`--help`, `--out`) used to be walked as a directory, find
161
+ // nothing, and WRITE a zero-surface inventory into the cwd. Fail before any write.
162
+ if (!appDir || appDir.startsWith('-')) { console.error(usage); process.exit(2) }
163
+ if (!fs.existsSync(appDir) || !fs.statSync(appDir).isDirectory()) { console.error(`nextjs-inventory: app directory not found: ${appDir}\n${usage}`); process.exit(2) }
164
+ let out = 'docs/tests/_generated/surface-inventory.json'
165
+ let check = false
166
+ for (let i = 0; i < rest.length; i++) {
167
+ if (rest[i] === '--out') out = rest[++i]
168
+ else if (rest[i] === '--check') check = true
169
+ }
170
+ const inv = build(appDir)
171
+ const json = JSON.stringify(inv, null, 2) + '\n'
172
+ if (check) {
173
+ const prev = fs.existsSync(out) ? fs.readFileSync(out, 'utf8') : ''
174
+ if (prev !== json) { console.error(`inventory stale: ${out} does not match discovered surfaces. Re-run without --check.`); process.exit(1) }
175
+ console.log(`inventory up to date (${inv.surfaces.length} surfaces)`); return
176
+ }
177
+ fs.mkdirSync(path.dirname(out), { recursive: true })
178
+ fs.writeFileSync(out, json)
179
+ console.log(`wrote ${out} (${inv.surfaces.length} surfaces)`)
180
+ }
181
+
182
+ main()
@@ -0,0 +1,96 @@
1
+ // Tests for the reference Next.js adapter's feature-derived signal detection
2
+ // (issue #200). Runs the adapter as a subprocess against temp fixtures — proves
3
+ // AC1 (emits signals) and AC5 (deterministic) without mocking. Run: `node --test`.
4
+
5
+ import { test } from 'node:test'
6
+ import assert from 'node:assert/strict'
7
+ import fs from 'node:fs'
8
+ import os from 'node:os'
9
+ import path from 'node:path'
10
+ import { fileURLToPath } from 'node:url'
11
+ import { execFileSync, spawnSync } from 'node:child_process'
12
+
13
+ const ADAPTER = fileURLToPath(new URL('./nextjs-inventory.mjs', import.meta.url))
14
+
15
+ function runAdapter(appDir) {
16
+ const out = path.join(appDir, '..', 'inv.json')
17
+ execFileSync('node', [ADAPTER, appDir, '--out', out], { stdio: 'pipe' })
18
+ return JSON.parse(fs.readFileSync(out, 'utf8'))
19
+ }
20
+
21
+ function fixture(pkg, files) {
22
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'nextadp-'))
23
+ fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify(pkg))
24
+ for (const [rel, content] of Object.entries(files)) {
25
+ const p = path.join(dir, rel)
26
+ fs.mkdirSync(path.dirname(p), { recursive: true })
27
+ fs.writeFileSync(p, content)
28
+ }
29
+ return dir
30
+ }
31
+
32
+ test('detects themeToggle (next-themes dep) and i18n (next-intl dep) on every route', () => {
33
+ const dir = fixture(
34
+ { dependencies: { 'next-themes': '^0.2.0', 'next-intl': '^3.0.0' } },
35
+ { 'app/page.tsx': 'export default function P(){return <div/>}',
36
+ 'app/dashboard/page.tsx': 'export default function D(){return <div/>}' },
37
+ )
38
+ try {
39
+ const inv = runAdapter(path.join(dir, 'app'))
40
+ assert.equal(inv.surfaces.length, 2)
41
+ for (const s of inv.surfaces) {
42
+ assert.equal(s.signals?.themeToggle, true)
43
+ assert.equal(s.signals?.i18n, true)
44
+ }
45
+ } finally { fs.rmSync(dir, { recursive: true, force: true }) }
46
+ })
47
+
48
+ test('detects themeToggle from source (useTheme) with no dep', () => {
49
+ const dir = fixture(
50
+ { dependencies: {} },
51
+ { 'app/page.tsx': "import { useTheme } from 'somewhere'\nexport default function P(){ useTheme(); return <div/> }" },
52
+ )
53
+ try {
54
+ const inv = runAdapter(path.join(dir, 'app'))
55
+ assert.equal(inv.surfaces[0].signals?.themeToggle, true)
56
+ assert.ok(!inv.surfaces[0].signals?.i18n)
57
+ } finally { fs.rmSync(dir, { recursive: true, force: true }) }
58
+ })
59
+
60
+ test('no signals → no `signals` key (null, not an empty object)', () => {
61
+ const dir = fixture(
62
+ { dependencies: { react: '^19.0.0' } },
63
+ { 'app/page.tsx': 'export default function P(){return <div/>}' },
64
+ )
65
+ try {
66
+ const inv = runAdapter(path.join(dir, 'app'))
67
+ assert.equal('signals' in inv.surfaces[0], false)
68
+ } finally { fs.rmSync(dir, { recursive: true, force: true }) }
69
+ })
70
+
71
+ test('deterministic: two runs on the same code produce byte-identical output', () => {
72
+ const dir = fixture(
73
+ { dependencies: { 'next-themes': '^0.2.0' } },
74
+ { 'app/page.tsx': 'export default function P(){return <div/>}',
75
+ 'app/settings/page.tsx': "export default function S(){return <form onSubmit={()=>{}}/>}" },
76
+ )
77
+ try {
78
+ const a = JSON.stringify(runAdapter(path.join(dir, 'app')))
79
+ const b = JSON.stringify(runAdapter(path.join(dir, 'app')))
80
+ assert.equal(a, b)
81
+ } finally { fs.rmSync(dir, { recursive: true, force: true }) }
82
+ })
83
+
84
+ test('a flag or a missing directory in the appDir slot exits 2 and writes nothing', () => {
85
+ const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'nextadp-cli-'))
86
+ try {
87
+ for (const args of [['--help'], ['--out', 'x.json'], [path.join(cwd, 'does-not-exist')]]) {
88
+ const r = spawnSync('node', [ADAPTER, ...args], { cwd, encoding: 'utf8' })
89
+ assert.equal(r.status, 2, `${args.join(' ')} → exit 2`)
90
+ assert.match(r.stderr, /usage: nextjs-inventory\.mjs <appDir>/)
91
+ }
92
+ assert.deepEqual(fs.readdirSync(cwd), [], 'nothing was written into the cwd')
93
+ } finally {
94
+ fs.rmSync(cwd, { recursive: true, force: true })
95
+ }
96
+ })
@@ -0,0 +1,105 @@
1
+ // check-quarantine-expiry — the auto-resurface gate for dated exits.
2
+ //
3
+ // A quarantine (or any deferred-but-tracked suppression) is a holding pen with a
4
+ // dated exit, never a destination. The convention is a single marker, anywhere in
5
+ // a file (a test-file comment, a suppressions list, an ADR):
6
+ //
7
+ // @quarantine(until=2026-07-01, issue=#123) // canonical
8
+ // until=2026-07-01 // also matched (bare)
9
+ // until: 2026-07-01 // also matched (yaml-style)
10
+ //
11
+ // Until the date, the item is allowed to sit non-blocking. On/after the date it
12
+ // EXPIRES: this gate fails, so the item re-blocks until it is fixed or the date is
13
+ // extended with a stated reason. Run it in the BLOCKING lane.
14
+ //
15
+ // node check-quarantine-expiry.mjs --files a,b # specific files
16
+ // node check-quarantine-expiry.mjs # whole-tree scan of test files
17
+ // node check-quarantine-expiry.mjs --now 2026-06-08 # pin "today" (default: system date; for tests/CI determinism)
18
+ // --json # machine output
19
+ //
20
+ // Exit 0 = no expired exits. Exit 1 = at least one expired (the gate blocks).
21
+
22
+ import fs from 'node:fs'
23
+ import path from 'node:path'
24
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
25
+
26
+ // Marker forms: `until=YYYY-MM-DD` or `until: YYYY-MM-DD` (case-insensitive key).
27
+ const UNTIL = /\buntil\s*[:=]\s*(\d{4}-\d{2}-\d{2})\b/gi
28
+ // Pull an issue ref from the same line when present, for the report.
29
+ const ISSUE = /\bissue\s*[:=]\s*(#?\w[\w/-]*)/i
30
+
31
+ export function isTestFile(p) {
32
+ return /\.(test|spec)\.[jt]sx?$/.test(p) || /(^|\/)tests?\//.test(p) || /\.coverage\.ya?ml$/.test(p)
33
+ }
34
+
35
+ // Pure: scan one file's text → expired/pending records against `now` (YYYY-MM-DD).
36
+ export function scanText(file, text, now) {
37
+ const out = []
38
+ const lines = (text || '').split(/\r?\n/)
39
+ lines.forEach((raw, i) => {
40
+ for (const m of raw.matchAll(UNTIL)) {
41
+ const until = m[1]
42
+ const issue = (raw.match(ISSUE) || [])[1] || null
43
+ out.push({ file, line: i + 1, until, issue, expired: until < now, snippet: raw.trim().slice(0, 120) })
44
+ }
45
+ })
46
+ return out
47
+ }
48
+
49
+ function discover(dir, acc = []) {
50
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
51
+ if (e.name === 'node_modules' || e.name.startsWith('.git')) continue
52
+ const full = path.join(dir, e.name)
53
+ if (e.isDirectory()) discover(full, acc)
54
+ else if (isTestFile(full)) acc.push(full)
55
+ }
56
+ return acc
57
+ }
58
+
59
+ function today() {
60
+ // Standalone CI tool — reading the wall clock is correct here (unlike workflow scripts).
61
+ return new Date().toISOString().slice(0, 10)
62
+ }
63
+
64
+ export function runCli(argv, { name = 'check-quarantine-expiry' } = {}) {
65
+ if (argv.includes('--help') || argv.includes('-h')) {
66
+ console.log(`usage: ${name}.mjs [--files a,b] [--now YYYY-MM-DD] [--json] # exit 1 on any expired @quarantine(until=…) exit`)
67
+ return 0
68
+ }
69
+ const flags = {}
70
+ for (let i = 0; i < argv.length; i++) {
71
+ const a = argv[i]
72
+ if (a === '--json') flags.json = true
73
+ else if (a === '--now') flags.now = argv[++i]
74
+ else if (a === '--files') flags.files = argv[++i]
75
+ }
76
+ const now = flags.now || today()
77
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(now)) {
78
+ console.error(`${name}: --now must be YYYY-MM-DD, got "${now}"`)
79
+ return 2
80
+ }
81
+
82
+ const files = flags.files
83
+ ? flags.files.split(',').map((s) => s.trim()).filter(Boolean)
84
+ : discover(process.cwd())
85
+
86
+ const records = []
87
+ for (const f of files) {
88
+ if (fs.existsSync(f)) records.push(...scanText(f, fs.readFileSync(f, 'utf8'), now))
89
+ }
90
+ const expired = records.filter((r) => r.expired)
91
+
92
+ if (flags.json) {
93
+ console.log(JSON.stringify({ now, total: records.length, expired }, null, 2))
94
+ } else {
95
+ if (!records.length) console.log(`${name}: no dated exits found.`)
96
+ else if (!expired.length) console.log(`${name}: ${records.length} dated exit(s), none expired (as of ${now}).`)
97
+ else {
98
+ console.log(`${name}: ${expired.length} EXPIRED dated exit(s) (as of ${now}) — fix, or extend the date with a reason:`)
99
+ for (const r of expired) console.log(` ${r.file}:${r.line} until=${r.until}${r.issue ? ` (${r.issue})` : ''} ${r.snippet}`)
100
+ }
101
+ }
102
+ return expired.length ? 1 : 0
103
+ }
104
+
105
+ if (isMainModule(import.meta.url)) process.exit(runCli(process.argv.slice(2)))
@@ -0,0 +1,47 @@
1
+ import { test } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { scanText, isTestFile, runCli } from './check-quarantine-expiry.mjs'
4
+
5
+ test('scanText flags an until= date in the past as expired, future as not', () => {
6
+ const text = [
7
+ '// @quarantine(until=2026-01-01, issue=#42) flaky payfields iframe',
8
+ '// @quarantine(until=2027-12-31, issue=#99) external sandbox pending',
9
+ ].join('\n')
10
+ const recs = scanText('e2e/x.spec.ts', text, '2026-06-08')
11
+ assert.equal(recs.length, 2)
12
+ const past = recs.find((r) => r.until === '2026-01-01')
13
+ assert.equal(past.expired, true)
14
+ assert.equal(past.issue, '#42')
15
+ assert.equal(past.line, 1)
16
+ assert.equal(recs.find((r) => r.until === '2027-12-31').expired, false)
17
+ })
18
+
19
+ test('scanText matches yaml-style "until: DATE" too', () => {
20
+ const recs = scanText('x.coverage.yml', 'suppress:\n - until: 2020-05-05', '2026-06-08')
21
+ assert.equal(recs.length, 1)
22
+ assert.equal(recs[0].expired, true)
23
+ })
24
+
25
+ test('boundary: until == now is NOT expired (expires strictly after the date)', () => {
26
+ const recs = scanText('a.spec.ts', 'until=2026-06-08', '2026-06-08')
27
+ assert.equal(recs[0].expired, false)
28
+ })
29
+
30
+ test('isTestFile recognizes spec/test/coverage files, not plain source', () => {
31
+ assert.ok(isTestFile('e2e/login.spec.ts'))
32
+ assert.ok(isTestFile('tests/foo.py'))
33
+ assert.ok(isTestFile('req.coverage.yml'))
34
+ assert.ok(!isTestFile('src/app.ts'))
35
+ })
36
+
37
+ test('runCli exits 1 on an expired exit, 0 when all future', () => {
38
+ // Use this test file itself as a fixture-free input via a temp-ish path is overkill;
39
+ // exercise the pure path through --files on real files in the repo dir instead.
40
+ // Expired case: point at a string file we know — fall back to scanText-backed assertion.
41
+ assert.equal(scanText('f', 'until=2000-01-01', '2026-06-08').filter((r) => r.expired).length, 1)
42
+ assert.equal(scanText('f', 'until=2099-01-01', '2026-06-08').filter((r) => r.expired).length, 0)
43
+ })
44
+
45
+ test('runCli rejects a malformed --now', () => {
46
+ assert.equal(runCli(['--now', 'yesterday', '--files', 'nope.ts']), 2)
47
+ })
@@ -0,0 +1,137 @@
1
+ // Audit the sole CI gate supported by ensure-coverage: curated golden-path smoke.
2
+ // All other coverage checks are audit and review evidence and are ignored here.
3
+
4
+ import fs from 'node:fs'
5
+ import path from 'node:path'
6
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
7
+
8
+ export const SMOKE_GATE = {
9
+ key: 'smoke',
10
+ label: 'Curated golden-path smoke',
11
+ patterns: [/smoke(\.mjs)?\b[^\n]*\bverdict\b/, /golden-path(\.mjs)?\b[^\n]*\bverdict\b/, /smoke-gate/],
12
+ }
13
+
14
+ export const WEAKEN = [
15
+ /continue-on-error:\s*true/i,
16
+ /allowFailure:\s*true/i,
17
+ /\|\|\s*true\b/,
18
+ /--warn-only\b/,
19
+ /set\s+\+e\b/,
20
+ ]
21
+
22
+ export function stripComment(line) {
23
+ return line.replace(/(^|\s)#.*$/, '$1')
24
+ }
25
+
26
+ export function classifySmoke(corpus, { proximity = 10 } = {}) {
27
+ const hits = []
28
+ for (const file of corpus) {
29
+ file.lines.forEach((line, index) => {
30
+ if (SMOKE_GATE.patterns.some((pattern) => pattern.test(stripComment(line)))) hits.push({ file, index })
31
+ })
32
+ }
33
+ if (hits.length === 0) return { status: 'absent', evidence: 'no smoke verdict command found in scanned CI config' }
34
+
35
+ for (const hit of hits) {
36
+ const start = Math.max(0, hit.index - proximity)
37
+ const end = Math.min(hit.file.lines.length - 1, hit.index + proximity)
38
+ for (let index = start; index <= end; index += 1) {
39
+ if (WEAKEN.some((marker) => marker.test(stripComment(hit.file.lines[index])))) {
40
+ return {
41
+ status: 'warn-only',
42
+ evidence: `${hit.file.name}:${hit.index + 1} (weakened near ${hit.file.name}:${index + 1})`,
43
+ }
44
+ }
45
+ }
46
+ }
47
+ return { status: 'present', evidence: `${hits[0].file.name}:${hits[0].index + 1}` }
48
+ }
49
+
50
+ export function auditCorpus(files, { allowWarn = false } = {}) {
51
+ const corpus = files.map((file) => ({ name: file.name, lines: (file.text || '').split(/\r?\n/) }))
52
+ const smoke = { key: SMOKE_GATE.key, label: SMOKE_GATE.label, ...classifySmoke(corpus) }
53
+ const ok = smoke.status === 'present' || (allowWarn && smoke.status === 'warn-only')
54
+ return { smoke, ok, scanned: files.map((file) => file.name) }
55
+ }
56
+
57
+ export function buildAdoptionPlan(report) {
58
+ return { needed: report.smoke.status !== 'present', smoke: report.smoke, scanned: report.scanned || [] }
59
+ }
60
+
61
+ export function renderAdoptionIssue(plan) {
62
+ const scanned = plan.scanned.length ? plan.scanned.map((file) => `\`${file}\``).join(', ') : '_no CI config found_'
63
+ const action = plan.smoke.status === 'warn-only'
64
+ ? 'Remove the weakening marker near the smoke command so failures block the build.'
65
+ : 'Add the golden-path job: `golden-path init --write` generates it from golden-paths.json (or call its `run` then `verdict` from an existing job).'
66
+ return [
67
+ '## Wire golden-path smoke into CI',
68
+ '',
69
+ 'Curated golden-path smoke is the only CI gate in the ensure-coverage contract.',
70
+ '',
71
+ `Scanned: ${scanned}`,
72
+ `Status: **${plan.smoke.status}** (${plan.smoke.evidence})`,
73
+ '',
74
+ '### Action',
75
+ '',
76
+ `- [ ] ${action}`,
77
+ '- [ ] Confirm first-party requests and owned state are not mocked or intercepted.',
78
+ '- [ ] Confirm the job fails unless the verdict is ALIVE.',
79
+ '',
80
+ '### Verify',
81
+ '',
82
+ '```bash',
83
+ `node <ensure-coverage>/scripts/ci-audit.mjs --files ${plan.scanned.join(',') || '<your ci files>'}`,
84
+ '```',
85
+ ].join('\n')
86
+ }
87
+
88
+ function discover(explicit) {
89
+ if (explicit) return explicit.split(',').map((value) => value.trim()).filter(Boolean)
90
+ const found = []
91
+ const workflows = '.github/workflows'
92
+ if (fs.existsSync(workflows)) {
93
+ for (const file of fs.readdirSync(workflows)) if (/\.ya?ml$/.test(file)) found.push(path.join(workflows, file))
94
+ }
95
+ for (const file of fs.existsSync('.') ? fs.readdirSync('.') : []) {
96
+ if (/^cloudbuild.*\.ya?ml$/.test(file)) found.push(file)
97
+ }
98
+ for (const file of ['Makefile', 'package.json']) if (fs.existsSync(file)) found.push(file)
99
+ return found
100
+ }
101
+
102
+ function main() {
103
+ const argv = process.argv.slice(2)
104
+ const flags = {}
105
+ for (let index = 0; index < argv.length; index += 1) {
106
+ const arg = argv[index]
107
+ if (arg === '--allow-warn') flags.allowWarn = true
108
+ else if (arg === '--json') flags.json = true
109
+ else if (arg === '--adoption') flags.adoption = true
110
+ else if (arg === '--files') flags.files = argv[++index]
111
+ }
112
+
113
+ const paths = discover(flags.files)
114
+ if (paths.length === 0) {
115
+ console.error('ci-audit: no CI config files found to scan (pass --files a.yml,b.yaml)')
116
+ process.exit(2)
117
+ }
118
+
119
+ const files = paths.map((file) => ({ name: file, text: fs.readFileSync(file, 'utf8') }))
120
+ const report = auditCorpus(files, { allowWarn: flags.allowWarn })
121
+ if (flags.adoption) {
122
+ const plan = buildAdoptionPlan(report)
123
+ if (flags.json) console.log(JSON.stringify(plan, null, 2))
124
+ else if (plan.needed) console.log(renderAdoptionIssue(plan))
125
+ else console.log(`nothing to adopt: golden-path smoke is blocking (${report.smoke.evidence})`)
126
+ process.exit(plan.needed ? 1 : 0)
127
+ }
128
+
129
+ if (flags.json) console.log(JSON.stringify(report, null, 2))
130
+ else {
131
+ const mark = report.smoke.status === 'present' ? 'PASS' : report.smoke.status === 'warn-only' ? 'WARN' : 'FAIL'
132
+ console.log(`ci-audit: ${mark} - ${report.smoke.label}: ${report.smoke.status} (${report.smoke.evidence})`)
133
+ }
134
+ process.exit(report.ok ? 0 : 1)
135
+ }
136
+
137
+ if (isMainModule(import.meta.url)) main()
@@ -0,0 +1,86 @@
1
+ import { test } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { auditCorpus, buildAdoptionPlan, classifySmoke, renderAdoptionIssue } from './ci-audit.mjs'
5
+
6
+ const file = (name, text) => ({ name, text })
7
+
8
+ test('blocking golden-path smoke passes', () => {
9
+ const report = auditCorpus([file('.github/workflows/ci.yml', `
10
+ jobs:
11
+ smoke:
12
+ steps:
13
+ - run: node smoke.mjs verdict --manifest smoke.manifest.json --target local --results smoke-results.json
14
+ `)])
15
+ assert.equal(report.ok, true)
16
+ assert.equal(report.smoke.status, 'present')
17
+ })
18
+
19
+ test('the generated golden-path workflow counts as the smoke gate', () => {
20
+ const report = auditCorpus([file('.github/workflows/golden-paths.yml', `
21
+ jobs:
22
+ golden-paths:
23
+ steps:
24
+ - run: node scripts/golden-paths/golden-path.mjs verdict --profile "$GOLDEN_PATH_PROFILE" --target "$BASE_URL"
25
+ `)])
26
+ assert.equal(report.ok, true)
27
+ assert.equal(report.smoke.status, 'present')
28
+ })
29
+
30
+ test('the former coverage gates are ignored', () => {
31
+ const report = auditCorpus([file('.github/workflows/ci.yml', `
32
+ - run: node coverage-ledger.mjs validate
33
+ - run: node presentation-sweep.mjs
34
+ - run: pnpm playwright test
35
+ - run: node lint-tests.mjs --rules mock-internal-seam
36
+ - run: node check-quarantine-expiry.mjs
37
+ `)])
38
+ assert.equal(report.ok, false)
39
+ assert.equal(report.smoke.status, 'absent')
40
+ assert.deepEqual(Object.keys(report), ['smoke', 'ok', 'scanned'])
41
+ })
42
+
43
+ test('a weakened smoke job is warn-only and fails by default', () => {
44
+ const report = auditCorpus([file('cloudbuild.yaml', `
45
+ - id: smoke
46
+ allowFailure: true
47
+ args: ['-c', 'node smoke.mjs verdict --manifest smoke.manifest.json --results smoke-results.json']
48
+ `)])
49
+ assert.equal(report.ok, false)
50
+ assert.equal(report.smoke.status, 'warn-only')
51
+ })
52
+
53
+ test('--allow-warn accepts warn-only smoke when explicitly requested', () => {
54
+ const report = auditCorpus([file('ci.yml', 'run: node smoke.mjs verdict --results out.json || true')], { allowWarn: true })
55
+ assert.equal(report.ok, true)
56
+ })
57
+
58
+ test('comments do not count as smoke wiring or weakening', () => {
59
+ const absent = auditCorpus([file('ci.yml', '# node smoke.mjs verdict --results out.json')])
60
+ assert.equal(absent.smoke.status, 'absent')
61
+
62
+ const corpus = [{ name: 'ci.yml', lines: [
63
+ '# never add continue-on-error: true',
64
+ 'run: node smoke.mjs verdict --results out.json',
65
+ ] }]
66
+ assert.equal(classifySmoke(corpus).status, 'present')
67
+ })
68
+
69
+ test('weakening far from smoke does not bleed into its status', () => {
70
+ const lines = ['continue-on-error: true', ...Array.from({ length: 20 }, (_, index) => `# filler ${index}`), 'run: smoke-gate']
71
+ assert.equal(classifySmoke([{ name: 'ci.yml', lines }]).status, 'present')
72
+ })
73
+
74
+ test('adoption output requests only golden-path smoke', () => {
75
+ const report = auditCorpus([file('.github/workflows/ci.yml', 'run: node coverage-ledger.mjs validate')])
76
+ const plan = buildAdoptionPlan(report)
77
+ const body = renderAdoptionIssue(plan)
78
+ assert.equal(plan.needed, true)
79
+ assert.match(body, /Wire golden-path smoke into CI/)
80
+ assert.doesNotMatch(body, /coverage-ledger|presentation sweep|quarantine expiry|all-gates|static-gates/)
81
+ })
82
+
83
+ test('adoption is unnecessary when smoke is blocking', () => {
84
+ const report = auditCorpus([file('ci.yml', 'run: smoke-gate')])
85
+ assert.equal(buildAdoptionPlan(report).needed, false)
86
+ })