@soleur/opencode 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (812) hide show
  1. package/.claude-plugin/agents.manifest.json +476 -0
  2. package/.claude-plugin/plugin.json +42 -0
  3. package/README.md +44 -2
  4. package/agents/community/.gitkeep +0 -0
  5. package/agents/engineering/cto.md +87 -0
  6. package/agents/engineering/design/ddd-architect.md +95 -0
  7. package/agents/engineering/discovery/agent-finder.md +214 -0
  8. package/agents/engineering/discovery/functional-discovery.md +182 -0
  9. package/agents/engineering/infra/infra-security.md +151 -0
  10. package/agents/engineering/infra/platform-strategist.md +109 -0
  11. package/agents/engineering/infra/terraform-architect.md +171 -0
  12. package/agents/engineering/prompt-engineer.md +37 -0
  13. package/agents/engineering/research/best-practices-researcher.md +115 -0
  14. package/agents/engineering/research/framework-docs-researcher.md +93 -0
  15. package/agents/engineering/research/git-history-analyzer.md +53 -0
  16. package/agents/engineering/research/learnings-researcher.md +285 -0
  17. package/agents/engineering/research/repo-research-analyst.md +118 -0
  18. package/agents/engineering/review/agent-native-reviewer.md +279 -0
  19. package/agents/engineering/review/architecture-strategist.md +61 -0
  20. package/agents/engineering/review/code-quality-analyst.md +92 -0
  21. package/agents/engineering/review/code-simplicity-reviewer.md +109 -0
  22. package/agents/engineering/review/data-integrity-guardian.md +82 -0
  23. package/agents/engineering/review/data-migration-expert.md +98 -0
  24. package/agents/engineering/review/deployment-verification-agent.md +183 -0
  25. package/agents/engineering/review/dhh-rails-reviewer.md +46 -0
  26. package/agents/engineering/review/kieran-rails-reviewer.md +87 -0
  27. package/agents/engineering/review/legacy-code-expert.md +55 -0
  28. package/agents/engineering/review/observability-coverage-reviewer.md +147 -0
  29. package/agents/engineering/review/pattern-recognition-specialist.md +59 -0
  30. package/agents/engineering/review/performance-oracle.md +130 -0
  31. package/agents/engineering/review/security-sentinel.md +167 -0
  32. package/agents/engineering/review/semgrep-sast.md +36 -0
  33. package/agents/engineering/review/test-design-reviewer.md +150 -0
  34. package/agents/engineering/review/user-impact-reviewer.md +70 -0
  35. package/agents/engineering/workflow/pr-comment-resolver.md +69 -0
  36. package/agents/finance/budget-analyst.md +29 -0
  37. package/agents/finance/cfo.md +44 -0
  38. package/agents/finance/financial-reporter.md +30 -0
  39. package/agents/finance/revenue-analyst.md +30 -0
  40. package/agents/legal/clo.md +115 -0
  41. package/agents/legal/legal-compliance-auditor.md +110 -0
  42. package/agents/legal/legal-document-generator.md +134 -0
  43. package/agents/marketing/analytics-analyst.md +25 -0
  44. package/agents/marketing/brand-architect.md +181 -0
  45. package/agents/marketing/cmo.md +76 -0
  46. package/agents/marketing/conversion-optimizer.md +19 -0
  47. package/agents/marketing/copywriter.md +20 -0
  48. package/agents/marketing/fact-checker.md +70 -0
  49. package/agents/marketing/growth-strategist.md +145 -0
  50. package/agents/marketing/paid-media-strategist.md +28 -0
  51. package/agents/marketing/pricing-strategist.md +17 -0
  52. package/agents/marketing/programmatic-seo-specialist.md +25 -0
  53. package/agents/marketing/retention-strategist.md +23 -0
  54. package/agents/marketing/seo-aeo-analyst.md +164 -0
  55. package/agents/operations/coo.md +50 -0
  56. package/agents/operations/ops-advisor.md +78 -0
  57. package/agents/operations/ops-provisioner.md +101 -0
  58. package/agents/operations/ops-research.md +52 -0
  59. package/agents/operations/service-automator.md +278 -0
  60. package/agents/product/business-validator.md +206 -0
  61. package/agents/product/competitive-intelligence.md +89 -0
  62. package/agents/product/cpo.md +63 -0
  63. package/agents/product/design/ux-design-lead.md +209 -0
  64. package/agents/product/spec-flow-analyzer.md +122 -0
  65. package/agents/sales/cro.md +44 -0
  66. package/agents/sales/deal-architect.md +29 -0
  67. package/agents/sales/outbound-strategist.md +29 -0
  68. package/agents/sales/pipeline-analyst.md +29 -0
  69. package/agents/support/cco.md +48 -0
  70. package/agents/support/community-manager.md +570 -0
  71. package/agents/support/ticket-triage.md +70 -0
  72. package/bin/soleur-opencode.js +29 -0
  73. package/commands/go.md +659 -0
  74. package/commands/help.md +273 -0
  75. package/commands/sync.md +977 -0
  76. package/commands/version.md +103 -0
  77. package/hooks/antigravity-hooks.json +84 -0
  78. package/hooks/antigravity-session-start.sh +15 -0
  79. package/hooks/bare-root-cwd-guard.sh +131 -0
  80. package/hooks/browser-snapshot-credential-guard.sh +200 -0
  81. package/hooks/codex-session-start.sh +9 -0
  82. package/hooks/compaction-state.sh +525 -0
  83. package/hooks/destructive-command-guard.sh +1387 -0
  84. package/hooks/devin-session-start.sh +90 -0
  85. package/hooks/ext-filter-detect.sh +171 -0
  86. package/hooks/hooks.json +133 -0
  87. package/hooks/lib/hook-tool-kind.sh +24 -0
  88. package/hooks/lib/log-rotation.sh +176 -0
  89. package/hooks/lib/shell-argv.pl +576 -0
  90. package/hooks/memory-backstop.sh +1114 -0
  91. package/hooks/operator-stage-approval.sh +391 -0
  92. package/hooks/stop-hook.sh +367 -0
  93. package/hooks/unkept-promise-hook.sh +383 -0
  94. package/hooks/version-banner.sh +127 -0
  95. package/hooks/welcome-hook.sh +50 -0
  96. package/install.js +108 -0
  97. package/lib/agent-registry.ts +154 -0
  98. package/lib/c4-canonical-cli.mjs +34 -0
  99. package/lib/c4-canonical.mjs +46 -0
  100. package/lib/c4-from-components.ts +554 -0
  101. package/lib/go-routing.ts +81 -0
  102. package/lib/grok-inspect-contract.ts +311 -0
  103. package/lib/harness-model-map.ts +101 -0
  104. package/lib/harness-parity.ts +726 -0
  105. package/lib/harness-tool-map.ts +180 -0
  106. package/lib/harness.ts +716 -0
  107. package/lib/heartbeat-live-reconcile.ts +1153 -0
  108. package/lib/heartbeat-manifest.ts +342 -0
  109. package/lib/kb-coverage.ts +252 -0
  110. package/lib/pr-merge-poll.ts +103 -0
  111. package/lib/workflow-fidelity.ts +388 -0
  112. package/opencode/INSTRUCTIONS.md +152 -0
  113. package/opencode/agents/engineering/cto.md +10 -0
  114. package/opencode/agents/engineering/design/ddd-architect.md +10 -0
  115. package/opencode/agents/engineering/discovery/agent-finder.md +10 -0
  116. package/opencode/agents/engineering/discovery/functional-discovery.md +10 -0
  117. package/opencode/agents/engineering/infra/infra-security.md +10 -0
  118. package/opencode/agents/engineering/infra/platform-strategist.md +10 -0
  119. package/opencode/agents/engineering/infra/terraform-architect.md +10 -0
  120. package/opencode/agents/engineering/prompt-engineer.md +10 -0
  121. package/opencode/agents/engineering/research/best-practices-researcher.md +10 -0
  122. package/opencode/agents/engineering/research/framework-docs-researcher.md +10 -0
  123. package/opencode/agents/engineering/research/git-history-analyzer.md +10 -0
  124. package/opencode/agents/engineering/research/learnings-researcher.md +10 -0
  125. package/opencode/agents/engineering/research/repo-research-analyst.md +10 -0
  126. package/opencode/agents/engineering/review/agent-native-reviewer.md +10 -0
  127. package/opencode/agents/engineering/review/architecture-strategist.md +10 -0
  128. package/opencode/agents/engineering/review/code-quality-analyst.md +10 -0
  129. package/opencode/agents/engineering/review/code-simplicity-reviewer.md +10 -0
  130. package/opencode/agents/engineering/review/data-integrity-guardian.md +10 -0
  131. package/opencode/agents/engineering/review/data-migration-expert.md +10 -0
  132. package/opencode/agents/engineering/review/deployment-verification-agent.md +10 -0
  133. package/opencode/agents/engineering/review/dhh-rails-reviewer.md +10 -0
  134. package/opencode/agents/engineering/review/kieran-rails-reviewer.md +10 -0
  135. package/opencode/agents/engineering/review/legacy-code-expert.md +10 -0
  136. package/opencode/agents/engineering/review/observability-coverage-reviewer.md +10 -0
  137. package/opencode/agents/engineering/review/pattern-recognition-specialist.md +10 -0
  138. package/opencode/agents/engineering/review/performance-oracle.md +10 -0
  139. package/opencode/agents/engineering/review/security-sentinel.md +10 -0
  140. package/opencode/agents/engineering/review/semgrep-sast.md +10 -0
  141. package/opencode/agents/engineering/review/test-design-reviewer.md +10 -0
  142. package/opencode/agents/engineering/review/user-impact-reviewer.md +10 -0
  143. package/opencode/agents/engineering/workflow/pr-comment-resolver.md +10 -0
  144. package/opencode/agents/finance/budget-analyst.md +10 -0
  145. package/opencode/agents/finance/cfo.md +10 -0
  146. package/opencode/agents/finance/financial-reporter.md +10 -0
  147. package/opencode/agents/finance/revenue-analyst.md +10 -0
  148. package/opencode/agents/legal/clo.md +10 -0
  149. package/opencode/agents/legal/legal-compliance-auditor.md +10 -0
  150. package/opencode/agents/legal/legal-document-generator.md +10 -0
  151. package/opencode/agents/marketing/analytics-analyst.md +10 -0
  152. package/opencode/agents/marketing/brand-architect.md +10 -0
  153. package/opencode/agents/marketing/cmo.md +10 -0
  154. package/opencode/agents/marketing/conversion-optimizer.md +10 -0
  155. package/opencode/agents/marketing/copywriter.md +10 -0
  156. package/opencode/agents/marketing/fact-checker.md +10 -0
  157. package/opencode/agents/marketing/growth-strategist.md +10 -0
  158. package/opencode/agents/marketing/paid-media-strategist.md +10 -0
  159. package/opencode/agents/marketing/pricing-strategist.md +10 -0
  160. package/opencode/agents/marketing/programmatic-seo-specialist.md +10 -0
  161. package/opencode/agents/marketing/retention-strategist.md +10 -0
  162. package/opencode/agents/marketing/seo-aeo-analyst.md +10 -0
  163. package/opencode/agents/operations/coo.md +10 -0
  164. package/opencode/agents/operations/ops-advisor.md +10 -0
  165. package/opencode/agents/operations/ops-provisioner.md +10 -0
  166. package/opencode/agents/operations/ops-research.md +10 -0
  167. package/opencode/agents/operations/service-automator.md +10 -0
  168. package/opencode/agents/product/business-validator.md +10 -0
  169. package/opencode/agents/product/competitive-intelligence.md +10 -0
  170. package/opencode/agents/product/cpo.md +10 -0
  171. package/opencode/agents/product/design/ux-design-lead.md +10 -0
  172. package/opencode/agents/product/spec-flow-analyzer.md +10 -0
  173. package/opencode/agents/sales/cro.md +10 -0
  174. package/opencode/agents/sales/deal-architect.md +10 -0
  175. package/opencode/agents/sales/outbound-strategist.md +10 -0
  176. package/opencode/agents/sales/pipeline-analyst.md +10 -0
  177. package/opencode/agents/support/cco.md +10 -0
  178. package/opencode/agents/support/community-manager.md +10 -0
  179. package/opencode/agents/support/ticket-triage.md +10 -0
  180. package/opencode/commands/go.md +10 -0
  181. package/opencode/commands/help.md +10 -0
  182. package/opencode/commands/sync.md +10 -0
  183. package/opencode/commands/version.md +11 -0
  184. package/opencode/opencode.json +8 -0
  185. package/opencode/plugin.ts +493 -0
  186. package/package.json +36 -4
  187. package/scripts/admin-merge-ready.sh +545 -0
  188. package/scripts/admin-merge-ready.test.sh +753 -0
  189. package/scripts/affected-tests.sh +908 -0
  190. package/scripts/affected-tests.test.sh +1797 -0
  191. package/scripts/alpha-metrics.sh +78 -0
  192. package/scripts/alpha-metrics.test.sh +115 -0
  193. package/scripts/ancestor-signal-helpers.baseline.txt +16 -0
  194. package/scripts/audit-flag-flip.sh +107 -0
  195. package/scripts/check-red-on-main.sh +316 -0
  196. package/scripts/ci-head-verdict.sh +363 -0
  197. package/scripts/cloud-detect.sh +193 -0
  198. package/scripts/delegation-verify.sh +657 -0
  199. package/scripts/delegation-verify.test.sh +1424 -0
  200. package/scripts/deploy-arm.sh +475 -0
  201. package/scripts/domain-model-drift.sh +419 -0
  202. package/scripts/emit-decision.sh +144 -0
  203. package/scripts/emit-decision.test.sh +144 -0
  204. package/scripts/ext-filter-divergence-corpus.txt +15 -0
  205. package/scripts/ext-filter-divergence.sh +189 -0
  206. package/scripts/generate-c4-from-components.ts +442 -0
  207. package/scripts/grok-fidelity-gate.sh +68 -0
  208. package/scripts/grok-pre-push-gate.sh +232 -0
  209. package/scripts/harness-discovery-smoke.ts +906 -0
  210. package/scripts/harness-parity-census.ts +92 -0
  211. package/scripts/inngest-luks-alert-armed-probe.ts +29 -0
  212. package/scripts/install-opencode-adapter.ts +520 -0
  213. package/scripts/lib/affected-tests/common.sh +365 -0
  214. package/scripts/lib/affected-tests/go.sh +157 -0
  215. package/scripts/lib/affected-tests/js.sh +188 -0
  216. package/scripts/lib/affected-tests/nx-turbo.sh +98 -0
  217. package/scripts/lib/affected-tests/python.sh +185 -0
  218. package/scripts/lib/context-sanitize.sh +49 -0
  219. package/scripts/lib/domain-model-lib.sh +180 -0
  220. package/scripts/lib/ext-filter-grammar.tsv +34 -0
  221. package/scripts/lib/operator-script.sh +1236 -0
  222. package/scripts/lib/proc.sh +580 -0
  223. package/scripts/lib/session-state.sh +748 -0
  224. package/scripts/lib/tmp-classify.sh +843 -0
  225. package/scripts/lib/wrapper-boundary.sh +47 -0
  226. package/scripts/lint-ratchet.py +1547 -0
  227. package/scripts/monitor-pr-checks.sh +441 -0
  228. package/scripts/pipeline-tally.sh +756 -0
  229. package/scripts/pipeline-tally.test.sh +740 -0
  230. package/scripts/plugin-version.sh +528 -0
  231. package/scripts/precommit-guard.sh +113 -0
  232. package/scripts/precommit-guard.test.sh +254 -0
  233. package/scripts/reconcile-live-heartbeats.ts +705 -0
  234. package/scripts/render-c4-model.sh +217 -0
  235. package/scripts/resolve-git-root.sh +55 -0
  236. package/scripts/resolve-regenerable-conflicts.sh +363 -0
  237. package/scripts/resolve-regenerable-conflicts.test.sh +780 -0
  238. package/scripts/ruff-requirements.txt +22 -0
  239. package/scripts/run-in-pid-namespace.sh +98 -0
  240. package/scripts/run-in-pid-namespace.test.sh +290 -0
  241. package/scripts/scan-ancestor-signal-helpers.py +556 -0
  242. package/scripts/scan-ancestor-signal-helpers.test.sh +670 -0
  243. package/scripts/setup-ralph-loop.sh +238 -0
  244. package/scripts/sync-cursor-name-map.ts +316 -0
  245. package/scripts/sync-grok-agent-compat.ts +188 -0
  246. package/scripts/sync-npm-package.ts +178 -0
  247. package/scripts/sync-opencode-adapter.ts +479 -0
  248. package/scripts/sync-pr-behind.sh +534 -0
  249. package/scripts/sync-pr-behind.test.sh +252 -0
  250. package/scripts/taste-profile-update.sh +180 -0
  251. package/scripts/taste-profile-update.test.sh +167 -0
  252. package/scripts/write-budget-marker.sh +23 -0
  253. package/scripts/write-kb-coverage.ts +113 -0
  254. package/skills/admin-ip-refresh/SKILL.md +81 -0
  255. package/skills/admin-ip-refresh/references/admin-ip-refresh-procedure.md +201 -0
  256. package/skills/agent-browser/SKILL.md +698 -0
  257. package/skills/agent-browser/scripts/playwright-mcp-profile-slot.sh +304 -0
  258. package/skills/agent-browser/scripts/playwright-mcp-redact-proxy.py +964 -0
  259. package/skills/agent-browser/scripts/redact-a11y-snapshot.py +443 -0
  260. package/skills/agent-browser/test/fixtures/capture-playwright-mcp-fixtures.py +217 -0
  261. package/skills/agent-browser/test/fixtures/fake-passthrough-proxy.py +24 -0
  262. package/skills/agent-browser/test/fixtures/fake-playwright-mcp.py +131 -0
  263. package/skills/agent-browser/test/fixtures/make-proxy-mutant.py +48 -0
  264. package/skills/agent-browser/test/fixtures/odd-shapes/dialog-link-injection.json +10 -0
  265. package/skills/agent-browser/test/fixtures/odd-shapes/empty-content.json +5 -0
  266. package/skills/agent-browser/test/fixtures/odd-shapes/error-and-result.json +4 -0
  267. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-bool.json +6 -0
  268. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-string.json +6 -0
  269. package/skills/agent-browser/test/fixtures/odd-shapes/error-message-tree.json +6 -0
  270. package/skills/agent-browser/test/fixtures/odd-shapes/error-no-data.json +6 -0
  271. package/skills/agent-browser/test/fixtures/odd-shapes/error-string.json +4 -0
  272. package/skills/agent-browser/test/fixtures/odd-shapes/error-with-data.json +9 -0
  273. package/skills/agent-browser/test/fixtures/odd-shapes/evaluate-escaped-object.json +10 -0
  274. package/skills/agent-browser/test/fixtures/odd-shapes/invalid-utf8.json +4 -0
  275. package/skills/agent-browser/test/fixtures/odd-shapes/link-result.json +10 -0
  276. package/skills/agent-browser/test/fixtures/odd-shapes/list-two-results.json +6 -0
  277. package/skills/agent-browser/test/fixtures/odd-shapes/meta-in-result.json +13 -0
  278. package/skills/agent-browser/test/fixtures/odd-shapes/no-content.json +5 -0
  279. package/skills/agent-browser/test/fixtures/odd-shapes/quoted-key.json +10 -0
  280. package/skills/agent-browser/test/fixtures/odd-shapes/resource-block.json +18 -0
  281. package/skills/agent-browser/test/fixtures/odd-shapes/result-and-method.json +11 -0
  282. package/skills/agent-browser/test/fixtures/odd-shapes/result-string.json +3 -0
  283. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped-one-row.json +10 -0
  284. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped.json +10 -0
  285. package/skills/agent-browser/test/fixtures/odd-shapes/structured-content.json +13 -0
  286. package/skills/agent-browser/test/fixtures/odd-shapes/tools-list-no-tools.json +5 -0
  287. package/skills/agent-browser/test/fixtures/odd-shapes/tree-no-credential.json +10 -0
  288. package/skills/agent-browser/test/fixtures/odd-shapes/two-text-blocks.json +14 -0
  289. package/skills/agent-browser/test/fixtures/odd-shapes/unparsable-line.json +3 -0
  290. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-brace.json +10 -0
  291. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-link-substring.json +10 -0
  292. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/close.json +12 -0
  293. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/evaluate.json +12 -0
  294. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/find.json +12 -0
  295. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/framing.json +6 -0
  296. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/initialize.json +14 -0
  297. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate-link.json +12 -0
  298. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate.json +12 -0
  299. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/roots-list-request.json +5 -0
  300. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/screenshot.json +17 -0
  301. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-filename.json +12 -0
  302. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-json.json +12 -0
  303. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-raw.json +12 -0
  304. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot.json +12 -0
  305. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/tools-list.json +827 -0
  306. package/skills/agent-browser/test/fixtures/proxy-session-driver.py +138 -0
  307. package/skills/agent-browser/test/fixtures/session-facts.py +102 -0
  308. package/skills/agent-browser/test/playwright-mcp-lifetime.test.sh +1620 -0
  309. package/skills/agent-browser/test/playwright-mcp-redact-proxy.test.sh +1599 -0
  310. package/skills/agent-browser/test/redact-a11y-snapshot.test.sh +527 -0
  311. package/skills/agent-native-architecture/SKILL.md +479 -0
  312. package/skills/agent-native-architecture/references/action-parity-discipline.md +430 -0
  313. package/skills/agent-native-architecture/references/agent-execution-patterns.md +483 -0
  314. package/skills/agent-native-architecture/references/agent-native-testing.md +605 -0
  315. package/skills/agent-native-architecture/references/architecture-patterns.md +493 -0
  316. package/skills/agent-native-architecture/references/dynamic-context-injection.md +358 -0
  317. package/skills/agent-native-architecture/references/files-universal-interface.md +314 -0
  318. package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +381 -0
  319. package/skills/agent-native-architecture/references/mcp-tool-design.md +524 -0
  320. package/skills/agent-native-architecture/references/mobile-patterns.md +897 -0
  321. package/skills/agent-native-architecture/references/product-implications.md +478 -0
  322. package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +342 -0
  323. package/skills/agent-native-architecture/references/self-modification.md +294 -0
  324. package/skills/agent-native-architecture/references/shared-workspace-architecture.md +700 -0
  325. package/skills/agent-native-architecture/references/system-prompt-design.md +263 -0
  326. package/skills/agent-native-audit/SKILL.md +300 -0
  327. package/skills/agent-native-audit/workflows/agent-native-audit.workflow.js +423 -0
  328. package/skills/andrew-kane-gem-writer/SKILL.md +189 -0
  329. package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  330. package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  331. package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  332. package/skills/andrew-kane-gem-writer/references/resources.md +126 -0
  333. package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  334. package/skills/architecture/SKILL.md +436 -0
  335. package/skills/architecture/references/adr-template.md +154 -0
  336. package/skills/architecture/references/likec4-reference.md +136 -0
  337. package/skills/architecture/references/nfr-reference.md +126 -0
  338. package/skills/archive-kb/SKILL.md +86 -0
  339. package/skills/archive-kb/scripts/archive-kb.sh +300 -0
  340. package/skills/archive-kb/test/archive-kb-partial-run.test.sh +276 -0
  341. package/skills/atdd-developer/SKILL.md +65 -0
  342. package/skills/brainstorm/SKILL.md +701 -0
  343. package/skills/brainstorm/references/brainstorm-brand-workshop.md +153 -0
  344. package/skills/brainstorm/references/brainstorm-domain-config.md +63 -0
  345. package/skills/brainstorm/references/brainstorm-validation-workshop.md +65 -0
  346. package/skills/brainstorm/references/ui-surface-terms.md +42 -0
  347. package/skills/brainstorm-techniques/SKILL.md +231 -0
  348. package/skills/brainstorm-techniques/references/decision-principles.md +150 -0
  349. package/skills/brainstorm-techniques/references/phase-boundaries.md +103 -0
  350. package/skills/brainstorm-techniques/references/standing-delegation.md +407 -0
  351. package/skills/brainstorm-techniques/references/technical-ruling-delegation.md +174 -0
  352. package/skills/campaign-calendar/SKILL.md +145 -0
  353. package/skills/cf-token-scope/SKILL.md +164 -0
  354. package/skills/cf-token-scope/references/widen-playbook.md +114 -0
  355. package/skills/cf-token-scope/scripts/cf-token-scope.sh +253 -0
  356. package/skills/changelog/SKILL.md +142 -0
  357. package/skills/code-to-prd/SKILL.md +66 -0
  358. package/skills/code-to-prd/references/banner-template.md +12 -0
  359. package/skills/code-to-prd/references/prd-template.md +41 -0
  360. package/skills/code-to-prd/scripts/code-to-prd.sh +634 -0
  361. package/skills/code-to-prd/test/code-to-prd.test.sh +447 -0
  362. package/skills/code-to-prd/test/fixture/.env.example +7 -0
  363. package/skills/code-to-prd/test/fixture/app/about/page.tsx +11 -0
  364. package/skills/code-to-prd/test/fixture/app/api/health/route.ts +10 -0
  365. package/skills/code-to-prd/test/fixture/app/page.tsx +14 -0
  366. package/skills/code-to-prd/test/fixture/next.config.mjs +3 -0
  367. package/skills/code-to-prd/test/fixture/package.json +6 -0
  368. package/skills/cohort-status/SKILL.md +62 -0
  369. package/skills/community/SKILL.md +210 -0
  370. package/skills/community/scripts/bsky-community.sh +644 -0
  371. package/skills/community/scripts/bsky-setup.sh +631 -0
  372. package/skills/community/scripts/community-router.sh +93 -0
  373. package/skills/community/scripts/discord-community.sh +487 -0
  374. package/skills/community/scripts/discord-setup.sh +784 -0
  375. package/skills/community/scripts/github-community.sh +706 -0
  376. package/skills/community/scripts/hn-community.sh +233 -0
  377. package/skills/community/scripts/lib/hmac-sha1-b64.sh +126 -0
  378. package/skills/community/scripts/linkedin-community.sh +750 -0
  379. package/skills/community/scripts/linkedin-setup.sh +758 -0
  380. package/skills/community/scripts/x-community.sh +890 -0
  381. package/skills/community/scripts/x-setup.sh +713 -0
  382. package/skills/community/test/community-argv.test.sh +2922 -0
  383. package/skills/community/test/github-community.test.sh +981 -0
  384. package/skills/competitive-analysis/SKILL.md +69 -0
  385. package/skills/competitive-analysis/references/peer-plugin-audit.md +218 -0
  386. package/skills/compound/SKILL.md +673 -0
  387. package/skills/compound/scripts/token-efficiency-report.sh +334 -0
  388. package/skills/compound/test/phase-16.test.sh +379 -0
  389. package/skills/compound-capture/SKILL.md +791 -0
  390. package/skills/compound-capture/assets/critical-pattern-template.md +37 -0
  391. package/skills/compound-capture/assets/resolution-template.md +116 -0
  392. package/skills/compound-capture/references/yaml-schema.md +67 -0
  393. package/skills/compound-capture/schema.yaml +181 -0
  394. package/skills/constraint-scaffold/SKILL.md +175 -0
  395. package/skills/constraint-scaffold/references/boundary-readme.template +35 -0
  396. package/skills/constraint-scaffold/references/constraint-gates-workflow.template +69 -0
  397. package/skills/constraint-scaffold/references/depcruise-config.template +230 -0
  398. package/skills/constraint-scaffold/references/fix-constraints-stage-a.template +240 -0
  399. package/skills/constraint-scaffold/references/fix-constraints-stage-b.template +313 -0
  400. package/skills/constraint-scaffold/references/shared-runner.template +135 -0
  401. package/skills/constraint-scaffold/scripts/constraint-scaffold.sh +589 -0
  402. package/skills/constraint-scaffold/test/bite-proof.test.sh +1338 -0
  403. package/skills/constraint-scaffold/test/boundary.test.sh +734 -0
  404. package/skills/constraint-scaffold/test/emit-fix-constraints.test.sh +193 -0
  405. package/skills/constraint-scaffold/test/generator.test.sh +93 -0
  406. package/skills/constraint-scaffold/test/parity.test.sh +285 -0
  407. package/skills/content-writer/SKILL.md +242 -0
  408. package/skills/content-writer/scripts/blog-jargon-scan.sh +42 -0
  409. package/skills/cron-delete/SKILL.md +56 -0
  410. package/skills/cron-list/SKILL.md +54 -0
  411. package/skills/deepen-plan/SKILL.md +937 -0
  412. package/skills/deepen-plan/workflows/deepen-plan.workflow.js +488 -0
  413. package/skills/deploy/SKILL.md +115 -0
  414. package/skills/deploy/references/hetzner-setup.md +65 -0
  415. package/skills/deploy/scripts/deploy.sh +37 -0
  416. package/skills/deploy-docs/SKILL.md +95 -0
  417. package/skills/dhh-rails-style/SKILL.md +203 -0
  418. package/skills/dhh-rails-style/references/architecture.md +717 -0
  419. package/skills/dhh-rails-style/references/controllers.md +323 -0
  420. package/skills/dhh-rails-style/references/frontend.md +556 -0
  421. package/skills/dhh-rails-style/references/gems.md +316 -0
  422. package/skills/dhh-rails-style/references/models.md +388 -0
  423. package/skills/dhh-rails-style/references/testing.md +354 -0
  424. package/skills/discord-content/SKILL.md +126 -0
  425. package/skills/docs-site/SKILL.md +214 -0
  426. package/skills/drain-labeled-backlog/SKILL.md +203 -0
  427. package/skills/drain-labeled-backlog/scripts/group-by-area.sh +208 -0
  428. package/skills/drain-labeled-backlog/workflows/drain-labeled-backlog.workflow.js +433 -0
  429. package/skills/drain-prs/SKILL.md +142 -0
  430. package/skills/drain-prs/scripts/triage-prs.sh +192 -0
  431. package/skills/drain-prs/test/argv-ceiling.test.sh +183 -0
  432. package/skills/dspy-ruby/SKILL.md +634 -0
  433. package/skills/dspy-ruby/assets/config-template.rb +359 -0
  434. package/skills/dspy-ruby/assets/module-template.rb +326 -0
  435. package/skills/dspy-ruby/assets/signature-template.rb +143 -0
  436. package/skills/dspy-ruby/references/core-concepts.md +268 -0
  437. package/skills/dspy-ruby/references/optimization.md +623 -0
  438. package/skills/dspy-ruby/references/providers.md +335 -0
  439. package/skills/eval-harness/README.md +194 -0
  440. package/skills/eval-harness/SKILL.md +157 -0
  441. package/skills/eval-harness/enums/go-routes.json +13 -0
  442. package/skills/eval-harness/enums/incident-threshold.json +5 -0
  443. package/skills/eval-harness/enums/lane.json +5 -0
  444. package/skills/eval-harness/enums/tool-selection.json +20 -0
  445. package/skills/eval-harness/enums/triage-levels.json +5 -0
  446. package/skills/eval-harness/gated-skills.json +34 -0
  447. package/skills/eval-harness/models.generated.json +5 -0
  448. package/skills/eval-harness/promptfooconfig-go-routing.yaml +35 -0
  449. package/skills/eval-harness/promptfooconfig-incident-threshold.yaml +32 -0
  450. package/skills/eval-harness/promptfooconfig-lane-inference.yaml +33 -0
  451. package/skills/eval-harness/promptfooconfig-ticket-triage.yaml +34 -0
  452. package/skills/eval-harness/promptfooconfig-tool-selection.yaml +33 -0
  453. package/skills/eval-harness/prompts/go-baseline.txt +6 -0
  454. package/skills/eval-harness/prompts/go-skill.txt +21 -0
  455. package/skills/eval-harness/prompts/incident-threshold-baseline.txt +6 -0
  456. package/skills/eval-harness/prompts/incident-threshold-skill.txt +12 -0
  457. package/skills/eval-harness/prompts/lane-inference-baseline.txt +6 -0
  458. package/skills/eval-harness/prompts/lane-inference-skill.txt +15 -0
  459. package/skills/eval-harness/prompts/tool-selection-baseline.txt +19 -0
  460. package/skills/eval-harness/prompts/tool-selection-skill.txt +22 -0
  461. package/skills/eval-harness/prompts/triage-baseline.txt +7 -0
  462. package/skills/eval-harness/prompts/triage-skill.txt +10 -0
  463. package/skills/eval-harness/scripts/eval-gate.cjs +318 -0
  464. package/skills/eval-harness/scripts/extract-block.cjs +87 -0
  465. package/skills/eval-harness/scripts/gate-classification.cjs +28 -0
  466. package/skills/eval-harness/scripts/gen-models.sh +41 -0
  467. package/skills/eval-harness/scripts/gen-skill-prompt.cjs +177 -0
  468. package/skills/eval-harness/scripts/measure-classification.cjs +30 -0
  469. package/skills/eval-harness/scripts/parse-label.cjs +93 -0
  470. package/skills/eval-harness/scripts/verdict.cjs +132 -0
  471. package/skills/eval-harness/tasks/go-routing.jsonl +8 -0
  472. package/skills/eval-harness/tasks/incident-threshold.jsonl +7 -0
  473. package/skills/eval-harness/tasks/lane-inference.jsonl +7 -0
  474. package/skills/eval-harness/tasks/ticket-triage.jsonl +6 -0
  475. package/skills/eval-harness/tasks/tool-selection.jsonl +15 -0
  476. package/skills/eval-harness/test/eval-gate.test.sh +132 -0
  477. package/skills/eval-harness/test/extract-block.test.sh +87 -0
  478. package/skills/eval-harness/test/gate-classification.test.sh +77 -0
  479. package/skills/eval-harness/test/gen-models.test.sh +75 -0
  480. package/skills/eval-harness/test/measure-classification.test.sh +74 -0
  481. package/skills/eval-harness/test/parse-label.test.sh +129 -0
  482. package/skills/eval-harness/test/registry-completeness.test.sh +109 -0
  483. package/skills/eval-harness/test/verdict.test.sh +123 -0
  484. package/skills/every-style-editor/SKILL.md +142 -0
  485. package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  486. package/skills/feature-tweet/SKILL.md +199 -0
  487. package/skills/feature-video/SKILL.md +412 -0
  488. package/skills/feature-video/scripts/check_deps.sh +281 -0
  489. package/skills/file-todos/SKILL.md +267 -0
  490. package/skills/file-todos/assets/todo-template.md +166 -0
  491. package/skills/fix-issue/SKILL.md +278 -0
  492. package/skills/fix-issue/references/agent-authored-exclusion.md +118 -0
  493. package/skills/fix-issue/references/exclude-label-jq-snippet.md +96 -0
  494. package/skills/flag-bootstrap/SETUP.md +142 -0
  495. package/skills/flag-create/SKILL.md +145 -0
  496. package/skills/flag-create/scripts/create.sh +273 -0
  497. package/skills/flag-delete/SKILL.md +167 -0
  498. package/skills/flag-delete/scripts/delete.sh +288 -0
  499. package/skills/flag-list/SKILL.md +99 -0
  500. package/skills/flag-list/scripts/list.sh +275 -0
  501. package/skills/flag-set-role/SKILL.md +229 -0
  502. package/skills/flag-set-role/scripts/flip.sh +774 -0
  503. package/skills/frontend-anti-slop/SKILL.md +106 -0
  504. package/skills/frontend-anti-slop/references/anti-patterns.md +199 -0
  505. package/skills/frontend-anti-slop/references/slop-rules.md +65 -0
  506. package/skills/frontend-anti-slop/scripts/tier1-scan.ts +525 -0
  507. package/skills/frontend-design/SKILL.md +77 -0
  508. package/skills/gdpr-gate/NOTICE +136 -0
  509. package/skills/gdpr-gate/SKILL.md +341 -0
  510. package/skills/gdpr-gate/references/fields.md +160 -0
  511. package/skills/gdpr-gate/references/layers/api-layer.md +355 -0
  512. package/skills/gdpr-gate/references/layers/auth-sessions.md +290 -0
  513. package/skills/gdpr-gate/references/layers/data-in-transit.md +331 -0
  514. package/skills/gdpr-gate/references/layers/data-lifecycle.md +341 -0
  515. package/skills/gdpr-gate/references/layers/frontend.md +249 -0
  516. package/skills/gdpr-gate/references/layers/testing-seeding.md +256 -0
  517. package/skills/gdpr-gate/references/leakage-vectors.md +248 -0
  518. package/skills/gdpr-gate/references/legacy/legal-consent-v1-prose.md +48 -0
  519. package/skills/gdpr-gate/references/legal-consent.md +140 -0
  520. package/skills/gdpr-gate/references/non-negotiables.md +60 -0
  521. package/skills/gdpr-gate/scripts/gdpr-gate.sh +271 -0
  522. package/skills/gdpr-gate/scripts/notice-frontmatter.sh +337 -0
  523. package/skills/gdpr-gate/scripts/path-denylist.txt +39 -0
  524. package/skills/gdpr-gate/scripts/repo-scan.sh +158 -0
  525. package/skills/gdpr-gate/scripts/vendor-drift-classify.sh +120 -0
  526. package/skills/gdpr-gate/scripts/vendor-pin-integrity.sh +237 -0
  527. package/skills/gemini-imagegen/SKILL.md +283 -0
  528. package/skills/gemini-imagegen/requirements.txt +5 -0
  529. package/skills/gemini-imagegen/scripts/_error_handling.py +146 -0
  530. package/skills/gemini-imagegen/scripts/compose_images.py +150 -0
  531. package/skills/gemini-imagegen/scripts/edit_image.py +137 -0
  532. package/skills/gemini-imagegen/scripts/gemini_images.py +256 -0
  533. package/skills/gemini-imagegen/scripts/generate_image.py +147 -0
  534. package/skills/gemini-imagegen/scripts/multi_turn_chat.py +223 -0
  535. package/skills/gemini-imagegen/scripts/test_error_handling.py +179 -0
  536. package/skills/git-worktree/SKILL.md +534 -0
  537. package/skills/git-worktree/scripts/git-repo-readiness-diag.sh +98 -0
  538. package/skills/git-worktree/scripts/worktree-manager.sh +4773 -0
  539. package/skills/git-worktree/test/create-from-origin-main.test.sh +116 -0
  540. package/skills/git-worktree/test/lease-protects-active.test.sh +1056 -0
  541. package/skills/git-worktree/test/no-repo-fail-loud.test.sh +88 -0
  542. package/skills/git-worktree/test/orphan-reaper-honest-count.test.sh +379 -0
  543. package/skills/git-worktree/test/reap-archive-persistence.test.sh +725 -0
  544. package/skills/git-worktree/test/stale-lock-sweep.test.sh +176 -0
  545. package/skills/go/SKILL.md +54 -0
  546. package/skills/growth/SKILL.md +164 -0
  547. package/skills/harvest-debt/SKILL.md +78 -0
  548. package/skills/harvest-debt/scripts/harvest-debt.sh +114 -0
  549. package/skills/heal-skill/SKILL.md +173 -0
  550. package/skills/help/SKILL.md +46 -0
  551. package/skills/incident/NOTICE +39 -0
  552. package/skills/incident/SKILL.md +395 -0
  553. package/skills/incident/scripts/dry-run.sh +448 -0
  554. package/skills/incident/scripts/redact-engine.py +412 -0
  555. package/skills/incident/scripts/redact-sentinel.sh +44 -0
  556. package/skills/incident/templates/pir.md +139 -0
  557. package/skills/incident/test/fixtures/dry-run-incident.json +26 -0
  558. package/skills/incident/test/fixtures/dry-run-secret-leak.json +26 -0
  559. package/skills/incident/test/fixtures/legacy-bash-scanner.sh +82 -0
  560. package/skills/incident/test/fixtures/positive-corpus.md +87 -0
  561. package/skills/incident/test/redact-sentinel.test.sh +1420 -0
  562. package/skills/invoice/SKILL.md +206 -0
  563. package/skills/kb-glossary/SKILL.md +71 -0
  564. package/skills/kb-glossary/references/glossary-format.md +111 -0
  565. package/skills/kb-glossary/references/rejected-request-register.md +115 -0
  566. package/skills/kb-search/SKILL.md +276 -0
  567. package/skills/kb-search/scripts/kb-search-cache.sh +123 -0
  568. package/skills/legal-audit/SKILL.md +161 -0
  569. package/skills/legal-generate/NOTICE +242 -0
  570. package/skills/legal-generate/SKILL.md +244 -0
  571. package/skills/legal-generate/references/templates/advisor-agreement/template.md +12 -0
  572. package/skills/legal-generate/references/templates/business-associate-agreement/template.md +112 -0
  573. package/skills/legal-generate/references/templates/cookie-notice/template.md +82 -0
  574. package/skills/legal-generate/references/templates/dpa-global/template.md +439 -0
  575. package/skills/legal-generate/references/templates/dpa-us/template.md +222 -0
  576. package/skills/legal-generate/references/templates/employee-offer-letter/template.md +75 -0
  577. package/skills/legal-generate/references/templates/master-services-agreement/template.md +252 -0
  578. package/skills/legal-generate/references/templates/mutual-nda/template.md +66 -0
  579. package/skills/legal-generate/references/templates/one-way-nda/template.md +38 -0
  580. package/skills/legal-generate/references/templates/privacy-policy-gdpr/template.md +427 -0
  581. package/skills/legal-generate/references/templates/privacy-policy-us/template.md +313 -0
  582. package/skills/legal-generate/references/templates/terms-of-use/template.md +75 -0
  583. package/skills/legal-generate/scripts/strip-vendor-credit.sh +96 -0
  584. package/skills/linear-fetch/SKILL.md +247 -0
  585. package/skills/linear-fetch/scripts/assert-no-linear-telemetry.sh +66 -0
  586. package/skills/linear-fetch/scripts/redact-linear-urls.sh +51 -0
  587. package/skills/linear-fetch/scripts/render-caller-template.sh +36 -0
  588. package/skills/linear-fetch/test/assert-no-linear-telemetry.test.sh +113 -0
  589. package/skills/linear-fetch/test/parity.test.sh +112 -0
  590. package/skills/linear-fetch/test/persist-safe-integration.test.sh +191 -0
  591. package/skills/linear-fetch/test/redact-linear-urls.test.sh +226 -0
  592. package/skills/merge-pr/SKILL.md +668 -0
  593. package/skills/model-launch-review/SKILL.md +255 -0
  594. package/skills/model-launch-review/scripts/audit-models.sh +501 -0
  595. package/skills/one-shot/SKILL.md +316 -0
  596. package/skills/one-shot/references/token-discipline.md +74 -0
  597. package/skills/operator-bootstrap/SKILL.md +412 -0
  598. package/skills/operator-bootstrap/template.sh +439 -0
  599. package/skills/operator-digest/SKILL.md +287 -0
  600. package/skills/operator-digest/assets/operator-digest.workflow.yml +175 -0
  601. package/skills/operator-digest/scripts/digest-scrub.sh +119 -0
  602. package/skills/operator-digest/scripts/provision-operator-digest-repo.sh +147 -0
  603. package/skills/operator-rephrase/SKILL.md +98 -0
  604. package/skills/pencil-setup/SKILL.md +201 -0
  605. package/skills/pencil-setup/scripts/check_deps.sh +556 -0
  606. package/skills/pencil-setup/scripts/copy_adapter.sh +80 -0
  607. package/skills/pencil-setup/scripts/package-lock.json +1172 -0
  608. package/skills/pencil-setup/scripts/package.json +14 -0
  609. package/skills/pencil-setup/scripts/pencil-error-enrichment.mjs +21 -0
  610. package/skills/pencil-setup/scripts/pencil-mcp-adapter.mjs +733 -0
  611. package/skills/pencil-setup/scripts/pencil-response-classify.mjs +38 -0
  612. package/skills/pencil-setup/scripts/pencil-save-gate.mjs +26 -0
  613. package/skills/pencil-setup/scripts/sanitize-filename.mjs +25 -0
  614. package/skills/plan/SKILL.md +1140 -0
  615. package/skills/plan/references/differential-migration-testing.md +185 -0
  616. package/skills/plan/references/plan-community-discovery.md +42 -0
  617. package/skills/plan/references/plan-founder-check.md +137 -0
  618. package/skills/plan/references/plan-functional-overlap.md +25 -0
  619. package/skills/plan/references/plan-host-fanout.md +51 -0
  620. package/skills/plan/references/plan-issue-templates.md +779 -0
  621. package/skills/plan/references/plan-network-outage-checklist.md +131 -0
  622. package/skills/plan/references/plan-scope-check.md +126 -0
  623. package/skills/plan/references/plan-sharp-edges.md +325 -0
  624. package/skills/plan/references/plan-signoff-lifecycle.md +12 -0
  625. package/skills/plan/references/webapp-cwv-observability.md +143 -0
  626. package/skills/plan-review/SKILL.md +91 -0
  627. package/skills/plan-review/lib/named-panel.mjs +58 -0
  628. package/skills/plan-review/workflows/plan-review.workflow.js +477 -0
  629. package/skills/postmerge/SKILL.md +642 -0
  630. package/skills/postmerge/references/deploy-status-debugging.md +138 -0
  631. package/skills/postmerge/references/graceful-degradation.md +20 -0
  632. package/skills/postmerge/references/sentry-error-count-delta.md +137 -0
  633. package/skills/preflight/SKILL.md +1553 -0
  634. package/skills/preflight/references/check-13-founder-check.md +286 -0
  635. package/skills/preflight/scripts/founder-check.py +1640 -0
  636. package/skills/preflight/scripts/parse-form-a.awk +107 -0
  637. package/skills/preflight/scripts/probe-verb-gate.sh +108 -0
  638. package/skills/product-roadmap/SKILL.md +357 -0
  639. package/skills/product-roadmap/scripts/roadmap-reconcile.sh +327 -0
  640. package/skills/provision-cloudflare/SKILL.md +67 -0
  641. package/skills/provision-cloudflare/scripts/provision-cloudflare.sh +271 -0
  642. package/skills/provision-doppler/SKILL.md +58 -0
  643. package/skills/provision-doppler/scripts/provision-doppler.sh +358 -0
  644. package/skills/provision-github/SKILL.md +59 -0
  645. package/skills/provision-github/scripts/provision-github.sh +300 -0
  646. package/skills/provision-hetzner/SKILL.md +76 -0
  647. package/skills/provision-hetzner/scripts/provision-hetzner.sh +262 -0
  648. package/skills/provision-hetzner/test/fixture/knowledge-base/legal/tenant-dpa-register.md +26 -0
  649. package/skills/provision-hetzner/test/fixture/provision-hetzner-dry-run.golden +34 -0
  650. package/skills/provision-hetzner/test/provision-hetzner-characterization.test.sh +227 -0
  651. package/skills/qa/SKILL.md +263 -0
  652. package/skills/qa/references/browser-preflight.md +22 -0
  653. package/skills/questionnaire-generate/SKILL.md +328 -0
  654. package/skills/questionnaire-generate/references/questionnaire.template +60 -0
  655. package/skills/rclone/SKILL.md +162 -0
  656. package/skills/rclone/scripts/check_setup.sh +63 -0
  657. package/skills/release-announce/SKILL.md +65 -0
  658. package/skills/release-docs/SKILL.md +92 -0
  659. package/skills/reproduce-bug/SKILL.md +358 -0
  660. package/skills/resolve-debt/SKILL.md +85 -0
  661. package/skills/resolve-debt/scripts/resolve-debt.py +584 -0
  662. package/skills/resolve-parallel/SKILL.md +45 -0
  663. package/skills/resolve-parallel/workflows/resolve-parallel.workflow.js +415 -0
  664. package/skills/resolve-pr-parallel/SKILL.md +68 -0
  665. package/skills/resolve-pr-parallel/workflows/resolve-pr-parallel.workflow.js +419 -0
  666. package/skills/resolve-todo-parallel/SKILL.md +57 -0
  667. package/skills/resolve-todo-parallel/workflows/resolve-todo-parallel.workflow.js +398 -0
  668. package/skills/review/SKILL.md +1621 -0
  669. package/skills/review/references/anti-slop-scanner-hook.md +40 -0
  670. package/skills/review/references/defect-classes-migrations.md +9 -0
  671. package/skills/review/references/generated-input-oracle-surfaces.md +15 -0
  672. package/skills/review/references/review-e2e-testing.md +116 -0
  673. package/skills/review/references/review-todo-structure.md +165 -0
  674. package/skills/review/references/risk-tier-and-fix-rounds.md +95 -0
  675. package/skills/review/references/semgrep-custom-rules.yaml +174 -0
  676. package/skills/review/references/ultrathink-phases.md +98 -0
  677. package/skills/review/references/wfs.md +6 -0
  678. package/skills/review/scripts/emit-review-trailer.sh +499 -0
  679. package/skills/review/scripts/ensure-semgrep.sh +99 -0
  680. package/skills/review/scripts/fix-round-seats.sh +197 -0
  681. package/skills/review/test/emit-review-trailer.test.sh +387 -0
  682. package/skills/review/test/ensure-semgrep.test.sh +111 -0
  683. package/skills/review/test/fix-round-seats.test.sh +237 -0
  684. package/skills/review/workflows/README.md +147 -0
  685. package/skills/review/workflows/review.workflow.js +667 -0
  686. package/skills/schedule/SKILL.md +796 -0
  687. package/skills/seo-aeo/SKILL.md +139 -0
  688. package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
  689. package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
  690. package/skills/ship/SKILL.md +3022 -0
  691. package/skills/ship/references/adr-ordinal-collision.md +47 -0
  692. package/skills/ship/references/affected-gate-contract.md +115 -0
  693. package/skills/ship/references/ci-run-diagnosis.md +29 -0
  694. package/skills/ship/references/ci-workflow-authoring.md +68 -0
  695. package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
  696. package/skills/ship/references/cto-ruling-armed-push.md +5 -0
  697. package/skills/ship/references/decision-challenges-render.md +71 -0
  698. package/skills/ship/references/detached-battery-verdict.md +13 -0
  699. package/skills/ship/references/feature-tweet-draft.md +42 -0
  700. package/skills/ship/references/followthrough-issue-body-template.md +47 -0
  701. package/skills/ship/references/followthrough-stub-template.sh +92 -0
  702. package/skills/ship/references/merge-queue-dequeue.md +39 -0
  703. package/skills/ship/references/operator-holds.md +149 -0
  704. package/skills/ship/references/pipeline-tally-render.md +43 -0
  705. package/skills/ship/references/pr-overlap.md +153 -0
  706. package/skills/ship/references/queue-mode.md +7 -0
  707. package/skills/ship/references/ready-run-wait.md +36 -0
  708. package/skills/ship/references/red-on-main-quarantine.md +110 -0
  709. package/skills/ship/references/register-update-pr-pattern.md +88 -0
  710. package/skills/ship/references/settle-then-admin-merge.md +130 -0
  711. package/skills/ship/references/supabase-column-probe.md +13 -0
  712. package/skills/ship/scripts/auto-close-scan.sh +76 -0
  713. package/skills/ship/scripts/battery-owed.sh +403 -0
  714. package/skills/ship/scripts/hold-gate-eval.sh +410 -0
  715. package/skills/ship/scripts/net-issue-flow.sh +665 -0
  716. package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
  717. package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
  718. package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
  719. package/skills/skill-creator/SKILL.md +299 -0
  720. package/skills/skill-creator/references/api-security.md +248 -0
  721. package/skills/skill-creator/references/authoring-levers.md +110 -0
  722. package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
  723. package/skills/skill-creator/references/best-practices.md +431 -0
  724. package/skills/skill-creator/references/common-patterns.md +639 -0
  725. package/skills/skill-creator/references/core-principles.md +193 -0
  726. package/skills/skill-creator/references/executable-code.md +188 -0
  727. package/skills/skill-creator/references/iteration-and-testing.md +509 -0
  728. package/skills/skill-creator/references/official-spec.md +193 -0
  729. package/skills/skill-creator/references/recommended-structure.md +180 -0
  730. package/skills/skill-creator/references/skill-structure.md +396 -0
  731. package/skills/skill-creator/references/using-scripts.md +122 -0
  732. package/skills/skill-creator/references/using-templates.md +120 -0
  733. package/skills/skill-creator/references/workflows-and-validation.md +541 -0
  734. package/skills/skill-creator/scripts/init_skill.py +322 -0
  735. package/skills/skill-creator/scripts/package_skill.py +110 -0
  736. package/skills/skill-creator/scripts/quick_validate.py +64 -0
  737. package/skills/skill-creator/templates/router-skill.md +73 -0
  738. package/skills/skill-creator/templates/simple-skill.md +34 -0
  739. package/skills/skill-creator/workflows/add-reference.md +96 -0
  740. package/skills/skill-creator/workflows/add-script.md +104 -0
  741. package/skills/skill-creator/workflows/add-template.md +83 -0
  742. package/skills/skill-creator/workflows/add-workflow.md +128 -0
  743. package/skills/skill-creator/workflows/audit-skill.md +159 -0
  744. package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
  745. package/skills/skill-creator/workflows/create-new-skill.md +207 -0
  746. package/skills/skill-creator/workflows/get-guidance.md +134 -0
  747. package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
  748. package/skills/skill-creator/workflows/verify-skill.md +226 -0
  749. package/skills/skill-security-scan/SKILL.md +145 -0
  750. package/skills/skill-security-scan/references/disclaimer.md +21 -0
  751. package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
  752. package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
  753. package/skills/skill-security-scan/references/override-mechanism.md +171 -0
  754. package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
  755. package/skills/skill-security-scan/references/regex-patterns.md +136 -0
  756. package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
  757. package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
  758. package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
  759. package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
  760. package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
  761. package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
  762. package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
  763. package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
  764. package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
  765. package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
  766. package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
  767. package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
  768. package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
  769. package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
  770. package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
  771. package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
  772. package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
  773. package/skills/skill-security-scan/scripts/lib.sh +197 -0
  774. package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
  775. package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
  776. package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
  777. package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
  778. package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
  779. package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
  780. package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
  781. package/skills/social-distribute/SKILL.md +485 -0
  782. package/skills/spec-templates/SKILL.md +274 -0
  783. package/skills/sync/SKILL.md +49 -0
  784. package/skills/test-browser/SKILL.md +464 -0
  785. package/skills/test-browser/references/feature-map.md +161 -0
  786. package/skills/test-fix-loop/SKILL.md +159 -0
  787. package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
  788. package/skills/triage/SKILL.md +402 -0
  789. package/skills/trigger-cron/SKILL.md +136 -0
  790. package/skills/trigger-cron/scripts/trigger.sh +198 -0
  791. package/skills/user-set-role/SKILL.md +147 -0
  792. package/skills/user-set-role/scripts/set-role.sh +218 -0
  793. package/skills/user-story-writer/SKILL.md +77 -0
  794. package/skills/ux-audit/SKILL.md +251 -0
  795. package/skills/ux-audit/references/finding.schema.json +62 -0
  796. package/skills/ux-audit/references/route-list.yaml +95 -0
  797. package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
  798. package/skills/ux-audit/scripts/bot-signin.ts +135 -0
  799. package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
  800. package/skills/work/SKILL.md +1479 -0
  801. package/skills/work/references/end-of-work-resume.md +7 -0
  802. package/skills/work/references/hook-test-main-cwd.md +24 -0
  803. package/skills/work/references/key-principles.md +83 -0
  804. package/skills/work/references/property-testing.md +122 -0
  805. package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
  806. package/skills/work/references/work-agent-teams.md +97 -0
  807. package/skills/work/references/work-lifecycle-parallel.md +147 -0
  808. package/skills/work/references/work-lockfile-bumps.md +97 -0
  809. package/skills/work/references/work-scratch-sandboxes.md +212 -0
  810. package/skills/work/references/work-subagent-fanout.md +61 -0
  811. package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
  812. package/skills/xcode-test/SKILL.md +360 -0
