@soleur/opencode 0.0.0-stage → 3.354.2

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 (832) hide show
  1. package/.claude-plugin/agents.manifest.json +476 -0
  2. package/.claude-plugin/plugin.json +42 -0
  3. package/README.md +44 -2
  4. package/agents/community/.gitkeep +0 -0
  5. package/agents/engineering/cto.md +87 -0
  6. package/agents/engineering/design/ddd-architect.md +95 -0
  7. package/agents/engineering/discovery/agent-finder.md +214 -0
  8. package/agents/engineering/discovery/functional-discovery.md +182 -0
  9. package/agents/engineering/infra/infra-security.md +151 -0
  10. package/agents/engineering/infra/platform-strategist.md +109 -0
  11. package/agents/engineering/infra/terraform-architect.md +171 -0
  12. package/agents/engineering/prompt-engineer.md +37 -0
  13. package/agents/engineering/research/best-practices-researcher.md +115 -0
  14. package/agents/engineering/research/framework-docs-researcher.md +93 -0
  15. package/agents/engineering/research/git-history-analyzer.md +53 -0
  16. package/agents/engineering/research/learnings-researcher.md +285 -0
  17. package/agents/engineering/research/repo-research-analyst.md +118 -0
  18. package/agents/engineering/review/agent-native-reviewer.md +279 -0
  19. package/agents/engineering/review/architecture-strategist.md +61 -0
  20. package/agents/engineering/review/code-quality-analyst.md +92 -0
  21. package/agents/engineering/review/code-simplicity-reviewer.md +109 -0
  22. package/agents/engineering/review/data-integrity-guardian.md +82 -0
  23. package/agents/engineering/review/data-migration-expert.md +98 -0
  24. package/agents/engineering/review/deployment-verification-agent.md +183 -0
  25. package/agents/engineering/review/dhh-rails-reviewer.md +46 -0
  26. package/agents/engineering/review/kieran-rails-reviewer.md +87 -0
  27. package/agents/engineering/review/legacy-code-expert.md +55 -0
  28. package/agents/engineering/review/observability-coverage-reviewer.md +147 -0
  29. package/agents/engineering/review/pattern-recognition-specialist.md +59 -0
  30. package/agents/engineering/review/performance-oracle.md +130 -0
  31. package/agents/engineering/review/security-sentinel.md +167 -0
  32. package/agents/engineering/review/semgrep-sast.md +36 -0
  33. package/agents/engineering/review/test-design-reviewer.md +150 -0
  34. package/agents/engineering/review/user-impact-reviewer.md +70 -0
  35. package/agents/engineering/workflow/pr-comment-resolver.md +69 -0
  36. package/agents/finance/budget-analyst.md +29 -0
  37. package/agents/finance/cfo.md +44 -0
  38. package/agents/finance/financial-reporter.md +30 -0
  39. package/agents/finance/revenue-analyst.md +30 -0
  40. package/agents/legal/clo.md +115 -0
  41. package/agents/legal/legal-compliance-auditor.md +110 -0
  42. package/agents/legal/legal-document-generator.md +134 -0
  43. package/agents/marketing/analytics-analyst.md +25 -0
  44. package/agents/marketing/brand-architect.md +181 -0
  45. package/agents/marketing/cmo.md +76 -0
  46. package/agents/marketing/conversion-optimizer.md +19 -0
  47. package/agents/marketing/copywriter.md +20 -0
  48. package/agents/marketing/fact-checker.md +70 -0
  49. package/agents/marketing/growth-strategist.md +145 -0
  50. package/agents/marketing/paid-media-strategist.md +28 -0
  51. package/agents/marketing/pricing-strategist.md +17 -0
  52. package/agents/marketing/programmatic-seo-specialist.md +25 -0
  53. package/agents/marketing/retention-strategist.md +23 -0
  54. package/agents/marketing/seo-aeo-analyst.md +164 -0
  55. package/agents/operations/coo.md +50 -0
  56. package/agents/operations/ops-advisor.md +78 -0
  57. package/agents/operations/ops-provisioner.md +101 -0
  58. package/agents/operations/ops-research.md +52 -0
  59. package/agents/operations/service-automator.md +278 -0
  60. package/agents/product/business-validator.md +206 -0
  61. package/agents/product/competitive-intelligence.md +89 -0
  62. package/agents/product/cpo.md +63 -0
  63. package/agents/product/design/ux-design-lead.md +209 -0
  64. package/agents/product/spec-flow-analyzer.md +122 -0
  65. package/agents/sales/cro.md +44 -0
  66. package/agents/sales/deal-architect.md +29 -0
  67. package/agents/sales/outbound-strategist.md +29 -0
  68. package/agents/sales/pipeline-analyst.md +29 -0
  69. package/agents/support/cco.md +48 -0
  70. package/agents/support/community-manager.md +570 -0
  71. package/agents/support/ticket-triage.md +70 -0
  72. package/bin/soleur-opencode.js +29 -0
  73. package/commands/go.md +660 -0
  74. package/commands/help.md +273 -0
  75. package/commands/sync.md +977 -0
  76. package/commands/version.md +103 -0
  77. package/hooks/antigravity-hooks.json +84 -0
  78. package/hooks/antigravity-session-start.sh +15 -0
  79. package/hooks/bare-root-cwd-guard.sh +131 -0
  80. package/hooks/browser-snapshot-credential-guard.sh +200 -0
  81. package/hooks/codex-session-start.sh +9 -0
  82. package/hooks/compaction-state.sh +525 -0
  83. package/hooks/destructive-command-guard.sh +1387 -0
  84. package/hooks/devin-session-start.sh +90 -0
  85. package/hooks/ext-filter-detect.sh +171 -0
  86. package/hooks/hooks.json +133 -0
  87. package/hooks/lib/hook-tool-kind.sh +24 -0
  88. package/hooks/lib/log-rotation.sh +176 -0
  89. package/hooks/lib/shell-argv.pl +576 -0
  90. package/hooks/memory-backstop.sh +1114 -0
  91. package/hooks/operator-stage-approval.sh +391 -0
  92. package/hooks/stop-hook.sh +367 -0
  93. package/hooks/unkept-promise-hook.sh +383 -0
  94. package/hooks/version-banner.sh +127 -0
  95. package/hooks/welcome-hook.sh +50 -0
  96. package/install.js +29 -0
  97. package/lib/agent-registry.ts +154 -0
  98. package/lib/c4-canonical-cli.mjs +34 -0
  99. package/lib/c4-canonical.mjs +46 -0
  100. package/lib/c4-from-components.ts +554 -0
  101. package/lib/go-routing.ts +81 -0
  102. package/lib/grok-inspect-contract.ts +311 -0
  103. package/lib/harness-model-map.ts +101 -0
  104. package/lib/harness-parity.ts +726 -0
  105. package/lib/harness-tool-map.ts +180 -0
  106. package/lib/harness.ts +716 -0
  107. package/lib/heartbeat-live-reconcile.ts +1153 -0
  108. package/lib/heartbeat-manifest.ts +361 -0
  109. package/lib/kb-coverage.ts +252 -0
  110. package/lib/pr-merge-poll.ts +103 -0
  111. package/lib/workflow-fidelity.ts +388 -0
  112. package/opencode/INSTRUCTIONS.md +171 -0
  113. package/opencode/agents/engineering/cto.md +10 -0
  114. package/opencode/agents/engineering/design/ddd-architect.md +10 -0
  115. package/opencode/agents/engineering/discovery/agent-finder.md +10 -0
  116. package/opencode/agents/engineering/discovery/functional-discovery.md +10 -0
  117. package/opencode/agents/engineering/infra/infra-security.md +10 -0
  118. package/opencode/agents/engineering/infra/platform-strategist.md +10 -0
  119. package/opencode/agents/engineering/infra/terraform-architect.md +10 -0
  120. package/opencode/agents/engineering/prompt-engineer.md +10 -0
  121. package/opencode/agents/engineering/research/best-practices-researcher.md +10 -0
  122. package/opencode/agents/engineering/research/framework-docs-researcher.md +10 -0
  123. package/opencode/agents/engineering/research/git-history-analyzer.md +10 -0
  124. package/opencode/agents/engineering/research/learnings-researcher.md +10 -0
  125. package/opencode/agents/engineering/research/repo-research-analyst.md +10 -0
  126. package/opencode/agents/engineering/review/agent-native-reviewer.md +10 -0
  127. package/opencode/agents/engineering/review/architecture-strategist.md +10 -0
  128. package/opencode/agents/engineering/review/code-quality-analyst.md +10 -0
  129. package/opencode/agents/engineering/review/code-simplicity-reviewer.md +10 -0
  130. package/opencode/agents/engineering/review/data-integrity-guardian.md +10 -0
  131. package/opencode/agents/engineering/review/data-migration-expert.md +10 -0
  132. package/opencode/agents/engineering/review/deployment-verification-agent.md +10 -0
  133. package/opencode/agents/engineering/review/dhh-rails-reviewer.md +10 -0
  134. package/opencode/agents/engineering/review/kieran-rails-reviewer.md +10 -0
  135. package/opencode/agents/engineering/review/legacy-code-expert.md +10 -0
  136. package/opencode/agents/engineering/review/observability-coverage-reviewer.md +10 -0
  137. package/opencode/agents/engineering/review/pattern-recognition-specialist.md +10 -0
  138. package/opencode/agents/engineering/review/performance-oracle.md +10 -0
  139. package/opencode/agents/engineering/review/security-sentinel.md +10 -0
  140. package/opencode/agents/engineering/review/semgrep-sast.md +10 -0
  141. package/opencode/agents/engineering/review/test-design-reviewer.md +10 -0
  142. package/opencode/agents/engineering/review/user-impact-reviewer.md +10 -0
  143. package/opencode/agents/engineering/workflow/pr-comment-resolver.md +10 -0
  144. package/opencode/agents/finance/budget-analyst.md +10 -0
  145. package/opencode/agents/finance/cfo.md +10 -0
  146. package/opencode/agents/finance/financial-reporter.md +10 -0
  147. package/opencode/agents/finance/revenue-analyst.md +10 -0
  148. package/opencode/agents/legal/clo.md +10 -0
  149. package/opencode/agents/legal/legal-compliance-auditor.md +10 -0
  150. package/opencode/agents/legal/legal-document-generator.md +10 -0
  151. package/opencode/agents/marketing/analytics-analyst.md +10 -0
  152. package/opencode/agents/marketing/brand-architect.md +10 -0
  153. package/opencode/agents/marketing/cmo.md +10 -0
  154. package/opencode/agents/marketing/conversion-optimizer.md +10 -0
  155. package/opencode/agents/marketing/copywriter.md +10 -0
  156. package/opencode/agents/marketing/fact-checker.md +10 -0
  157. package/opencode/agents/marketing/growth-strategist.md +10 -0
  158. package/opencode/agents/marketing/paid-media-strategist.md +10 -0
  159. package/opencode/agents/marketing/pricing-strategist.md +10 -0
  160. package/opencode/agents/marketing/programmatic-seo-specialist.md +10 -0
  161. package/opencode/agents/marketing/retention-strategist.md +10 -0
  162. package/opencode/agents/marketing/seo-aeo-analyst.md +10 -0
  163. package/opencode/agents/operations/coo.md +10 -0
  164. package/opencode/agents/operations/ops-advisor.md +10 -0
  165. package/opencode/agents/operations/ops-provisioner.md +10 -0
  166. package/opencode/agents/operations/ops-research.md +10 -0
  167. package/opencode/agents/operations/service-automator.md +10 -0
  168. package/opencode/agents/product/business-validator.md +10 -0
  169. package/opencode/agents/product/competitive-intelligence.md +10 -0
  170. package/opencode/agents/product/cpo.md +10 -0
  171. package/opencode/agents/product/design/ux-design-lead.md +10 -0
  172. package/opencode/agents/product/spec-flow-analyzer.md +10 -0
  173. package/opencode/agents/sales/cro.md +10 -0
  174. package/opencode/agents/sales/deal-architect.md +10 -0
  175. package/opencode/agents/sales/outbound-strategist.md +10 -0
  176. package/opencode/agents/sales/pipeline-analyst.md +10 -0
  177. package/opencode/agents/support/cco.md +10 -0
  178. package/opencode/agents/support/community-manager.md +10 -0
  179. package/opencode/agents/support/ticket-triage.md +10 -0
  180. package/opencode/commands/go.md +10 -0
  181. package/opencode/commands/help.md +10 -0
  182. package/opencode/commands/sync.md +10 -0
  183. package/opencode/commands/version.md +11 -0
  184. package/opencode/opencode.json +8 -0
  185. package/opencode/plugin.ts +818 -0
  186. package/package.json +36 -4
  187. package/scripts/admin-merge-ready.sh +545 -0
  188. package/scripts/admin-merge-ready.test.sh +753 -0
  189. package/scripts/affected-tests.sh +908 -0
  190. package/scripts/affected-tests.test.sh +1797 -0
  191. package/scripts/alpha-metrics.sh +78 -0
  192. package/scripts/alpha-metrics.test.sh +115 -0
  193. package/scripts/ancestor-signal-helpers.baseline.txt +16 -0
  194. package/scripts/audit-flag-flip.sh +107 -0
  195. package/scripts/check-red-on-main.sh +316 -0
  196. package/scripts/ci-head-verdict.sh +411 -0
  197. package/scripts/cloud-detect.sh +193 -0
  198. package/scripts/delegation-verify.sh +657 -0
  199. package/scripts/delegation-verify.test.sh +1424 -0
  200. package/scripts/deploy-arm.sh +475 -0
  201. package/scripts/domain-model-drift.sh +419 -0
  202. package/scripts/emit-decision.sh +144 -0
  203. package/scripts/emit-decision.test.sh +144 -0
  204. package/scripts/ext-filter-divergence-corpus.txt +15 -0
  205. package/scripts/ext-filter-divergence.sh +189 -0
  206. package/scripts/generate-c4-from-components.ts +442 -0
  207. package/scripts/grok-fidelity-gate.sh +68 -0
  208. package/scripts/grok-pre-push-gate.sh +232 -0
  209. package/scripts/harness-discovery-smoke.ts +906 -0
  210. package/scripts/harness-parity-census.ts +92 -0
  211. package/scripts/inngest-luks-alert-armed-probe.ts +29 -0
  212. package/scripts/install-opencode-adapter.ts +509 -0
  213. package/scripts/lib/affected-tests/common.sh +365 -0
  214. package/scripts/lib/affected-tests/go.sh +157 -0
  215. package/scripts/lib/affected-tests/js.sh +188 -0
  216. package/scripts/lib/affected-tests/nx-turbo.sh +98 -0
  217. package/scripts/lib/affected-tests/python.sh +185 -0
  218. package/scripts/lib/context-sanitize.sh +49 -0
  219. package/scripts/lib/domain-model-lib.sh +180 -0
  220. package/scripts/lib/ext-filter-grammar.tsv +34 -0
  221. package/scripts/lib/operator-script.sh +1236 -0
  222. package/scripts/lib/proc.sh +580 -0
  223. package/scripts/lib/session-state.sh +748 -0
  224. package/scripts/lib/tmp-classify.sh +843 -0
  225. package/scripts/lib/wrapper-boundary.sh +47 -0
  226. package/scripts/lint-ratchet.py +1547 -0
  227. package/scripts/monitor-pr-checks.sh +441 -0
  228. package/scripts/pipeline-tally.sh +756 -0
  229. package/scripts/pipeline-tally.test.sh +740 -0
  230. package/scripts/plugin-version.sh +528 -0
  231. package/scripts/precommit-guard.sh +115 -0
  232. package/scripts/precommit-guard.test.sh +254 -0
  233. package/scripts/reconcile-live-heartbeats.ts +705 -0
  234. package/scripts/render-c4-model.sh +217 -0
  235. package/scripts/resolve-git-root.sh +55 -0
  236. package/scripts/resolve-regenerable-conflicts.sh +363 -0
  237. package/scripts/resolve-regenerable-conflicts.test.sh +780 -0
  238. package/scripts/ruff-requirements.txt +22 -0
  239. package/scripts/run-in-pid-namespace.sh +98 -0
  240. package/scripts/run-in-pid-namespace.test.sh +290 -0
  241. package/scripts/scan-ancestor-signal-helpers.py +556 -0
  242. package/scripts/scan-ancestor-signal-helpers.test.sh +670 -0
  243. package/scripts/setup-ralph-loop.sh +238 -0
  244. package/scripts/sync-cursor-name-map.ts +316 -0
  245. package/scripts/sync-grok-agent-compat.ts +188 -0
  246. package/scripts/sync-npm-package.ts +165 -0
  247. package/scripts/sync-opencode-adapter.ts +498 -0
  248. package/scripts/sync-pr-behind.sh +647 -0
  249. package/scripts/sync-pr-behind.test.sh +252 -0
  250. package/scripts/taste-profile-update.sh +180 -0
  251. package/scripts/taste-profile-update.test.sh +167 -0
  252. package/scripts/write-budget-marker.sh +23 -0
  253. package/scripts/write-kb-coverage.ts +113 -0
  254. package/skills/admin-ip-refresh/SKILL.md +81 -0
  255. package/skills/admin-ip-refresh/references/admin-ip-refresh-procedure.md +201 -0
  256. package/skills/agent-browser/SKILL.md +698 -0
  257. package/skills/agent-browser/scripts/playwright-mcp-profile-slot.sh +304 -0
  258. package/skills/agent-browser/scripts/playwright-mcp-redact-proxy.py +964 -0
  259. package/skills/agent-browser/scripts/redact-a11y-snapshot.py +443 -0
  260. package/skills/agent-browser/test/fixtures/capture-playwright-mcp-fixtures.py +217 -0
  261. package/skills/agent-browser/test/fixtures/fake-passthrough-proxy.py +24 -0
  262. package/skills/agent-browser/test/fixtures/fake-playwright-mcp.py +131 -0
  263. package/skills/agent-browser/test/fixtures/make-proxy-mutant.py +48 -0
  264. package/skills/agent-browser/test/fixtures/odd-shapes/dialog-link-injection.json +10 -0
  265. package/skills/agent-browser/test/fixtures/odd-shapes/empty-content.json +5 -0
  266. package/skills/agent-browser/test/fixtures/odd-shapes/error-and-result.json +4 -0
  267. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-bool.json +6 -0
  268. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-string.json +6 -0
  269. package/skills/agent-browser/test/fixtures/odd-shapes/error-message-tree.json +6 -0
  270. package/skills/agent-browser/test/fixtures/odd-shapes/error-no-data.json +6 -0
  271. package/skills/agent-browser/test/fixtures/odd-shapes/error-string.json +4 -0
  272. package/skills/agent-browser/test/fixtures/odd-shapes/error-with-data.json +9 -0
  273. package/skills/agent-browser/test/fixtures/odd-shapes/evaluate-escaped-object.json +10 -0
  274. package/skills/agent-browser/test/fixtures/odd-shapes/invalid-utf8.json +4 -0
  275. package/skills/agent-browser/test/fixtures/odd-shapes/link-result.json +10 -0
  276. package/skills/agent-browser/test/fixtures/odd-shapes/list-two-results.json +6 -0
  277. package/skills/agent-browser/test/fixtures/odd-shapes/meta-in-result.json +13 -0
  278. package/skills/agent-browser/test/fixtures/odd-shapes/no-content.json +5 -0
  279. package/skills/agent-browser/test/fixtures/odd-shapes/quoted-key.json +10 -0
  280. package/skills/agent-browser/test/fixtures/odd-shapes/resource-block.json +18 -0
  281. package/skills/agent-browser/test/fixtures/odd-shapes/result-and-method.json +11 -0
  282. package/skills/agent-browser/test/fixtures/odd-shapes/result-string.json +3 -0
  283. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped-one-row.json +10 -0
  284. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped.json +10 -0
  285. package/skills/agent-browser/test/fixtures/odd-shapes/structured-content.json +13 -0
  286. package/skills/agent-browser/test/fixtures/odd-shapes/tools-list-no-tools.json +5 -0
  287. package/skills/agent-browser/test/fixtures/odd-shapes/tree-no-credential.json +10 -0
  288. package/skills/agent-browser/test/fixtures/odd-shapes/two-text-blocks.json +14 -0
  289. package/skills/agent-browser/test/fixtures/odd-shapes/unparsable-line.json +3 -0
  290. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-brace.json +10 -0
  291. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-link-substring.json +10 -0
  292. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/close.json +12 -0
  293. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/evaluate.json +12 -0
  294. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/find.json +12 -0
  295. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/framing.json +6 -0
  296. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/initialize.json +14 -0
  297. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate-link.json +12 -0
  298. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate.json +12 -0
  299. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/roots-list-request.json +5 -0
  300. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/screenshot.json +17 -0
  301. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-filename.json +12 -0
  302. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-json.json +12 -0
  303. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-raw.json +12 -0
  304. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot.json +12 -0
  305. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/tools-list.json +827 -0
  306. package/skills/agent-browser/test/fixtures/proxy-session-driver.py +138 -0
  307. package/skills/agent-browser/test/fixtures/session-facts.py +102 -0
  308. package/skills/agent-browser/test/playwright-mcp-lifetime.test.sh +1620 -0
  309. package/skills/agent-browser/test/playwright-mcp-redact-proxy.test.sh +1599 -0
  310. package/skills/agent-browser/test/redact-a11y-snapshot.test.sh +527 -0
  311. package/skills/agent-native-architecture/SKILL.md +479 -0
  312. package/skills/agent-native-architecture/references/action-parity-discipline.md +430 -0
  313. package/skills/agent-native-architecture/references/agent-execution-patterns.md +483 -0
  314. package/skills/agent-native-architecture/references/agent-native-testing.md +605 -0
  315. package/skills/agent-native-architecture/references/architecture-patterns.md +493 -0
  316. package/skills/agent-native-architecture/references/dynamic-context-injection.md +358 -0
  317. package/skills/agent-native-architecture/references/files-universal-interface.md +314 -0
  318. package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +381 -0
  319. package/skills/agent-native-architecture/references/mcp-tool-design.md +524 -0
  320. package/skills/agent-native-architecture/references/mobile-patterns.md +897 -0
  321. package/skills/agent-native-architecture/references/product-implications.md +478 -0
  322. package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +342 -0
  323. package/skills/agent-native-architecture/references/self-modification.md +294 -0
  324. package/skills/agent-native-architecture/references/shared-workspace-architecture.md +700 -0
  325. package/skills/agent-native-architecture/references/system-prompt-design.md +263 -0
  326. package/skills/agent-native-audit/SKILL.md +300 -0
  327. package/skills/agent-native-audit/workflows/agent-native-audit.workflow.js +423 -0
  328. package/skills/andrew-kane-gem-writer/SKILL.md +189 -0
  329. package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  330. package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  331. package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  332. package/skills/andrew-kane-gem-writer/references/resources.md +126 -0
  333. package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  334. package/skills/architecture/SKILL.md +436 -0
  335. package/skills/architecture/references/adr-template.md +154 -0
  336. package/skills/architecture/references/likec4-reference.md +136 -0
  337. package/skills/architecture/references/nfr-reference.md +126 -0
  338. package/skills/archive-kb/SKILL.md +86 -0
  339. package/skills/archive-kb/scripts/archive-kb.sh +300 -0
  340. package/skills/archive-kb/test/archive-kb-partial-run.test.sh +276 -0
  341. package/skills/atdd-developer/SKILL.md +65 -0
  342. package/skills/brainstorm/SKILL.md +701 -0
  343. package/skills/brainstorm/references/brainstorm-brand-workshop.md +153 -0
  344. package/skills/brainstorm/references/brainstorm-domain-config.md +63 -0
  345. package/skills/brainstorm/references/brainstorm-validation-workshop.md +65 -0
  346. package/skills/brainstorm/references/ui-surface-terms.md +42 -0
  347. package/skills/brainstorm-techniques/SKILL.md +231 -0
  348. package/skills/brainstorm-techniques/references/decision-principles.md +150 -0
  349. package/skills/brainstorm-techniques/references/phase-boundaries.md +103 -0
  350. package/skills/brainstorm-techniques/references/standing-delegation.md +407 -0
  351. package/skills/brainstorm-techniques/references/technical-ruling-delegation.md +174 -0
  352. package/skills/campaign-calendar/SKILL.md +145 -0
  353. package/skills/cf-token-scope/SKILL.md +164 -0
  354. package/skills/cf-token-scope/references/widen-playbook.md +114 -0
  355. package/skills/cf-token-scope/scripts/cf-token-scope.sh +253 -0
  356. package/skills/changelog/SKILL.md +142 -0
  357. package/skills/code-to-prd/SKILL.md +66 -0
  358. package/skills/code-to-prd/references/banner-template.md +12 -0
  359. package/skills/code-to-prd/references/prd-template.md +41 -0
  360. package/skills/code-to-prd/scripts/code-to-prd.sh +634 -0
  361. package/skills/code-to-prd/test/code-to-prd.test.sh +447 -0
  362. package/skills/code-to-prd/test/fixture/.env.example +7 -0
  363. package/skills/code-to-prd/test/fixture/app/about/page.tsx +11 -0
  364. package/skills/code-to-prd/test/fixture/app/api/health/route.ts +10 -0
  365. package/skills/code-to-prd/test/fixture/app/page.tsx +14 -0
  366. package/skills/code-to-prd/test/fixture/next.config.mjs +3 -0
  367. package/skills/code-to-prd/test/fixture/package.json +6 -0
  368. package/skills/cohort-status/SKILL.md +62 -0
  369. package/skills/community/SKILL.md +210 -0
  370. package/skills/community/scripts/bsky-community.sh +644 -0
  371. package/skills/community/scripts/bsky-setup.sh +631 -0
  372. package/skills/community/scripts/community-router.sh +93 -0
  373. package/skills/community/scripts/discord-community.sh +487 -0
  374. package/skills/community/scripts/discord-setup.sh +784 -0
  375. package/skills/community/scripts/github-community.sh +706 -0
  376. package/skills/community/scripts/hn-community.sh +233 -0
  377. package/skills/community/scripts/lib/hmac-sha1-b64.sh +126 -0
  378. package/skills/community/scripts/linkedin-community.sh +750 -0
  379. package/skills/community/scripts/linkedin-setup.sh +758 -0
  380. package/skills/community/scripts/x-community.sh +890 -0
  381. package/skills/community/scripts/x-setup.sh +713 -0
  382. package/skills/community/test/community-argv.test.sh +2922 -0
  383. package/skills/community/test/github-community.test.sh +981 -0
  384. package/skills/competitive-analysis/SKILL.md +69 -0
  385. package/skills/competitive-analysis/references/peer-plugin-audit.md +218 -0
  386. package/skills/compound/SKILL.md +673 -0
  387. package/skills/compound/scripts/token-efficiency-report.sh +334 -0
  388. package/skills/compound/test/phase-16.test.sh +379 -0
  389. package/skills/compound-capture/SKILL.md +791 -0
  390. package/skills/compound-capture/assets/critical-pattern-template.md +37 -0
  391. package/skills/compound-capture/assets/resolution-template.md +116 -0
  392. package/skills/compound-capture/references/yaml-schema.md +67 -0
  393. package/skills/compound-capture/schema.yaml +181 -0
  394. package/skills/constraint-scaffold/SKILL.md +175 -0
  395. package/skills/constraint-scaffold/references/boundary-readme.template +35 -0
  396. package/skills/constraint-scaffold/references/constraint-gates-workflow.template +69 -0
  397. package/skills/constraint-scaffold/references/depcruise-config.template +230 -0
  398. package/skills/constraint-scaffold/references/fix-constraints-stage-a.template +240 -0
  399. package/skills/constraint-scaffold/references/fix-constraints-stage-b.template +313 -0
  400. package/skills/constraint-scaffold/references/shared-runner.template +135 -0
  401. package/skills/constraint-scaffold/scripts/constraint-scaffold.sh +589 -0
  402. package/skills/constraint-scaffold/test/bite-proof.test.sh +1338 -0
  403. package/skills/constraint-scaffold/test/boundary.test.sh +734 -0
  404. package/skills/constraint-scaffold/test/emit-fix-constraints.test.sh +193 -0
  405. package/skills/constraint-scaffold/test/generator.test.sh +93 -0
  406. package/skills/constraint-scaffold/test/parity.test.sh +285 -0
  407. package/skills/content-writer/SKILL.md +242 -0
  408. package/skills/content-writer/scripts/blog-jargon-scan.sh +42 -0
  409. package/skills/cron-delete/SKILL.md +56 -0
  410. package/skills/cron-list/SKILL.md +54 -0
  411. package/skills/deepen-plan/SKILL.md +937 -0
  412. package/skills/deepen-plan/workflows/deepen-plan.workflow.js +488 -0
  413. package/skills/deploy/SKILL.md +115 -0
  414. package/skills/deploy/references/hetzner-setup.md +67 -0
  415. package/skills/deploy/scripts/deploy.sh +37 -0
  416. package/skills/deploy-docs/SKILL.md +95 -0
  417. package/skills/dhh-rails-style/SKILL.md +203 -0
  418. package/skills/dhh-rails-style/references/architecture.md +717 -0
  419. package/skills/dhh-rails-style/references/controllers.md +323 -0
  420. package/skills/dhh-rails-style/references/frontend.md +556 -0
  421. package/skills/dhh-rails-style/references/gems.md +316 -0
  422. package/skills/dhh-rails-style/references/models.md +388 -0
  423. package/skills/dhh-rails-style/references/testing.md +354 -0
  424. package/skills/discord-content/SKILL.md +126 -0
  425. package/skills/docs-site/SKILL.md +214 -0
  426. package/skills/drain-labeled-backlog/SKILL.md +203 -0
  427. package/skills/drain-labeled-backlog/scripts/group-by-area.sh +208 -0
  428. package/skills/drain-labeled-backlog/workflows/drain-labeled-backlog.workflow.js +433 -0
  429. package/skills/drain-prs/SKILL.md +143 -0
  430. package/skills/drain-prs/scripts/triage-prs.sh +192 -0
  431. package/skills/drain-prs/test/argv-ceiling.test.sh +183 -0
  432. package/skills/dspy-ruby/SKILL.md +634 -0
  433. package/skills/dspy-ruby/assets/config-template.rb +359 -0
  434. package/skills/dspy-ruby/assets/module-template.rb +326 -0
  435. package/skills/dspy-ruby/assets/signature-template.rb +143 -0
  436. package/skills/dspy-ruby/references/core-concepts.md +268 -0
  437. package/skills/dspy-ruby/references/optimization.md +623 -0
  438. package/skills/dspy-ruby/references/providers.md +335 -0
  439. package/skills/eval-harness/README.md +194 -0
  440. package/skills/eval-harness/SKILL.md +157 -0
  441. package/skills/eval-harness/enums/go-routes.json +13 -0
  442. package/skills/eval-harness/enums/incident-threshold.json +5 -0
  443. package/skills/eval-harness/enums/lane.json +5 -0
  444. package/skills/eval-harness/enums/tool-selection.json +20 -0
  445. package/skills/eval-harness/enums/triage-levels.json +5 -0
  446. package/skills/eval-harness/gated-skills.json +34 -0
  447. package/skills/eval-harness/models.generated.json +5 -0
  448. package/skills/eval-harness/promptfooconfig-go-routing.yaml +35 -0
  449. package/skills/eval-harness/promptfooconfig-incident-threshold.yaml +32 -0
  450. package/skills/eval-harness/promptfooconfig-lane-inference.yaml +33 -0
  451. package/skills/eval-harness/promptfooconfig-ticket-triage.yaml +34 -0
  452. package/skills/eval-harness/promptfooconfig-tool-selection.yaml +33 -0
  453. package/skills/eval-harness/prompts/go-baseline.txt +6 -0
  454. package/skills/eval-harness/prompts/go-skill.txt +21 -0
  455. package/skills/eval-harness/prompts/incident-threshold-baseline.txt +6 -0
  456. package/skills/eval-harness/prompts/incident-threshold-skill.txt +12 -0
  457. package/skills/eval-harness/prompts/lane-inference-baseline.txt +6 -0
  458. package/skills/eval-harness/prompts/lane-inference-skill.txt +15 -0
  459. package/skills/eval-harness/prompts/tool-selection-baseline.txt +19 -0
  460. package/skills/eval-harness/prompts/tool-selection-skill.txt +22 -0
  461. package/skills/eval-harness/prompts/triage-baseline.txt +7 -0
  462. package/skills/eval-harness/prompts/triage-skill.txt +10 -0
  463. package/skills/eval-harness/scripts/eval-gate.cjs +318 -0
  464. package/skills/eval-harness/scripts/extract-block.cjs +87 -0
  465. package/skills/eval-harness/scripts/gate-classification.cjs +28 -0
  466. package/skills/eval-harness/scripts/gen-models.sh +41 -0
  467. package/skills/eval-harness/scripts/gen-skill-prompt.cjs +177 -0
  468. package/skills/eval-harness/scripts/measure-classification.cjs +30 -0
  469. package/skills/eval-harness/scripts/parse-label.cjs +93 -0
  470. package/skills/eval-harness/scripts/verdict.cjs +132 -0
  471. package/skills/eval-harness/tasks/go-routing.jsonl +8 -0
  472. package/skills/eval-harness/tasks/incident-threshold.jsonl +7 -0
  473. package/skills/eval-harness/tasks/lane-inference.jsonl +7 -0
  474. package/skills/eval-harness/tasks/ticket-triage.jsonl +6 -0
  475. package/skills/eval-harness/tasks/tool-selection.jsonl +15 -0
  476. package/skills/eval-harness/test/eval-gate.test.sh +132 -0
  477. package/skills/eval-harness/test/extract-block.test.sh +87 -0
  478. package/skills/eval-harness/test/gate-classification.test.sh +77 -0
  479. package/skills/eval-harness/test/gen-models.test.sh +75 -0
  480. package/skills/eval-harness/test/measure-classification.test.sh +74 -0
  481. package/skills/eval-harness/test/parse-label.test.sh +129 -0
  482. package/skills/eval-harness/test/registry-completeness.test.sh +109 -0
  483. package/skills/eval-harness/test/verdict.test.sh +123 -0
  484. package/skills/every-style-editor/SKILL.md +142 -0
  485. package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  486. package/skills/feature-tweet/SKILL.md +199 -0
  487. package/skills/feature-video/SKILL.md +412 -0
  488. package/skills/feature-video/scripts/check_deps.sh +281 -0
  489. package/skills/file-todos/SKILL.md +267 -0
  490. package/skills/file-todos/assets/todo-template.md +166 -0
  491. package/skills/fix-issue/SKILL.md +278 -0
  492. package/skills/fix-issue/references/agent-authored-exclusion.md +120 -0
  493. package/skills/fix-issue/references/exclude-label-jq-snippet.md +97 -0
  494. package/skills/flag-bootstrap/SETUP.md +142 -0
  495. package/skills/flag-create/SKILL.md +145 -0
  496. package/skills/flag-create/scripts/create.sh +273 -0
  497. package/skills/flag-delete/SKILL.md +167 -0
  498. package/skills/flag-delete/scripts/delete.sh +288 -0
  499. package/skills/flag-list/SKILL.md +99 -0
  500. package/skills/flag-list/scripts/list.sh +275 -0
  501. package/skills/flag-set-role/SKILL.md +229 -0
  502. package/skills/flag-set-role/scripts/flip.sh +774 -0
  503. package/skills/frontend-anti-slop/SKILL.md +106 -0
  504. package/skills/frontend-anti-slop/references/anti-patterns.md +199 -0
  505. package/skills/frontend-anti-slop/references/slop-rules.md +65 -0
  506. package/skills/frontend-anti-slop/scripts/tier1-scan.ts +525 -0
  507. package/skills/frontend-design/SKILL.md +77 -0
  508. package/skills/gdpr-gate/NOTICE +136 -0
  509. package/skills/gdpr-gate/SKILL.md +341 -0
  510. package/skills/gdpr-gate/references/fields.md +160 -0
  511. package/skills/gdpr-gate/references/layers/api-layer.md +355 -0
  512. package/skills/gdpr-gate/references/layers/auth-sessions.md +290 -0
  513. package/skills/gdpr-gate/references/layers/data-in-transit.md +331 -0
  514. package/skills/gdpr-gate/references/layers/data-lifecycle.md +341 -0
  515. package/skills/gdpr-gate/references/layers/frontend.md +249 -0
  516. package/skills/gdpr-gate/references/layers/testing-seeding.md +256 -0
  517. package/skills/gdpr-gate/references/leakage-vectors.md +248 -0
  518. package/skills/gdpr-gate/references/legacy/legal-consent-v1-prose.md +48 -0
  519. package/skills/gdpr-gate/references/legal-consent.md +140 -0
  520. package/skills/gdpr-gate/references/non-negotiables.md +60 -0
  521. package/skills/gdpr-gate/scripts/gdpr-gate.sh +271 -0
  522. package/skills/gdpr-gate/scripts/notice-frontmatter.sh +337 -0
  523. package/skills/gdpr-gate/scripts/path-denylist.txt +39 -0
  524. package/skills/gdpr-gate/scripts/repo-scan.sh +158 -0
  525. package/skills/gdpr-gate/scripts/vendor-drift-classify.sh +120 -0
  526. package/skills/gdpr-gate/scripts/vendor-pin-integrity.sh +237 -0
  527. package/skills/gemini-imagegen/SKILL.md +283 -0
  528. package/skills/gemini-imagegen/requirements.txt +5 -0
  529. package/skills/gemini-imagegen/scripts/_error_handling.py +146 -0
  530. package/skills/gemini-imagegen/scripts/compose_images.py +150 -0
  531. package/skills/gemini-imagegen/scripts/edit_image.py +137 -0
  532. package/skills/gemini-imagegen/scripts/gemini_images.py +256 -0
  533. package/skills/gemini-imagegen/scripts/generate_image.py +147 -0
  534. package/skills/gemini-imagegen/scripts/multi_turn_chat.py +223 -0
  535. package/skills/gemini-imagegen/scripts/test_error_handling.py +179 -0
  536. package/skills/git-worktree/SKILL.md +534 -0
  537. package/skills/git-worktree/scripts/git-repo-readiness-diag.sh +98 -0
  538. package/skills/git-worktree/scripts/worktree-manager.sh +4773 -0
  539. package/skills/git-worktree/test/create-from-origin-main.test.sh +116 -0
  540. package/skills/git-worktree/test/lease-protects-active.test.sh +1056 -0
  541. package/skills/git-worktree/test/no-repo-fail-loud.test.sh +88 -0
  542. package/skills/git-worktree/test/orphan-reaper-honest-count.test.sh +379 -0
  543. package/skills/git-worktree/test/reap-archive-persistence.test.sh +725 -0
  544. package/skills/git-worktree/test/stale-lock-sweep.test.sh +176 -0
  545. package/skills/go/SKILL.md +54 -0
  546. package/skills/growth/SKILL.md +164 -0
  547. package/skills/harvest-debt/SKILL.md +78 -0
  548. package/skills/harvest-debt/scripts/harvest-debt.sh +114 -0
  549. package/skills/heal-skill/SKILL.md +173 -0
  550. package/skills/help/SKILL.md +46 -0
  551. package/skills/incident/NOTICE +39 -0
  552. package/skills/incident/SKILL.md +395 -0
  553. package/skills/incident/scripts/dry-run.sh +448 -0
  554. package/skills/incident/scripts/redact-engine.py +412 -0
  555. package/skills/incident/scripts/redact-sentinel.sh +44 -0
  556. package/skills/incident/templates/pir.md +139 -0
  557. package/skills/incident/test/fixtures/dry-run-incident.json +26 -0
  558. package/skills/incident/test/fixtures/dry-run-secret-leak.json +26 -0
  559. package/skills/incident/test/fixtures/legacy-bash-scanner.sh +82 -0
  560. package/skills/incident/test/fixtures/positive-corpus.md +87 -0
  561. package/skills/incident/test/redact-sentinel.test.sh +1420 -0
  562. package/skills/invoice/SKILL.md +206 -0
  563. package/skills/kb-glossary/SKILL.md +71 -0
  564. package/skills/kb-glossary/references/glossary-format.md +111 -0
  565. package/skills/kb-glossary/references/rejected-request-register.md +115 -0
  566. package/skills/kb-search/SKILL.md +276 -0
  567. package/skills/kb-search/scripts/kb-search-cache.sh +123 -0
  568. package/skills/legal-audit/SKILL.md +161 -0
  569. package/skills/legal-generate/NOTICE +242 -0
  570. package/skills/legal-generate/SKILL.md +244 -0
  571. package/skills/legal-generate/references/templates/advisor-agreement/template.md +12 -0
  572. package/skills/legal-generate/references/templates/business-associate-agreement/template.md +112 -0
  573. package/skills/legal-generate/references/templates/cookie-notice/template.md +82 -0
  574. package/skills/legal-generate/references/templates/dpa-global/template.md +439 -0
  575. package/skills/legal-generate/references/templates/dpa-us/template.md +222 -0
  576. package/skills/legal-generate/references/templates/employee-offer-letter/template.md +75 -0
  577. package/skills/legal-generate/references/templates/master-services-agreement/template.md +252 -0
  578. package/skills/legal-generate/references/templates/mutual-nda/template.md +66 -0
  579. package/skills/legal-generate/references/templates/one-way-nda/template.md +38 -0
  580. package/skills/legal-generate/references/templates/privacy-policy-gdpr/template.md +427 -0
  581. package/skills/legal-generate/references/templates/privacy-policy-us/template.md +313 -0
  582. package/skills/legal-generate/references/templates/terms-of-use/template.md +75 -0
  583. package/skills/legal-generate/scripts/strip-vendor-credit.sh +96 -0
  584. package/skills/linear-fetch/SKILL.md +247 -0
  585. package/skills/linear-fetch/scripts/assert-no-linear-telemetry.sh +66 -0
  586. package/skills/linear-fetch/scripts/redact-linear-urls.sh +51 -0
  587. package/skills/linear-fetch/scripts/render-caller-template.sh +36 -0
  588. package/skills/linear-fetch/test/assert-no-linear-telemetry.test.sh +113 -0
  589. package/skills/linear-fetch/test/parity.test.sh +112 -0
  590. package/skills/linear-fetch/test/persist-safe-integration.test.sh +191 -0
  591. package/skills/linear-fetch/test/redact-linear-urls.test.sh +226 -0
  592. package/skills/merge-pr/SKILL.md +670 -0
  593. package/skills/model-launch-review/SKILL.md +255 -0
  594. package/skills/model-launch-review/scripts/audit-models.sh +501 -0
  595. package/skills/one-shot/SKILL.md +316 -0
  596. package/skills/one-shot/references/token-discipline.md +74 -0
  597. package/skills/operator-bootstrap/SKILL.md +412 -0
  598. package/skills/operator-bootstrap/template.sh +439 -0
  599. package/skills/operator-digest/SKILL.md +287 -0
  600. package/skills/operator-digest/assets/operator-digest.workflow.yml +175 -0
  601. package/skills/operator-digest/scripts/digest-scrub.sh +119 -0
  602. package/skills/operator-digest/scripts/provision-operator-digest-repo.sh +147 -0
  603. package/skills/operator-rephrase/SKILL.md +98 -0
  604. package/skills/pencil-setup/SKILL.md +201 -0
  605. package/skills/pencil-setup/scripts/check_deps.sh +556 -0
  606. package/skills/pencil-setup/scripts/copy_adapter.sh +80 -0
  607. package/skills/pencil-setup/scripts/package-lock.json +1172 -0
  608. package/skills/pencil-setup/scripts/package.json +14 -0
  609. package/skills/pencil-setup/scripts/pencil-error-enrichment.mjs +21 -0
  610. package/skills/pencil-setup/scripts/pencil-mcp-adapter.mjs +733 -0
  611. package/skills/pencil-setup/scripts/pencil-response-classify.mjs +38 -0
  612. package/skills/pencil-setup/scripts/pencil-save-gate.mjs +26 -0
  613. package/skills/pencil-setup/scripts/sanitize-filename.mjs +25 -0
  614. package/skills/plan/SKILL.md +1140 -0
  615. package/skills/plan/references/differential-migration-testing.md +185 -0
  616. package/skills/plan/references/plan-community-discovery.md +42 -0
  617. package/skills/plan/references/plan-founder-check.md +137 -0
  618. package/skills/plan/references/plan-functional-overlap.md +25 -0
  619. package/skills/plan/references/plan-host-fanout.md +51 -0
  620. package/skills/plan/references/plan-issue-templates.md +779 -0
  621. package/skills/plan/references/plan-network-outage-checklist.md +131 -0
  622. package/skills/plan/references/plan-scope-check.md +126 -0
  623. package/skills/plan/references/plan-sharp-edges.md +331 -0
  624. package/skills/plan/references/plan-signoff-lifecycle.md +12 -0
  625. package/skills/plan/references/webapp-cwv-observability.md +143 -0
  626. package/skills/plan-review/SKILL.md +91 -0
  627. package/skills/plan-review/lib/named-panel.mjs +58 -0
  628. package/skills/plan-review/workflows/plan-review.workflow.js +477 -0
  629. package/skills/postmerge/SKILL.md +642 -0
  630. package/skills/postmerge/references/deploy-status-debugging.md +141 -0
  631. package/skills/postmerge/references/graceful-degradation.md +20 -0
  632. package/skills/postmerge/references/sentry-error-count-delta.md +137 -0
  633. package/skills/preflight/SKILL.md +1553 -0
  634. package/skills/preflight/references/check-13-founder-check.md +286 -0
  635. package/skills/preflight/scripts/founder-check.py +1640 -0
  636. package/skills/preflight/scripts/parse-form-a.awk +107 -0
  637. package/skills/preflight/scripts/probe-verb-gate.sh +108 -0
  638. package/skills/product-roadmap/SKILL.md +357 -0
  639. package/skills/product-roadmap/scripts/roadmap-reconcile.sh +327 -0
  640. package/skills/provision-cloudflare/SKILL.md +67 -0
  641. package/skills/provision-cloudflare/scripts/provision-cloudflare.sh +271 -0
  642. package/skills/provision-doppler/SKILL.md +58 -0
  643. package/skills/provision-doppler/scripts/provision-doppler.sh +358 -0
  644. package/skills/provision-github/SKILL.md +59 -0
  645. package/skills/provision-github/scripts/provision-github.sh +300 -0
  646. package/skills/provision-hetzner/SKILL.md +76 -0
  647. package/skills/provision-hetzner/scripts/provision-hetzner.sh +262 -0
  648. package/skills/provision-hetzner/test/fixture/knowledge-base/legal/tenant-dpa-register.md +26 -0
  649. package/skills/provision-hetzner/test/fixture/provision-hetzner-dry-run.golden +34 -0
  650. package/skills/provision-hetzner/test/provision-hetzner-characterization.test.sh +227 -0
  651. package/skills/qa/SKILL.md +263 -0
  652. package/skills/qa/references/browser-preflight.md +22 -0
  653. package/skills/questionnaire-generate/SKILL.md +328 -0
  654. package/skills/questionnaire-generate/references/questionnaire.template +60 -0
  655. package/skills/rclone/SKILL.md +162 -0
  656. package/skills/rclone/scripts/check_setup.sh +63 -0
  657. package/skills/release-announce/SKILL.md +65 -0
  658. package/skills/release-docs/SKILL.md +92 -0
  659. package/skills/reproduce-bug/SKILL.md +358 -0
  660. package/skills/resolve-debt/SKILL.md +85 -0
  661. package/skills/resolve-debt/scripts/resolve-debt.py +584 -0
  662. package/skills/resolve-parallel/SKILL.md +45 -0
  663. package/skills/resolve-parallel/workflows/resolve-parallel.workflow.js +415 -0
  664. package/skills/resolve-pr-parallel/SKILL.md +68 -0
  665. package/skills/resolve-pr-parallel/workflows/resolve-pr-parallel.workflow.js +419 -0
  666. package/skills/resolve-todo-parallel/SKILL.md +57 -0
  667. package/skills/resolve-todo-parallel/workflows/resolve-todo-parallel.workflow.js +398 -0
  668. package/skills/review/SKILL.md +1620 -0
  669. package/skills/review/references/anti-slop-scanner-hook.md +40 -0
  670. package/skills/review/references/defect-classes-migrations.md +9 -0
  671. package/skills/review/references/generated-input-oracle-surfaces.md +15 -0
  672. package/skills/review/references/review-e2e-testing.md +116 -0
  673. package/skills/review/references/review-evidence-comment.md +36 -0
  674. package/skills/review/references/review-todo-structure.md +165 -0
  675. package/skills/review/references/risk-tier-and-fix-rounds.md +97 -0
  676. package/skills/review/references/semgrep-custom-rules.yaml +174 -0
  677. package/skills/review/references/ultrathink-phases.md +98 -0
  678. package/skills/review/references/wfs.md +6 -0
  679. package/skills/review/scripts/emit-review-trailer.sh +499 -0
  680. package/skills/review/scripts/ensure-semgrep.sh +99 -0
  681. package/skills/review/scripts/fix-round-seats.sh +197 -0
  682. package/skills/review/test/emit-review-trailer.test.sh +387 -0
  683. package/skills/review/test/ensure-semgrep.test.sh +111 -0
  684. package/skills/review/test/fix-round-seats.test.sh +237 -0
  685. package/skills/review/workflows/README.md +147 -0
  686. package/skills/review/workflows/review.workflow.js +667 -0
  687. package/skills/schedule/SKILL.md +796 -0
  688. package/skills/seo-aeo/SKILL.md +139 -0
  689. package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
  690. package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
  691. package/skills/ship/SKILL.md +3023 -0
  692. package/skills/ship/references/adr-ordinal-collision.md +47 -0
  693. package/skills/ship/references/affected-gate-contract.md +115 -0
  694. package/skills/ship/references/ci-run-diagnosis.md +29 -0
  695. package/skills/ship/references/ci-workflow-authoring.md +68 -0
  696. package/skills/ship/references/cleanup-merged-archival.md +39 -0
  697. package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
  698. package/skills/ship/references/cto-ruling-armed-push.md +5 -0
  699. package/skills/ship/references/decision-challenges-render.md +71 -0
  700. package/skills/ship/references/delegated-act-authoring-form.md +7 -0
  701. package/skills/ship/references/detached-battery-verdict.md +13 -0
  702. package/skills/ship/references/epic-close-sweep.md +62 -0
  703. package/skills/ship/references/feature-tweet-draft.md +42 -0
  704. package/skills/ship/references/followthrough-issue-body-template.md +47 -0
  705. package/skills/ship/references/followthrough-stub-template.sh +92 -0
  706. package/skills/ship/references/merge-queue-dequeue.md +39 -0
  707. package/skills/ship/references/operator-holds.md +179 -0
  708. package/skills/ship/references/pipeline-tally-render.md +43 -0
  709. package/skills/ship/references/pr-overlap.md +153 -0
  710. package/skills/ship/references/queue-mode.md +7 -0
  711. package/skills/ship/references/ready-run-wait.md +36 -0
  712. package/skills/ship/references/red-on-main-quarantine.md +110 -0
  713. package/skills/ship/references/register-update-pr-pattern.md +88 -0
  714. package/skills/ship/references/settle-then-admin-merge.md +130 -0
  715. package/skills/ship/references/supabase-column-probe.md +13 -0
  716. package/skills/ship/scripts/auto-close-scan.sh +76 -0
  717. package/skills/ship/scripts/battery-owed.sh +403 -0
  718. package/skills/ship/scripts/hold-gate-eval.sh +410 -0
  719. package/skills/ship/scripts/net-issue-flow.sh +665 -0
  720. package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
  721. package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
  722. package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
  723. package/skills/skill-creator/SKILL.md +299 -0
  724. package/skills/skill-creator/references/api-security.md +248 -0
  725. package/skills/skill-creator/references/authoring-levers.md +110 -0
  726. package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
  727. package/skills/skill-creator/references/best-practices.md +431 -0
  728. package/skills/skill-creator/references/common-patterns.md +639 -0
  729. package/skills/skill-creator/references/core-principles.md +193 -0
  730. package/skills/skill-creator/references/executable-code.md +188 -0
  731. package/skills/skill-creator/references/iteration-and-testing.md +509 -0
  732. package/skills/skill-creator/references/official-spec.md +193 -0
  733. package/skills/skill-creator/references/recommended-structure.md +180 -0
  734. package/skills/skill-creator/references/skill-structure.md +396 -0
  735. package/skills/skill-creator/references/using-scripts.md +122 -0
  736. package/skills/skill-creator/references/using-templates.md +120 -0
  737. package/skills/skill-creator/references/workflows-and-validation.md +541 -0
  738. package/skills/skill-creator/scripts/init_skill.py +322 -0
  739. package/skills/skill-creator/scripts/package_skill.py +110 -0
  740. package/skills/skill-creator/scripts/quick_validate.py +64 -0
  741. package/skills/skill-creator/templates/router-skill.md +73 -0
  742. package/skills/skill-creator/templates/simple-skill.md +34 -0
  743. package/skills/skill-creator/workflows/add-reference.md +96 -0
  744. package/skills/skill-creator/workflows/add-script.md +104 -0
  745. package/skills/skill-creator/workflows/add-template.md +83 -0
  746. package/skills/skill-creator/workflows/add-workflow.md +128 -0
  747. package/skills/skill-creator/workflows/audit-skill.md +159 -0
  748. package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
  749. package/skills/skill-creator/workflows/create-new-skill.md +207 -0
  750. package/skills/skill-creator/workflows/get-guidance.md +134 -0
  751. package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
  752. package/skills/skill-creator/workflows/verify-skill.md +226 -0
  753. package/skills/skill-security-scan/SKILL.md +145 -0
  754. package/skills/skill-security-scan/references/disclaimer.md +21 -0
  755. package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
  756. package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
  757. package/skills/skill-security-scan/references/override-mechanism.md +171 -0
  758. package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
  759. package/skills/skill-security-scan/references/regex-patterns.md +136 -0
  760. package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
  761. package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
  762. package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
  763. package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
  764. package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
  765. package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
  766. package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
  767. package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
  768. package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
  769. package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
  770. package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
  771. package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
  772. package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
  773. package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
  774. package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
  775. package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
  776. package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
  777. package/skills/skill-security-scan/scripts/lib.sh +197 -0
  778. package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
  779. package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
  780. package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
  781. package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
  782. package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
  783. package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
  784. package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
  785. package/skills/social-distribute/SKILL.md +485 -0
  786. package/skills/spec-templates/SKILL.md +274 -0
  787. package/skills/sync/SKILL.md +49 -0
  788. package/skills/test-browser/SKILL.md +464 -0
  789. package/skills/test-browser/references/feature-map.md +161 -0
  790. package/skills/test-fix-loop/SKILL.md +159 -0
  791. package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
  792. package/skills/triage/SKILL.md +402 -0
  793. package/skills/trigger-cron/SKILL.md +136 -0
  794. package/skills/trigger-cron/scripts/trigger.sh +198 -0
  795. package/skills/user-set-role/SKILL.md +147 -0
  796. package/skills/user-set-role/scripts/set-role.sh +218 -0
  797. package/skills/user-story-writer/SKILL.md +77 -0
  798. package/skills/ux-audit/SKILL.md +251 -0
  799. package/skills/ux-audit/references/finding.schema.json +62 -0
  800. package/skills/ux-audit/references/route-list.yaml +95 -0
  801. package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
  802. package/skills/ux-audit/scripts/bot-signin.ts +135 -0
  803. package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
  804. package/skills/verification-scaffold/SKILL.md +73 -0
  805. package/skills/verification-scaffold/references/gitleaks.toml.template +13 -0
  806. package/skills/verification-scaffold/references/guardrail-audit.md +156 -0
  807. package/skills/verification-scaffold/references/guards/block-stash-hook.sh.template +72 -0
  808. package/skills/verification-scaffold/references/guards/commit-on-main-hook.sh.template +82 -0
  809. package/skills/verification-scaffold/references/guards/orphan-test-check.sh.template +102 -0
  810. package/skills/verification-scaffold/references/guards/precommit-guard.sh.template +115 -0
  811. package/skills/verification-scaffold/references/guards/secret-scan-hook.sh.template +176 -0
  812. package/skills/verification-scaffold/references/guards/verification-gates.yml.template +49 -0
  813. package/skills/verification-scaffold/references/guards/wrapper-boundary.sh.template +47 -0
  814. package/skills/verification-scaffold/references/guards.tsv +21 -0
  815. package/skills/verification-scaffold/references/verification-readme.template +55 -0
  816. package/skills/verification-scaffold/scripts/verification-scaffold.sh +785 -0
  817. package/skills/verification-scaffold/test/bite-proof.test.sh +159 -0
  818. package/skills/verification-scaffold/test/generator.test.sh +319 -0
  819. package/skills/verification-scaffold/test/manifest.test.sh +144 -0
  820. package/skills/work/SKILL.md +1480 -0
  821. package/skills/work/references/end-of-work-resume.md +7 -0
  822. package/skills/work/references/hook-test-main-cwd.md +24 -0
  823. package/skills/work/references/key-principles.md +83 -0
  824. package/skills/work/references/property-testing.md +122 -0
  825. package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
  826. package/skills/work/references/work-agent-teams.md +97 -0
  827. package/skills/work/references/work-lifecycle-parallel.md +147 -0
  828. package/skills/work/references/work-lockfile-bumps.md +97 -0
  829. package/skills/work/references/work-scratch-sandboxes.md +212 -0
  830. package/skills/work/references/work-subagent-fanout.md +61 -0
  831. package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
  832. package/skills/xcode-test/SKILL.md +360 -0
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env bash
2
+ # Bite-proof coverage for verification-scaffold.sh (#10404): installs the v1 set
3
+ # into a fixture repo and drives each emitted guard pass -> fail -> pass —
4
+ # independent of the generator's own internal bite (this suite RE-drives the
5
+ # emitted artifacts as a consumer would). Needs gitleaks on PATH for the
6
+ # secret-scan arm; that arm is skipped loudly when the binary is absent
7
+ # (matching the guard's own contract: a missing scanner is a tool error, not a
8
+ # finding). Runs in the scripts shard. Accumulate-then-exit.
9
+ set -uo pipefail
10
+ export TMPDIR="${TMPDIR:-/var/tmp}"
11
+
12
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
14
+ GEN="$REPO_ROOT/plugins/soleur/skills/verification-scaffold/scripts/verification-scaffold.sh"
15
+
16
+ passes=0; fails=0
17
+ pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
18
+ fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
19
+
20
+ TMPROOT="$(mktemp -d)"
21
+ # The body below is the CANONICAL copy of assert_fixture_dir (#7652) — do not reword.
22
+ assert_fixture_dir() {
23
+ case "${1-}" in
24
+ "") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
25
+ */../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
26
+ /proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
27
+ /|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
28
+ /*) : ;;
29
+ *) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
30
+ esac
31
+ }
32
+ trap 'rm -rf "$TMPROOT"' EXIT
33
+
34
+ mkrepo() { # mkrepo <name> -> committed fixture repo on main
35
+ local d="$TMPROOT/$1"
36
+ mkdir -p "$d"
37
+ git -C "$d" init -q
38
+ git -C "$d" config user.email t@t
39
+ git -C "$d" config user.name t
40
+ local t c
41
+ t="$(git -C "$d" write-tree)"
42
+ c="$(echo init | git -C "$d" commit-tree "$t")"
43
+ git -C "$d" update-ref refs/heads/main "$c"
44
+ git -C "$d" symbolic-ref HEAD refs/heads/main
45
+ printf '%s' "$d"
46
+ }
47
+
48
+ payload() { jq -nc --arg c "$1" --arg w "$2" '{tool_name:"Bash",tool_input:{command:$c},cwd:$w}'; }
49
+ decide() { sed -n 's/.*"permissionDecision": *"\([a-z]*\)".*/\1/p' | head -n 1; }
50
+
51
+ # --- install into the fixture ---------------------------------------------------
52
+ FX="$(mkrepo installed)"; assert_fixture_dir "$FX"
53
+ OUT="$(bash "$GEN" --target "$FX" --headless 2>&1)" || { fail "install failed: $OUT"; printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"; exit 1; }
54
+ grep -q 'bite-proof' <<<"$OUT" \
55
+ && pass "install reports the internal bite-proof per guard" \
56
+ || fail "install output carries no bite-proof lines: $OUT"
57
+ # The internal bite must have run all four arms (a SKIP is a failure HERE —
58
+ # gitleaks is expected on this host; on a host without it the arm prints SKIP).
59
+ for g in secret-scan commit-on-main block-stash orphan-test; do
60
+ if grep -q "bite-proof $g: pass -> fail" <<<"$OUT"; then
61
+ pass "internal bite-proof: $g pass -> fail -> pass"
62
+ elif [[ "$g" == "secret-scan" ]] && ! command -v gitleaks >/dev/null 2>&1 \
63
+ && grep -q "bite-proof secret-scan: SKIP" <<<"$OUT"; then
64
+ pass "internal bite-proof: secret-scan SKIP (no gitleaks on PATH — documented)"
65
+ else
66
+ fail "internal bite-proof arm missing or failed for $g: $(grep 'bite-proof' <<<"$OUT" | tr '\n' ';')"
67
+ fi
68
+ done
69
+
70
+ # --- commit-on-main, re-driven against the emitted pair --------------------------
71
+ HOOK="$FX/.claude/hooks/commit-on-main.sh"
72
+ # A fixture repo ON a feature branch: pass arm.
73
+ F2="$TMPROOT/feat-repo"; assert_fixture_dir "$F2"
74
+ mkdir -p "$F2"
75
+ git -C "$F2" init -q; git -C "$F2" config user.email t@t; git -C "$F2" config user.name t
76
+ git -C "$F2" symbolic-ref HEAD refs/heads/main
77
+ t="$(git -C "$F2" write-tree)"; c="$(echo x | git -C "$F2" commit-tree "$t")"; git -C "$F2" update-ref refs/heads/main "$c"
78
+ git -C "$F2" checkout -qb feat-x
79
+ OUT="$(cd "$FX" && payload "git -C $F2 commit -m x" "$F2" | bash "$HOOK")"
80
+ [[ "$(decide <<<"$OUT")" == "allow" ]] && pass "commit-on-main: feature-branch payload allowed" \
81
+ || fail "commit-on-main feature branch: $OUT"
82
+ # On main: advisory warn+allow with a refusal WARN on stderr.
83
+ git -C "$F2" checkout -q main
84
+ ERR="$TMPROOT/err"; OUT="$(cd "$FX" && payload "git -C $F2 commit -m x" "$F2" | bash "$HOOK" 2>"$ERR")"
85
+ if [[ "$(decide <<<"$OUT")" == "allow" ]] && grep -qE 'not allowed|refused' "$ERR"; then
86
+ pass "commit-on-main: main payload warns+allows (advisory)"
87
+ else
88
+ fail "commit-on-main main arm: out=$OUT err=$(cat "$ERR")"
89
+ fi
90
+ # Enforce flip is one line: MODE=enforce denies.
91
+ sed 's/^MODE="advisory"$/MODE="enforce"/' "$HOOK" > "$TMPROOT/hook-enf.sh"
92
+ OUT="$(cd "$FX" && payload "git -C $F2 commit -m x" "$F2" | bash "$TMPROOT/hook-enf.sh" 2>/dev/null)"
93
+ [[ "$(decide <<<"$OUT")" == "deny" ]] && pass "commit-on-main: MODE=enforce flip denies (one-line promotion)" \
94
+ || fail "enforce flip did not deny: $OUT"
95
+
96
+ # --- block-stash ------------------------------------------------------------------
97
+ HOOK="$FX/.claude/hooks/block-stash.sh"
98
+ OUT="$(cd "$FX" && payload "git status" "$FX" | bash "$HOOK")"
99
+ [[ "$(decide <<<"$OUT")" == "allow" ]] && pass "block-stash: git status allowed" \
100
+ || fail "block-stash status: $OUT"
101
+ ERR="$TMPROOT/err2"; OUT="$(cd "$FX" && payload "git add x && git stash pop" "$FX" | bash "$HOOK" 2>"$ERR")"
102
+ if [[ "$(decide <<<"$OUT")" == "allow" ]] && grep -q 'not allowed' "$ERR"; then
103
+ pass "block-stash: chained 'git stash pop' warns+allows"
104
+ else
105
+ fail "block-stash stash arm: out=$OUT err=$(cat "$ERR")"
106
+ fi
107
+ OUT="$(cd "$FX" && payload "git stash list" "$FX" | bash "$HOOK")"
108
+ [[ "$(decide <<<"$OUT")" == "allow" ]] && pass "block-stash: read-only 'git stash list' allowed" \
109
+ || fail "block-stash stash list: $OUT"
110
+
111
+ # --- orphan-test ------------------------------------------------------------------
112
+ CHECK="$FX/scripts/verification/orphan-test-check.sh"
113
+ OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" && pass "orphan-test: clean tree passes" \
114
+ || fail "orphan-test clean tree: $OUT"
115
+ printf '#!/usr/bin/env bash\nexit 0\n' > "$FX/scratch.test.sh"
116
+ git -C "$FX" add scratch.test.sh
117
+ RC=0; OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" || RC=$?
118
+ if [[ "$RC" -ne 0 && "$OUT" == *scratch.test.sh* ]]; then
119
+ pass "orphan-test: injected unregistered suite named by path"
120
+ else
121
+ fail "orphan-test injected suite: rc=$RC out=$OUT"
122
+ fi
123
+ # Reason-carrying exclusion registers it.
124
+ printf 'scratch.test.sh # deliberate exclusion for the bite suite\n' >> "$FX/.github/verification-known-orphans.txt"
125
+ OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" && pass "orphan-test: reasoned exclusion passes" \
126
+ || fail "orphan-test exclusion arm: $OUT"
127
+ # A reasonless exclusion line is itself a finding.
128
+ printf 'scratch.test.sh\n' >> "$FX/.github/verification-known-orphans.txt"
129
+ RC=0; OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" || RC=$?
130
+ [[ "$RC" -ne 0 && "$OUT" == *reasonless* ]] && pass "orphan-test: reasonless exclusion is a finding" \
131
+ || fail "orphan-test reasonless arm: rc=$RC out=$OUT"
132
+ git -C "$FX" rm -q --cached scratch.test.sh 2>/dev/null; rm -f "$FX/scratch.test.sh"
133
+ git -C "$FX" checkout -q -- .github/verification-known-orphans.txt 2>/dev/null \
134
+ || git -C "$FX" restore --staged --worktree .github/verification-known-orphans.txt 2>/dev/null || true
135
+
136
+ # --- secret-scan (skipped without gitleaks) ---------------------------------------
137
+ HOOK="$FX/.claude/hooks/secret-scan.sh"
138
+ if command -v gitleaks >/dev/null 2>&1; then
139
+ printf 'x\n' > "$FX/clean.txt"; git -C "$FX" add clean.txt
140
+ OUT="$(cd "$FX" && payload "git commit -m x" "$FX" | bash "$HOOK" 2>/dev/null)"
141
+ [[ "$(decide <<<"$OUT")" == "allow" ]] && pass "secret-scan: clean staged file allows" \
142
+ || fail "secret-scan clean arm: $OUT"
143
+ # Synthetic-but-shaped secret (the AWS docs example key is allowlisted in
144
+ # gitleaks's default ruleset — this variant keeps the 40-char shape only).
145
+ printf 'AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYSYNTHETIC0"\n' > "$FX/secret.txt"
146
+ git -C "$FX" add secret.txt
147
+ OUT="$(cd "$FX" && payload "git commit -m x" "$FX" | bash "$HOOK" 2>/dev/null)"
148
+ [[ "$(decide <<<"$OUT")" == "ask" ]] && pass "secret-scan: staged secret surfaces as ask (advisory)" \
149
+ || fail "secret-scan secret arm: $OUT"
150
+ git -C "$FX" rm -q --cached secret.txt; rm -f "$FX/secret.txt"
151
+ OUT="$(cd "$FX" && payload "git commit -m x" "$FX" | bash "$HOOK" 2>/dev/null)"
152
+ [[ "$(decide <<<"$OUT")" == "allow" ]] && pass "secret-scan: reverted tree allows again" \
153
+ || fail "secret-scan revert arm: $OUT"
154
+ else
155
+ pass "secret-scan arms skipped (no gitleaks on PATH — the hook warns+allows per commit)"
156
+ fi
157
+
158
+ printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"
159
+ [[ "$fails" -eq 0 ]]
@@ -0,0 +1,319 @@
1
+ #!/usr/bin/env bash
2
+ # Generator coverage for verification-scaffold.sh (#10404) against HERMETIC
3
+ # fixture repos — a throwaway `git init` per arm under a mktemp dir. Covers the
4
+ # flag/exit-matrix paths that need no gitleaks:
5
+ # 64 --mode bogus; unknown guard
6
+ # 65 --target outside a git work tree
7
+ # 66 refuse-if-exists (pre-placed artifact; full second run)
8
+ # 69 malformed .claude/settings.json refused BEFORE any write
9
+ # settings merge: absent created, unrelated keys preserved, re-run dedupe
10
+ # --dry-run writes nothing; --uninstall is surgical + idempotent
11
+ # --guards subset emits only that guard's artifacts
12
+ # Runs in the scripts shard. Accumulate-then-exit.
13
+ set -uo pipefail
14
+ export TMPDIR="${TMPDIR:-/var/tmp}"
15
+
16
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
18
+ GEN="$REPO_ROOT/plugins/soleur/skills/verification-scaffold/scripts/verification-scaffold.sh"
19
+
20
+ passes=0; fails=0
21
+ pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
22
+ fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
23
+
24
+ TMPROOT="$(mktemp -d)"
25
+ # The body below is the CANONICAL copy of assert_fixture_dir (#7652) — do not reword.
26
+ assert_fixture_dir() {
27
+ case "${1-}" in
28
+ "") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
29
+ */../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
30
+ /proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
31
+ /|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
32
+ /*) : ;;
33
+ *) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
34
+ esac
35
+ }
36
+ trap 'rm -rf "$TMPROOT"' EXIT
37
+
38
+ mkrepo() { # mkrepo <name> -> fixture git repo path (empty tree, one commit)
39
+ local d="$TMPROOT/$1"
40
+ mkdir -p "$d"
41
+ git -C "$d" init -q
42
+ git -C "$d" config user.email t@t
43
+ git -C "$d" config user.name t
44
+ local t c
45
+ t="$(git -C "$d" write-tree)"
46
+ c="$(echo init | git -C "$d" commit-tree "$t")"
47
+ git -C "$d" update-ref refs/heads/main "$c"
48
+ git -C "$d" symbolic-ref HEAD refs/heads/main
49
+ printf '%s' "$d"
50
+ }
51
+
52
+ run_gen() { # run_gen <repo> <args...> -> rc (never aborts the suite)
53
+ local root="$1"; shift
54
+ local rc=0
55
+ bash "$GEN" --target "$root" "$@" >/dev/null 2>&1 || rc=$?
56
+ printf '%s' "$rc"
57
+ }
58
+
59
+ run_gen_out() { # run_gen_out <repo> <args...> -> "rc|stdout"
60
+ local root="$1"; shift
61
+ local rc=0 out
62
+ out="$(bash "$GEN" --target "$root" "$@" 2>/dev/null)" || rc=$?
63
+ printf '%s|%s' "$rc" "$out"
64
+ }
65
+
66
+ # --- 65: not a git work tree ---------------------------------------------------
67
+ NOTREPO="$TMPROOT/notrepo"; mkdir -p "$NOTREPO"
68
+ RC="$(run_gen "$NOTREPO" --headless)"
69
+ [[ "$RC" == "65" ]] && pass "exit 65: target outside a git work tree refused" \
70
+ || fail "expected 65 for non-repo target, got $RC"
71
+
72
+ # --- 64: --mode bogus / unknown guard -------------------------------------------
73
+ FX="$(mkrepo modebogus)"; assert_fixture_dir "$FX"
74
+ RC="$(run_gen "$FX" --mode bogus --headless)"
75
+ [[ "$RC" == "64" ]] && pass "exit 64: --mode bogus refused pre-write" \
76
+ || fail "expected 64 for --mode bogus, got $RC"
77
+ RC="$(run_gen "$FX" --guards nosuchguard --headless)"
78
+ [[ "$RC" == "64" ]] && pass "exit 64: unknown guard refused" \
79
+ || fail "expected 64 for unknown guard, got $RC"
80
+
81
+ # --- 69: malformed settings.json refused BEFORE any write -----------------------
82
+ FX="$(mkrepo badsettings)"; assert_fixture_dir "$FX"
83
+ mkdir -p "$FX/.claude"
84
+ printf '{not json' > "$FX/.claude/settings.json"
85
+ RC="$(run_gen "$FX" --headless)"
86
+ if [[ "$RC" == "69" ]] && [[ ! -e "$FX/.claude/hooks/secret-scan.sh" ]] \
87
+ && [[ "$(cat "$FX/.claude/settings.json")" == '{not json' ]]; then
88
+ pass "exit 69: malformed settings.json refused before any write (file untouched)"
89
+ else
90
+ fail "malformed settings.json arm: rc=$RC settings=$(cat "$FX/.claude/settings.json" 2>/dev/null)"
91
+ fi
92
+
93
+ # --- 66: pre-existing artifact refuses -------------------------------------------
94
+ FX="$(mkrepo collides)"; assert_fixture_dir "$FX"
95
+ mkdir -p "$FX/.claude/hooks"
96
+ printf '# mine\n' > "$FX/.claude/hooks/secret-scan.sh"
97
+ RC="$(run_gen "$FX" --headless)"
98
+ [[ "$RC" == "66" && "$(cat "$FX/.claude/hooks/secret-scan.sh")" == '# mine' ]] \
99
+ && pass "exit 66: pre-existing hook refuses, zero writes (file untouched)" \
100
+ || fail "expected 66 with untouched file, got rc=$RC"
101
+
102
+ # pre-existing .gitleaks.toml also refuses (AC5)
103
+ FX="$(mkrepo glcollide)"; assert_fixture_dir "$FX"
104
+ printf '[extend]\nuseDefault = false\n' > "$FX/.gitleaks.toml"
105
+ RC="$(run_gen "$FX" --headless)"
106
+ [[ "$RC" == "66" && "$(cat "$FX/.gitleaks.toml")" == "[extend]
107
+ useDefault = false" ]] \
108
+ && pass "exit 66: pre-existing .gitleaks.toml refuses (never overwrites a user ruleset)" \
109
+ || fail "expected 66 for pre-existing .gitleaks.toml, got rc=$RC"
110
+
111
+ # --- --guards subset -------------------------------------------------------------
112
+ FX="$(mkrepo subset)"; assert_fixture_dir "$FX"
113
+ RC="$(run_gen "$FX" --guards block-stash --headless)"
114
+ if [[ "$RC" == "0" && -f "$FX/.claude/hooks/block-stash.sh" \
115
+ && ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.github/workflows/verification-gates.yml" ]]; then
116
+ pass "--guards block-stash emits only that guard's artifacts"
117
+ else
118
+ fail "subset install wrong: rc=$RC $(ls "$FX/.claude/hooks" 2>/dev/null | tr '\n' ' ')"
119
+ fi
120
+ grep -q 'block-stash' "$FX/.claude/settings.json" 2>/dev/null \
121
+ && pass "subset install registered the hook in settings.json" \
122
+ || fail "subset install: no settings.json hook entry"
123
+
124
+ # --- --dry-run writes nothing ----------------------------------------------------
125
+ FX="$(mkrepo dryrun)"; assert_fixture_dir "$FX"
126
+ OUT="$(run_gen_out "$FX" --dry-run)"
127
+ if [[ "${OUT%%|*}" == "0" && ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.claude/settings.json" ]]; then
128
+ pass "--dry-run exits 0 and writes nothing"
129
+ else
130
+ fail "dry-run arm: rc=${OUT%%|*}"
131
+ fi
132
+
133
+ # --- full install + advisory markers (AC3) ---------------------------------------
134
+ FX="$(mkrepo full)"; assert_fixture_dir "$FX"
135
+ RC="$(run_gen "$FX" --headless)"
136
+ [[ "$RC" == "0" ]] || fail "advisory install failed rc=$RC"
137
+ G=1
138
+ for p in .claude/hooks/secret-scan.sh .claude/hooks/commit-on-main.sh .claude/hooks/block-stash.sh \
139
+ scripts/verification/precommit-guard.sh scripts/verification/lib/wrapper-boundary.sh \
140
+ scripts/verification/orphan-test-check.sh .gitleaks.toml \
141
+ .github/workflows/verification-gates.yml .github/verification-known-orphans.txt \
142
+ .claude/settings.json VERIFICATION.md; do
143
+ [[ -f "$FX/$p" ]] || { G=0; fail "missing emitted artifact: $p"; }
144
+ done
145
+ [[ "$G" == "1" ]] && pass "advisory install emits all v1 artifacts"
146
+ grep -q 'MODE="advisory"' "$FX/.claude/hooks/secret-scan.sh" \
147
+ && grep -q 'MODE="advisory"' "$FX/.claude/hooks/commit-on-main.sh" \
148
+ && grep -q 'MODE="advisory"' "$FX/.claude/hooks/block-stash.sh" \
149
+ && pass "advisory install stamps MODE=advisory in every hook" \
150
+ || fail "MODE=advisory stamp missing in an emitted hook"
151
+ test "$(grep -c 'continue-on-error: true' "$FX/.github/workflows/verification-gates.yml")" = 2 \
152
+ && pass "advisory workflow carries continue-on-error: true on both jobs" \
153
+ || fail "advisory workflow continue-on-error wrong: $(grep -c 'continue-on-error' "$FX/.github/workflows/verification-gates.yml")"
154
+ if grep -rqE '@(MODE|CI_CONTINUE_ON_ERROR|DEFAULT_BRANCHES|GUARD_LIST|GUARD_TABLE|DATE)@' \
155
+ "$FX/.claude/hooks" "$FX/scripts/verification" "$FX/.github/workflows/verification-gates.yml" "$FX/VERIFICATION.md" 2>/dev/null; then
156
+ fail "unsubstituted placeholder leaked into emitted artifacts"
157
+ else
158
+ pass "no unsubstituted @PLACEHOLDER@ leaks into emitted artifacts"
159
+ fi
160
+ grep -q 'verification-scaffold:readme:start' "$FX/VERIFICATION.md" \
161
+ && pass "VERIFICATION.md created with the marker-keyed doc block" \
162
+ || fail "VERIFICATION.md doc block missing"
163
+
164
+ # settings.json: hook entries present, dedupe on command string
165
+ node -e '
166
+ const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
167
+ const cmds = d.hooks.PreToolUse.flatMap(m => m.hooks.map(h => h.command));
168
+ for (const n of ["secret-scan", "commit-on-main", "block-stash"])
169
+ if (!cmds.some(c => c.includes("/.claude/hooks/" + n + ".sh"))) process.exit(3);
170
+ ' "$FX/.claude/settings.json" \
171
+ && pass "settings.json registers all three hook commands" \
172
+ || fail "settings.json hook entries missing"
173
+
174
+ # --- enforce mode flips only the decision verb (AC3/Guard 6) ---------------------
175
+ FX="$(mkrepo enforce)"; assert_fixture_dir "$FX"
176
+ RC="$(run_gen "$FX" --mode enforce --headless)"
177
+ if [[ "$RC" == "0" ]]; then
178
+ grep -q 'MODE="enforce"' "$FX/.claude/hooks/block-stash.sh" \
179
+ && grep -q 'continue-on-error: false' "$FX/.github/workflows/verification-gates.yml" \
180
+ && pass "enforce install stamps MODE=enforce + continue-on-error: false" \
181
+ || fail "enforce stamps wrong"
182
+ else
183
+ fail "enforce install failed rc=$RC"
184
+ fi
185
+
186
+ # --- re-run refuses (AC5) ---------------------------------------------------------
187
+ RC="$(run_gen "$FX" --headless)"
188
+ [[ "$RC" == "66" ]] && pass "second full run refuses (66), zero writes" \
189
+ || fail "expected 66 on second run, got $RC"
190
+
191
+ # --- idempotent merge: manually re-add the same command -> stays single ----------
192
+ # (The generator refuses before reaching the merge, so prove dedupe via a repo
193
+ # whose ONLY drift is a missing settings entry while artifacts exist is refused
194
+ # anyway — instead assert the emitted file itself: a merge that ran twice would
195
+ # carry two identical command strings.)
196
+ node -e '
197
+ const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
198
+ const cmds = d.hooks.PreToolUse.flatMap(m => m.hooks.map(h => h.command));
199
+ if (new Set(cmds).size !== cmds.length) process.exit(3);
200
+ ' "$FX/.claude/settings.json" \
201
+ && pass "settings.json has no duplicate hook commands" \
202
+ || fail "duplicate hook commands in settings.json"
203
+
204
+ # --- merge preserves unrelated entries ------------------------------------------
205
+ FX="$(mkrepo preserve)"; assert_fixture_dir "$FX"
206
+ mkdir -p "$FX/.claude"
207
+ printf '%s\n' '{"permissions":{"allow":["Bash(ls:*)"]},"hooks":{"PreToolUse":[{"matcher":"Write","hooks":[{"type":"command","command":"keepme"}]}]}}' > "$FX/.claude/settings.json"
208
+ RC="$(run_gen "$FX" --guards block-stash --headless)"
209
+ if [[ "$RC" == "0" ]]; then
210
+ node -e '
211
+ const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
212
+ const ok = d.permissions.allow.includes("Bash(ls:*)")
213
+ && d.hooks.PreToolUse.some(m => m.hooks.some(h => h.command === "keepme"))
214
+ && d.hooks.PreToolUse.some(m => m.hooks.some(h => h.command.includes("block-stash")));
215
+ process.exit(ok ? 0 : 3);
216
+ ' "$FX/.claude/settings.json" \
217
+ && pass "merge preserves unrelated permissions + hook entries" \
218
+ || fail "merge clobbered unrelated settings.json entries"
219
+ else
220
+ fail "preserve install failed rc=$RC"
221
+ fi
222
+
223
+ # --- --uninstall: surgical + idempotent (AC5/SpecFlow 5) --------------------------
224
+ RC="$(run_gen "$FX" --uninstall block-stash)"
225
+ if [[ "$RC" == "0" && ! -e "$FX/.claude/hooks/block-stash.sh" ]]; then
226
+ node -e '
227
+ const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
228
+ const cmds = d.hooks.PreToolUse.flatMap(m => m.hooks.map(h => h.command));
229
+ process.exit(cmds.some(c => c.includes("block-stash")) || !cmds.includes("keepme") ? 3 : 0);
230
+ ' "$FX/.claude/settings.json" \
231
+ && pass "--uninstall removes the artifact + settings entry, leaves siblings" \
232
+ || fail "uninstall left a block-stash settings entry or removed keepme"
233
+ else
234
+ fail "uninstall block-stash: rc=$RC artifact=$(ls "$FX/.claude/hooks" 2>/dev/null | tr '\n' ' ')"
235
+ fi
236
+ RC="$(run_gen "$FX" --uninstall block-stash)"
237
+ [[ "$RC" == "0" ]] && pass "--uninstall on a removed guard is a clean no-op (exit 0)" \
238
+ || fail "idempotent uninstall expected rc=0, got $RC"
239
+
240
+ # --- --list ----------------------------------------------------------------------
241
+ OUT="$(run_gen_out "$FX" --list)"
242
+ [[ "${OUT%%|*}" == "0" ]] && grep -q 'secret-scan' <<<"${OUT#*|}" \
243
+ && pass "--list prints the guard manifest" \
244
+ || fail "--list failed: ${OUT%%|*}"
245
+
246
+ # --- 64: a v2-candidate guard is refused (#10759) --------------------------------
247
+ FX="$(mkrepo v2refuse)"; assert_fixture_dir "$FX"
248
+ RC="$(run_gen "$FX" --guards block-rm-rf --headless)"
249
+ [[ "$RC" == "64" && ! -e "$FX/.claude/hooks/block-rm-rf.sh" ]] \
250
+ && pass "exit 64: v2-candidate guard refused, nothing emitted" \
251
+ || fail "expected 64 for v2-tier guard, got $RC"
252
+
253
+ # --- 69: TMPDIR resolving inside the repo is refused pre-write (#10759) ----------
254
+ FX="$(mkrepo tmpinside)"; assert_fixture_dir "$FX"
255
+ mkdir -p "$FX/tmp"
256
+ RC=0; TMPDIR="$FX/tmp" bash "$GEN" --target "$FX" --headless >/dev/null 2>&1 || RC=$?
257
+ if [[ "$RC" == "69" && ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.claude/settings.json" ]]; then
258
+ pass "exit 69: TMPDIR inside the target repo refused before any artifact"
259
+ else
260
+ fail "TMPDIR-inside-repo arm: expected 69, got rc=$RC"
261
+ fi
262
+
263
+ # --- --uninstall secret-scan: strip only its job from the shared workflow --------
264
+ FX="$(mkrepo jobstrip)"; assert_fixture_dir "$FX"
265
+ RC="$(run_gen "$FX" --guards secret-scan,orphan-test --headless)"
266
+ [[ "$RC" == "0" ]] || fail "secret-scan+orphan-test install failed rc=$RC"
267
+ OUT="$(run_gen_out "$FX" --uninstall secret-scan)"
268
+ if [[ "${OUT%%|*}" == "0" && "${OUT#*|}" == *job-stripped* \
269
+ && -f "$FX/.github/workflows/verification-gates.yml" \
270
+ && -f "$FX/scripts/verification/orphan-test-check.sh" \
271
+ && ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.gitleaks.toml" ]]; then
272
+ pass "--uninstall secret-scan strips only its job block from the shared workflow"
273
+ else
274
+ fail "shared-artifact uninstall arm: rc=${OUT%%|*} out=${OUT#*|}"
275
+ fi
276
+ WF="$FX/.github/workflows/verification-gates.yml"
277
+ if grep -qF '# verification-scaffold:begin:orphan-test' "$WF" \
278
+ && ! grep -qF 'verification-scaffold:begin:secret-scan' "$WF"; then
279
+ pass "shared workflow keeps the orphan-test job, drops secret-scan's"
280
+ else
281
+ fail "shared workflow job blocks wrong after strip: $(grep -c 'begin:' "$WF" 2>/dev/null)"
282
+ fi
283
+
284
+ # --- --uninstall of a never-installed ci guard: no phantom job-strip (#10759) -----
285
+ FX="$(mkrepo neverci)"; assert_fixture_dir "$FX"
286
+ RC="$(run_gen "$FX" --guards secret-scan --headless)"
287
+ [[ "$RC" == "0" ]] || fail "secret-scan-only install failed rc=$RC"
288
+ OUT="$(run_gen_out "$FX" --uninstall orphan-test)"
289
+ if [[ "${OUT%%|*}" == "0" && "${OUT#*|}" == *"not installed"* && "${OUT#*|}" != *"job-stripped"* ]]; then
290
+ pass "--uninstall of a never-installed ci guard reports not-installed (no phantom job-strip)"
291
+ else
292
+ fail "never-installed ci guard arm: rc=${OUT%%|*} out=${OUT#*|}"
293
+ fi
294
+ grep -qF 'verification-scaffold:begin:secret-scan' "$FX/.github/workflows/verification-gates.yml" \
295
+ && pass "shared workflow untouched by the never-installed guard's uninstall" \
296
+ || fail "workflow lost its secret-scan block on a phantom uninstall"
297
+
298
+ # --- doc block is pruned once no v1 artifact remains (#10759) --------------------
299
+ OUT="$(run_gen_out "$FX" --uninstall secret-scan)"
300
+ if [[ "${OUT%%|*}" == "0" && ! -e "$FX/VERIFICATION.md" \
301
+ && ! -e "$FX/.github/workflows/verification-gates.yml" ]]; then
302
+ pass "last-guard uninstall prunes the stale VERIFICATION.md marker block"
303
+ else
304
+ fail "doc-block prune arm: rc=${OUT%%|*} VERIFICATION.md=$(ls "$FX/VERIFICATION.md" 2>/dev/null || echo absent)"
305
+ fi
306
+
307
+ # --- default branch named a&b still emits a working regex (#10759) ----------------
308
+ FX="$(mkrepo ampbranch)"; assert_fixture_dir "$FX"
309
+ git -C "$FX" update-ref refs/remotes/origin/a\&b "$(git -C "$FX" rev-parse HEAD)"
310
+ git -C "$FX" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/a\&b
311
+ RC="$(run_gen "$FX" --guards commit-on-main --mode enforce --headless)"
312
+ if [[ "$RC" == "0" ]] && ! grep -qF '@DEFAULT_BRANCHES@' "$FX/scripts/verification/precommit-guard.sh"; then
313
+ pass "default branch 'a&b': emitted regex is literal — enforce install + bite green"
314
+ else
315
+ fail "a&b default-branch arm: rc=$RC"
316
+ fi
317
+
318
+ printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"
319
+ [[ "$fails" -eq 0 ]]
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env bash
2
+ # Manifest consistency for verification-scaffold (#10404):
3
+ # 1. every guards.tsv v1 row's templates exist under references/, and every
4
+ # references/guards/*.template is named by some v1 row (no orphans either way);
5
+ # 2. every audit corpus member (.claude/hooks/**/*.sh non-test + scripts/lint-*
6
+ # minus .test.sh/.baseline.txt/.highwater) appears in guardrail-audit.md —
7
+ # the census is git-ls-files driven, so a NEW unclassified member reds CI;
8
+ # 3. one-hunk parity (AC11): precommit-guard.sh.template renders byte-identical
9
+ # to plugins/soleur/scripts/precommit-guard.sh under the default
10
+ # main|master substitution and the VERIFICATION_->SOLEUR_ rename; the
11
+ # wrapper-boundary pair is the same rename-normalized cmp;
12
+ # 4. emitted-content hygiene (AC8): zero SOLEUR_/knowledge-base//plugins/soleur
13
+ # refs and zero curl|wget|https?:// tokens outside comments in templates;
14
+ # 5. portability floor: no GNU-only tokens (sed -i, readlink -f, stat -c,
15
+ # date -d, bc, /usr/bin/time, unguarded `timeout`) in emitted templates;
16
+ # 6. the emitted verification-gates.yml renders actionlint-clean (when
17
+ # actionlint is on PATH).
18
+ # Runs in the scripts shard. Accumulate-then-exit.
19
+ set -uo pipefail
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
23
+ SKILL="$REPO_ROOT/plugins/soleur/skills/verification-scaffold"
24
+ TSV="$SKILL/references/guards.tsv"
25
+ AUDIT="$SKILL/references/guardrail-audit.md"
26
+
27
+ passes=0; fails=0
28
+ pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
29
+ fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
30
+
31
+ # --- 1. guards.tsv v1 rows <-> templates -----------------------------------------
32
+ missing=0
33
+ while IFS=$'\t' read -r name verdict surfaces templates dmode deps src emits tier; do
34
+ case "$name" in \#*|name) continue ;; esac
35
+ [[ "$tier" == "v1" ]] || continue
36
+ [[ -n "$name" && -n "$templates" && -n "$emits" ]] || { fail "guards.tsv row malformed: $name"; missing=1; continue; }
37
+ IFS=';' read -ra tp <<<"$templates"
38
+ for t in "${tp[@]}"; do
39
+ [[ -f "$SKILL/$t" ]] || { fail "guards.tsv $name names missing template: $t"; missing=1; }
40
+ done
41
+ done < "$TSV"
42
+ [[ "$missing" -eq 0 ]] && pass "every v1 row's templates exist"
43
+
44
+ orphaned=0
45
+ while IFS= read -r t; do
46
+ rel="${t#"$SKILL/"}"
47
+ # A template is owned by a guards.tsv row (guard artifacts) or by the
48
+ # generator itself (the doc block: verification-readme.template).
49
+ grep -qF "$rel" "$TSV" || grep -qF "$rel" "$SKILL/scripts/verification-scaffold.sh" \
50
+ || { fail "orphaned template (named by nothing): $rel"; orphaned=1; }
51
+ done < <(find "$SKILL/references" -name '*.template' | sort)
52
+ [[ "$orphaned" -eq 0 ]] && pass "every template is named by a guards.tsv row or the generator"
53
+
54
+ # --- 2. audit census over the live tree -------------------------------------------
55
+ # The producer is git ls-files — identical to this file's own corpus definition,
56
+ # so a new member lacking an audit row is caught here, not by review.
57
+ uncov=0
58
+ while IFS= read -r f; do
59
+ base="$(basename "$f")"
60
+ grep -qF "$base" "$AUDIT" || { fail "audit has no row for $f"; uncov=1; }
61
+ done < <(git -C "$REPO_ROOT" ls-files '.claude/hooks/*.sh' | grep -v '\.test\.sh$' | grep -v '/test/')
62
+ while IFS= read -r f; do
63
+ base="$(basename "$f")"
64
+ grep -qF "$base" "$AUDIT" || { fail "audit has no row for $f"; uncov=1; }
65
+ done < <(git -C "$REPO_ROOT" ls-files 'scripts/lint-*' | grep -v '\.test\.sh$\|\.baseline\.txt$\|\.highwater')
66
+ [[ "$uncov" -eq 0 ]] && pass "audit covers every corpus member (git ls-files census)"
67
+
68
+ # --- 3. one-hunk parity (AC11) ------------------------------------------------------
69
+ SRC_GUARD="$REPO_ROOT/plugins/soleur/scripts/precommit-guard.sh"
70
+ SRC_WRAP="$REPO_ROOT/plugins/soleur/scripts/lib/wrapper-boundary.sh"
71
+ rendered="$(mktemp)"; trap 'rm -f "$rendered"' EXIT
72
+ sed -e 's/VERIFICATION_/SOLEUR_/g' -e 's/@DEFAULT_BRANCHES@/main|master/g' \
73
+ "$SKILL/references/guards/precommit-guard.sh.template" > "$rendered"
74
+ cmp -s "$rendered" "$SRC_GUARD" \
75
+ && pass "precommit-guard template renders byte-identical to source under main|master" \
76
+ || fail "precommit-guard template/source drifted (run: diff <(sed -e s/VERIFICATION_/SOLEUR_/g -e s/@DEFAULT_BRANCHES@/main\\\\|master/g .../precommit-guard.sh.template) plugins/soleur/scripts/precommit-guard.sh)"
77
+ sed 's/VERIFICATION_/SOLEUR_/g' "$SKILL/references/guards/wrapper-boundary.sh.template" > "$rendered"
78
+ cmp -s "$rendered" "$SRC_WRAP" \
79
+ && pass "wrapper-boundary template is rename-normalized byte-identical to source" \
80
+ || fail "wrapper-boundary template/source drifted"
81
+
82
+ # --- 4. emitted-content hygiene (AC8) ----------------------------------------------
83
+ # Templates contain @PLACEHOLDER@ markers; the runtime text must carry zero
84
+ # Soleur couplings and zero network egress.
85
+ hyg=0
86
+ while IFS= read -r t; do
87
+ if grep -nE 'SOLEUR_|knowledge-base/|plugins/soleur' "$t" >/dev/null; then
88
+ fail "Soleur coupling in template $(basename "$t"): $(grep -nE 'SOLEUR_|knowledge-base/|plugins/soleur' "$t" | head -3 | tr '\n' ';')"
89
+ hyg=1
90
+ fi
91
+ # egress tokens outside comments: strip comment lines then grep.
92
+ if grep -vE '^[[:space:]]*#' "$t" | grep -nE 'curl|wget|https?://' >/dev/null; then
93
+ fail "network egress token in template $(basename "$t")"
94
+ hyg=1
95
+ fi
96
+ done < <(find "$SKILL/references" -name '*.template' | sort)
97
+ [[ "$hyg" -eq 0 ]] && pass "zero Soleur couplings + zero egress tokens in emitted templates"
98
+
99
+ # --- 5. portability floor ----------------------------------------------------------
100
+ # GNU-only forms banned in emitted templates (stock macOS must run them).
101
+ port=0
102
+ while IFS= read -r t; do
103
+ case "$t" in *.yml.template) continue ;; esac
104
+ if grep -nE 'sed -i|readlink -f|realpath|stat -c|date -d|/usr/bin/time|(^|[;&| ]|^[^#]*[;&| ])bc |mapfile' "$t" | grep -vE '^[0-9]+:[[:space:]]*#' >/dev/null; then
105
+ fail "GNU-only token in template $(basename "$t"): $(grep -nE 'sed -i|readlink -f|realpath|stat -c|date -d|/usr/bin/time|bc |mapfile' "$t" | grep -vE '^[0-9]+:[[:space:]]*#' | head -3 | tr '\n' ';')"
106
+ port=1
107
+ fi
108
+ if grep -nE '(^|[^_a-zA-Z])timeout [0-9]' "$t" | grep -v 'command -v timeout\|gtimeout' >/dev/null; then
109
+ fail "unguarded timeout invocation in $(basename "$t")"
110
+ port=1
111
+ fi
112
+ done < <(find "$SKILL/references" -name '*.template' | sort)
113
+ [[ "$port" -eq 0 ]] && pass "portability floor: no GNU-only forms in emitted templates"
114
+
115
+ # --- 6. actionlint on the RENDERED workflow ------------------------------------------
116
+ if command -v actionlint >/dev/null 2>&1; then
117
+ WF="$(mktemp -d)"
118
+ # Render like the generator does: keep both job blocks, stamp continue-on-error.
119
+ awk '{print}' "$SKILL/references/guards/verification-gates.yml.template" \
120
+ | sed 's/@CI_CONTINUE_ON_ERROR@/true/g' > "$WF/verification-gates.yml"
121
+ if actionlint -oneline "$WF/verification-gates.yml" >"$WF/lint.log" 2>&1; then
122
+ pass "rendered verification-gates.yml is actionlint-clean"
123
+ else
124
+ fail "actionlint reds on rendered workflow: $(cat "$WF/lint.log" | head -5 | tr '\n' ';')"
125
+ fi
126
+ rm -rf "$WF"
127
+ else
128
+ pass "actionlint not on PATH — workflow lint arm skipped (CI must provide it)"
129
+ fi
130
+
131
+ # --- 7. SKILL.md + audit + tsv exist and are non-empty -------------------------------
132
+ for f in "$SKILL/SKILL.md" "$AUDIT" "$TSV" "$SKILL/references/verification-readme.template" "$SKILL/references/gitleaks.toml.template"; do
133
+ [[ -s "$f" ]] || fail "missing/empty: ${f#"$REPO_ROOT"/}"
134
+ done
135
+ pass "required skill files exist (SKILL.md presence asserted by the file list)"
136
+
137
+ # guards.tsv: the emitted .gitleaks.toml is a default-ruleset pointer (Guard 1
138
+ # mutation-6 anchor — the template's declared ruleset shape is pinned here).
139
+ grep -q 'useDefault = true' "$SKILL/references/gitleaks.toml.template" \
140
+ && pass "gitleaks.toml.template is the default-ruleset pointer guards.tsv declares" \
141
+ || fail "gitleaks.toml.template lost its useDefault=true ruleset shape"
142
+
143
+ printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"
144
+ [[ "$fails" -eq 0 ]]