@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,193 @@
1
+ #!/usr/bin/env bash
2
+ # Emitter coverage for the two-stage `fix-constraints` recovery dispatcher (#5814, ADR-074).
3
+ # Proves constraint-scaffold.sh emits BOTH stage workflows (Stage A = untrusted pull_request
4
+ # producer; Stage B = privileged workflow_run consumer) into the target, refuses to overwrite,
5
+ # fully substitutes __TARGET_DIR__, and that the security-load-bearing structural invariants
6
+ # hold: Stage A is NOT the privileged issue_comment/pull_request_target trigger; Stage B never
7
+ # checks out the untrusted tree / never bun-installs / never git-applies; and Stage A's `name:`
8
+ # is coupled to Stage B's `on: workflow_run: workflows:` filter (a mismatch silently disables
9
+ # recovery). Hermetic: every fixture is a throwaway `git init` repo under a mktemp dir targeted
10
+ # via CONSTRAINT_SCAFFOLD_REPO_ROOT; the real apps/web-platform tree is never touched. No
11
+ # dependency-cruiser needed — the emit (cp/sed) happens BEFORE baseline capture, so a
12
+ # default-mode run writes the workflows and then bails at the origin/main merge-base step.
13
+ #
14
+ # Runs in the scripts shard (scripts/test-all.sh globs
15
+ # plugins/soleur/skills/*/test/*.test.sh). Accumulate-then-exit; command-substitutions that
16
+ # run grep/sed are guarded with `|| true` so `set -e` does not abort before fail() prints.
17
+ set -euo pipefail
18
+
19
+ REPO_ROOT="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)"
20
+ GEN="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/scripts/constraint-scaffold.sh"
21
+ FIX_A="apps/web-platform/.github/workflows/fix-constraints-stage-a.yml"
22
+ FIX_B="apps/web-platform/.github/workflows/fix-constraints-stage-b.yml"
23
+
24
+ passes=0
25
+ fails=0
26
+ pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
27
+ fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
28
+
29
+ TMPROOT="$(mktemp -d)"
30
+ trap 'rm -rf "$TMPROOT"' EXIT
31
+ # Hermetic git environment for the fixtures (the repo's chokepoint, #7849): a developer
32
+ # commit.gpgsign / signing key / GIT_DIR must not reach the fixture commits or the scaffold under test.
33
+ # shellcheck source=../../../test/lib/git-fixture-env.sh
34
+ source "$REPO_ROOT/plugins/soleur/test/lib/git-fixture-env.sh"
35
+ mkdir -p "$TMPROOT/anchor"
36
+ git_fixture_env "$TMPROOT/anchor" || { echo "FATAL: git_fixture_env refused $TMPROOT/anchor" >&2; exit 1; }
37
+
38
+ # Throwaway git repo with a valid Next.js-shaped app dir, committed clean, origin/main == HEAD, and
39
+ # a fixture-owned stub `depcruise` (baseline -> [], clean err -> rc 0, probe err -> both rules on
40
+ # their edges, rc 1) so a default-mode run COMPLETES. Since #8288 a run that fails anywhere after
41
+ # the first write removes every artifact it emitted, so the workflows can only be observed after a
42
+ # run that reaches exit 0 — the pre-#8288 "assert on the artifacts a failed run left behind" is the
43
+ # residue class that PR closed.
44
+ make_repo() {
45
+ local fx="$TMPROOT/$1"
46
+ mkdir -p "$fx/apps/web-platform/app" "$fx/apps/web-platform/components" "$fx/apps/web-platform/server"
47
+ git -C "$fx" init -q
48
+ git -C "$fx" config user.email "test@example.com"
49
+ git -C "$fx" config user.name "test"
50
+ printf 'node_modules\n' > "$fx/.gitignore"
51
+ printf 'module.exports = {};\n' > "$fx/apps/web-platform/next.config.js"
52
+ printf '{ "dependencies": { "next": "15.0.0" } }\n' > "$fx/apps/web-platform/package.json"
53
+ printf 'export default function Page() { return null; }\n' > "$fx/apps/web-platform/app/page.tsx"
54
+ printf '"use client";\nexport const G = () => "g";\n' > "$fx/apps/web-platform/components/g.tsx"
55
+ printf 'export const APP = "fixture";\n' > "$fx/apps/web-platform/server/config.ts"
56
+ git -C "$fx" add -A
57
+ git -C "$fx" commit -q -m "seed app"
58
+ git -C "$fx" update-ref refs/remotes/origin/main HEAD
59
+ local stub="$TMPROOT/stub-$1"
60
+ mkdir -p "$stub/.bin" "$stub/dependency-cruiser"
61
+ printf '{ "name": "dependency-cruiser", "version": "0.0.0-stub" }\n' > "$stub/dependency-cruiser/package.json"
62
+ cat > "$stub/.bin/depcruise" <<'STUB'
63
+ #!/usr/bin/env bash
64
+ case " $* " in
65
+ *" --output-type json "*) printf '{"modules":[]}\n' ;;
66
+ *" --output-type baseline "*) printf '[]\n' ;;
67
+ *" --output-type err "*)
68
+ if [[ -e components/__constraint_scaffold_bite_probe__/direct.tsx ]]; then
69
+ printf '\n error no-client-to-server-secret-transitive: components/__constraint_scaffold_bite_probe__/via-hop.tsx → server/__constraint_scaffold_bite_probe__.ts\n error no-client-to-server-secret: components/__constraint_scaffold_bite_probe__/direct.tsx → server/__constraint_scaffold_bite_probe__.ts\n\nx 2 dependency violations (2 errors, 0 warnings). 5 modules, 3 dependencies cruised.\n'
70
+ exit 1
71
+ fi
72
+ printf '\n✔ no dependency violations found (1 modules, 0 dependencies cruised)\n\n'; exit 0 ;;
73
+ *) echo "stub depcruise: unhandled argv: $*" >&2; exit 64 ;;
74
+ esac
75
+ STUB
76
+ chmod +x "$stub/.bin/depcruise"
77
+ ln -s "$stub" "$fx/apps/web-platform/node_modules"
78
+ printf '%s' "$fx"
79
+ }
80
+
81
+ # --- Emit: default mode writes BOTH stage workflows -------------------------------------
82
+ FX="$(make_repo emit)"
83
+ set +e
84
+ CONSTRAINT_SCAFFOLD_REPO_ROOT="$FX" TMPDIR="$TMPROOT" bash "$GEN" >"$TMPROOT/emit.out" 2>"$TMPROOT/emit.err"
85
+ EMIT_RC=$?
86
+ set -e
87
+ # The run must COMPLETE (rc 0) for the artifacts to remain; a non-zero rc here is a real failure.
88
+ if [[ "$EMIT_RC" == "0" ]]; then
89
+ pass "emit: default mode completed (rc 0) against the stub toolchain"
90
+ else
91
+ fail "emit: default mode rc=$EMIT_RC (stdout: $(tail -2 "$TMPROOT/emit.out" | tr '\n' ' '))"
92
+ fi
93
+ for pair in "A:$FIX_A" "B:$FIX_B"; do
94
+ stage="${pair%%:*}"; rel="${pair#*:}"
95
+ if [[ -f "$FX/$rel" ]]; then
96
+ pass "emit: Stage $stage ($rel) written to the target"
97
+ else
98
+ fail "emit: Stage $stage ($rel) NOT written (run rc=$EMIT_RC)"
99
+ fi
100
+ done
101
+
102
+ # __TARGET_DIR__ must be fully substituted (no residual placeholder) in both stages.
103
+ for pair in "A:$FIX_A" "B:$FIX_B"; do
104
+ stage="${pair%%:*}"; rel="${pair#*:}"
105
+ if grep -q '__TARGET_DIR__' "$FX/$rel" 2>/dev/null; then
106
+ fail "emit: __TARGET_DIR__ left UNSUBSTITUTED in Stage $stage"
107
+ else
108
+ pass "emit: __TARGET_DIR__ fully substituted in Stage $stage"
109
+ fi
110
+ done
111
+
112
+ # Runner path substituted to the target dir in Stage A (the gate it runs).
113
+ if grep -qF 'bash apps/web-platform/scripts/constraint-gates.sh' "$FX/$FIX_A" 2>/dev/null; then
114
+ pass "emit: Stage A runner path substituted to the target dir (apps/web-platform)"
115
+ else
116
+ fail "emit: substituted runner path not found in Stage A"
117
+ fi
118
+
119
+ # --- Trigger anchors (on syntactic `on:`-block keys, NOT header prose) ---------------
120
+ # Stage A is the UNTRUSTED pull_request producer — never the privileged issue_comment /
121
+ # pull_request_target trigger (the whole point of the redesign). Anchor on 2-space indent.
122
+ if grep -qE '^[[:space:]]{2}pull_request:' "$FX/$FIX_A" 2>/dev/null; then
123
+ pass "trigger: Stage A fires on pull_request (anchored on:-block key)"
124
+ else
125
+ fail "trigger: Stage A missing the pull_request trigger block"
126
+ fi
127
+ if grep -qE '^[[:space:]]{2}(issue_comment|pull_request_target|workflow_run):' "$FX/$FIX_A" 2>/dev/null; then
128
+ fail "trigger: Stage A declares a privileged/consumer trigger (issue_comment/pull_request_target/workflow_run) — must not"
129
+ else
130
+ pass "trigger: Stage A declares no privileged issue_comment/pull_request_target (nor workflow_run) trigger"
131
+ fi
132
+ # Stage B is the PRIVILEGED workflow_run consumer — never an untrusted PR trigger.
133
+ if grep -qE '^[[:space:]]{2}workflow_run:' "$FX/$FIX_B" 2>/dev/null; then
134
+ pass "trigger: Stage B fires on workflow_run (anchored on:-block key)"
135
+ else
136
+ fail "trigger: Stage B missing the workflow_run trigger block"
137
+ fi
138
+ if grep -qE '^[[:space:]]{2}(pull_request|pull_request_target|issue_comment):' "$FX/$FIX_B" 2>/dev/null; then
139
+ fail "trigger: Stage B declares an untrusted PR trigger — must only be workflow_run"
140
+ else
141
+ pass "trigger: Stage B declares no untrusted pull_request/issue_comment trigger"
142
+ fi
143
+
144
+ # --- Forbidden-pattern: Stage B never executes the untrusted tree --------------------
145
+ # Stage B builds the commit via the Git Data API — no checkout of head, no git apply, no
146
+ # bun install, no PR-script execution. The header/shell COMMENTS in Stage B legitimately
147
+ # NAME these constructs ("never git-applies", "never runs bun install"), so strip comment
148
+ # lines (both YAML `#` and shell `#`) before grepping the executable body.
149
+ B_CODE="$(grep -vE '^[[:space:]]*#' "$FX/$FIX_B" || true)"
150
+ # checkout is a `uses:` step — anchor on the action ref (comments have no `uses:`).
151
+ if grep -qE '(^|[[:space:]-])uses:[[:space:]]*actions/checkout' "$FX/$FIX_B" 2>/dev/null; then
152
+ fail "forbidden: Stage B contains an actions/checkout step (must never check out any tree)"
153
+ else
154
+ pass "forbidden: Stage B has no actions/checkout step (Git Data API only)"
155
+ fi
156
+ for tok in 'bun install' 'setup-bun' 'git apply'; do
157
+ if printf '%s\n' "$B_CODE" | grep -cF >/dev/null "$tok" 2>/dev/null; then
158
+ fail "forbidden: Stage B executable body contains '$tok' (must never run it)"
159
+ else
160
+ pass "forbidden: Stage B executable body has no '$tok'"
161
+ fi
162
+ done
163
+
164
+ # --- Name-coupling: Stage A `name:` == Stage B `workflows:` filter string ------------
165
+ # The `workflows:` filter matches a workflow's `name:` field, NOT its filename — a mismatch
166
+ # makes Stage B silently NEVER trigger (no error). Load-bearing (architecture-strategist P1).
167
+ A_NAME="$(grep -E '^name:' "$FX/$FIX_A" 2>/dev/null | head -1 | sed -E 's/^name:[[:space:]]*//' || true)"
168
+ B_WF="$(grep -E '^[[:space:]]+workflows:' "$FX/$FIX_B" 2>/dev/null | head -1 | sed -E 's/.*workflows:[[:space:]]*\[[[:space:]]*"?([^]"]*)"?[[:space:]]*\].*/\1/' || true)"
169
+ if [[ -n "$A_NAME" && "$A_NAME" == "$B_WF" ]]; then
170
+ pass "name-coupling: Stage A name: ('$A_NAME') == Stage B workflows: filter ('$B_WF')"
171
+ else
172
+ fail "name-coupling: Stage A name: ('$A_NAME') != Stage B workflows: filter ('$B_WF') — Stage B would never trigger"
173
+ fi
174
+
175
+ # --- Refuse-if-exists: a pre-existing stage file blocks the emit (exit 66) -----------
176
+ FX2="$(make_repo refuse)"
177
+ : "${FX2:?fixture dir is empty; git -C <empty> would retarget this write}"
178
+ mkdir -p "$(dirname "$FX2/$FIX_A")"
179
+ printf '# already here\n' > "$FX2/$FIX_A"
180
+ git -C "$FX2" add -A && git -C "$FX2" commit -q -m "pre-place fix-constraints-stage-a"
181
+ set +e
182
+ REFUSE_OUT="$(CONSTRAINT_SCAFFOLD_REPO_ROOT="$FX2" bash "$GEN" 2>&1)"
183
+ REFUSE_RC=$?
184
+ set -e
185
+ if [[ "$REFUSE_RC" == "66" ]] && printf '%s' "$REFUSE_OUT" | grep -c >/dev/null 'fix-constraints-stage-a.yml already present'; then
186
+ pass "refuse: pre-existing fix-constraints-stage-a.yml triggers refuse-if-exists (exit 66)"
187
+ else
188
+ fail "refuse: expected exit 66 naming fix-constraints-stage-a.yml, got rc=$REFUSE_RC: $REFUSE_OUT"
189
+ fi
190
+
191
+ echo "---"
192
+ echo "emit-fix-constraints.test.sh: $passes passed, $fails failed"
193
+ [[ "$fails" -eq 0 ]]
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env bash
2
+ # Generator-script coverage for constraint-scaffold.sh (ADR-071). Exercises the
3
+ # script's guard/exit-matrix paths against HERMETIC fixture repos — the real
4
+ # apps/web-platform emitted files are never read or written. Each fixture is a
5
+ # throwaway `git init` repo under a mktemp dir, targeted via the
6
+ # CONSTRAINT_SCAFFOLD_REPO_ROOT override. None of these paths reach baseline
7
+ # capture (they bail at a precondition/guard), so dependency-cruiser is not
8
+ # needed.
9
+ #
10
+ # Covers:
11
+ # exit 65 not-a-Next.js-app detection (no next.config / no anchored "next").
12
+ # exit 66 refuse-if-exists: default mode on an already-emitted tree.
13
+ # exit 67 --refresh-baseline on a dirty working tree refuses.
14
+ #
15
+ # Runs in the scripts shard (scripts/test-all.sh globs
16
+ # plugins/soleur/skills/*/test/*.test.sh). Accumulate-then-exit.
17
+ set -euo pipefail
18
+
19
+ REPO_ROOT="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)"
20
+ GEN="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/scripts/constraint-scaffold.sh"
21
+
22
+ passes=0
23
+ fails=0
24
+ pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
25
+ fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
26
+
27
+ TMPROOT="$(mktemp -d)"
28
+ trap 'rm -rf "$TMPROOT"' EXIT
29
+
30
+ # Build a throwaway git repo with an apps/web-platform-shaped app dir. $1 = name,
31
+ # $2 = "next" to make it a valid Next.js app (next.config + anchored "next" dep).
32
+ make_repo() {
33
+ local fx="$TMPROOT/$1"
34
+ mkdir -p "$fx/apps/web-platform/app"
35
+ git -C "$fx" init -q
36
+ git -C "$fx" config user.email "test@example.com"
37
+ git -C "$fx" config user.name "test"
38
+ if [[ "${2:-}" == "next" ]]; then
39
+ printf 'module.exports = {};\n' > "$fx/apps/web-platform/next.config.js"
40
+ printf '{ "dependencies": { "next": "15.0.0" } }\n' > "$fx/apps/web-platform/package.json"
41
+ fi
42
+ printf '%s' "$fx"
43
+ }
44
+
45
+ run_gen() {
46
+ # $1 = repo root, rest = args. Captures rc; never aborts the suite.
47
+ local root="$1"; shift
48
+ set +e
49
+ CONSTRAINT_SCAFFOLD_REPO_ROOT="$root" bash "$GEN" "$@" >/dev/null 2>&1
50
+ local rc=$?
51
+ set -e
52
+ printf '%s' "$rc"
53
+ }
54
+
55
+ # --- exit 65: not a Next.js app ----------------------------------------------
56
+ FX="$(make_repo notnext)" # no next.config, no package.json
57
+ RC="$(run_gen "$FX")"
58
+ if [[ "$RC" == "65" ]]; then
59
+ pass "exit 65: not-a-Next.js-app detected (no next.config / anchored \"next\")"
60
+ else
61
+ fail "exit 65 expected for non-Next.js target, got rc=$RC"
62
+ fi
63
+
64
+ # --- exit 66: refuse-if-exists (default mode on an already-emitted tree) ------
65
+ FX="$(make_repo emitted next)"
66
+ # Pre-place an emitted artifact (untracked -> the clean-tree guard still passes,
67
+ # since git diff ignores untracked files) so refuse-if-exists fires.
68
+ printf '// already here\n' > "$FX/apps/web-platform/.dependency-cruiser.cjs"
69
+ RC="$(run_gen "$FX")"
70
+ if [[ "$RC" == "66" ]]; then
71
+ pass "exit 66: default mode refuses when an artifact already exists (no --force)"
72
+ else
73
+ fail "exit 66 expected for already-emitted tree, got rc=$RC"
74
+ fi
75
+
76
+ # --- exit 67: --refresh-baseline on a dirty tree refuses ----------------------
77
+ FX="$(make_repo dirty next)"
78
+ : "${FX:?fixture dir is empty; git -C <empty> would retarget this write}"
79
+ printf '// gate config\n' > "$FX/apps/web-platform/.dependency-cruiser.cjs"
80
+ git -C "$FX" add apps/web-platform
81
+ git -C "$FX" commit -q -m "seed gate"
82
+ # Dirty a TRACKED file so `git diff --quiet` reports the tree dirty.
83
+ printf '// edited\n' >> "$FX/apps/web-platform/.dependency-cruiser.cjs"
84
+ RC="$(run_gen "$FX" --refresh-baseline)"
85
+ if [[ "$RC" == "67" ]]; then
86
+ pass "exit 67: --refresh-baseline refuses on a dirty working tree"
87
+ else
88
+ fail "exit 67 expected for --refresh-baseline on dirty tree, got rc=$RC"
89
+ fi
90
+
91
+ echo "---"
92
+ echo "generator.test.sh: $passes passed, $fails failed"
93
+ [[ "$fails" -eq 0 ]]
@@ -0,0 +1,285 @@
1
+ #!/usr/bin/env bash
2
+ # Template <-> emission parity for the constraint-scaffold L1 gate (ADR-071).
3
+ #
4
+ # The dependency-cruiser config and the shared runner are emitted as
5
+ # BYTE-IDENTICAL copies of the skill's templates; the CI workflow is a single
6
+ # `sed __TARGET_DIR__ -> apps/web-platform` substitution of the workflow
7
+ # template; and the repo-root dogfood gate lives folded as `jobs.constraint-gates` inside
8
+ # `.github/workflows/pr-quality-guards.yml` (#8902) — structurally compared to the template job. ANY edit to a template
9
+ # MUST be mirrored into every emitted copy (and vice-versa), or the gate Soleur
10
+ # ships diverges from the gate Soleur tests. This test fails loud on any drift.
11
+ #
12
+ # Runs in the scripts shard (scripts/test-all.sh globs
13
+ # plugins/soleur/skills/*/test/*.test.sh). Accumulate-then-exit; diff
14
+ # command-substitutions are guarded with `|| true` so `set -e` does not abort
15
+ # before fail() prints.
16
+ set -euo pipefail
17
+
18
+ REPO_ROOT="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)"
19
+ REF="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/references"
20
+ APP="$REPO_ROOT/apps/web-platform"
21
+ TARGET_DIR="apps/web-platform"
22
+
23
+ passes=0
24
+ fails=0
25
+ # The INDEPENDENT row counter (ADR-193 #2). Incremented at every CALL SITE, never inside
26
+ # pass()/fail() — the VERDICT helpers touch only the verdict counters — so a stubbed fail() drops
27
+ # a verdict without dropping its count and the conservation check below notices. Top level only,
28
+ # never inside a `$( … )`.
29
+ cases=0
30
+ pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
31
+ fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
32
+ # Instrument self-test — DIRECTION, not only presence (a fail() misrouted to `passes` keeps the
33
+ # conservation check and the floor green). Reported via printf >&2 + exit 1, never through the
34
+ # helper it checks (ADR-193).
35
+ fail "instrument self-test (expected — proves fail() records a FAILURE)" >/dev/null
36
+ pass "instrument self-test (expected — proves pass() records a PASS)" >/dev/null
37
+ if [[ "$fails" != "1" || "$passes" != "1" ]]; then
38
+ printf '[FATAL] HELPER CONTROL BROKEN: after one fail() and one pass(), fails=%s passes=%s (want 1/1)\n' "$fails" "$passes" >&2
39
+ exit 1
40
+ fi
41
+ passes=0; fails=0
42
+
43
+ # 1. dependency-cruiser config — byte-identical to the template.
44
+ D="$(diff "$REF/depcruise-config.template" "$APP/.dependency-cruiser.cjs" 2>&1 || true)"
45
+ cases=$((cases + 1))
46
+ if [[ -z "$D" ]]; then
47
+ pass ".dependency-cruiser.cjs is byte-identical to depcruise-config.template"
48
+ else
49
+ fail ".dependency-cruiser.cjs DIVERGES from depcruise-config.template"
50
+ printf '%s\n' "$D" | sed 's/^/ /'
51
+ fi
52
+
53
+ # 2. shared runner — byte-identical to the template.
54
+ D="$(diff "$REF/shared-runner.template" "$APP/scripts/constraint-gates.sh" 2>&1 || true)"
55
+ cases=$((cases + 1))
56
+ if [[ -z "$D" ]]; then
57
+ pass "scripts/constraint-gates.sh is byte-identical to shared-runner.template"
58
+ else
59
+ fail "scripts/constraint-gates.sh DIVERGES from shared-runner.template"
60
+ printf '%s\n' "$D" | sed 's/^/ /'
61
+ fi
62
+
63
+ # 3. apps/web-platform workflow == sed(__TARGET_DIR__ -> apps/web-platform) of the template.
64
+ SUBST="$(sed "s|__TARGET_DIR__|$TARGET_DIR|g" "$REF/constraint-gates-workflow.template")"
65
+ D="$(printf '%s\n' "$SUBST" | diff - "$APP/.github/workflows/constraint-gates.yml" 2>&1 || true)"
66
+ cases=$((cases + 1))
67
+ if [[ -z "$D" ]]; then
68
+ pass "apps/web-platform workflow == sed(__TARGET_DIR__) of the workflow template"
69
+ else
70
+ fail "apps/web-platform workflow DIVERGES from the substituted template"
71
+ printf '%s\n' "$D" | sed 's/^/ /'
72
+ fi
73
+
74
+ # 4. The folded repo-root gate == the template's constraint-gates job. Since
75
+ # #8902 the dogfood instance lives as `jobs.constraint-gates` inside
76
+ # `.github/workflows/pr-quality-guards.yml` (the standalone root file was
77
+ # folded into the shared PR-gates workflow). Structural compare: parse both
78
+ # sides, drop the fold-added `if:` (PR-only gate — the template file has no
79
+ # merge_group so the arm is equivalent), and diff canonical YAML.
80
+ strip_body() { grep -vE '^[[:space:]]*#' | grep -vE '^[[:space:]]*$' || true; }
81
+ D="$(python3 - "$SUBST" "$REPO_ROOT/.github/workflows/pr-quality-guards.yml" <<'PY' 2>&1 || true
82
+ import sys, yaml
83
+ tmpl = yaml.safe_load(sys.argv[1])["jobs"]["constraint-gates"]
84
+ root = yaml.safe_load(open(sys.argv[2]))["jobs"]["constraint-gates"]
85
+ root.pop("if", None) # fold-added: host file merges merge_group; job is PR-only
86
+ a = yaml.safe_dump(tmpl, sort_keys=True)
87
+ b = yaml.safe_dump(root, sort_keys=True)
88
+ if a != b:
89
+ import difflib
90
+ print("\n".join(difflib.unified_diff(a.splitlines(), b.splitlines(),
91
+ "template.jobs.constraint-gates", "pr-quality-guards.jobs.constraint-gates",
92
+ lineterm="")))
93
+ PY
94
+ )"
95
+ cases=$((cases + 1))
96
+ if [[ -z "$D" ]]; then
97
+ pass "jobs.constraint-gates in pr-quality-guards.yml == substituted template job"
98
+ else
99
+ fail "jobs.constraint-gates in pr-quality-guards.yml DIVERGES from template job"
100
+ printf '%s\n' "$D" | sed 's/^/ /'
101
+ fi
102
+
103
+ # 5. repo-root dogfood Stage B == sed(__TARGET_DIR__) of the Stage B template (comment-stripped
104
+ # body). Stage B is the PRIVILEGED, write-capable recovery consumer and carries the entire
105
+ # fork-defense (isCrossRepository gate, path allowlist, sha256 round-trip, mandatory
106
+ # base_tree); it has NO intentional dogfood divergence, so its body must match the tenant
107
+ # template exactly. Guards the silent-drift class the emit test — which only inspects emitted
108
+ # tenant fixtures, never the committed repo-root dogfood — structurally cannot catch (#5814).
109
+ B_ROOT="$REPO_ROOT/.github/workflows/fix-constraints-stage-b.yml"
110
+ STAGE_B_SUBST="$(sed "s|__TARGET_DIR__|$TARGET_DIR|g" "$REF/fix-constraints-stage-b.template")"
111
+ ROOT_B_BODY="$(strip_body < "$B_ROOT")"
112
+ TMPL_B_BODY="$(printf '%s\n' "$STAGE_B_SUBST" | strip_body)"
113
+ D="$(diff <(printf '%s\n' "$ROOT_B_BODY") <(printf '%s\n' "$TMPL_B_BODY") 2>&1 || true)"
114
+ cases=$((cases + 1))
115
+ if [[ -z "$D" ]]; then
116
+ pass "repo-root fix-constraints-stage-b body == substituted Stage B template body"
117
+ else
118
+ fail "repo-root fix-constraints-stage-b DIVERGES from the substituted template body"
119
+ printf '%s\n' "$D" | sed 's/^/ /'
120
+ fi
121
+
122
+ # 6. Dogfood security invariants on the two repo-root recovery workflows. Stage A intentionally
123
+ # diverges from its template (dogfood-only api-spend steps + a richer anthropic-preflight
124
+ # composite), so it gets invariant assertions rather than a body diff.
125
+ A_ROOT="$REPO_ROOT/.github/workflows/fix-constraints-stage-a.yml"
126
+
127
+ # 6a. Name-coupling: Stage A `name:` == Stage B `workflows:` filter (workflow_run matches by the
128
+ # workflow's name, NOT its filename — a drift makes Stage B silently never trigger).
129
+ A_NAME="$(grep -E '^name:' "$A_ROOT" | head -1 | sed -E 's/^name:[[:space:]]*//' || true)"
130
+ B_WF="$(grep -E '^[[:space:]]+workflows:' "$B_ROOT" | head -1 | sed -E 's/.*workflows:[[:space:]]*\[[[:space:]]*"?([^]"]*)"?[[:space:]]*\].*/\1/' || true)"
131
+ cases=$((cases + 1))
132
+ if [[ -n "$A_NAME" && "$A_NAME" == "$B_WF" ]]; then
133
+ pass "dogfood name-coupling: Stage A name: ('$A_NAME') == Stage B workflows: filter"
134
+ else
135
+ fail "dogfood name-coupling BROKEN: Stage A name: ('$A_NAME') != Stage B workflows: ('$B_WF') — Stage B would never trigger"
136
+ fi
137
+
138
+ # 6a'. The same coupling on the TEMPLATES a founder repo receives: template A `name:` == template B
139
+ # `workflows:` filter (the dogfood pair above can hold while the emitted pair drifts).
140
+ TA_NAME="$(grep -E '^name:' "$REF/fix-constraints-stage-a.template" | head -1 | sed -E 's/^name:[[:space:]]*//' || true)"
141
+ TB_WF="$(grep -E '^[[:space:]]+workflows:' "$REF/fix-constraints-stage-b.template" | head -1 | sed -E 's/.*workflows:[[:space:]]*\[[[:space:]]*"?([^]"]*)"?[[:space:]]*\].*/\1/' || true)"
142
+ cases=$((cases + 1))
143
+ if [[ -n "$TA_NAME" && "$TA_NAME" == "$TB_WF" ]]; then
144
+ pass "template name-coupling: Stage A template name: ('$TA_NAME') == Stage B template workflows: filter"
145
+ else
146
+ fail "template name-coupling BROKEN: Stage A template name: ('$TA_NAME') != Stage B template workflows: ('$TB_WF')"
147
+ fi
148
+
149
+ # 6b. Stage B (privileged) executes no untrusted tree: no checkout-of-head / bun install /
150
+ # git apply in its executable body (full-line comments stripped so the header's prose that
151
+ # NAMES these constructs cannot false-match).
152
+ B_CODE="$(grep -vE '^[[:space:]]*#' "$B_ROOT" || true)"
153
+ bfail=0
154
+ if grep -qE '(^|[[:space:]-])uses:[[:space:]]*actions/checkout' "$B_ROOT"; then bfail=1; fi
155
+ for tok in 'bun install' 'setup-bun' 'git apply'; do
156
+ if printf '%s\n' "$B_CODE" | grep -cF >/dev/null "$tok"; then bfail=1; fi
157
+ done
158
+ cases=$((cases + 1))
159
+ if [[ "$bfail" -eq 0 ]]; then
160
+ pass "dogfood Stage B executes no untrusted tree (no checkout/bun-install/git-apply)"
161
+ else
162
+ fail "dogfood Stage B contains a forbidden execution construct (checkout/bun-install/git-apply)"
163
+ fi
164
+
165
+ # 6c. Stage A (untrusted producer) is read-only: declares contents: read, never contents: write.
166
+ cases=$((cases + 1))
167
+ if grep -qE '^[[:space:]]*contents:[[:space:]]*read' "$A_ROOT" && ! grep -qE '^[[:space:]]*contents:[[:space:]]*write' "$A_ROOT"; then
168
+ pass "dogfood Stage A is read-only (contents: read, no contents: write)"
169
+ else
170
+ fail "dogfood Stage A permission drift: expected contents: read only, found a write scope"
171
+ fi
172
+
173
+ # 7. Dogfood README block == the EMITTER's transform of boundary-readme.template (first-line
174
+ # attribution stripped, __TARGET_DIR__ substituted). `-s` FIRST: a `diff` of two empty
175
+ # operands passes, which is the parity vacuity that matters. The strip expression is pinned by
176
+ # `grep -cF` against the script's `content="$(sed …` ASSIGNMENT (a stale comment quoting the
177
+ # expression cannot stand in for the live one) so the two copies of the one transform cannot
178
+ # diverge silently. The comparison normalises trailing newlines exactly as the emitter does
179
+ # (`content="$(…)"` then `printf '%s\n'`), so a template ending in 0 or 2 newlines compares
180
+ # against what the emitter actually writes.
181
+ README_TMPL="$REF/boundary-readme.template"
182
+ README_DOG="$APP/server/README.md"
183
+ STRIP_EXPR="sed -e '1{/^<!-- Inspired by /d;}' -e \"s|__TARGET_DIR__|\$TARGET_REL|g\""
184
+ GEN_SCRIPT="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/scripts/constraint-scaffold.sh"
185
+ STRIP_PIN="$(grep -E '^\s*content="\$\(sed ' "$GEN_SCRIPT" 2>/dev/null | grep -cF -- "$STRIP_EXPR" || true)"
186
+ D=""
187
+ if [[ ! -s "$README_TMPL" ]]; then
188
+ D="template $README_TMPL is missing or empty"
189
+ elif [[ ! -s "$README_DOG" ]]; then
190
+ D="dogfood $README_DOG is missing or empty"
191
+ elif [[ "$STRIP_PIN" != "1" ]]; then
192
+ D="strip expression pin: the script contains the literal emitter expression $STRIP_PIN time(s), expected exactly 1"
193
+ elif ! head -1 "$README_TMPL" | grep -c >/dev/null '^<!-- Inspired by '; then
194
+ D="template line 1 is not the attribution comment (the emitter strips exactly that line)"
195
+ else
196
+ EXPECTED_README="$(sed -e '1{/^<!-- Inspired by /d;}' -e "s|__TARGET_DIR__|$TARGET_DIR|g" "$README_TMPL")"
197
+ D="$(printf '%s\n' "$EXPECTED_README" | diff - "$README_DOG" 2>&1 || true)"
198
+ fi
199
+ cases=$((cases + 1))
200
+ if [[ -z "$D" ]]; then
201
+ pass "apps/web-platform/server/README.md == emitter transform of boundary-readme.template (non-empty; strip expression pinned)"
202
+ else
203
+ fail "apps/web-platform/server/README.md DIVERGES from the template transform"
204
+ printf '%s\n' "$D" | sed 's/^/ /'
205
+ fi
206
+
207
+ # 8. Repo-root CLAUDE.md carries the pointer marker EXACTLY once, on a line naming the dogfood
208
+ # README path, with no `@apps/` import form (an `@path` line is a Claude Code import and would
209
+ # load the README into every session). Four selections for a four-dimension claim.
210
+ CLAUDE_MD="$REPO_ROOT/CLAUDE.md"
211
+ POINTER_MARKER='<!-- constraint-scaffold:pointer -->'
212
+ PTR_CT="$(grep -c -- "$POINTER_MARKER" "$CLAUDE_MD" 2>/dev/null || true)"
213
+ PTR_LINE="$(grep -- "$POINTER_MARKER" "$CLAUDE_MD" 2>/dev/null | head -1 || true)"
214
+ D=""
215
+ if [[ ! -s "$CLAUDE_MD" ]]; then
216
+ D="CLAUDE.md is missing or empty"
217
+ elif [[ "$PTR_CT" != "1" ]]; then
218
+ D="pointer marker appears $PTR_CT time(s), expected exactly 1"
219
+ elif [[ "$PTR_LINE" != *"apps/web-platform/server/README.md"* ]]; then
220
+ D="pointer line does not name apps/web-platform/server/README.md: '$PTR_LINE'"
221
+ elif [[ "$PTR_LINE" == *"@apps/"* ]]; then
222
+ D="pointer line uses the forbidden @apps/ import form: '$PTR_LINE'"
223
+ fi
224
+ cases=$((cases + 1))
225
+ if [[ -z "$D" ]]; then
226
+ pass "CLAUDE.md carries the constraint-scaffold pointer once, naming the README path, without @apps/"
227
+ else
228
+ fail "CLAUDE.md pointer: $D"
229
+ fi
230
+
231
+ # 9. Emission census: every `cp`/`sed` of a `$REF_DIR/*.template` in the script's default-mode
232
+ # emit block has a parity row above (rows 1–5 read one template each; the README template is
233
+ # row 7). A sixth emitted template with no dogfood row would otherwise red nothing here.
234
+ EMITTED_TEMPLATES="$(grep -oE '"\$REF_DIR/[a-z-]+\.template"' "$GEN_SCRIPT" 2>/dev/null | sort -u | grep -c . || true)"
235
+ ROW_TEMPLATES="$(grep -oE '"\$REF/[a-z-]+\.template"' "${BASH_SOURCE[0]}" | sort -u | grep -c . || true)"
236
+ cases=$((cases + 1))
237
+ if [[ "$EMITTED_TEMPLATES" -ge 6 && "$EMITTED_TEMPLATES" == "$ROW_TEMPLATES" ]]; then
238
+ pass "emission census: the script reads $EMITTED_TEMPLATES distinct templates and this suite has a row for each"
239
+ else
240
+ fail "emission census: script reads $EMITTED_TEMPLATES distinct templates, this suite reads $ROW_TEMPLATES (want equal, >= 6)"
241
+ fi
242
+
243
+ echo "---"
244
+
245
+ # --- Accounting conservation (ADR-193 #3) --------------------------------------------------
246
+ # Ordered BEFORE the floor (ADR-193 #4): a neutered fail()/pass() deflates the verdict counters, so
247
+ # the floor below would ALSO trip and would report the misleading "arms were deleted". This says
248
+ # "a verdict was discarded" instead. Reported with `printf >&2` + `exit 1` DIRECTLY, never
249
+ # through fail(): a check that reports by calling the verdict helper increments the very counter
250
+ # the exit status reads, so neutering fail() silences the rows AND the check meant to notice the
251
+ # silence. Every row records exactly one verdict, so passes+fails MUST equal cases; because
252
+ # `cases` moves at the CALL SITE and not inside the verdict helpers, the identity is a real
253
+ # constraint rather than a tautology. The literal `[FATAL] accounting` is load-bearing —
254
+ # guard-vacuity-floor's ARM 10 builds its conservation population by grepping that exact string.
255
+ if [[ $((passes + fails)) -ne "$cases" ]]; then
256
+ printf '\n[FATAL] accounting: passes+fails (%d) != cases (%d).\n' "$((passes + fails))" "$cases" >&2
257
+ if [[ $((passes + fails)) -lt "$cases" ]]; then
258
+ printf ' A row was counted but its verdict was not recorded — that is what a neutered pass()/fail() looks like.\n' >&2
259
+ else
260
+ printf ' A verdict was recorded at a call site with no `cases=$((cases + 1))` before it. This is a harness bug, not a product failure: add the increment at that call site.\n' >&2
261
+ fi
262
+ echo "parity.test.sh: $passes passed, $fails failed ($cases rows)"
263
+ exit 1
264
+ fi
265
+
266
+ # --- Anti-vacuity floor (ADR-193 #1) -------------------------------------------------------
267
+ # Reads the INDEPENDENT `cases` counter, and reports with `printf >&2` + `exit 1` DIRECTLY.
268
+ # This suite previously carried NO suite-level floor at all: a harness that silently asserted
269
+ # nothing printed a clean smaller total and exited 0. MIN_ROWS is derived at commit time by
270
+ # counting the `cases=$((cases + 1))` call sites in this file: 8 pre-existing verdict sites (rows
271
+ # 1, 2, 3, 4, 5, 6a, 6b, 6c) + rows 7–8 = 10. The literal sits on the line directly above the `if`
272
+ # because guard-vacuity-floor's backward slice carries only contiguous simple assignments into
273
+ # its neutered-machinery mutant; bound anywhere else, the mutant dies unbound and the floor
274
+ # scores CONSTRUCTION instead of FIRES.
275
+ MIN_ROWS=12
276
+ if [[ "$cases" -lt "$MIN_ROWS" ]]; then
277
+ printf '\n[FATAL] anti-vacuity floor: only %d row(s) ran, expected >= %d.\n' \
278
+ "$cases" "$MIN_ROWS" >&2
279
+ printf ' Rows were deleted or skipped; a green run here would be a coverage loss.\n' >&2
280
+ echo "parity.test.sh: $passes passed, $fails failed ($cases rows)"
281
+ exit 1
282
+ fi
283
+
284
+ echo "parity.test.sh: $passes passed, $fails failed ($cases rows)"
285
+ [[ "$fails" -eq 0 ]]