@@ -0,0 +1,642 @@
1
+ ---
2
+ name: postmerge
3
+ description: "This skill should be used when verifying a merged PR deployed correctly and production is healthy."
4
+ ---
5
+
6
+ <!-- soleur-cloud-mode:start -->
7
+ **Cloud Mode (Devin):** before pipeline work run `bash "${CLAUDE_PLUGIN_ROOT}/scripts/cloud-detect.sh"`. If `CLAUDE_PLUGIN_ROOT` is unset (cloud exec shells do not export it), resolve the root by IDENTITY, never by script basename: for `d` in `"$HOME/.local/share/devin/cli/plugins/cache"` and `/opt/.devin/plugins`, skip unless `[ -d "$d" ]`, then `MANIFEST="$(find "$d" -path '*/.claude-plugin/plugin.json' -exec grep -l '"name"[[:space:]]*:[[:space:]]*"soleur"' {} + 2>/dev/null | head -1)"`, `ROOT="${MANIFEST%/.claude-plugin/plugin.json}"` — one resolution, two consumers: `$ROOT/scripts/cloud-detect.sh` and `$ROOT/scripts/precommit-guard.sh`. (Shape check, not authentication: a planted `{"name":"soleur"}` dir passes — ADR-179 A11.) `local` or `not-local:no-devin-env` proceeds normally; any other `not-local:<reason>` applies `<plugin-root>/devin/INSTRUCTIONS.md` §Cloud Mode: emit the `--banner`, fan out sequentially with `Reviewed-Coverage: sequential-fallback` disclosure (never claim an independent review ran), `message_user` ack before any secrets read or production mutation, and run `precommit-guard.sh` before any `git commit` — hooks do not fire in cloud.
8
+ <!-- soleur-cloud-mode:end -->
9
+
10
+ <!-- grok-harness-invoke:start -->
11
+ **Grok Build (`plugins/soleur/lib/harness.ts` `invokeSkill()`):** Read this SKILL.md in this process and run it to completion. A one-segment `soleur:<name>` in this document names a SKILL — on Grok Build, Read `plugins/soleur/skills/<name>/SKILL.md` in this process; it is not a nested tool_use. A multi-segment id such as `soleur:<domain>:<name>` names an AGENT: spawn it, never Read it, and on Grok Build spawn_subagent takes the id with its colons replaced by hyphens (`agentIdToGrokSubagentType`). **Claude Code:** Skill tool for a skill (`soleur:<name>`), Task tool with `subagent_type` for an agent. Forbidden is executing a subset, not the Read.
12
+ <!-- grok-harness-invoke:end -->
13
+
14
+ # postmerge Skill
15
+
16
+ <!-- postmerge-harness-protocol:start -->
17
+ ## Harness adapter (Claude vs Grok Build)
18
+
19
+ Invoke via **Claude:** `soleur:postmerge <PR>` | **Grok:** `soleur:postmerge <PR>`.
20
+
21
+ **Polling CI / health checks without asking the operator:**
22
+
23
+ - **Claude Code:** Monitor tool for Phase 2 main CI and Phase 3 health retries.
24
+ - **Grok Build:** AwaitShell with `pattern` (`completed success`, `postmerge verification complete`) or Shell with `block_until_ms`.
25
+
26
+ Canonical: `plugins/soleur/lib/harness.ts` → `pollInstructions()`. Parent skills (`ship` Step 3.8, `one-shot` Step 8) MUST invoke postmerge before `<promise>DONE</promise>`.
27
+ <!-- postmerge-harness-protocol:end -->
28
+
29
+ **Purpose:** Enforce post-merge verification so bugs that only appear in production context are caught immediately after merge -- not days later. This closes the "last mile" gap where QA passes locally but production diverges (stale files, unapplied migrations, CSP violations from injected scripts).
30
+
31
+ **CRITICAL: No command substitution.** Never use `$()` in Bash commands. When a step says "get value X, then use it in command Y", run them as **two separate Bash tool calls** -- first get the value, then use it literally in the next call.
32
+
33
+ ## Arguments
34
+
35
+ `$ARGUMENTS` should contain the PR number. If omitted, detect from the most recently merged PR on the current branch.
36
+
37
+ ## Phase 1: Verify PR is Merged
38
+
39
+ Confirm the PR reached MERGED state:
40
+
41
+ ```bash
42
+ gh pr view <number> --json state,mergeCommit,headRefName --jq '{state, mergeCommit: .mergeCommit.oid, branch: .headRefName}'
43
+ ```
44
+
45
+ If state is not `MERGED`, stop:
46
+
47
+ ```text
48
+ STOPPED: PR #<number> is not merged (state: <state>). Run soleur:merge-pr first.
49
+ ```
50
+
51
+ Record the merge commit SHA for later verification.
52
+
53
+ ## Phase 2: Wait for CI on Main
54
+
55
+ Check the latest CI run on main triggered by the merge:
56
+
57
+ ```bash
58
+ gh run list --branch main --limit 3 --json databaseId,status,conclusion,headSha
59
+ ```
60
+
61
+ Find the run matching the merge commit SHA. If no matching run yet, poll with the harness adapter (max 5 minutes) — **Claude:** Monitor tool; **Grok:** AwaitShell/Shell per `pollInstructions()`. Do NOT ask the operator to watch CI. Do NOT use Bash `run_in_background`:
62
+
63
+ ```bash
64
+ for i in $(seq 1 20); do
65
+ result=$(gh run view <run-id> --json status,conclusion --jq '{status, conclusion}')
66
+ echo "$(date +%H:%M:%S) $result"
67
+ echo "$result" | grep -q '"completed"' && break
68
+ sleep 15
69
+ done
70
+ ```
71
+
72
+ React to the final status from the Monitor output.
73
+
74
+ **If CI passes:** Proceed to Phase 3.
75
+
76
+ **If CI fails:** Report the failure with details:
77
+
78
+ ```bash
79
+ gh run view <run-id> --log-failed 2>&1 | tail -50
80
+ ```
81
+
82
+ Ship refuses post-deploy actions on `CI=failure` too. Still run Phase 3's `find`: a `MATCH=descendant DEPLOY=success` line means production carries the merge via `<DEPLOYED_SHA>` — say so.
83
+
84
+ Stop:
85
+
86
+ ```text
87
+ STOPPED: CI failed on main after merge.
88
+
89
+ Run ID: <run-id>
90
+ Conclusion: <conclusion>
91
+
92
+ Failed log tail:
93
+ <last 50 lines>
94
+
95
+ Investigate before proceeding. The merge is complete but production may not deploy.
96
+ ```
97
+
98
+ ## Phase 3: Verify Production Deployment
99
+
100
+ Check if a health endpoint is configured. Look for deployment URLs in environment or project config:
101
+
102
+ ```bash
103
+ # Check for DEPLOY_URL or PRODUCTION_URL in environment
104
+ echo "${DEPLOY_URL:-not_set}"
105
+ echo "${PRODUCTION_URL:-not_set}"
106
+ ```
107
+
108
+ If a production URL is available, verify the deployment:
109
+
110
+ ```bash
111
+ curl -sf --max-time 10 "<production-url>/health" | jq .
112
+ ```
113
+
114
+ Use `/health` (the public, middleware-/CSP-bypassed health route returning `{"status":"ok","version","build_sha","supabase","sentry",...}`), NOT `/api/health` — the latter is an authenticated API route that 307-redirects an unauthenticated probe to `/login`, so `curl -sf` fails and `HEALTH_VERIFIED` is left `false` even when production is healthy. For this repo, `build_sha` is judged by `deploy-arm.sh` below.
115
+
116
+ **This repo (`web-platform-release.yml` present):** identify the deploy and what production serves, with literal arguments (no command substitution) and the FULL 40-hex merge sha (a short one matches nothing, #8135). First wait for `find` — it polls about once a minute for up to 120 polls and prints one line; watch it with the harness poller (**Claude:** Monitor tool, matching `^ARM=`; **Grok:** AwaitShell), never Bash `run_in_background`. Only once that line has arrived with rc ≠ 4, run `served`:
117
+
118
+ ```bash
119
+ bash plugins/soleur/scripts/deploy-arm.sh find --wait <full-merge-sha>
120
+ bash plugins/soleur/scripts/deploy-arm.sh served <full-merge-sha>
121
+ ```
122
+
123
+ First matching row wins:
124
+
125
+ | `find` | `served` | result |
126
+ |---|---|---|
127
+ | any | `UNRESOLVED` | could-not-measure, never a mismatch |
128
+ | rc 2 (`REASON=error`) | any | could-not-measure; report `CAUSE` |
129
+ | `DEPLOY=skipped` | any | not deployed by design (`CI=failure` → CI red, Phase 2) |
130
+ | `DEPLOY=success\|superseded`, or rc 3 `ARM=none` (incl. `timeout`) | `CONTAINS` | verified — `MATCH=descendant`/`superseded`/`ARM=none` mean a later deploy (or a manual redeploy) delivered it |
131
+ | `DEPLOY=failure\|blocked` | `CONTAINS` | verified via a later deploy; still report this merge's own failed deploy and name the job |
132
+ | any other | `NOT_CONTAINED` | not verified — report the `find` line; if it said `DEPLOY=success`, production does not serve the merge (lagging host or rollback): report prominently |
133
+
134
+ **If health check succeeds:** HTTP 200 alone is NOT success — `/health` returns 200 with `status: "ok"` whatever the database state, and only `.supabase` flips to `"error"`. Require `jq -e '.supabase == "connected"'` (and, here, the table above) before recording the response and setting `HEALTH_VERIFIED=true`. A 200 with `supabase: "error"` is a production database outage: set `HEALTH_VERIFIED=false`, report it prominently, and diagnose per §Production Debugging (2026-09-15 post-mortem `prd-supabase-database-unreachable-2026-09-15-postmortem.md`).
135
+
136
+ **If health check fails or no URL configured:** set `HEALTH_VERIFIED=false`, warn, and proceed (not all PRs trigger deployments):
137
+
138
+ ```text
139
+ WARNING: No production health check available. Skipping deployment verification.
140
+ ```
141
+
142
+ `HEALTH_VERIFIED` is the explicit signal Phase 3.8 gates the feature-tweet draft
143
+ on — a ship tweet must only be drafted for a feature confirmed live. Track it as
144
+ a literal `true`/`false`; do NOT infer "verified" from "reached this line" (the
145
+ warn-and-proceed branch also falls through to the next phase).
146
+
147
+ ## Phase 3.5: Sentry Cron Monitor Health
148
+
149
+ Verify scheduled functions are healthy post-deploy by querying Sentry cron monitors.
150
+
151
+ **Prerequisites:** `SENTRY_AUTH_TOKEN` (or `SENTRY_API_TOKEN` fallback) must be available. If missing, warn and skip:
152
+
153
+ ```text
154
+ WARNING: SENTRY_AUTH_TOKEN not set. Skipping Sentry health verification.
155
+ ```
156
+
157
+ Query cron monitors:
158
+
159
+ ```bash
160
+ SENTRY_TOKEN=$(doppler secrets get SENTRY_AUTH_TOKEN -p soleur -c prd --plain 2>/dev/null || \
161
+ doppler secrets get SENTRY_API_TOKEN -p soleur -c prd --plain)
162
+ SENTRY_ORG=$(doppler secrets get SENTRY_ORG -p soleur -c prd --plain 2>/dev/null || echo "jikigai")
163
+ API_HOST="${SENTRY_ORG}.sentry.io"
164
+
165
+ # argv shows in /proc/<pid>/cmdline, so the token rides curl's stdin config. Bash only; `bash -x` would print the token.
166
+ # Advisory phase: a missing or malformed token SKIPS (exit 0), it never fails the run.
167
+ if ! (LC_ALL=C; case "$SENTRY_TOKEN" in ''|*[!A-Za-z0-9._~+/=-]*) exit 1;; esac); then
168
+ echo "WARNING: SENTRY_TOKEN (Doppler prd SENTRY_AUTH_TOKEN or SENTRY_API_TOKEN) unset or not [A-Za-z0-9._~+/=-] (refused, not sent). Sentry cron monitor health: SKIPPED."
169
+ else
170
+ curl --disable --proto '=https' -m 30 -fsS --config - \
171
+ "https://${API_HOST}/api/0/organizations/${SENTRY_ORG}/monitors/?per_page=100" \
172
+ < <(printf 'header = "Authorization: Bearer %s"\n' "$SENTRY_TOKEN") \
173
+ | jq '[.[] | {slug: .slug, status: .status}] | map(select(.status != "ok" and .status != "active"))'
174
+ fi
175
+ ```
176
+
177
+ - If all monitors report `ok` or `active`: "Sentry cron monitors: all healthy"
178
+ - If any monitor reports `error` or `missed`: flag with monitor name and status. This is a WARNING, not a blocker — the monitor may have been unhealthy before this deploy.
179
+ - If Sentry API is unreachable or returns non-200: warn and skip (do not block on Sentry outages).
180
+
181
+ **Graceful degradation:** This check is advisory. A Sentry API failure does not block the postmerge pipeline.
182
+
183
+ ### Inngest liveness awareness (#6374)
184
+
185
+ Surface any OPEN inngest-down alarm so the operator is never told "prod is healthy" while the durable trigger layer (armed reminders + all `server/inngest/functions/` crons) is dark. The external watchdog (`scheduled-inngest-health.yml`) files `[ci/inngest-down]` on a confirmed down; this is a cheap read that needs no Sentry token:
186
+
187
+ ```bash
188
+ gh issue list --label ci/inngest-down --state open \
189
+ --json number,title,createdAt --jq '.[] | "#\(.number) \(.title) (opened \(.createdAt))"'
190
+ ```
191
+
192
+ - If it prints an open issue: surface a one-line advisory — "ADVISORY: inngest reports down (`#<n>`) — armed reminders and scheduled crons may not be firing; the external watchdog is auto-restarting / escalating. Do not assume scheduled work ran." Include it prominently in the Phase 7 report.
193
+ - If empty: silent (no line needed).
194
+
195
+ **Advisory only — never hard-block the turn.** inngest-down does not block all work; the operator retains agency. (An optional deeper probe — `curl` the `/hooks/inngest-liveness` HMAC+CF-Access hook — is available for a live verdict but is not required here; the open-issue read is the cheap default.)
196
+
197
+ ## Phase 3.6: Sentry Error-Count Delta (Fix Efficacy)
198
+
199
+ A merged-and-deployed fix can pass every gate above and still not work — the deploy is healthy, monitors are alive, files are fresh, but the error keeps firing because the fix addressed the wrong root cause (the KB-sync / oauth-probe failure class). Phase 3.5 proves the *monitor* is alive; this phase asks the harder question: **did the error this PR claims to fix actually stop?**
200
+
201
+ **Run only when** the PR body or linked issue names a specific Sentry issue (a `*.sentry.io/issues/<id>` URL, a `SENTRY-<SHORTID>`, or a `Closes #N` whose issue references one). If no Sentry issue is identified, skip silently — there is no error to measure.
202
+
203
+ When a Sentry issue is identified, read [sentry-error-count-delta.md](./references/sentry-error-count-delta.md) now and run it; otherwise skip silently. It holds the prerequisites, the issue GET, the interpretation and the guarded auto-resolve PUT.
204
+
205
+ Report vocabulary for this phase (Phase 7 reads it): `AUTO-RESOLVED` (write succeeded) / `STOPPED` (stopped firing, no token or already resolved) / `STILL-FIRING` / `SKIPPED`. All outcomes are WARN-only, never a merge blocker.
206
+
207
+ ## Phase 3.7: First-Deploy-After-Pipeline-Change Watch
208
+
209
+ Enforces `wg-dark-launch-deploy-gates`. A change to deploy-*gating* logic cannot be validated by the same deploy it gates: if the changed gate is itself broken, the *first* post-merge deploy rolls back, and the rollback looks like a bad app deploy rather than a bad gate. This phase makes that case explicit so the gating change — not the app — is suspected first.
210
+
211
+ **Trigger (skip the phase if none match).** Check whether the merged PR touched deploy-gating logic:
212
+
213
+ ```bash
214
+ # Did this PR change a gate that can roll back / block a deploy?
215
+ gh pr diff <number> --name-only | grep -qE 'apps/web-platform/infra/ci-deploy\.sh|apps/web-platform/infra/ci-deploy-wrapper\.sh' && PIPELINE_GATE_CHANGE=1
216
+ # Also treat changes to the gating phases of the ship/postmerge skills as pipeline-gate changes.
217
+ gh pr diff <number> --name-only | grep -qE 'plugins/soleur/skills/(ship|postmerge)/SKILL\.md|plugins/soleur/scripts/deploy-arm\.sh' && PIPELINE_GATE_CHANGE=1
218
+ ```
219
+
220
+ If `PIPELINE_GATE_CHANGE` is unset, skip to Phase 4.
221
+
222
+ **Watch the first post-merge release run** (the one Phase 2/3 already identified) for a canary rollback.
223
+
224
+ **Select the DEPLOY arm, not "the latest run".** Since #5806 / ADR-217 `web-platform-release.yml` is split across two triggers, so every merge produces **two** runs of it:
225
+
226
+ | arm | trigger | jobs |
227
+ |---|---|---|
228
+ | push arm | `on: push` to `main` | `release` only (build + publish) |
229
+ | deploy arm | `on: workflow_run` (CI completed) | `resolve-target`, `migrate`, `verify-migrations`, `verify-doppler-secrets`, `deploy`, `live-verify`, `notify-gated`, `release-outcome` |
230
+
231
+ `--limit 1` with no event filter lands on the push arm roughly half the time, where `deploy` exists only as a `skipped` job — a false green against an empty log. **Identify the deploy arm by what its `resolve-target` checks out, never by `head_sha`:** a `workflow_run` run's `head_sha` is `main`'s tip when it fired, so a `head_sha=<merge>` query misses your arm on a busy `main` (#8297) and returns the previous merge's arm (#8391). `deploy-arm.sh find` reads each candidate's checked-out SHA and accepts your merge or a descendant (#8492).
232
+
233
+ Reuse Phase 3's `find` line (run `bash plugins/soleur/scripts/deploy-arm.sh find <full-merge-sha>` if Phase 3 did not). Copy the digits after `ARM=` literally into the next call; `ARM=none` means there is no run — never pass `none` to `gh run view`. Rollback reason:
234
+
235
+ ```bash
236
+ gh run view <ARM digits> --log 2>/dev/null | grep -oE 'reason=(canary_sandbox_failed|production_start_failed|canary_[a-z_]+)' | head -1
237
+ ```
238
+
239
+ **A green `live-verify` is not evidence it ran:** it can be `success` with the harness and every
240
+ substantive step `skipped` by its changed-file gate — read the step list. **Probe
241
+ `app.soleur.ai/health`** (`web-platform-release.yml:1288`); the apex returns an EMPTY body —
242
+ could-not-measure, reported UNRESOLVED, never a mismatch. **Why:** #8265, #8297, #8391 — each a
243
+ selector that returned another merge's arm, or none, while the real arm had deployed.
244
+
245
+ **Interpretation** (by `MATCH` and `DEPLOY`):
246
+
247
+ - `exact` + `success` → `GATE-VALIDATED`. `descendant` + `success` → `GATE-VALIDATED (via <DEPLOYED_SHA>, run <ARM>)`.
248
+ - `DEPLOY=skipped` → `GATE-NOT-EXERCISED`: the arm clean-skipped (docs-only; `CI=failure` → `ci_not_green`) — the `workflow_run` trigger inherits neither `on.push.paths` nor `check_changed` (ADR-217). Neither a failure nor a validation; the watch stays open until a merge that deploys.
249
+ - `DEPLOY=superseded|blocked` → `GATE-INDETERMINATE — <DEPLOY>` (lock-queue cancellation; a resolve/migrate/verify job failed).
250
+ - `DEPLOY=blocked` from `resolve-target`: read its reason, which the annotation carries (job outputs are not readable through the API): `gh run view <ARM> --json jobs --jq '.jobs[] | select(.name=="resolve-target") | .databaseId'`, then `gh api repos/jikig-ai/soleur/check-runs/<id>/annotations --jq '.[].message'` and match `[skip_reason=<reason>]`. For `release_run_missing` or `github_api_unavailable` (a lookup failure, not a broken release) recover yourself: `gh run rerun <ARM> --failed` once, then re-arm `deploy-arm.sh find --wait`; if it fails the same way, wait ~15 minutes and retry once more. Never re-run the push-arm run. Any other reason (`release_failed`, `identity_mismatch`, `schema_mismatch`, …) is not a re-run case — report it.
251
+ - rc 2/3 `ARM=none` (incl. `timeout`, `error`) → `GATE-INDETERMINATE — <REASON> <CAUSE>`: absence of evidence, never a pass. rc 4 → still pending; poll.
252
+ - `descendant` + `failure` → `GATE-SUSPECT`: list `git log --oneline <merge>..<DEPLOYED_SHA>` beside this PR's gate diff — the failure may be the later merge's, so do not recommend an immediate revert.
253
+ - `exact` + `failure` with a canary/sandbox rollback reason AND this PR changed gating logic: **suspect the gate, not the app.** A gating check that diverged from production reality (e.g. a synthetic probe that does not match what runs in prod) blocks every deploy. Recommended action: **revert the gating change immediately** (it is unvalidated by definition — its first real deploy rolled back), restore the prior known-good gate, and re-deploy; investigate the probe separately and re-introduce it NON-BLOCKING per `wg-dark-launch-deploy-gates`. Report `GATE-SUSPECT — revert recommended` and surface it at the top of the Phase 7 report.
254
+ - Release failed with a non-gate reason (build, migration, unrelated infra): ordinary deploy failure — investigate normally; do not assume the gate.
255
+
256
+ **Why a watch and not a pre-merge block:** the only faithful validation of a deploy gate is a real deploy, which by definition happens post-merge. The pre-merge half of the rule — ship the gate non-blocking first — lives in `wg-dark-launch-deploy-gates`; this phase is the safety net that catches a gate shipped blocking-first anyway, turning "every deploy silently rolls back" into a named, one-revert recovery. **Why:** #4932 — a canary bwrap probe validated only against an always-succeeding test mock failed on a healthy host and rolled back every web-platform deploy until reverted (#4941).
257
+
258
+ ## Phase 3.8: Feature-Tweet Draft (verify + display)
259
+
260
+ The draft is now generated **pre-merge by `soleur:ship`** (Phase 6 "Feature-Tweet
261
+ Draft (pre-merge bundle)") and committed to the feature branch, so for the
262
+ normal `soleur:one-shot` / `soleur:ship` flow it ALREADY landed on `main` with this PR —
263
+ where `content-publisher.sh` reads from. This phase **verifies** that on-`main`
264
+ draft, **displays** it for approval, and warns when deploy health is unverified.
265
+ It only *generates* a draft as a catch-up when `soleur:ship` was hand-rolled and the
266
+ draft never landed.
267
+
268
+ ```bash
269
+ bash scripts/lib/tweet-eligibility.sh <merged-pr-number>
270
+ ```
271
+
272
+ Branch on eligibility, then on whether the draft is already on `main`:
273
+
274
+ - **Ineligible** (exit non-zero, `excluded: <reason>`) → **silent no-op.** Most
275
+ PRs land here (fixes, infra, non-product); exclusion is the designed outcome,
276
+ not a fault. Do not surface it in the report.
277
+ - **Eligible AND a draft for this PR is on `main`** (the `soleur:ship` pre-merge
278
+ bundle worked — detect via
279
+ `git grep -l 'pr_reference: "#<merged-pr-number>"' origin/main -- knowledge-base/marketing/distribution-content/`):
280
+ **display the draft's full content** (title + every X tweet + the Bluesky
281
+ post) inline for operator approval — read it back from `main`
282
+ (`git show origin/main:<path>`), never reproduce from memory. Then:
283
+ - `HEALTH_VERIFIED=true` → operator instruction: "the draft is on `main`; set
284
+ BOTH `publish_date` and `status: scheduled` to publish."
285
+ - `HEALTH_VERIFIED=false` → **warn, do not block:** "the draft is on `main`
286
+ but production health was NOT verified — do NOT set `status: scheduled`
287
+ until you confirm the deploy is live." (The draft is inert until then.)
288
+
289
+ The display-for-approval contract is owned by `feature-tweet` SKILL.md
290
+ §Output; the path alone is insufficient (the operator cannot approve copy they
291
+ cannot see).
292
+ - **Eligible BUT no draft on `main`** (a hand-rolled `soleur:ship` skipped the
293
+ pre-merge bundle) → catch-up: invoke the draft generator, display it, and note
294
+ it needs a follow-up commit to reach `main`:
295
+
296
+ ```
297
+ soleur:feature-tweet #<merged-pr-number>
298
+ ```
299
+
300
+ > Eligible PR #N had no feature-tweet draft on `main` (the `soleur:ship` pre-merge
301
+ > bundle was skipped). Generated a catch-up draft — commit it to `main` via a
302
+ > follow-up PR so `content-publisher.sh` can drain it, then set both
303
+ > `publish_date` and `status: scheduled` once the deploy is confirmed.
304
+
305
+ **Multi-PR contract (explicit v1):** one tweet per eligible PR, using postmerge's
306
+ single bound PR number. If a deploy bundled multiple PRs, only the bound PR is
307
+ drafted — note in the Phase 7 report that other eligible PRs need the standalone
308
+ catch-up path. `soleur:merge-pr`-only flows bypass this hook by design; the
309
+ recovery is standalone `soleur:feature-tweet #N`.
310
+
311
+ ## Phase 4: Verify File Freshness
312
+
313
+ Read key files from the merged commit to verify they match expectations -- NOT from the bare repo filesystem which may contain stale content.
314
+
315
+ For each file changed in the PR:
316
+
317
+ ```bash
318
+ gh pr diff <number> --name-only
319
+ ```
320
+
321
+ **Fetch first.** The merge commit was created on the remote; nothing pulls it into a
322
+ local worktree as a side effect of the merge, so run `git fetch origin main` before the
323
+ first `git show`. Skipping this produces a false MISSING on every spot-checked file —
324
+ see the two-message table below, which is the tell.
325
+
326
+ Spot-check up to 5 files by reading from **the merge commit recorded in Phase 1** — not from the `main` ref:
327
+
328
+ ```bash
329
+ git fetch origin main
330
+ git show <merge-commit-sha-from-phase-1>:<filepath>
331
+ ```
332
+
333
+ **Read the failure message precisely — two of them are one word apart and mean opposite
334
+ things.** Measured against a real merge commit, with an all-zeros SHA as the control:
335
+
336
+ | message | what it actually means |
337
+ |---|---|
338
+ | `fatal: path 'X' does not exist in '<sha>'` | genuine answer: the file is NOT in that tree |
339
+ | `fatal: path 'X' exists on disk, but not in '<sha>'` | **git does not have that object** — it never read a tree |
340
+
341
+ The second is not a statement about the merge's contents. It is what git prints when the
342
+ commit is unknown to this repository, and it names the path anyway, so it reads exactly
343
+ like a content verdict. If Phase 4 reports files MISSING with that second wording, you
344
+ have an unfetched commit, not a bad merge — fetch and re-run before reporting anything.
345
+
346
+ **Query `actions/runs?head_sha=` with the FULL 40-char SHA, and refuse a verdict when `total_count` is below the
347
+ runs you expect.** A short SHA matches zero runs, and a poll that reports "0 pending" over an empty set reads as
348
+ `ALL_RUNS_COMPLETE` — a set must be proven non-empty before it can be reported drained. **Why:** PR #8135 — a
349
+ 9-char `head_sha` returned `total_count:0` on the first tick and the Monitor declared all 15 post-merge runs
350
+ complete before any had started.
351
+
352
+ **Do NOT use `git show main:<path>` here.** `main` is a LOCAL ref and it lags: in a worktree or bare-repo layout nothing fast-forwards it as a side effect of the merge, so it routinely points at a commit from before this PR landed. Reading a file that this PR ADDED through a stale `main` returns `fatal: path ... does not exist`, and the phase whose entire job is answering *"did the merge land?"* then reports **MISSING** for a file that is present in the merge commit. The failure is silent and inverted — it manufactures a false alarm about the thing it is verifying, and it gets worse the busier the repo is.
353
+
354
+ `git rev-parse --short main` next to `git rev-parse --short origin/main` is the cheap tell when a result looks wrong. Prefer the merge SHA unconditionally: it is immutable, it is the exact tree that merged, and it cannot drift while the phase runs. `origin/main` is an acceptable second choice only immediately after a fetch, and even then a sibling merge can move it mid-phase.
355
+
356
+ Compare against expectations from the PR description and review. Flag if any file content seems stale or doesn't reflect the PR changes. **Why:** PR #7240 — Phase 4 read `git show main:` while local `main` sat 2 commits behind, reported the PR's own new learning file as MISSING, and the same stale ref undercounted `blkid` occurrences 2-vs-8 in a file the PR had rewritten. **And PR #7770** — Phase 4 addressed the merge SHA correctly, as the paragraphs above instruct, and still reported all 5 spot-checked files MISSING: the worktree had not fetched the merge commit, and git's `exists on disk, but not in <sha>` wording was read as a verdict about the tree. One `git fetch` made all 5 read correctly. Both failures are the same shape — Phase 4 manufacturing a false alarm about the merge it exists to confirm — reached by two different routes, which is why the fetch and the message table above are both load-bearing.
357
+
358
+ ## Phase 5: Browser Verification (Conditional)
359
+
360
+ **Skip if:** The PR has no UI changes (no `.tsx`, `.css`, `.html` files in the diff).
361
+
362
+ **If UI changes exist:**
363
+
364
+ 1. Start the dev server if not running (or use the production URL if available)
365
+ 2. Use Playwright MCP to navigate to affected pages
366
+ 3. Take screenshots of key states
367
+ 4. Check browser console for errors (especially CSP violations)
368
+ 5. Verify no broken resources or layout regressions
369
+
370
+ If Playwright MCP is unavailable, do NOT warn-and-skip — **fall through to the
371
+ committed harness path** (Phase 5.5 below), which drives the deployed app via the
372
+ chromium bundled in `@playwright/test` with no MCP-browser dependency. The
373
+ warn-and-skip punt is exactly what let the #5391/#5421/#5436 broken fixes pass
374
+ green. Record `Browser verification: DELEGATED-TO-LIVE-VERIFY` and proceed.
375
+
376
+ ## Phase 5.5: Live Verification (path-triggered; BLOCKING in CI)
377
+
378
+ Verifies the **deployed artifact** for the PR classes where the mock-hermetic e2e
379
+ suite structurally lies (realtime / server-commit-timing / session-auth /
380
+ DOM-server-timing — the #5391→#5421→#5436 class). The harness
381
+ (`apps/web-platform/scripts/live-verify/run.ts`, #5452 / ADR-064) signs in as a
382
+ dedicated **synthetic prod principal** (never an operator/real-user session),
383
+ drives the deployed UI, and asserts a freshly-started conversation appears in the
384
+ Recent Conversations rail.
385
+
386
+ **Gate posture: BLOCKING, enforced in CI (#5463, PR #5576).** The authority is the `live-verify` job in `.github/workflows/web-platform-release.yml`: its "Enforce live-verify gate" step fails the release run when the emit step computes `BLOCK=1` (a `FAIL`, an empty result line, or `CANT-RUN:cannot-spend-violated`). `CANT-RUN:cannot-spend-unverified` (the I-cannot-spend check could not read its inputs) is annotated `::error` but BLOCK=0, because the throw before the browser launch already delivers the safety property. Re-derive gate state from that workflow, not from this prose. This skill's own harness run (below) is separate evidence for the report and does not decide the release; a boolean flip inside this skill is NOT the gate (the #4932 non-deterministic-blocking-gate class).
387
+
388
+ **What a PASS does and does not prove.** The harness refuses to run unless the synthetic principal holds no decryptable credential (ADR-064 `I-cannot-spend`, in `verifyPrincipal`, also under `--dry-run`). `RESULT: PASS` means ONE flow worked against the deployed app: a fresh conversation appeared in the Recent Conversations rail. It does not attest the real CONNECT path or Squid `%un` egress attribution (`I-egress-not-attested-by-gate`) and generates no Concierge traffic. **A green `live-verify` job is not a PASS:** SKIPPED and every environmental `CANT-RUN` leave it green, so only the `RESULT: PASS` line counts and anything else is UNVERIFIED. When a check needs traffic the gate cannot generate, do not ask the operator to start a session: record `Live verification: UNVERIFIED:<capability>` and reference #10460 / #10461 (see `flag-set-role` §"Verifying a flip"). The job runs after each successful deploy (`workflow_run`) but its harness step is diff-gated on `trigger-paths.txt`, and a flag flip is not a commit, so a flip starts nothing; the flip and rollback stay operator-typed (ADR-249).
389
+
390
+ **1. Path trigger (FR7).** The trigger set is the committed source-of-truth
391
+ `apps/web-platform/scripts/live-verify/trigger-paths.txt` (not SKILL.md prose).
392
+ Reuse Phase 4's changed-file list and match:
393
+
394
+ ```bash
395
+ changed=$(gh pr diff <number> --name-only)
396
+ patterns=$(grep -vE '^[[:space:]]*#|^[[:space:]]*$' \
397
+ apps/web-platform/scripts/live-verify/trigger-paths.txt)
398
+ if printf '%s\n' "$changed" | grep -qE -f <(printf '%s\n' "$patterns"); then
399
+ TRIGGERED=1
400
+ else
401
+ TRIGGERED=0 # pure logic/docs/copy/config → skip (fail-open; the drift
402
+ # canary test guards against an un-listed new realtime dir)
403
+ fi
404
+ ```
405
+
406
+ If `TRIGGERED=0`: record `Live verification: SKIPPED (no triggering paths)` and
407
+ continue to Phase 6.
408
+
409
+ **2. Run the harness.** The harness needs Doppler `prd` secrets
410
+ (`LIVE_VERIFY_USER_PASSWORD`, `LIVE_VERIFY_EXPECTED_UID/REF`, the Supabase
411
+ anon-key, `PRODUCTION_URL`). It is service-role-free (AC2b) and message-minimal
412
+ (I-action-send-free). Run from the app dir under `prd`:
413
+
414
+ ```bash
415
+ cd apps/web-platform && \
416
+ doppler run -p soleur -c prd -- bun run scripts/live-verify/run.ts \
417
+ 2>&1 | grep -E '^RESULT: '
418
+ ```
419
+
420
+ **Runner browser (#5485).** If this host's OS does not support the bundled
421
+ `@playwright/test` chromium (`chromium.launch()` → `CANT-RUN:browser-launch:…`),
422
+ prepend a system-browser override — `LIVE_VERIFY_BROWSER_CHANNEL=chrome` (or
423
+ `LIVE_VERIFY_BROWSER_PATH=/path/to/chrome`) — to the `doppler run` line. Unset on
424
+ ubuntu-latest (bundled chromium works); see ADR-064 §"Runner browser + cookie
425
+ shape". The blocking substrate is the GitHub Actions job (#5463 item 3), not this
426
+ override.
427
+
428
+ The harness emits exactly one structured line: `RESULT: PASS`,
429
+ `RESULT: FAIL — <redacted detail>`, or `RESULT: CANT-RUN:<reason>`. Empty output
430
+ is treated as `CANT-RUN:no-result-line` (fail-closed semantics for the result
431
+ *recording*; CI independently blocks on a missing result line). If the harness
432
+ cannot bootstrap (synthetic principal not yet seeded — see
433
+ `apps/web-platform/scripts/bootstrap-live-verify.sh`), expect `CANT-RUN:CONFIG:…`.
434
+
435
+ **3. Record + surface the tri-state.** Always surface the result; never silently
436
+ drop it:
437
+
438
+ - `PASS` → record `Live verification: PASS`.
439
+ - `FAIL` → record `Live verification: FAIL — <detail>` and **surface prominently**
440
+ (this is the regression the gate exists to catch). The CI job has already
441
+ blocked the release run on a FAIL; report what it concluded.
442
+ - `UNVERIFIED:<capability>` is not a harness result: record it when a check needs traffic the
443
+ gate cannot generate, or when CI's verdict is SKIPPED or a `CANT-RUN` (see the PASS caveat
444
+ above). It reuses #10460 / #10461; a failed LOCAL harness run below still files its own issue.
445
+ - `CANT-RUN:<reason>` → record `Live verification: CANT-RUN:<reason>` and
446
+ **auto-file a tracking issue** (`wg-when-deferring-a-capability-create-a`):
447
+
448
+ ```bash
449
+ gh issue create --label type/chore \
450
+ --title "live-verify CANT-RUN: <reason> (PR #<number>)" \
451
+ --body "deferred-automation backlog item; the live-verify harness could not complete.
452
+ reason: <reason>
453
+ re-evaluate when: synthetic principal seeded / deploy URL reachable / teardown invariant restored.
454
+ Tracks the live-verify gate (blocking in CI since #5463)."
455
+ ```
456
+
457
+ A `CANT-RUN:CANT-TEARDOWN-has-action-sends` reason is an invariant breach (the
458
+ synthetic principal acquired a WORM `action_sends` row) — escalate it, do NOT
459
+ reap-next-run.
460
+
461
+ ## Phase 5.6: Registry-host delivery verdict (path-triggered, REPORT-ONLY)
462
+
463
+ When the merged diff touched `apps/web-platform/infra/cloud-init-registry.yml` or
464
+ `.github/workflows/registry-host-replace-dispatch.yml`, the merge fired the
465
+ registry-host-replace dispatcher (#7555, #8279), and its verdict is the delivery's
466
+ own record — read it rather than inferring delivery from a green merge:
467
+
468
+ ```bash
469
+ run=$(gh run list --workflow=registry-host-replace-dispatch.yml --branch main --limit 1 \
470
+ --json databaseId,conclusion --jq '.[0] | "\(.databaseId) \(.conclusion)"')
471
+ gh run view "${run%% *}" --log | grep -E 'Z (range|prs|summary|targets)=|Z Nothing since the watermark'
472
+ gh api --paginate --slurp "repos/jikig-ai/soleur/issues/<number>/comments?per_page=100" \
473
+ | jq -r '[.[][] | select(.body | test("<!-- registry-delivery run=[0-9]+ kind="))] | last | .body // "no verdict"'
474
+ ```
475
+
476
+ `deliver=false` (a registration-only or comment-only push) and a green run with no verdict is
477
+ the expected case. Any `kind=` other than none is reported verbatim with the runbook's next
478
+ action (`knowledge-base/engineering/operations/runbooks/registry-host-replace-dispatch.md`);
479
+ this phase reports, it does not block "done".
480
+
481
+ ## Phase 5.7: Sole-copy protection read-back (path-triggered, REPORT-ONLY)
482
+
483
+ When the merged PR touched `apps/web-platform/infra/inngest-redis-luks.tf` (`gh pr diff <number> --name-only`), the merge's
484
+ per-merge apply is what delivers the Hetzner delete protection on the Inngest sole-copy volume (#9879, ADR-282), so a green
485
+ merge proves nothing about it. Otherwise record `Sole-copy read-back: SKIPPED (no triggering paths)` and continue. This phase
486
+ reports; it never dispatches a production apply on its own.
487
+
488
+ 1. **Derive the expected word** (never hard-code it): `git fetch origin main`, then
489
+ `git show <merge-sha>:apps/web-platform/infra/inngest-redis-luks.tf` and read `delete_protection` on
490
+ `hcloud_volume.inngest_redis_luks`. `true` expects `protected`, `false` expects `not-protected`. The sanctioned lift PR
491
+ (runbook break-glass step 1, deliberate unprotect step 1) expects `not-protected` and is NOT a failure. Report a
492
+ mismatch only.
493
+ 2. **Find the merge-SHA run and wait for it:**
494
+ `gh run list --workflow apply-web-platform-infra.yml --commit <merge-sha> --limit 5 --json databaseId,status,conclusion`. An empty
495
+ list right after the merge is retried (every 30 s, up to 10 min), not read as "no run". Watch the id under Monitor
496
+ (`gh run watch <id>`; never `run_in_background` polling), bounded to about 50 min (the job runs up to 41 min plus queueing
497
+ on the shared concurrency group). `success` is read back. `cancelled`, `timed_out`, `startup_failure`, `skipped`,
498
+ `failure` or no run within the bound mean **not delivered or superseded**: read back anyway (a merge-SHA run can be
499
+ `cancelled` by the shared concurrency group and still have delivered); the read-back is the arbiter.
500
+ 3. **Run the read-back** from runbook `knowledge-base/engineering/operations/runbooks/inngest-luks-cutover-6894.md` §5c
501
+ (read-only, token on stdin, one word). Run exactly:
502
+
503
+ ```bash
504
+ doppler run -p soleur -c prd_terraform --only-secrets HCLOUD_TOKEN_READONLY --no-exit-on-missing-only-secrets -- sh -c '[ -n "$HCLOUD_TOKEN_READONLY" ] || { echo missing-token; exit 3; }; r=$(printf "header = \"Authorization: Bearer %s\"\n" "$HCLOUD_TOKEN_READONLY" | curl -sS --config - -w "\n%{http_code}" https://api.hetzner.cloud/v1/volumes/106903269) || { echo read-failed; exit 2; }; case "$(printf %s "$r" | tail -n 1)" in 200) w=$(printf %s "$r" | sed "\$d" | jq -r "if .volume.protection.delete == true then \"protected\" elif .volume.protection.delete == false then \"not-protected\" else \"read-failed\" end" 2>/dev/null);; 404) w=volume-gone;; *) w=read-failed;; esac; case "$w" in protected) echo protected;; not-protected) echo not-protected; exit 1;; volume-gone) echo volume-gone; exit 4;; *) echo read-failed; exit 2;; esac'
505
+ ```
506
+
507
+ 4. **Route on the word, compared with the expected one.** `protected` / `not-protected` equal to the expected word passes;
508
+ a mismatch is a red status. `volume-gone` (HTTP 404) is not a read problem: report it and route to the runbook's "After
509
+ a total loss". `read-failed` (an HTTP error such as a 401, a network error, a non-JSON body or a missing field) and a
510
+ **missing word** (nothing printed: `doppler` absent or unauthenticated, an error before the command ran) mean the read
511
+ did not happen: report them, never dispatch on their account. `missing-token` means `HCLOUD_TOKEN_READONLY` is absent from
512
+ `prd_terraform`; minting it is operator step O5 in `knowledge-base/engineering/operations/runbooks/infra-credential-tiers-8209.md`.
513
+ Report `missing-token` and file an issue (the idiom of Phase 5.5, with the same label and the repo milestone):
514
+
515
+ ```bash
516
+ gh issue create --label type/chore --milestone "Post-MVP / Later" \
517
+ --title "sole-copy read-back missing-token: mint HCLOUD_TOKEN_READONLY (PR #<number>)" \
518
+ --body "Post-merge read-back of the Inngest sole-copy volume could not run: HCLOUD_TOKEN_READONLY is absent from Doppler prd_terraform (operator step O5, infra-credential-tiers-8209.md). Until it is minted the delete protection on the only copy of the user queue and run state cannot be verified after a merge. Re-evaluate when O5 is done."
519
+ ```
520
+
521
+ 5. **`not-protected` when `protected` was expected: report, recommend, wait.** Name the exact command and ask the owner for an
522
+ explicit per-command go-ahead naming it; a menu answer is not one (`hr-menu-option-ack-not-prod-write-auth`). Never
523
+ dispatch it on your own. It applies the **whole per-merge plan**, not only the protection:
524
+ `gh workflow run apply-web-platform-infra.yml --ref main -f apply_target=manual-rerun -f reason='deliver sole-copy protection'`.
525
+ After a go-ahead and the dispatch: note the newest run id first, then
526
+ `gh run list --workflow apply-web-platform-infra.yml --event workflow_dispatch --limit 1 --json databaseId,status`
527
+ (an empty or unchanged id is stale: retry), watch it under Monitor bounded to about 50 min, then read back again.
528
+ `success` is read back; `cancelled`, `timed_out`, `startup_failure`, `skipped` or no run within the bound mean not
529
+ delivered or superseded: read back anyway, and if it is still `not-protected` recommend the dispatch again (go-ahead).
530
+ 6. **On a `protected` read-back that matches the expected word, and only while ADR-282's status is still `adopting`, file ONE tracking issue** so the status flip does not depend
531
+ on memory (skip if one is already open: `gh issue list --state open --limit 20 --search "flip ADR-282" --json number`):
532
+
533
+ ```bash
534
+ gh issue create --label type/chore --milestone "Post-MVP / Later" \
535
+ --title "chore: flip ADR-282 adopting to accepted (and the sister records)" \
536
+ --body "The Inngest sole-copy delete protection was read back as protected after PR #<number>. ADR-282, runbook inngest-luks-cutover-6894.md section 5c, the ADR-119, ADR-142 and ADR-263 addenda, the C4 model, the Art. 30 register, compliance-posture and the encryption-posture ledger still say adopting, so a reader treats a verified protection on user data as a plan. Flip them to accepted in one follow-up PR."
537
+ ```
538
+
539
+ A failed or unrun read-back is a **red post-merge status**: report it verbatim as `Sole-copy read-back: <word>` in the Phase 6
540
+ comment and the Phase 7 summary. It does not itself block "done" (report-only, like Phase 5.6; Phase 5.5 is blocking in CI).
541
+
542
+ ## Phase 5.8: KB archival read-back (REPORT-ONLY)
543
+
544
+ The ship-side archival gate (`ship` Phase 6.45 + the `ship-kb-archive-gate.sh` PreToolUse hook) only sees merges that pass through
545
+ the agent's own `gh pr merge` — UI merges, `gh api` merges, and queue merges from other harnesses bypass it. This phase is the
546
+ catch-net: read the merge's landed diff and report any KB artifact it left at a LIVE path.
547
+
548
+ For the merge commit recorded in Phase 1, diff the whole merge range against `origin/main`'s merge-base — `<merge-sha>^..<sha>`
549
+ only covers squash and first-parent merge shapes; a `--rebase`-shape merge lands N commits and a single-parent diff misses the
550
+ earlier ones. `git fetch origin main` first, so the worktree holds both endpoints:
551
+
552
+ ```bash
553
+ git fetch origin main
554
+ git diff --name-status --diff-filter=AMRCT \
555
+ "$(git merge-base origin/main <merge-sha>)" "<merge-sha>" -- \
556
+ knowledge-base/project/specs knowledge-base/project/plans knowledge-base/project/brainstorms
557
+ ```
558
+
559
+ If `git merge-base` returns empty (shallow clone), diff `origin/main^..<merge-sha>` instead and report that fallback in the
560
+ status line. Only `<root>/archive/` rows are compliant — a path under `specs/<live-dir>/archive/` is still inside a live spec
561
+ dir. `R`/`C` rows are judged on the destination: `git mv specs/archive/x specs/y` lands a live path. Every remaining
562
+ `A`/`M`/`R`/`C`/`T` row is an artifact the merge landed live. Report the surviving rows **verbatim** as a **red post-merge
563
+ status** — `KB archival read-back: <verbatim rows, or "clean">` — in the Phase 6 issue comment AND the Phase 7 summary.
564
+
565
+ **Remediation is per-row `git mv`, not `archive-kb.sh`:** the archiver's three discovery axes (slug glob, branch-diff, untracked
566
+ `??`) cannot reach a spec dir that a leaked merge already committed — on a fresh branch all three return empty and the script
567
+ exits `No artifacts found`, which reads as clean. On a NEW branch from `origin/main`, for each reported row:
568
+
569
+ ```bash
570
+ git mv <row-path> knowledge-base/project/<root>/archive/$(date +%Y%m%d-%H%M%S)-<name> \
571
+ && git commit -m "chore(kb): archive leaked artifacts from <pr>"
572
+ ```
573
+
574
+ then open a follow-up PR — archival cannot ride a PR that already merged. **M-row caveat:** an `M` on `specs/<dir>/` can be a
575
+ drive-by edit to a SIBLING feature's in-flight spec — verify the dir belongs to the merged feature first; if not, revert the
576
+ edit (`git checkout origin/main -- <path>` then commit) rather than `git mv`-ing another feature's dir. Like Phases 5.6/5.7
577
+ it is REPORT-ONLY (Phase 5.5 is blocking in CI): it never blocks the "done" verdict; the signal is for immediate operator attention, not rollback.
578
+
579
+ ## Phase 6: Update Issue and Compound
580
+
581
+ If the PR body contained `Closes #N`, update the linked issue with verification results:
582
+
583
+ ```bash
584
+ gh issue comment <issue-number> --body "Post-merge verification complete for PR #<pr-number>.
585
+
586
+ - CI on main: PASSED
587
+ - Production health: <PASSED/SKIPPED/FAILED>
588
+ - Sentry monitors: <HEALTHY/WARNING/SKIPPED>
589
+ - Sentry error-count delta: <AUTO-RESOLVED/STOPPED/STILL-FIRING/SKIPPED>
590
+ - File freshness: <PASSED/N files checked>
591
+ - Browser verification: <PASSED/SKIPPED/DELEGATED-TO-LIVE-VERIFY>
592
+ - Live verification: <PASS/FAIL/CANT-RUN:reason/SKIPPED/UNVERIFIED:capability> (blocking in CI, #5463)
593
+ - Sole-copy read-back: <protected/not-protected/volume-gone/read-failed/missing-token/no word/SKIPPED> (report-only, #9879)
594
+ - KB archival read-back: <clean/verbatim rows> (report-only)
595
+ "
596
+ ```
597
+
598
+ Run compound to capture any learnings from the merge:
599
+
600
+ ```
601
+ skill: soleur:compound
602
+ ```
603
+
604
+ ## Phase 7: Report
605
+
606
+ Print a summary:
607
+
608
+ ```text
609
+ postmerge verification complete!
610
+
611
+ PR: #<number>
612
+ Merge commit: <sha>
613
+ CI on main: PASSED
614
+ Production health: <PASSED/SKIPPED/FAILED>
615
+ Sentry monitors: <HEALTHY/WARNING/SKIPPED>
616
+ Sentry error-count delta: <AUTO-RESOLVED/STOPPED/STILL-FIRING/SKIPPED>
617
+ File freshness: <N files verified>
618
+ Browser verification: <PASSED/SKIPPED/DELEGATED-TO-LIVE-VERIFY>
619
+ Live verification: <PASS/FAIL/CANT-RUN:reason/SKIPPED/UNVERIFIED:capability> (blocking in CI, #5463)
620
+ Sole-copy read-back: <protected/not-protected/volume-gone/read-failed/missing-token/no word/SKIPPED> (report-only, #9879)
621
+ KB archival read-back: <clean/verbatim rows> (report-only)
622
+ Feature-tweet draft: <path + "flip publish_date + status: scheduled to publish" / CATCH-UP: run soleur:feature-tweet #N / NONE — ineligible>
623
+ ```
624
+
625
+ ## Graceful Degradation
626
+
627
+ When a prerequisite is missing, read
628
+ [references/graceful-degradation.md](./references/graceful-degradation.md) for the
629
+ per-prerequisite behaviour (skip / warn / poll).
630
+
631
+ ## Notes
632
+
633
+ - Always read merged files out of git rather than off the bare repo filesystem — but address them by the **merge commit SHA** (`git show <merge-sha>:<path>`), never by the local `main` ref. `main` is not fast-forwarded as a side effect of a merge, so in a worktree/bare layout it lags and a file the PR ADDED reads as absent. `git fetch origin main` FIRST: the merge SHA is correct but useless if the worktree does not have that object yet, and git reports the shortfall in wording (`exists on disk, but not in <sha>`) that looks like a verdict about the file. See Phase 4.
634
+ - MCP tools resolve paths from the repo root. Use absolute paths when in a worktree.
635
+ - This skill is designed to run after `soleur:merge-pr` completes. It can also be invoked standalone with a PR number.
636
+
637
+ ## Production Debugging
638
+
639
+ - **A deploy-arm database step failing on an auth/connect timeout is a production database signal, not an isolated flake: read readiness before rerunning.** `/health` returns HTTP 200 `status: ok` whatever the database state (only `.supabase` flips to `error`), the Management API project `status` can read `ACTIVE_HEALTHY` while Postgres is down, and a rerun's `migrate` can go green through the pooler. Read `curl -sS <prod>/health | jq -r .supabase` and `GET /v1/projects/<ref>/health?services=db&services=auth&services=rest&services=pooler` first — the latter carries the account-level admin PAT, so call it the way [supabase-logs-query.sh](../../../../scripts/supabase-logs-query.sh) does (header on stdin via `--header @-`, `--disable --noproxy '*'`, under `doppler run`), never with the token in argv. **Why:** 2026-09-15 — prd Postgres was unreachable 89 min; a rerun looped on health verification and `/health` was read directly only ~16 min later (post-mortem `prd-supabase-database-unreachable-2026-09-15-postmortem.md`).
640
+ - For production debugging use Sentry API (`SENTRY_API_TOKEN` in Doppler `prd`), Better Stack, or `/health` — never SSH for logs. SSH is for infra provisioning only. (ex-`cq-for-production-debugging-use`) To read a Sentry issue/event by id inline, use `doppler run -p soleur -c prd -- scripts/sentry-issue.sh <id>` (runbook `knowledge-base/engineering/operations/runbooks/sentry-issue-read.md`); for host/app logs use [betterstack-query.sh](../../../../scripts/betterstack-query.sh) (runbook `betterstack-log-query.md`).
641
+ - For deploy webhook debugging, fetch `WEBHOOK_DEPLOY_SECRET`/`CF_ACCESS_CLIENT_ID`/`CF_ACCESS_CLIENT_SECRET` from Doppler `prd_terraform` (not `prd`). GET `https://deploy.soleur.ai/hooks/deploy-status` with CF Access headers + HMAC-sha256 over empty body, all on curl's stdin config. Full runbook: [deploy-status-debugging.md](./references/deploy-status-debugging.md). (ex-`cq-deploy-webhook-observability-debug`)
642
+ - Doppler env values on prd are baked into the container at start via `--env-file` (cloud-init.yml). Flipping a flag in Doppler does NOT affect the running container — POST-X gates that depend on a freshly-flipped flag must redeploy the current image tag (POST to `/hooks/deploy`) between the flip and the verification smoke. Full context: [2026-05-19-doppler-env-hot-reload-limitation.md](../../../../knowledge-base/project/learnings/2026-05-19-doppler-env-hot-reload-limitation.md).