forge-workflow 0.0.10 → 0.1.0-beta.3

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 (468) 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 +82 -5
  5. package/.forge/hooks/forge-native-hook.js +431 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +151 -61
  8. package/CHANGELOG.md +709 -0
  9. package/CLAUDE.md +9 -118
  10. package/QUICKSTART.md +175 -0
  11. package/README.md +275 -365
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +532 -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/forge/TOOLCHAIN.md +670 -0
  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 +121 -0
  29. package/docs/guides/SUPPORT.md +190 -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 +214 -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/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
  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 +155 -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/activation/ensure-forge-home.js +135 -0
  67. package/lib/adapter-cli.js +307 -0
  68. package/lib/adapters/beads-issue-adapter.js +127 -0
  69. package/lib/adapters/beads-kernel-compat.js +1109 -0
  70. package/lib/adapters/greptile-review-adapter.js +141 -0
  71. package/lib/adapters/kernel-issue-adapter.js +101 -0
  72. package/lib/adapters/pr-state-adapter.js +484 -0
  73. package/lib/adoption-profiles.js +139 -0
  74. package/lib/agents/README.md +2 -6
  75. package/lib/agents/claude.plugin.json +3 -8
  76. package/lib/agents/codex.plugin.json +9 -1
  77. package/lib/agents/cursor.plugin.json +2 -6
  78. package/lib/agents/hermes.plugin.json +22 -0
  79. package/lib/agents-config.js +39 -1236
  80. package/lib/audit-evidence.js +282 -0
  81. package/lib/beads-detect.js +60 -0
  82. package/lib/beads-nudge.js +91 -0
  83. package/lib/beads-setup.js +121 -0
  84. package/lib/beads-sync-scaffold.js +25 -101
  85. package/lib/codex-skills.js +51 -1
  86. package/lib/commands/_aliases.js +248 -0
  87. package/lib/commands/_issue.js +780 -77
  88. package/lib/commands/_manifest.js +93 -0
  89. package/lib/commands/_registry.js +99 -34
  90. package/lib/commands/_resolve-command-opts.js +230 -0
  91. package/lib/commands/_serve-security.js +270 -0
  92. package/lib/commands/adapter.js +12 -0
  93. package/lib/commands/add.js +118 -0
  94. package/lib/commands/audit.js +70 -0
  95. package/lib/commands/blocked.js +5 -0
  96. package/lib/commands/board.js +64 -0
  97. package/lib/commands/claim.js +21 -2
  98. package/lib/commands/claims.js +7 -0
  99. package/lib/commands/clean.js +485 -75
  100. package/lib/commands/close.js +2 -2
  101. package/lib/commands/comment.js +5 -0
  102. package/lib/commands/control.js +148 -0
  103. package/lib/commands/create.js +2 -2
  104. package/lib/commands/dev.js +185 -7
  105. package/lib/commands/doc-gate.js +336 -0
  106. package/lib/commands/doctor.js +156 -0
  107. package/lib/commands/explain.js +15 -0
  108. package/lib/commands/export.js +237 -0
  109. package/lib/commands/gate.js +209 -0
  110. package/lib/commands/hooks.js +377 -0
  111. package/lib/commands/inbox.js +118 -0
  112. package/lib/commands/init.js +604 -0
  113. package/lib/commands/insights.js +79 -0
  114. package/lib/commands/issue.js +12 -1
  115. package/lib/commands/issues.js +17 -0
  116. package/lib/commands/lint.js +5 -0
  117. package/lib/commands/list.js +2 -2
  118. package/lib/commands/memory.js +81 -0
  119. package/lib/commands/merge.js +312 -0
  120. package/lib/commands/migrate.js +362 -0
  121. package/lib/commands/new.js +12 -0
  122. package/lib/commands/options.js +241 -0
  123. package/lib/commands/orient.js +13 -0
  124. package/lib/commands/orphans.js +5 -0
  125. package/lib/commands/patch.js +67 -0
  126. package/lib/commands/plan.js +481 -29
  127. package/lib/commands/pr.js +88 -0
  128. package/lib/commands/preflight.js +211 -0
  129. package/lib/commands/prime.js +13 -0
  130. package/lib/commands/push.js +135 -2
  131. package/lib/commands/ready.js +2 -2
  132. package/lib/commands/recall.js +171 -0
  133. package/lib/commands/recap.js +75 -0
  134. package/lib/commands/recommend.js +0 -1
  135. package/lib/commands/release.js +104 -0
  136. package/lib/commands/remember.js +140 -0
  137. package/lib/commands/role.js +99 -0
  138. package/lib/commands/serve.js +581 -0
  139. package/lib/commands/setup.js +900 -971
  140. package/lib/commands/shepherd.js +501 -0
  141. package/lib/commands/ship.js +59 -1
  142. package/lib/commands/show.js +2 -2
  143. package/lib/commands/stage.js +192 -0
  144. package/lib/commands/stale.js +5 -0
  145. package/lib/commands/status.js +158 -21
  146. package/lib/commands/sync.js +34 -46
  147. package/lib/commands/team.js +4 -1
  148. package/lib/commands/test.js +43 -27
  149. package/lib/commands/update.js +2 -2
  150. package/lib/commands/upgrade.js +47 -0
  151. package/lib/commands/validate.js +43 -18
  152. package/lib/commands/worktree.js +362 -99
  153. package/lib/config-writer.js +202 -0
  154. package/lib/control-plane.js +236 -0
  155. package/lib/core/runtime-graph.js +977 -0
  156. package/lib/dep-guard/keyword-ripple.js +2 -2
  157. package/lib/deprecated-sync-cleanup.js +362 -0
  158. package/lib/detect-agent.js +2 -28
  159. package/lib/detect-worktree.js +35 -9
  160. package/lib/doc-gate/declaration.js +177 -0
  161. package/lib/doc-gate/detect.js +289 -0
  162. package/lib/doc-gate/gate.js +375 -0
  163. package/lib/doc-gate/okf-config.js +128 -0
  164. package/lib/doc-gate/okf.js +429 -0
  165. package/lib/docs-command.js +1161 -6
  166. package/lib/forge-issues.js +382 -11
  167. package/lib/forge-lock.js +262 -0
  168. package/lib/gate-events.js +192 -0
  169. package/lib/global-flags.js +104 -0
  170. package/lib/greptile-match.js +7 -63
  171. package/lib/grounding/context-events.js +230 -0
  172. package/lib/grounding/read-first.js +112 -0
  173. package/lib/harness-capability-matrix.js +380 -0
  174. package/lib/hook-global-installer.js +347 -0
  175. package/lib/hook-renderer.js +541 -0
  176. package/lib/inbox.js +391 -0
  177. package/lib/insights.js +397 -0
  178. package/lib/issue-adapter.js +156 -0
  179. package/lib/issue-backend.js +145 -0
  180. package/lib/issue-render.js +220 -0
  181. package/lib/kernel/backing-issue.js +311 -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/owned-kernel.js +43 -0
  192. package/lib/kernel/planning-buckets-schema.js +109 -0
  193. package/lib/kernel/projection-jsonl-writer.js +450 -0
  194. package/lib/kernel/readiness-model.js +329 -0
  195. package/lib/kernel/schema.js +356 -0
  196. package/lib/kernel/sqlite-driver.js +2540 -0
  197. package/lib/kernel/taxonomy-validator.js +394 -0
  198. package/lib/lefthook-check.js +3 -2
  199. package/lib/lefthook-wiring.js +413 -0
  200. package/lib/mcp-config-renderer.js +288 -0
  201. package/lib/memory/graphiti-mcp.js +106 -0
  202. package/lib/memory/router.js +387 -0
  203. package/lib/memory/typed-api.js +102 -0
  204. package/lib/memory-digest.js +195 -0
  205. package/lib/merge-rules.js +395 -0
  206. package/lib/migrate-dry-run.js +466 -0
  207. package/lib/orientation.js +863 -0
  208. package/lib/package-manager-remediation.js +103 -0
  209. package/lib/package-root.js +381 -0
  210. package/lib/patch-intent.js +890 -0
  211. package/lib/plugin-catalog.js +3 -4
  212. package/lib/plugin-manager.js +0 -5
  213. package/lib/pr-bundle.js +186 -0
  214. package/lib/pr-monitor/auto-actions.js +175 -0
  215. package/lib/pr-monitor/differ.js +195 -0
  216. package/lib/pr-monitor/digest.js +206 -0
  217. package/lib/pr-monitor/events.js +0 -0
  218. package/lib/pr-monitor/gather.js +124 -0
  219. package/lib/pr-monitor/journal.js +299 -0
  220. package/lib/pr-monitor/monitor.js +146 -0
  221. package/lib/pr-monitor/render-sticky.js +192 -0
  222. package/lib/pr-monitor/upsert-sticky.js +169 -0
  223. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  224. package/lib/pr-monitor/watch.js +247 -0
  225. package/lib/pr-pull.js +1314 -0
  226. package/lib/pr-shepherd.js +494 -0
  227. package/lib/pr-state-validator.js +59 -0
  228. package/lib/preflight/gates.js +237 -0
  229. package/lib/preflight/runner.js +116 -0
  230. package/lib/project-discovery.js +0 -53
  231. package/lib/project-memory.js +99 -497
  232. package/lib/protected-path-manifest.js +281 -0
  233. package/lib/protected-state-surfaces.js +387 -0
  234. package/lib/release-readiness.js +2105 -0
  235. package/lib/reset.js +59 -45
  236. package/lib/review-adapter.js +68 -0
  237. package/lib/rules-sync.js +260 -0
  238. package/lib/runtime-health.js +241 -20
  239. package/lib/safety-config-renderer.js +268 -0
  240. package/lib/setup-action-log.js +1 -7
  241. package/lib/setup.js +27 -65
  242. package/lib/shell-utils.js +76 -6
  243. package/lib/skills-sync.js +330 -0
  244. package/lib/smart-status/scoring.js +17 -3
  245. package/lib/status/beads-snapshot.js +45 -2
  246. package/lib/status/presenter.js +169 -18
  247. package/lib/status/snapshot.js +186 -0
  248. package/lib/sync-backend.js +202 -0
  249. package/lib/untrusted-content.js +52 -0
  250. package/lib/upgrade-safety.js +251 -0
  251. package/lib/workflow/enforce-stage.js +351 -45
  252. package/lib/workflow/stage-transition.js +115 -0
  253. package/lib/workflow/stages.js +30 -6
  254. package/lib/workflow/state-manager.js +11 -22
  255. package/lib/workflow/state.js +23 -1
  256. package/lib/workflow-profiles.js +17 -5
  257. package/package.json +37 -35
  258. package/rules/documentation.md +19 -0
  259. package/rules/kernel-tracking.md +26 -0
  260. package/rules/security.md +22 -0
  261. package/rules/tdd.md +20 -0
  262. package/rules/workflow.md +27 -0
  263. package/scripts/auto-backing-issue.js +47 -0
  264. package/scripts/beads-context.sh +81 -57
  265. package/scripts/beads-upgrade-smoke.sh +24 -3
  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.sh +22 -3
  272. package/scripts/file-index.sh +3 -0
  273. package/scripts/forge-team/lib/claim.sh +34 -18
  274. package/scripts/forge-team/lib/dashboard.sh +61 -86
  275. package/scripts/forge-team/lib/epic.sh +99 -263
  276. package/scripts/forge-team/lib/hooks.sh +26 -28
  277. package/scripts/forge-team/lib/identity.sh +4 -4
  278. package/scripts/forge-team/lib/sync-github.sh +49 -84
  279. package/scripts/forge-team/lib/verify.sh +93 -83
  280. package/scripts/forge-team/lib/workload.sh +41 -65
  281. package/scripts/forge-team/tests/claim.test.sh +25 -19
  282. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  283. package/scripts/forge-team/tests/epic.test.sh +52 -71
  284. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  285. package/scripts/forge-team/tests/identity.test.sh +3 -3
  286. package/scripts/forge-team/tests/integration.test.sh +44 -66
  287. package/scripts/forge-team/tests/sync-github.test.sh +50 -83
  288. package/scripts/forge-team/tests/verify.test.sh +37 -46
  289. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  290. package/scripts/forge-team/tests/workload.test.sh +32 -66
  291. package/scripts/gen-command-manifest.js +153 -0
  292. package/scripts/gen-embedded-assets.mjs +129 -0
  293. package/scripts/install.ps1 +139 -0
  294. package/scripts/install.sh +268 -0
  295. package/scripts/lib/release-asset.mjs +84 -0
  296. package/scripts/parity-check.mjs +145 -0
  297. package/scripts/parity-check.test.mjs +58 -0
  298. package/scripts/pin-agentic-workflow-images.js +112 -0
  299. package/scripts/pr-auto-actions.js +93 -0
  300. package/scripts/pr-coordinator.sh +3 -0
  301. package/scripts/pr-verdict-label.js +50 -0
  302. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  303. package/scripts/preflight.sh +21 -94
  304. package/scripts/protected-state-check.js +104 -0
  305. package/scripts/smart-status.sh +60 -57
  306. package/scripts/spikes/config-race-bench.js +111 -0
  307. package/scripts/spikes/harness-capability-matrix.js +13 -0
  308. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  309. package/scripts/spikes/protected-path-manifest.js +20 -0
  310. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  311. package/scripts/sync-agent-skills.js +62 -0
  312. package/scripts/sync-utils.sh +3 -0
  313. package/scripts/test-ci-shard.js +13 -6
  314. package/scripts/test.js +95 -12
  315. package/skills/claim-safety/SKILL.md +102 -0
  316. package/skills/claim-safety/evals/evals.json +46 -0
  317. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
  318. package/skills/dev/evals/evals.json +50 -0
  319. package/skills/hermes-forge/SKILL.md +185 -0
  320. package/skills/hermes-forge/evals/evals.json +46 -0
  321. package/skills/issue-basics/SKILL.md +111 -0
  322. package/skills/issue-basics/evals/evals.json +46 -0
  323. package/skills/kernel/SKILL.md +166 -0
  324. package/skills/kernel/evals/evals.json +50 -0
  325. package/skills/memory/SKILL.md +102 -0
  326. package/skills/parallel-deep-research/SKILL.md +14 -11
  327. package/skills/parallel-deep-research/evals/evals.json +11 -27
  328. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
  329. package/skills/plan/evals/evals.json +42 -0
  330. package/skills/research/SKILL.md +195 -0
  331. package/skills/research/evals/evals.json +42 -0
  332. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  333. package/skills/review/evals/evals.json +42 -0
  334. package/skills/rollback/SKILL.md +110 -0
  335. package/skills/rollback/evals/evals.json +46 -0
  336. package/skills/rollback/references/methods.md +204 -0
  337. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  338. package/skills/shepherd/SKILL.md +66 -0
  339. package/skills/shepherd/evals/evals.json +42 -0
  340. package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
  341. package/skills/ship/evals/evals.json +42 -0
  342. package/skills/smith/SKILL.md +142 -0
  343. package/skills/smith/evals/evals.json +46 -0
  344. package/skills/smith/references/autonomy-and-gates.md +94 -0
  345. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  346. package/skills/sonarcloud/evals/evals.json +46 -0
  347. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  348. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  349. package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
  350. package/skills/status/evals/evals.json +50 -0
  351. package/skills/triage-ready/SKILL.md +121 -0
  352. package/skills/triage-ready/evals/evals.json +42 -0
  353. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  354. package/skills/validate/evals/evals.json +42 -0
  355. package/skills/verify/SKILL.md +299 -0
  356. package/skills/verify/evals/evals.json +50 -0
  357. package/.claude/commands/dev.md +0 -345
  358. package/.claude/commands/plan.md +0 -566
  359. package/.claude/commands/premerge.md +0 -186
  360. package/.claude/commands/research.md +0 -42
  361. package/.claude/commands/review.md +0 -451
  362. package/.claude/commands/rollback.md +0 -721
  363. package/.claude/commands/ship.md +0 -213
  364. package/.claude/commands/sonarcloud.md +0 -152
  365. package/.claude/commands/status.md +0 -90
  366. package/.claude/commands/validate.md +0 -288
  367. package/.claude/commands/verify.md +0 -269
  368. package/.claude/rules/workflow.md +0 -121
  369. package/.cline/workflows/dev.md +0 -342
  370. package/.cline/workflows/plan.md +0 -563
  371. package/.cline/workflows/premerge.md +0 -183
  372. package/.cline/workflows/research.md +0 -39
  373. package/.cline/workflows/review.md +0 -448
  374. package/.cline/workflows/rollback.md +0 -718
  375. package/.cline/workflows/ship.md +0 -210
  376. package/.cline/workflows/sonarcloud.md +0 -146
  377. package/.cline/workflows/status.md +0 -87
  378. package/.cline/workflows/validate.md +0 -285
  379. package/.cline/workflows/verify.md +0 -266
  380. package/.codex/config.toml +0 -11
  381. package/.codex/skills/dev/SKILL.md +0 -345
  382. package/.codex/skills/plan/SKILL.md +0 -566
  383. package/.codex/skills/premerge/SKILL.md +0 -186
  384. package/.codex/skills/research/SKILL.md +0 -42
  385. package/.codex/skills/review/SKILL.md +0 -451
  386. package/.codex/skills/rollback/SKILL.md +0 -721
  387. package/.codex/skills/ship/SKILL.md +0 -213
  388. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  389. package/.codex/skills/status/SKILL.md +0 -90
  390. package/.codex/skills/validate/SKILL.md +0 -288
  391. package/.codex/skills/verify/SKILL.md +0 -269
  392. package/.cursor/commands/dev.md +0 -342
  393. package/.cursor/commands/plan.md +0 -563
  394. package/.cursor/commands/premerge.md +0 -183
  395. package/.cursor/commands/research.md +0 -39
  396. package/.cursor/commands/review.md +0 -448
  397. package/.cursor/commands/ship.md +0 -210
  398. package/.cursor/commands/sonarcloud.md +0 -146
  399. package/.cursor/commands/status.md +0 -87
  400. package/.cursor/commands/validate.md +0 -285
  401. package/.cursor/commands/verify.md +0 -266
  402. package/.cursorrules +0 -149
  403. package/.github/prompts/premerge.prompt.md +0 -188
  404. package/.github/prompts/research.prompt.md +0 -44
  405. package/.github/prompts/rollback.prompt.md +0 -723
  406. package/.github/prompts/verify.prompt.md +0 -271
  407. package/.github/workflows/beads-to-github.yml +0 -89
  408. package/.github/workflows/github-to-beads.yml +0 -100
  409. package/.kilocode/workflows/dev.md +0 -346
  410. package/.kilocode/workflows/plan.md +0 -567
  411. package/.kilocode/workflows/premerge.md +0 -187
  412. package/.kilocode/workflows/research.md +0 -43
  413. package/.kilocode/workflows/review.md +0 -452
  414. package/.kilocode/workflows/rollback.md +0 -722
  415. package/.kilocode/workflows/ship.md +0 -214
  416. package/.kilocode/workflows/sonarcloud.md +0 -150
  417. package/.kilocode/workflows/status.md +0 -91
  418. package/.kilocode/workflows/validate.md +0 -289
  419. package/.kilocode/workflows/verify.md +0 -270
  420. package/.opencode/commands/dev.md +0 -345
  421. package/.opencode/commands/plan.md +0 -566
  422. package/.opencode/commands/premerge.md +0 -186
  423. package/.opencode/commands/research.md +0 -42
  424. package/.opencode/commands/review.md +0 -451
  425. package/.opencode/commands/rollback.md +0 -721
  426. package/.opencode/commands/ship.md +0 -213
  427. package/.opencode/commands/sonarcloud.md +0 -149
  428. package/.opencode/commands/status.md +0 -90
  429. package/.opencode/commands/validate.md +0 -288
  430. package/.opencode/commands/verify.md +0 -269
  431. package/.roo/commands/dev.md +0 -346
  432. package/.roo/commands/plan.md +0 -567
  433. package/.roo/commands/premerge.md +0 -187
  434. package/.roo/commands/research.md +0 -43
  435. package/.roo/commands/review.md +0 -452
  436. package/.roo/commands/rollback.md +0 -722
  437. package/.roo/commands/ship.md +0 -214
  438. package/.roo/commands/sonarcloud.md +0 -150
  439. package/.roo/commands/status.md +0 -91
  440. package/.roo/commands/validate.md +0 -289
  441. package/.roo/commands/verify.md +0 -270
  442. package/docs/BEADS_GITHUB_SYNC.md +0 -281
  443. package/docs/GREPTILE_SETUP.md +0 -400
  444. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  445. package/docs/SETUP.md +0 -663
  446. package/docs/VALIDATION.md +0 -363
  447. package/lib/agents/cline.plugin.json +0 -29
  448. package/lib/agents/copilot.plugin.json +0 -24
  449. package/lib/agents/kilocode.plugin.json +0 -22
  450. package/lib/agents/opencode.plugin.json +0 -23
  451. package/lib/agents/roo.plugin.json +0 -30
  452. package/lib/beads-bootstrap.js +0 -225
  453. package/lib/beads-health-check.js +0 -188
  454. package/lib/commands/commands-reset.js +0 -147
  455. package/opencode.json +0 -67
  456. package/scripts/beads-context.test.js +0 -584
  457. package/scripts/github-beads-sync/comment.mjs +0 -64
  458. package/scripts/github-beads-sync/config.mjs +0 -148
  459. package/scripts/github-beads-sync/github-api.mjs +0 -131
  460. package/scripts/github-beads-sync/index.mjs +0 -356
  461. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  462. package/scripts/github-beads-sync/mapping.mjs +0 -132
  463. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  464. package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
  465. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  466. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  467. package/scripts/github-beads-sync.config.json +0 -26
  468. package/scripts/sync-commands.js +0 -600
