@soleur/opencode 0.0.0-stage → 3.354.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (832) hide show
  1. package/.claude-plugin/agents.manifest.json +476 -0
  2. package/.claude-plugin/plugin.json +42 -0
  3. package/README.md +44 -2
  4. package/agents/community/.gitkeep +0 -0
  5. package/agents/engineering/cto.md +87 -0
  6. package/agents/engineering/design/ddd-architect.md +95 -0
  7. package/agents/engineering/discovery/agent-finder.md +214 -0
  8. package/agents/engineering/discovery/functional-discovery.md +182 -0
  9. package/agents/engineering/infra/infra-security.md +151 -0
  10. package/agents/engineering/infra/platform-strategist.md +109 -0
  11. package/agents/engineering/infra/terraform-architect.md +171 -0
  12. package/agents/engineering/prompt-engineer.md +37 -0
  13. package/agents/engineering/research/best-practices-researcher.md +115 -0
  14. package/agents/engineering/research/framework-docs-researcher.md +93 -0
  15. package/agents/engineering/research/git-history-analyzer.md +53 -0
  16. package/agents/engineering/research/learnings-researcher.md +285 -0
  17. package/agents/engineering/research/repo-research-analyst.md +118 -0
  18. package/agents/engineering/review/agent-native-reviewer.md +279 -0
  19. package/agents/engineering/review/architecture-strategist.md +61 -0
  20. package/agents/engineering/review/code-quality-analyst.md +92 -0
  21. package/agents/engineering/review/code-simplicity-reviewer.md +109 -0
  22. package/agents/engineering/review/data-integrity-guardian.md +82 -0
  23. package/agents/engineering/review/data-migration-expert.md +98 -0
  24. package/agents/engineering/review/deployment-verification-agent.md +183 -0
  25. package/agents/engineering/review/dhh-rails-reviewer.md +46 -0
  26. package/agents/engineering/review/kieran-rails-reviewer.md +87 -0
  27. package/agents/engineering/review/legacy-code-expert.md +55 -0
  28. package/agents/engineering/review/observability-coverage-reviewer.md +147 -0
  29. package/agents/engineering/review/pattern-recognition-specialist.md +59 -0
  30. package/agents/engineering/review/performance-oracle.md +130 -0
  31. package/agents/engineering/review/security-sentinel.md +167 -0
  32. package/agents/engineering/review/semgrep-sast.md +36 -0
  33. package/agents/engineering/review/test-design-reviewer.md +150 -0
  34. package/agents/engineering/review/user-impact-reviewer.md +70 -0
  35. package/agents/engineering/workflow/pr-comment-resolver.md +69 -0
  36. package/agents/finance/budget-analyst.md +29 -0
  37. package/agents/finance/cfo.md +44 -0
  38. package/agents/finance/financial-reporter.md +30 -0
  39. package/agents/finance/revenue-analyst.md +30 -0
  40. package/agents/legal/clo.md +115 -0
  41. package/agents/legal/legal-compliance-auditor.md +110 -0
  42. package/agents/legal/legal-document-generator.md +134 -0
  43. package/agents/marketing/analytics-analyst.md +25 -0
  44. package/agents/marketing/brand-architect.md +181 -0
  45. package/agents/marketing/cmo.md +76 -0
  46. package/agents/marketing/conversion-optimizer.md +19 -0
  47. package/agents/marketing/copywriter.md +20 -0
  48. package/agents/marketing/fact-checker.md +70 -0
  49. package/agents/marketing/growth-strategist.md +145 -0
  50. package/agents/marketing/paid-media-strategist.md +28 -0
  51. package/agents/marketing/pricing-strategist.md +17 -0
  52. package/agents/marketing/programmatic-seo-specialist.md +25 -0
  53. package/agents/marketing/retention-strategist.md +23 -0
  54. package/agents/marketing/seo-aeo-analyst.md +164 -0
  55. package/agents/operations/coo.md +50 -0
  56. package/agents/operations/ops-advisor.md +78 -0
  57. package/agents/operations/ops-provisioner.md +101 -0
  58. package/agents/operations/ops-research.md +52 -0
  59. package/agents/operations/service-automator.md +278 -0
  60. package/agents/product/business-validator.md +206 -0
  61. package/agents/product/competitive-intelligence.md +89 -0
  62. package/agents/product/cpo.md +63 -0
  63. package/agents/product/design/ux-design-lead.md +209 -0
  64. package/agents/product/spec-flow-analyzer.md +122 -0
  65. package/agents/sales/cro.md +44 -0
  66. package/agents/sales/deal-architect.md +29 -0
  67. package/agents/sales/outbound-strategist.md +29 -0
  68. package/agents/sales/pipeline-analyst.md +29 -0
  69. package/agents/support/cco.md +48 -0
  70. package/agents/support/community-manager.md +570 -0
  71. package/agents/support/ticket-triage.md +70 -0
  72. package/bin/soleur-opencode.js +29 -0
  73. package/commands/go.md +660 -0
  74. package/commands/help.md +273 -0
  75. package/commands/sync.md +977 -0
  76. package/commands/version.md +103 -0
  77. package/hooks/antigravity-hooks.json +84 -0
  78. package/hooks/antigravity-session-start.sh +15 -0
  79. package/hooks/bare-root-cwd-guard.sh +131 -0
  80. package/hooks/browser-snapshot-credential-guard.sh +200 -0
  81. package/hooks/codex-session-start.sh +9 -0
  82. package/hooks/compaction-state.sh +525 -0
  83. package/hooks/destructive-command-guard.sh +1387 -0
  84. package/hooks/devin-session-start.sh +90 -0
  85. package/hooks/ext-filter-detect.sh +171 -0
  86. package/hooks/hooks.json +133 -0
  87. package/hooks/lib/hook-tool-kind.sh +24 -0
  88. package/hooks/lib/log-rotation.sh +176 -0
  89. package/hooks/lib/shell-argv.pl +576 -0
  90. package/hooks/memory-backstop.sh +1114 -0
  91. package/hooks/operator-stage-approval.sh +391 -0
  92. package/hooks/stop-hook.sh +367 -0
  93. package/hooks/unkept-promise-hook.sh +383 -0
  94. package/hooks/version-banner.sh +127 -0
  95. package/hooks/welcome-hook.sh +50 -0
  96. package/install.js +29 -0
  97. package/lib/agent-registry.ts +154 -0
  98. package/lib/c4-canonical-cli.mjs +34 -0
  99. package/lib/c4-canonical.mjs +46 -0
  100. package/lib/c4-from-components.ts +554 -0
  101. package/lib/go-routing.ts +81 -0
  102. package/lib/grok-inspect-contract.ts +311 -0
  103. package/lib/harness-model-map.ts +101 -0
  104. package/lib/harness-parity.ts +726 -0
  105. package/lib/harness-tool-map.ts +180 -0
  106. package/lib/harness.ts +716 -0
  107. package/lib/heartbeat-live-reconcile.ts +1153 -0
  108. package/lib/heartbeat-manifest.ts +361 -0
  109. package/lib/kb-coverage.ts +252 -0
  110. package/lib/pr-merge-poll.ts +103 -0
  111. package/lib/workflow-fidelity.ts +388 -0
  112. package/opencode/INSTRUCTIONS.md +171 -0
  113. package/opencode/agents/engineering/cto.md +10 -0
  114. package/opencode/agents/engineering/design/ddd-architect.md +10 -0
  115. package/opencode/agents/engineering/discovery/agent-finder.md +10 -0
  116. package/opencode/agents/engineering/discovery/functional-discovery.md +10 -0
  117. package/opencode/agents/engineering/infra/infra-security.md +10 -0
  118. package/opencode/agents/engineering/infra/platform-strategist.md +10 -0
  119. package/opencode/agents/engineering/infra/terraform-architect.md +10 -0
  120. package/opencode/agents/engineering/prompt-engineer.md +10 -0
  121. package/opencode/agents/engineering/research/best-practices-researcher.md +10 -0
  122. package/opencode/agents/engineering/research/framework-docs-researcher.md +10 -0
  123. package/opencode/agents/engineering/research/git-history-analyzer.md +10 -0
  124. package/opencode/agents/engineering/research/learnings-researcher.md +10 -0
  125. package/opencode/agents/engineering/research/repo-research-analyst.md +10 -0
  126. package/opencode/agents/engineering/review/agent-native-reviewer.md +10 -0
  127. package/opencode/agents/engineering/review/architecture-strategist.md +10 -0
  128. package/opencode/agents/engineering/review/code-quality-analyst.md +10 -0
  129. package/opencode/agents/engineering/review/code-simplicity-reviewer.md +10 -0
  130. package/opencode/agents/engineering/review/data-integrity-guardian.md +10 -0
  131. package/opencode/agents/engineering/review/data-migration-expert.md +10 -0
  132. package/opencode/agents/engineering/review/deployment-verification-agent.md +10 -0
  133. package/opencode/agents/engineering/review/dhh-rails-reviewer.md +10 -0
  134. package/opencode/agents/engineering/review/kieran-rails-reviewer.md +10 -0
  135. package/opencode/agents/engineering/review/legacy-code-expert.md +10 -0
  136. package/opencode/agents/engineering/review/observability-coverage-reviewer.md +10 -0
  137. package/opencode/agents/engineering/review/pattern-recognition-specialist.md +10 -0
  138. package/opencode/agents/engineering/review/performance-oracle.md +10 -0
  139. package/opencode/agents/engineering/review/security-sentinel.md +10 -0
  140. package/opencode/agents/engineering/review/semgrep-sast.md +10 -0
  141. package/opencode/agents/engineering/review/test-design-reviewer.md +10 -0
  142. package/opencode/agents/engineering/review/user-impact-reviewer.md +10 -0
  143. package/opencode/agents/engineering/workflow/pr-comment-resolver.md +10 -0
  144. package/opencode/agents/finance/budget-analyst.md +10 -0
  145. package/opencode/agents/finance/cfo.md +10 -0
  146. package/opencode/agents/finance/financial-reporter.md +10 -0
  147. package/opencode/agents/finance/revenue-analyst.md +10 -0
  148. package/opencode/agents/legal/clo.md +10 -0
  149. package/opencode/agents/legal/legal-compliance-auditor.md +10 -0
  150. package/opencode/agents/legal/legal-document-generator.md +10 -0
  151. package/opencode/agents/marketing/analytics-analyst.md +10 -0
  152. package/opencode/agents/marketing/brand-architect.md +10 -0
  153. package/opencode/agents/marketing/cmo.md +10 -0
  154. package/opencode/agents/marketing/conversion-optimizer.md +10 -0
  155. package/opencode/agents/marketing/copywriter.md +10 -0
  156. package/opencode/agents/marketing/fact-checker.md +10 -0
  157. package/opencode/agents/marketing/growth-strategist.md +10 -0
  158. package/opencode/agents/marketing/paid-media-strategist.md +10 -0
  159. package/opencode/agents/marketing/pricing-strategist.md +10 -0
  160. package/opencode/agents/marketing/programmatic-seo-specialist.md +10 -0
  161. package/opencode/agents/marketing/retention-strategist.md +10 -0
  162. package/opencode/agents/marketing/seo-aeo-analyst.md +10 -0
  163. package/opencode/agents/operations/coo.md +10 -0
  164. package/opencode/agents/operations/ops-advisor.md +10 -0
  165. package/opencode/agents/operations/ops-provisioner.md +10 -0
  166. package/opencode/agents/operations/ops-research.md +10 -0
  167. package/opencode/agents/operations/service-automator.md +10 -0
  168. package/opencode/agents/product/business-validator.md +10 -0
  169. package/opencode/agents/product/competitive-intelligence.md +10 -0
  170. package/opencode/agents/product/cpo.md +10 -0
  171. package/opencode/agents/product/design/ux-design-lead.md +10 -0
  172. package/opencode/agents/product/spec-flow-analyzer.md +10 -0
  173. package/opencode/agents/sales/cro.md +10 -0
  174. package/opencode/agents/sales/deal-architect.md +10 -0
  175. package/opencode/agents/sales/outbound-strategist.md +10 -0
  176. package/opencode/agents/sales/pipeline-analyst.md +10 -0
  177. package/opencode/agents/support/cco.md +10 -0
  178. package/opencode/agents/support/community-manager.md +10 -0
  179. package/opencode/agents/support/ticket-triage.md +10 -0
  180. package/opencode/commands/go.md +10 -0
  181. package/opencode/commands/help.md +10 -0
  182. package/opencode/commands/sync.md +10 -0
  183. package/opencode/commands/version.md +11 -0
  184. package/opencode/opencode.json +8 -0
  185. package/opencode/plugin.ts +818 -0
  186. package/package.json +36 -4
  187. package/scripts/admin-merge-ready.sh +545 -0
  188. package/scripts/admin-merge-ready.test.sh +753 -0
  189. package/scripts/affected-tests.sh +908 -0
  190. package/scripts/affected-tests.test.sh +1797 -0
  191. package/scripts/alpha-metrics.sh +78 -0
  192. package/scripts/alpha-metrics.test.sh +115 -0
  193. package/scripts/ancestor-signal-helpers.baseline.txt +16 -0
  194. package/scripts/audit-flag-flip.sh +107 -0
  195. package/scripts/check-red-on-main.sh +316 -0
  196. package/scripts/ci-head-verdict.sh +411 -0
  197. package/scripts/cloud-detect.sh +193 -0
  198. package/scripts/delegation-verify.sh +657 -0
  199. package/scripts/delegation-verify.test.sh +1424 -0
  200. package/scripts/deploy-arm.sh +475 -0
  201. package/scripts/domain-model-drift.sh +419 -0
  202. package/scripts/emit-decision.sh +144 -0
  203. package/scripts/emit-decision.test.sh +144 -0
  204. package/scripts/ext-filter-divergence-corpus.txt +15 -0
  205. package/scripts/ext-filter-divergence.sh +189 -0
  206. package/scripts/generate-c4-from-components.ts +442 -0
  207. package/scripts/grok-fidelity-gate.sh +68 -0
  208. package/scripts/grok-pre-push-gate.sh +232 -0
  209. package/scripts/harness-discovery-smoke.ts +906 -0
  210. package/scripts/harness-parity-census.ts +92 -0
  211. package/scripts/inngest-luks-alert-armed-probe.ts +29 -0
  212. package/scripts/install-opencode-adapter.ts +509 -0
  213. package/scripts/lib/affected-tests/common.sh +365 -0
  214. package/scripts/lib/affected-tests/go.sh +157 -0
  215. package/scripts/lib/affected-tests/js.sh +188 -0
  216. package/scripts/lib/affected-tests/nx-turbo.sh +98 -0
  217. package/scripts/lib/affected-tests/python.sh +185 -0
  218. package/scripts/lib/context-sanitize.sh +49 -0
  219. package/scripts/lib/domain-model-lib.sh +180 -0
  220. package/scripts/lib/ext-filter-grammar.tsv +34 -0
  221. package/scripts/lib/operator-script.sh +1236 -0
  222. package/scripts/lib/proc.sh +580 -0
  223. package/scripts/lib/session-state.sh +748 -0
  224. package/scripts/lib/tmp-classify.sh +843 -0
  225. package/scripts/lib/wrapper-boundary.sh +47 -0
  226. package/scripts/lint-ratchet.py +1547 -0
  227. package/scripts/monitor-pr-checks.sh +441 -0
  228. package/scripts/pipeline-tally.sh +756 -0
  229. package/scripts/pipeline-tally.test.sh +740 -0
  230. package/scripts/plugin-version.sh +528 -0
  231. package/scripts/precommit-guard.sh +115 -0
  232. package/scripts/precommit-guard.test.sh +254 -0
  233. package/scripts/reconcile-live-heartbeats.ts +705 -0
  234. package/scripts/render-c4-model.sh +217 -0
  235. package/scripts/resolve-git-root.sh +55 -0
  236. package/scripts/resolve-regenerable-conflicts.sh +363 -0
  237. package/scripts/resolve-regenerable-conflicts.test.sh +780 -0
  238. package/scripts/ruff-requirements.txt +22 -0
  239. package/scripts/run-in-pid-namespace.sh +98 -0
  240. package/scripts/run-in-pid-namespace.test.sh +290 -0
  241. package/scripts/scan-ancestor-signal-helpers.py +556 -0
  242. package/scripts/scan-ancestor-signal-helpers.test.sh +670 -0
  243. package/scripts/setup-ralph-loop.sh +238 -0
  244. package/scripts/sync-cursor-name-map.ts +316 -0
  245. package/scripts/sync-grok-agent-compat.ts +188 -0
  246. package/scripts/sync-npm-package.ts +165 -0
  247. package/scripts/sync-opencode-adapter.ts +498 -0
  248. package/scripts/sync-pr-behind.sh +647 -0
  249. package/scripts/sync-pr-behind.test.sh +252 -0
  250. package/scripts/taste-profile-update.sh +180 -0
  251. package/scripts/taste-profile-update.test.sh +167 -0
  252. package/scripts/write-budget-marker.sh +23 -0
  253. package/scripts/write-kb-coverage.ts +113 -0
  254. package/skills/admin-ip-refresh/SKILL.md +81 -0
  255. package/skills/admin-ip-refresh/references/admin-ip-refresh-procedure.md +201 -0
  256. package/skills/agent-browser/SKILL.md +698 -0
  257. package/skills/agent-browser/scripts/playwright-mcp-profile-slot.sh +304 -0
  258. package/skills/agent-browser/scripts/playwright-mcp-redact-proxy.py +964 -0
  259. package/skills/agent-browser/scripts/redact-a11y-snapshot.py +443 -0
  260. package/skills/agent-browser/test/fixtures/capture-playwright-mcp-fixtures.py +217 -0
  261. package/skills/agent-browser/test/fixtures/fake-passthrough-proxy.py +24 -0
  262. package/skills/agent-browser/test/fixtures/fake-playwright-mcp.py +131 -0
  263. package/skills/agent-browser/test/fixtures/make-proxy-mutant.py +48 -0
  264. package/skills/agent-browser/test/fixtures/odd-shapes/dialog-link-injection.json +10 -0
  265. package/skills/agent-browser/test/fixtures/odd-shapes/empty-content.json +5 -0
  266. package/skills/agent-browser/test/fixtures/odd-shapes/error-and-result.json +4 -0
  267. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-bool.json +6 -0
  268. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-string.json +6 -0
  269. package/skills/agent-browser/test/fixtures/odd-shapes/error-message-tree.json +6 -0
  270. package/skills/agent-browser/test/fixtures/odd-shapes/error-no-data.json +6 -0
  271. package/skills/agent-browser/test/fixtures/odd-shapes/error-string.json +4 -0
  272. package/skills/agent-browser/test/fixtures/odd-shapes/error-with-data.json +9 -0
  273. package/skills/agent-browser/test/fixtures/odd-shapes/evaluate-escaped-object.json +10 -0
  274. package/skills/agent-browser/test/fixtures/odd-shapes/invalid-utf8.json +4 -0
  275. package/skills/agent-browser/test/fixtures/odd-shapes/link-result.json +10 -0
  276. package/skills/agent-browser/test/fixtures/odd-shapes/list-two-results.json +6 -0
  277. package/skills/agent-browser/test/fixtures/odd-shapes/meta-in-result.json +13 -0
  278. package/skills/agent-browser/test/fixtures/odd-shapes/no-content.json +5 -0
  279. package/skills/agent-browser/test/fixtures/odd-shapes/quoted-key.json +10 -0
  280. package/skills/agent-browser/test/fixtures/odd-shapes/resource-block.json +18 -0
  281. package/skills/agent-browser/test/fixtures/odd-shapes/result-and-method.json +11 -0
  282. package/skills/agent-browser/test/fixtures/odd-shapes/result-string.json +3 -0
  283. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped-one-row.json +10 -0
  284. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped.json +10 -0
  285. package/skills/agent-browser/test/fixtures/odd-shapes/structured-content.json +13 -0
  286. package/skills/agent-browser/test/fixtures/odd-shapes/tools-list-no-tools.json +5 -0
  287. package/skills/agent-browser/test/fixtures/odd-shapes/tree-no-credential.json +10 -0
  288. package/skills/agent-browser/test/fixtures/odd-shapes/two-text-blocks.json +14 -0
  289. package/skills/agent-browser/test/fixtures/odd-shapes/unparsable-line.json +3 -0
  290. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-brace.json +10 -0
  291. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-link-substring.json +10 -0
  292. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/close.json +12 -0
  293. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/evaluate.json +12 -0
  294. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/find.json +12 -0
  295. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/framing.json +6 -0
  296. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/initialize.json +14 -0
  297. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate-link.json +12 -0
  298. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate.json +12 -0
  299. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/roots-list-request.json +5 -0
  300. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/screenshot.json +17 -0
  301. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-filename.json +12 -0
  302. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-json.json +12 -0
  303. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-raw.json +12 -0
  304. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot.json +12 -0
  305. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/tools-list.json +827 -0
  306. package/skills/agent-browser/test/fixtures/proxy-session-driver.py +138 -0
  307. package/skills/agent-browser/test/fixtures/session-facts.py +102 -0
  308. package/skills/agent-browser/test/playwright-mcp-lifetime.test.sh +1620 -0
  309. package/skills/agent-browser/test/playwright-mcp-redact-proxy.test.sh +1599 -0
  310. package/skills/agent-browser/test/redact-a11y-snapshot.test.sh +527 -0
  311. package/skills/agent-native-architecture/SKILL.md +479 -0
  312. package/skills/agent-native-architecture/references/action-parity-discipline.md +430 -0
  313. package/skills/agent-native-architecture/references/agent-execution-patterns.md +483 -0
  314. package/skills/agent-native-architecture/references/agent-native-testing.md +605 -0
  315. package/skills/agent-native-architecture/references/architecture-patterns.md +493 -0
  316. package/skills/agent-native-architecture/references/dynamic-context-injection.md +358 -0
  317. package/skills/agent-native-architecture/references/files-universal-interface.md +314 -0
  318. package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +381 -0
  319. package/skills/agent-native-architecture/references/mcp-tool-design.md +524 -0
  320. package/skills/agent-native-architecture/references/mobile-patterns.md +897 -0
  321. package/skills/agent-native-architecture/references/product-implications.md +478 -0
  322. package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +342 -0
  323. package/skills/agent-native-architecture/references/self-modification.md +294 -0
  324. package/skills/agent-native-architecture/references/shared-workspace-architecture.md +700 -0
  325. package/skills/agent-native-architecture/references/system-prompt-design.md +263 -0
  326. package/skills/agent-native-audit/SKILL.md +300 -0
  327. package/skills/agent-native-audit/workflows/agent-native-audit.workflow.js +423 -0
  328. package/skills/andrew-kane-gem-writer/SKILL.md +189 -0
  329. package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  330. package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  331. package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  332. package/skills/andrew-kane-gem-writer/references/resources.md +126 -0
  333. package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  334. package/skills/architecture/SKILL.md +436 -0
  335. package/skills/architecture/references/adr-template.md +154 -0
  336. package/skills/architecture/references/likec4-reference.md +136 -0
  337. package/skills/architecture/references/nfr-reference.md +126 -0
  338. package/skills/archive-kb/SKILL.md +86 -0
  339. package/skills/archive-kb/scripts/archive-kb.sh +300 -0
  340. package/skills/archive-kb/test/archive-kb-partial-run.test.sh +276 -0
  341. package/skills/atdd-developer/SKILL.md +65 -0
  342. package/skills/brainstorm/SKILL.md +701 -0
  343. package/skills/brainstorm/references/brainstorm-brand-workshop.md +153 -0
  344. package/skills/brainstorm/references/brainstorm-domain-config.md +63 -0
  345. package/skills/brainstorm/references/brainstorm-validation-workshop.md +65 -0
  346. package/skills/brainstorm/references/ui-surface-terms.md +42 -0
  347. package/skills/brainstorm-techniques/SKILL.md +231 -0
  348. package/skills/brainstorm-techniques/references/decision-principles.md +150 -0
  349. package/skills/brainstorm-techniques/references/phase-boundaries.md +103 -0
  350. package/skills/brainstorm-techniques/references/standing-delegation.md +407 -0
  351. package/skills/brainstorm-techniques/references/technical-ruling-delegation.md +174 -0
  352. package/skills/campaign-calendar/SKILL.md +145 -0
  353. package/skills/cf-token-scope/SKILL.md +164 -0
  354. package/skills/cf-token-scope/references/widen-playbook.md +114 -0
  355. package/skills/cf-token-scope/scripts/cf-token-scope.sh +253 -0
  356. package/skills/changelog/SKILL.md +142 -0
  357. package/skills/code-to-prd/SKILL.md +66 -0
  358. package/skills/code-to-prd/references/banner-template.md +12 -0
  359. package/skills/code-to-prd/references/prd-template.md +41 -0
  360. package/skills/code-to-prd/scripts/code-to-prd.sh +634 -0
  361. package/skills/code-to-prd/test/code-to-prd.test.sh +447 -0
  362. package/skills/code-to-prd/test/fixture/.env.example +7 -0
  363. package/skills/code-to-prd/test/fixture/app/about/page.tsx +11 -0
  364. package/skills/code-to-prd/test/fixture/app/api/health/route.ts +10 -0
  365. package/skills/code-to-prd/test/fixture/app/page.tsx +14 -0
  366. package/skills/code-to-prd/test/fixture/next.config.mjs +3 -0
  367. package/skills/code-to-prd/test/fixture/package.json +6 -0
  368. package/skills/cohort-status/SKILL.md +62 -0
  369. package/skills/community/SKILL.md +210 -0
  370. package/skills/community/scripts/bsky-community.sh +644 -0
  371. package/skills/community/scripts/bsky-setup.sh +631 -0
  372. package/skills/community/scripts/community-router.sh +93 -0
  373. package/skills/community/scripts/discord-community.sh +487 -0
  374. package/skills/community/scripts/discord-setup.sh +784 -0
  375. package/skills/community/scripts/github-community.sh +706 -0
  376. package/skills/community/scripts/hn-community.sh +233 -0
  377. package/skills/community/scripts/lib/hmac-sha1-b64.sh +126 -0
  378. package/skills/community/scripts/linkedin-community.sh +750 -0
  379. package/skills/community/scripts/linkedin-setup.sh +758 -0
  380. package/skills/community/scripts/x-community.sh +890 -0
  381. package/skills/community/scripts/x-setup.sh +713 -0
  382. package/skills/community/test/community-argv.test.sh +2922 -0
  383. package/skills/community/test/github-community.test.sh +981 -0
  384. package/skills/competitive-analysis/SKILL.md +69 -0
  385. package/skills/competitive-analysis/references/peer-plugin-audit.md +218 -0
  386. package/skills/compound/SKILL.md +673 -0
  387. package/skills/compound/scripts/token-efficiency-report.sh +334 -0
  388. package/skills/compound/test/phase-16.test.sh +379 -0
  389. package/skills/compound-capture/SKILL.md +791 -0
  390. package/skills/compound-capture/assets/critical-pattern-template.md +37 -0
  391. package/skills/compound-capture/assets/resolution-template.md +116 -0
  392. package/skills/compound-capture/references/yaml-schema.md +67 -0
  393. package/skills/compound-capture/schema.yaml +181 -0
  394. package/skills/constraint-scaffold/SKILL.md +175 -0
  395. package/skills/constraint-scaffold/references/boundary-readme.template +35 -0
  396. package/skills/constraint-scaffold/references/constraint-gates-workflow.template +69 -0
  397. package/skills/constraint-scaffold/references/depcruise-config.template +230 -0
  398. package/skills/constraint-scaffold/references/fix-constraints-stage-a.template +240 -0
  399. package/skills/constraint-scaffold/references/fix-constraints-stage-b.template +313 -0
  400. package/skills/constraint-scaffold/references/shared-runner.template +135 -0
  401. package/skills/constraint-scaffold/scripts/constraint-scaffold.sh +589 -0
  402. package/skills/constraint-scaffold/test/bite-proof.test.sh +1338 -0
  403. package/skills/constraint-scaffold/test/boundary.test.sh +734 -0
  404. package/skills/constraint-scaffold/test/emit-fix-constraints.test.sh +193 -0
  405. package/skills/constraint-scaffold/test/generator.test.sh +93 -0
  406. package/skills/constraint-scaffold/test/parity.test.sh +285 -0
  407. package/skills/content-writer/SKILL.md +242 -0
  408. package/skills/content-writer/scripts/blog-jargon-scan.sh +42 -0
  409. package/skills/cron-delete/SKILL.md +56 -0
  410. package/skills/cron-list/SKILL.md +54 -0
  411. package/skills/deepen-plan/SKILL.md +937 -0
  412. package/skills/deepen-plan/workflows/deepen-plan.workflow.js +488 -0
  413. package/skills/deploy/SKILL.md +115 -0
  414. package/skills/deploy/references/hetzner-setup.md +67 -0
  415. package/skills/deploy/scripts/deploy.sh +37 -0
  416. package/skills/deploy-docs/SKILL.md +95 -0
  417. package/skills/dhh-rails-style/SKILL.md +203 -0
  418. package/skills/dhh-rails-style/references/architecture.md +717 -0
  419. package/skills/dhh-rails-style/references/controllers.md +323 -0
  420. package/skills/dhh-rails-style/references/frontend.md +556 -0
  421. package/skills/dhh-rails-style/references/gems.md +316 -0
  422. package/skills/dhh-rails-style/references/models.md +388 -0
  423. package/skills/dhh-rails-style/references/testing.md +354 -0
  424. package/skills/discord-content/SKILL.md +126 -0
  425. package/skills/docs-site/SKILL.md +214 -0
  426. package/skills/drain-labeled-backlog/SKILL.md +203 -0
  427. package/skills/drain-labeled-backlog/scripts/group-by-area.sh +208 -0
  428. package/skills/drain-labeled-backlog/workflows/drain-labeled-backlog.workflow.js +433 -0
  429. package/skills/drain-prs/SKILL.md +143 -0
  430. package/skills/drain-prs/scripts/triage-prs.sh +192 -0
  431. package/skills/drain-prs/test/argv-ceiling.test.sh +183 -0
  432. package/skills/dspy-ruby/SKILL.md +634 -0
  433. package/skills/dspy-ruby/assets/config-template.rb +359 -0
  434. package/skills/dspy-ruby/assets/module-template.rb +326 -0
  435. package/skills/dspy-ruby/assets/signature-template.rb +143 -0
  436. package/skills/dspy-ruby/references/core-concepts.md +268 -0
  437. package/skills/dspy-ruby/references/optimization.md +623 -0
  438. package/skills/dspy-ruby/references/providers.md +335 -0
  439. package/skills/eval-harness/README.md +194 -0
  440. package/skills/eval-harness/SKILL.md +157 -0
  441. package/skills/eval-harness/enums/go-routes.json +13 -0
  442. package/skills/eval-harness/enums/incident-threshold.json +5 -0
  443. package/skills/eval-harness/enums/lane.json +5 -0
  444. package/skills/eval-harness/enums/tool-selection.json +20 -0
  445. package/skills/eval-harness/enums/triage-levels.json +5 -0
  446. package/skills/eval-harness/gated-skills.json +34 -0
  447. package/skills/eval-harness/models.generated.json +5 -0
  448. package/skills/eval-harness/promptfooconfig-go-routing.yaml +35 -0
  449. package/skills/eval-harness/promptfooconfig-incident-threshold.yaml +32 -0
  450. package/skills/eval-harness/promptfooconfig-lane-inference.yaml +33 -0
  451. package/skills/eval-harness/promptfooconfig-ticket-triage.yaml +34 -0
  452. package/skills/eval-harness/promptfooconfig-tool-selection.yaml +33 -0
  453. package/skills/eval-harness/prompts/go-baseline.txt +6 -0
  454. package/skills/eval-harness/prompts/go-skill.txt +21 -0
  455. package/skills/eval-harness/prompts/incident-threshold-baseline.txt +6 -0
  456. package/skills/eval-harness/prompts/incident-threshold-skill.txt +12 -0
  457. package/skills/eval-harness/prompts/lane-inference-baseline.txt +6 -0
  458. package/skills/eval-harness/prompts/lane-inference-skill.txt +15 -0
  459. package/skills/eval-harness/prompts/tool-selection-baseline.txt +19 -0
  460. package/skills/eval-harness/prompts/tool-selection-skill.txt +22 -0
  461. package/skills/eval-harness/prompts/triage-baseline.txt +7 -0
  462. package/skills/eval-harness/prompts/triage-skill.txt +10 -0
  463. package/skills/eval-harness/scripts/eval-gate.cjs +318 -0
  464. package/skills/eval-harness/scripts/extract-block.cjs +87 -0
  465. package/skills/eval-harness/scripts/gate-classification.cjs +28 -0
  466. package/skills/eval-harness/scripts/gen-models.sh +41 -0
  467. package/skills/eval-harness/scripts/gen-skill-prompt.cjs +177 -0
  468. package/skills/eval-harness/scripts/measure-classification.cjs +30 -0
  469. package/skills/eval-harness/scripts/parse-label.cjs +93 -0
  470. package/skills/eval-harness/scripts/verdict.cjs +132 -0
  471. package/skills/eval-harness/tasks/go-routing.jsonl +8 -0
  472. package/skills/eval-harness/tasks/incident-threshold.jsonl +7 -0
  473. package/skills/eval-harness/tasks/lane-inference.jsonl +7 -0
  474. package/skills/eval-harness/tasks/ticket-triage.jsonl +6 -0
  475. package/skills/eval-harness/tasks/tool-selection.jsonl +15 -0
  476. package/skills/eval-harness/test/eval-gate.test.sh +132 -0
  477. package/skills/eval-harness/test/extract-block.test.sh +87 -0
  478. package/skills/eval-harness/test/gate-classification.test.sh +77 -0
  479. package/skills/eval-harness/test/gen-models.test.sh +75 -0
  480. package/skills/eval-harness/test/measure-classification.test.sh +74 -0
  481. package/skills/eval-harness/test/parse-label.test.sh +129 -0
  482. package/skills/eval-harness/test/registry-completeness.test.sh +109 -0
  483. package/skills/eval-harness/test/verdict.test.sh +123 -0
  484. package/skills/every-style-editor/SKILL.md +142 -0
  485. package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  486. package/skills/feature-tweet/SKILL.md +199 -0
  487. package/skills/feature-video/SKILL.md +412 -0
  488. package/skills/feature-video/scripts/check_deps.sh +281 -0
  489. package/skills/file-todos/SKILL.md +267 -0
  490. package/skills/file-todos/assets/todo-template.md +166 -0
  491. package/skills/fix-issue/SKILL.md +278 -0
  492. package/skills/fix-issue/references/agent-authored-exclusion.md +120 -0
  493. package/skills/fix-issue/references/exclude-label-jq-snippet.md +97 -0
  494. package/skills/flag-bootstrap/SETUP.md +142 -0
  495. package/skills/flag-create/SKILL.md +145 -0
  496. package/skills/flag-create/scripts/create.sh +273 -0
  497. package/skills/flag-delete/SKILL.md +167 -0
  498. package/skills/flag-delete/scripts/delete.sh +288 -0
  499. package/skills/flag-list/SKILL.md +99 -0
  500. package/skills/flag-list/scripts/list.sh +275 -0
  501. package/skills/flag-set-role/SKILL.md +229 -0
  502. package/skills/flag-set-role/scripts/flip.sh +774 -0
  503. package/skills/frontend-anti-slop/SKILL.md +106 -0
  504. package/skills/frontend-anti-slop/references/anti-patterns.md +199 -0
  505. package/skills/frontend-anti-slop/references/slop-rules.md +65 -0
  506. package/skills/frontend-anti-slop/scripts/tier1-scan.ts +525 -0
  507. package/skills/frontend-design/SKILL.md +77 -0
  508. package/skills/gdpr-gate/NOTICE +136 -0
  509. package/skills/gdpr-gate/SKILL.md +341 -0
  510. package/skills/gdpr-gate/references/fields.md +160 -0
  511. package/skills/gdpr-gate/references/layers/api-layer.md +355 -0
  512. package/skills/gdpr-gate/references/layers/auth-sessions.md +290 -0
  513. package/skills/gdpr-gate/references/layers/data-in-transit.md +331 -0
  514. package/skills/gdpr-gate/references/layers/data-lifecycle.md +341 -0
  515. package/skills/gdpr-gate/references/layers/frontend.md +249 -0
  516. package/skills/gdpr-gate/references/layers/testing-seeding.md +256 -0
  517. package/skills/gdpr-gate/references/leakage-vectors.md +248 -0
  518. package/skills/gdpr-gate/references/legacy/legal-consent-v1-prose.md +48 -0
  519. package/skills/gdpr-gate/references/legal-consent.md +140 -0
  520. package/skills/gdpr-gate/references/non-negotiables.md +60 -0
  521. package/skills/gdpr-gate/scripts/gdpr-gate.sh +271 -0
  522. package/skills/gdpr-gate/scripts/notice-frontmatter.sh +337 -0
  523. package/skills/gdpr-gate/scripts/path-denylist.txt +39 -0
  524. package/skills/gdpr-gate/scripts/repo-scan.sh +158 -0
  525. package/skills/gdpr-gate/scripts/vendor-drift-classify.sh +120 -0
  526. package/skills/gdpr-gate/scripts/vendor-pin-integrity.sh +237 -0
  527. package/skills/gemini-imagegen/SKILL.md +283 -0
  528. package/skills/gemini-imagegen/requirements.txt +5 -0
  529. package/skills/gemini-imagegen/scripts/_error_handling.py +146 -0
  530. package/skills/gemini-imagegen/scripts/compose_images.py +150 -0
  531. package/skills/gemini-imagegen/scripts/edit_image.py +137 -0
  532. package/skills/gemini-imagegen/scripts/gemini_images.py +256 -0
  533. package/skills/gemini-imagegen/scripts/generate_image.py +147 -0
  534. package/skills/gemini-imagegen/scripts/multi_turn_chat.py +223 -0
  535. package/skills/gemini-imagegen/scripts/test_error_handling.py +179 -0
  536. package/skills/git-worktree/SKILL.md +534 -0
  537. package/skills/git-worktree/scripts/git-repo-readiness-diag.sh +98 -0
  538. package/skills/git-worktree/scripts/worktree-manager.sh +4773 -0
  539. package/skills/git-worktree/test/create-from-origin-main.test.sh +116 -0
  540. package/skills/git-worktree/test/lease-protects-active.test.sh +1056 -0
  541. package/skills/git-worktree/test/no-repo-fail-loud.test.sh +88 -0
  542. package/skills/git-worktree/test/orphan-reaper-honest-count.test.sh +379 -0
  543. package/skills/git-worktree/test/reap-archive-persistence.test.sh +725 -0
  544. package/skills/git-worktree/test/stale-lock-sweep.test.sh +176 -0
  545. package/skills/go/SKILL.md +54 -0
  546. package/skills/growth/SKILL.md +164 -0
  547. package/skills/harvest-debt/SKILL.md +78 -0
  548. package/skills/harvest-debt/scripts/harvest-debt.sh +114 -0
  549. package/skills/heal-skill/SKILL.md +173 -0
  550. package/skills/help/SKILL.md +46 -0
  551. package/skills/incident/NOTICE +39 -0
  552. package/skills/incident/SKILL.md +395 -0
  553. package/skills/incident/scripts/dry-run.sh +448 -0
  554. package/skills/incident/scripts/redact-engine.py +412 -0
  555. package/skills/incident/scripts/redact-sentinel.sh +44 -0
  556. package/skills/incident/templates/pir.md +139 -0
  557. package/skills/incident/test/fixtures/dry-run-incident.json +26 -0
  558. package/skills/incident/test/fixtures/dry-run-secret-leak.json +26 -0
  559. package/skills/incident/test/fixtures/legacy-bash-scanner.sh +82 -0
  560. package/skills/incident/test/fixtures/positive-corpus.md +87 -0
  561. package/skills/incident/test/redact-sentinel.test.sh +1420 -0
  562. package/skills/invoice/SKILL.md +206 -0
  563. package/skills/kb-glossary/SKILL.md +71 -0
  564. package/skills/kb-glossary/references/glossary-format.md +111 -0
  565. package/skills/kb-glossary/references/rejected-request-register.md +115 -0
  566. package/skills/kb-search/SKILL.md +276 -0
  567. package/skills/kb-search/scripts/kb-search-cache.sh +123 -0
  568. package/skills/legal-audit/SKILL.md +161 -0
  569. package/skills/legal-generate/NOTICE +242 -0
  570. package/skills/legal-generate/SKILL.md +244 -0
  571. package/skills/legal-generate/references/templates/advisor-agreement/template.md +12 -0
  572. package/skills/legal-generate/references/templates/business-associate-agreement/template.md +112 -0
  573. package/skills/legal-generate/references/templates/cookie-notice/template.md +82 -0
  574. package/skills/legal-generate/references/templates/dpa-global/template.md +439 -0
  575. package/skills/legal-generate/references/templates/dpa-us/template.md +222 -0
  576. package/skills/legal-generate/references/templates/employee-offer-letter/template.md +75 -0
  577. package/skills/legal-generate/references/templates/master-services-agreement/template.md +252 -0
  578. package/skills/legal-generate/references/templates/mutual-nda/template.md +66 -0
  579. package/skills/legal-generate/references/templates/one-way-nda/template.md +38 -0
  580. package/skills/legal-generate/references/templates/privacy-policy-gdpr/template.md +427 -0
  581. package/skills/legal-generate/references/templates/privacy-policy-us/template.md +313 -0
  582. package/skills/legal-generate/references/templates/terms-of-use/template.md +75 -0
  583. package/skills/legal-generate/scripts/strip-vendor-credit.sh +96 -0
  584. package/skills/linear-fetch/SKILL.md +247 -0
  585. package/skills/linear-fetch/scripts/assert-no-linear-telemetry.sh +66 -0
  586. package/skills/linear-fetch/scripts/redact-linear-urls.sh +51 -0
  587. package/skills/linear-fetch/scripts/render-caller-template.sh +36 -0
  588. package/skills/linear-fetch/test/assert-no-linear-telemetry.test.sh +113 -0
  589. package/skills/linear-fetch/test/parity.test.sh +112 -0
  590. package/skills/linear-fetch/test/persist-safe-integration.test.sh +191 -0
  591. package/skills/linear-fetch/test/redact-linear-urls.test.sh +226 -0
  592. package/skills/merge-pr/SKILL.md +670 -0
  593. package/skills/model-launch-review/SKILL.md +255 -0
  594. package/skills/model-launch-review/scripts/audit-models.sh +501 -0
  595. package/skills/one-shot/SKILL.md +316 -0
  596. package/skills/one-shot/references/token-discipline.md +74 -0
  597. package/skills/operator-bootstrap/SKILL.md +412 -0
  598. package/skills/operator-bootstrap/template.sh +439 -0
  599. package/skills/operator-digest/SKILL.md +287 -0
  600. package/skills/operator-digest/assets/operator-digest.workflow.yml +175 -0
  601. package/skills/operator-digest/scripts/digest-scrub.sh +119 -0
  602. package/skills/operator-digest/scripts/provision-operator-digest-repo.sh +147 -0
  603. package/skills/operator-rephrase/SKILL.md +98 -0
  604. package/skills/pencil-setup/SKILL.md +201 -0
  605. package/skills/pencil-setup/scripts/check_deps.sh +556 -0
  606. package/skills/pencil-setup/scripts/copy_adapter.sh +80 -0
  607. package/skills/pencil-setup/scripts/package-lock.json +1172 -0
  608. package/skills/pencil-setup/scripts/package.json +14 -0
  609. package/skills/pencil-setup/scripts/pencil-error-enrichment.mjs +21 -0
  610. package/skills/pencil-setup/scripts/pencil-mcp-adapter.mjs +733 -0
  611. package/skills/pencil-setup/scripts/pencil-response-classify.mjs +38 -0
  612. package/skills/pencil-setup/scripts/pencil-save-gate.mjs +26 -0
  613. package/skills/pencil-setup/scripts/sanitize-filename.mjs +25 -0
  614. package/skills/plan/SKILL.md +1140 -0
  615. package/skills/plan/references/differential-migration-testing.md +185 -0
  616. package/skills/plan/references/plan-community-discovery.md +42 -0
  617. package/skills/plan/references/plan-founder-check.md +137 -0
  618. package/skills/plan/references/plan-functional-overlap.md +25 -0
  619. package/skills/plan/references/plan-host-fanout.md +51 -0
  620. package/skills/plan/references/plan-issue-templates.md +779 -0
  621. package/skills/plan/references/plan-network-outage-checklist.md +131 -0
  622. package/skills/plan/references/plan-scope-check.md +126 -0
  623. package/skills/plan/references/plan-sharp-edges.md +331 -0
  624. package/skills/plan/references/plan-signoff-lifecycle.md +12 -0
  625. package/skills/plan/references/webapp-cwv-observability.md +143 -0
  626. package/skills/plan-review/SKILL.md +91 -0
  627. package/skills/plan-review/lib/named-panel.mjs +58 -0
  628. package/skills/plan-review/workflows/plan-review.workflow.js +477 -0
  629. package/skills/postmerge/SKILL.md +642 -0
  630. package/skills/postmerge/references/deploy-status-debugging.md +141 -0
  631. package/skills/postmerge/references/graceful-degradation.md +20 -0
  632. package/skills/postmerge/references/sentry-error-count-delta.md +137 -0
  633. package/skills/preflight/SKILL.md +1553 -0
  634. package/skills/preflight/references/check-13-founder-check.md +286 -0
  635. package/skills/preflight/scripts/founder-check.py +1640 -0
  636. package/skills/preflight/scripts/parse-form-a.awk +107 -0
  637. package/skills/preflight/scripts/probe-verb-gate.sh +108 -0
  638. package/skills/product-roadmap/SKILL.md +357 -0
  639. package/skills/product-roadmap/scripts/roadmap-reconcile.sh +327 -0
  640. package/skills/provision-cloudflare/SKILL.md +67 -0
  641. package/skills/provision-cloudflare/scripts/provision-cloudflare.sh +271 -0
  642. package/skills/provision-doppler/SKILL.md +58 -0
  643. package/skills/provision-doppler/scripts/provision-doppler.sh +358 -0
  644. package/skills/provision-github/SKILL.md +59 -0
  645. package/skills/provision-github/scripts/provision-github.sh +300 -0
  646. package/skills/provision-hetzner/SKILL.md +76 -0
  647. package/skills/provision-hetzner/scripts/provision-hetzner.sh +262 -0
  648. package/skills/provision-hetzner/test/fixture/knowledge-base/legal/tenant-dpa-register.md +26 -0
  649. package/skills/provision-hetzner/test/fixture/provision-hetzner-dry-run.golden +34 -0
  650. package/skills/provision-hetzner/test/provision-hetzner-characterization.test.sh +227 -0
  651. package/skills/qa/SKILL.md +263 -0
  652. package/skills/qa/references/browser-preflight.md +22 -0
  653. package/skills/questionnaire-generate/SKILL.md +328 -0
  654. package/skills/questionnaire-generate/references/questionnaire.template +60 -0
  655. package/skills/rclone/SKILL.md +162 -0
  656. package/skills/rclone/scripts/check_setup.sh +63 -0
  657. package/skills/release-announce/SKILL.md +65 -0
  658. package/skills/release-docs/SKILL.md +92 -0
  659. package/skills/reproduce-bug/SKILL.md +358 -0
  660. package/skills/resolve-debt/SKILL.md +85 -0
  661. package/skills/resolve-debt/scripts/resolve-debt.py +584 -0
  662. package/skills/resolve-parallel/SKILL.md +45 -0
  663. package/skills/resolve-parallel/workflows/resolve-parallel.workflow.js +415 -0
  664. package/skills/resolve-pr-parallel/SKILL.md +68 -0
  665. package/skills/resolve-pr-parallel/workflows/resolve-pr-parallel.workflow.js +419 -0
  666. package/skills/resolve-todo-parallel/SKILL.md +57 -0
  667. package/skills/resolve-todo-parallel/workflows/resolve-todo-parallel.workflow.js +398 -0
  668. package/skills/review/SKILL.md +1620 -0
  669. package/skills/review/references/anti-slop-scanner-hook.md +40 -0
  670. package/skills/review/references/defect-classes-migrations.md +9 -0
  671. package/skills/review/references/generated-input-oracle-surfaces.md +15 -0
  672. package/skills/review/references/review-e2e-testing.md +116 -0
  673. package/skills/review/references/review-evidence-comment.md +36 -0
  674. package/skills/review/references/review-todo-structure.md +165 -0
  675. package/skills/review/references/risk-tier-and-fix-rounds.md +97 -0
  676. package/skills/review/references/semgrep-custom-rules.yaml +174 -0
  677. package/skills/review/references/ultrathink-phases.md +98 -0
  678. package/skills/review/references/wfs.md +6 -0
  679. package/skills/review/scripts/emit-review-trailer.sh +499 -0
  680. package/skills/review/scripts/ensure-semgrep.sh +99 -0
  681. package/skills/review/scripts/fix-round-seats.sh +197 -0
  682. package/skills/review/test/emit-review-trailer.test.sh +387 -0
  683. package/skills/review/test/ensure-semgrep.test.sh +111 -0
  684. package/skills/review/test/fix-round-seats.test.sh +237 -0
  685. package/skills/review/workflows/README.md +147 -0
  686. package/skills/review/workflows/review.workflow.js +667 -0
  687. package/skills/schedule/SKILL.md +796 -0
  688. package/skills/seo-aeo/SKILL.md +139 -0
  689. package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
  690. package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
  691. package/skills/ship/SKILL.md +3023 -0
  692. package/skills/ship/references/adr-ordinal-collision.md +47 -0
  693. package/skills/ship/references/affected-gate-contract.md +115 -0
  694. package/skills/ship/references/ci-run-diagnosis.md +29 -0
  695. package/skills/ship/references/ci-workflow-authoring.md +68 -0
  696. package/skills/ship/references/cleanup-merged-archival.md +39 -0
  697. package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
  698. package/skills/ship/references/cto-ruling-armed-push.md +5 -0
  699. package/skills/ship/references/decision-challenges-render.md +71 -0
  700. package/skills/ship/references/delegated-act-authoring-form.md +7 -0
  701. package/skills/ship/references/detached-battery-verdict.md +13 -0
  702. package/skills/ship/references/epic-close-sweep.md +62 -0
  703. package/skills/ship/references/feature-tweet-draft.md +42 -0
  704. package/skills/ship/references/followthrough-issue-body-template.md +47 -0
  705. package/skills/ship/references/followthrough-stub-template.sh +92 -0
  706. package/skills/ship/references/merge-queue-dequeue.md +39 -0
  707. package/skills/ship/references/operator-holds.md +179 -0
  708. package/skills/ship/references/pipeline-tally-render.md +43 -0
  709. package/skills/ship/references/pr-overlap.md +153 -0
  710. package/skills/ship/references/queue-mode.md +7 -0
  711. package/skills/ship/references/ready-run-wait.md +36 -0
  712. package/skills/ship/references/red-on-main-quarantine.md +110 -0
  713. package/skills/ship/references/register-update-pr-pattern.md +88 -0
  714. package/skills/ship/references/settle-then-admin-merge.md +130 -0
  715. package/skills/ship/references/supabase-column-probe.md +13 -0
  716. package/skills/ship/scripts/auto-close-scan.sh +76 -0
  717. package/skills/ship/scripts/battery-owed.sh +403 -0
  718. package/skills/ship/scripts/hold-gate-eval.sh +410 -0
  719. package/skills/ship/scripts/net-issue-flow.sh +665 -0
  720. package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
  721. package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
  722. package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
  723. package/skills/skill-creator/SKILL.md +299 -0
  724. package/skills/skill-creator/references/api-security.md +248 -0
  725. package/skills/skill-creator/references/authoring-levers.md +110 -0
  726. package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
  727. package/skills/skill-creator/references/best-practices.md +431 -0
  728. package/skills/skill-creator/references/common-patterns.md +639 -0
  729. package/skills/skill-creator/references/core-principles.md +193 -0
  730. package/skills/skill-creator/references/executable-code.md +188 -0
  731. package/skills/skill-creator/references/iteration-and-testing.md +509 -0
  732. package/skills/skill-creator/references/official-spec.md +193 -0
  733. package/skills/skill-creator/references/recommended-structure.md +180 -0
  734. package/skills/skill-creator/references/skill-structure.md +396 -0
  735. package/skills/skill-creator/references/using-scripts.md +122 -0
  736. package/skills/skill-creator/references/using-templates.md +120 -0
  737. package/skills/skill-creator/references/workflows-and-validation.md +541 -0
  738. package/skills/skill-creator/scripts/init_skill.py +322 -0
  739. package/skills/skill-creator/scripts/package_skill.py +110 -0
  740. package/skills/skill-creator/scripts/quick_validate.py +64 -0
  741. package/skills/skill-creator/templates/router-skill.md +73 -0
  742. package/skills/skill-creator/templates/simple-skill.md +34 -0
  743. package/skills/skill-creator/workflows/add-reference.md +96 -0
  744. package/skills/skill-creator/workflows/add-script.md +104 -0
  745. package/skills/skill-creator/workflows/add-template.md +83 -0
  746. package/skills/skill-creator/workflows/add-workflow.md +128 -0
  747. package/skills/skill-creator/workflows/audit-skill.md +159 -0
  748. package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
  749. package/skills/skill-creator/workflows/create-new-skill.md +207 -0
  750. package/skills/skill-creator/workflows/get-guidance.md +134 -0
  751. package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
  752. package/skills/skill-creator/workflows/verify-skill.md +226 -0
  753. package/skills/skill-security-scan/SKILL.md +145 -0
  754. package/skills/skill-security-scan/references/disclaimer.md +21 -0
  755. package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
  756. package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
  757. package/skills/skill-security-scan/references/override-mechanism.md +171 -0
  758. package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
  759. package/skills/skill-security-scan/references/regex-patterns.md +136 -0
  760. package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
  761. package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
  762. package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
  763. package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
  764. package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
  765. package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
  766. package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
  767. package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
  768. package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
  769. package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
  770. package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
  771. package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
  772. package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
  773. package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
  774. package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
  775. package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
  776. package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
  777. package/skills/skill-security-scan/scripts/lib.sh +197 -0
  778. package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
  779. package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
  780. package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
  781. package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
  782. package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
  783. package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
  784. package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
  785. package/skills/social-distribute/SKILL.md +485 -0
  786. package/skills/spec-templates/SKILL.md +274 -0
  787. package/skills/sync/SKILL.md +49 -0
  788. package/skills/test-browser/SKILL.md +464 -0
  789. package/skills/test-browser/references/feature-map.md +161 -0
  790. package/skills/test-fix-loop/SKILL.md +159 -0
  791. package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
  792. package/skills/triage/SKILL.md +402 -0
  793. package/skills/trigger-cron/SKILL.md +136 -0
  794. package/skills/trigger-cron/scripts/trigger.sh +198 -0
  795. package/skills/user-set-role/SKILL.md +147 -0
  796. package/skills/user-set-role/scripts/set-role.sh +218 -0
  797. package/skills/user-story-writer/SKILL.md +77 -0
  798. package/skills/ux-audit/SKILL.md +251 -0
  799. package/skills/ux-audit/references/finding.schema.json +62 -0
  800. package/skills/ux-audit/references/route-list.yaml +95 -0
  801. package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
  802. package/skills/ux-audit/scripts/bot-signin.ts +135 -0
  803. package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
  804. package/skills/verification-scaffold/SKILL.md +73 -0
  805. package/skills/verification-scaffold/references/gitleaks.toml.template +13 -0
  806. package/skills/verification-scaffold/references/guardrail-audit.md +156 -0
  807. package/skills/verification-scaffold/references/guards/block-stash-hook.sh.template +72 -0
  808. package/skills/verification-scaffold/references/guards/commit-on-main-hook.sh.template +82 -0
  809. package/skills/verification-scaffold/references/guards/orphan-test-check.sh.template +102 -0
  810. package/skills/verification-scaffold/references/guards/precommit-guard.sh.template +115 -0
  811. package/skills/verification-scaffold/references/guards/secret-scan-hook.sh.template +176 -0
  812. package/skills/verification-scaffold/references/guards/verification-gates.yml.template +49 -0
  813. package/skills/verification-scaffold/references/guards/wrapper-boundary.sh.template +47 -0
  814. package/skills/verification-scaffold/references/guards.tsv +21 -0
  815. package/skills/verification-scaffold/references/verification-readme.template +55 -0
  816. package/skills/verification-scaffold/scripts/verification-scaffold.sh +785 -0
  817. package/skills/verification-scaffold/test/bite-proof.test.sh +159 -0
  818. package/skills/verification-scaffold/test/generator.test.sh +319 -0
  819. package/skills/verification-scaffold/test/manifest.test.sh +144 -0
  820. package/skills/work/SKILL.md +1480 -0
  821. package/skills/work/references/end-of-work-resume.md +7 -0
  822. package/skills/work/references/hook-test-main-cwd.md +24 -0
  823. package/skills/work/references/key-principles.md +83 -0
  824. package/skills/work/references/property-testing.md +122 -0
  825. package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
  826. package/skills/work/references/work-agent-teams.md +97 -0
  827. package/skills/work/references/work-lifecycle-parallel.md +147 -0
  828. package/skills/work/references/work-lockfile-bumps.md +97 -0
  829. package/skills/work/references/work-scratch-sandboxes.md +212 -0
  830. package/skills/work/references/work-subagent-fanout.md +61 -0
  831. package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
  832. package/skills/xcode-test/SKILL.md +360 -0
