forge-workflow 0.0.9 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (479) hide show
  1. package/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
  2. package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
  3. package/.cursor/rules/permissions-guidance.mdc +2 -2
  4. package/.forge/hooks/check-tdd.js +3 -0
  5. package/.forge/hooks/forge-native-hook.js +245 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +151 -61
  8. package/CHANGELOG.md +681 -0
  9. package/CLAUDE.md +9 -106
  10. package/QUICKSTART.md +171 -0
  11. package/README.md +271 -363
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +466 -489
  15. package/docs/INDEX.md +93 -0
  16. package/docs/PROJECT_DESIGN.md +685 -0
  17. package/docs/architecture/index.md +66 -0
  18. package/docs/architecture/notes/README.md +35 -0
  19. package/docs/architecture/subsystems/README.md +46 -0
  20. package/docs/{TOOLCHAIN.md → forge/TOOLCHAIN.md} +56 -47
  21. package/docs/forge/VALIDATION.md +82 -0
  22. package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
  23. package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
  24. package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
  25. package/docs/guides/GREPTILE_SETUP.md +46 -0
  26. package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
  27. package/docs/guides/MIGRATION.md +56 -0
  28. package/docs/guides/SETUP.md +118 -0
  29. package/docs/guides/SUPPORT.md +185 -0
  30. package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
  31. package/docs/guides/memory-backends.md +183 -0
  32. package/docs/reference/ADAPTERS.md +128 -0
  33. package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
  34. package/docs/reference/COMMANDS.md +205 -0
  35. package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
  36. package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
  37. package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
  38. package/docs/reference/HERMES_INTEGRATION.md +118 -0
  39. package/docs/reference/INSIGHTS_RECAP.md +63 -0
  40. package/docs/reference/INSTALL.md +164 -0
  41. package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
  42. package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
  43. package/docs/reference/RELEASE.md +68 -0
  44. package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
  45. package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
  46. package/docs/reference/SKILLS.md +35 -0
  47. package/docs/reference/STATUS_BOARD.md +80 -0
  48. package/docs/reference/TEMPLATES.md +106 -0
  49. package/docs/reference/TOOLCHAIN.md +658 -0
  50. package/docs/reference/VALIDATION.md +82 -0
  51. package/docs/reference/agent-permissions.md +169 -0
  52. package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
  53. package/docs/reference/control-plane-guarantees.md +125 -0
  54. package/docs/reference/dependency-chain.md +331 -0
  55. package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
  56. package/docs/reference/forge-kernel-schema.md +72 -0
  57. package/docs/reference/kernel-conflict-evaluators.md +27 -0
  58. package/docs/reference/patch-md-format.md +77 -0
  59. package/docs/reference/protected-state-surfaces.md +59 -0
  60. package/docs/reference/shepherd.md +115 -0
  61. package/docs/reference/superpowers-analysis.md +320 -0
  62. package/docs/reference/superpowers-integration-options.md +404 -0
  63. package/docs/reference/test-environment.md +519 -0
  64. package/docs/reference/upgrade-safety.md +59 -0
  65. package/lefthook.yml +18 -0
  66. package/lib/adapter-cli.js +307 -0
  67. package/lib/adapters/beads-issue-adapter.js +127 -0
  68. package/lib/adapters/beads-kernel-compat.js +1042 -0
  69. package/lib/adapters/greptile-review-adapter.js +141 -0
  70. package/lib/adapters/kernel-issue-adapter.js +101 -0
  71. package/lib/adapters/pr-state-adapter.js +484 -0
  72. package/lib/adoption-profiles.js +126 -0
  73. package/lib/agents/README.md +2 -6
  74. package/lib/agents/claude.plugin.json +3 -8
  75. package/lib/agents/codex.plugin.json +9 -1
  76. package/lib/agents/cursor.plugin.json +2 -6
  77. package/lib/agents/hermes.plugin.json +22 -0
  78. package/lib/agents-config.js +39 -1236
  79. package/lib/audit-evidence.js +282 -0
  80. package/lib/beads-setup.js +225 -28
  81. package/lib/beads-sync-scaffold.js +36 -107
  82. package/lib/codex-skills.js +51 -1
  83. package/lib/commands/_issue.js +744 -70
  84. package/lib/commands/_manifest.js +91 -0
  85. package/lib/commands/_registry.js +85 -34
  86. package/lib/commands/_resolve-command-opts.js +261 -0
  87. package/lib/commands/_serve-security.js +270 -0
  88. package/lib/commands/adapter.js +12 -0
  89. package/lib/commands/add.js +118 -0
  90. package/lib/commands/audit.js +70 -0
  91. package/lib/commands/blocked.js +5 -0
  92. package/lib/commands/board.js +64 -0
  93. package/lib/commands/claim.js +21 -2
  94. package/lib/commands/claims.js +7 -0
  95. package/lib/commands/clean.js +485 -75
  96. package/lib/commands/close.js +2 -2
  97. package/lib/commands/comment.js +5 -0
  98. package/lib/commands/control.js +148 -0
  99. package/lib/commands/create.js +2 -2
  100. package/lib/commands/dev.js +185 -7
  101. package/lib/commands/doc-gate.js +336 -0
  102. package/lib/commands/doctor.js +156 -0
  103. package/lib/commands/explain.js +15 -0
  104. package/lib/commands/export.js +237 -0
  105. package/lib/commands/gate.js +192 -0
  106. package/lib/commands/hooks.js +242 -0
  107. package/lib/commands/inbox.js +118 -0
  108. package/lib/commands/init.js +598 -0
  109. package/lib/commands/insights.js +79 -0
  110. package/lib/commands/issue.js +12 -1
  111. package/lib/commands/issues.js +66 -0
  112. package/lib/commands/lint.js +5 -0
  113. package/lib/commands/list.js +2 -2
  114. package/lib/commands/merge.js +312 -0
  115. package/lib/commands/migrate.js +523 -0
  116. package/lib/commands/new.js +12 -0
  117. package/lib/commands/options.js +241 -0
  118. package/lib/commands/orient.js +13 -0
  119. package/lib/commands/orphans.js +5 -0
  120. package/lib/commands/patch.js +67 -0
  121. package/lib/commands/plan.js +436 -24
  122. package/lib/commands/preflight.js +211 -0
  123. package/lib/commands/prime.js +13 -0
  124. package/lib/commands/push.js +69 -2
  125. package/lib/commands/ready.js +2 -2
  126. package/lib/commands/recall.js +116 -0
  127. package/lib/commands/recap.js +61 -0
  128. package/lib/commands/recommend.js +22 -2
  129. package/lib/commands/release.js +91 -0
  130. package/lib/commands/remember.js +74 -0
  131. package/lib/commands/role.js +99 -0
  132. package/lib/commands/serve.js +581 -0
  133. package/lib/commands/setup.js +851 -979
  134. package/lib/commands/shepherd.js +436 -0
  135. package/lib/commands/ship.js +23 -1
  136. package/lib/commands/show.js +2 -2
  137. package/lib/commands/stage.js +192 -0
  138. package/lib/commands/stale.js +5 -0
  139. package/lib/commands/status.js +329 -11
  140. package/lib/commands/sync.js +34 -46
  141. package/lib/commands/team.js +15 -2
  142. package/lib/commands/test.js +58 -7
  143. package/lib/commands/update.js +2 -2
  144. package/lib/commands/upgrade.js +47 -0
  145. package/lib/commands/validate.js +56 -25
  146. package/lib/commands/worktree.js +308 -128
  147. package/lib/config-writer.js +202 -0
  148. package/lib/control-plane.js +236 -0
  149. package/lib/core/runtime-graph.js +946 -0
  150. package/lib/dep-guard/keyword-ripple.js +184 -0
  151. package/lib/deprecated-sync-cleanup.js +362 -0
  152. package/lib/detect-agent.js +2 -28
  153. package/lib/detect-worktree.js +42 -17
  154. package/lib/doc-gate/declaration.js +177 -0
  155. package/lib/doc-gate/detect.js +289 -0
  156. package/lib/doc-gate/gate.js +375 -0
  157. package/lib/doc-gate/okf-config.js +128 -0
  158. package/lib/doc-gate/okf.js +429 -0
  159. package/lib/docs-command.js +1161 -6
  160. package/lib/forge-issues.js +697 -0
  161. package/lib/forge-lock.js +262 -0
  162. package/lib/gate-events.js +193 -0
  163. package/lib/global-flags.js +74 -0
  164. package/lib/greptile-match.js +7 -63
  165. package/lib/harness-capability-matrix.js +380 -0
  166. package/lib/hook-global-installer.js +347 -0
  167. package/lib/hook-renderer.js +451 -0
  168. package/lib/inbox.js +391 -0
  169. package/lib/insights.js +397 -0
  170. package/lib/issue-adapter.js +156 -0
  171. package/lib/issue-backend.js +145 -0
  172. package/lib/issue-render.js +220 -0
  173. package/lib/issue-sync/authority.js +100 -0
  174. package/lib/issue-sync/github-pull.js +184 -0
  175. package/lib/issue-sync/import-primitives.js +98 -0
  176. package/lib/issue-sync/legacy-link-bridge.js +436 -0
  177. package/lib/issue-sync/link-store.js +292 -0
  178. package/lib/issue-sync/project-github.js +123 -0
  179. package/lib/issue-sync/reconcile.js +195 -0
  180. package/lib/issue-sync/schema.js +126 -0
  181. package/lib/kernel/backing-issue.js +305 -0
  182. package/lib/kernel/broker.js +1218 -0
  183. package/lib/kernel/cli-broker-factory.js +130 -0
  184. package/lib/kernel/conflict-signal.js +82 -0
  185. package/lib/kernel/evaluators.js +195 -0
  186. package/lib/kernel/fs-class.js +495 -0
  187. package/lib/kernel/issue-command-contract.js +559 -0
  188. package/lib/kernel/issue-id-resolver.js +186 -0
  189. package/lib/kernel/lease-enforcer.js +158 -0
  190. package/lib/kernel/migrations.js +333 -0
  191. package/lib/kernel/planning-buckets-schema.js +109 -0
  192. package/lib/kernel/projection-jsonl-writer.js +450 -0
  193. package/lib/kernel/readiness-model.js +329 -0
  194. package/lib/kernel/schema.js +356 -0
  195. package/lib/kernel/sqlite-driver.js +2504 -0
  196. package/lib/kernel/taxonomy-validator.js +394 -0
  197. package/lib/lefthook-check.js +8 -4
  198. package/lib/lefthook-wiring.js +413 -0
  199. package/lib/mcp-config-renderer.js +288 -0
  200. package/lib/memory/graphiti-mcp.js +106 -0
  201. package/lib/memory/router.js +387 -0
  202. package/lib/memory/typed-api.js +102 -0
  203. package/lib/memory-digest.js +195 -0
  204. package/lib/merge-rules.js +395 -0
  205. package/lib/migrate-dry-run.js +466 -0
  206. package/lib/orientation.js +863 -0
  207. package/lib/package-manager-remediation.js +103 -0
  208. package/lib/package-root.js +381 -0
  209. package/lib/patch-intent.js +890 -0
  210. package/lib/plugin-catalog.js +3 -4
  211. package/lib/plugin-manager.js +0 -5
  212. package/lib/pr-bundle.js +186 -0
  213. package/lib/pr-monitor/differ.js +195 -0
  214. package/lib/pr-monitor/events.js +0 -0
  215. package/lib/pr-monitor/gather.js +124 -0
  216. package/lib/pr-monitor/journal.js +299 -0
  217. package/lib/pr-monitor/monitor.js +146 -0
  218. package/lib/pr-monitor/render-sticky.js +157 -0
  219. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  220. package/lib/pr-monitor/watch.js +247 -0
  221. package/lib/pr-pull.js +1273 -0
  222. package/lib/pr-shepherd.js +494 -0
  223. package/lib/pr-state-validator.js +59 -0
  224. package/lib/preflight/gates.js +237 -0
  225. package/lib/preflight/runner.js +116 -0
  226. package/lib/project-discovery.js +0 -53
  227. package/lib/project-memory.js +166 -0
  228. package/lib/protected-path-manifest.js +281 -0
  229. package/lib/protected-state-surfaces.js +387 -0
  230. package/lib/release-readiness.js +2089 -0
  231. package/lib/reset.js +59 -45
  232. package/lib/review-adapter.js +68 -0
  233. package/lib/rules-sync.js +260 -0
  234. package/lib/runtime-health.js +332 -23
  235. package/lib/safety-config-renderer.js +268 -0
  236. package/lib/setup-action-log.js +1 -7
  237. package/lib/setup.js +27 -65
  238. package/lib/shell-utils.js +76 -6
  239. package/lib/skills-sync.js +330 -0
  240. package/lib/smart-status/conflicts.js +205 -0
  241. package/lib/smart-status/scoring.js +191 -0
  242. package/lib/status/beads-snapshot.js +145 -0
  243. package/lib/status/presenter.js +216 -0
  244. package/lib/status/snapshot.js +186 -0
  245. package/lib/sync-backend.js +202 -0
  246. package/lib/untrusted-content.js +52 -0
  247. package/lib/upgrade-safety.js +199 -0
  248. package/lib/workflow/enforce-stage.js +298 -47
  249. package/lib/workflow/stage-transition.js +115 -0
  250. package/lib/workflow/stages.js +30 -6
  251. package/lib/workflow/state-manager.js +159 -14
  252. package/lib/workflow/state.js +23 -1
  253. package/lib/workflow-profiles.js +17 -5
  254. package/package.json +46 -36
  255. package/rules/documentation.md +19 -0
  256. package/rules/kernel-tracking.md +26 -0
  257. package/rules/security.md +22 -0
  258. package/rules/tdd.md +20 -0
  259. package/rules/workflow.md +27 -0
  260. package/scripts/auto-backing-issue.js +47 -0
  261. package/scripts/beads-context.sh +165 -22
  262. package/scripts/beads-migrate-to-dolt.sh +7 -0
  263. package/scripts/beads-upgrade-smoke.sh +284 -0
  264. package/scripts/behavioral-judge.sh +115 -11
  265. package/scripts/benchmark.js +349 -63
  266. package/scripts/bootstrap-windows-tools.sh +78 -0
  267. package/scripts/branch-protection.js +2 -3
  268. package/scripts/check-agents.js +34 -137
  269. package/scripts/commitlint.js +3 -1
  270. package/scripts/conflict-detect.sh +3 -0
  271. package/scripts/dep-guard-analyze.js +52 -17
  272. package/scripts/dep-guard-keyword-ripple.js +29 -0
  273. package/scripts/dep-guard-render-review.js +86 -0
  274. package/scripts/dep-guard.sh +64 -232
  275. package/scripts/file-index.sh +3 -0
  276. package/scripts/forge-team/lib/claim.sh +34 -18
  277. package/scripts/forge-team/lib/dashboard.sh +61 -86
  278. package/scripts/forge-team/lib/epic.sh +99 -263
  279. package/scripts/forge-team/lib/hooks.sh +26 -28
  280. package/scripts/forge-team/lib/identity.sh +4 -4
  281. package/scripts/forge-team/lib/sync-github.sh +144 -47
  282. package/scripts/forge-team/lib/verify.sh +93 -83
  283. package/scripts/forge-team/lib/workload.sh +41 -65
  284. package/scripts/forge-team/tests/claim.test.sh +25 -19
  285. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  286. package/scripts/forge-team/tests/epic.test.sh +52 -71
  287. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  288. package/scripts/forge-team/tests/identity.test.sh +3 -3
  289. package/scripts/forge-team/tests/integration.test.sh +44 -66
  290. package/scripts/forge-team/tests/sync-github.test.sh +183 -79
  291. package/scripts/forge-team/tests/verify.test.sh +37 -46
  292. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  293. package/scripts/forge-team/tests/workload.test.sh +32 -66
  294. package/scripts/gen-command-manifest.js +153 -0
  295. package/scripts/gen-embedded-assets.mjs +129 -0
  296. package/scripts/install.ps1 +139 -0
  297. package/scripts/install.sh +268 -0
  298. package/scripts/lib/beads-migrate-to-dolt.mjs +503 -0
  299. package/scripts/lib/release-asset.mjs +84 -0
  300. package/scripts/parity-check.mjs +145 -0
  301. package/scripts/parity-check.test.mjs +58 -0
  302. package/scripts/pin-agentic-workflow-images.js +112 -0
  303. package/scripts/pr-coordinator.sh +3 -0
  304. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  305. package/scripts/preflight.sh +108 -0
  306. package/scripts/protected-state-check.js +104 -0
  307. package/scripts/smart-status-score.js +31 -0
  308. package/scripts/smart-status-sessions.js +51 -0
  309. package/scripts/smart-status.sh +117 -369
  310. package/scripts/spikes/config-race-bench.js +111 -0
  311. package/scripts/spikes/harness-capability-matrix.js +13 -0
  312. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  313. package/scripts/spikes/protected-path-manifest.js +20 -0
  314. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  315. package/scripts/sync-agent-skills.js +62 -0
  316. package/scripts/sync-agentic-workflow.js +48 -0
  317. package/scripts/sync-utils.sh +3 -0
  318. package/scripts/test-ci-shard.js +251 -0
  319. package/scripts/test-dashboard.js +188 -52
  320. package/scripts/test-full-suite.js +186 -0
  321. package/scripts/test-profile.js +278 -0
  322. package/scripts/test.js +302 -28
  323. package/scripts/validate.js +143 -0
  324. package/scripts/validate.sh +18 -1
  325. package/skills/claim-safety/SKILL.md +102 -0
  326. package/skills/claim-safety/evals/evals.json +46 -0
  327. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +46 -52
  328. package/skills/dev/evals/evals.json +50 -0
  329. package/skills/hermes-forge/SKILL.md +185 -0
  330. package/skills/hermes-forge/evals/evals.json +46 -0
  331. package/skills/issue-basics/SKILL.md +111 -0
  332. package/skills/issue-basics/evals/evals.json +46 -0
  333. package/skills/kernel/SKILL.md +166 -0
  334. package/skills/kernel/evals/evals.json +50 -0
  335. package/skills/memory/SKILL.md +102 -0
  336. package/skills/parallel-deep-research/SKILL.md +14 -11
  337. package/skills/parallel-deep-research/evals/evals.json +11 -27
  338. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +134 -159
  339. package/skills/plan/evals/evals.json +42 -0
  340. package/skills/research/SKILL.md +195 -0
  341. package/skills/research/evals/evals.json +42 -0
  342. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  343. package/skills/review/evals/evals.json +42 -0
  344. package/skills/rollback/SKILL.md +110 -0
  345. package/skills/rollback/evals/evals.json +46 -0
  346. package/skills/rollback/references/methods.md +204 -0
  347. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  348. package/skills/shepherd/SKILL.md +66 -0
  349. package/skills/shepherd/evals/evals.json +42 -0
  350. package/skills/ship/SKILL.md +251 -0
  351. package/skills/ship/evals/evals.json +42 -0
  352. package/skills/smith/SKILL.md +142 -0
  353. package/skills/smith/evals/evals.json +46 -0
  354. package/skills/smith/references/autonomy-and-gates.md +94 -0
  355. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  356. package/skills/sonarcloud/evals/evals.json +46 -0
  357. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  358. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  359. package/skills/status/SKILL.md +102 -0
  360. package/skills/status/evals/evals.json +50 -0
  361. package/skills/triage-ready/SKILL.md +121 -0
  362. package/skills/triage-ready/evals/evals.json +42 -0
  363. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  364. package/skills/validate/evals/evals.json +42 -0
  365. package/skills/verify/SKILL.md +299 -0
  366. package/skills/verify/evals/evals.json +50 -0
  367. package/.claude/commands/dev.md +0 -345
  368. package/.claude/commands/plan.md +0 -566
  369. package/.claude/commands/premerge.md +0 -186
  370. package/.claude/commands/research.md +0 -42
  371. package/.claude/commands/review.md +0 -451
  372. package/.claude/commands/rollback.md +0 -721
  373. package/.claude/commands/ship.md +0 -213
  374. package/.claude/commands/sonarcloud.md +0 -152
  375. package/.claude/commands/status.md +0 -90
  376. package/.claude/commands/validate.md +0 -288
  377. package/.claude/commands/verify.md +0 -269
  378. package/.claude/rules/workflow.md +0 -121
  379. package/.cline/workflows/dev.md +0 -342
  380. package/.cline/workflows/plan.md +0 -563
  381. package/.cline/workflows/premerge.md +0 -183
  382. package/.cline/workflows/research.md +0 -39
  383. package/.cline/workflows/review.md +0 -448
  384. package/.cline/workflows/rollback.md +0 -718
  385. package/.cline/workflows/ship.md +0 -210
  386. package/.cline/workflows/sonarcloud.md +0 -146
  387. package/.cline/workflows/status.md +0 -87
  388. package/.cline/workflows/validate.md +0 -285
  389. package/.cline/workflows/verify.md +0 -266
  390. package/.codex/config.toml +0 -11
  391. package/.codex/skills/dev/SKILL.md +0 -345
  392. package/.codex/skills/plan/SKILL.md +0 -566
  393. package/.codex/skills/premerge/SKILL.md +0 -186
  394. package/.codex/skills/research/SKILL.md +0 -42
  395. package/.codex/skills/review/SKILL.md +0 -451
  396. package/.codex/skills/rollback/SKILL.md +0 -721
  397. package/.codex/skills/ship/SKILL.md +0 -213
  398. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  399. package/.codex/skills/status/SKILL.md +0 -90
  400. package/.codex/skills/validate/SKILL.md +0 -288
  401. package/.codex/skills/verify/SKILL.md +0 -269
  402. package/.cursor/commands/dev.md +0 -342
  403. package/.cursor/commands/plan.md +0 -563
  404. package/.cursor/commands/premerge.md +0 -183
  405. package/.cursor/commands/research.md +0 -39
  406. package/.cursor/commands/review.md +0 -448
  407. package/.cursor/commands/ship.md +0 -210
  408. package/.cursor/commands/sonarcloud.md +0 -146
  409. package/.cursor/commands/status.md +0 -87
  410. package/.cursor/commands/validate.md +0 -285
  411. package/.cursor/commands/verify.md +0 -266
  412. package/.cursorrules +0 -149
  413. package/.github/prompts/premerge.prompt.md +0 -188
  414. package/.github/prompts/research.prompt.md +0 -44
  415. package/.github/prompts/rollback.prompt.md +0 -723
  416. package/.github/prompts/ship.prompt.md +0 -215
  417. package/.github/prompts/status.prompt.md +0 -92
  418. package/.github/prompts/verify.prompt.md +0 -271
  419. package/.github/workflows/beads-to-github.yml +0 -56
  420. package/.github/workflows/github-to-beads.yml +0 -97
  421. package/.kilocode/workflows/dev.md +0 -346
  422. package/.kilocode/workflows/plan.md +0 -567
  423. package/.kilocode/workflows/premerge.md +0 -187
  424. package/.kilocode/workflows/research.md +0 -43
  425. package/.kilocode/workflows/review.md +0 -452
  426. package/.kilocode/workflows/rollback.md +0 -722
  427. package/.kilocode/workflows/ship.md +0 -214
  428. package/.kilocode/workflows/sonarcloud.md +0 -150
  429. package/.kilocode/workflows/status.md +0 -91
  430. package/.kilocode/workflows/validate.md +0 -289
  431. package/.kilocode/workflows/verify.md +0 -270
  432. package/.opencode/commands/dev.md +0 -345
  433. package/.opencode/commands/plan.md +0 -566
  434. package/.opencode/commands/premerge.md +0 -186
  435. package/.opencode/commands/research.md +0 -42
  436. package/.opencode/commands/review.md +0 -451
  437. package/.opencode/commands/rollback.md +0 -721
  438. package/.opencode/commands/ship.md +0 -213
  439. package/.opencode/commands/sonarcloud.md +0 -149
  440. package/.opencode/commands/status.md +0 -90
  441. package/.opencode/commands/validate.md +0 -288
  442. package/.opencode/commands/verify.md +0 -269
  443. package/.roo/commands/dev.md +0 -346
  444. package/.roo/commands/plan.md +0 -567
  445. package/.roo/commands/premerge.md +0 -187
  446. package/.roo/commands/research.md +0 -43
  447. package/.roo/commands/review.md +0 -452
  448. package/.roo/commands/rollback.md +0 -722
  449. package/.roo/commands/ship.md +0 -214
  450. package/.roo/commands/sonarcloud.md +0 -150
  451. package/.roo/commands/status.md +0 -91
  452. package/.roo/commands/validate.md +0 -289
  453. package/.roo/commands/verify.md +0 -270
  454. package/docs/BEADS_GITHUB_SYNC.md +0 -255
  455. package/docs/GREPTILE_SETUP.md +0 -400
  456. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  457. package/docs/SETUP.md +0 -663
  458. package/docs/VALIDATION.md +0 -363
  459. package/lib/agents/cline.plugin.json +0 -29
  460. package/lib/agents/copilot.plugin.json +0 -24
  461. package/lib/agents/kilocode.plugin.json +0 -22
  462. package/lib/agents/opencode.plugin.json +0 -23
  463. package/lib/agents/roo.plugin.json +0 -30
  464. package/lib/beads-health-check.js +0 -143
  465. package/lib/commands/commands-reset.js +0 -147
  466. package/opencode.json +0 -67
  467. package/scripts/beads-context.test.js +0 -567
  468. package/scripts/github-beads-sync/comment.mjs +0 -64
  469. package/scripts/github-beads-sync/config.mjs +0 -148
  470. package/scripts/github-beads-sync/github-api.mjs +0 -131
  471. package/scripts/github-beads-sync/index.mjs +0 -332
  472. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  473. package/scripts/github-beads-sync/mapping.mjs +0 -78
  474. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  475. package/scripts/github-beads-sync/reverse-sync.mjs +0 -138
  476. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  477. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  478. package/scripts/github-beads-sync.config.json +0 -26
  479. package/scripts/sync-commands.js +0 -600
