@soleur/opencode 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (812) 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 +659 -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 +108 -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 +342 -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 +152 -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 +493 -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 +363 -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 +520 -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 +113 -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 +178 -0
  247. package/scripts/sync-opencode-adapter.ts +479 -0
  248. package/scripts/sync-pr-behind.sh +534 -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 +65 -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 +142 -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 +118 -0
  493. package/skills/fix-issue/references/exclude-label-jq-snippet.md +96 -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 +668 -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 +325 -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 +138 -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 +1621 -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-todo-structure.md +165 -0
  674. package/skills/review/references/risk-tier-and-fix-rounds.md +95 -0
  675. package/skills/review/references/semgrep-custom-rules.yaml +174 -0
  676. package/skills/review/references/ultrathink-phases.md +98 -0
  677. package/skills/review/references/wfs.md +6 -0
  678. package/skills/review/scripts/emit-review-trailer.sh +499 -0
  679. package/skills/review/scripts/ensure-semgrep.sh +99 -0
  680. package/skills/review/scripts/fix-round-seats.sh +197 -0
  681. package/skills/review/test/emit-review-trailer.test.sh +387 -0
  682. package/skills/review/test/ensure-semgrep.test.sh +111 -0
  683. package/skills/review/test/fix-round-seats.test.sh +237 -0
  684. package/skills/review/workflows/README.md +147 -0
  685. package/skills/review/workflows/review.workflow.js +667 -0
  686. package/skills/schedule/SKILL.md +796 -0
  687. package/skills/seo-aeo/SKILL.md +139 -0
  688. package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
  689. package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
  690. package/skills/ship/SKILL.md +3022 -0
  691. package/skills/ship/references/adr-ordinal-collision.md +47 -0
  692. package/skills/ship/references/affected-gate-contract.md +115 -0
  693. package/skills/ship/references/ci-run-diagnosis.md +29 -0
  694. package/skills/ship/references/ci-workflow-authoring.md +68 -0
  695. package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
  696. package/skills/ship/references/cto-ruling-armed-push.md +5 -0
  697. package/skills/ship/references/decision-challenges-render.md +71 -0
  698. package/skills/ship/references/detached-battery-verdict.md +13 -0
  699. package/skills/ship/references/feature-tweet-draft.md +42 -0
  700. package/skills/ship/references/followthrough-issue-body-template.md +47 -0
  701. package/skills/ship/references/followthrough-stub-template.sh +92 -0
  702. package/skills/ship/references/merge-queue-dequeue.md +39 -0
  703. package/skills/ship/references/operator-holds.md +149 -0
  704. package/skills/ship/references/pipeline-tally-render.md +43 -0
  705. package/skills/ship/references/pr-overlap.md +153 -0
  706. package/skills/ship/references/queue-mode.md +7 -0
  707. package/skills/ship/references/ready-run-wait.md +36 -0
  708. package/skills/ship/references/red-on-main-quarantine.md +110 -0
  709. package/skills/ship/references/register-update-pr-pattern.md +88 -0
  710. package/skills/ship/references/settle-then-admin-merge.md +130 -0
  711. package/skills/ship/references/supabase-column-probe.md +13 -0
  712. package/skills/ship/scripts/auto-close-scan.sh +76 -0
  713. package/skills/ship/scripts/battery-owed.sh +403 -0
  714. package/skills/ship/scripts/hold-gate-eval.sh +410 -0
  715. package/skills/ship/scripts/net-issue-flow.sh +665 -0
  716. package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
  717. package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
  718. package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
  719. package/skills/skill-creator/SKILL.md +299 -0
  720. package/skills/skill-creator/references/api-security.md +248 -0
  721. package/skills/skill-creator/references/authoring-levers.md +110 -0
  722. package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
  723. package/skills/skill-creator/references/best-practices.md +431 -0
  724. package/skills/skill-creator/references/common-patterns.md +639 -0
  725. package/skills/skill-creator/references/core-principles.md +193 -0
  726. package/skills/skill-creator/references/executable-code.md +188 -0
  727. package/skills/skill-creator/references/iteration-and-testing.md +509 -0
  728. package/skills/skill-creator/references/official-spec.md +193 -0
  729. package/skills/skill-creator/references/recommended-structure.md +180 -0
  730. package/skills/skill-creator/references/skill-structure.md +396 -0
  731. package/skills/skill-creator/references/using-scripts.md +122 -0
  732. package/skills/skill-creator/references/using-templates.md +120 -0
  733. package/skills/skill-creator/references/workflows-and-validation.md +541 -0
  734. package/skills/skill-creator/scripts/init_skill.py +322 -0
  735. package/skills/skill-creator/scripts/package_skill.py +110 -0
  736. package/skills/skill-creator/scripts/quick_validate.py +64 -0
  737. package/skills/skill-creator/templates/router-skill.md +73 -0
  738. package/skills/skill-creator/templates/simple-skill.md +34 -0
  739. package/skills/skill-creator/workflows/add-reference.md +96 -0
  740. package/skills/skill-creator/workflows/add-script.md +104 -0
  741. package/skills/skill-creator/workflows/add-template.md +83 -0
  742. package/skills/skill-creator/workflows/add-workflow.md +128 -0
  743. package/skills/skill-creator/workflows/audit-skill.md +159 -0
  744. package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
  745. package/skills/skill-creator/workflows/create-new-skill.md +207 -0
  746. package/skills/skill-creator/workflows/get-guidance.md +134 -0
  747. package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
  748. package/skills/skill-creator/workflows/verify-skill.md +226 -0
  749. package/skills/skill-security-scan/SKILL.md +145 -0
  750. package/skills/skill-security-scan/references/disclaimer.md +21 -0
  751. package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
  752. package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
  753. package/skills/skill-security-scan/references/override-mechanism.md +171 -0
  754. package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
  755. package/skills/skill-security-scan/references/regex-patterns.md +136 -0
  756. package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
  757. package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
  758. package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
  759. package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
  760. package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
  761. package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
  762. package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
  763. package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
  764. package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
  765. package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
  766. package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
  767. package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
  768. package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
  769. package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
  770. package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
  771. package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
  772. package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
  773. package/skills/skill-security-scan/scripts/lib.sh +197 -0
  774. package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
  775. package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
  776. package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
  777. package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
  778. package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
  779. package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
  780. package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
  781. package/skills/social-distribute/SKILL.md +485 -0
  782. package/skills/spec-templates/SKILL.md +274 -0
  783. package/skills/sync/SKILL.md +49 -0
  784. package/skills/test-browser/SKILL.md +464 -0
  785. package/skills/test-browser/references/feature-map.md +161 -0
  786. package/skills/test-fix-loop/SKILL.md +159 -0
  787. package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
  788. package/skills/triage/SKILL.md +402 -0
  789. package/skills/trigger-cron/SKILL.md +136 -0
  790. package/skills/trigger-cron/scripts/trigger.sh +198 -0
  791. package/skills/user-set-role/SKILL.md +147 -0
  792. package/skills/user-set-role/scripts/set-role.sh +218 -0
  793. package/skills/user-story-writer/SKILL.md +77 -0
  794. package/skills/ux-audit/SKILL.md +251 -0
  795. package/skills/ux-audit/references/finding.schema.json +62 -0
  796. package/skills/ux-audit/references/route-list.yaml +95 -0
  797. package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
  798. package/skills/ux-audit/scripts/bot-signin.ts +135 -0
  799. package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
  800. package/skills/work/SKILL.md +1479 -0
  801. package/skills/work/references/end-of-work-resume.md +7 -0
  802. package/skills/work/references/hook-test-main-cwd.md +24 -0
  803. package/skills/work/references/key-principles.md +83 -0
  804. package/skills/work/references/property-testing.md +122 -0
  805. package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
  806. package/skills/work/references/work-agent-teams.md +97 -0
  807. package/skills/work/references/work-lifecycle-parallel.md +147 -0
  808. package/skills/work/references/work-lockfile-bumps.md +97 -0
  809. package/skills/work/references/work-scratch-sandboxes.md +212 -0
  810. package/skills/work/references/work-subagent-fanout.md +61 -0
  811. package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
  812. package/skills/xcode-test/SKILL.md +360 -0