@@ -0,0 +1,230 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module grounding/context-events
5
+ *
6
+ * The state primitive behind gate.read_first: "this issue's context was loaded"
7
+ * recorded as a durable kernel EVENT, structurally identical to gate.approved
8
+ * (lib/gate-events.js). `forge recap`/`forge show` append a `context.loaded`
9
+ * event to the issue's stream on a successful render; `forge claim` refuses to
10
+ * proceed until such an event exists for the issue this session/window.
11
+ *
12
+ * Mechanism (mirrors gate-events, deliberately): a PURE APPEND via the driver
13
+ * primitives (`insertKernelEvent` + `listKernelEvents`), NOT the guarded
14
+ * issue-mutation pipeline — context.loaded does not mutate the issue, so it must
15
+ * not participate in the issue-revision CAS. Idempotency is enforced by a
16
+ * window-bucketed key (so a re-read inside the freshness window mints no
17
+ * duplicate, but a re-read in the NEXT window mints a fresh event that clears a
18
+ * re-block) plus the unique idempotency index catching a concurrent race.
19
+ *
20
+ * Config-surface note: whether the gate is enabled lives in the runtime graph +
21
+ * `.forge/config.yaml`; this module only records/reads the events.
22
+ */
23
+
24
+ const { resolveOwnedKernel, closeIfOwned } = require('../kernel/owned-kernel');
25
+ const { resolveIssueActor } = require('../forge-issues');
26
+
27
+ const CONTEXT_LOADED_EVENT = 'context.loaded';
28
+ const ISSUE_ENTITY_TYPE = 'issue';
29
+ const CONTEXT_EVENT_ORIGIN = 'cli';
30
+ // Tier-2 agnostic freshness floor: a stale-but-loaded issue re-blocks after this
31
+ // window; one `forge recap` clears it. Overridable via
32
+ // `workflow.gates.gate.read_first.window` at the call site (P2).
33
+ const DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000;
34
+
35
+ // Kernel lifecycle (resolve + close-what-you-built) is shared with gate-events
36
+ // via lib/kernel/owned-kernel; `resolveOwnedKernel`/`closeIfOwned` are imported.
37
+
38
+ /** Coarse window bucket for a timestamp — the roll-over that makes re-reads fresh. */
39
+ function windowBucket(nowMs, windowMs) {
40
+ return Math.floor(nowMs / windowMs);
41
+ }
42
+
43
+ /**
44
+ * Idempotency key for a context.loaded event. Scoped to issue + scope
45
+ * (session id when present, else actor) + window bucket so a re-read inside the
46
+ * window is idempotent, while the next window mints a fresh event.
47
+ */
48
+ function contextLoadedIdempotencyKey(issueId, scope, bucket) {
49
+ return `${CONTEXT_LOADED_EVENT}:${issueId}:${scope}:${bucket}`;
50
+ }
51
+
52
+ /** Shape a stored kernel_events row into the context-event view callers consume. */
53
+ function parseContextEvent(row) {
54
+ let payload;
55
+ try {
56
+ payload = row.payload_json ? JSON.parse(row.payload_json) : {};
57
+ } catch {
58
+ payload = {};
59
+ }
60
+ const view = {
61
+ event_type: row.event_type,
62
+ actor: row.actor,
63
+ created_at: row.created_at,
64
+ };
65
+ if (payload.session !== undefined) view.session = payload.session;
66
+ if (payload.cmd !== undefined) view.cmd = payload.cmd;
67
+ if (payload.budget !== undefined) view.budget = payload.budget;
68
+ return view;
69
+ }
70
+
71
+ function isIdempotencyRace(error) {
72
+ const message = error && error.message ? String(error.message) : '';
73
+ return /UNIQUE constraint failed/i.test(message) && /idempotency_key/i.test(message);
74
+ }
75
+
76
+ /**
77
+ * Record that an issue's context was loaded. Idempotent per issue+scope+window.
78
+ * Validates the issue exists (no orphan events).
79
+ *
80
+ * @param {string} projectRoot
81
+ * @param {Object} params
82
+ * @param {string} params.issueId
83
+ * @param {string} [params.cmd] - the command that loaded the context (recap|show).
84
+ * @param {string} [params.session] - harness session id (Tier-1 scoping) when known.
85
+ * @param {number|string} [params.budget]
86
+ * @param {Object} [params.env] - env source for actor resolution.
87
+ * @param {Object} [params.deps] - injected { kernelBroker, kernelDriver }.
88
+ * @param {string} [params.now] - ISO timestamp (defaults to now).
89
+ * @param {number} [params.windowMs] - freshness window (defaults to 24h).
90
+ * @returns {Promise<{ ok: boolean, duplicate?: boolean, issueMissing?: boolean, event?: Object, actor?: string }>}
91
+ */
92
+ async function recordContextLoaded(projectRoot, params = {}) {
93
+ const { issueId, cmd, session, budget, env, deps, now, windowMs } = params;
94
+ const actor = resolveIssueActor(env || process.env) || 'forge';
95
+ const kernel = await resolveOwnedKernel(projectRoot, deps);
96
+ const { driver, config } = kernel;
97
+
98
+ try {
99
+ const entity = await driver.loadKernelEntity(ISSUE_ENTITY_TYPE, issueId, {}, config);
100
+ if (!entity) {
101
+ return { ok: false, issueMissing: true, actor };
102
+ }
103
+
104
+ const nowIso = now || new Date().toISOString();
105
+ const win = Number.isFinite(windowMs) ? windowMs : DEFAULT_WINDOW_MS;
106
+ const bucket = windowBucket(Date.parse(nowIso), win);
107
+ const scope = session || actor;
108
+ const idempotencyKey = contextLoadedIdempotencyKey(issueId, scope, bucket);
109
+
110
+ const existing = await driver.loadKernelEventByIdempotencyKey(idempotencyKey, {}, config);
111
+ if (existing) {
112
+ return { ok: true, duplicate: true, event: parseContextEvent(existing), actor };
113
+ }
114
+
115
+ const payload = { actor };
116
+ if (typeof session === 'string' && session.length > 0) payload.session = session;
117
+ if (typeof cmd === 'string' && cmd.length > 0) payload.cmd = cmd;
118
+ if (budget !== undefined) payload.budget = budget;
119
+
120
+ const event = {
121
+ entity_type: ISSUE_ENTITY_TYPE,
122
+ entity_id: issueId,
123
+ event_type: CONTEXT_LOADED_EVENT,
124
+ idempotency_key: idempotencyKey,
125
+ expected_revision: 0,
126
+ actor,
127
+ origin: CONTEXT_EVENT_ORIGIN,
128
+ payload,
129
+ created_at: nowIso,
130
+ };
131
+
132
+ try {
133
+ const inserted = await driver.insertKernelEvent(event, {}, config);
134
+ return { ok: true, duplicate: false, event: parseContextEvent(inserted), actor };
135
+ } catch (error) {
136
+ if (isIdempotencyRace(error)) {
137
+ const winner = await driver.loadKernelEventByIdempotencyKey(idempotencyKey, {}, config);
138
+ return { ok: true, duplicate: true, event: winner ? parseContextEvent(winner) : parseContextEvent(event), actor };
139
+ }
140
+ throw error;
141
+ }
142
+ } finally {
143
+ closeIfOwned(kernel);
144
+ }
145
+ }
146
+
147
+ /**
148
+ * List every context.loaded event on an issue, oldest first.
149
+ *
150
+ * @returns {Promise<Array<{ event_type: string, actor: string, created_at: string, session?: string, cmd?: string }>>}
151
+ */
152
+ async function listContextLoadedEvents(projectRoot, issueId, options = {}) {
153
+ const kernel = await resolveOwnedKernel(projectRoot, options.deps);
154
+ try {
155
+ const rows = await kernel.driver.listKernelEvents(ISSUE_ENTITY_TYPE, issueId, {}, kernel.config);
156
+ return (rows || [])
157
+ .filter(row => row.event_type === CONTEXT_LOADED_EVENT)
158
+ .map(parseContextEvent);
159
+ } finally {
160
+ closeIfOwned(kernel);
161
+ }
162
+ }
163
+
164
+ /**
165
+ * True iff the issue has a context.loaded event that satisfies scoping:
166
+ * - Tier-1 (session given): an event stamped with the SAME session.
167
+ * - Tier-2 (no session): an event newer than the freshness window.
168
+ *
169
+ * @param {string} projectRoot
170
+ * @param {string} issueId
171
+ * @param {{ session?: string, windowMs?: number, now?: string, deps?: Object }} [options]
172
+ * @returns {Promise<boolean>}
173
+ */
174
+ async function hasFreshContextLoaded(projectRoot, issueId, options = {}) {
175
+ const { session, windowMs, now, deps } = options;
176
+ const events = await listContextLoadedEvents(projectRoot, issueId, { deps });
177
+ return eventsSatisfyFreshness(events, { session, windowMs, now });
178
+ }
179
+
180
+ /** Shared freshness predicate over an already-listed event set. */
181
+ function eventsSatisfyFreshness(events, { session, windowMs, now } = {}) {
182
+ if (!events || events.length === 0) return false;
183
+ if (typeof session === 'string' && session.length > 0) {
184
+ return events.some(event => event.session === session);
185
+ }
186
+ const nowMs = now ? Date.parse(now) : Date.now();
187
+ const win = Number.isFinite(windowMs) ? windowMs : DEFAULT_WINDOW_MS;
188
+ return events.some(event => {
189
+ const ts = Date.parse(event.created_at);
190
+ return Number.isFinite(ts) && (nowMs - ts) <= win;
191
+ });
192
+ }
193
+
194
+ /**
195
+ * The gate.read_first verdict for an issue, resolving the kernel ONCE:
196
+ * - 'missing': the issue does not exist in the consulted kernel. The gate is
197
+ * INERT — grounding a phantom issue is meaningless and the real claim will
198
+ * fail on its own; this is also what keeps unit doubles (fake runner, no real
199
+ * store) from being false-blocked. No bypass for a REAL issue: a claim on a
200
+ * non-existent issue fails regardless.
201
+ * - 'loaded': a context.loaded event satisfies session/window scoping -> allow.
202
+ * - 'unread': the issue exists but has no fresh context.loaded event -> BLOCK.
203
+ *
204
+ * @returns {Promise<'missing'|'loaded'|'unread'>}
205
+ */
206
+ async function readFirstVerdict(projectRoot, issueId, options = {}) {
207
+ const { session, windowMs, now, deps } = options;
208
+ const kernel = await resolveOwnedKernel(projectRoot, deps);
209
+ const { driver, config } = kernel;
210
+ try {
211
+ const entity = await driver.loadKernelEntity(ISSUE_ENTITY_TYPE, issueId, {}, config);
212
+ if (!entity) return 'missing';
213
+ const rows = await driver.listKernelEvents(ISSUE_ENTITY_TYPE, issueId, {}, config);
214
+ const events = (rows || []).filter(row => row.event_type === CONTEXT_LOADED_EVENT).map(parseContextEvent);
215
+ return eventsSatisfyFreshness(events, { session, windowMs, now }) ? 'loaded' : 'unread';
216
+ } finally {
217
+ closeIfOwned(kernel);
218
+ }
219
+ }
220
+
221
+ module.exports = {
222
+ CONTEXT_LOADED_EVENT,
223
+ DEFAULT_WINDOW_MS,
224
+ contextLoadedIdempotencyKey,
225
+ parseContextEvent,
226
+ recordContextLoaded,
227
+ listContextLoadedEvents,
228
+ hasFreshContextLoaded,
229
+ readFirstVerdict,
230
+ };
@@ -0,0 +1,112 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module grounding/read-first
5
+ *
6
+ * gate.read_first — the first gate that DENIES (fd4c03b3's first real payment):
7
+ * acting on an issue requires having read it. Consulted at the `forge claim`
8
+ * chokepoint (P1) exactly like gate.issue_verify is consulted at the _issue.js
9
+ * boundary (isIssueVerifyEnabled). Fail-closed: no context.loaded event for the
10
+ * issue this session/window -> a block result whose remedy IS the load action
11
+ * (`forge recap <id>`), so the cheapest path through the gate is the correct
12
+ * behavior. Disabling rail.grounding (master) or gate.read_first allows the
13
+ * action (logged), same toggle surface as rail.kernel_tracking.
14
+ */
15
+
16
+ const { getResolvedRuntimeGraph } = require('../core/runtime-graph');
17
+ const { readFirstVerdict } = require('./context-events');
18
+
19
+ const GROUNDING_RAIL_ID = 'rail.grounding';
20
+ const READ_FIRST_GATE_ID = 'gate.read_first';
21
+
22
+ /**
23
+ * The block message. Contract: exit != 0, remedy is one copy-pastable command,
24
+ * and running that command both satisfies the gate AND injects the context.
25
+ */
26
+ function buildReadFirstBlockMessage(issueId) {
27
+ return [
28
+ `✗ ${READ_FIRST_GATE_ID}: issue ${issueId} has not been read this session.`,
29
+ ` Run: forge recap ${issueId} first`,
30
+ ` Then retry. (Override: forge gate disable ${READ_FIRST_GATE_ID} — logged.)`,
31
+ ].join('\n');
32
+ }
33
+
34
+ /**
35
+ * Resolve whether grounding + read_first are BOTH enabled. Mirrors
36
+ * isIssueVerifyEnabled: an injected opts.resolveRuntimeGraph wins (tests); an
37
+ * unresolvable config (lint errors) yields `unknown` so the caller can fail-open
38
+ * on a broken config rather than bricking claim.
39
+ *
40
+ * @returns {{ enabled: boolean, disabledPrimitive?: string, unknown?: boolean }}
41
+ */
42
+ function resolveReadFirstEnabled(projectRoot, opts = {}) {
43
+ const resolveGraph = opts.resolveRuntimeGraph || getResolvedRuntimeGraph;
44
+ let graph;
45
+ try {
46
+ graph = resolveGraph({ projectRoot });
47
+ } catch {
48
+ return { enabled: false, unknown: true };
49
+ }
50
+ const rail = (graph.rails || []).find(candidate => candidate.id === GROUNDING_RAIL_ID);
51
+ const gate = (graph.gates || []).find(candidate => candidate.id === READ_FIRST_GATE_ID);
52
+ const railOn = rail ? rail.enabled !== false : true;
53
+ const gateOn = gate ? gate.enabled !== false : true;
54
+ if (!railOn) return { enabled: false, disabledPrimitive: GROUNDING_RAIL_ID };
55
+ if (!gateOn) return { enabled: false, disabledPrimitive: READ_FIRST_GATE_ID };
56
+ return { enabled: true };
57
+ }
58
+
59
+ /**
60
+ * Consult gate.read_first for an issue. Returns `null` when the action is
61
+ * allowed (gate off, or a fresh context.loaded event exists), or a block result
62
+ * `{ success:false, error, exitCode }` when the issue has not been read.
63
+ *
64
+ * @param {string} projectRoot
65
+ * @param {string} issueId
66
+ * @param {Object} [opts] - { resolveRuntimeGraph, kernelBroker, kernelDriver, session, windowMs, now }
67
+ * @returns {Promise<null | { success: false, error: string, exitCode: number }>}
68
+ */
69
+ async function checkReadFirst(projectRoot, issueId, opts = {}) {
70
+ const state = resolveReadFirstEnabled(projectRoot, opts);
71
+ if (!state.enabled) {
72
+ // Disabled (or unresolvable config) -> allow. Log the deliberate skip.
73
+ if (state.disabledPrimitive) {
74
+ console.error(`forge: ${state.disabledPrimitive} disabled — claim on ${issueId} allowed without grounding check.`);
75
+ }
76
+ return null;
77
+ }
78
+
79
+ const deps = (opts.kernelBroker && opts.kernelDriver)
80
+ ? { kernelBroker: opts.kernelBroker, kernelDriver: opts.kernelDriver }
81
+ : undefined;
82
+
83
+ let verdict;
84
+ try {
85
+ verdict = await readFirstVerdict(projectRoot, issueId, {
86
+ session: opts.session,
87
+ windowMs: opts.windowMs,
88
+ now: opts.now,
89
+ deps,
90
+ });
91
+ } catch {
92
+ // Kernel unavailable (broken env) -> fail-open, like issue_verify on a
93
+ // config error. In production the project kernel resolves; the enforced
94
+ // path is the normal one.
95
+ return null;
96
+ }
97
+
98
+ // 'missing' -> the issue is not in the consulted kernel; the gate is inert (a
99
+ // real claim on a non-existent issue fails on its own — no grounding bypass).
100
+ // 'loaded' -> a fresh context.loaded event exists. Both allow.
101
+ if (verdict !== 'unread') return null;
102
+
103
+ return { success: false, error: buildReadFirstBlockMessage(issueId), exitCode: 6 };
104
+ }
105
+
106
+ module.exports = {
107
+ GROUNDING_RAIL_ID,
108
+ READ_FIRST_GATE_ID,
109
+ buildReadFirstBlockMessage,
110
+ resolveReadFirstEnabled,
111
+ checkReadFirst,
112
+ };