@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,271 @@
1
+ #!/usr/bin/env bash
2
+ # gdpr-gate advisory pre-commit hook (lefthook).
3
+ #
4
+ # Always exits 0 — the hook is advisory, never blocking. Blocking enforcement
5
+ # lives in /soleur:ship Phase 5.5 (post-PR). This hook prints a one-line
6
+ # stderr breadcrumb when staged paths match the canonical regulated-data
7
+ # regex (single source of truth: SKILL.md §"Path globs (canonical)").
8
+ #
9
+ # Telemetry: emits, via .claude/hooks/lib/incidents.sh, an
10
+ # `hr-gdpr-gate-on-regulated-data-surfaces` event when a regulated-data path
11
+ # is touched, plus `gdpr-gate-staleness` and `gdpr-gate-cron-binding` events
12
+ # for the corpus-freshness signals. Telemetry survives even when the
13
+ # operator's terminal swallows stderr.
14
+ #
15
+ # This block previously documented a `gdpr-gate-touch` event. No such event
16
+ # has ever been emitted by this file (#7710). The name was corrected rather
17
+ # than the emit: `hr-gdpr-gate-on-regulated-data-surfaces` is the rule this
18
+ # gate enforces, and it is accepted by the incident allow-list via the
19
+ # closed-corpus arm of `_valid_rule` (it is a real `[id: ...]` in
20
+ # AGENTS.rules.md), not via the synthetic `gdpr-gate-*` prefix arm.
21
+ #
22
+ # Invoked from lefthook.yml:
23
+ # gdpr-gate-advisory:
24
+ # priority: 6
25
+ # run: bash plugins/soleur/skills/gdpr-gate/scripts/gdpr-gate.sh {staged_files}
26
+
27
+ set -euo pipefail
28
+
29
+ # Refuse to run under `set -x` while a live credential is in the environment
30
+ # (#7797). An xtrace of this script echoes every expansion, and the token would
31
+ # land in whatever captured that trace — a CI log, a `bash -x` debugging
32
+ # session, a pasted transcript. Placed immediately after `set` so nothing
33
+ # credential-bearing executes ahead of it.
34
+ case "$-" in
35
+ *x*)
36
+ if [ -n "${GH_TOKEN:+x}${GITHUB_TOKEN:+x}" ]; then
37
+ printf '[FATAL] refusing to trace with a live credential set (see #7797)\n' >&2
38
+ exit 78
39
+ fi
40
+ ;;
41
+ esac
42
+
43
+
44
+ # REPO_ROOT was REMOVED here (#7450 round-2 review). After `NOTICE_PARSER` moved to
45
+ # $BASH_SOURCE-relative resolution it had ZERO remaining expansions, leaving a bare
46
+ # `git rev-parse --show-toplevel` as the only statement in this file that could abort the
47
+ # run: it sits under `set -euo pipefail`, and this gate is documented at the top as
48
+ # "always exits 0 ... never blocking". It fails on a non-repo CWD, a broken .git worktree
49
+ # pointer, or a `safe.directory` ownership refusal — all routine on a fresh install or a
50
+ # container mount — and would have aborted the operator's `git commit` via lefthook.
51
+
52
+ # Source telemetry helper if present. Downstream installs of the Soleur plugin
53
+ # may not ship .claude/hooks/lib/incidents.sh — preserve the always-exit-0
54
+ # advisory contract by no-op'ing emit_incident in that case rather than
55
+ # letting `set -e` abort before the breadcrumb.
56
+ #
57
+ # CODE ROOT, not a data root (#7450; ADR-179's classification). This path gets
58
+ # SOURCED, so it executes in THIS shell — and it must therefore never be derived
59
+ # from `git rev-parse --show-toplevel`, which on the review path resolves to the
60
+ # contributor's checked-out tree. `review/SKILL.md` instructs `gh pr checkout`,
61
+ # and this script is itself a compliance gate, so a same-named file in a hostile
62
+ # PR would run with the gate's authority. CLAUDE_PROJECT_DIR is supplied by the
63
+ # harness rather than by the tree under review.
64
+ #
65
+ # There is no `REPO_ROOT` in this file any more (see above). Two successive revisions of
66
+ # this comment were wrong about it, and both are recorded because the second was written
67
+ # to correct the first:
68
+ # 1. It first claimed every remaining `REPO_ROOT` use was a data-root read. FALSE —
69
+ # `NOTICE_PARSER` below is EXECUTED (a code root by this ADR's classification) and was
70
+ # resolved from it, with `GH_TOKEN` exported into the child. On the review path that
71
+ # handed a GitHub token to a contributor-supplied script from inside the compliance
72
+ # gate, in the very file edited to remove that vector.
73
+ # 2. The correction then claimed `REPO_ROOT` "stays for data-root reads". Also FALSE —
74
+ # once `NOTICE_PARSER` moved to $BASH_SOURCE-relative there were no reads left at all,
75
+ # so the assignment was dead code that could still abort the operator's commit.
76
+ # Resolution, in trust order, and NEVER from `git rev-parse --show-toplevel`:
77
+ # 1. CLAUDE_PROJECT_DIR — supplied by the harness, not by the tree under review.
78
+ # Measured 2026-08-12: unset in a plain Claude Code session and in git hooks,
79
+ # so it cannot be the ONLY arm without silently retiring this telemetry.
80
+ # 2. This script's OWN location. Layout-invariant per ADR-178, and crucially NOT
81
+ # CWD-derived: a `gh pr checkout` cannot redirect it, because by the time this
82
+ # line runs the anchor decision has already been made — if a hostile script
83
+ # were executing, sourcing its sibling lib adds nothing. On a plugin INSTALL
84
+ # the walk lands somewhere with no such lib, so it no-ops, which is correct.
85
+ # The `-f` test is the safety net for both arms: a wrong root simply no-ops.
86
+ _incidents_root="${CLAUDE_PROJECT_DIR:-$(cd -P "$(dirname "${BASH_SOURCE[0]}")/../../../../.." 2>/dev/null && pwd -P)}"
87
+ INCIDENTS_LIB="${_incidents_root:+${_incidents_root}/.claude/hooks/lib/incidents.sh}"
88
+ if [[ -n "$INCIDENTS_LIB" && -f "$INCIDENTS_LIB" ]]; then
89
+ # shellcheck source=/dev/null
90
+ source "$INCIDENTS_LIB"
91
+ else
92
+ emit_incident() { :; }
93
+ fi
94
+
95
+ # Runtime staleness check (FR6 / TR2 / TR6).
96
+ #
97
+ # The gdpr-gate skill is partially driven by detection rules lifted from
98
+ # upstream gosprinto/compliance-skills (see plugins/soleur/skills/gdpr-gate/NOTICE).
99
+ # When the cron-driven re-vendor pipeline silently breaks (workflow disabled,
100
+ # GH outage, PR queued), the lifted rules go stale and the gate's
101
+ # "no findings" output becomes a false-clean signal on regulated PRs.
102
+ # The runtime banner is the load-bearing user-protection layer in that case.
103
+ #
104
+ # Banner emits to STDOUT (not stderr) — agent runtimes commonly swallow stderr.
105
+ # Gate exits 0 in all paths (advisory contract preserved).
106
+ # Subshell-exec (not source) so parser failure / deletion / future date all
107
+ # resolve to days_stale=999 → banner fires → gate stays advisory.
108
+ #
109
+ # Trust-binding (#3535): invoke parser twice and compute MIN in the caller
110
+ # frame. NOTICE last-verified is operator-controlled (a PR can backdate it);
111
+ # the content-vendor-drift cron's run timestamp is not. Taking the MIN ensures
112
+ # a fresh-looking last-verified cannot suppress a stale-cron banner.
113
+ # NOTICE_FILE and GH_TOKEN propagate explicitly — Bash subshell-exec does NOT
114
+ # inherit them otherwise. Operator-attested-mode banner fires only when the
115
+ # cron binding is unavailable AND last-verified is parseable — when both are
116
+ # 999 the existing 30d/90d banners cover the case.
117
+ #
118
+ # The cron half of this binding was inert from the Inngest migration until
119
+ # #7255 fixed the probe: `cron_days_stale` then resolved to 999 on every call
120
+ # because the query targeted a deleted GHA workflow, and the MIN below was
121
+ # always MIN(notice, 999) == notice — the fail-safe direction, which is why
122
+ # it went unnoticed. The probe now reads the check's own GitHub artifact
123
+ # (the `ci/vendor-attest-*` PR the cron writes each run — see the DATA SOURCE
124
+ # comment in `notice-frontmatter.sh` `cmd_cron_run_stale`), so the
125
+ # anti-backdating property described above is in force again whenever a
126
+ # token is present.
127
+ # SIBLING of this script, so it needs no root at all: `$BASH_SOURCE`-relative is
128
+ # layout-invariant (ADR-178) and leaves NO operand for a checked-out tree to shadow —
129
+ # strictly better here than any root-anchored form, including CLAUDE_PROJECT_DIR.
130
+ # It was `"$REPO_ROOT/plugins/soleur/…"` (i.e. `git rev-parse --show-toplevel`) until
131
+ # #7450 review: EXECUTED below, three times, once with GH_TOKEN exported to the child.
132
+ NOTICE_PARSER="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd -P)/notice-frontmatter.sh"
133
+ notice_days_stale=$(NOTICE_FILE="${NOTICE_FILE:-}" \
134
+ bash "$NOTICE_PARSER" days-stale 2>/dev/null || echo 999)
135
+ cron_days_stale=$(NOTICE_FILE="${NOTICE_FILE:-}" \
136
+ GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-}}" \
137
+ bash "$NOTICE_PARSER" cron-run-stale 2>/dev/null || echo 999)
138
+
139
+ # MIN-of-both compute (caller frame — Bash env exports drop across the
140
+ # subshell-exec boundary, so the comparison must live here).
141
+ if [[ "$cron_days_stale" != "999" && "$notice_days_stale" != "999" ]]; then
142
+ if (( cron_days_stale < notice_days_stale )); then
143
+ days_stale="$cron_days_stale"
144
+ emit_incident gdpr-gate-cron-binding min-wins \
145
+ "cron=${cron_days_stale} notice=${notice_days_stale}" \
146
+ 2>/dev/null || true
147
+ else
148
+ days_stale="$notice_days_stale"
149
+ emit_incident gdpr-gate-cron-binding applied \
150
+ "cron=${cron_days_stale} notice=${notice_days_stale}" \
151
+ 2>/dev/null || true
152
+ fi
153
+ elif [[ "$cron_days_stale" != "999" ]]; then
154
+ days_stale="$cron_days_stale"
155
+ emit_incident gdpr-gate-cron-binding applied \
156
+ "cron-only=${cron_days_stale}" 2>/dev/null || true
157
+ else
158
+ days_stale="$notice_days_stale"
159
+ fi
160
+
161
+ last_verified=$(NOTICE_FILE="${NOTICE_FILE:-}" \
162
+ bash "$NOTICE_PARSER" field last-verified 2>/dev/null || echo "unknown")
163
+ [[ -n "$last_verified" ]] || last_verified="unknown"
164
+ if (( days_stale > 30 )); then
165
+ printf '⚠ gdpr-gate rules %s days stale (last verified %s) — output is advisory only and may miss recently-patched detection rules. Refresh: see "Corpus freshness" in this skill'"'"'s SKILL.md.\n' \
166
+ "$days_stale" "$last_verified"
167
+ emit_incident gdpr-gate-staleness warn "${days_stale}-days-stale" \
168
+ 2>/dev/null || true
169
+ fi
170
+ if (( days_stale > 90 )); then
171
+ printf 'POSTURE_FAIL: gdpr-gate rules >90 days stale — compliance/critical posture row required. Operator chain: see "POSTURE_FAIL operator chain" in this skill'"'"'s SKILL.md.\n'
172
+ emit_incident gdpr-gate-staleness deny "${days_stale}-days-stale-posture-fail" \
173
+ 2>/dev/null || true
174
+ fi
175
+
176
+ # Single source of truth — mirrors SKILL.md §"Path globs (canonical)".
177
+ CANONICAL_REGEX='^(apps/web-platform/supabase/migrations/|apps/web-platform/lib/auth/|apps/web-platform/server/.*auth.*\.(ts|tsx|js)|apps/web-platform/app/api/.*\.(ts|tsx)$|.*\.sql$)'
178
+
179
+ matched=()
180
+ examined=0
181
+ # DEDUPE BY PATH. lefthook passes a path once PER MATCHING GLOB, not once per
182
+ # staged file, and the `gdpr-gate-advisory` stanza carries overlapping globs by
183
+ # construction: in gobwas a single `*` CROSSES `/`, so
184
+ # `apps/web-platform/lib/auth/*.ts` already matches a nested file that
185
+ # `apps/web-platform/lib/auth/**/*.ts` also matches, and bare `*.sql` already
186
+ # matches `apps/web-platform/supabase/migrations/*.sql`.
187
+ #
188
+ # Measured against real lefthook 2 on the real stanza's shape: three staged
189
+ # files — one SQL migration, one nested auth module, one nested API route —
190
+ # arrive as SIX arguments. The two most common regulated shapes in this repo
191
+ # are therefore ALWAYS doubled, so the un-deduped line told a customer who
192
+ # staged one migration that two paths were examined. That is the wrong number
193
+ # on the one artifact this change exists to produce.
194
+ #
195
+ # Deduping HERE rather than by trimming the glob list is deliberate: the
196
+ # script must report what it examined whatever it is handed, and a future
197
+ # overlapping glob must not be able to re-break the count. `seen` is keyed on
198
+ # the literal argument, so a genuine repeat on one command line collapses too
199
+ # — which is correct, it is the same file.
200
+ declare -A _gdpr_seen=()
201
+ for f in "$@"; do
202
+ [[ -n "${_gdpr_seen[$f]+x}" ]] && continue
203
+ _gdpr_seen["$f"]=1
204
+ examined=$((examined + 1))
205
+ if [[ "$f" =~ $CANONICAL_REGEX ]]; then
206
+ matched+=("$f")
207
+ fi
208
+ done
209
+
210
+ # Scan-completion line (#7710). UNCONDITIONAL and AFTER the loop, reporting
211
+ # what the loop actually counted.
212
+ #
213
+ # Before this line existed, "the scan ran and matched nothing" and "the scan
214
+ # never ran" produced byte-identical output — nothing at all. On a corpus
215
+ # past the 90-day threshold the gate printed a staleness banner and a
216
+ # POSTURE_FAIL and no evidence that any path had been examined, so the
217
+ # refusal read as the whole output and a reader could not tell a healthy
218
+ # no-findings scan from a gate that never looked. That is the defect #7710
219
+ # reported, and it is why this line must NOT be gated on
220
+ # `${#matched[@]} > 0`: the zero-match case is precisely the state the
221
+ # property forbids being silent about.
222
+ #
223
+ # STDOUT, because agent runtimes commonly swallow stderr — the same reason
224
+ # the staleness banners are on stdout. The path-naming breadcrumb below stays
225
+ # on stderr.
226
+ #
227
+ # COUNTS ONLY, never path names: this line goes to a customer's terminal, and
228
+ # path structure is third-party-content-adjacent
229
+ # (hr-third-party-content-grep-on-undertaking; #7331 is the live scar). The
230
+ # stderr breadcrumb already names paths for the local operator.
231
+ #
232
+ # It carries neither `days stale` nor `POSTURE_FAIL`, so its presence is
233
+ # independent of the corpus's freshness state. That independence is the
234
+ # point: the evidence that a scan occurred must not be entangled with the
235
+ # age of the rules the scan used. It also keeps the existing negative
236
+ # assertions on those two strings able to witness a banner regression.
237
+ printf 'gdpr-gate: path scan complete — %d examined, %d matched\n' \
238
+ "$examined" "${#matched[@]}"
239
+
240
+ if (( ${#matched[@]} > 0 )); then
241
+ echo "gdpr-gate: regulated-data path touched (${matched[*]}); run /soleur:gdpr-gate" >&2
242
+ emit_incident hr-gdpr-gate-on-regulated-data-surfaces applied \
243
+ "regulated-data path touched: ${matched[0]}" 2>/dev/null || true
244
+
245
+ # Operator-attested-mode banner — fires ONLY when (a) a regulated path is
246
+ # being judged this commit AND (b) the cron binding is unavailable but
247
+ # NOTICE last-verified is parseable.
248
+ #
249
+ # The #3541 relevance property is real, but this conditional is not what
250
+ # delivers it, and the previous wording here was false (#7710). It claimed
251
+ # that without the matched-path gate the banner "would fire on every
252
+ # commit". It would not: lefthook invokes this script only when a staged
253
+ # path matches the `gdpr-gate-advisory` glob, so on the pre-commit path
254
+ # relevance is already bought by the glob and this conditional is a second,
255
+ # narrower filter over an already-filtered set.
256
+ #
257
+ # What the conditional actually buys is relevance on the paths the glob does
258
+ # NOT gate: direct invocation, the CI self-test, and `/soleur:gdpr-gate`,
259
+ # where arbitrary arguments reach the script. That is a real property and
260
+ # worth keeping — it is simply a different one from the claim it replaced.
261
+ #
262
+ # Banner literal is load-bearing: the self-test asserts it verbatim. See
263
+ # review finding from user-impact-reviewer #3541.
264
+ if [[ "$cron_days_stale" == "999" && "$notice_days_stale" != "999" ]]; then
265
+ printf 'ℹ gdpr-gate: operator-attested mode (no GH_TOKEN available — cron-run timestamp unverified, falling back to NOTICE last-verified)\n'
266
+ emit_incident gdpr-gate-cron-binding unavailable \
267
+ "no-token-or-gh-cli" 2>/dev/null || true
268
+ fi
269
+ fi
270
+
271
+ exit 0
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env bash
2
+ # notice-frontmatter.sh — pure-bash parser for the NOTICE YAML frontmatter.
3
+ #
4
+ # Subcommands:
5
+ # field <name> Print scalar value (upstream, pinned-commit,
6
+ # last-verified, registry).
7
+ # days-stale Integer days since last-verified. Future date / parse
8
+ # fail / missing frontmatter all return 999 (treat as
9
+ # stale immediately, per plan TR2 + SpecFlow P1.5).
10
+ # Always exits 0 — the gdpr-gate hook subshell-execs this
11
+ # and depends on the always-exit-0 advisory contract.
12
+ # cron-run-stale Integer days since the content-vendor-drift check last
13
+ # produced its attestation artifact — the weekly
14
+ # `ci/vendor-attest-*` PR the Inngest cron writes on every
15
+ # completed run (ADR-203), read via `gh pr list --search
16
+ # head:ci/vendor-attest`. 999 on any failure mode (no
17
+ # GH_TOKEN, no gh CLI, network blocked, empty result,
18
+ # malformed timestamp, timeout). The `gdpr-gate.sh` caller
19
+ # computes MIN(days-stale, cron-run-stale) to defend
20
+ # against a backdated last-verified field (issue #3535).
21
+ # lifted-files One `<path>:<local-blob-sha>` per line. Local blob SHAs
22
+ # pin the file as it exists in this repo (post-attribution
23
+ # header) and are consumed by `vendor-pin-integrity.sh`.
24
+ # soleur-authored One `<path>:<local-blob-sha>` per line, for the reference
25
+ # files written from scratch for this plugin. Same record
26
+ # shape and same consumer as `lifted-files`, but no
27
+ # upstream provenance: these never appear in
28
+ # `upstream-files`. Pinning them keeps a tamper check on
29
+ # the files the gate's own GDPR framing depends on while
30
+ # leaving them editable through the normal update-the-pin
31
+ # flow (#7710).
32
+ # record-count <block>
33
+ # Integer count of `- path:` records DECLARED in the named
34
+ # block, regardless of whether each record is complete.
35
+ #
36
+ # This exists because every other view here is a FILTERED
37
+ # projection: `_emit_files` flushes a record only when BOTH
38
+ # its path key and its sha key are non-empty, so a record
39
+ # that loses `upstream-blob-sha` is silently absent from
40
+ # `upstream-files`. A consumer that derives "how many files
41
+ # should I have compared?" from that view is comparing the
42
+ # parser's output against itself — the denominator shrinks
43
+ # with the numerator and a partial comparison reads as
44
+ # complete (#7710 review). `record-count` is the
45
+ # unfiltered denominator.
46
+ # upstream-files One `<upstream-path>:<upstream-blob-sha>` per line.
47
+ # Upstream blob SHAs pin the file as it exists at
48
+ # `pinned-commit` and are consumed by the drift workflow.
49
+ #
50
+ # NOTICE location: $NOTICE_FILE if set, else <script-dir>/../NOTICE.
51
+ #
52
+ # `set -euo pipefail` is internal; subcommand wrappers catch failures so the
53
+ # caller (`gdpr-gate.sh`) can `bash notice-frontmatter.sh days-stale 2>/dev/null
54
+ # || echo 999` without aborting the gate on parser death.
55
+ #
56
+ # TR2: target p95 <50ms over 100 invocations of `days-stale`.
57
+
58
+ set -euo pipefail
59
+
60
+ # Refuse to run under `set -x` while a live credential is in the environment
61
+ # (#7797). An xtrace of this script echoes every expansion, and the token would
62
+ # land in whatever captured that trace — a CI log, a `bash -x` debugging
63
+ # session, a pasted transcript. Placed immediately after `set` so nothing
64
+ # credential-bearing executes ahead of it.
65
+ case "$-" in
66
+ *x*)
67
+ if [ -n "${GH_TOKEN:+x}${GITHUB_TOKEN:+x}" ]; then
68
+ printf '[FATAL] refusing to trace with a live credential set (see #7797)\n' >&2
69
+ exit 78
70
+ fi
71
+ ;;
72
+ esac
73
+
74
+
75
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
76
+ NOTICE_FILE="${NOTICE_FILE:-$SCRIPT_DIR/../NOTICE}"
77
+
78
+ # Print only the YAML body between the first two `---` lines.
79
+ # Returns empty + exit 1 if no frontmatter.
80
+ extract_frontmatter() {
81
+ [[ -f "$NOTICE_FILE" ]] || return 1
82
+ awk '
83
+ BEGIN { count=0; in_fm=0 }
84
+ /^---[[:space:]]*$/ {
85
+ count++
86
+ if (count == 1) { in_fm = 1; next }
87
+ if (count == 2) { in_fm = 0; exit }
88
+ }
89
+ in_fm { print }
90
+ END { if (count < 2) exit 1 }
91
+ ' "$NOTICE_FILE"
92
+ }
93
+
94
+ cmd_field() {
95
+ local name="$1"
96
+ local fm
97
+ fm=$(extract_frontmatter) || return 1
98
+ [[ -n "$fm" ]] || return 1
99
+ # Match top-level scalar lines (`<name>: <value>`); skip indented (nested).
100
+ printf '%s\n' "$fm" | awk -v key="$name" '
101
+ /^[[:space:]]/ { next }
102
+ {
103
+ idx = index($0, ":")
104
+ if (idx == 0) next
105
+ k = substr($0, 1, idx - 1)
106
+ v = substr($0, idx + 1)
107
+ sub(/^[[:space:]]+/, "", v)
108
+ sub(/[[:space:]]+$/, "", v)
109
+ if (k == key) { print v; exit }
110
+ }
111
+ '
112
+ }
113
+
114
+ cmd_days_stale() {
115
+ local last_verified last_epoch today_epoch days
116
+ last_verified=$(cmd_field last-verified 2>/dev/null) || { echo 999; return 0; }
117
+ [[ -n "$last_verified" ]] || { echo 999; return 0; }
118
+ # Strict ISO-8601 date guard. `date -d` otherwise accepts "now",
119
+ # "yesterday", etc., letting a malicious NOTICE PR set last-verified to
120
+ # any natural-language value and pin days-stale at 0 forever.
121
+ [[ "$last_verified" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || { echo 999; return 0; }
122
+ # Anchor to UTC midnight so the comparison against `date -u +%s` is
123
+ # consistent across timezones (otherwise a UTC+12 host computes a day
124
+ # off the UTC-anchored today_epoch).
125
+ last_epoch=$(date -u -d "${last_verified}T00:00:00Z" +%s 2>/dev/null) || { echo 999; return 0; }
126
+ today_epoch=$(date -u +%s)
127
+ days=$(( (today_epoch - last_epoch) / 86400 ))
128
+ # Future date → treat as stale immediately (per SpecFlow P1.5).
129
+ if (( days < 0 )); then
130
+ echo 999
131
+ else
132
+ echo "$days"
133
+ fi
134
+ }
135
+
136
+ _emit_files() {
137
+ # Args: $1 = block-key ("lifted-files" | "soleur-authored"), $2 = path-key
138
+ # ("path" | "upstream-path"), $3 = sha-key ("local-blob-sha" |
139
+ # "upstream-blob-sha"). Walks the named block and prints
140
+ # `<path-value>:<sha-value>` per entry.
141
+ #
142
+ # The block key is a parameter rather than a literal because the registry
143
+ # has TWO lists with the same record shape and opposite provenance
144
+ # (#7710): upstream-derived files in `lifted-files`, Soleur-authored files
145
+ # in `soleur-authored`. Both are pinned by `local-blob-sha` and both are
146
+ # checked by vendor-pin-integrity.sh; only the former carries an upstream
147
+ # SHA, so only the former is a valid input to `upstream-files`.
148
+ local block_key="$1"
149
+ local path_key="$2"
150
+ local sha_key="$3"
151
+ local fm
152
+ fm=$(extract_frontmatter) || return 0
153
+ [[ -n "$fm" ]] || return 0
154
+ printf '%s\n' "$fm" | awk -v block_key="$block_key" -v path_key="$path_key" -v sha_key="$sha_key" '
155
+ BEGIN { in_block=0; cur_path=""; cur_sha="" }
156
+ $0 ~ "^" block_key ":[[:space:]]*$" { in_block=1; next }
157
+ /^[A-Za-z]/ { in_block=0 }
158
+ in_block {
159
+ line = $0
160
+ sub(/^[[:space:]]+/, "", line)
161
+ n = split(line, tok, /[[:space:]]+/)
162
+ # New entry sentinel: `- path: <value>` always opens a record. Flush
163
+ # the previous record before starting the new one.
164
+ # Normalize `key : value` (YAML-legal space-before-colon) to `key:`.
165
+ # Without this, tok[1] is the bare key and tok[2] is `:`, silently
166
+ # dropping the entry from the registry view.
167
+ sub(/[[:space:]]+:[[:space:]]+/, ": ", line)
168
+ n = split(line, tok, /[[:space:]]+/)
169
+ if (n >= 3 && tok[1] == "-" && tok[2] == "path:") {
170
+ if (cur_path != "" && cur_sha != "") print cur_path ":" cur_sha
171
+ cur_path = ""
172
+ cur_sha = ""
173
+ if (path_key == "path") cur_path = tok[3]
174
+ } else if (n >= 2 && tok[1] == path_key ":") {
175
+ # tok layout for `path:` and `upstream-path:` lines without leading dash.
176
+ cur_path = tok[2]
177
+ } else if (n >= 2 && tok[1] == sha_key ":") {
178
+ cur_sha = tok[2]
179
+ }
180
+ }
181
+ END {
182
+ if (cur_path != "" && cur_sha != "") print cur_path ":" cur_sha
183
+ }
184
+ '
185
+ }
186
+
187
+ cmd_cron_run_stale() {
188
+ # Days since the content-vendor-drift check last produced its attestation
189
+ # artifact. Always exits 0 — any failure mode (no token, no gh, network
190
+ # blocked, empty result, malformed timestamp, non-zero clock skew) resolves
191
+ # to 999 so the caller's subshell-exec contract holds. Wrap the network call
192
+ # with `timeout 5s` to bound the runtime-banner wall clock.
193
+ #
194
+ # DATA SOURCE (#7255). The check is the Inngest cron
195
+ # `apps/web-platform/server/inngest/functions/cron-content-vendor-drift.ts`
196
+ # — it has no GitHub Actions run, so a `gh run list` query can never see it
197
+ # (that is exactly how this probe once went dead at 999 with nobody
198
+ # noticing). What the run DOES leave behind on every completed execution is
199
+ # a GitHub artifact: the self-merging attestation PR on head branch
200
+ # `ci/vendor-attest-*` (`ATTEST_BRANCH_PREFIX` in the function file;
201
+ # ADR-203's unchanged-attestation machinery creates one even when zero
202
+ # files drift). "Days since the newest such PR was CREATED" is the honest
203
+ # "days since the check last ran to completion" — PR creation is the run's
204
+ # output, whereas mergedAt lags days behind the run and is unrelated to
205
+ # cron health.
206
+ #
207
+ # Query notes, both measured: `--state all` is load-bearing (the search
208
+ # treats merged/closed PRs correctly; a `--state merged` variant of this
209
+ # same query returned empty while the merged attest PR exists); and the
210
+ # `max` aggregation over `--limit 10` removes any dependence on
211
+ # search-result ordering. If this job's artifact moves again — new branch
212
+ # prefix, different substrate — the probe goes back to 999; the
213
+ # `TS-cron-argv` case in the notice-frontmatter suites pins the query shape
214
+ # so that regression is loud.
215
+ local token raw ts cron_epoch today_epoch days
216
+ token="${GH_TOKEN:-${GITHUB_TOKEN:-}}"
217
+ [[ -n "$token" ]] || { echo 999; return 0; }
218
+ command -v gh >/dev/null 2>&1 || { echo 999; return 0; }
219
+ # `// empty` collapses the empty result set to empty string.
220
+ # Belt-and-suspenders with the strict-ISO regex below — a softened guard
221
+ # alone would silently slip a null through.
222
+ raw=$(GH_TOKEN="$token" timeout 5s gh pr list \
223
+ --search "head:ci/vendor-attest" --state all --limit 10 \
224
+ --json createdAt --jq '[.[].createdAt] | max // empty' \
225
+ 2>/dev/null) || { echo 999; return 0; }
226
+ ts="${raw%%[[:space:]]*}"
227
+ [[ -n "$ts" ]] || { echo 999; return 0; }
228
+ [[ "$ts" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ ]] \
229
+ || { echo 999; return 0; }
230
+ cron_epoch=$(date -u -d "$ts" +%s 2>/dev/null) || { echo 999; return 0; }
231
+ today_epoch=$(date -u +%s)
232
+ days=$(( (today_epoch - cron_epoch) / 86400 ))
233
+ if (( days < 0 )); then echo 999; else echo "$days"; fi
234
+ }
235
+
236
+ cmd_lifted_files() {
237
+ _emit_files lifted-files path local-blob-sha
238
+ }
239
+
240
+ cmd_upstream_files() {
241
+ _emit_files lifted-files upstream-path upstream-blob-sha
242
+ }
243
+
244
+ cmd_record_count() {
245
+ # Count `- path:` record openers in the named block. Deliberately does NOT
246
+ # require the record to be complete: the whole point is to expose records
247
+ # that the filtered views drop.
248
+ local block_key="${1:-lifted-files}"
249
+ local fm
250
+ fm=$(extract_frontmatter) || { echo 0; return 0; }
251
+ [[ -n "$fm" ]] || { echo 0; return 0; }
252
+ printf '%s\n' "$fm" | awk -v block_key="$block_key" '
253
+ BEGIN { in_block=0; n=0 }
254
+ $0 ~ "^" block_key ":[[:space:]]*$" { in_block=1; next }
255
+ /^[A-Za-z]/ { in_block=0 }
256
+ in_block {
257
+ line = $0
258
+ sub(/^[[:space:]]+/, "", line)
259
+ sub(/[[:space:]]+:[[:space:]]+/, ": ", line)
260
+ n_tok = split(line, tok, /[[:space:]]+/)
261
+ if (n_tok >= 3 && tok[1] == "-" && tok[2] == "path:") n++
262
+ }
263
+ END { print n+0 }
264
+ '
265
+ }
266
+
267
+ cmd_key_count() {
268
+ # Count occurrences of a KEY inside the named block, independent of record
269
+ # boundaries.
270
+ #
271
+ # This exists as a SECOND, differently-derived view of the registry's size.
272
+ # `record-count` counts `- path:` openers, so it shares its record-opener
273
+ # predicate with `_emit_files` — which means deleting an OPENER line shrinks
274
+ # both views together and a completeness check comparing them holds while a
275
+ # record was silently absorbed into its predecessor (measured: declared 7,
276
+ # emitted 7, one record lost, #7710 review). Counting a key that every record
277
+ # carries but the opener predicate does NOT consume breaks that coupling.
278
+ local block_key="${1:-lifted-files}"
279
+ local want_key="${2:-status}"
280
+ local fm
281
+ fm=$(extract_frontmatter) || { echo 0; return 0; }
282
+ [[ -n "$fm" ]] || { echo 0; return 0; }
283
+ printf '%s\n' "$fm" | awk -v block_key="$block_key" -v want_key="$want_key" '
284
+ BEGIN { in_block=0; n=0 }
285
+ $0 ~ "^" block_key ":[[:space:]]*$" { in_block=1; next }
286
+ /^[A-Za-z]/ { in_block=0 }
287
+ in_block {
288
+ line = $0
289
+ sub(/^[[:space:]]+/, "", line)
290
+ sub(/[[:space:]]+:[[:space:]]+/, ": ", line)
291
+ split(line, tok, /[[:space:]]+/)
292
+ if (tok[1] == want_key ":") n++
293
+ }
294
+ END { print n+0 }
295
+ '
296
+ }
297
+
298
+ cmd_soleur_authored() {
299
+ # Soleur-authored reference files. These are NOT upstream-derived, so they
300
+ # carry a `local-blob-sha` only and never appear in `upstream-files` — a
301
+ # `lifted-files` row for one of them would attest goSprinto MIT provenance
302
+ # for Soleur's own writing, falsifying provenance in both directions.
303
+ _emit_files soleur-authored path local-blob-sha
304
+ }
305
+
306
+ case "${1:-}" in
307
+ field)
308
+ cmd_field "${2:-}" || true
309
+ ;;
310
+ days-stale)
311
+ cmd_days_stale
312
+ ;;
313
+ cron-run-stale)
314
+ cmd_cron_run_stale
315
+ ;;
316
+ lifted-files)
317
+ cmd_lifted_files
318
+ ;;
319
+ soleur-authored)
320
+ cmd_soleur_authored
321
+ ;;
322
+ record-count)
323
+ cmd_record_count "${2:-lifted-files}"
324
+ ;;
325
+ key-count)
326
+ cmd_key_count "${2:-lifted-files}" "${3:-status}"
327
+ ;;
328
+ upstream-files)
329
+ cmd_upstream_files
330
+ ;;
331
+ *)
332
+ echo "Usage: $0 {field <name>|days-stale|cron-run-stale|lifted-files|soleur-authored|upstream-files|record-count [block]|key-count [block] [key]}" >&2
333
+ exit 2
334
+ ;;
335
+ esac
336
+
337
+ exit 0
@@ -0,0 +1,39 @@
1
+ # gdpr-gate `--repo-scan` path deny-list.
2
+ #
3
+ # Single source of truth for paths the repo-scan walker MUST NOT read or
4
+ # forward to the model. Every pattern below is a bash `[[ =~ ]]` extended
5
+ # regex — NOT a shell glob. Patterns that look like globs (e.g. `*.pem`)
6
+ # silently fail to match.
7
+ #
8
+ # `repo-scan.sh` sets `LC_ALL=POSIX` for locale-determinism, but contributors
9
+ # editing patterns should still verify on both Linux and macOS — character
10
+ # classes for non-ASCII bytes still differ between bash builds.
11
+ #
12
+ # Format:
13
+ # - One pattern per line.
14
+ # - `#` lines are comments. Blank lines ignored.
15
+ # - Patterns are matched against the path as `git ls-files` reports it
16
+ # (relative to the repo root, forward-slash-separated, no leading `./`).
17
+ #
18
+ # v2 surface (7 patterns, verified at plan-write time per AC-DENYLIST-2):
19
+ # 1. .env* / .envrc at any depth — NFR-014 explicit. Pattern covers
20
+ # `.env`, `.env.local`, `.env.production`,
21
+ # `.envrc` (direnv files often hold
22
+ # `export KEY=...` lines).
23
+ # 2. secrets/ at any depth — defense-in-depth; intent-driven name.
24
+ # 3. .pem / .key / .crt / etc. — defense-in-depth; private-key shapes.
25
+ # Matched case-insensitively by repo-scan.sh
26
+ # (`shopt -s nocasematch`) so `.PEM`/`.KEY`
27
+ # filenames are also blocked.
28
+ # 4. test snapshot/golden dirs — realistic-shape fixtures.
29
+ # 5. web-platform test fixtures — known fixture root.
30
+ # 6. skill reference catalogues — gate's own layer files.
31
+ # 7. plan / spec markdown — design docs, not regulated data.
32
+
33
+ (^|/)\.env(\.[^/]*|rc)?$
34
+ (^|/)secrets/
35
+ \.(pem|key|crt|p8|pfx|jks|keystore|asc|ppk)$
36
+ (^|/)__synthesized__/|(^|/)__goldens__/|(^|/)__snapshots__/|\.snap$
37
+ ^apps/web-platform/test/fixtures/
38
+ ^plugins/soleur/skills/[^/]+/references/
39
+ ^knowledge-base/(project/)?(plans|specs)/.*\.md$