@@ -0,0 +1,342 @@
1
+ #!/usr/bin/env bash
2
+ # run-scan.sh — orchestrate the five category checks, aggregate verdict,
3
+ # emit markdown findings + mandatory disclaimer footer, write .scan-meta.json
4
+ # (with PII redaction).
5
+ #
6
+ # Stdin: SKILL.md content. Or: positional file path.
7
+ # Stdout: markdown findings table + disclaimer footer.
8
+ # Exit code: NOT guaranteed 0. This header claimed "0 always (advisory)" and
9
+ # that was false the moment `set -euo pipefail` below was added: any internal
10
+ # command failure, unset variable, or failing pipeline aborts this script with a
11
+ # non-zero status. Callers MUST check it. The claim was load-bearing in the
12
+ # wrong direction -- the skill-security-scan workflows relied on it to justify
13
+ # `2>/dev/null | head -1 | grep ... || echo UNKNOWN`, which converted a crashed
14
+ # scanner into a verdict the gate then accepted (#7629).
15
+ #
16
+ # The VERDICT is advisory; the EXIT STATUS is not. A non-zero exit means no
17
+ # verdict was produced, which is not the same as a clean skill.
18
+
19
+ set -euo pipefail
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
23
+ SCANNER_VERSION="0.1.0"
24
+
25
+ # Resolve input file
26
+ if [ "$#" -ge 1 ] && [ -f "$1" ]; then
27
+ INPUT="$1"
28
+ CLEANUP=""
29
+ else
30
+ INPUT="$(mktemp -t skill-scan-input-XXXXXX)"
31
+ CLEANUP="$INPUT"
32
+ cat > "$INPUT"
33
+ fi
34
+ trap '[ -n "$CLEANUP" ] && rm -f "$CLEANUP"' EXIT
35
+
36
+ # ---------------------------------------------------------------------------
37
+ # Self-defense: rule-pack SHA validation (per Phase 5)
38
+ # ---------------------------------------------------------------------------
39
+ manifest="$SKILL_DIR/references/rules/manifest.yaml"
40
+ rule_pack_sha="unknown"
41
+ rule_pack_version="unknown"
42
+ if [ -f "$manifest" ]; then
43
+ rule_pack_version="$(awk '/^version:/ { gsub(/^version:[[:space:]]*"?|"?$/, ""); print; exit }' "$manifest")"
44
+ # Compute current manifest SHA over the manifest file itself for traceability.
45
+ rule_pack_sha="$(sha256sum "$manifest" | cut -d' ' -f1)"
46
+ # Validate per-file SHAs declared in manifest. Tampered file → flag and
47
+ # short-circuit to REVIEW. Manifest format: list of `- path:`/`sha256:`
48
+ # tuples relative to the rules/ directory.
49
+ tampered=""
50
+ while IFS= read -r line; do
51
+ case "$line" in
52
+ *path:*)
53
+ cur_path="${line#*path:}"
54
+ cur_path="${cur_path// /}"
55
+ cur_path="${cur_path//\"/}"
56
+ cur_path="${cur_path//\'/}"
57
+ ;;
58
+ *sha256:*)
59
+ cur_sha="${line#*sha256:}"
60
+ cur_sha="${cur_sha// /}"
61
+ cur_sha="${cur_sha//\"/}"
62
+ cur_sha="${cur_sha//\'/}"
63
+ actual="$(sha256sum "$SKILL_DIR/references/$cur_path" 2>/dev/null | cut -d' ' -f1 || echo "")"
64
+ if [ -n "$actual" ] && [ "$actual" != "$cur_sha" ]; then
65
+ tampered+="$cur_path "
66
+ fi
67
+ cur_path=""
68
+ ;;
69
+ esac
70
+ done < "$manifest"
71
+ if [ -n "$tampered" ]; then
72
+ # Tamper short-circuits to HIGH-RISK (deny-by-default), not REVIEW.
73
+ # Rationale: REVIEW maps to `ask` in the PreToolUse hook, which an operator
74
+ # can confirm-through; an attacker with rule-pack write access could then
75
+ # downgrade a real HIGH-RISK skill to REVIEW and have the operator accept.
76
+ # HIGH-RISK on tamper forces an override-artifact path and audit trail.
77
+ cat <<EOF
78
+ # skill-security-scan verdict: HIGH-RISK
79
+
80
+ **Self-defense:** rule pack tampered. Files with SHA mismatch:
81
+
82
+ $(echo "$tampered" | tr ' ' '\n' | grep -v '^$' | sed 's/^/ - /')
83
+
84
+ Re-run with \`scripts/run-self-test.sh --regenerate-manifest\` (dev) or fix
85
+ the rule pack before scanning. Override requires a structured artifact under
86
+ \`knowledge-base/engineering/security/skill-overrides/\`.
87
+
88
+ ---
89
+ Advisory static analysis only. LOW-RISK does not constitute a security audit,
90
+ certification, or warranty of safety. The skill executes in your environment
91
+ under your account; you remain responsible for review.
92
+
93
+ Scanner version: $SCANNER_VERSION Rule pack: ${rule_pack_sha:0:12} Scanned: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
94
+ EOF
95
+ exit 0
96
+ fi
97
+ fi
98
+
99
+ # ---------------------------------------------------------------------------
100
+ # Run the five category checks. Each consumes stdin (the SKILL.md content)
101
+ # and emits a JSON document on stdout. We collect into a temp dir.
102
+ # ---------------------------------------------------------------------------
103
+ results_dir="$(mktemp -dt skill-scan-results-XXXXXX)"
104
+ trap '[ -n "$CLEANUP" ] && rm -f "$CLEANUP"; rm -rf "$results_dir"' EXIT
105
+
106
+ run_category() {
107
+ local script="$1" out="$2"
108
+ bash "$SCRIPT_DIR/$script" < "$INPUT" > "$out" 2>/dev/null || \
109
+ echo '{"verdict":"REVIEW","category":"unknown","findings":[{"rule_id":"check-failed","severity":"REVIEW","line":0,"snippet":"category script error"}]}' > "$out"
110
+ }
111
+
112
+ run_category check-codeexec.sh "$results_dir/code-execution.json" &
113
+ run_category check-prompt-injection.sh "$results_dir/prompt-injection.json" &
114
+ run_category check-supply-chain.sh "$results_dir/supply-chain.json" &
115
+ run_category check-filesystem-boundary.sh "$results_dir/filesystem-boundary.json" &
116
+ run_category check-telemetry-surface.sh "$results_dir/telemetry-surface.json" &
117
+ wait
118
+
119
+ # Aggregate verdict (max-severity wins).
120
+ agg_verdict="LOW-RISK"
121
+ for f in "$results_dir"/*.json; do
122
+ v="$(jq -r '.verdict' "$f" 2>/dev/null || echo "REVIEW")"
123
+ case "$v" in
124
+ HIGH-RISK) agg_verdict="HIGH-RISK"; break ;;
125
+ REVIEW) [ "$agg_verdict" = "LOW-RISK" ] && agg_verdict="REVIEW" ;;
126
+ esac
127
+ done
128
+
129
+ # Build findings_summary JSON (with PII + secret redaction).
130
+ # Per GDPR-DataMin-1 (PII) and security review P2-4 (high-entropy secrets):
131
+ # redact email/IPv4/IBAN PLUS JWT, Anthropic/OpenAI keys, GitHub PAT/OAuth,
132
+ # Doppler tokens, GitLab PAT, Slack tokens, AWS access keys.
133
+ redact_pii() {
134
+ sed -E '
135
+ s/\bghp_[A-Za-z0-9._~+/=-]{20,}/<github-pat>/g;
136
+ s/\bgho_[A-Za-z0-9._~+/=-]{20,}/<github-oauth>/g;
137
+ s/\bghs_[A-Za-z0-9._~+/=-]{20,}/<github-server>/g;
138
+ s/\bghr_[A-Za-z0-9._~+/=-]{20,}/<github-refresh>/g;
139
+ s/\bghu_[A-Za-z0-9._~+/=-]{20,}/<github-user>/g;
140
+ s/\bgithub_pat_[A-Za-z0-9._~+/=-]{40,}/<github-pat>/g;
141
+ s/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/<email>/g;
142
+ s/\b([0-9]{1,3}\.){3}[0-9]{1,3}\b/<ip>/g;
143
+ s/\b[A-Z]{2}[0-9]{2}[A-Z0-9]{4,}\b/<iban>/g;
144
+ s/eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/<jwt>/g;
145
+ s/sk-ant-[A-Za-z0-9_-]{8,}/<anthropic-key>/g;
146
+ s/sk-[A-Za-z0-9]{20,}/<openai-key>/g;
147
+ s/\bglpat-[A-Za-z0-9_-]{8,}/<gitlab-pat>/g;
148
+ s/dp\.ct\.[A-Za-z0-9_-]{20,}/<doppler-token>/g;
149
+ s/dp\.pt\.[A-Za-z0-9_-]{20,}/<doppler-token>/g;
150
+ s/dp\.st\.[A-Za-z0-9_-]{20,}/<doppler-token>/g;
151
+ s/xox[bopas]-[A-Za-z0-9-]{10,}/<slack-token>/g;
152
+ s/\bAKIA[A-Z0-9]{16}\b/<aws-access-key>/g
153
+ '
154
+ }
155
+
156
+ # ARGV CEILING (#6736). Both the per-category body and the accumulated summary are
157
+ # kept in FILES and bound with `--rawfile … | fromjson`, never `--argjson`. A shell
158
+ # variable bound via --argjson is ONE argv argument, and the kernel caps a SINGLE argv
159
+ # argument at MAX_ARG_STRLEN = 131,072 B — verified by bisect on this host: 131,071 B
160
+ # passes, 131,072 B fails E2BIG. This is NOT `getconf ARG_MAX` (2,097,152 B, the
161
+ # argv+envp total); a payload at 6% of ARG_MAX still dies.
162
+ #
163
+ # Nothing bounds this: snippets are capped at 200 chars by apply_yaml_rules, but the
164
+ # FINDING COUNT is uncapped (one grep hit per matching line), and $findings_summary is
165
+ # the sum over all five categories — so it crosses the ceiling before any single
166
+ # category does. Pre-fix this died with `Argument list too long` mid-scan, after the
167
+ # per-category checks had already succeeded.
168
+ #
169
+ # The scratch files live in "$results_dir/.agg" rather than "$results_dir" itself:
170
+ # the markdown-table loop below re-globs "$results_dir"/*.json, and a summary file
171
+ # sitting there would be read back as a sixth bogus category row. A dot-prefixed
172
+ # subdirectory is invisible to that glob and is still cleaned by the existing
173
+ # `rm -rf "$results_dir"` EXIT trap, so this adds no new cleanup obligation.
174
+ agg_dir="$results_dir/.agg"
175
+ mkdir -p "$agg_dir"
176
+ summary_file="$agg_dir/findings-summary.json"
177
+ body_file="$agg_dir/body-redacted.json"
178
+ echo '{}' > "$summary_file"
179
+ for f in "$results_dir"/*.json; do
180
+ cat="$(jq -r '.category' "$f")"
181
+ jq '{verdict, findings}' "$f" | redact_pii > "$body_file"
182
+ jq --arg c "$cat" --rawfile b "$body_file" '. + {($c): ($b | fromjson)}' \
183
+ "$summary_file" > "$summary_file.next"
184
+ mv "$summary_file.next" "$summary_file"
185
+ done
186
+
187
+ # Write .scan-meta.json under meta_base (XDG_RUNTIME_DIR, else /tmp).
188
+ # umask 077 ensures persisted findings are not world-readable on shared hosts.
189
+ ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
190
+ meta_base="${SKILL_SCAN_META_BASE:-${XDG_RUNTIME_DIR:-/tmp}}"
191
+
192
+ # Bound the per-invocation meta_dir leak (#6789). Each run creates
193
+ # skill-security-scan-<pid>/ and NOTHING removes it: measured 12,889 leaked
194
+ # dirs. The fix is a STARTUP age-reap of OLDER siblings — deliberately NOT a
195
+ # `trap 'rm -rf "$meta_dir"' EXIT`. `.scan-meta.json` is GDPR Art. 32 evidence:
196
+ # override-mechanism.md instructs the operator to reference this path in an
197
+ # override artifact AFTER the scan exits (see the "written to:" line below), so
198
+ # a naive EXIT trap would delete the very artifact the override flow needs (R1).
199
+ # The current process's own dir is created after this reap and is never a
200
+ # candidate here, so the artifact this run writes always survives this run.
201
+ # Age-only is the correct sole dimension: these dirs are per-pid and single-use,
202
+ # so an OLD one is definitionally abandoned (name-scoped age is safe here —
203
+ # unlike a generic /tmp reaper, which cannot distinguish producer families).
204
+ #
205
+ # The floor defaults to 7 DAYS, not 24h: .scan-meta.json is Art. 32 evidence an
206
+ # operator may reference when building an override artifact, and that can happen
207
+ # a day or more after the scan. A generous floor keeps a still-referenceable
208
+ # evidence dir alive across a realistic operator gap while still bounding the
209
+ # leak — these dirs are tiny (one JSON file) and live in the runtime tmpfs,
210
+ # which is near-empty, so the leak's cost is inode COUNT, not bytes, and a 7-day
211
+ # window caps that at a manageable steady state. A longer-lived reference is the
212
+ # same pre-existing fragility the override mechanism already carries
213
+ # ($XDG_RUNTIME_DIR is cleared on logout regardless), out of scope here.
214
+ # SKILL_SCAN_META_REAP_MIN overrides the floor (minutes). Non-numeric values
215
+ # fall back to the default rather than silently disabling BOTH reaps below;
216
+ # `10#` normalizes leading zeros — unnormalized, the expansion error on
217
+ # `08`/`09` silently strands the literal string (the `||` fallback and the
218
+ # clamp both skip on arithmetic error), so find reads an octal-legal floor
219
+ # BELOW the 60-minute minimum.
220
+ _reap_min="${SKILL_SCAN_META_REAP_MIN:-10080}"
221
+ [[ "$_reap_min" =~ ^[0-9]{1,9}$ ]] && _reap_min=$((10#${_reap_min})) || _reap_min=10080
222
+ # Both sweeps clamp to >=60 minutes: `-mmin "+0"` matches ANY past mtime,
223
+ # so a pathological or test-seam floor below an hour reaps a CONCURRENT
224
+ # scan's live scratch and meta dir — the exclusions below cover only this
225
+ # run's own entries. 60 bounds a plausible scan lifetime; the operator's
226
+ # floor above it is verbatim.
227
+ _reap_min=$(( _reap_min < 60 ? 60 : _reap_min ))
228
+ meta_root="$(cd -P "$meta_base" 2>/dev/null && pwd -P || true)"
229
+ if [ -n "$meta_root" ]; then
230
+ # -maxdepth 1 -type d, older than the floor, own the current uid. `-mmin` on
231
+ # each dir is safe here: the dir is written once at creation and never touched
232
+ # again, so its own mtime IS the run's age. cd -P canonicalizes the base —
233
+ # find under default -P does not descend a symlinked startpoint, so a
234
+ # symlinked meta_base would silently no-op the whole reap. rm failures (a
235
+ # sibling reaping the same dir) are tolerated; a non-zero find exit warns
236
+ # instead of silently disabling the reap.
237
+ find "$meta_root" -mindepth 1 -maxdepth 1 -type d \
238
+ -name 'skill-security-scan-*' -user "$(id -u)" -mmin "+${_reap_min}" \
239
+ -exec rm -rf {} + 2>/dev/null \
240
+ || echo "run-scan: meta_dir reap failed; orphans retained" >&2
241
+ fi
242
+
243
+ # #6760: age-floor sweep for the scratch families under ${TMPDIR:-/tmp} —
244
+ # orphans the meta-base reap cannot reach. Three classes: the `skill-scan-*`
245
+ # scratch producers (skill-scan-input-*, skill-scan-results-*,
246
+ # skill-scan-XXXXXX + .code/.fm/.body/.req/.resp siblings — created by
247
+ # `mktemp -t` under TMPDIR and EXIT-trap-cleaned only on a clean exit);
248
+ # `skill-security-scan-*` meta dirs stranded under /tmp by the
249
+ # XDG_RUNTIME_DIR env flip (when ${TMPDIR:-/tmp} resolves to that base —
250
+ # with a custom TMPDIR the pre-flip orphans sit on a root this sweep does
251
+ # not scan); and `sss-write.*.err` captures from the skill's own write-hook.
252
+ # Top-level `-mmin` is the sole age test because every producer write creates
253
+ # a new entry (dir mtime tracks its last child) — a write-once invariant
254
+ # matching the meta reap's, so an OLD entry is definitionally orphaned.
255
+ #
256
+ # The `! -samefile` exclusions are load-bearing and asymmetric with the meta
257
+ # reap: INPUT and results_dir are created BEFORE this reap (meta_dir is
258
+ # created after), so this run's own live scratch is otherwise a candidate —
259
+ # a positional INPUT can carry an mtime far older than any floor (a stale
260
+ # file is a legitimate scan target); results_dir's mtime is refreshed by
261
+ # aggregation writes right before this reap, so its exclusion covers only
262
+ # stalls/suspension between creation and this point — belt-and-suspenders
263
+ # for the same self-reap class. `-samefile` (inode compare), never `-path`
264
+ # (literal/fnmatch string compare): a relative or glob-shaped INPUT spelling
265
+ # defeats string equality and could rm -rf the very file the operator asked
266
+ # to scan. The `[ -e ]` gates skip an exclusion whose referent died or
267
+ # became unstatable mid-scan — a dead -samefile operand would error the
268
+ # whole find (now a warn, not a silent no-op).
269
+ #
270
+ # Residual surfaces, accepted: a PEER's live input named like a family
271
+ # member under TMPDIR is indistinguishable from an orphan by age (do not
272
+ # name scan targets skill-scan-*/sss-write.* inside TMPDIR); a same-uid
273
+ # bind/FUSE mount inside a family-named dir is descended by rm -rf (same-uid
274
+ # blast radius — find's -mount is a no-op at maxdepth 1 and cannot reach
275
+ # rm's own recursion); a family-named symlink entry loses the link, never
276
+ # its target; a find build without -samefile/-mmin (a stripped BusyBox
277
+ # config — both are default-on features upstream — or heirloom) warns and
278
+ # skips rather than sweeping; an unreachable base canonicalizes to empty
279
+ # and skips silently (nothing reapable there anyway).
280
+ _excl=()
281
+ [ -e "$INPUT" ] && _excl+=("!" -samefile "$INPUT")
282
+ [ -e "$results_dir" ] && _excl+=("!" -samefile "$results_dir")
283
+ tmp_root="$(cd -P "${TMPDIR:-/tmp}" 2>/dev/null && pwd -P || true)"
284
+ if [ -n "$tmp_root" ]; then
285
+ # cd -P resolves a symlinked base (macOS /tmp -> private/tmp) — find under
286
+ # default -P does not descend a symlinked startpoint, so without
287
+ # canonicalization the sweep silently no-ops there.
288
+ find "$tmp_root" -mindepth 1 -maxdepth 1 -user "$(id -u)" \
289
+ -mmin "+${_reap_min}" \
290
+ \( -name 'skill-security-scan-*' -o -name 'skill-scan-*' -o -name 'sss-write.*.err' \) \
291
+ ${_excl[@]+"${_excl[@]}"} \
292
+ -exec rm -rf {} + 2>/dev/null \
293
+ || echo "run-scan: scratch reap failed; orphans retained" >&2
294
+ fi
295
+
296
+ (umask 077; mkdir -p "$meta_base/skill-security-scan-$$")
297
+ meta_dir="$meta_base/skill-security-scan-$$"
298
+ meta_path="$meta_dir/.scan-meta.json"
299
+ jq -n \
300
+ --arg sv "$SCANNER_VERSION" \
301
+ --arg rpv "$rule_pack_version" \
302
+ --arg sha "$rule_pack_sha" \
303
+ --arg v "$agg_verdict" \
304
+ --arg ts "$ts" \
305
+ --rawfile fs "$summary_file" \
306
+ '{scanner_version: $sv, rule_pack_version: $rpv, rule_pack_sha256: $sha, verdict: $v, timestamp: $ts, findings_summary: ($fs | fromjson)}' \
307
+ > "$meta_path"
308
+
309
+ # Emit markdown findings table + mandatory disclaimer.
310
+ echo "# skill-security-scan verdict: $agg_verdict"
311
+ echo ""
312
+ echo "| Category | Verdict | Findings |"
313
+ echo "|---|---|---|"
314
+ for f in "$results_dir"/*.json; do
315
+ cat="$(jq -r '.category' "$f")"
316
+ v="$(jq -r '.verdict' "$f")"
317
+ n="$(jq -r '.findings | length' "$f")"
318
+ echo "| $cat | $v | $n |"
319
+ done
320
+ echo ""
321
+ echo "Per-finding details (operator-facing, unredacted):"
322
+ echo ""
323
+ for f in "$results_dir"/*.json; do
324
+ v="$(jq -r '.verdict' "$f")"
325
+ if [ "$v" != "LOW-RISK" ]; then
326
+ cat="$(jq -r '.category' "$f")"
327
+ echo "## $cat ($v)"
328
+ echo ""
329
+ jq -r '.findings[] | "- **\(.rule_id)** (\(.severity)) line \(.line): `\(.snippet)`"' "$f"
330
+ echo ""
331
+ fi
332
+ done
333
+ echo ".scan-meta.json written to: $meta_path"
334
+ echo ""
335
+ cat <<EOF
336
+ ---
337
+ Advisory static analysis only. LOW-RISK does not constitute a security audit,
338
+ certification, or warranty of safety. The skill executes in your environment
339
+ under your account; you remain responsible for review.
340
+
341
+ Scanner version: $SCANNER_VERSION Rule pack: ${rule_pack_sha:0:12} Scanned: $ts
342
+ EOF
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bash
2
+ # Fail-loud self-test for skill-security-scan.
3
+ #
4
+ # Iterates references/test-fixtures/{malicious-*,clean-*}.skill.md and asserts
5
+ # deterministic verdicts:
6
+ # - malicious-*.skill.md → HIGH-RISK
7
+ # - clean-*.skill.md → LOW-RISK
8
+ #
9
+ # Exits 1 with diagnostic if any false-negative or false-positive is observed.
10
+ # Wired into CI per .github/workflows/skill-security-scan-corpus.yml.
11
+ #
12
+ # Flags:
13
+ # --regenerate-manifest recompute manifest SHAs from current rule-file
14
+ # contents BEFORE running fixtures. Used during
15
+ # rule-pack development. CI rejects this flag when
16
+ # env CI=true (per plan SpecFlow Gap 4).
17
+
18
+ set -euo pipefail
19
+
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
22
+ FIXTURES="$SKILL_DIR/references/test-fixtures"
23
+ MANIFEST="$SKILL_DIR/references/rules/manifest.yaml"
24
+
25
+ REGENERATE=0
26
+ if [ "${1:-}" = "--regenerate-manifest" ]; then
27
+ if [ "${CI:-false}" = "true" ]; then
28
+ echo "ERROR: --regenerate-manifest is rejected in CI (CI=true). See SpecFlow Gap 4." >&2
29
+ exit 2
30
+ fi
31
+ REGENERATE=1
32
+ fi
33
+
34
+ if [ "$REGENERATE" = "1" ]; then
35
+ echo "regenerating manifest SHAs..." >&2
36
+ tmp_manifest="$(mktemp)"
37
+ # Owning trap (ADR-129): mv consumes the file on success (rm -f then no-ops);
38
+ # the trap covers the awk/mv failure window.
39
+ trap 'rm -f "$tmp_manifest"' EXIT
40
+ awk -v skill_dir="$SKILL_DIR/references" '
41
+ /^[[:space:]]*-[[:space:]]*path:/ {
42
+ path = $0
43
+ sub(/^[[:space:]]*-[[:space:]]*path:[[:space:]]*/, "", path)
44
+ gsub(/[[:space:]]*$/, "", path)
45
+ print
46
+ cmd = "sha256sum \"" skill_dir "/" path "\" | cut -d\" \" -f1"
47
+ cmd | getline sha
48
+ close(cmd)
49
+ print " sha256: " sha
50
+ next
51
+ }
52
+ /^[[:space:]]+sha256:/ { next }
53
+ { print }
54
+ ' "$MANIFEST" > "$tmp_manifest"
55
+ mv "$tmp_manifest" "$MANIFEST"
56
+ echo "manifest updated. commit it alongside the rule-pack edits." >&2
57
+ fi
58
+
59
+ failures=0
60
+
61
+ # Test malicious fixtures: must be HIGH-RISK.
62
+ for fx in "$FIXTURES"/malicious-*.skill.md; do
63
+ [ -f "$fx" ] || continue
64
+ fx_name="$(basename "$fx")"
65
+ out="$(bash "$SCRIPT_DIR/run-scan.sh" < "$fx" 2>/dev/null || echo "")"
66
+ verdict="$(echo "$out" | head -1 | grep -oE 'HIGH-RISK|REVIEW|LOW-RISK' || echo "UNKNOWN")"
67
+ if [ "$verdict" != "HIGH-RISK" ]; then
68
+ echo "FAIL: $fx_name expected HIGH-RISK, got $verdict" >&2
69
+ failures=$((failures + 1))
70
+ else
71
+ echo "ok: $fx_name → HIGH-RISK" >&2
72
+ fi
73
+ done
74
+
75
+ # Test clean fixtures: must be LOW-RISK.
76
+ for fx in "$FIXTURES"/clean-*.skill.md; do
77
+ [ -f "$fx" ] || continue
78
+ fx_name="$(basename "$fx")"
79
+ out="$(SKILL_SECURITY_SCAN_OFFLINE=1 bash "$SCRIPT_DIR/run-scan.sh" < "$fx" 2>/dev/null || echo "")"
80
+ verdict="$(echo "$out" | head -1 | grep -oE 'HIGH-RISK|REVIEW|LOW-RISK' || echo "UNKNOWN")"
81
+ if [ "$verdict" != "LOW-RISK" ]; then
82
+ echo "FAIL: $fx_name expected LOW-RISK, got $verdict" >&2
83
+ failures=$((failures + 1))
84
+ else
85
+ echo "ok: $fx_name → LOW-RISK" >&2
86
+ fi
87
+ done
88
+
89
+ if [ "$failures" -gt 0 ]; then
90
+ echo "self-test FAILED: $failures fixture(s) returned wrong verdict" >&2
91
+ exit 1
92
+ fi
93
+
94
+ echo "self-test PASSED: all fixtures returned expected verdicts" >&2
95
+ exit 0
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env bash
2
+ # Argv-ceiling regression for skill-security-scan (#6736).
3
+ #
4
+ # WHAT THIS GUARDS. Two sites used to bind an unbounded payload as ONE argv argument:
5
+ # - scripts/lib.sh emit_result() `--argjson f "$findings_json"` (per category)
6
+ # - scripts/run-scan.sh `--argjson fs "$findings_summary"` (all five)
7
+ # The kernel caps a SINGLE argv argument at MAX_ARG_STRLEN = 131,072 B -- bisected on this
8
+ # host: 131,071 B passes, 131,072 B fails E2BIG. That is NOT `getconf ARG_MAX` (2,097,152 B
9
+ # here); a payload at 6% of ARG_MAX still dies. Both now use stdin / `--rawfile`, which is
10
+ # file-or-pipe I/O and has no per-argument limit.
11
+ #
12
+ # WHY THIS IS THE UNBOUNDED ONE. apply_yaml_rules caps each snippet at 200 chars, so it
13
+ # LOOKS bounded -- but nothing caps the FINDING COUNT: one grep hit per matching line, over
14
+ # a SKILL.md of any length. At ~265 B/finding the ceiling lands near 490 findings, and this
15
+ # repo already ships a 220,523 B SKILL.md.
16
+ #
17
+ # THE FAILURE WAS SILENT, which is why the behavioural assertions below check CONTENT and
18
+ # not just the exit code. run-scan.sh invokes each category as
19
+ # `bash check-*.sh … || echo '{"…check-failed…"}'`, so an E2BIG inside a category script is
20
+ # swallowed into a "category script error" placeholder: the scan exits 0 and reports a
21
+ # REVIEW verdict with ZERO real findings instead of the hundreds it actually found. An
22
+ # exit-code-only test passes straight through that.
23
+ #
24
+ # FIXTURE ADEQUACY. The fixture is SYNTHESIZED (cq-test-fixtures-synthesized-only) -- it is
25
+ # generated here, never copied from a real skill. It is also PRODUCTION-SHAPED: each line is
26
+ # long enough to fill the 200-char snippet window, because BYTES PER FINDING is the
27
+ # load-bearing parameter, not finding count. Short matching lines would yield ~70 B findings,
28
+ # so even thousands of them would stay under the ceiling and PASS ON UNMODIFIED CODE.
29
+
30
+ set -uo pipefail
31
+
32
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
33
+ SCRIPTS="$SCRIPT_DIR/../scripts"
34
+ CHECK_FS="$SCRIPTS/check-filesystem-boundary.sh"
35
+ RUN_SCAN="$SCRIPTS/run-scan.sh"
36
+
37
+ # Named at every use, never bare.
38
+ MAX_ARG_STRLEN=131072
39
+
40
+ PASS=0
41
+ FAIL=0
42
+ pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
43
+ fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
44
+
45
+ command -v jq >/dev/null 2>&1 || { echo "SKIP: jq missing"; exit 0; }
46
+ [[ -f "$CHECK_FS" ]] || { echo "ERROR: not found: $CHECK_FS" >&2; exit 1; }
47
+
48
+ WORK="$(mktemp -d)"
49
+ trap 'rm -rf "$WORK"' EXIT
50
+ export SKILL_SECURITY_SCAN_OFFLINE=1
51
+
52
+ echo "TEST: skill-security-scan argv ceiling (#6736)"
53
+
54
+ # --- Synthesized, production-shaped fixture ---------------------------------------------
55
+ # Each line trips filesystem-boundary's `path-traversal-absolute` rule (a quote followed by
56
+ # /etc/) and is padded past 200 chars so the captured snippet fills its cap. Nothing here is
57
+ # copied from a real SKILL.md.
58
+ FIXTURE="$WORK/synth.skill.md"
59
+ ROWS=900
60
+ {
61
+ printf '# Synthesized fixture skill\n\n'
62
+ for i in $(seq 1 "$ROWS"); do
63
+ printf 'Line %04d config path "/etc/synthesized-fixture-%04d/a-deliberately-long-configuration-path-segment-that-fills-the-two-hundred-character-snippet-window-so-that-bytes-per-finding-not-finding-count-is-what-drives-this-fixture-over-the-ceiling"\n' "$i" "$i"
64
+ done
65
+ } > "$FIXTURE"
66
+
67
+ # --- Generator cardinality --------------------------------------------------------------
68
+ gen_rows="$(grep -c '^Line [0-9]' "$FIXTURE")"
69
+ if [[ "$gen_rows" -eq "$ROWS" ]]; then
70
+ pass "fixture generator emitted $gen_rows matching lines (want $ROWS)"
71
+ else
72
+ fail "fixture generator emitted $gen_rows lines (want $ROWS) -- asserts below would be vacuous"
73
+ fi
74
+
75
+ # --- Category level: emit_result must survive a >ceiling findings array ------------------
76
+ cat_out="$(bash "$CHECK_FS" < "$FIXTURE" 2>"$WORK/cat_err.txt")"
77
+ cat_rc=$?
78
+ if [[ "$cat_rc" -eq 0 ]]; then
79
+ pass "check-filesystem-boundary exits 0 on a >ceiling finding set"
80
+ else
81
+ fail "check-filesystem-boundary exit=$cat_rc -- stderr: $(head -c 200 "$WORK/cat_err.txt")"
82
+ fi
83
+
84
+ # FIXTURE ADEQUACY, asserted IN-SUITE so this cannot silently degrade to vacuous as the
85
+ # rule pack, the snippet cap, or jq's encoding changes.
86
+ findings_bytes="$(printf '%s' "$cat_out" | jq -c '.findings' | wc -c)"
87
+ if [[ "$findings_bytes" -gt "$MAX_ARG_STRLEN" ]]; then
88
+ pass "findings payload is ${findings_bytes} B > MAX_ARG_STRLEN (${MAX_ARG_STRLEN})"
89
+ else
90
+ fail "findings payload is only ${findings_bytes} B -- below MAX_ARG_STRLEN (${MAX_ARG_STRLEN}), this test proves nothing"
91
+ fi
92
+
93
+ # Count asserted RELATIONALLY against the source line count, not a literal pin.
94
+ findings_n="$(printf '%s' "$cat_out" | jq '.findings | length')"
95
+ if [[ "$findings_n" -eq "$gen_rows" ]]; then
96
+ pass "findings|length=$findings_n == $gen_rows source lines (no truncation)"
97
+ else
98
+ fail "findings|length=$findings_n != $gen_rows source lines (undercount / truncation)"
99
+ fi
100
+
101
+ # The findings must really carry their rule_id and snippet -- not empty shells.
102
+ real_findings="$(printf '%s' "$cat_out" | jq '[.findings[] | select(.rule_id == "path-traversal-absolute" and (.snippet | length) > 100)] | length')"
103
+ if [[ "$real_findings" -eq "$gen_rows" ]]; then
104
+ pass "all $real_findings findings carry rule_id + a full snippet at >ceiling size"
105
+ else
106
+ fail "only $real_findings of $gen_rows findings carry rule_id + full snippet"
107
+ fi
108
+
109
+ # --- Aggregator level: run-scan must not degrade to the check-failed placeholder ---------
110
+ scan_out="$(bash "$RUN_SCAN" "$FIXTURE" 2>"$WORK/scan_err.txt")"
111
+ scan_rc=$?
112
+ if [[ "$scan_rc" -eq 0 ]]; then
113
+ pass "run-scan.sh exits 0 on a >ceiling finding set"
114
+ else
115
+ fail "run-scan.sh exit=$scan_rc -- stderr: $(head -c 200 "$WORK/scan_err.txt")"
116
+ fi
117
+
118
+ # THE ANTI-SILENT-DEGRADATION ASSERTION. Pre-fix, the E2BIG inside check-filesystem-boundary
119
+ # is swallowed by run-scan's `|| echo '{"…check-failed…"}'` fallback, so the run still exits
120
+ # 0 -- but the filesystem-boundary row is replaced by an "unknown" category carrying a single
121
+ # `check-failed` finding. Asserting on the REAL row is what makes that visible.
122
+ #
123
+ # `grep -c` on a herestring, never `producer | grep -q`: under `set -o pipefail` an early
124
+ # match closes the pipe, the producer takes SIGPIPE (141), and the pipeline reports failure
125
+ # even though grep MATCHED.
126
+ fs_row="$(grep -cE '^\| filesystem-boundary \| (REVIEW|HIGH-RISK) \| [0-9]+ \|' <<<"$scan_out")"
127
+ if [[ "$fs_row" -ge 1 ]]; then
128
+ pass "filesystem-boundary reported as a real category row"
129
+ else
130
+ fail "no real filesystem-boundary row -- the category silently degraded to check-failed"
131
+ fi
132
+
133
+ reported_n="$(sed -nE 's/^\| filesystem-boundary \| [A-Z-]+ \| ([0-9]+) \|.*/\1/p' <<<"$scan_out" | head -1)"
134
+ if [[ "${reported_n:-0}" -eq "$gen_rows" ]]; then
135
+ pass "run-scan reports all $reported_n findings (== $gen_rows source lines)"
136
+ else
137
+ fail "run-scan reports ${reported_n:-<none>} findings but fixture had $gen_rows -- silent loss"
138
+ fi
139
+
140
+ checkfailed="$(grep -c 'check-failed' <<<"$scan_out")"
141
+ if [[ "$checkfailed" -eq 0 ]]; then
142
+ pass "no check-failed placeholder in the report"
143
+ else
144
+ fail "report contains $checkfailed check-failed placeholder(s) -- a category died and was swallowed"
145
+ fi
146
+
147
+ if grep -qiE 'argument list too long' "$WORK/cat_err.txt" "$WORK/scan_err.txt"; then
148
+ fail "an E2BIG diagnostic reached stderr -- argv ceiling was hit"
149
+ else
150
+ pass "no 'Argument list too long' diagnostic on stderr"
151
+ fi
152
+
153
+ # --- Structural: neither site may rebind an unbounded payload onto argv ------------------
154
+ # Anchored on syntax a COMMENT cannot produce. Both files now carry prose mentioning
155
+ # `--argjson`, so a bare-token grep would false-pass on this fix's own documentation
156
+ # (cq-assert-anchor-not-bare-token). `-cE` with a leading `^[^#]*` restricts to code lines.
157
+ lib_argjson="$(grep -cE '^[^#]*--argjson[[:space:]]+f[[:space:]]+"\$findings_json"' "$SCRIPTS/lib.sh")"
158
+ if [[ "$lib_argjson" -eq 0 ]]; then
159
+ pass "lib.sh does not bind \$findings_json via --argjson"
160
+ else
161
+ fail "lib.sh rebinds \$findings_json via --argjson on $lib_argjson code line(s)"
162
+ fi
163
+
164
+ scan_argjson="$(grep -cE '^[^#]*--argjson[[:space:]]+(fs|b)[[:space:]]+"\$(findings_summary|body_redacted)"' "$RUN_SCAN")"
165
+ if [[ "$scan_argjson" -eq 0 ]]; then
166
+ pass "run-scan.sh does not bind the summary/body via --argjson"
167
+ else
168
+ fail "run-scan.sh rebinds an unbounded payload via --argjson on $scan_argjson code line(s)"
169
+ fi
170
+
171
+ # Positive form: the --rawfile binding must actually be present. `--rawfile\s+\w+` is
172
+ # syntax a comment cannot produce in the code position asserted here.
173
+ if grep -qE '^[^#]*--rawfile[[:space:]]+fs[[:space:]]+"\$summary_file"' "$RUN_SCAN"; then
174
+ pass "run-scan.sh binds the summary with --rawfile"
175
+ else
176
+ fail "run-scan.sh no longer binds the summary with --rawfile"
177
+ fi
178
+
179
+ echo "=== Results: $PASS passed, $FAIL failed ==="
180
+ [[ "$FAIL" -eq 0 ]]