@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,725 @@
1
+ #!/usr/bin/env bash
2
+ # 2026-09-28 reproducer for #9127: cleanup_merged_worktrees archives KB
3
+ # artifacts with plain `mv`. Where the artifact is TRACKED (a non-bare clone
4
+ # parked on main, a feature-branch checkout, or a bare root's HEAD-materialized
5
+ # mirror) the move has no persistence owner: nothing commits it, and the
6
+ # SOLEUR-GUARD-MAINRESET `git reset --hard HEAD` — or sync_bare_files'
7
+ # checkout-index mirroring — restores the tracked half while the untracked
8
+ # archive copy persists. Result: a live+archive twin ("stranded spec").
9
+ #
10
+ # The fix (ADR-258): every reap archive move persists via the checkout's own
11
+ # commit path, or is not made at all.
12
+ # tracked + committable (feature branch) -> `git mv` + a pathspec-scoped
13
+ # `chore(archive-kb)` commit on the current branch (SOLEUR_REAP_ARCHIVE_COMMITTED)
14
+ # tracked + non-committable -> no move, SOLEUR_REAP_ARCHIVE_DEFERRED
15
+ # reason=<main-checkout|detached|unborn|merge-in-progress|bare|
16
+ # git-mv-failed|outside-git-root|unsafe-destination>
17
+ # untracked -> plain `mv`, unchanged (no resurrection mechanism applies)
18
+ #
19
+ # The existing sibling suites cannot see this class: their fixtures are
20
+ # untracked files, where `mv` is tracking-agnostic. Every "tracked" fixture
21
+ # below asserts its tracked-ness BEFORE the reap (guard-matrix row 6) so a
22
+ # neutered fixture fails loud instead of passing vacuously.
23
+ #
24
+ # Plan: knowledge-base/project/plans/archive/20261013-051752-2026-09-28-fix-reaper-archive-tracked-kb-persistence-plan.md
25
+ # Issue: https://github.com/jikig-ai/soleur/issues/9127
26
+ #
27
+ # Run via: bash plugins/soleur/skills/git-worktree/test/reap-archive-persistence.test.sh
28
+
29
+ set -uo pipefail
30
+
31
+ # Git-location tripwire (#7833). These suites drive worktree-manager.sh, which runs
32
+ # `git worktree remove`, `git branch -D` and `git reset --hard` -- the highest-damage git writes
33
+ # in the corpus. An inherited GIT_DIR aims all of them at the developer's real repository, so
34
+ # this file aborts rather than proceeding. Inline rather than sourcing test-helpers.sh, which
35
+ # would also import an assertion framework these suites do not use.
36
+ for _v in GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_COMMON_DIR GIT_OBJECT_DIRECTORY \
37
+ GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_NAMESPACE GIT_TEMPLATE_DIR GIT_EXEC_PATH; do
38
+ if [[ -n "${!_v:-}" && "${SOLEUR_GIT_TRIPWIRE_ALLOW:-0}" != "1" ]]; then
39
+ printf 'FATAL: %s started with an inherited git-location environment (%s=%s).\n' \
40
+ "${BASH_SOURCE[0]}" "$_v" "${!_v}" >&2
41
+ printf 'Fix the ENTRY POINT: unset %s && <runner>\n' "$_v" >&2
42
+ exit 97
43
+ fi
44
+ done
45
+ unset _v
46
+
47
+ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)"
48
+ WM="$REPO_ROOT/plugins/soleur/skills/git-worktree/scripts/worktree-manager.sh"
49
+
50
+ PASS=0; FAIL=0
51
+ fail() { echo " FAIL: $1"; FAIL=$((FAIL+1)); }
52
+ pass() { echo " pass: $1"; PASS=$((PASS+1)); }
53
+
54
+ TMP=$(mktemp -d) || { echo "FATAL: mktemp -d failed — refusing to run with an empty \$TMP, every fixture path would resolve against /" >&2; exit 2; }
55
+ trap 'rm -rf "$TMP"' EXIT
56
+
57
+ # Resolved ONCE, with `pwd -P`: TMPDIR is routinely a symlink, and comparing an
58
+ # unresolved $TMP against a resolved toplevel false-FAILS every call.
59
+ TMP_REAL="$(cd "$TMP" && pwd -P)" || TMP_REAL=""
60
+ case "$TMP_REAL" in
61
+ /*) : ;;
62
+ *) echo "FATAL: could not resolve the fixture root '$TMP' to an absolute path — refusing, an empty root makes the containment check match everything" >&2
63
+ exit 2 ;;
64
+ esac
65
+ readonly TMP_REAL
66
+
67
+ # cd into a NON-BARE fixture, or refuse (see lease-protects-active.test.sh for
68
+ # the full rationale: a missing/absent fixture dir leaves git walking up to a
69
+ # LIVE repository).
70
+ cdx() {
71
+ local target="$1" top
72
+ if ! cd "$target" 2>/dev/null; then
73
+ printf ' FAIL: fixture directory absent: %s\n' "$target" >&2
74
+ printf ' refusing to run fixture commands in %s — that is a LIVE repository.\n' "$PWD" >&2
75
+ : > "$TMP/.cdx-failed"
76
+ exit 90
77
+ fi
78
+ top="$(git rev-parse --show-toplevel 2>/dev/null)" || top=""
79
+ case "${top:-<none>}" in
80
+ "$TMP_REAL"|"$TMP_REAL"/*) return 0 ;;
81
+ esac
82
+ printf ' FAIL: %s exists, but its git toplevel is %s\n' "$target" "${top:-<not a git repository>}" >&2
83
+ printf ' which is OUTSIDE the fixture root %s — refusing, git would write to that repository.\n' "$TMP_REAL" >&2
84
+ : > "$TMP/.cdx-failed"
85
+ exit 90
86
+ }
87
+
88
+ # cd into a BARE fixture, or refuse. A bare repo has no toplevel, so cdx cannot
89
+ # guard it; the containment property is identical (resolved path inside $TMP)
90
+ # plus a positive bare check so a non-bare dir can never slip this arm.
91
+ cdb() {
92
+ local target="$1" resolved
93
+ if ! cd "$target" 2>/dev/null; then
94
+ printf ' FAIL: fixture directory absent: %s\n' "$target" >&2
95
+ printf ' refusing to run fixture commands in %s — that is a LIVE repository.\n' "$PWD" >&2
96
+ : > "$TMP/.cdx-failed"
97
+ exit 90
98
+ fi
99
+ resolved="$(pwd -P)"
100
+ case "$resolved" in
101
+ "$TMP_REAL"|"$TMP_REAL"/*) ;;
102
+ *) printf ' FAIL: %s resolved to %s, OUTSIDE the fixture root %s\n' "$target" "$resolved" "$TMP_REAL" >&2
103
+ : > "$TMP/.cdx-failed"
104
+ exit 90 ;;
105
+ esac
106
+ if [[ "$(git rev-parse --is-bare-repository 2>/dev/null)" != "true" ]]; then
107
+ printf ' FAIL: %s is not a bare repository — cdb is the bare-fixture guard; use cdx\n' "$target" >&2
108
+ : > "$TMP/.cdx-failed"
109
+ exit 90
110
+ fi
111
+ }
112
+
113
+ # Bare-`cd "` self-check — same construction as lease-protects-active.test.sh:
114
+ # strip comments, join continuations, flag any `cd "` whose logical line is not
115
+ # guarded by &&/||/if-while-until or routed through cdx/cdb.
116
+ _bare_cd="$(awk '
117
+ BEGIN { start_ln = 1 }
118
+ {
119
+ l = $0
120
+ sub(/(^|[[:space:]])#.*$/, "", l)
121
+ line = line l
122
+ if (sub(/\\[[:space:]]*$/, " ", line)) next
123
+ if (line ~ /(^|[^[:alnum:]_])cd "/ \
124
+ && line !~ /&&/ && line !~ /\|\|/ \
125
+ && line !~ /(^|[[:space:]])(if|while|until)[[:space:]]+!?[[:space:]]*cd[[:space:]]"/ \
126
+ && line !~ /(^|[^[:alnum:]_])(cdx|cdb)[[:space:]]/) print start_ln ": " line
127
+ line = ""; start_ln = NR + 1
128
+ }
129
+ ' "${BASH_SOURCE[0]}")"
130
+ if [[ -n "$_bare_cd" ]]; then
131
+ printf ' FAIL: unguarded cd site(s) in this suite — every fixture cd must go through cdx()/cdb():\n' >&2
132
+ printf '%s\n' "$_bare_cd" >&2
133
+ printf ' A bare cd here runs git in the CALLER CWD when the fixture is missing.\n' >&2
134
+ exit 1
135
+ fi
136
+
137
+ # ---------------------------------------------------------------------------
138
+ # Fixture helpers
139
+ # ---------------------------------------------------------------------------
140
+
141
+ # The body below is the CANONICAL copy, asserted byte-for-byte against every other copy by
142
+ # plugins/soleur/test/fixture-dir-operand-assert.test.sh. Do not reword it in one file only. #7652
143
+ assert_fixture_dir() {
144
+ case "${1-}" in
145
+ "") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
146
+ */../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
147
+ /proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
148
+ /|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
149
+ /*) : ;;
150
+ *) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
151
+ esac
152
+ }
153
+
154
+ mk_lease_root() {
155
+ local d="$1"
156
+ assert_fixture_dir "$d"
157
+ mkdir -p "$d/leases" "$d/locks" "$d/logs" || return 1
158
+ # Pre-stamp the #7409 first-run arming hold: without it the reaper reports
159
+ # rather than reaps on the first armed run and every assertion below would
160
+ # pass for the wrong reason.
161
+ : > "$d/reaper-armed" || return 1
162
+ }
163
+
164
+ # Build <bare> + <clone> where merged branch feat-victim carries TRACKED kb
165
+ # artifacts: a plan file (always) and the spec dir only when mode=tracked
166
+ # (mode=untracked writes the spec dir post-merge, never committed).
167
+ build_clone() {
168
+ local bare="$1" clone="$2" spec_mode="$3"
169
+ git init --bare -b main "$bare" >/dev/null || return 1
170
+ git clone "$bare" "$clone" >/dev/null 2>&1 || return 1
171
+ ( set -e
172
+ cdx "$clone"
173
+ git config user.email t@t
174
+ git config user.name t
175
+ git config commit.gpgsign false
176
+ git commit --allow-empty -m seed >/dev/null
177
+ git checkout -b feat-victim >/dev/null 2>&1
178
+ mkdir -p knowledge-base/project/plans
179
+ echo plan > "knowledge-base/project/plans/2026-01-01-feat-victim-plan.md"
180
+ if [[ "$spec_mode" == tracked ]]; then
181
+ mkdir -p knowledge-base/project/specs/feat-victim
182
+ echo spec > knowledge-base/project/specs/feat-victim/spec.md
183
+ fi
184
+ git add knowledge-base
185
+ # Backdated past the reaper's <10-minute recent-commit grace so the branch
186
+ # is a real reap candidate, not a grace-skipped one (vacuous-green guard).
187
+ GIT_COMMITTER_DATE="2025-01-01T00:00:00Z" \
188
+ git commit --date "2025-01-01T00:00:00Z" -m "victim kb artifacts" >/dev/null
189
+ git checkout main >/dev/null 2>&1
190
+ git merge --no-ff -m "merge feat-victim" feat-victim >/dev/null 2>&1
191
+ if [[ "$spec_mode" == untracked ]]; then
192
+ mkdir -p knowledge-base/project/specs/feat-victim
193
+ echo spec > knowledge-base/project/specs/feat-victim/spec.md
194
+ fi
195
+ git push origin main feat-victim >/dev/null 2>&1
196
+ )
197
+ }
198
+
199
+ # Run cleanup-merged inside fixture <dir> (non-bare via cdx); marker stream to
200
+ # <out>. rc is swallowed — every assertion keys on markers/disk state, and
201
+ # cleanup-merged returns 0 for most internal failures by design.
202
+ run_cleanup() {
203
+ local dir="$1" out="$2"; shift 2
204
+ assert_fixture_dir "$dir"; assert_fixture_dir "$out"
205
+ ( cdx "$dir"
206
+ env "$@" SOLEUR_SESSION_STATE_ROOT="$LEASE_ROOT" bash "$WM" cleanup-merged
207
+ ) >"$out" 2>&1 || true
208
+ }
209
+
210
+ run_cleanup_bare() {
211
+ local dir="$1" out="$2"; shift 2
212
+ assert_fixture_dir "$dir"; assert_fixture_dir "$out"
213
+ ( cdb "$dir"
214
+ env "$@" SOLEUR_SESSION_STATE_ROOT="$LEASE_ROOT" bash "$WM" cleanup-merged
215
+ ) >"$out" 2>&1 || true
216
+ }
217
+
218
+ is_tracked() { git -C "$1" ls-files --error-unmatch -- "$2" >/dev/null 2>&1; }
219
+
220
+ spec_live() { [[ -e "$1/knowledge-base/project/specs/feat-victim" ]]; }
221
+ spec_arch() { grep -q 'feat-victim' < <(ls "$1/knowledge-base/project/specs/archive/" 2>/dev/null); }
222
+ plan_live() { [[ -f "$1/knowledge-base/project/plans/2026-01-01-feat-victim-plan.md" ]]; }
223
+ plan_arch() { grep -q 'feat-victim' < <(ls "$1/knowledge-base/project/plans/archive/" 2>/dev/null); }
224
+
225
+ # ===========================================================================
226
+ # FIXTURE A — non-bare clone on `main`, TRACKED spec dir + plan file.
227
+ # The defect surface: today's plain `mv` + same-run/next-run `reset --hard`
228
+ # manufactures the twin. Expect: no move at all, DEFERRED reason=main-checkout.
229
+ # ===========================================================================
230
+ LEASE_ROOT="$TMP/lease-a"; mk_lease_root "$LEASE_ROOT"
231
+ BARE_A="$TMP/a-origin.git"; CLONE_A="$TMP/a-clone"
232
+ build_clone "$BARE_A" "$CLONE_A" tracked
233
+
234
+ # Precondition (guard-matrix row 6): the "tracked" fixture is really tracked.
235
+ if is_tracked "$CLONE_A" knowledge-base/project/specs/feat-victim/spec.md \
236
+ && is_tracked "$CLONE_A" knowledge-base/project/plans/2026-01-01-feat-victim-plan.md; then
237
+ pass "A precondition: spec dir + plan file are tracked on main"
238
+ else
239
+ fail "A precondition: 'tracked' fixture is really untracked — the suite cannot see the class it tests"
240
+ fi
241
+ if [[ "$(git -C "$CLONE_A" rev-parse --abbrev-ref HEAD)" == "main" ]]; then
242
+ pass "A precondition: checkout is on main"
243
+ else
244
+ fail "A precondition: checkout is not on main"
245
+ fi
246
+
247
+ OUT_A="$TMP/a-out.txt"
248
+ run_cleanup "$CLONE_A" "$OUT_A"
249
+
250
+ if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=main-checkout' "$OUT_A"; then
251
+ pass "A: tracked reap archive on main emits SOLEUR_REAP_ARCHIVE_DEFERRED reason=main-checkout"
252
+ else
253
+ fail "A: no DEFERRED/main-checkout marker (output: $(grep -c 'SOLEUR_' "$OUT_A") SOLEUR lines)"
254
+ fi
255
+ if spec_live "$CLONE_A"; then
256
+ pass "A: live spec dir still on disk after reap on main"
257
+ else
258
+ fail "A: live spec dir was moved on main (non-committable checkout must not move tracked artifacts)"
259
+ fi
260
+ if is_tracked "$CLONE_A" knowledge-base/project/specs/feat-victim/spec.md; then
261
+ pass "A: spec file still tracked after reap on main"
262
+ else
263
+ fail "A: spec file lost index tracking on main"
264
+ fi
265
+ if spec_arch "$CLONE_A"; then
266
+ fail "A: archive copy of spec dir was created on main — the twin mechanism"
267
+ else
268
+ pass "A: no spec archive copy created on main"
269
+ fi
270
+ if plan_live "$CLONE_A" && ! plan_arch "$CLONE_A"; then
271
+ pass "A: tracked plan file deferred too (live kept, no archive copy)"
272
+ else
273
+ fail "A: tracked plan file was moved on main"
274
+ fi
275
+ if [[ -z "$(git -C "$CLONE_A" status --porcelain 2>/dev/null)" ]]; then
276
+ pass "A: worktree clean after deferred reap"
277
+ else
278
+ fail "A: worktree dirty after deferred reap: $(git -C "$CLONE_A" status --porcelain | head -3)"
279
+ fi
280
+ if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_A" log --oneline -5 --format=%s); then
281
+ pass "A: no commit landed on main"
282
+ else
283
+ fail "A: a chore(archive-kb) commit landed on main — commits to main are prohibited"
284
+ fi
285
+
286
+ # Regression arm: same-run reset AND a second cleanup+reset pair (next-session).
287
+ git -C "$CLONE_A" reset --hard HEAD >/dev/null 2>&1
288
+ if spec_live "$CLONE_A" && ! spec_arch "$CLONE_A"; then
289
+ pass "A: same-run reset --hard produces no live+archive twin"
290
+ else
291
+ fail "A: reset --hard resurrected the twin (live+archive both present)"
292
+ fi
293
+ OUT_A2="$TMP/a2-out.txt"
294
+ run_cleanup "$CLONE_A" "$OUT_A2"
295
+ git -C "$CLONE_A" reset --hard HEAD >/dev/null 2>&1
296
+ if spec_live "$CLONE_A" && ! spec_arch "$CLONE_A"; then
297
+ pass "A: next-session cleanup+reset still produces no twin"
298
+ else
299
+ fail "A: a second cleanup/reset cycle manufactured the twin"
300
+ fi
301
+
302
+ # ===========================================================================
303
+ # FIXTURE B — clone on a FEATURE branch, tracked artifacts for a merged OTHER
304
+ # branch. Expect: git mv + pathspec-scoped chore(archive-kb) commit; a
305
+ # pre-staged unrelated file is never swept (AC5); an untracked brainstorm file
306
+ # in the same batch still plain-mv's (mixed batch, per-file classification).
307
+ # ===========================================================================
308
+ LEASE_ROOT="$TMP/lease-b"; mk_lease_root "$LEASE_ROOT"
309
+ BARE_B="$TMP/b-origin.git"; CLONE_B="$TMP/b-clone"
310
+ build_clone "$BARE_B" "$CLONE_B" tracked
311
+
312
+ ( set -e
313
+ cdx "$CLONE_B"
314
+ git checkout -b feat-actor >/dev/null 2>&1
315
+ echo unrelated > staged.txt
316
+ git add staged.txt
317
+ mkdir -p knowledge-base/project/brainstorms
318
+ echo brainstorm > "knowledge-base/project/brainstorms/2026-01-01-feat-victim-brainstorm.md"
319
+ )
320
+
321
+ OUT_B="$TMP/b-out.txt"
322
+ run_cleanup "$CLONE_B" "$OUT_B"
323
+
324
+ if grep -q 'SOLEUR_REAP_ARCHIVE_COMMITTED' "$OUT_B"; then
325
+ pass "B: committable checkout emits SOLEUR_REAP_ARCHIVE_COMMITTED"
326
+ else
327
+ fail "B: no COMMITTED marker on a feature-branch reap (output: $(grep 'SOLEUR_' "$OUT_B" | head -5))"
328
+ fi
329
+
330
+ ARCH_COMMIT="$(git -C "$CLONE_B" log -1 --format=%s feat-actor 2>/dev/null)"
331
+ if [[ "$ARCH_COMMIT" == "chore(archive-kb): persist reap archive for feat-victim" ]]; then
332
+ pass "B: scoped chore(archive-kb) commit is the feat-actor tip"
333
+ else
334
+ fail "B: feat-actor tip is '$ARCH_COMMIT', not the archive commit"
335
+ fi
336
+
337
+ if grep -q '^R100' < <(git -C "$CLONE_B" show --name-status --format= feat-actor); then
338
+ pass "B: commit records R100 renames (git mv, not add+delete)"
339
+ else
340
+ fail "B: no R100 rename in the archive commit — the move was not `git mv`"
341
+ fi
342
+
343
+ # The commit's touched-path set equals EXACTLY the archive-move set.
344
+ # `git show --name-only` on a rename commit lists the DESTINATION paths
345
+ # (sources appear only via --name-status, asserted above as R100).
346
+ COMMIT_PATHS="$(git -C "$CLONE_B" show --name-only --format= feat-actor | LC_ALL=C sort)"
347
+ COMMIT_PATH_COUNT="$(printf '%s\n' "$COMMIT_PATHS" | grep -c .)"
348
+ BAD_PATHS="$(printf '%s\n' "$COMMIT_PATHS" | grep -vcE '^knowledge-base/project/(specs|plans)/archive/.*feat-victim' || true)"
349
+ if [[ "$COMMIT_PATH_COUNT" -eq 2 && "$BAD_PATHS" -eq 0 ]] \
350
+ && grep -q 'specs/archive/.*feat-victim' <<<"$COMMIT_PATHS" \
351
+ && grep -q 'plans/archive/.*feat-victim' <<<"$COMMIT_PATHS"; then
352
+ pass "B: commit path-set is exactly the archive-move set (no staged.txt, no untracked brainstorm)"
353
+ else
354
+ fail "B: commit path-set wrong: $(printf '%s' "$COMMIT_PATHS" | head -8)"
355
+ fi
356
+
357
+ if [[ "$(git -C "$CLONE_B" diff --cached --name-only)" == "staged.txt" ]]; then
358
+ pass "B: pre-staged unrelated file still staged-and-uncommitted (AC5)"
359
+ else
360
+ fail "B: staged.txt was swept or lost: index now '$(git -C "$CLONE_B" diff --cached --name-only | head -3)'"
361
+ fi
362
+
363
+ if [[ ! -e "$CLONE_B/knowledge-base/project/specs/feat-victim" ]] && spec_arch "$CLONE_B"; then
364
+ pass "B: tracked spec dir moved live->archive via git mv"
365
+ else
366
+ fail "B: spec dir did not reach archive/ on a committable checkout"
367
+ fi
368
+
369
+ # The untracked brainstorm file in the SAME batch plain-mv'd (per-file probe).
370
+ if grep -q 'feat-victim' < <(ls "$CLONE_B/knowledge-base/project/brainstorms/archive/" 2>/dev/null) \
371
+ && ! is_tracked "$CLONE_B" "$(cd "$CLONE_B" 2>/dev/null && cd knowledge-base/project/brainstorms/archive 2>/dev/null && ls | grep feat-victim | head -1 | sed 's|^|knowledge-base/project/brainstorms/archive/|')"; then
372
+ pass "B: untracked brainstorm file plain-mv'd in the same reap (mixed batch)"
373
+ else
374
+ fail "B: untracked brainstorm file missing from archive or wrongly committed"
375
+ fi
376
+
377
+ # ===========================================================================
378
+ # FIXTURE C — untracked spec dir on `main`. Plain `mv` is a contract-permitted
379
+ # variant (guard-matrix row 7): untracked files cannot resurrect.
380
+ # ===========================================================================
381
+ LEASE_ROOT="$TMP/lease-c"; mk_lease_root "$LEASE_ROOT"
382
+ BARE_C="$TMP/c-origin.git"; CLONE_C="$TMP/c-clone"
383
+ build_clone "$BARE_C" "$CLONE_C" untracked
384
+
385
+ if spec_live "$CLONE_C" && ! is_tracked "$CLONE_C" knowledge-base/project/specs/feat-victim/spec.md; then
386
+ pass "C precondition: spec dir present and untracked on main"
387
+ else
388
+ fail "C precondition: untracked fixture is tracked or absent — vacuous fixture"
389
+ fi
390
+
391
+ OUT_C="$TMP/c-out.txt"
392
+ run_cleanup "$CLONE_C" "$OUT_C"
393
+
394
+ if spec_arch "$CLONE_C" && ! spec_live "$CLONE_C"; then
395
+ pass "C: untracked spec dir still archives via plain mv on main"
396
+ else
397
+ fail "C: untracked spec dir did not reach archive/ (plain-mv arm regressed)"
398
+ fi
399
+ if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_C" log --oneline -5 --format=%s); then
400
+ pass "C: untracked move produced no commit on main"
401
+ else
402
+ fail "C: a commit landed on main for an untracked move"
403
+ fi
404
+ if plan_live "$CLONE_C" && ! plan_arch "$CLONE_C"; then
405
+ pass "C: TRACKED plan file in the same reap was still deferred (per-file probe)"
406
+ else
407
+ fail "C: tracked plan file moved on main — per-file classification failed"
408
+ fi
409
+
410
+ # ===========================================================================
411
+ # FIXTURE D — bare repo whose HEAD tracks the spec path (stale on-disk
412
+ # mirror). Expect DEFERRED reason=bare and zero disk churn of the mirror:
413
+ # sync_bare_files would only re-materialize a moved file anyway.
414
+ # ===========================================================================
415
+ LEASE_ROOT="$TMP/lease-d"; mk_lease_root "$LEASE_ROOT"
416
+ BARE_D="$TMP/d-bare.git"
417
+ git init --bare -b main "$BARE_D" >/dev/null
418
+ SEED_D="$TMP/d-seed"
419
+ git clone "$BARE_D" "$SEED_D" >/dev/null 2>&1
420
+ ( set -e
421
+ cdx "$SEED_D"
422
+ git -c user.email=t@t -c user.name=t commit --allow-empty -m seed >/dev/null
423
+ git checkout -b feat-victim >/dev/null 2>&1
424
+ mkdir -p knowledge-base/project/specs/feat-victim
425
+ echo spec > knowledge-base/project/specs/feat-victim/spec.md
426
+ git add knowledge-base
427
+ GIT_COMMITTER_DATE="2025-01-01T00:00:00Z" \
428
+ git -c user.email=t@t -c user.name=t commit --date "2025-01-01T00:00:00Z" -m "victim kb artifacts" >/dev/null
429
+ git push origin feat-victim main >/dev/null 2>&1
430
+ )
431
+ # feat-victim tip IS main's tip => 'git branch --merged main' lists it.
432
+ git -C "$BARE_D" update-ref refs/heads/main "$(git -C "$BARE_D" rev-parse refs/heads/feat-victim)"
433
+ # cleanup-merged fetches origin — give the bare repo a working (self) remote.
434
+ git -C "$BARE_D" remote add origin "$BARE_D"
435
+ # The stale on-disk mirror: HEAD-tracked content parked at the live path.
436
+ mkdir -p "$BARE_D/knowledge-base/project/specs/feat-victim"
437
+ echo spec > "$BARE_D/knowledge-base/project/specs/feat-victim/spec.md"
438
+
439
+ # Precondition: the mirror path IS tracked in HEAD on the bare repo.
440
+ if [[ -n "$(git -C "$BARE_D" ls-tree -r HEAD --name-only -- knowledge-base/project/specs/feat-victim)" ]]; then
441
+ pass "D precondition: mirror path is HEAD-tracked on the bare repo"
442
+ else
443
+ fail "D precondition: mirror path not in HEAD — vacuous fixture"
444
+ fi
445
+
446
+ OUT_D="$TMP/d-out.txt"
447
+ run_cleanup_bare "$BARE_D" "$OUT_D"
448
+
449
+ if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=bare' "$OUT_D"; then
450
+ pass "D: bare-root reap emits DEFERRED reason=bare"
451
+ else
452
+ fail "D: no DEFERRED/bare marker (output: $(grep 'SOLEUR_' "$OUT_D" | head -5))"
453
+ fi
454
+ if spec_live "$BARE_D"; then
455
+ pass "D: bare-root mirror left in place"
456
+ else
457
+ fail "D: bare-root mirror was churned (moved) — sync_bare_files would re-materialize it"
458
+ fi
459
+ if spec_arch "$BARE_D"; then
460
+ fail "D: an archive copy was produced on the bare root — the mirror-twin mechanism"
461
+ else
462
+ pass "D: no archive copy produced on the bare root"
463
+ fi
464
+
465
+ # ===========================================================================
466
+ # FIXTURE E — feature-branch checkout where `git commit` fails (no resolvable
467
+ # identity). Expect STAGED: the staged rename payload persists so the session's
468
+ # own commits carry it.
469
+ # ===========================================================================
470
+ LEASE_ROOT="$TMP/lease-e"; mk_lease_root "$LEASE_ROOT"
471
+ BARE_E="$TMP/e-origin.git"; CLONE_E="$TMP/e-clone"
472
+ build_clone "$BARE_E" "$CLONE_E" tracked
473
+
474
+ ( set -e
475
+ cdx "$CLONE_E"
476
+ # No local identity, and force failure if one is still resolved: the reap's
477
+ # chore commit must fail deterministically on ANY host.
478
+ git config --unset user.email 2>/dev/null || true
479
+ git config --unset user.name 2>/dev/null || true
480
+ git config user.useConfigOnly true
481
+ git checkout -b feat-actor >/dev/null 2>&1
482
+ )
483
+ mkdir -p "$TMP/nohome" # empty HOME + XDG_CONFIG_HOME => no --global identity either
484
+ # (git reads $XDG_CONFIG_HOME/git/config for global config; HOME alone is not enough)
485
+
486
+ OUT_E="$TMP/e-out.txt"
487
+ run_cleanup "$CLONE_E" "$OUT_E" "HOME=$TMP/nohome" "XDG_CONFIG_HOME=$TMP/nohome" "GIT_CONFIG_NOSYSTEM=1"
488
+
489
+ if grep -q 'SOLEUR_REAP_ARCHIVE_STAGED' "$OUT_E"; then
490
+ pass "E: commit failure emits SOLEUR_REAP_ARCHIVE_STAGED"
491
+ else
492
+ fail "E: no STAGED marker on commit failure (output: $(grep 'SOLEUR_' "$OUT_E" | head -5))"
493
+ fi
494
+ if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_E" log --oneline -5 --format=%s feat-actor); then
495
+ pass "E: no archive commit landed when commit failed"
496
+ else
497
+ fail "E: chore commit landed despite the forced identity failure"
498
+ fi
499
+ if grep -qE '^R100|^A' < <(git -C "$CLONE_E" diff --cached --name-status); then
500
+ pass "E: staged rename payload survives in the index for the session to carry"
501
+ else
502
+ fail "E: archive move vanished instead of staying staged"
503
+ fi
504
+
505
+ # ===========================================================================
506
+ # FIXTURE F — detached HEAD. AC2 names detached; the HEAD arm must defer.
507
+ # ===========================================================================
508
+ LEASE_ROOT="$TMP/lease-f"; mk_lease_root "$LEASE_ROOT"
509
+ BARE_F="$TMP/f-origin.git"; CLONE_F="$TMP/f-clone"
510
+ build_clone "$BARE_F" "$CLONE_F" tracked
511
+
512
+ ( set -e
513
+ cdx "$CLONE_F"
514
+ git checkout --detach HEAD >/dev/null 2>&1
515
+ )
516
+
517
+ if [[ "$(git -C "$CLONE_F" rev-parse --abbrev-ref HEAD)" == "HEAD" ]]; then
518
+ pass "F precondition: checkout is detached"
519
+ else
520
+ fail "F precondition: checkout is not detached"
521
+ fi
522
+
523
+ OUT_F="$TMP/f-out.txt"
524
+ run_cleanup "$CLONE_F" "$OUT_F"
525
+
526
+ if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=detached' "$OUT_F"; then
527
+ pass "F: detached checkout emits DEFERRED reason=detached"
528
+ else
529
+ fail "F: no DEFERRED/detached marker (output: $(grep 'SOLEUR_' "$OUT_F" | head -5))"
530
+ fi
531
+ if spec_live "$CLONE_F" && ! spec_arch "$CLONE_F"; then
532
+ pass "F: tracked spec dir left live on a detached HEAD"
533
+ else
534
+ fail "F: tracked spec dir moved on a detached HEAD"
535
+ fi
536
+
537
+ # ===========================================================================
538
+ # FIXTURE G — committable checkout where `git mv` fails (specs/ parent made
539
+ # read-only). Expect: DEFERRED reason=git-mv-failed for the spec, the tracked
540
+ # plan still commits, and no marker-free partial move.
541
+ # ===========================================================================
542
+ LEASE_ROOT="$TMP/lease-g"; mk_lease_root "$LEASE_ROOT"
543
+ BARE_G="$TMP/g-origin.git"; CLONE_G="$TMP/g-clone"
544
+ build_clone "$BARE_G" "$CLONE_G" tracked
545
+
546
+ ( set -e
547
+ cdx "$CLONE_G"
548
+ git checkout -b feat-actor >/dev/null 2>&1
549
+ # git mv needs write perms on the destination's parent chain; a read-only
550
+ # specs/ fails every spec move deterministically on any host.
551
+ chmod a-w knowledge-base/project/specs
552
+ )
553
+
554
+ OUT_G="$TMP/g-out.txt"
555
+ run_cleanup "$CLONE_G" "$OUT_G"
556
+ # Restore perms before assertions (and so the EXIT trap's rm -rf can clean up).
557
+ chmod -R u+w "$CLONE_G" 2>/dev/null || true
558
+
559
+ # One failure of fixture G was seen under shard contention with at most five marker
560
+ # lines on its first arm and nothing on the other two (cause unproven, #7376 class). $OUT_G
561
+ # lives under $TMP and the EXIT trap deletes it, so inline everything a reader
562
+ # needs to tell a STAGED outcome from a COMMITTED one from a hook failure,
563
+ # flattened to one line.
564
+ g_diag() {
565
+ local markers tailout status log
566
+ markers="$(grep 'SOLEUR_' "$OUT_G" 2>/dev/null | tr '\n' '|')"
567
+ tailout="$(tail -20 "$OUT_G" 2>/dev/null | tr '\n' '|')"
568
+ status="$(git --no-optional-locks -C "$CLONE_G" status --short 2>&1 | tr '\n' '|')"
569
+ log="$(git -C "$CLONE_G" log --oneline -5 feat-actor 2>&1 | tr '\n' '|')"
570
+ printf 'markers=[%s] tail20=[%s] status=[%s] log=[%s]' "$markers" "$tailout" "$status" "$log"
571
+ }
572
+
573
+ if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=git-mv-failed' "$OUT_G"; then
574
+ pass "G: failed git mv emits DEFERRED reason=git-mv-failed (not a silent warn)"
575
+ else
576
+ fail "G: no git-mv-failed marker ($(g_diag))"
577
+ fi
578
+ if spec_live "$CLONE_G" && ! spec_arch "$CLONE_G"; then
579
+ pass "G: failed git mv left the spec dir live (no partial move, no plain-mv fallback)"
580
+ else
581
+ fail "G: spec dir moved/archived despite the failed git mv ($(g_diag))"
582
+ fi
583
+ # The tracked plan file DID move (plans/ stayed writable) — its commit proves
584
+ # the mv-failure arm did not abort the reap loop mid-batch.
585
+ if grep -q 'chore(archive-kb)' < <(git -C "$CLONE_G" log --oneline -3 --format=%s feat-actor); then
586
+ pass "G: tracked plan still committed — failed spec move did not abort the reap"
587
+ else
588
+ fail "G: plan archive commit missing — the mv failure aborted the run ($(g_diag))"
589
+ fi
590
+ # The diagnostic only runs inside the three failure arms above, so nothing else
591
+ # exercises it: pin that it still emits every field a reader needs.
592
+ G_DIAG_OUT="$(g_diag)"
593
+ if [[ "$G_DIAG_OUT" == *"markers=["*"SOLEUR_"*"] tail20=["*"] status=["*"] log=["*"]" ]]; then
594
+ pass "G: failure diagnostic carries SOLEUR_ markers, tail20, status and log"
595
+ else
596
+ fail "G: failure diagnostic is missing a field: $G_DIAG_OUT"
597
+ fi
598
+
599
+ # ===========================================================================
600
+ # FIXTURE H — committable branch mid-merge (MERGE_HEAD present). A scoped
601
+ # commit is refused by git mid-merge and the payload would fold into the
602
+ # operator's merge commit — defer instead.
603
+ # ===========================================================================
604
+ LEASE_ROOT="$TMP/lease-h"; mk_lease_root "$LEASE_ROOT"
605
+ BARE_H="$TMP/h-origin.git"; CLONE_H="$TMP/h-clone"
606
+ build_clone "$BARE_H" "$CLONE_H" tracked
607
+
608
+ ( set -e
609
+ cdx "$CLONE_H"
610
+ git checkout -b feat-actor >/dev/null 2>&1
611
+ echo one > conflict.txt
612
+ git add conflict.txt
613
+ git commit -m actor-side >/dev/null
614
+ git checkout -b feat-side main >/dev/null 2>&1
615
+ echo two > conflict.txt
616
+ git add conflict.txt
617
+ git commit -m side >/dev/null
618
+ git checkout feat-actor >/dev/null 2>&1
619
+ # Conflicting merge -> MERGE_HEAD present on feat-actor.
620
+ git merge feat-side >/dev/null 2>&1 || true
621
+ )
622
+
623
+ if git -C "$CLONE_H" rev-parse -q --verify MERGE_HEAD >/dev/null 2>&1 \
624
+ && [[ "$(git -C "$CLONE_H" rev-parse --abbrev-ref HEAD)" == "feat-actor" ]]; then
625
+ pass "H precondition: merge in progress on a feature branch"
626
+ else
627
+ fail "H precondition: merge did not produce MERGE_HEAD — vacuous fixture"
628
+ fi
629
+
630
+ OUT_H="$TMP/h-out.txt"
631
+ run_cleanup "$CLONE_H" "$OUT_H"
632
+
633
+ if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=merge-in-progress' "$OUT_H"; then
634
+ pass "H: merge-in-progress checkout emits DEFERRED reason=merge-in-progress"
635
+ else
636
+ fail "H: no merge-in-progress marker (output: $(grep 'SOLEUR_' "$OUT_H" | head -5))"
637
+ fi
638
+ if spec_live "$CLONE_H" && ! spec_arch "$CLONE_H"; then
639
+ pass "H: tracked spec dir left live mid-merge (payload never folds into a merge commit)"
640
+ else
641
+ fail "H: tracked spec dir moved mid-merge"
642
+ fi
643
+ if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_H" log --oneline -3 --format=%s feat-actor); then
644
+ pass "H: no archive commit landed during a merge"
645
+ else
646
+ fail "H: chore commit landed mid-merge"
647
+ fi
648
+
649
+ # ===========================================================================
650
+ # FIXTURE I — branch literally named `feat-`: feature_slug strips to EMPTY,
651
+ # which would collapse the plans/brainstorms glob to `*` and sweep every file
652
+ # in the directory. The guard must refuse the batch entirely.
653
+ # ===========================================================================
654
+ LEASE_ROOT="$TMP/lease-i"; mk_lease_root "$LEASE_ROOT"
655
+ BARE_I="$TMP/i-origin.git"; CLONE_I="$TMP/i-clone"
656
+ git init --bare -b main "$BARE_I" >/dev/null
657
+ git clone "$BARE_I" "$CLONE_I" >/dev/null 2>&1
658
+ ( set -e
659
+ cdx "$CLONE_I"
660
+ git config user.email t@t
661
+ git config user.name t
662
+ git config commit.gpgsign false
663
+ git commit --allow-empty -m seed >/dev/null
664
+ git checkout -b 'feat-' >/dev/null 2>&1
665
+ mkdir -p knowledge-base/project/plans
666
+ echo p > "knowledge-base/project/plans/2026-01-01-feat--plan.md"
667
+ echo u > "knowledge-base/project/plans/2026-02-02-unrelated-plan.md"
668
+ git add knowledge-base
669
+ GIT_COMMITTER_DATE="2025-01-01T00:00:00Z" \
670
+ git commit --date "2025-01-01T00:00:00Z" -m "kb artifacts" >/dev/null
671
+ git checkout main >/dev/null 2>&1
672
+ git merge --no-ff -m "merge feat-" 'feat-' >/dev/null 2>&1
673
+ git push origin main 'feat-' >/dev/null 2>&1
674
+ git checkout -b feat-actor >/dev/null 2>&1
675
+ )
676
+
677
+ OUT_I="$TMP/i-out.txt"
678
+ run_cleanup "$CLONE_I" "$OUT_I"
679
+
680
+ if [[ -f "$CLONE_I/knowledge-base/project/plans/2026-02-02-unrelated-plan.md" ]]; then
681
+ pass "I: unrelated plan file survived — empty slug did not sweep the directory"
682
+ else
683
+ fail "I: unrelated plan file was swept (empty-slug glob collapse)"
684
+ fi
685
+ if [[ -f "$CLONE_I/knowledge-base/project/plans/2026-01-01-feat--plan.md" ]]; then
686
+ pass "I: the feat- plan file stayed live too (empty slug refuses the batch)"
687
+ else
688
+ fail "I: feat- plan file moved — the guard should refuse, not partially move"
689
+ fi
690
+ if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_I" log --oneline -3 --format=%s feat-actor); then
691
+ pass "I: no archive commit produced for an empty feature slug"
692
+ else
693
+ fail "I: a chore commit landed for the empty-slug sweep"
694
+ fi
695
+
696
+ # ===========================================================================
697
+ # Census (guard-matrix row 5): every KB archive move routes through
698
+ # reap_archive_persist. Extract the two caller regions and the helper body;
699
+ # a bare `mv`/`git mv` in a caller region is the defect class reborn.
700
+ # ===========================================================================
701
+ _arch_body="$(awk '/^archive_kb_files\(\) \{/,/^\}/' "$WM")"
702
+ _spec_block="$(awk '/Archive spec directory/,/Extract feature slug/' "$WM")"
703
+ _helper_body="$(awk '/^reap_archive_persist\(\) \{/,/^\}/' "$WM")"
704
+
705
+ _mv_cmds() { grep -vE '^[[:space:]]*#' | grep -cE '\b(git[[:space:]]+)?mv[[:space:]]' || true; }
706
+
707
+ if grep -q 'reap_archive_persist' <<<"$_arch_body" && [[ "$(printf '%s\n' "$_arch_body" | _mv_cmds)" -eq 0 ]]; then
708
+ pass "census: archive_kb_files routes through reap_archive_persist, no bare mv"
709
+ else
710
+ fail "census: archive_kb_files moves artifacts without the helper"
711
+ fi
712
+ if grep -q 'reap_archive_persist' <<<"$_spec_block" && [[ "$(printf '%s\n' "$_spec_block" | _mv_cmds)" -eq 0 ]]; then
713
+ pass "census: spec-dir block routes through reap_archive_persist, no bare mv"
714
+ else
715
+ fail "census: spec-dir block moves artifacts without the helper"
716
+ fi
717
+ if grep -q 'git -C "$GIT_ROOT" mv -- ' <<<"$_helper_body" && grep -qE '(^|[^[:alnum:]_])mv -- "\$src"' <<<"$_helper_body"; then
718
+ pass "census: the helper owns both move arms (git mv + plain mv)"
719
+ else
720
+ fail "census: reap_archive_persist does not own both move arms"
721
+ fi
722
+
723
+ echo ""
724
+ echo "=== $PASS passed, $FAIL failed ==="
725
+ [[ "$FAIL" -eq 0 ]]