@@ -0,0 +1,589 @@
1
+ #!/usr/bin/env bash
2
+ # constraint-scaffold — deterministic generator for the Layer-1 client->server-secret
3
+ # import-boundary gate (ADR-071, Option D). Emits a dependency-cruiser config, a
4
+ # shared runner, and a CI workflow into the target Next.js app, captures the
5
+ # known-violations baseline, PROVES the emitted gate bites on a detached worktree of
6
+ # HEAD (pass -> fail -> pass), then appends a README block next to the governed path
7
+ # and one pointer line to the repo's agent-instructions file. v1 target =
8
+ # apps/web-platform (Next.js-only).
9
+ # <!-- Inspired by mattpocock/skills/skills/in-progress/setup-ts-deep-modules/SKILL.md (MIT, Copyright (c) 2026 Matt Pocock). -->
10
+ #
11
+ # Modes:
12
+ # (default) detect Next.js -> require app/ components/ server/ -> emit
13
+ # config + runner + workflows (refuse if any already exists;
14
+ # NO --force) -> capture baseline -> bite-proof -> README block
15
+ # + instructions pointer (append-once, written LAST).
16
+ # --refresh-baseline clean-tree guard, then re-capture the baseline against the
17
+ # origin/main merge-base (so a same-PR violation is NOT
18
+ # grandfathered), then bite-proof. Never writes README/pointer.
19
+ # Agent-only; never shown to the founder.
20
+ #
21
+ # Base ref: origin/main when it exists, else the remote's default branch (origin/HEAD, e.g. a
22
+ # founder repo on master). Neither present -> 69 BEFORE anything is written.
23
+ #
24
+ # Exit matrix (every non-zero is a hard, fail-closed stop; every message is printed on STDOUT
25
+ # first — agent runtimes surface stdout and swallow stderr — then on stderr):
26
+ # 0 success
27
+ # 2 CONSTRAINT_SCAFFOLD_REPO_ROOT override is empty, "/", or relative (refused before any git call)
28
+ # 64 usage error (unknown argument)
29
+ # 65 precondition failed (target is not a Next.js app, or lacks app/ components/ server/)
30
+ # 66 refuse-if-exists (a non-baseline artifact already present; no --force)
31
+ # 67 dirty working tree (baseline capture requires a clean tree)
32
+ # 68 dependency-cruiser binary missing, or baseline capture failed
33
+ # 69 git/base-ref/worktree/temp-dir error, TMPDIR resolves inside the repository, or another
34
+ # scaffold run holds the run lock (<git-common-dir>/constraint-scaffold.lock, owner pid inside)
35
+ # 70 --refresh-baseline before generation (no .dependency-cruiser.cjs yet — run default mode first)
36
+ # 71 bite-proof: gate did not pass on the clean HEAD tree before the probe (config/toolchain)
37
+ # 72 bite-proof: gate did NOT reject the injected client->server-secret imports on their edges
38
+ # 73 bite-proof: gate did not return to green after the probes were removed
39
+ # 74 bite-proof: real client->server-secret violation(s) on HEAD newer than the baseline
40
+ #
41
+ # In default mode the self-cleanup is armed BEFORE the first artifact is written and disarmed
42
+ # only after the bite has passed: every failure in between (67..74, a failed `mktemp`, a
43
+ # `set -e` abort) REMOVES every artifact this run emitted, so a failed first install is
44
+ # re-runnable and never leaves a half-installed gate. The README and the pointer are written
45
+ # after the disarm. An INT/TERM mid-run does the same and exits 143; a runner interrupted by a
46
+ # terminal Ctrl-C (rc 130) is treated as an interrupt, never as a verdict. Only a SIGKILL can
47
+ # leave residue (the six files plus a stale `.git/worktrees` registration) — the 66 message
48
+ # names the recovery.
49
+ #
50
+ # Portable: POSIX tools only (no `realpath -m`, no `sed -i`) — the generator runs on founder hosts
51
+ # including stock macOS (bash 3.2, BSD sed). Tool errors (git worktree add, dependency-cruiser)
52
+ # are carried into the 68/69 message, never discarded.
53
+ #
54
+ # No test seams: this script reads no test-only environment variable. The self-tests
55
+ # drive every failure arm through a fixture-owned stub `depcruise` reached via the target's
56
+ # node_modules symlink (bite-proof.test.sh). CONSTRAINT_SCAFFOLD_REPO_ROOT (below) only
57
+ # re-roots the generator at a synthesized repo; it changes no branch of the logic.
58
+ set -euo pipefail
59
+
60
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
61
+ REF_DIR="$(cd "$SCRIPT_DIR/../references" && pwd)"
62
+ # REPO_ROOT defaults to the skill's own repo. CONSTRAINT_SCAFFOLD_REPO_ROOT points
63
+ # the generator at a synthesized fixture repo (apps/web-platform-shaped) for the
64
+ # hermetic generator self-tests; in normal use it is unset. Templates (REF_DIR)
65
+ # always come from the real skill.
66
+ REPO_ROOT="${CONSTRAINT_SCAFFOLD_REPO_ROOT:-$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)}"
67
+ # CONSTRAINT_SCAFFOLD_REPO_ROOT is caller-supplied. The `:-` default is absolute
68
+ # (`rev-parse --show-toplevel`), but an override is not, and every `git -C "$REPO_ROOT"` below —
69
+ # including a `worktree add`/`worktree remove` pair — would then resolve against CWD instead.
70
+ case "$REPO_ROOT" in
71
+ "") printf 'FATAL: REPO_ROOT is empty; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
72
+ /|//|/.) printf 'FATAL: REPO_ROOT resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
73
+ /*) : ;;
74
+ *) printf 'FATAL: REPO_ROOT %s is RELATIVE; refusing\n' "$REPO_ROOT" >&2; exit 2 ;;
75
+ esac
76
+ # physdir <dir>: the physical path of an EXISTING directory (`pwd -P`), POSIX — the generator runs
77
+ # on founder hosts where `realpath -m` does not exist (BSD/macOS). Prints nothing on a missing dir.
78
+ physdir() { ( cd -- "$1" 2>/dev/null && pwd -P ); }
79
+ # physpath <path>: physical path of a file that may not exist yet, via its (existing) parent.
80
+ physpath() { local d; d="$(physdir "$(dirname -- "$1")")" || return 1; [[ -n "$d" ]] && printf '%s/%s' "$d" "$(basename -- "$1")"; }
81
+ # Canonical form once (a trailing slash would defeat every `${f#"$REPO_ROOT"/}` display and the
82
+ # TMPDIR containment case below), re-guarded: the value now comes from a command substitution.
83
+ REPO_ROOT="$(physdir "$REPO_ROOT")"
84
+ case "$REPO_ROOT" in
85
+ /|//|/.) printf 'FATAL: REPO_ROOT canonicalises to the filesystem root; refusing\n' >&2; exit 2 ;;
86
+ /*) : ;;
87
+ *) printf 'FATAL: REPO_ROOT %s did not canonicalise to an absolute path; refusing\n' "$REPO_ROOT" >&2; exit 2 ;;
88
+ esac
89
+
90
+ # v1: the one supported target.
91
+ TARGET_REL="apps/web-platform"
92
+ TARGET="$REPO_ROOT/$TARGET_REL"
93
+
94
+ CFG="$TARGET/.dependency-cruiser.cjs"
95
+ RUNNER="$TARGET/scripts/constraint-gates.sh"
96
+ WORKFLOW="$TARGET/.github/workflows/constraint-gates.yml"
97
+ # Two-stage recovery dispatcher (ADR-074, #5814): an UNTRUSTED pull_request producer
98
+ # (Stage A) + a PRIVILEGED workflow_run consumer (Stage B). Replaces the single held
99
+ # issue_comment dispatcher — the privileged trigger no longer co-locates with untrusted
100
+ # PR-code execution.
101
+ FIXWORKFLOW_A="$TARGET/.github/workflows/fix-constraints-stage-a.yml"
102
+ FIXWORKFLOW_B="$TARGET/.github/workflows/fix-constraints-stage-b.yml"
103
+ BASELINE="$TARGET/.dependency-cruiser-known-violations.json"
104
+ DEPCRUISE="$TARGET/node_modules/.bin/depcruise"
105
+ README="$TARGET/server/README.md"
106
+
107
+ # The two rules the emitted config defines (bite-proof.test.sh pins these literals equal to
108
+ # the `name:` fields of depcruise-config.template) and the four probe paths the bite injects —
109
+ # top-level scalars, no array, no `$( )`.
110
+ RULE_DIRECT="no-client-to-server-secret"
111
+ RULE_TRANSITIVE="no-client-to-server-secret-transitive"
112
+ PROBE_DIRECT="components/__constraint_scaffold_bite_probe__/direct.tsx"
113
+ PROBE_HOP="components/__constraint_scaffold_bite_probe__/hop.ts"
114
+ PROBE_VIA_HOP="components/__constraint_scaffold_bite_probe__/via-hop.tsx"
115
+ PROBE_SERVER="server/__constraint_scaffold_bite_probe__.ts"
116
+
117
+ log() { printf 'constraint-scaffold: %s\n' "$*" >&2; }
118
+ # Agent runtimes surface stdout and swallow stderr, so anything the founder or the agent must
119
+ # act on is printed on STDOUT (warn/say) and only then logged. `die` is the ONE failure path:
120
+ # every non-zero exit prints `FAILED (<code>): <msg>` on stdout, then the message on stderr.
121
+ say() { printf 'constraint-scaffold: %s\n' "$*"; }
122
+ warn() { printf 'constraint-scaffold: WARNING: %s\n' "$*"; }
123
+ die() { say "FAILED (${2:-1}): $1"; log "$1"; exit "${2:-1}"; }
124
+ # fail_stdout <code> <msg>: kept as the named form the tests and the header cite; same path.
125
+ fail_stdout() { die "$2" "$1"; }
126
+
127
+ MODE="default"
128
+ case "${1:-}" in
129
+ "") MODE="default" ;;
130
+ --refresh-baseline) MODE="refresh" ;;
131
+ *) die "unknown argument: $1 (expected none or --refresh-baseline)" 64 ;;
132
+ esac
133
+
134
+ # --- Precondition: target is a Next.js app -----------------------------------
135
+ detect_nextjs() {
136
+ # next.config.* present AND an anchored "next": dependency key (the anchor
137
+ # avoids matching "next-themes" etc.).
138
+ compgen -G "$TARGET/next.config.*" >/dev/null 2>&1 || return 1
139
+ grep -qE '"next"[[:space:]]*:' "$TARGET/package.json" 2>/dev/null || return 1
140
+ }
141
+ detect_nextjs || die "target $TARGET_REL is not a Next.js app (need next.config.* + anchored \"next\": in package.json)" 65
142
+
143
+ # --- Default-mode self-cleanup ------------------------------------------------
144
+ # Removes every artifact a default-mode run emits and prints the list it removed. The script
145
+ # refuses to start when any of these exists, so at cleanup time each one present was written by
146
+ # THIS run. Also `rmdir`s the two `mkdir -p` directories when empty. The list below is pinned by
147
+ # bite-proof.test.sh against the refuse-if-exists loop: a new artifact cannot be left behind on a
148
+ # failed bite without also being left out of the refuse loop, and vice-versa.
149
+ remove_emitted_artifacts() {
150
+ local removed="" f
151
+ for f in "$CFG" "$RUNNER" "$WORKFLOW" "$FIXWORKFLOW_A" "$FIXWORKFLOW_B" "$BASELINE"; do
152
+ [[ -e "$f" ]] || continue
153
+ rm -f -- "$f"
154
+ removed="$removed ${f#"$REPO_ROOT"/}"
155
+ done
156
+ rmdir "$TARGET/scripts" "$TARGET/.github/workflows" "$TARGET/.github" >/dev/null 2>&1 || true
157
+ printf '%s' "${removed# }"
158
+ }
159
+
160
+ # --- Detached-worktree helper (the ONE trap owner, ADR-129) --------------------
161
+ # with_detached_worktree <ref> <fn>: creates a mktemp dir, refuses one that resolves inside the
162
+ # repository (the worktree and its logs must never land in the founder's tree as untracked
163
+ # files), installs the EXIT and INT/TERM traps BEFORE `worktree add --detach`, calls <fn> "$WT",
164
+ # removes the worktree, clears the traps. The signal arm clears EXIT inside itself so cleanup
165
+ # runs once and exits 143 (the precedent is scripts/rotate-sentry-actions-ro-token.sh; 143 for
166
+ # both signals because the distinction buys nothing here). Both the baseline capture and the
167
+ # bite-proof are callers, so there is exactly one trap owner and no ordering hazard.
168
+ WT=""
169
+ # _wt_cleanup [interrupted]: the ONE trap handler. Removes the worktree if one is open and, in
170
+ # default mode, every artifact this run emitted. The word "interrupted" is printed only when a
171
+ # signal arrived; a failed step says "run aborted".
172
+ _wt_cleanup() {
173
+ local why="${1:-run aborted}"
174
+ release_run_lock
175
+ if [[ -n "${WT:-}" ]]; then
176
+ git -C "$REPO_ROOT" worktree remove --force "$WT" >/dev/null 2>&1 || true
177
+ rm -rf -- "$WT"
178
+ fi
179
+ # Default mode: a TERM (or a die anywhere after the first write) must not leave the repo at 66.
180
+ if [[ "$MODE" == "default" ]]; then
181
+ local removed
182
+ removed="$(remove_emitted_artifacts)"
183
+ [[ -n "$removed" ]] && say "$why; removed: $removed"
184
+ elif [[ "$why" == "interrupted" ]]; then
185
+ say "interrupted (refresh mode): nothing removed; the committed baseline may already have been rewritten — review it with \`git diff\` before deciding"
186
+ fi
187
+ return 0
188
+ }
189
+ # Run lock: two scaffold runs in one repo (a default run and a --refresh-baseline, or two
190
+ # sessions) would each `mv` into the same baseline and one run's cleanup would delete the other's
191
+ # staged inputs mid-bite. One `mkdir` lock in the git common dir, holding the owner pid; a stale
192
+ # lock (owner gone) is taken over, a live one is a 69 with the pid named. Released by the handler.
193
+ RUN_LOCK=""
194
+ take_run_lock() {
195
+ local common
196
+ common="$(git -C "$REPO_ROOT" rev-parse --git-common-dir 2>/dev/null)" || common=".git"
197
+ [[ "$common" == /* ]] || common="$REPO_ROOT/$common"
198
+ RUN_LOCK="$common/constraint-scaffold.lock"
199
+ if ! mkdir "$RUN_LOCK" 2>/dev/null; then
200
+ local owner
201
+ owner="$(cat "$RUN_LOCK/pid" 2>/dev/null || true)"
202
+ if [[ -n "$owner" ]] && kill -0 "$owner" 2>/dev/null; then
203
+ RUN_LOCK=""
204
+ fail_stdout 69 "another constraint-scaffold run (pid $owner) is in progress in this repository; wait for it"
205
+ fi
206
+ rm -rf -- "$RUN_LOCK"
207
+ mkdir "$RUN_LOCK" 2>/dev/null || { RUN_LOCK=""; fail_stdout 69 "cannot take the run lock at $RUN_LOCK"; }
208
+ fi
209
+ printf '%s\n' "$$" > "$RUN_LOCK/pid"
210
+ }
211
+ release_run_lock() {
212
+ [[ -n "${RUN_LOCK:-}" && -d "$RUN_LOCK" ]] && rm -rf -- "$RUN_LOCK"
213
+ RUN_LOCK=""
214
+ return 0
215
+ }
216
+ # TMPDIR containment, checked before the first write (a `mktemp -d` under a TMPDIR inside the
217
+ # repo would land the bite worktree — and its logs — in the founder's tree as untracked files).
218
+ check_tmpdir_outside_repo() {
219
+ local t
220
+ t="$(physdir "${TMPDIR:-/tmp}")" || t=""
221
+ # A TMPDIR that does not exist cannot be inside the repo; mktemp reports it (69) at first use.
222
+ [[ -n "$t" ]] || return 0
223
+ case "$t" in
224
+ "$REPO_ROOT"|"$REPO_ROOT"/*)
225
+ fail_stdout 69 "TMPDIR ($t) resolves inside the repository; refusing to create the bite worktree there" ;;
226
+ esac
227
+ }
228
+ with_detached_worktree() {
229
+ local ref="$1" fn="$2"
230
+ trap '_wt_cleanup' EXIT
231
+ trap '_wt_cleanup interrupted; trap - EXIT; exit 143' INT TERM
232
+ WT="$(mktemp -d)" || fail_stdout 69 "cannot create a temp dir under TMPDIR=${TMPDIR:-/tmp}"
233
+ case "$(physdir "$WT")" in
234
+ "$REPO_ROOT"/*)
235
+ fail_stdout 69 "TMPDIR resolves inside the repository; refusing to create the bite worktree there" ;;
236
+ esac
237
+ # Keep git's own reason (a failing post-checkout hook, LFS, a corrupt object): a 69 whose
238
+ # message ends in "failed" with the cause discarded is a question the founder cannot answer.
239
+ local git_err
240
+ git_err="$(git -C "$REPO_ROOT" worktree add --detach "$WT" "$ref" 2>&1 >/dev/null)" \
241
+ || fail_stdout 69 "git worktree add at ${ref:0:12} failed: $(printf '%s' "$git_err" | tail -n 3 | tr '\n' ' ')"
242
+ "$fn" "$WT"
243
+ git -C "$REPO_ROOT" worktree remove --force "$WT" >/dev/null 2>&1 || true
244
+ rm -rf -- "$WT"
245
+ WT=""
246
+ # Leave the handler armed while the default-mode tail owns it (CLEANUP_ARMED=1).
247
+ [[ "${CLEANUP_ARMED:-0}" == 1 ]] || trap - EXIT INT TERM
248
+ }
249
+
250
+ # --- Baseline capture (shared) -----------------------------------------------
251
+ # Captures the value-violations of the tree rooted at $1 into $BASELINE. Scans
252
+ # only the client dirs (app/components) that actually exist plus server/, so a
253
+ # single-client-dir app does not error on a missing dir.
254
+ capture_baseline() {
255
+ local app_root="$1"
256
+ [[ -x "$DEPCRUISE" ]] || fail_stdout 68 "dependency-cruiser not found at ${DEPCRUISE#"$REPO_ROOT"/} — run 'npm ci --ignore-scripts' in $TARGET_REL first"
257
+ local scan_dirs=()
258
+ local d
259
+ for d in app components server; do
260
+ [[ -d "$app_root/$d" ]] && scan_dirs+=("$d")
261
+ done
262
+ [[ "${#scan_dirs[@]}" -gt 0 ]] || fail_stdout 68 "no app/components/server dirs under $app_root — cannot capture baseline"
263
+ local tmp dc_err
264
+ tmp="$(mktemp)"
265
+ if ! dc_err="$( ( cd "$app_root" && "$DEPCRUISE" --config .dependency-cruiser.cjs --output-type baseline "${scan_dirs[@]}" ) 2>&1 > "$tmp" )"; then
266
+ rm -f "$tmp"
267
+ fail_stdout 68 "baseline capture failed — dependency-cruiser said: $(printf '%s' "$dc_err" | tail -n 5 | tr '\n' ' ') (config error, or the hoisted node_modules symlink did not resolve?)"
268
+ fi
269
+ mv "$tmp" "$BASELINE"
270
+ log "captured baseline: $(grep -c '"rule"' "$BASELINE" 2>/dev/null || true) known violation(s) -> ${BASELINE#"$REPO_ROOT"/}"
271
+ }
272
+
273
+ _capture_baseline_in_worktree() {
274
+ local wt="$1"
275
+ local wt_target="$wt/$TARGET_REL"
276
+ [[ -d "$wt_target/app" || -d "$wt_target/components" ]] \
277
+ || fail_stdout 69 "base tree ($BASE_REF) has no $TARGET_REL/app|components — cannot capture baseline"
278
+ # The merge-base may predate the gate: ensure the current config is present, and
279
+ # reuse the installed node_modules (depcruise binary + resolver) via symlink.
280
+ cp "$CFG" "$wt_target/.dependency-cruiser.cjs"
281
+ [[ -e "$wt_target/node_modules" ]] || ln -s "$TARGET/node_modules" "$wt_target/node_modules"
282
+ capture_baseline "$wt_target"
283
+ }
284
+
285
+ # resolve_base_ref: sets BASE_REF (origin/main, else the remote's default branch via
286
+ # origin/HEAD) and MB (its merge-base with HEAD). Runs BEFORE the first write in both modes, so
287
+ # a founder repo without origin/main fails 69 with nothing to clean up. Read-only.
288
+ resolve_base_ref() {
289
+ if git -C "$REPO_ROOT" rev-parse -q --verify origin/main >/dev/null 2>&1; then
290
+ BASE_REF="origin/main"
291
+ elif BASE_REF="$(git -C "$REPO_ROOT" symbolic-ref -q --short refs/remotes/origin/HEAD 2>/dev/null)" && [[ -n "$BASE_REF" ]]; then
292
+ :
293
+ else
294
+ fail_stdout 69 "no origin/main and no origin/HEAD — fetch the default branch first (git fetch origin main, or git remote set-head origin -a)"
295
+ fi
296
+ if ! MB="$(git -C "$REPO_ROOT" merge-base "$BASE_REF" HEAD 2>/dev/null)"; then
297
+ local shallow=""
298
+ [[ "$(git -C "$REPO_ROOT" rev-parse --is-shallow-repository 2>/dev/null)" == "true" ]] \
299
+ && shallow=" — this is a SHALLOW clone: run \`git fetch --unshallow\` first"
300
+ fail_stdout 69 "could not compute merge-base of $BASE_REF and HEAD (unrelated histories, or $BASE_REF not fetched?)$shallow"
301
+ fi
302
+ }
303
+
304
+ # Capture the baseline against the base-ref merge-base in a detached worktree,
305
+ # so a violation introduced in the SAME PR (branch-added) is NOT grandfathered —
306
+ # only violations pre-existing on the base land in the baseline. Used by BOTH modes:
307
+ # first adoption (default) must not grandfather a same-PR leak any more than a
308
+ # refresh does. Requires a clean tree (committed state == reviewable baseline).
309
+ # require_clean_tree <when>: 67 on a dirty tree (committed state == reviewable baseline).
310
+ require_clean_tree() {
311
+ if ! { git -C "$REPO_ROOT" diff --quiet && git -C "$REPO_ROOT" diff --cached --quiet; }; then
312
+ die "working tree is dirty — commit or discard changes $1" 67
313
+ fi
314
+ }
315
+
316
+ capture_baseline_mergebase() {
317
+ require_clean_tree "before capturing the baseline"
318
+ log "capturing baseline against $BASE_REF merge-base ${MB:0:12} (same-PR violations excluded)"
319
+ with_detached_worktree "$MB" _capture_baseline_in_worktree
320
+ }
321
+
322
+ # --- Bite-proof ------------------------------------------------------------------
323
+ # verdict_fail <code> <msg> [<log-file>] [<extra stdout lines>]: prints the verdict on STDOUT,
324
+ # then the last 40 lines of the captured runner log, then (default mode) removes every artifact
325
+ # this run emitted and says so; then dies with <code>. Refresh mode removes nothing (the
326
+ # artifacts are committed) and says the baseline was rewritten.
327
+ verdict_fail() {
328
+ local code="$1" msg="$2" logf="${3:-}" extra="${4:-}"
329
+ say "bite-proof FAILED ($code): $msg"
330
+ if [[ -n "$extra" ]]; then printf '%s\n' "$extra"; fi
331
+ if [[ -n "$logf" && -f "$logf" ]]; then
332
+ printf -- '--- last 40 lines of %s ---\n' "$(basename "$logf")"
333
+ tail -n 40 "$logf"
334
+ printf -- '--- end of log ---\n'
335
+ fi
336
+ if [[ "$MODE" == "default" ]]; then
337
+ local removed
338
+ removed="$(remove_emitted_artifacts)"
339
+ say "removed the artifacts this run emitted (${removed:-none}); the repo is as it was (a SIGKILL may leave a stale registration: \`git worktree prune\`); re-run after fixing the cause"
340
+ else
341
+ say "refresh mode: the baseline was rewritten by this run — review it with \`git diff\` before deciding; no artifact was removed"
342
+ fi
343
+ # The verdict line above IS the stdout copy; log to stderr and exit (not `die`, which would
344
+ # print a second FAILED line). The EXIT trap removes the worktree.
345
+ log "$msg"
346
+ exit "$code"
347
+ }
348
+
349
+ # Run the emitted runner against the worktree copy, capturing stdout+stderr to a file (so a
350
+ # failure can show its evidence before the worktree is removed). Sets RC; never aborts under
351
+ # `set -e` (a bare non-zero runner call would end the scaffold before the arm dispatch).
352
+ _run_gate() {
353
+ local wt_target="$1" logf="$2"
354
+ RC=0
355
+ CONSTRAINT_GATES_DIR="$wt_target" bash "$wt_target/scripts/constraint-gates.sh" >"$logf" 2>&1 || RC=$?
356
+ # A terminal Ctrl-C reaches the node child first: it exits 130 and bash never sees the
357
+ # signal, so without this arm the interrupted run would be dispatched as a 71/72/73 verdict.
358
+ if [[ "$RC" -eq 130 ]]; then
359
+ _wt_cleanup interrupted; trap - EXIT; exit 130
360
+ fi
361
+ # Belt and braces with the runner's NO_COLOR=1: a FORCE_COLOR environment decorates
362
+ # depcruise's `error <rule>:` lines and both anchors below would match nothing.
363
+ sed $'s/\e\\[[0-9;]*m//g' "$logf" > "$logf.plain" && mv -f "$logf.plain" "$logf"
364
+ }
365
+
366
+ _depcruise_version() {
367
+ local wt_target="$1"
368
+ node -p 'require(process.argv[1] + "/node_modules/dependency-cruiser/package.json").version' "$wt_target" 2>/dev/null \
369
+ || printf 'unknown'
370
+ }
371
+
372
+ _prove_bite_in_worktree() {
373
+ local wt="$1"
374
+ local wt_target="$wt/$TARGET_REL"
375
+ # 1. Stage. Copy the three artifacts that may be uncommitted into the HEAD worktree. Ordering
376
+ # dependency: the clean-tree guard in capture_baseline_mergebase ran first, so for tracked
377
+ # files the working tree == HEAD and these copies are no-ops by content; the untracked case
378
+ # (first install) is exactly what the copy exists for. node_modules is reused via symlink,
379
+ # exactly as the baseline capture does.
380
+ mkdir -p "$wt_target/scripts"
381
+ cp "$CFG" "$wt_target/.dependency-cruiser.cjs"
382
+ cp "$RUNNER" "$wt_target/scripts/constraint-gates.sh"
383
+ chmod +x "$wt_target/scripts/constraint-gates.sh"
384
+ cp "$BASELINE" "$wt_target/.dependency-cruiser-known-violations.json"
385
+ [[ -e "$wt_target/node_modules" ]] || ln -s "$TARGET/node_modules" "$wt_target/node_modules"
386
+ local ver
387
+ ver="$(_depcruise_version "$wt_target" | tr -cd 'A-Za-z0-9.+-' | cut -c1-40)"
388
+
389
+ # 2. Pass on the clean tree.
390
+ _run_gate "$wt_target" "$wt/bite-1.log"
391
+ if [[ "$RC" -ne 0 ]]; then
392
+ local violations n
393
+ violations="$(grep -E '^[[:space:]]*error [^:]+: ' "$wt/bite-1.log" || true)"
394
+ if [[ -n "$violations" ]]; then
395
+ n="$(printf '%s\n' "$violations" | grep -c . || true)"
396
+ verdict_fail 74 "$n real client->server-secret violation(s) on HEAD newer than the merge-base baseline — the gate is live; fix the listed imports, then re-run" "$wt/bite-1.log" "$violations"
397
+ fi
398
+ verdict_fail 71 "gate did not pass on the clean tree before the probe (rc=$RC) — config or toolchain error; see the log tail" "$wt/bite-1.log"
399
+ fi
400
+
401
+ # 3. Inject — each rule on the edge it exists for. A symlinked server/ or components/ would
402
+ # route the probes OUTSIDE the worktree (a checked-out link resolves the same as in the
403
+ # founder's tree): refuse rather than write through it.
404
+ local d
405
+ for d in server components; do
406
+ [[ -L "$wt_target/$d" ]] && verdict_fail 71 "$TARGET_REL/$d is a symlink; refusing to write the bite probes through it"
407
+ done
408
+ # Each rule on the edge it exists for. direct.tsx is a "use client" module
409
+ # value-importing the probe server module (direct rule); hop.ts is a NON-client helper that
410
+ # value-imports it; via-hop.tsx is a "use client" module value-importing ./hop (transitive
411
+ # rule). The server module exports one string that is visibly not a secret.
412
+ mkdir -p "$wt_target/$(dirname "$PROBE_DIRECT")"
413
+ printf 'export const BITE_PROBE_MARKER = "constraint-scaffold bite probe (not a secret)";\n' > "$wt_target/$PROBE_SERVER"
414
+ printf '"use client";\nimport { BITE_PROBE_MARKER } from "@/server/__constraint_scaffold_bite_probe__";\nexport const Direct = () => BITE_PROBE_MARKER;\n' > "$wt_target/$PROBE_DIRECT"
415
+ printf 'import { BITE_PROBE_MARKER } from "@/server/__constraint_scaffold_bite_probe__";\nexport const hop = () => BITE_PROBE_MARKER;\n' > "$wt_target/$PROBE_HOP"
416
+ printf '"use client";\nimport { hop } from "./hop";\nexport const ViaHop = () => hop();\n' > "$wt_target/$PROBE_VIA_HOP"
417
+
418
+ # 4. Fail, naming both rules on their own edges. Anchored on depcruise's `error <rule>: `
419
+ # call-form on the captured stream, never a bare rule name (the runner's zero-reachability
420
+ # prose carries the bare transitive token, and a `warn` line must not satisfy it).
421
+ _run_gate "$wt_target" "$wt/bite-2.log"
422
+ local named=""
423
+ if grep -qE "^[[:space:]]*error $RULE_DIRECT: .*direct\.tsx" "$wt/bite-2.log"; then
424
+ named="$named $RULE_DIRECT@direct"
425
+ fi
426
+ if grep -qE "^[[:space:]]*error $RULE_TRANSITIVE: .*via-hop\.tsx" "$wt/bite-2.log"; then
427
+ named="$named $RULE_TRANSITIVE@via-hop"
428
+ fi
429
+ if [[ "$RC" -eq 0 || "$named" != " $RULE_DIRECT@direct $RULE_TRANSITIVE@via-hop" ]]; then
430
+ verdict_fail 72 "the gate did NOT reject the injected client->server-secret import (rc=$RC; depcruise=$ver; rules named on their edges:${named:- none}) — a gate that cannot fail is not a gate" "$wt/bite-2.log"
431
+ fi
432
+
433
+ # 5. Revert.
434
+ rm -f -- "$wt_target/$PROBE_DIRECT" "$wt_target/$PROBE_HOP" "$wt_target/$PROBE_VIA_HOP" "$wt_target/$PROBE_SERVER"
435
+ rmdir "$wt_target/$(dirname "$PROBE_DIRECT")" >/dev/null 2>&1 || true
436
+
437
+ # 6. Pass again.
438
+ _run_gate "$wt_target" "$wt/bite-3.log"
439
+ if [[ "$RC" -ne 0 ]]; then
440
+ verdict_fail 73 "gate did not return to green after the probes were removed (rc=$RC) — non-deterministic gate" "$wt/bite-3.log"
441
+ fi
442
+
443
+ # 7. One verdict line on STDOUT (ASCII arrows so an AC can grep it).
444
+ printf 'constraint-scaffold: bite-proof pass -> fail(%s@direct, %s@via-hop) -> pass depcruise=%s\n' "$RULE_DIRECT" "$RULE_TRANSITIVE" "$ver"
445
+ }
446
+
447
+ # prove_bite: called at the tail of BOTH modes. Runs the emitted gate on a detached worktree of
448
+ # HEAD through the shared helper; the helper removes the worktree afterwards.
449
+ prove_bite() {
450
+ with_detached_worktree HEAD _prove_bite_in_worktree
451
+ }
452
+
453
+ # --- README block + agent-instructions pointer (append-once, written LAST) ---------
454
+ # append_once <file> <marker> <content>: refuses a symlinked target first (a
455
+ # `CLAUDE.md -> ~/.claude/CLAUDE.md` link is a common founder shape and `>>` would write into
456
+ # their GLOBAL instructions — CWE-59); idempotent on <marker>; guards the trailing newline of the
457
+ # existing file; then appends. Returns non-zero on refusal or a failed write so the callers can
458
+ # warn rather than die (after a successful bite, prose is not the gate).
459
+ append_once() {
460
+ local f="$1" marker="$2" content="$3"
461
+ [[ -L "$f" ]] && { warn "refusing to append through a symlink: ${f#"$REPO_ROOT"/} -> $(readlink "$f")"; return 1; }
462
+ # A symlinked PARENT (server/ -> outside) passes `-L` on the file: require containment.
463
+ local phys
464
+ phys="$(physpath "$f")" || phys=""
465
+ case "$phys" in
466
+ "$REPO_ROOT"/*) ;;
467
+ *) warn "refusing to append outside the repository: ${f#"$REPO_ROOT"/} resolves to ${phys:-<unresolvable>}"; return 1 ;;
468
+ esac
469
+ grep -qF -- "$marker" "$f" 2>/dev/null && return 0
470
+ [[ -s "$f" && -n "$(tail -c 1 "$f")" ]] && printf '\n' >> "$f"
471
+ printf '%s\n' "$content" >> "$f" || return 1
472
+ return 0
473
+ }
474
+
475
+ emit_readme() {
476
+ local content
477
+ content="$(sed -e '1{/^<!-- Inspired by /d;}' -e "s|__TARGET_DIR__|$TARGET_REL|g" "$REF_DIR/boundary-readme.template" 2>/dev/null || true)"
478
+ if [[ -n "$content" ]] && append_once "$README" "<!-- constraint-scaffold:readme:start -->" "$content"; then
479
+ log "README block present in ${README#"$REPO_ROOT"/}"
480
+ else
481
+ warn "could not append the boundary README block to ${README#"$REPO_ROOT"/} — the gate is installed and proven; the missing doc is references/boundary-readme.template of soleur:constraint-scaffold (add it by hand)"
482
+ fi
483
+ }
484
+
485
+ emit_pointer() {
486
+ # Pointer file: repo-root CLAUDE.md if present, else AGENTS.md (created if absent). Plain,
487
+ # informational prose with a repo-relative path — never the `@path` import form, which would
488
+ # load the README into every session and promote an unpinned markdown file to instructions.
489
+ local f
490
+ if [[ -e "$REPO_ROOT/CLAUDE.md" || -L "$REPO_ROOT/CLAUDE.md" ]]; then
491
+ f="$REPO_ROOT/CLAUDE.md"
492
+ else
493
+ f="$REPO_ROOT/AGENTS.md"
494
+ fi
495
+ local line="The client/server import boundary and its CI gate are documented in $TARGET_REL/server/README.md (generated by soleur:constraint-scaffold). <!-- constraint-scaffold:pointer -->"
496
+ if append_once "$f" "<!-- constraint-scaffold:pointer -->" "$line"; then
497
+ log "instructions pointer present in ${f#"$REPO_ROOT"/}"
498
+ else
499
+ warn "could not append the instructions pointer to ${f#"$REPO_ROOT"/} — the gate is installed and proven; the missing line points at $TARGET_REL/server/README.md (add it by hand)"
500
+ fi
501
+ }
502
+
503
+ if [[ "$MODE" == "refresh" ]]; then
504
+ [[ -f "$CFG" ]] || die "no .dependency-cruiser.cjs at $TARGET_REL — run the default mode first to generate the gate" 70
505
+ require_clean_tree "before capturing the baseline"
506
+ resolve_base_ref
507
+ check_tmpdir_outside_repo
508
+ trap '_wt_cleanup' EXIT
509
+ trap '_wt_cleanup interrupted; trap - EXIT; exit 143' INT TERM
510
+ CLEANUP_ARMED=1
511
+ take_run_lock
512
+ capture_baseline_mergebase
513
+ prove_bite
514
+ release_run_lock
515
+ CLEANUP_ARMED=0
516
+ trap - EXIT INT TERM
517
+ log "refresh complete — review the baseline diff before merging."
518
+ exit 0
519
+ fi
520
+
521
+ # --- Default mode: emit artifacts (non-destructive) --------------------------
522
+ # Clean-tree guard FIRST — the baseline is captured against the origin/main
523
+ # merge-base (below), and we refuse to emit onto a dirty tree so the resulting
524
+ # baseline + artifact diff is reviewable and deterministic.
525
+ require_clean_tree "before generating the gate"
526
+
527
+ for f in "$CFG" "$RUNNER" "$WORKFLOW" "$FIXWORKFLOW_A" "$FIXWORKFLOW_B"; do
528
+ [[ -e "$f" ]] && die "refuse-if-exists: ${f#"$REPO_ROOT"/} already present (no --force). Committed gate: re-baseline via --refresh-baseline. Untracked leftovers of a killed first install: delete them (\`git clean -n $TARGET_REL\` lists them), run \`git worktree prune\`, re-run" 66
529
+ done
530
+ [[ -e "$BASELINE" ]] && die "refuse-if-exists: ${BASELINE#"$REPO_ROOT"/} already present (re-baseline via --refresh-baseline)" 66
531
+
532
+ # Three-dirs precondition, BEFORE anything is emitted: the emitted runner cruises all three
533
+ # and would fail its own CI on a target missing one; the README names the requirement.
534
+ for d in app components server; do
535
+ [[ -d "$TARGET/$d" ]] || fail_stdout 65 "target $TARGET_REL lacks $d/ (the emitted runner cruises app/ components/ server/ and would fail its own CI)"
536
+ done
537
+
538
+ # Base ref and temp dir, BEFORE anything is emitted: the two first-install failures a founder
539
+ # repo actually hits (no origin/main; an IDE TMPDIR inside the repo) must not write first.
540
+ resolve_base_ref
541
+ check_tmpdir_outside_repo
542
+
543
+ # Arm the self-cleanup before the first write (single handler: _wt_cleanup). Disarmed only
544
+ # after prove_bite returns — the worktree helper re-installs the same handler and leaves it
545
+ # armed while CLEANUP_ARMED=1. The run lock is taken inside the armed window so the handler
546
+ # releases it on every exit.
547
+ CLEANUP_ARMED=1
548
+ trap '_wt_cleanup' EXIT
549
+ trap '_wt_cleanup interrupted; trap - EXIT; exit 143' INT TERM
550
+ take_run_lock
551
+ mkdir -p "$TARGET/scripts" "$TARGET/.github/workflows"
552
+
553
+ # .dependency-cruiser.cjs — emitted verbatim (the from-set is computed at
554
+ # require-time, never baked in).
555
+ cp "$REF_DIR/depcruise-config.template" "$CFG"
556
+
557
+ # Shared runner.
558
+ cp "$REF_DIR/shared-runner.template" "$RUNNER"
559
+ chmod +x "$RUNNER"
560
+
561
+ # CI workflow — substitute the target dir (path-check glob + working-directory +
562
+ # runner path). sed delimiter is '|' since the value contains no '|'.
563
+ sed "s|__TARGET_DIR__|$TARGET_REL|g" "$REF_DIR/constraint-gates-workflow.template" > "$WORKFLOW"
564
+
565
+ # Two-stage recovery dispatcher (ADR-074): same __TARGET_DIR__ substitution. Stage A
566
+ # (untrusted producer) + Stage B (privileged consumer, Git Data API — no checkout/apply).
567
+ sed "s|__TARGET_DIR__|$TARGET_REL|g" "$REF_DIR/fix-constraints-stage-a.template" > "$FIXWORKFLOW_A"
568
+ sed "s|__TARGET_DIR__|$TARGET_REL|g" "$REF_DIR/fix-constraints-stage-b.template" > "$FIXWORKFLOW_B"
569
+
570
+ log "emitted: ${CFG#"$REPO_ROOT"/}, ${RUNNER#"$REPO_ROOT"/}, ${WORKFLOW#"$REPO_ROOT"/}, ${FIXWORKFLOW_A#"$REPO_ROOT"/}, ${FIXWORKFLOW_B#"$REPO_ROOT"/}"
571
+
572
+ # Capture the initial baseline against the origin/main merge-base — same path as
573
+ # --refresh-baseline, so a leak introduced in the SAME PR that scaffolds the gate
574
+ # is NOT grandfathered (only violations pre-existing on main are).
575
+ capture_baseline_mergebase
576
+
577
+ # Prove the gate bites on HEAD, THEN write the prose. The README block and the pointer are the
578
+ # last writes of the run: the clean-tree guard inside the baseline capture must never see them
579
+ # (a tracked CLAUDE.md or server/README.md appended earlier would exit 67 with the executables
580
+ # already emitted and leave the next run at 66), and a 71/72/73/74 never has to undo them.
581
+ prove_bite
582
+ release_run_lock
583
+ CLEANUP_ARMED=0
584
+ trap - EXIT INT TERM
585
+ emit_readme
586
+ emit_pointer
587
+
588
+ log "done. Verify green: (cd $TARGET_REL && bash scripts/constraint-gates.sh)"
589
+ exit 0