@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,410 @@
1
+ #!/usr/bin/env bash
2
+ # shellcheck disable=SC2015,SC2018,SC2019 # A && B || C is the check idiom; tr A-Z is the portable ASCII lowering
3
+ # The /ship Phase 6 step 5 hold evaluator: turns the recorded `Gate:` predicates of `## Operator Holds` (or of a
4
+ # Production Envelope's `Preconditions:`) into a mechanical verdict, so a hold is discharged by evidence and never
5
+ # by a model's reading of prose. Procedure and wording: skills/ship/references/operator-holds.md. Format source:
6
+ # skills/brainstorm-techniques/references/standing-delegation.md.
7
+ #
8
+ # Property: plan mode verifies the delegation, and a hold is discharged only if a Standing Delegation is cited
9
+ # (verifier rc 0 AND a first line `delegation: valid`) and EVERY one of its `Gate:` predicates is a known kind that
10
+ # evaluates true now. Any other state leaves it standing: an unknown kind, an unreadable probe, a missing,
11
+ # ambiguous or invalid delegation, a missing envelope, a timeout, a missing time-limit tool, a hold with no gate.
12
+ # --file mode does not verify a delegation (the caller just did); it only measures one envelope's `Preconditions:` gates.
13
+ #
14
+ # Usage:
15
+ # hold-gate-eval.sh --plan <plan.md> evaluate `## Operator Holds`
16
+ # hold-gate-eval.sh --file <envelope.md> --section "<title>" evaluate one envelope's gates
17
+ # hold-gate-eval.sh --file "<envelope.md>#<title>" the same, addressed as the verifier does
18
+ # Run from the repository root (repo-relative paths are resolved from the working directory). The title is matched
19
+ # without regard to case against `##`..`####` headings (substring).
20
+ #
21
+ # Plan format (read from the file, never from conversation). The heading is `## Operator Holds` at level 2 to 4,
22
+ # any case; a section ends at the next heading of the same or a shallower level:
23
+ # ## Operator Holds
24
+ # Delegation: <comment url> exactly one; without it no hold can be discharged here (exit 3)
25
+ # Envelope: <path>[#<title>] REQUIRED beside a Delegation line; passed to the verifier
26
+ # - Hold: <the operator's words, verbatim>
27
+ # Gate: pr-merged <N> | no-inflight-run <workflow-file>
28
+ # `command` and `run-green` are deferred. The first real consumer re-adds them, and only by CTO ruling. A `Gate:`
29
+ # line of any other kind is an unknown kind: it exits 2 and the hold stands. Markers (`Hold:`, `Gate:`,
30
+ # `Delegation:`, `Envelope:`) are read in any case, with or without the list dash and a space before the colon.
31
+ # Lines inside a code fence (same character to close, at least as long) are examples and are ignored.
32
+ #
33
+ # Exit: 0 every hold discharged (or none recorded: an absent or empty section is a no-op);
34
+ # 1 at least one hold STANDS; 2 cannot evaluate (treated as STANDS by the caller; includes a hold or a gate
35
+ # outside any section this script can read, a Delegation line with zero holds, two Delegation or
36
+ # Envelope lines, a missing Envelope line, an unknown kind, an unreadable probe, an unreadable delegation,
37
+ # a missing time-limit tool);
38
+ # 3 no `Delegation:` line anywhere in the hold sections: legacy prose holds. Decided BEFORE every structure
39
+ # and tool check, so the caller keeps its prose evaluation (operator-holds.md section 3).
40
+ # stdout: when a delegation was checked, its verdict line first (`delegation: <valid|invalid|unverifiable>
41
+ # reason=<token>`); then one plain line per hold, then `holds: N discharged: M standing: K`. A `Done:` line carries
42
+ # the gate text that was true. Exit 2 and 1 are never converted to a pass by any caller; nothing here retries a
43
+ # failed probe into a pass. Any other status the caller sees (127 script not found, 124, 137) is a hold that was
44
+ # not checked: treat it as 2.
45
+ #
46
+ # `Operator-reserved:` (at the START of a hold's words; case, spaces, hyphens, underscores, bold, quotes, full-width colon and
47
+ # invisible characters are ignored, so `Operator reserved:` and `**Operator-reserved:**` count) marks a hold that reserves the decision to the
48
+ # operator (pricing approval, brand copy, spend). A gate only says WHEN a condition is true, never WHO may clear the
49
+ # hold, so such a hold always STANDS: it is printed `Reserved for you: ... - only you can clear this`, its gates are
50
+ # not probed, and the run exits 2. Every `Hold:` or `Gate:` line must sit inside a readable hold section; one that does
51
+ # not (a misspelt second heading, text after the next heading) is exit 2, never silently dropped. --file mode reads the
52
+ # COMMITTED blob (HEAD), exactly as the verifier does, never the working tree: an untracked, symlinked or dirty file
53
+ # cannot change the answer. Test seam: HGE_VERIFY_TIMEOUT (seconds, 1-59) can only SHORTEN the 60 s verifier limit.
54
+ #
55
+ # The default branch is resolved once (origin/HEAD, else `git ls-remote --symref`); `pr-merged` needs MERGED into
56
+ # it and the merge commit reachable from HEAD after a fresh fetch of it. Every gh, git and verifier call gets
57
+ # `</dev/null`, so a call that drains stdin cannot swallow the remaining gates or holds. In flight means the
58
+ # status is queued, in_progress, waiting, requested or pending (ONE `gh run list`, the last 100 runs); a status
59
+ # this script does not know is exit 2.
60
+ #
61
+ # `set -uo pipefail`, deliberately NOT `-e`. Portable to bash 3.2 and mawk. Lines ending `# mut:<name>` are the
62
+ # mutation points the suite edits to prove each check can fail.
63
+
64
+ set -uo pipefail
65
+ export LC_ALL=C
66
+
67
+ SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
68
+ VERIFY="$SCRIPT_DIR/../../../scripts/delegation-verify.sh"
69
+ WORK=""
70
+ cleanup() { [ -n "$WORK" ] && rm -rf "${WORK:?}"; return 0; }
71
+ trap cleanup EXIT
72
+
73
+ die2() { printf '%s\n' "$1" >&2; exit 2; }
74
+ trim() { local s="$1"; s="${s#"${s%%[![:space:]]*}"}"; s="${s%"${s##*[![:space:]]}"}"; printf '%s' "$s"; }
75
+ # Control characters, C1 controls, zero-width and bidi marks and the line/paragraph separators are dropped (byte-wise: LC_ALL=C).
76
+ clean_text() { printf '%s' "$1" | tr -d '[:cntrl:]' | sed -e $'s/\xc2[\x80-\x9f]//g' -e $'s/\xe2\x80[\x8b-\x8f\xa8-\xae]//g' -e $'s/\xe2\x81[\xa6-\xa9]//g' -e $'s/\xef\xbb\xbf//g' | cut -c1-160; } # mut:clean-text
77
+
78
+ VT=60
79
+ case "${HGE_VERIFY_TIMEOUT:-}" in ''|*[!0-9]*) ;; *) [ "$HGE_VERIFY_TIMEOUT" -ge 1 ] && [ "$HGE_VERIFY_TIMEOUT" -lt 60 ] && VT="$HGE_VERIFY_TIMEOUT" ;; esac
80
+ TO10=(); TO30=(); TO60=(); HAVE_TO=0
81
+ if command -v timeout >/dev/null 2>&1; then TO10=(timeout 10); TO30=(timeout 30); TO60=(timeout "$VT"); HAVE_TO=1
82
+ elif command -v gtimeout >/dev/null 2>&1; then TO10=(gtimeout 10); TO30=(gtimeout 30); TO60=(gtimeout "$VT"); HAVE_TO=1; fi
83
+
84
+ DEFBR=""; DEFBR_DONE=""
85
+ resolve_default_branch() { # sets DEFBR to the repository's default branch name, or leaves it empty
86
+ [ -z "$DEFBR_DONE" ] || return 0
87
+ DEFBR_DONE=1
88
+ local ref
89
+ ref="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD </dev/null 2>/dev/null)"; ref="${ref#origin/}"
90
+ if [ -z "$ref" ]; then
91
+ ref="$(GIT_TERMINAL_PROMPT=0 ${TO10[@]+"${TO10[@]}"} git ls-remote --symref origin HEAD </dev/null 2>/dev/null | sed -n 's|^ref: refs/heads/\(.*\)[[:space:]]HEAD$|\1|p' | head -1)"
92
+ fi
93
+ [[ "$ref" =~ ^[A-Za-z0-9._/-]+$ ]] && DEFBR="$ref" # mut:defbr
94
+ return 0
95
+ }
96
+
97
+ FETCHED=""; FETCH_RC=0
98
+ ensure_fetch() {
99
+ [ -n "$FETCHED" ] && return "$FETCH_RC"
100
+ FETCHED=1
101
+ GIT_TERMINAL_PROMPT=0 ${TO30[@]+"${TO30[@]}"} git fetch --no-tags -q origin "$DEFBR" </dev/null >/dev/null 2>&1; FETCH_RC=$? # mut:fetch
102
+ return "$FETCH_RC"
103
+ }
104
+
105
+ gh_json() { # <outfile> <gh args...>: 0 only when gh succeeded and printed valid JSON
106
+ local out="$1"; shift
107
+ ${TO10[@]+"${TO10[@]}"} gh "$@" > "$out" 2>/dev/null </dev/null || return 1 # mut:stdin-gh
108
+ jq -e . "$out" >/dev/null 2>&1 </dev/null
109
+ }
110
+
111
+ known_kind() { case "$1" in pr-merged|no-inflight-run) return 0 ;; esac; return 1; }
112
+
113
+ GRES=""; GWHY=""
114
+ gate_pr_merged() {
115
+ local n="$1" st sha base rc
116
+ [[ "$n" =~ ^[0-9]+$ ]] || { GRES=UNEVAL; GWHY="the earlier change is not named by a plain number"; return; }
117
+ resolve_default_branch
118
+ [ -n "$DEFBR" ] || { GRES=UNEVAL; GWHY="I could not tell which line of work is the main one"; return; }
119
+ ensure_fetch || true
120
+ gh_json "$WORK/pr.json" pr view "$n" --json state,mergeCommit,baseRefName || { GRES=UNEVAL; GWHY="I could not read the state of the earlier change"; return; }
121
+ st="$(jq -r '.state // empty' "$WORK/pr.json" </dev/null)"; sha="$(jq -r '.mergeCommit.oid // empty' "$WORK/pr.json" </dev/null)"; base="$(jq -r '.baseRefName // empty' "$WORK/pr.json" </dev/null)"
122
+ GWHY="the earlier change has not gone live yet"
123
+ if [ "$st" = MERGED ] && [ "$base" = "$DEFBR" ] && [[ "$sha" =~ ^[0-9a-f]{7,40}$ ]]; then
124
+ git merge-base --is-ancestor "$sha" HEAD </dev/null >/dev/null 2>&1; rc=$?
125
+ case "$rc" in
126
+ 0) GRES=TRUE ;;
127
+ 1) GRES=FALSE; GWHY="the earlier change is live, but this work has not been brought up to date with it yet" ;;
128
+ *) GRES=UNEVAL; GWHY="I could not compare this work with the earlier change" ;;
129
+ esac
130
+ else
131
+ GRES=FALSE
132
+ if [ "$st" = MERGED ] && [ "$base" = "$DEFBR" ]; then GWHY="the earlier change is recorded as live, but I cannot see which version of the work it became"
133
+ elif [ "$st" = MERGED ]; then GWHY="the earlier change went into another line of work, not the main one"; fi
134
+ fi
135
+ }
136
+
137
+ gate_no_inflight() {
138
+ local wf="$1" live unk
139
+ [[ "$wf" =~ ^[A-Za-z0-9._-]+\.ya?ml$ ]] || { GRES=UNEVAL; GWHY="the release is not named as a plain workflow file"; return; }
140
+ if ! gh_json "$WORK/runs.json" run list --workflow "$wf" --limit 100 --json status \
141
+ || ! jq -e 'type == "array" and all(.[]; type == "object")' "$WORK/runs.json" >/dev/null 2>&1 </dev/null; then
142
+ GRES=UNEVAL; GWHY="I could not read the list of running releases"; return
143
+ fi
144
+ live="$(jq '[.[] | .status as $s | select($s == "queued" or $s == "in_progress" or $s == "waiting" or $s == "requested" or $s == "pending")] | length' "$WORK/runs.json" </dev/null)"
145
+ unk="$(jq '[.[] | .status as $s | select($s != "completed" and $s != "queued" and $s != "in_progress" and $s != "waiting" and $s != "requested" and $s != "pending")] | length' "$WORK/runs.json" </dev/null)"
146
+ GWHY="a release is still running"
147
+ if [ "${live:-1}" -gt 0 ]; then GRES=FALSE
148
+ elif [ "${unk:-1}" -gt 0 ]; then GRES=UNEVAL; GWHY="a release is in a state I do not know" # mut:status-unknown
149
+ else GRES=TRUE; fi
150
+ }
151
+
152
+ eval_gate() { # <gate text after `Gate:`> -> GRES (TRUE|FALSE|UNEVAL), GWHY
153
+ local text="$1" kind rest
154
+ GRES=UNEVAL; GWHY="I do not know this kind of condition, so it stays on hold"
155
+ kind="${text%%[[:space:]]*}"; rest="$(trim "${text#"$kind"}")"
156
+ known_kind "$kind" || { GRES=UNEVAL; return; } # mut:unknown-kind
157
+ case "$kind" in
158
+ pr-merged) gate_pr_merged "$rest" ;;
159
+ no-inflight-run) gate_no_inflight "$rest" ;;
160
+ esac
161
+ }
162
+
163
+ # split_sections <file> <mode> <match>: sections into $WORK/sec.<n> (heads in sec.heads), count in sec.count.
164
+ # Plan mode: a heading of level 2-4 reading "Operator Holds" in any case. File mode: a level 2-4 heading containing
165
+ # <match> (any case). A section ends at the next heading of the same or a shallower level. Fenced lines are text.
166
+ split_sections() {
167
+ awk -v dir="$WORK" -v mode="$2" -v match_text="$3" '
168
+ function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s }
169
+ function fence( tok, c, n) {
170
+ tok = t; sub(/^ +/, "", tok)
171
+ match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
172
+ if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
173
+ if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
174
+ }
175
+ BEGIN { mt = tolower(match_text) }
176
+ { t = $0; sub(/\r$/, "", t) }
177
+ t ~ /^ ? ? ?(```+|~~~+)/ { fence() } # mut:fence-split
178
+ f == 0 && (t ~ /^#+[ \t]/ || t ~ /^#+$/) {
179
+ match(t, /^#+/); L = RLENGTH
180
+ if (cur != "" && L <= curlvl) { close(cur); cur = "" }
181
+ if (cur == "" && L >= 2 && L <= 4) {
182
+ rest = tolower(trim(substr(t, L + 1))) # mut:heading-ci
183
+ sub(/[ \t]+#+$/, "", rest)
184
+ if (mode == "plan") hit = (rest ~ /^operator[ \t]+holds$/ || rest ~ /^operator[ \t]+holds[^a-z0-9]/); else hit = (mt != "" && index(rest, mt) > 0)
185
+ if (hit) { n++; cur = dir "/sec." n; curlvl = L; print t > (dir "/sec.heads") }
186
+ }
187
+ }
188
+ cur != "" { print $0 > cur }
189
+ END { print n + 0 > (dir "/sec.count") }
190
+ ' "$1"
191
+ }
192
+
193
+ # Marker spellings (security V4). Both the counter and the parser first NORMALISE a line: full-width colon to ":", NBSP and the
194
+ # other Unicode spaces to " ", zero-width characters and the soft hyphen dropped, Unicode hyphens to "-"; then leading list,
195
+ # quote and emphasis markers (`* ` `+ ` `- ` `1. ` `2) ` `> ` `**` `__`) are stripped, so `* Hold:`, `> Hold:`, `- **Hold:**`,
196
+ # `Hold:` and `Hold<NBSP>:` are all the marker `hold:`. byte-wise (LC_ALL=C).
197
+ NORM_AWK='
198
+ function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s }
199
+ function norm(s) {
200
+ gsub(/\357\274\232/, ":", s)
201
+ gsub(/\302\240/, " ", s); gsub(/\342\200[\200-\212]/, " ", s); gsub(/\342\200\257/, " ", s); gsub(/\342\201\237/, " ", s); gsub(/\343\200\200/, " ", s)
202
+ gsub(/\342\200[\213-\215]/, "", s); gsub(/\342\201\240/, "", s); gsub(/\357\273\277/, "", s); gsub(/\302\255/, "", s)
203
+ gsub(/\342\200[\220-\225]/, "-", s)
204
+ return s
205
+ }
206
+ function strip_prefix(s) {
207
+ while (match(s, /^([ \t]+|[>*+_-]+|[0-9]+[.)]([ \t]|$))/)) s = substr(s, RLENGTH + 1)
208
+ return s
209
+ }
210
+ function val(s) { s = substr(s, index(s, ":") + 1); sub(/^[*_ \t]+/, "", s); return trim(s) }
211
+ '
212
+
213
+ # marker_count <file>: prints how many unfenced `Hold:` or `Gate:` marker lines the file has.
214
+ marker_count() {
215
+ awk "$NORM_AWK"'
216
+ function fence( tok, c, n) {
217
+ tok = t; sub(/^ +/, "", tok)
218
+ match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
219
+ if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
220
+ if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
221
+ }
222
+ { t = $0; sub(/\r$/, "", t) }
223
+ t ~ /^ ? ? ?(```+|~~~+)/ { fence(); next }
224
+ f { next }
225
+ { nt = norm(t) # mut:marker-norm
226
+ st = strip_prefix(nt); lt = tolower(st) # mut:ci-markers
227
+ }
228
+ lt ~ /^(hold|gate)[*_ \t]*:/ { found++ }
229
+ END { print found + 0 }
230
+ ' "$1"
231
+ }
232
+
233
+ # parse_items <section file> <mode>: records DELEG / ENVF / HOLD i text / GATE i text / ORPHAN.
234
+ parse_items() {
235
+ awk -v mode="$2" "$NORM_AWK"'
236
+ function fence( tok, c, n) {
237
+ tok = t; sub(/^ +/, "", tok)
238
+ match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
239
+ if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
240
+ if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
241
+ }
242
+ NR == 1 { if (mode == "file") { n = 1; print "HOLD\t1\tthe conditions before the act" } next }
243
+ { t = $0; sub(/\r$/, "", t)
244
+ if (t ~ /^ ? ? ?(```+|~~~+)/) { fence(); next }
245
+ if (f) next
246
+ nt = norm(t) # mut:marker-norm
247
+ st = strip_prefix(nt); lt = tolower(st) # mut:ci-markers
248
+ if (mode == "plan" && lt ~ /^delegation[*_ \t]*:/) { print "DELEG\t" val(st); next }
249
+ if (mode == "plan" && lt ~ /^envelope[*_ \t]*:/) { print "ENVF\t" val(st); next }
250
+ if (mode == "plan" && lt ~ /^hold[*_ \t]*:/) { n++; print "HOLD\t" n "\t" val(st); next }
251
+ if (lt ~ /^gate[*_ \t]*:/) { if (n > 0) print "GATE\t" n "\t" val(st); else print "ORPHAN"; next }
252
+ }
253
+ ' "$1"
254
+ }
255
+
256
+ print_result_line() { # <verdict> <text> <why> <gate text>
257
+ local gsuffix=""
258
+ [ -z "${4:-}" ] || gsuffix=" - checked: $(clean_text "$4")" # mut:done-gates
259
+ case "$1" in
260
+ OK) printf 'Done: %s%s\n' "$(clean_text "$2")" "$gsuffix" ;;
261
+ WAIT) printf 'Still waiting: %s - %s\n' "$(clean_text "$2")" "$3" ;;
262
+ NEEDS) printf 'Needs a person: %s - only a person can settle this\n' "$(clean_text "$2")" ;;
263
+ RESERVED) printf 'Reserved for you: %s - only you can clear this\n' "$(clean_text "$2")" ;;
264
+ *) printf 'Could not check: %s - %s\n' "$(clean_text "$2")" "$3" ;;
265
+ esac
266
+ }
267
+
268
+ # stall_unchecked <sentence> <why>: every hold stays on hold because the record itself cannot be used (exit 2).
269
+ stall_unchecked() {
270
+ local i text
271
+ echo "$1"
272
+ while IFS=$'\t' read -r _ i text; do print_result_line UNEVAL "$text" "$2"; done < <(grep '^HOLD' "$WORK/items")
273
+ echo "holds: $NH discharged: 0 standing: $NH"
274
+ exit 2
275
+ }
276
+
277
+ # stand_all <state> <token> <rc-fits>: the delegation did not verify, so every hold stands (1 when invalid, 2 otherwise).
278
+ stand_all() {
279
+ local i text
280
+ echo "delegation: $1 reason=$2"
281
+ echo "Your standing approval could not be confirmed, so every hold stays on hold."
282
+ while IFS=$'\t' read -r _ i text; do print_result_line WAIT "$text" "waiting for your standing approval"; done < <(grep '^HOLD' "$WORK/items")
283
+ echo "holds: $NH discharged: 0 standing: $NH"
284
+ [ "$1" = invalid ] && [ "$3" = fits ] && exit 1
285
+ exit 2
286
+ }
287
+
288
+ split_file_title() { # --file "<path>#<title>": the title becomes the section; naming it twice is a usage error
289
+ case "$FILE" in
290
+ *'#'*)
291
+ local ht="${FILE#*#}"
292
+ FILE="${FILE%%#*}"
293
+ [ -n "$ht" ] || die2 "the envelope title after # is empty, so no condition can be found"
294
+ [ -z "$SECTION" ] || die2 "the envelope title is named twice (after # and with --section), so no condition can be found"
295
+ SECTION="$ht" ;;
296
+ esac
297
+ }
298
+
299
+ MODE=""; PLAN=""; FILE=""; SECTION=""
300
+ while [ $# -gt 0 ]; do
301
+ case "$1" in
302
+ --plan) [ $# -ge 2 ] || die2 "--plan needs a file"; PLAN="$2"; shift 2 ;;
303
+ --file) [ $# -ge 2 ] || die2 "--file needs a file"; FILE="$2"; shift 2 ;;
304
+ --section) [ $# -ge 2 ] || die2 "--section needs a heading"; SECTION="$2"; shift 2 ;;
305
+ *) die2 "unknown argument: $1" ;;
306
+ esac
307
+ done
308
+ split_file_title # mut:file-title
309
+ if [ -n "$PLAN" ] && [ -z "$FILE" ] && [ -z "$SECTION" ]; then MODE="plan"; SRC="$PLAN"
310
+ elif [ -n "$FILE" ] && [ -n "$SECTION" ] && [ -z "$PLAN" ]; then MODE="file"; SRC="$FILE"
311
+ else die2 "usage: hold-gate-eval.sh --plan <plan.md> | --file <envelope.md> --section <title> | --file <envelope.md>#<title>"; fi
312
+ [ "$MODE" = file ] || { [ -f "$SRC" ] && [ -r "$SRC" ] || die2 "cannot read $SRC, so no hold can be checked"; }
313
+ WORK="$(mktemp -d -t hge.XXXXXXXX)" || die2 "could not create a scratch folder"
314
+
315
+ # read_head_blob <path>: --file mode reads the COMMITTED regular file (as the verifier does), never the working tree.
316
+ read_head_blob() {
317
+ local p="$1" ent
318
+ case "$p" in ""|/*|..|../*|*/..|*/../*|*[*?[]*) die2 "the envelope path is not a plain path inside this repository, so its conditions are treated as not met" ;; esac
319
+ p="${p#./}"
320
+ command -v git >/dev/null 2>&1 || die2 "git is not installed, so no hold can be checked"
321
+ ent="$(GIT_LITERAL_PATHSPECS=1 git ls-tree HEAD -- "./$p" </dev/null 2>/dev/null | head -1)"
322
+ case "$ent" in "100644 blob "*) ;; *) die2 "the envelope file is not saved in the project history as a normal file, so its conditions are treated as not met" ;; esac
323
+ GIT_LITERAL_PATHSPECS=1 git show "HEAD:./$p" > "$WORK/head.md" 2>/dev/null </dev/null || die2 "could not read the saved envelope file, so its conditions are treated as not met"
324
+ }
325
+ if [ "$MODE" = file ]; then read_head_blob "$FILE"; SRC="$WORK/head.md"; fi # mut:file-head
326
+
327
+ need_tools() { # after the no-delegation exit: nothing below can run without these
328
+ command -v jq >/dev/null 2>&1 || die2 "jq is not installed, so no hold can be checked"
329
+ command -v gh >/dev/null 2>&1 || die2 "the GitHub command line tool is not installed, so no hold can be checked"
330
+ command -v git >/dev/null 2>&1 || die2 "git is not installed, so no hold can be checked"
331
+ [ "$HAVE_TO" -eq 1 ] || die2 "no time limit tool (timeout) is available on this machine, so no hold can be checked" # mut:need-timeout
332
+ }
333
+
334
+ split_sections "$SRC" "$MODE" "$SECTION"
335
+ CNT="$(cat "$WORK/sec.count" 2>/dev/null || echo 0)"
336
+ if [ "$MODE" = plan ]; then
337
+ if [ "$CNT" -eq 0 ]; then
338
+ [ "$(marker_count "$SRC")" -gt 0 ] && { echo "I found a hold that is not inside a hold section I can read, so I am treating it as still on hold."; exit 2; } # mut:stray
339
+ echo "No holds are recorded, so there is nothing to wait for."
340
+ echo "holds: 0 discharged: 0 standing: 0"
341
+ exit 0
342
+ fi
343
+ nonblank=0; ND=0; NE=0; NH=0; : > "$WORK/items"
344
+ for ((s = 1; s <= CNT; s++)); do
345
+ awk 'NR > 1 && /[^ \t\r]/ { f = 1 } END { exit (f ? 0 : 1) }' "$WORK/sec.$s" && nonblank=1
346
+ parse_items "$WORK/sec.$s" plan > "$WORK/items.$s"
347
+ cat "$WORK/items.$s" >> "$WORK/items"
348
+ done
349
+ if [ "$nonblank" -eq 0 ]; then
350
+ [ "$(marker_count "$SRC")" -eq 0 ] || { echo "I found a hold that is not inside a hold section I can read, so I am treating it as still on hold."; exit 2; }
351
+ echo "No holds are recorded, so there is nothing to wait for."
352
+ echo "holds: 0 discharged: 0 standing: 0"
353
+ exit 0
354
+ fi
355
+ ND="$(grep -c '^DELEG' "$WORK/items" || true)"; NE="$(grep -c '^ENVF' "$WORK/items" || true)"; NH="$(grep -c '^HOLD' "$WORK/items" || true)"
356
+ [ "$ND" -gt 0 ] || { echo "No standing approval is recorded, so the usual check applies."; [ "$NH" -eq 0 ] || echo "holds: $NH discharged: 0 standing: $NH"; exit 3; } # mut:no-deleg
357
+ PARSED="$(grep -c '^\(HOLD\|GATE\|ORPHAN\)' "$WORK/items" || true)"
358
+ [ "$(marker_count "$SRC")" -eq "$PARSED" ] || { echo "I found a hold that is not inside a hold section I can read, so I am treating every hold as still on hold."; echo "holds: $NH discharged: 0 standing: $NH"; exit 2; } # mut:stray-all
359
+ [ "$ND" -eq 1 ] || stall_unchecked "More than one standing approval is named, so I am treating every hold as still on hold." "the standing approval is not clear" # mut:deleg-multi
360
+ [ "$CNT" -eq 1 ] || stall_unchecked "The plan has more than one hold section, so I am treating every hold as still on hold." "the plan is not clear"
361
+ [ "$NE" -eq 1 ] || stall_unchecked "The standing approval does not name exactly one runbook it covers, so I am treating every hold as still on hold." "the standing approval is incomplete" # mut:envelope-req
362
+ need_tools
363
+ if grep -q '^ORPHAN' "$WORK/items"; then echo "A condition is written outside any hold, so I am treating every hold as still on hold."; echo "holds: $NH discharged: 0 standing: $NH"; exit 2; fi
364
+ [ "$NH" -gt 0 ] || { echo "I found a hold section but could not read any hold in it, so I am treating it as still on hold."; exit 2; } # mut:zero-holds
365
+ DELEG="$(awk -F'\t' '$1 == "DELEG" { print $2; exit }' "$WORK/items")"
366
+ ENVF="$(awk -F'\t' '$1 == "ENVF" { print $2; exit }' "$WORK/items")"
367
+ [ -f "$VERIFY" ] || { echo "I could not find the standing-approval checker, so every hold stays on hold."; echo "holds: $NH discharged: 0 standing: $NH"; exit 2; }
368
+ ${TO60[@]+"${TO60[@]}"} bash "$VERIFY" verify --delegation "$DELEG" --envelope "$ENVF" </dev/null > "$WORK/verdict" 2>"$WORK/verdict.err"; VRC=$? # mut:stdin-verify
369
+ VLINE="$(head -1 "$WORK/verdict" 2>/dev/null)"; VSTATE=""; VTOKEN=""
370
+ if [[ "$VLINE" =~ ^delegation:\ (valid|invalid|unverifiable)\ reason=([a-z0-9-]+)$ ]]; then VSTATE="${BASH_REMATCH[1]}"; VTOKEN="${BASH_REMATCH[2]}"; fi
371
+ VOK=0; [ "$VSTATE" = valid ] && [ "$VRC" -eq 0 ] && VOK=1 # mut:deleg-rc
372
+ if [ "$VOK" -eq 1 ]; then
373
+ echo "delegation: valid reason=$VTOKEN"
374
+ else
375
+ [ -n "$VSTATE" ] || { VSTATE=unverifiable; VTOKEN=no-answer; }
376
+ FITS=no; [ "$VSTATE" = invalid ] && [ "$VRC" -eq 1 ] && FITS=fits
377
+ [ "$VSTATE" = valid ] && { VSTATE=unverifiable; VTOKEN=verifier-error; }
378
+ [ "$VSTATE" = invalid ] && [ "$FITS" != fits ] && { VSTATE=unverifiable; VTOKEN=verifier-error; }
379
+ stand_all "$VSTATE" "$VTOKEN" "$FITS" # mut:deleg-valid
380
+ fi
381
+ else
382
+ [ "$CNT" -eq 1 ] || { echo "I could not find exactly one matching envelope section, so I am treating its conditions as not met."; exit 2; }
383
+ need_tools
384
+ parse_items "$WORK/sec.1" "$MODE" > "$WORK/items"
385
+ NH="$(grep -c '^HOLD' "$WORK/items" || true)"
386
+ [ "$(grep -c '^GATE' "$WORK/items" || true)" -ge 1 ] || { echo "The envelope lists no conditions I can check, so I am treating them as not met."; exit 2; }
387
+ fi
388
+
389
+ DISCHARGED=0; STANDING=0; ANY_UNEVAL=0
390
+ while IFS=$'\t' read -r _ i text; do
391
+ lt="$(printf '%s' "$text" | tr 'A-Z' 'a-z')"
392
+ rn="$(printf '%s' "$lt" | tr -cd 'a-z0-9' | cut -c1-16)" # mut:reserved-norm
393
+ case "$rn" in operatorreserved) print_result_line RESERVED "$text" ""; STANDING=$((STANDING + 1)); ANY_UNEVAL=1; continue ;; esac # mut:reserved
394
+ awk -F'\t' -v i="$i" '$1 == "GATE" && $2 == i { print $3 }' "$WORK/items" > "$WORK/g.$i"
395
+ ng="$(wc -l < "$WORK/g.$i" | tr -d ' ')"
396
+ HV=OK; WHY=""; GTXT=""
397
+ [ "$ng" -gt 0 ] || HV=NEEDS # mut:zero-gates
398
+ while IFS= read -r gate; do
399
+ eval_gate "$gate"
400
+ GTXT="${GTXT:+$GTXT; }$gate"
401
+ case "$GRES" in TRUE) ;; FALSE) [ "$HV" = OK ] && { HV=WAIT; WHY="$GWHY"; } ;; *) HV=UNEVAL; WHY="$GWHY"; ANY_UNEVAL=1 ;; esac # mut:all-gates
402
+ done < "$WORK/g.$i"
403
+ print_result_line "$HV" "$text" "$WHY" "$GTXT"
404
+ if [ "$HV" = OK ]; then DISCHARGED=$((DISCHARGED + 1)); else STANDING=$((STANDING + 1)); fi
405
+ done < <(grep '^HOLD' "$WORK/items")
406
+
407
+ echo "holds: $NH discharged: $DISCHARGED standing: $STANDING"
408
+ [ "$ANY_UNEVAL" -eq 0 ] || exit 2
409
+ [ "$STANDING" -eq 0 ] || exit 1
410
+ exit 0