@@ -0,0 +1,202 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module config-writer
5
+ *
6
+ * Sparse read-modify-write for the ONE schema-validated config surface,
7
+ * `.forge/config.yaml` (the file `lib/core/runtime-graph.js` reads via
8
+ * `loadRuntimeGraphConfig`). This is the single missing primitive behind the
9
+ * `forge gate` / `forge role` verbs: create-or-update the file, set/remove one
10
+ * nested key, and preserve every other key untouched.
11
+ *
12
+ * Design: docs/work/2026-07-04-kernel-native-skills/extensibility-architecture.md
13
+ * (§9 "the sparse writer"). This is NOT a generalization of the legacy
14
+ * `.forge/adapters.json` review writer — that path stays where it is.
15
+ *
16
+ * Key paths are ARRAYS of segments, not dotted strings, because real keys
17
+ * contain dots (e.g. the gate id `gate.plan-exit`). Splitting on `.` would
18
+ * corrupt them, so callers pass `['workflow', 'gates', 'gate.plan-exit',
19
+ * 'enabled']`.
20
+ */
21
+
22
+ const fs = require('node:fs');
23
+ const path = require('node:path');
24
+ const YAML = require('yaml');
25
+ const { getPackageRoot } = require('./package-root');
26
+
27
+ /** Root of the installed Forge package (ships the canonical `skills/` dir). */
28
+ const PACKAGE_ROOT = path.join(__dirname, '..');
29
+
30
+ const CONFIG_RELATIVE = path.join('.forge', 'config.yaml');
31
+
32
+ function getConfigPath(projectRoot = process.cwd()) {
33
+ return path.join(projectRoot, '.forge', 'config.yaml');
34
+ }
35
+
36
+ function assertKeyPath(keyPath) {
37
+ if (!Array.isArray(keyPath) || keyPath.length === 0
38
+ || keyPath.some(seg => typeof seg !== 'string' || seg === '')) {
39
+ throw new Error('config-writer: keyPath must be a non-empty array of non-empty string segments.');
40
+ }
41
+ }
42
+
43
+ /** Load the raw config object (or `{}` if the file is absent/empty). */
44
+ function loadRawConfig(projectRoot = process.cwd()) {
45
+ const configPath = getConfigPath(projectRoot);
46
+ if (!fs.existsSync(configPath)) return {};
47
+ const raw = fs.readFileSync(configPath, 'utf8');
48
+ if (raw.trim() === '') return {};
49
+ const parsed = YAML.parse(raw);
50
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
51
+ throw new Error(`${CONFIG_RELATIVE} root must be an object.`);
52
+ }
53
+ return parsed;
54
+ }
55
+
56
+ function writeRawConfig(projectRoot, config) {
57
+ const configPath = getConfigPath(projectRoot);
58
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
59
+ fs.writeFileSync(configPath, YAML.stringify(config));
60
+ return configPath;
61
+ }
62
+
63
+ /**
64
+ * Set a nested key to `value`, creating intermediate objects as needed and
65
+ * preserving all sibling keys. Creates `.forge/config.yaml` if absent.
66
+ *
67
+ * @param {string} projectRoot
68
+ * @param {string[]} keyPath - Segments, e.g. ['roles', 'plan', 'skill'].
69
+ * @param {*} value
70
+ * @returns {{config: object, configPath: string}}
71
+ */
72
+ function setConfigOverride(projectRoot, keyPath, value) {
73
+ assertKeyPath(keyPath);
74
+ const config = loadRawConfig(projectRoot);
75
+ let node = config;
76
+ for (let i = 0; i < keyPath.length - 1; i += 1) {
77
+ const key = keyPath[i];
78
+ if (!node[key] || typeof node[key] !== 'object' || Array.isArray(node[key])) {
79
+ node[key] = {};
80
+ }
81
+ node = node[key];
82
+ }
83
+ node[keyPath[keyPath.length - 1]] = value;
84
+ return { config, configPath: writeRawConfig(projectRoot, config) };
85
+ }
86
+
87
+ /**
88
+ * Remove a nested key (a "reset" to the profile/default). Prunes ancestor
89
+ * objects that become empty so the surface stays sparse. No-op if the key is
90
+ * absent or the file does not exist.
91
+ *
92
+ * @param {string} projectRoot
93
+ * @param {string[]} keyPath
94
+ * @returns {{config: object, configPath: string, removed: boolean}}
95
+ */
96
+ function removeConfigOverride(projectRoot, keyPath) {
97
+ assertKeyPath(keyPath);
98
+ const configPath = getConfigPath(projectRoot);
99
+ if (!fs.existsSync(configPath)) {
100
+ return { config: {}, configPath, removed: false };
101
+ }
102
+ const config = loadRawConfig(projectRoot);
103
+ const chain = [config];
104
+ let node = config;
105
+ for (let i = 0; i < keyPath.length - 1; i += 1) {
106
+ const key = keyPath[i];
107
+ if (!node[key] || typeof node[key] !== 'object' || Array.isArray(node[key])) {
108
+ return { config, configPath, removed: false };
109
+ }
110
+ node = node[key];
111
+ chain.push(node);
112
+ }
113
+ const leaf = keyPath[keyPath.length - 1];
114
+ if (!Object.hasOwn(node, leaf)) {
115
+ return { config, configPath, removed: false };
116
+ }
117
+ delete node[leaf];
118
+ // Prune now-empty ancestor objects, deepest first.
119
+ for (let i = chain.length - 1; i > 0; i -= 1) {
120
+ if (Object.keys(chain[i]).length === 0) {
121
+ delete chain[i - 1][keyPath[i - 1]];
122
+ } else {
123
+ break;
124
+ }
125
+ }
126
+ return { config, configPath: writeRawConfig(projectRoot, config), removed: true };
127
+ }
128
+
129
+ /** Project-local skill dirs (highest precedence), independent of any extraction. */
130
+ function localSkillSearchDirs(projectRoot = process.cwd()) {
131
+ return [path.join(projectRoot, '.skills'), path.join(projectRoot, 'skills')];
132
+ }
133
+
134
+ /**
135
+ * The packaged (shipped-default) skills dir — resolved LAZILY and NON-throwing.
136
+ * In a compiled binary this triggers asset extraction, so it must only run after
137
+ * the project-local dirs miss (and must never abort skill resolution if assets
138
+ * cannot be resolved). Returns null if unavailable.
139
+ */
140
+ function packagedSkillsDir() {
141
+ try {
142
+ return path.join(getPackageRoot(PACKAGE_ROOT), 'skills');
143
+ } catch {
144
+ return null;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Directories searched (in precedence order) when resolving a skill name.
150
+ * Mirrors the skills-sync precedence: `.skills/` shadow wins over canonical
151
+ * `skills/`, then the installed package's shipped defaults (resolved lazily).
152
+ */
153
+ function skillSearchDirs(projectRoot = process.cwd()) {
154
+ const dirs = localSkillSearchDirs(projectRoot);
155
+ const packaged = packagedSkillsDir();
156
+ if (packaged) dirs.push(packaged);
157
+ return dirs;
158
+ }
159
+
160
+ /**
161
+ * Resolve a skill NAME to a real `SKILL.md` via `.skills/ > skills/`
162
+ * precedence. Returns null if no such skill exists — the `forge role` verb
163
+ * uses this for write-time validation so an unresolvable skill errors before
164
+ * anything is written (never mid-run).
165
+ *
166
+ * @param {string} projectRoot
167
+ * @param {string} name
168
+ * @returns {{name: string, dir: string, path: string}|null}
169
+ */
170
+ function resolveSkill(projectRoot, name) {
171
+ if (typeof name !== 'string' || name === ''
172
+ || name.includes('/') || name.includes('\\') || name.includes('\0')
173
+ || name === '.' || name === '..') {
174
+ return null;
175
+ }
176
+ // Check project-local dirs FIRST — these never trigger extraction, so a
177
+ // project-local skill resolves without touching the packaged fallback.
178
+ for (const dir of localSkillSearchDirs(projectRoot)) {
179
+ const skillMd = path.join(dir, name, 'SKILL.md');
180
+ if (fs.existsSync(skillMd)) {
181
+ return { name, dir, path: skillMd };
182
+ }
183
+ }
184
+ // Only now resolve the packaged fallback (lazy, non-throwing).
185
+ const packaged = packagedSkillsDir();
186
+ if (packaged) {
187
+ const skillMd = path.join(packaged, name, 'SKILL.md');
188
+ if (fs.existsSync(skillMd)) {
189
+ return { name, dir: packaged, path: skillMd };
190
+ }
191
+ }
192
+ return null;
193
+ }
194
+
195
+ module.exports = {
196
+ getConfigPath,
197
+ loadRawConfig,
198
+ setConfigOverride,
199
+ removeConfigOverride,
200
+ resolveSkill,
201
+ skillSearchDirs,
202
+ };
@@ -0,0 +1,236 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module control-plane
5
+ *
6
+ * The single source of truth for the **control-plane guarantee matrix**
7
+ * (docs/reference/control-plane-guarantees.md): it classifies each control
8
+ * surface, names its enforcement-locus, derives the tri-state label, renders the
9
+ * honest read badge, and resolves a `forge control` write-intent into the ONE
10
+ * resolver-enforced field — `workflow.gates.<id>.enabled`.
11
+ *
12
+ * Why this module exists: the cockpit uses a tri-state vocabulary
13
+ * (`mandatory` / `optional` / `permission`), but that vocabulary is only
14
+ * meaningful where Forge can actually DENY at run time — on gates and rails. On
15
+ * MCP servers, rules, and skills there is no run-time deny; "mandatory" there
16
+ * would mean nothing more than *the file is present*. This module draws that
17
+ * line so the UI and the `forge control` command never sell enforcement Forge
18
+ * cannot deliver. Pure + dependency-free so it is trivially testable and shared
19
+ * by the command, `forge options`, and any dashboard snapshot.
20
+ */
21
+
22
+ /** The closed set of human gates — satisfied by a `gate.approved` kernel EVENT. */
23
+ const HUMAN_GATE_IDS = new Set(['gate.intent', 'gate.plan-approval', 'gate.merge']);
24
+
25
+ const CONTROLLABLE_SURFACES = new Set(['gate', 'human-gate', 'rail']);
26
+
27
+ const GUARANTEE_DOC = 'docs/reference/control-plane-guarantees.md';
28
+
29
+ const VALID_STATES = new Set(['mandatory', 'optional', 'permission']);
30
+
31
+ /**
32
+ * Classify a control id into its surface. The id namespaces are disjoint, so a
33
+ * prefix match is unambiguous; the three human gates are singled out because
34
+ * their enforcement-locus (a human approval event) differs from ordinary gates.
35
+ *
36
+ * @param {string} id
37
+ * @returns {'gate'|'human-gate'|'rail'|'mcp'|'rule'|'skill'|'unknown'}
38
+ */
39
+ function classifySurface(id) {
40
+ if (typeof id !== 'string') return 'unknown';
41
+ if (HUMAN_GATE_IDS.has(id)) return 'human-gate';
42
+ if (id.startsWith('gate.')) return 'gate';
43
+ if (id.startsWith('rail.')) return 'rail';
44
+ if (id.startsWith('mcp.')) return 'mcp';
45
+ if (id.startsWith('rule.')) return 'rule';
46
+ if (id.startsWith('skill.')) return 'skill';
47
+ return 'unknown';
48
+ }
49
+
50
+ /**
51
+ * True only for surfaces `forge control` can CONFIGURE (gates + rails).
52
+ *
53
+ * NOTE: "controllable" means CLI-configurable, NOT runtime-enforced — the two are
54
+ * deliberately separate. Configuring one of these writes a declared flag; whether
55
+ * anything actually denies on it is a distinct question answered by
56
+ * `enforcementLocus` (today: nothing does). See docs/reference/control-plane-guarantees.md.
57
+ */
58
+ function isControllable(id) {
59
+ return CONTROLLABLE_SURFACES.has(classifySurface(id));
60
+ }
61
+
62
+ /**
63
+ * The honest enforcement-locus — WHERE and WHETHER Forge actually consumes this
64
+ * flag TODAY (as of 2026-07-15). This deliberately does NOT claim `run-time-deny`
65
+ * for the configurable gates/rails, because an adversarial grep of every consumer
66
+ * of the resolved graph found NONE that denies on `workflow.gates.<id>.enabled`:
67
+ *
68
+ * - stage-exit gates + rails: no runtime consumer reads their `.enabled` to
69
+ * refuse. `enforce-stage.js` enforces stage ORDER + kernel COMPLETION, which
70
+ * is independent of these flags. → "registry — declared, not yet enforced".
71
+ * - `gate.issue_verify`: consumed by lib/commands/_issue.js, but WARN-ONLY —
72
+ * a mismatch prints a warning and never overturns the write's `ok`.
73
+ * - human gates: the `forge gate approve`/`check` primitives are real and
74
+ * deny-CAPABLE, but no chokepoint auto-invokes `forge gate check`, so nothing
75
+ * denies on them yet. → "deny-on-check (no chokepoint yet)".
76
+ *
77
+ * Real enforcement today lives elsewhere and is independent of these flags: the
78
+ * B3 lefthook TDD pre-commit hook, B2 fail-closed `validate`/`preflight`, and
79
+ * `enforce-stage` order+completion. See docs/reference/control-plane-guarantees.md.
80
+ *
81
+ * @param {string} id
82
+ */
83
+ function enforcementLocus(id) {
84
+ const surface = classifySurface(id);
85
+ if (surface === 'human-gate') {
86
+ return 'deny-on-check (deny-capable via forge gate check; no chokepoint invokes it yet)';
87
+ }
88
+ if (id === 'gate.issue_verify') {
89
+ return 'run-time verify (warn-only, never denies)';
90
+ }
91
+ if (surface === 'gate' || surface === 'rail') {
92
+ return 'registry — declared, not yet enforced';
93
+ }
94
+ // mcp / rule / skill / unknown — presence written into harness config only.
95
+ return 'render-time presence-only';
96
+ }
97
+
98
+ /**
99
+ * Derive the tri-state label from the resolver-enforced fields, so state is
100
+ * never stored twice (single source of truth = `enabled`).
101
+ *
102
+ * @param {{id: string, enabled?: boolean}} primitive
103
+ * @returns {'mandatory'|'optional'|'permission'|null} null for advisory surfaces.
104
+ */
105
+ function deriveState(primitive) {
106
+ const surface = classifySurface(primitive.id);
107
+ if (!CONTROLLABLE_SURFACES.has(surface)) return null;
108
+ const enabled = primitive.enabled !== false;
109
+ if (surface === 'human-gate') return enabled ? 'permission' : 'optional';
110
+ return enabled ? 'mandatory' : 'optional';
111
+ }
112
+
113
+ /**
114
+ * The read-view badge: reflects the HONEST wiring status TODAY, never the
115
+ * author's intent, so the UI can never imply enforcement a surface lacks.
116
+ * `ENFORCED` is reserved strictly for a wired runtime deny — a set that is
117
+ * EMPTY today for these configurable flags, so this function never returns it.
118
+ * A `locked` primitive appends a `LOCKED` marker (it cannot be lowered).
119
+ *
120
+ * @param {{id: string, enabled?: boolean, locked?: boolean}} primitive
121
+ * @returns {string}
122
+ */
123
+ function badgeFor(primitive) {
124
+ const surface = classifySurface(primitive.id);
125
+ if (!CONTROLLABLE_SURFACES.has(surface)) return 'PRESENT (advisory)';
126
+
127
+ const enabled = primitive.enabled !== false;
128
+ let badge;
129
+ if (!enabled) {
130
+ badge = 'OFF (optional)';
131
+ } else if (surface === 'human-gate') {
132
+ // Deny-capable via `forge gate check`, but no chokepoint invokes it yet.
133
+ badge = 'DENY-ON-CHECK';
134
+ } else if (primitive.id === 'gate.issue_verify') {
135
+ // Consumed by _issue.js, but warn-only — never overturns a write.
136
+ badge = 'VERIFY (warn-only)';
137
+ } else {
138
+ // stage-exit gates + rails: declared in the registry, no runtime consumer.
139
+ badge = 'DECLARED (no runtime consumer yet)';
140
+ }
141
+ return primitive.locked === true ? `${badge} · LOCKED` : badge;
142
+ }
143
+
144
+ /**
145
+ * The full read record for a primitive — everything a read view / badge needs.
146
+ *
147
+ * @param {{id: string, enabled?: boolean, locked?: boolean}} primitive
148
+ */
149
+ function describeControl(primitive) {
150
+ const surface = classifySurface(primitive.id);
151
+ return {
152
+ id: primitive.id,
153
+ surface,
154
+ controllable: CONTROLLABLE_SURFACES.has(surface),
155
+ state: deriveState(primitive),
156
+ locus: enforcementLocus(primitive.id),
157
+ badge: badgeFor(primitive),
158
+ locked: primitive.locked === true,
159
+ };
160
+ }
161
+
162
+ /**
163
+ * Resolve a `forge control <id> <state>` write-intent into the enabled boolean
164
+ * for `workflow.gates.<id>.enabled` — or an honest refusal. This is the guard
165
+ * that keeps the tri-state vocabulary from over-promising:
166
+ *
167
+ * - advisory surfaces (mcp/rule/skill/unknown) → refused (presence-only).
168
+ * - `permission` is valid ONLY for human gates; elsewhere it has no path.
169
+ * - `mandatory` on a human gate → refused, directed to `permission`.
170
+ * - `optional` on a `locked` primitive → refused (cannot be lowered).
171
+ *
172
+ * @param {{id: string, locked?: boolean}} primitive
173
+ * @param {string} state - requested tri-state
174
+ * @returns {{ok: true, enabled: boolean}|{ok: false, error: string}}
175
+ */
176
+ function planControl(primitive, state) {
177
+ const surface = classifySurface(primitive.id);
178
+
179
+ if (!CONTROLLABLE_SURFACES.has(surface)) {
180
+ return {
181
+ ok: false,
182
+ error: `${primitive.id} is presence-only, not enforceable — Forge has no `
183
+ + `run-time deny for this surface. It stays read-only in the cockpit `
184
+ + `(badge PRESENT (advisory)). See ${GUARANTEE_DOC}.`,
185
+ };
186
+ }
187
+
188
+ if (!VALID_STATES.has(state)) {
189
+ return {
190
+ ok: false,
191
+ error: `Unknown state '${state}'. Use one of: mandatory, optional, permission.`,
192
+ };
193
+ }
194
+
195
+ const isHuman = surface === 'human-gate';
196
+
197
+ if (state === 'permission' && !isHuman) {
198
+ return {
199
+ ok: false,
200
+ error: `'permission' applies only to a human gate `
201
+ + `(${[...HUMAN_GATE_IDS].join(', ')}); ${primitive.id} enforces evidence, `
202
+ + `not approval. Use 'mandatory' or 'optional'. See ${GUARANTEE_DOC}.`,
203
+ };
204
+ }
205
+
206
+ if (state === 'mandatory' && isHuman) {
207
+ return {
208
+ ok: false,
209
+ error: `${primitive.id} is a human gate — it blocks until a human approval `
210
+ + `event, so use 'permission' (not 'mandatory'). See ${GUARANTEE_DOC}.`,
211
+ };
212
+ }
213
+
214
+ if (state === 'optional' && primitive.locked === true) {
215
+ return {
216
+ ok: false,
217
+ error: `Cannot lower locked ${surface} '${primitive.id}' to optional.`,
218
+ };
219
+ }
220
+
221
+ // mandatory / permission → enabled; optional → disabled. Written to the ONE
222
+ // field the resolver honors, so enforcement is genuine.
223
+ return { ok: true, enabled: state !== 'optional' };
224
+ }
225
+
226
+ module.exports = {
227
+ HUMAN_GATE_IDS,
228
+ GUARANTEE_DOC,
229
+ classifySurface,
230
+ isControllable,
231
+ enforcementLocus,
232
+ deriveState,
233
+ badgeFor,
234
+ describeControl,
235
+ planControl,
236
+ };