@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,419 @@
1
+ #!/usr/bin/env bash
2
+ # domain-model-drift.sh — /soleur:sync domain-model analyzer (#5754).
3
+ #
4
+ # Deterministically extracts a repo's structural domain model (RLS policies after
5
+ # last-writer-wins replay, table constraints, SECURITY DEFINER signatures, named TS
6
+ # guard symbols) and drift-checks it against the business-rules register
7
+ # (knowledge-base/engineering/architecture/domain-model.md).
8
+ #
9
+ # Modes:
10
+ # extract [--repo <path>] → JSON of live structural facts (stdout)
11
+ # drift [--repo <path>] [--register <path>] → two-way markdown drift report (stdout)
12
+ # write-row --register <path> --anchor <a> --statement <s>
13
+ # → approval-gated append to ## Auto-inferred
14
+ #
15
+ # The `extract` JSON is INTERNAL/UNSTABLE (carries schema_version); the consumer
16
+ # contract for the #5871 enforcement gates is finalized when #5871 constrains it.
17
+ #
18
+ # Guarantee is bounded to STRUCTURAL documentation coverage — NOT semantic
19
+ # access-control correctness. Dynamic RLS (EXECUTE format / DO $$), function-body
20
+ # logic, and ALTER POLICY partial-modifies are disclosed as blind_spots, never
21
+ # counted as facts. This is best-effort extraction, NOT a security audit.
22
+ set -euo pipefail
23
+ export LC_ALL=C
24
+
25
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
26
+ # shellcheck source=plugins/soleur/scripts/lib/domain-model-lib.sh
27
+ source "$SCRIPT_DIR/lib/domain-model-lib.sh"
28
+
29
+ # Shared context-sanitize lib (#10395), beside this script under lib/. When it
30
+ # is unreadable the same-name fallback carries this site's pre-change strip set
31
+ # (C0 minus \t\n, DEL, plus the NEL/LS/PS sed) — never weaker than today.
32
+ _ctx_lib="$SCRIPT_DIR/lib/context-sanitize.sh"
33
+ # shellcheck source=/dev/null
34
+ [[ -r "$_ctx_lib" ]] && . "$_ctx_lib" || true
35
+ declare -F soleur_ctx_sanitize_lines >/dev/null 2>&1 \
36
+ || soleur_ctx_sanitize_lines() { LC_ALL=C tr -d '\000-\010\013-\037\177' | LC_ALL=C sed -e $'s/\xc2\x85//g' -e $'s/\xe2\x80\xa8//g' -e $'s/\xe2\x80\xa9//g'; }
37
+
38
+ SCHEMA_VERSION=1
39
+ DISCLAIMER="Best-effort structural extraction from migrations/RLS/types; NOT a security audit or access-control attestation. Absence from this report does not imply an invariant is unenforced, and presence does not imply it is correctly enforced. Dynamic SQL and function-body logic are disclosed as blind_spots, not analyzed."
40
+
41
+ # --- shared tempfile cleanup: ONE array, ONE trap, registered in the MAIN shell ---
42
+ # Every mktemp in this script registers here. The trap is the only cleanup path.
43
+ #
44
+ # INVARIANT (do not break): allocation must happen in the MAIN SHELL, never inside
45
+ # a function that a caller runs under `$( )`. `drift` mode invokes emit_extract_json
46
+ # via command substitution (see emit_drift_report), so an append made inside that
47
+ # function would land in a subshell copy of the array and be lost, AND bash does not
48
+ # run the parent's EXIT trap when the subshell exits — the files would leak on every
49
+ # `drift` run while the trap looked correct. Allocate in the caller; pass paths in.
50
+ _TMPFILES=()
51
+ _cleanup_tmpfiles() { [[ ${#_TMPFILES[@]} -gt 0 ]] && rm -f "${_TMPFILES[@]}"; return 0; }
52
+ # INT/TERM as well as EXIT: bash does not run an EXIT trap for an uncaught
53
+ # SIGINT/SIGTERM in a non-interactive script, so Ctrl-C or a CI job kill would
54
+ # otherwise leak the spool files. Contents are non-sensitive by construction (the
55
+ # secret scan runs BEFORE any spool write) and mode is 0600, so this is disk
56
+ # hygiene rather than disclosure — but the leak is free to close.
57
+ trap _cleanup_tmpfiles EXIT INT TERM
58
+
59
+ # Allocate the two extract spool files in main-shell scope (see the invariant above).
60
+ SPOOL_FACTS=""
61
+ SPOOL_BLIND=""
62
+ alloc_spools() {
63
+ SPOOL_FACTS="$(mktemp)"; SPOOL_BLIND="$(mktemp)"
64
+ _TMPFILES+=("$SPOOL_FACTS" "$SPOOL_BLIND")
65
+ }
66
+
67
+ die() { echo "domain-model-drift: $*" >&2; exit 2; }
68
+ usage() { echo "usage: domain-model-drift.sh <extract|drift|write-row|init> [--repo <path>] [--register <path>] [--anchor <a>] [--statement <s>]" >&2; exit 2; }
69
+
70
+ # --- arg parsing (--terminated, quoted; no flag can arrive from file content) ---
71
+ MODE="${1:-}"; shift || true
72
+ REPO="."
73
+ REGISTER=""
74
+ ANCHOR=""
75
+ STATEMENT=""
76
+ while [[ $# -gt 0 ]]; do
77
+ case "$1" in
78
+ --repo) REPO="${2:-}"; shift 2 ;;
79
+ --register) REGISTER="${2:-}"; shift 2 ;;
80
+ --anchor) ANCHOR="${2:-}"; shift 2 ;;
81
+ --statement) STATEMENT="${2:-}"; shift 2 ;;
82
+ --) shift; break ;;
83
+ *) usage ;;
84
+ esac
85
+ done
86
+ [[ -n "$MODE" ]] || usage
87
+
88
+ # realpath-confine the repo root (reject nonexistent / unreadable)
89
+ REPO="$(realpath -e -- "$REPO" 2>/dev/null)" || die "--repo does not resolve to an existing path"
90
+ [[ -d "$REPO" ]] || die "--repo is not a directory"
91
+
92
+ # ---------------------------------------------------------------------------
93
+ # extract: emit the structural-facts JSON for REPO
94
+ # ---------------------------------------------------------------------------
95
+ #
96
+ # Spool files are ALLOCATED BY THE CALLER (alloc_spools) and passed in — this
97
+ # function is called under `$( )` in drift mode, so it must not own cleanup.
98
+ emit_extract_json() {
99
+ local facts_f="$1" blind_f="$2"
100
+ local migdir facts_tsv blind_tsv events
101
+ migdir="$(dm_find_migrations_dir "$REPO")"
102
+
103
+ if [[ -z "$migdir" ]]; then
104
+ jq -Sn --argjson v "$SCHEMA_VERSION" --arg d "$DISCLAIMER" \
105
+ '{schema_version:$v, stack:"unsupported", disclaimer:$d, facts:[], blind_spots:[]}'
106
+ return 0
107
+ fi
108
+
109
+ # gather the raw event stream (tokenizer treats SQL strictly as data)
110
+ local base_files=()
111
+ while IFS= read -r f; do [[ -n "$f" ]] && base_files+=("$f"); done < <(dm_base_migrations "$migdir")
112
+ events="$( { [[ ${#base_files[@]} -gt 0 ]] && dm_tokenize "${base_files[@]}"; dm_guards_from_ts "$REPO"; } )"
113
+
114
+ # reduce policy events (last-writer-wins) + pass constraints/guards → facts TSV
115
+ facts_tsv="$(printf '%s\n' "$events" | awk -F'\t' '
116
+ $1=="EVENT" && $2=="policy_create" { k=$4 SUBSEP $5; live[k]=$3 SUBSEP $6 }
117
+ $1=="EVENT" && $2=="policy_drop" { k=$4 SUBSEP $5; delete live[k] }
118
+ $1=="EVENT" && $2=="constraint" { printf "constraint\t%s › %s.%s\t%s\t%s\n", $3,$4,$5,$5,$6 }
119
+ $1=="EVENT" && $2=="guard" { printf "guard\t%s › %s()\t%s\t%s\n", $3,$5,$5,$6 }
120
+ END { for (k in live) { split(k,a,SUBSEP); split(live[k],v,SUBSEP);
121
+ printf "policy\t%s › %s.%s\t%s\t%s\n", v[1], a[1], a[2], a[2], v[2] } }
122
+ ' | LC_ALL=C sort -u)"
123
+
124
+ # blind spots (dedup by file+detail)
125
+ blind_tsv="$(printf '%s\n' "$events" | awk -F'\t' '
126
+ $1=="EVENT" && $2=="blind" { printf "%s\t%s\n", $3, $6 }
127
+ ' | LC_ALL=C sort -u)"
128
+
129
+ # fail-closed secret-shape scan over ALL assembled text before emit
130
+ if dm_secret_scan "$facts_tsv$blind_tsv"; then
131
+ echo "domain-model-drift: secret-shaped substring in extracted facts; refusing to emit" >&2
132
+ exit 3
133
+ fi
134
+
135
+ # Spool the TSVs to files and bind with --rawfile (#6720). A shell variable bound
136
+ # via --argjson is ONE argv argument and is capped by MAX_ARG_STRLEN = 131,072 B
137
+ # PER ARGUMENT (not ARG_MAX) — verified by bisect: 131,071 B passes, 131,072 B
138
+ # fails E2BIG. The fact corpus grows monotonically with the migration set, so the
139
+ # old form was on a collision course with a hard `Argument list too long`.
140
+ # --rawfile binds the file's RAW TEXT to a string variable and file I/O has no
141
+ # per-argument limit, so the ceiling is gone. The jq programs below are moved
142
+ # verbatim from the two former pre-passes — the source is TSV, and the program
143
+ # already parses TSV from a string, so this is a MOVE, not a rewrite.
144
+ # (--slurpfile was rejected: the payload is a single top-level array, so it would
145
+ # bind as [[...]] and yield a SILENT `.facts|length == 1` undercount.)
146
+ # Precedent: scripts/rule-metrics-aggregate.sh (rules_tsv_file / --rawfile rules_tsv).
147
+ printf '%s' "$facts_tsv" > "$facts_f"
148
+ printf '%s' "$blind_tsv" > "$blind_f"
149
+
150
+ jq -Sn --argjson v "$SCHEMA_VERSION" --arg d "$DISCLAIMER" \
151
+ --rawfile facts_tsv "$facts_f" --rawfile blind_tsv "$blind_f" \
152
+ '{schema_version:$v, stack:"supabase-ts", disclaimer:$d,
153
+ facts: ($facts_tsv | split("\n") | map(select(length>0)) | map(split("\t")) |
154
+ map({kind:.[0], anchor:.[1], object:.[2], detail:.[3]}
155
+ + (if .[0]=="policy" then {predicate:.[3]} else {} end))
156
+ | sort_by(.anchor)),
157
+ blind_spots: ($blind_tsv | split("\n") | map(select(length>0)) | map(split("\t")) |
158
+ map({file:.[0], detail:.[1]}) | sort_by([.file,.detail]))}'
159
+ }
160
+
161
+ # ---------------------------------------------------------------------------
162
+ # drift: two-way report — stale register citations + undocumented source facts.
163
+ # Exit: 0 = clean, 1 = drift found, 2 = error, 3 = secret-refuse.
164
+ # ---------------------------------------------------------------------------
165
+ emit_drift_report() {
166
+ local reg="$REGISTER"
167
+ if [[ -z "$reg" ]]; then
168
+ reg="$REPO/knowledge-base/engineering/architecture/domain-model.md"
169
+ fi
170
+ reg="$(realpath -e -- "$reg" 2>/dev/null)" || die "--register does not resolve to an existing file"
171
+ # confine: the register must live under the repo root (no arbitrary write/read target)
172
+ case "$reg" in "$REPO"/*) ;; *) die "--register must resolve under --repo" ;; esac
173
+
174
+ # NOTE: declare + assign on SEPARATE lines — `local x="$(cmd)"` masks the
175
+ # subshell exit code, which would swallow the fail-closed secret-refuse (exit 3).
176
+ local extract_json
177
+ extract_json="$(emit_extract_json "$SPOOL_FACTS" "$SPOOL_BLIND")" || exit $?
178
+
179
+ # FAIL-OPEN GUARD (user-impact P1): if no Supabase migrations dir resolved, the
180
+ # extract is empty and a naive report reads identical to a fully-documented repo
181
+ # (0 stale / 0 undocumented / exit 0). Surface the zero-source condition loudly
182
+ # and exit 2 (error) — a register cannot be drift-checked against unanalyzable source.
183
+ if [[ "$(printf '%s' "$extract_json" | jq -r '.stack')" == "unsupported" ]]; then
184
+ echo "# Domain-model drift report"
185
+ echo
186
+ echo "> $DISCLAIMER"
187
+ echo
188
+ echo "## Source not analyzable"
189
+ echo
190
+ echo "_No Supabase migrations directory resolved under \`$REPO\` — **0 source facts analyzed**. This is NOT a clean result: the register could not be drift-checked. (Generic/unsupported stack, or a moved/renamed migrations dir.)_"
191
+ exit 2
192
+ fi
193
+
194
+ # STALE: register code-citations whose symbol no longer resolves in the cited file.
195
+ local stale=""
196
+ while IFS=$'\t' read -r _ cfile csym; do
197
+ [[ -n "${csym:-}" ]] || continue
198
+ local path; path="$(find "$REPO" -type f -name "$cfile" -not -path '*/node_modules/*' 2>/dev/null | LC_ALL=C sort | head -1)"
199
+ if [[ -z "$path" ]]; then
200
+ stale+="- \`$cfile\` › \`$csym\` — cited file not found in repo"$'\n'
201
+ elif ! grep -qE "\\b${csym//[^A-Za-z0-9_]/}\\b" "$path" 2>/dev/null; then
202
+ stale+="- \`$cfile\` › \`$csym\` — symbol not found in \`$cfile\` (stale citation)"$'\n'
203
+ fi
204
+ done < <(dm_register_code_citations "$reg")
205
+
206
+ # UNDOCUMENTED: tables carrying a policy/constraint whose name the register never mentions.
207
+ local undoc="" undoc_n=0
208
+ local reg_body; reg_body="$(cat "$reg")"
209
+ while IFS= read -r tbl; do
210
+ [[ -n "$tbl" ]] || continue
211
+ if ! grep -qE "\\b${tbl//[^A-Za-z0-9_]/}\\b" <<<"$reg_body"; then
212
+ undoc_n=$((undoc_n + 1))
213
+ [[ $undoc_n -le 25 ]] && undoc+="- \`$tbl\` — table has RLS/constraints but is not named in the register"$'\n'
214
+ fi
215
+ done < <(printf '%s' "$extract_json" | jq -r '[.facts[] | select(.kind=="policy" or .kind=="constraint") | (.anchor | capture("› (?<t>[^.]+)\\.") .t)] | unique | .[]' 2>/dev/null | LC_ALL=C sort -u)
216
+
217
+ local blind_n; blind_n="$(printf '%s' "$extract_json" | jq '.blind_spots | length')"
218
+ local stale_n; stale_n="$(printf '%s\n' "$stale" | grep -c '^- ' || true)"
219
+
220
+ # ---- report ----
221
+ echo "# Domain-model drift report"
222
+ echo
223
+ echo "> $DISCLAIMER"
224
+ echo
225
+ echo "## Stale register citations ($stale_n)"
226
+ echo
227
+ [[ -n "$stale" ]] && printf '%s\n' "$stale" || echo "_none_"
228
+ echo "## Undocumented source facts ($undoc_n tables not in the register)"
229
+ echo
230
+ [[ -n "$undoc" ]] && printf '%s\n' "$undoc" || echo "_none_"
231
+ [[ $undoc_n -gt 25 ]] && echo "_… and $((undoc_n - 25)) more (capped)._" && echo
232
+ echo "## Blind spots ($blind_n)"
233
+ echo
234
+ echo "_$blind_n source constructs (dynamic \`EXECUTE format\`/\`DO \$\$\`, un-merged \`ALTER POLICY\`) were NOT statically analyzed and are not covered by the counts above._"
235
+
236
+ [[ $stale_n -gt 0 || $undoc_n -gt 0 ]] && exit 1 || exit 0
237
+ }
238
+
239
+ # ---------------------------------------------------------------------------
240
+ # write-row: the approval-gated write primitive. The /soleur:sync command calls
241
+ # this ONCE PER operator-approved candidate. It never touches the curated
242
+ # `## Business Rules` table; it appends an escaped, secret-scanned, deduped row
243
+ # to `## Auto-inferred (unreviewed)` via an atomic whole-file rewrite.
244
+ # Exit: 0 = written (or deduped no-op), 2 = error/abort, 3 = secret-refuse.
245
+ # ---------------------------------------------------------------------------
246
+ # ---------------------------------------------------------------------------
247
+ # init: seed an absent register with the canonical headings
248
+ # ---------------------------------------------------------------------------
249
+ #
250
+ # WHY THIS IS A SEPARATE SUBCOMMAND. `drift` and `write-row` both `realpath -e`
251
+ # the register and die when it does not resolve. Those guards are CORRECT — they
252
+ # must never operate on a path they cannot resolve — and they are deliberately
253
+ # left untouched. But they also mean `/soleur:sync domain-model` is dead on a
254
+ # fresh repo, which has no register and nothing to bootstrap it. `init` is the
255
+ # one command allowed to CREATE.
256
+ #
257
+ # The file shape lives here rather than in sync.md because `write-row` depends on
258
+ # the exact heading text and on the Auto-inferred table separator to find its
259
+ # append target. A register with the right headings but no separator is one
260
+ # write-row refuses to touch, so the two must be authored together.
261
+ init_register() {
262
+ local reg="$REGISTER"
263
+ [[ -n "$reg" ]] || die "init needs --register"
264
+
265
+ # `-m` (not `-e`): the whole point is that the file may not exist yet. It still
266
+ # canonicalizes `..` and symlinks, so the confinement check below is not
267
+ # bypassable by a traversal in the argument.
268
+ reg="$(realpath -m -- "$reg" 2>/dev/null)" || die "--register does not canonicalize"
269
+ case "$reg" in "$REPO"/*) ;; *) die "--register must resolve under --repo" ;; esac
270
+
271
+ # Idempotent: an existing register is a no-op success, so `all` dispatch can
272
+ # call init unconditionally on every run.
273
+ if [[ -e "$reg" ]]; then
274
+ [[ -f "$reg" ]] || die "--register exists and is not a regular file"
275
+ return 0
276
+ fi
277
+
278
+ mkdir -p -- "$(dirname -- "$reg")" || die "could not create the register's parent directory"
279
+
280
+ # Atomic create, mirroring write_row's temp-then-rename discipline.
281
+ local tmp; tmp="$(mktemp)"; _TMPFILES+=("$tmp")
282
+ cat > "$tmp" <<'REGISTER_TEMPLATE'
283
+ # Domain Model & Business Rules Register
284
+
285
+ > Seeded by `/soleur:sync domain-model`. The curated `## Business Rules` table is
286
+ > maintained by hand; the `## Auto-inferred (unreviewed)` table is machine-appended
287
+ > and is NEVER a source of truth.
288
+
289
+ ## Business Rules
290
+
291
+ | ID | Rule | Statement | Source |
292
+ |---|---|---|---|
293
+
294
+ ## Auto-inferred (unreviewed)
295
+
296
+ > Rows proposed by `/soleur:sync domain-model`. This section is **machine-appended**
297
+ > and is NEVER a source of truth. Promote a row to a curated rule by a deliberate
298
+ > human edit: assign a `BR-*` id, refine the statement, and keep the source anchor
299
+ > (the anchor is the dedup key, so a promoted row is never re-proposed). Do not
300
+ > hand-edit the table shape.
301
+
302
+ | Anchor | Candidate statement |
303
+ |---|---|
304
+ REGISTER_TEMPLATE
305
+
306
+ mv "$tmp" "$reg" || die "could not write the register"
307
+ }
308
+
309
+ write_row() {
310
+ [[ -n "$ANCHOR" && -n "$STATEMENT" ]] || die "write-row needs --anchor and --statement"
311
+ local reg="$REGISTER"
312
+ reg="$(realpath -e -- "$reg" 2>/dev/null)" || die "--register does not resolve to an existing file"
313
+ # confine the write target under the repo root — parity with drift mode (security P2).
314
+ # (REPO defaults to the resolved cwd; the sync command passes the repo-relative register.)
315
+ case "$reg" in "$REPO"/*) ;; *) die "--register must resolve under --repo" ;; esac
316
+
317
+ # fail-closed secret-shape scan on BOTH fields before any write
318
+ if dm_secret_scan "$ANCHOR$STATEMENT"; then
319
+ echo "domain-model-drift: secret-shaped substring in candidate row; refusing to write" >&2
320
+ exit 3
321
+ fi
322
+ # reject structural-breakout content outright (a forged BR-/heading row)
323
+ case "$ANCHOR$STATEMENT" in
324
+ *$'\n'*) die "candidate row contains a newline" ;;
325
+ esac
326
+ # escape markdown-table hazards: pipes, ALL C0 control chars (except tab \011;
327
+ # newline \012 already rejected above), DEL, and unicode line separators
328
+ # U+0085/U+2028/U+2029 (security P2 — full control-char class).
329
+ local esc_anchor esc_stmt
330
+ esc_anchor="$(printf '%s' "$ANCHOR" | soleur_ctx_sanitize_lines | sed 's/|/\\|/g')"
331
+ esc_stmt="$(printf '%s' "$STATEMENT" | soleur_ctx_sanitize_lines | sed 's/|/\\|/g')"
332
+ # neutralize a forged row/heading marker at the START of EITHER field — the anchor
333
+ # is column 1, exactly where curated `BR-NNN` IDs live (security P2).
334
+ esc_anchor="${esc_anchor/#BR-/BR‑}"; esc_anchor="${esc_anchor/#\#\#/\\#\\#}"
335
+ esc_stmt="${esc_stmt/#BR-/BR‑}"; esc_stmt="${esc_stmt/#\#\#/\\#\\#}"
336
+
337
+ # TOCTOU: re-read the register NOW and locate exactly one Auto-inferred heading.
338
+ #
339
+ # `hn="$(grep -c …)"` is an ASSIGNMENT whose status is the substitution's, and
340
+ # `grep -c` exits 1 when the count is 0 — so under `set -e` a register with NO
341
+ # Auto-inferred heading killed the script HERE, before the `die` below could print.
342
+ # Observed: exit 1 with completely empty stderr, and 1 is not in this command's
343
+ # documented 0/2/3 contract (it collides with drift's "drift found"). Every
344
+ # pre-existing register lacking the heading appended nothing, silently, forever —
345
+ # and #7332's headless path runs this on every sync. `|| true` keeps the informative
346
+ # abort reachable.
347
+ local hn
348
+ hn="$(grep -cE '^## Auto-inferred \(unreviewed\)' "$reg" || true)"
349
+ [[ "$hn" -eq 1 ]] || die "register has $hn '## Auto-inferred (unreviewed)' headings (want exactly 1) — aborting"
350
+
351
+ # Content-anchor dedup: never re-propose an anchor already present.
352
+ #
353
+ # Anchored on the whole table CELL, not a bare substring. `grep -qF "$ANCHOR"`
354
+ # matched anywhere in the file, so an anchor that is a PREFIX of an existing one
355
+ # was silently swallowed: with `m.sql > t.p10` already written, a genuinely new
356
+ # `m.sql > t.p1` deduped to a no-op and exited 0 — reproduced. Under #7332's
357
+ # headless path that drops real candidates on every sync with no diagnostic.
358
+ #
359
+ # Compare against the ESCAPED form too: the row is written as `$esc_anchor`, so a
360
+ # raw-form-only check never matches an anchor the escaper transformed (any `|`, or
361
+ # a leading `BR-`/`##`), which made re-runs append the same row without bound.
362
+ if grep -qxF "| $ANCHOR | $STATEMENT |" "$reg" \
363
+ || grep -qF "| $ANCHOR |" "$reg" \
364
+ || grep -qF "| $esc_anchor |" "$reg"; then
365
+ exit 0 # already known (curated or previously accepted) — no-op
366
+ fi
367
+
368
+ # atomic whole-file rewrite (mktemp + mv), inserting the row after the heading's table
369
+ # migrated onto the shared _TMPFILES trap — a local `trap … EXIT` here would
370
+ # REPLACE it, and the matching `trap - EXIT` would CLEAR it (write_row runs in
371
+ # the main shell, so the append is visible to the parent array).
372
+ local tmp; tmp="$(mktemp)"; _TMPFILES+=("$tmp")
373
+ # `insec` must CLEAR at the next `^## ` heading.
374
+ #
375
+ # Without that clause the insert lands at the first `^|---` at-or-after the
376
+ # Auto-inferred heading with no check that the separator BELONGS to that section.
377
+ # On a register whose Auto-inferred section precedes `## Business Rules` — a legal
378
+ # ordering nothing forbids — the candidate row was written INTO THE CURATED TABLE
379
+ # and write-row exited 0. The post-write verification below could not catch it
380
+ # because it only asks WHETHER the row landed, never WHERE.
381
+ #
382
+ # This is unattended now: #7332's headless path appends without per-row approval,
383
+ # so it would corrupt a customer's hand-curated business rules on a normal sync.
384
+ # The existing test fixture is built by `init`, which always emits the safe
385
+ # ordering, so the suite was structurally blind to it.
386
+ awk -v row="| $esc_anchor | $esc_stmt |" '
387
+ { print }
388
+ /^## Auto-inferred \(unreviewed\)/ { insec = 1; next }
389
+ /^## / { insec = 0 }
390
+ insec && /^\|---/ && !done { print row; done = 1; insec = 0 }
391
+ ' "$reg" > "$tmp"
392
+ # verify the row landed, AND that it landed inside the Auto-inferred section.
393
+ # A bare "did it appear anywhere" check is what let the curated-table write pass.
394
+ if ! grep -qF "$esc_anchor" "$tmp"; then
395
+ die "could not locate the Auto-inferred table separator — aborting (register unchanged)"
396
+ fi
397
+ local ai_line row_line
398
+ ai_line="$(grep -nE '^## Auto-inferred \(unreviewed\)' "$tmp" | head -1 | cut -d: -f1 || true)"
399
+ row_line="$(grep -nF "$esc_anchor" "$tmp" | head -1 | cut -d: -f1 || true)"
400
+ if [[ -z "$ai_line" || -z "$row_line" || "$row_line" -le "$ai_line" ]]; then
401
+ die "row would land outside the Auto-inferred section (row line ${row_line:-?}, heading line ${ai_line:-?}) — aborting (register unchanged)"
402
+ fi
403
+ # And that no LATER `^## ` heading precedes it — i.e. it is inside Auto-inferred's
404
+ # own section, not merely somewhere below the heading.
405
+ local next_h
406
+ next_h="$(awk -v s="$ai_line" 'NR>s && /^## /{print NR; exit}' "$tmp" || true)"
407
+ if [[ -n "$next_h" && "$row_line" -ge "$next_h" ]]; then
408
+ die "row would land in the section starting at line $next_h, not Auto-inferred — aborting (register unchanged)"
409
+ fi
410
+ mv "$tmp" "$reg"
411
+ }
412
+
413
+ case "$MODE" in
414
+ extract) alloc_spools; emit_extract_json "$SPOOL_FACTS" "$SPOOL_BLIND" ;;
415
+ drift) alloc_spools; emit_drift_report ;;
416
+ write-row) write_row ;;
417
+ init) init_register ;;
418
+ *) usage ;;
419
+ esac
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # emit-decision.sh -- append one field-allowlisted decision record to
4
+ # .soleur/decisions.jsonl at the project git root.
5
+ #
6
+ # Usage:
7
+ # emit-decision.sh --event route_decision --label work [--skill X] [--agent_domain D]
8
+ # emit-decision.sh --event tool_invocation --label flag-list [--skill X]
9
+ # emit-decision.sh --selfcheck
10
+ #
11
+ # NO-ECHO contract (the sole writer chokepoint -- everything funnels here):
12
+ # the record carries metadata ONLY. Never prompt text, args, file contents,
13
+ # repo names, or free-text reasons. `repo_hash` is a sha256 prefix of the git
14
+ # root path -- correlatable across runs, never the path itself.
15
+ #
16
+ # Portability contract: runs on tester machines (stock macOS). No flock,
17
+ # timeout, jq, python3, date -d, sed -i, stat, or readlink -f. bash 3.2-safe.
18
+ # A single `printf >>` under PIPE_BUF is atomic on POSIX -- no lock.
19
+ #
20
+ # Fail-open everywhere: exit 0 is the only exit. Kill switch:
21
+ # SOLEUR_DISABLE_DECISION_LOG=1 disables all writes.
22
+
23
+ set -uo pipefail
24
+
25
+ SOCK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
26
+
27
+ [ "${SOLEUR_DISABLE_DECISION_LOG:-}" = "1" ] && exit 0
28
+
29
+ EVENT=""; LABEL=""; SKILL=""; AGENT_DOMAIN=""; SELFCHECK=""
30
+ while [ $# -gt 0 ]; do
31
+ case "$1" in
32
+ --event) EVENT="${2:-}"; shift 2 ;;
33
+ --label) LABEL="${2:-}"; shift 2 ;;
34
+ --skill) SKILL="${2:-}"; shift 2 ;;
35
+ --agent_domain) AGENT_DOMAIN="${2:-}"; shift 2 ;;
36
+ --selfcheck) SELFCHECK=1; shift ;;
37
+ *) shift ;; # unknown args are ignored: never fatal
38
+ esac
39
+ done
40
+
41
+ if [ -n "$SELFCHECK" ]; then
42
+ # Runs BEFORE git-root resolution so the probe answers "emitter works",
43
+ # not "am I in a repo" — outside a repo the record path exits silently below.
44
+ echo "SOLEUR_EMIT_OK"
45
+ exit 0
46
+ fi
47
+
48
+ # shellcheck source=plugins/soleur/scripts/resolve-git-root.sh
49
+ . "$SOCK_DIR/resolve-git-root.sh" 2>/dev/null || exit 0
50
+ [ -d "${GIT_ROOT:-}" ] || exit 0
51
+
52
+ [ -n "$EVENT" ] || exit 0
53
+
54
+ # The event enum is frozen at the chokepoint ({route_decision, tool_invocation})
55
+ # — anything else is caller error, not a record. Fail-open per contract.
56
+ case "$EVENT" in
57
+ route_decision|tool_invocation) ;;
58
+ *) exit 0 ;;
59
+ esac
60
+
61
+ # --- derived fields ---------------------------------------------------------
62
+
63
+ harness="unknown"
64
+ if [ -n "${CLAUDECODE:-}" ]; then
65
+ harness="claude"
66
+ elif [ -n "${OPENCODE:-}" ] || [ "${AI_AGENT:-}" = "opencode" ]; then
67
+ harness="opencode"
68
+ elif [ -n "${GROK_HOME:-}" ] || [ -n "${GROK_AGENT:-}" ] || [ -n "${GROK_DEFAULT_MODEL:-}" ] || [ -n "${GROK_SUBAGENTS:-}" ]; then
69
+ harness="grok"
70
+ elif [ -n "${CODEX_THREAD_ID:-}" ]; then
71
+ harness="codex"
72
+ elif [ -n "${DEVIN:-}" ] || [ -n "${DEVIN_HOME:-}" ]; then
73
+ harness="devin"
74
+ fi
75
+
76
+ session_id="${CLAUDE_SESSION_ID:-${OPENCODE_SESSION_ID:-${DEVIN_SESSION_ID:-${CODEX_THREAD_ID:-${GROK_SESSION_ID:-}}}}}"
77
+ if [ -z "$session_id" ]; then
78
+ # Four harnesses still export no session env var (the repo's own learnings
79
+ # measured this — 2026-03-17 PPID note); OpenCode does export
80
+ # `OPENCODE_SESSION_ID`, measured live on 2.0.32, so it is in the chain above.
81
+ # Derive a session-stable,
82
+ # non-correlatable id from the parent pid: one emit writer per agent session
83
+ # shares the same PPID, and hashing keeps the raw pid out of the corpus.
84
+ if command -v sha256sum >/dev/null 2>&1; then
85
+ session_id="ppid-$(printf '%s:%s' "$GIT_ROOT" "$PPID" | sha256sum | cut -c1-12)"
86
+ elif command -v shasum >/dev/null 2>&1; then
87
+ session_id="ppid-$(printf '%s:%s' "$GIT_ROOT" "$PPID" | shasum -a 256 | cut -c1-12)"
88
+ else
89
+ session_id="unknown"
90
+ fi
91
+ fi
92
+
93
+ plugin_sha="unknown"
94
+ if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
95
+ _sha="$(git -C "$CLAUDE_PLUGIN_ROOT" rev-parse --short HEAD 2>/dev/null)"
96
+ [ -n "$_sha" ] && plugin_sha="$_sha"
97
+ fi
98
+ [ "$plugin_sha" = "unknown" ] && {
99
+ _sha="$(git -C "$SOCK_DIR/.." rev-parse --short HEAD 2>/dev/null)"
100
+ [ -n "$_sha" ] && plugin_sha="$_sha"
101
+ }
102
+
103
+ repo_hash="unknown"
104
+ if command -v sha256sum >/dev/null 2>&1; then
105
+ repo_hash="$(printf '%s' "$GIT_ROOT" | sha256sum | cut -c1-12)"
106
+ elif command -v shasum >/dev/null 2>&1; then
107
+ repo_hash="$(printf '%s' "$GIT_ROOT" | shasum -a 256 | cut -c1-12)"
108
+ fi
109
+
110
+ # --- emit -------------------------------------------------------------------
111
+
112
+ SOLEUR_DIR="$GIT_ROOT/.soleur"
113
+ LOG="$SOLEUR_DIR/decisions.jsonl"
114
+
115
+ mkdir -p "$SOLEUR_DIR" 2>/dev/null || exit 0
116
+ [ -f "$SOLEUR_DIR/.gitignore" ] || printf '*\n' > "$SOLEUR_DIR/.gitignore" 2>/dev/null || true
117
+
118
+ # rotate at ~5 MB (wc -c is portable; stat is not)
119
+ if [ -f "$LOG" ]; then
120
+ size="$(wc -c < "$LOG" 2>/dev/null | tr -d ' ')"
121
+ case "$size" in ''|*[!0-9]*) size=0 ;; esac
122
+ if [ "$size" -gt 5242880 ]; then
123
+ mv "$LOG" "$LOG.1" 2>/dev/null || true
124
+ fi
125
+ fi
126
+
127
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null)"
128
+
129
+ # field hygiene: values are allowlisted tokens, not free text. Reject outright
130
+ # (rather than escaping) anything containing a quote, backslash, or control
131
+ # character — a newline would split the append-only JSONL record and an ESC
132
+ # would carry terminal-escape injection into alpha-metrics.sh's stdout.
133
+ jesc() {
134
+ case "$1" in
135
+ *\"*|*\\*|*[[:cntrl:]]*) printf '__REDACTED__' ;;
136
+ *) printf '%s' "$1" ;;
137
+ esac
138
+ }
139
+
140
+ printf '{"v":1,"ts":"%s","event":"%s","label":"%s","skill":"%s","agent_domain":"%s","harness":"%s","session_id":"%s","plugin_sha":"%s","repo_hash":"%s"}\n' \
141
+ "$ts" "$(jesc "$EVENT")" "$(jesc "$LABEL")" "$(jesc "$SKILL")" "$(jesc "$AGENT_DOMAIN")" \
142
+ "$harness" "$(jesc "$session_id")" "$(jesc "$plugin_sha")" "$repo_hash" >> "$LOG" 2>/dev/null || true
143
+
144
+ exit 0