forge-workflow 0.1.0-beta.4 → 0.1.0-beta.6

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 (196) hide show
  1. package/AGENTS.md +18 -7
  2. package/CHANGELOG.md +79 -1
  3. package/CLAUDE.md +0 -12
  4. package/CODING_STANDARDS.md +72 -0
  5. package/README.md +6 -2
  6. package/bin/forge-cmd.js +20 -0
  7. package/bin/forge.js +28 -375
  8. package/docs/INDEX.md +1 -1
  9. package/docs/guides/BEADS_GITHUB_SYNC.md +2 -31
  10. package/docs/guides/MIGRATION.md +4 -4
  11. package/docs/guides/SETUP.md +16 -16
  12. package/docs/reference/COMMANDS.md +8 -5
  13. package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +4 -0
  14. package/docs/reference/INSIGHTS_RECAP.md +9 -20
  15. package/docs/reference/INSTALL.md +4 -0
  16. package/docs/reference/LEGACY_CLAIM_REPAIR.md +112 -0
  17. package/docs/reference/RELEASE.md +5 -3
  18. package/docs/reference/TOOLCHAIN.md +8 -0
  19. package/docs/reference/github-accounts.md +134 -0
  20. package/docs/reference/protected-state-surfaces.md +4 -4
  21. package/docs/reference/shepherd.md +114 -35
  22. package/lefthook.yml +12 -0
  23. package/lib/activation/ensure-forge-home.js +33 -15
  24. package/lib/adapters/pr-state-adapter.js +359 -144
  25. package/lib/audit-evidence.js +71 -110
  26. package/lib/base-remote.js +138 -0
  27. package/lib/beta5-compatibility-evidence.js +1093 -0
  28. package/lib/bun-lockfile-proof.js +413 -0
  29. package/lib/bun-workflow-pins.js +461 -0
  30. package/lib/capabilities/index.js +9 -0
  31. package/lib/capabilities/model.js +141 -0
  32. package/lib/capabilities/probes.js +347 -0
  33. package/lib/capped-jsonl-log.js +236 -0
  34. package/lib/codex-skills.js +2 -2
  35. package/lib/commands/_manifest.js +1 -0
  36. package/lib/commands/_registry.js +50 -20
  37. package/lib/commands/clean.js +252 -32
  38. package/lib/commands/dev.js +4 -33
  39. package/lib/commands/doctor.js +37 -6
  40. package/lib/commands/gate.js +197 -27
  41. package/lib/commands/github.js +215 -0
  42. package/lib/commands/hooks.js +276 -30
  43. package/lib/commands/insights.js +8 -3
  44. package/lib/commands/memory.js +66 -2
  45. package/lib/commands/merge.js +1265 -58
  46. package/lib/commands/plan.js +33 -2
  47. package/lib/commands/pr.js +3 -1
  48. package/lib/commands/preflight.js +21 -4
  49. package/lib/commands/prime.js +21 -8
  50. package/lib/commands/push.js +146 -54
  51. package/lib/commands/recall.js +127 -49
  52. package/lib/commands/recap.js +6 -1
  53. package/lib/commands/release.js +39 -3
  54. package/lib/commands/remember.js +28 -4
  55. package/lib/commands/serve.js +26 -9
  56. package/lib/commands/setup.js +323 -98
  57. package/lib/commands/shepherd.js +591 -73
  58. package/lib/commands/ship.js +36 -91
  59. package/lib/commands/skill.js +127 -11
  60. package/lib/commands/status.js +17 -1
  61. package/lib/commands/team.js +47 -8
  62. package/lib/commands/test.js +187 -38
  63. package/lib/commands/validate.js +65 -21
  64. package/lib/commands/worktree.js +359 -45
  65. package/lib/core/runtime-graph.js +1 -1
  66. package/lib/doc-assertions.js +297 -0
  67. package/lib/existing-tdd-gate.js +253 -0
  68. package/lib/fixtures/beta5-corpus/v1/README.md +9 -0
  69. package/lib/fixtures/beta5-corpus/v1/contract/command-contract.json +26 -0
  70. package/lib/fixtures/beta5-corpus/v1/contract/package-contract.json +13 -0
  71. package/lib/fixtures/beta5-corpus/v1/contract/workflow-stage-matrix.json +8 -0
  72. package/lib/fixtures/beta5-corpus/v1/manifest.json +25 -0
  73. package/lib/fixtures/beta5-corpus/v1/state/comments.jsonl +1 -0
  74. package/lib/fixtures/beta5-corpus/v1/state/config.yaml +6 -0
  75. package/lib/fixtures/beta5-corpus/v1/state/dependencies.jsonl +1 -0
  76. package/lib/fixtures/beta5-corpus/v1/state/issues.jsonl +2 -0
  77. package/lib/fixtures/beta5-corpus/v1/state/kernel.sql +20 -0
  78. package/lib/forge-context.js +1 -4
  79. package/lib/forge-issues.js +134 -32
  80. package/lib/gate-events.js +98 -10
  81. package/lib/git-defaults.js +56 -0
  82. package/lib/github-context.js +308 -0
  83. package/lib/global-flags.js +1 -0
  84. package/lib/harness-capability-matrix.js +3 -3
  85. package/lib/hook-renderer.js +122 -5
  86. package/lib/insights.js +96 -80
  87. package/lib/issue-render.js +19 -0
  88. package/lib/kernel/backing-issue.js +14 -2
  89. package/lib/kernel/broker.js +739 -31
  90. package/lib/kernel/claim-reconciler.js +238 -0
  91. package/lib/kernel/cli-broker-factory.js +12 -1
  92. package/lib/kernel/close-on-merge.js +154 -0
  93. package/lib/kernel/fs-class.js +42 -25
  94. package/lib/kernel/lease-enforcer.js +9 -4
  95. package/lib/kernel/legacy-claim-repair.js +442 -0
  96. package/lib/kernel/live-claim-projection.js +26 -0
  97. package/lib/kernel/migrations.js +118 -3
  98. package/lib/kernel/readiness-model.js +184 -12
  99. package/lib/kernel/schema.js +49 -1
  100. package/lib/kernel/sqlite-driver.js +3435 -172
  101. package/lib/kernel/taxonomy-validator.js +4 -1
  102. package/lib/kernel/windows-private-acl.js +239 -0
  103. package/lib/lefthook-wiring.js +21 -1
  104. package/lib/memory/hygiene.js +191 -0
  105. package/lib/memory/router.js +110 -28
  106. package/lib/memory/usage-evidence.js +4 -0
  107. package/lib/memory-digest.js +106 -15
  108. package/lib/memory-recall-events.js +145 -0
  109. package/lib/memory-recall.js +71 -10
  110. package/lib/merge-rules.js +143 -21
  111. package/lib/npm-publish-workflow.js +465 -0
  112. package/lib/orientation.js +68 -43
  113. package/lib/package-root.js +2 -0
  114. package/lib/plugin-catalog.js +14 -4
  115. package/lib/pr-bundle.js +5 -6
  116. package/lib/pr-monitor/auto-actions.js +169 -28
  117. package/lib/pr-monitor/differ.js +110 -4
  118. package/lib/pr-monitor/events.js +0 -0
  119. package/lib/pr-monitor/flow-monitor.js +1424 -0
  120. package/lib/pr-monitor/gather.js +251 -44
  121. package/lib/pr-monitor/journal.js +18 -39
  122. package/lib/pr-monitor/monitor.js +117 -10
  123. package/lib/pr-monitor/process-identity.js +117 -0
  124. package/lib/pr-monitor/reconcile-executor.js +1129 -470
  125. package/lib/pr-monitor/reconcile.js +0 -0
  126. package/lib/pr-monitor/render-summary.js +293 -0
  127. package/lib/pr-monitor/review-preflight.js +269 -0
  128. package/lib/pr-monitor/shepherd-lease.js +38 -20
  129. package/lib/pr-monitor/verdict.js +438 -0
  130. package/lib/pr-monitor/watch-lifecycle.js +145 -27
  131. package/lib/pr-monitor/watch-owner.js +1414 -0
  132. package/lib/pr-monitor/watch.js +129 -58
  133. package/lib/pr-pull.js +33 -14
  134. package/lib/pr-shepherd.js +51 -11
  135. package/lib/preflight/gates.js +65 -18
  136. package/lib/preflight/runner.js +5 -0
  137. package/lib/project-memory.js +178 -4
  138. package/lib/protected-state-authority.js +1100 -0
  139. package/lib/protected-state-surfaces.js +243 -45
  140. package/lib/release-readiness.js +53 -7
  141. package/lib/review-adapter.js +65 -0
  142. package/lib/shell-utils.js +1 -1
  143. package/lib/skills-sync.js +71 -35
  144. package/lib/smart-merge.js +28 -4
  145. package/lib/symlink-utils.js +74 -26
  146. package/lib/upgrade-safety.js +39 -0
  147. package/lib/using-forge.js +19 -6
  148. package/lib/validation/risk-manifest.js +339 -0
  149. package/lib/workflow/enforce-stage.js +44 -0
  150. package/lib/workflow/plan-authority.js +225 -0
  151. package/package.json +12 -9
  152. package/scripts/commitlint.js +13 -15
  153. package/scripts/doc-asserting-tests.js +158 -0
  154. package/scripts/generate-risk-manifest.js +91 -0
  155. package/scripts/github-context-bridge.sh +10 -0
  156. package/scripts/legacy-claim-repair.js +145 -0
  157. package/scripts/lib/behavioral-eval-runner.js +310 -0
  158. package/scripts/lib/behavioral-eval-runtime.js +457 -0
  159. package/scripts/lib/eval-evidence.js +328 -0
  160. package/scripts/lib/eval-runner.js +81 -41
  161. package/scripts/lib/immutable-eval-corpus.js +309 -0
  162. package/scripts/lib/promotion-evidence-loader.js +94 -0
  163. package/scripts/lib/promotion-scorecard.js +314 -0
  164. package/scripts/npm-release-receipt.js +134 -0
  165. package/scripts/process-tree.js +773 -0
  166. package/scripts/protected-state-check.js +479 -31
  167. package/scripts/run-command-eval.js +29 -1
  168. package/scripts/sync-agent-skills.js +333 -34
  169. package/scripts/sync-d20-audit.js +172 -0
  170. package/scripts/test-full-suite.js +935 -37
  171. package/scripts/test-profile.js +13 -3
  172. package/scripts/test.js +271 -57
  173. package/skills/coverage.json +1 -0
  174. package/skills/review/SKILL.md +6 -11
  175. package/skills/review/evals/scorecard.json +4 -4
  176. package/skills/rollback/SKILL.md +4 -11
  177. package/skills/rollback/evals/scorecard.json +3 -3
  178. package/skills/setup/SKILL.md +18 -0
  179. package/skills/setup/evals/scorecard.json +3 -3
  180. package/skills/shepherd/SKILL.md +39 -16
  181. package/skills/shepherd/evals/scorecard.json +4 -4
  182. package/skills/ship/SKILL.md +4 -12
  183. package/skills/ship/evals/scorecard.json +3 -3
  184. package/skills/validate/SKILL.md +3 -0
  185. package/skills/validate/evals/scorecard.json +1 -1
  186. package/skills/worktree/SKILL.md +6 -1
  187. package/skills/worktree/evals/scorecard.json +2 -2
  188. package/lib/beads-setup.js +0 -538
  189. package/lib/beads-sync-scaffold.js +0 -189
  190. package/lib/pat-setup.js +0 -207
  191. package/lib/pr-monitor/render-sticky.js +0 -206
  192. package/lib/pr-monitor/upsert-sticky.js +0 -169
  193. package/scripts/beads-context.sh +0 -577
  194. package/scripts/beads-migrate-to-dolt.sh +0 -7
  195. package/scripts/beads-upgrade-smoke.sh +0 -284
  196. package/scripts/lib/beads-migrate-to-dolt.mjs +0 -503
package/AGENTS.md CHANGED
@@ -1,9 +1,14 @@
1
+ <!-- FORGE:START -->
1
2
  # Project Workflow Instructions
2
3
 
3
4
  ## Default TDD-First Workflow Template
4
5
 
5
6
  This project ships a **default TDD-first workflow template** with 6 workflow stages plus a composable **research** skill (a phase of `/plan` and usable standalone). In v3, these stages are one configurable composition over Forge runtime building blocks, not a product-wide mandatory ladder. Commands may be invoked as full stages or as smaller skill fragments when the active plan permits it. Pre-merge is an embedded gate in `/ship` and `/review` (not a numbered stage); `/status` and `/shepherd` are utilities (not stages).
6
7
 
8
+ ## Skill Dispatch (auto-trigger)
9
+
10
+ Before ANY response — including clarifying questions or exploring the codebase — if there is even a 1% chance a Forge skill applies, invoke it, then announce `Using [skill] to [purpose]`. Invoke the `using-forge` dispatch skill (auto-discovered from your agent's own skills — Forge setup installs it into each harness's skills dir; it carries the 1%-rule and routing table), or run `forge skill for "<situation>"` for the deterministic best-fit skill. This is agent-agnostic — never branch on harness identity.
11
+
7
12
  | Stage | Command | Purpose | Required For |
8
13
  |-------|-------------|-----------------------------------------------------------|--------------|
9
14
  | 1 | `/plan` | Design intent → research → branch + worktree + task list | Critical, Standard, Refactor |
@@ -17,7 +22,7 @@ This project ships a **default TDD-first workflow template** with 6 workflow sta
17
22
 
18
23
  **Utility**: `/status` — Context check before starting work (not a numbered stage)
19
24
 
20
- **Utility**: `/shepherd <pr>` — Autonomous PR ownership. `forge shepherd daemon` is a singleton reconcile daemon that owns **all** open PRs for the repo: it converges CI check state into kernel verdicts, re-runs flaky required checks (Tier-A), reaps orphan watchers, and self-retires when no PRs remain — so agents read verdicts (`forge shepherd <pr> --pull --json`, `forge shepherd events`) instead of hand-polling. `forge shepherd <pr>` is the one-shot bounded pass for a single PR. It is a utility, **not** a workflow stage. It **never merges** (the human merges in the GitHub UI) and **never resolves review threads** (that stays with `/review`). `--auto-rebase` is opt-in and default OFF; kill-switches: `FORGE_SHEPHERD_DISABLE`, `forge gate disable rail.auto_shepherd`. **Startup/containment**: the daemon is a repo singleton (O_EXCL lease a duplicate start is a clean no-op) started in the harness background shell so it is session-reaped; agents never launch it as a detached spawn (automatic per-command launch is a planned follow-up, W-S4c). See [docs/reference/shepherd.md](docs/reference/shepherd.md).
25
+ **Utility**: `/shepherd <pr>` — Autonomous PR ownership. `forge shepherd daemon` is a singleton reconcile daemon that owns **all** open PRs for the repo: it converges CI check state into kernel verdicts, re-runs flaky required checks (Tier-A), reaps orphan watchers, and self-retires when no PRs remain — so agents read verdicts (`forge shepherd <pr> --pull --json`, `forge shepherd events`) instead of hand-polling. `forge shepherd <pr>` is the one-shot bounded pass for a single PR. It is a utility, **not** a workflow stage. It **never merges** (the human merges in the GitHub UI) and **never resolves review threads** (that stays with `/review`). `--auto-rebase` is opt-in and default OFF; kill-switches: `FORGE_SHEPHERD_DISABLE`, `forge gate disable rail.auto_shepherd`. **Startup/containment**: Forge automatically wakes the repo-singleton daemon after a supported session start, every successful push, and every successful non-dry-run ship; duplicate starts remain clean no-ops under the O_EXCL lease. Injected CI/test and kill-switch guards return before lock or process work. Forge prefers the session-reaped harness background shell and otherwise detaches from the stable common repository root, never a disposable worktree cwd. See [docs/reference/shepherd.md](docs/reference/shepherd.md).
21
26
 
22
27
  ## Automatic Change Classification
23
28
 
@@ -113,11 +118,13 @@ Task 2: Validation logic
113
118
  ✓ Quality review: ✅
114
119
  ```
115
120
 
116
- ## State Management (Single Source of Truth)
121
+ **Flaky tests:** a test that changes result without the code changing gets
122
+ quarantined and an issue filed — never retried until green. Register it in
123
+ `test/QUARANTINE.md`. Reviewers reject a "re-run CI" as a fix.
117
124
 
118
- > GitHub issue lifecycle may sync to Beads via CI -- see [docs/guides/BEADS_GITHUB_SYNC.md](docs/guides/BEADS_GITHUB_SYNC.md).
125
+ ## State Management (Single Source of Truth)
119
126
 
120
- **Current implementation**: The Forge Kernel is the default issue-state authority; issue commands read and write the kernel store unless Beads is explicitly selected (`--issue-backend beads`, `FORGE_ISSUE_BACKEND=beads`, or `issueBackend: beads` in `.forge/config.yaml`), where it serves as an import/export/projection compatibility layer. **Direction (D44)**: continue consolidating issue/workflow/run authority in the Kernel with Beads remaining a compatibility projection. New authority work must follow [docs/work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md](docs/work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md) and [docs/reference/FORGE_KERNEL_STORAGE_MODEL.md](docs/reference/FORGE_KERNEL_STORAGE_MODEL.md).
127
+ **Current implementation**: The Forge Kernel is the sole issue-state authority — every issue command reads and writes the kernel store, with no backend to select. Beads exists only as an inbound migration path: `forge migrate --from beads` imports an existing Beads store into the kernel once, and no Forge command depends on Beads at runtime. **Direction (D45)**: the Kernel owns issue/workflow/run authority outright; Beads is retired as a live feature. New authority work must follow [docs/work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md](docs/work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md) and [docs/reference/FORGE_KERNEL_STORAGE_MODEL.md](docs/reference/FORGE_KERNEL_STORAGE_MODEL.md).
121
128
 
122
129
  ```json
123
130
  {
@@ -151,6 +158,7 @@ This project uses the **Professional Git Workflow** with Lefthook for automated
151
158
  - Offers guided recovery (add tests now, skip with tech debt tracking, emergency override)
152
159
  - No AI decision required - automatic validation
153
160
  - **Strong default, not a hard floor.** The TDD gate is the default-ON `rail.tdd_intent` rail; turn it off with `forge gate disable rail.tdd_intent` (the `minimal` adoption profile ships it off). The installed hooks read the resolved config at run time, so a disabled rail makes them genuinely inert — enforcement honestly follows your config.
161
+ - **Defers to a gate you already have.** If your repo already runs a TDD / source-test coupling check on pre-commit (any runner: lefthook, husky, the `pre-commit` framework, a raw `.git/hooks/pre-commit`), `forge setup` detects it, does **not** install a second gate on the same commit, turns `rail.tdd_intent` off, and says so. Prefer Forge's gate? Remove yours and run `forge gate enable rail.tdd_intent` — an explicit setting is never overwritten by a later setup.
154
162
 
155
163
  **Pre-push hook validates tests:**
156
164
  - Branch protection: blocks direct push to `main`/`master`
@@ -169,7 +177,7 @@ This project uses the **Professional Git Workflow** with Lefthook for automated
169
177
 
170
178
  ```bash
171
179
  forge push # Branch protection + lint + tests, then push
172
- forge push --quick # Review-cycle: lint-only push (CI runs full suite)
180
+ forge push --quick # Review-cycle: lint-only end to end (the pre-push hook's test job is skipped too; CI runs the full suite)
173
181
  forge worktree create <slug> # Create a worktree
174
182
  forge test # Run tests with correct timeouts
175
183
  forge sync # Sync issue data
@@ -231,7 +239,7 @@ See [.mcp.json.example](.mcp.json.example) for configuration (Claude Code: copy
231
239
 
232
240
  **Forge v3 / Kernel Plan (active design):**
233
241
  - [docs/work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md](docs/work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md) — canonical Forge Kernel authority reset plan for issue authority, local broker, team authority, adapters, storage, and gates
234
- - [docs/work/2026-04-28-skeleton-pivot/locked-decisions.md](docs/work/2026-04-28-skeleton-pivot/locked-decisions.md) — D1–D44 decisions ledger with rationale + tradeoffs + anti-decisions; D44 supersedes Beads-only authority portions of earlier decisions
242
+ - [docs/work/2026-04-28-skeleton-pivot/locked-decisions.md](docs/work/2026-04-28-skeleton-pivot/locked-decisions.md) — D1–D45 decisions ledger with rationale + tradeoffs + anti-decisions; D44 supersedes Beads-only authority portions of earlier decisions, and D45 retires Beads as a live feature
235
243
  - [docs/work/2026-04-28-skeleton-pivot/v3-redesign-strategy.md](docs/work/2026-04-28-skeleton-pivot/v3-redesign-strategy.md) — historical v3 strategy and background; do not use its legacy default-substrate language over D44
236
244
  - See [docs/INDEX.md](docs/INDEX.md) for the full reading order across the v3 design folder
237
245
 
@@ -303,7 +311,7 @@ forge insights # Detect recurring evidence patterns, suggest con
303
311
  forge upgrade # Preview and self-heal safe Forge upgrade readiness
304
312
  forge gate <verb> <gate-id> # Toggle a workflow gate, or record/query human-gate approval events
305
313
  forge role <role> --use <skill> # Bind a role to a skill/ideology in .forge/config.yaml
306
- forge merge --auto <pr> # Opt-in conditional auto-merge merges only when configured rules pass (OFF by default)
314
+ forge merge --auto <pr> --expect-head <full-sha> --issue <issue-id> # Opt-in guarded merge; exact head + owned issue required (OFF by default)
307
315
  ```
308
316
 
309
317
  ### Rules
@@ -334,6 +342,7 @@ runtime rail. Turn it off only deliberately: `forge gate disable rail.kernel_tra
334
342
  - **Unused params**: Prefix with `_` (e.g., `_searchTerm`) — ESLint `no-unused-vars` enforced with `--max-warnings 0`.
335
343
  - **Pre-push test env**: `test-env/` fixture tests can fail during actual `git push` due to git mid-push state. Fix the root cause — never use `LEFTHOOK=0`.
336
344
  - **Skill sync**: Canonical skills live in `skills/<name>/SKILL.md`; per-agent copies are generated from them. `.agents/skills` (Codex's repo-local discovery path) is committed so a fresh clone gets discovery without `forge setup` — a pre-commit hook keeps it byte-identical to `skills/` and the drift gate enforces it. The other mirrors (`.claude/skills`, `.codex/skills`, `.cursor/skills`, `.hermes/skills`) are gitignored and regenerated at `forge setup`. Never hand-edit a generated mirror — edit the canonical `skills/` source.
345
+ - **Skill invocation metadata**: Canonical skill frontmatter may declare `invocation: model|user`; omission means `model`. Only `ship`, `review`, and `rollback` are currently user-invoked. Keep the field harness-neutral and preserve it byte-identically in every generated mirror.
337
346
 
338
347
  ## Session Completion
339
348
 
@@ -361,3 +370,5 @@ runtime rail. Turn it off only deliberately: `forge gate disable rail.kernel_tra
361
370
  - NEVER say "ready to push when you are" - YOU must push
362
371
  - If push fails, resolve and retry until it succeeds
363
372
  - After fixing review feedback, always push the changes and resolve the related GitHub review threads via the GraphQL API before considering the work complete
373
+
374
+ <!-- FORGE:END -->
package/CHANGELOG.md CHANGED
@@ -7,7 +7,85 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  > **Note**: `/check` was renamed to `/validate` and `/merge` was renamed to `/premerge` in v0.0.3. Historical entries below may use the old names.
9
9
 
10
- ## [Unreleased]
10
+ ## [0.1.0-beta.6] - 2026-09-11
11
+
12
+ ### Added
13
+
14
+ - **Optional repository-scoped GitHub account context.** Adds clone-local `github.account` binding, native GitHub CLI named-account retrieval, live identity verification, child-only credential scoping across Forge GitHub routes, and concurrent launcher isolation without changing global authentication, Git authorship, or transport configuration. (#554, issue `ee4869d5-77af-4959-909c-190e99b3ada0`)
15
+ - **Dormant Shepherd owner-authority foundation.** Adds the composite-key Kernel schema, migration gate, and bounded transactional owner API without changing any production watcher, daemon, lease, monitor, or command caller. The atomic caller cutover remains isolated in the dependent PR. (#540, issue `ca693a15-c430-404b-9e97-7de59b529eee`)
16
+ - **Atomic Shepherd watcher-authority cutover.** Routes direct, adopt, child, and daemon watcher lifecycles through the Kernel owner row and exact-complete migration gate; reduces the singleton lease to election only; and removes persisted PID, lease-watcher, generation-marker, cleanup-marker, and in-memory authority writers. (#541, issue `700c07c3-e06d-48ed-9b24-229cd7872069`)
17
+ - **Public receipt-bound PR lifecycle authority.** `@forge/memory` now issues exact-head WorkPackets, authenticates RunReceipts, durably links exact `pr.opened` evidence through public Kernel provider seams, requires and rechecks live session-bound ownership and authoritative readiness, preserves Kernel ready order, and fails closed on replay conflicts, stale evidence, unsafe paths, provider loss, and unbounded operations. External merge and terminal `pr.merged` linkage remain owned by the guarded Forge merge path; canonical LeaseReceipt epochs remain explicitly deferred for 0.1. (issue `c2a3c655-ade2-4156-a8dc-e6b4ee2827ad`)
18
+ - **Human-gated legacy claim repair.** Adds a fixed-time, privacy-safe claim preflight, separately restored SQLite backup proof, and exact-digest `BEGIN IMMEDIATE` repair with terminal precedence, null-expiry preservation, CAS drift rejection, idempotent receipts, and interruption rollback. The operator-only script is never run at startup. (PR #528, issue `0fd8b8c1-686c-4808-8d99-f9ed5b9571de`)
19
+ - **Memory recall and session-attention stabilization.** Typed recall now filters before limits, superseded notes hide by default but remain recoverable, Claude read-attention injects only fenced path-matched notes, and session-summary reminders remain current and idempotent. (#504, issue `0874844f-9c0c-449a-994e-a804fe3fc3a5`)
20
+ - **Frozen beta.5 compatibility evidence.** Adds a content-hashed v0.1.0-beta.5 contract and state corpus, privacy-safe inventory, isolated backup/restore proof, and deterministic non-mutating migration dry-run results for Windows and Linux-safe paths. (#498, issue `5dad8dbf-1c49-444d-a407-a48583537817`)
21
+ - **Forge 0.1.0 control-plane foundations.** Adds executable issue-readiness contracts, dead-run claim reconciliation, issue-scoped approval receipts, Kernel-authoritative plan snapshots, fail-closed risk-to-test selection, and distinct npm beta, RC, and stable release channels. (#497; issues `4ee7f9a9-4fa0-42c1-bd96-96638cc9feff`, `9b69a551-f5a0-4057-9d9f-96fb0d744fd3`, `b977b0a2-11f6-40d7-a230-8e2ff5f79115`, `b811a974-a866-47e0-8f83-3f5d2423aded`, `7a6a3fb3-c82c-48e7-86ee-630c171b924c`, `3e46debd-11c3-4b1c-b59a-17304c37cb03`)
22
+ - **Deterministic Bun lockfile ownership.** Protected-state validation can approve a staged root `bun.lock` only when pinned Bun reproduces its exact bytes from captured staged package manifests: first from the committed lock, then from a clean no-lock state only after an exact byte mismatch. Index races, tampering, unsafe paths/configuration, tool drift, and environment-seam hiding fail closed. (issue `a6c52ac8-6f80-4f2d-8d3c-d83eb92becbd`)
23
+
24
+ ### Fixed
25
+
26
+ - **Legacy claim repair now compares exact Windows file identities and timestamps.** BigInt filesystem metadata prevents rounded device/inode collisions from treating distinct files as aliases, while nanosecond timestamps keep recovery-state drift checks fail closed. (#556, issue `7e164066-4d41-4d14-90ef-1b7ee14e2b73`)
27
+ - **Dep-guard apply-decision tests no longer contend with shared Windows subprocess shards.** The process-heavy suite now uses the existing exclusive resource lane, with exact scheduler coverage and no timeout increase or exemption. (issue `762ae565-0059-4827-9c3d-b4249f2b3364`)
28
+ - **Bun workflow proof tests no longer contend with shared full-suite shards.** The process-heavy commit-boundary proof now uses the existing exclusive resource lane, with exact scheduler coverage and no timeout increase or exemption. (#552, issue `2daab8c0-34d6-4378-8cf4-dce6fdbfb86b`)
29
+
30
+ - **The protected-state pre-commit check is now merge-aware.** While a merge is in progress (per-worktree `MERGE_HEAD`), a staged protected path is exempt only when its full staged index entry (mode, object type and object id) is identical to that path's entry on `HEAD`, or on a `MERGE_HEAD` contained in the repository's canonical upstream ref (the base remote — `upstream` preferred over `origin`, the same resolution `/ship` uses to pick a PR base, then that remote's default branch) — content already published on the official base rather than on a contributor's fork. The base-remote resolver now lives in `lib/base-remote.js` and is shared with `/ship`, so a change merged from a fork's default branch but never published upstream stays blocked — content already published on the line this repo integrates into, carried in by the merge rather than edited. A local-only branch, an untrusted contributor remote, or a hand-created `refs/remotes/*` ref earns no exemption, an unresolvable `HEAD` grants no exemption context at all, `bun.lock` still requires its regeneration proof, paths differing from every trusted revision stay blocked, the non-merge path is unchanged, and any failed git query fails closed. (issue `f6d43eb1-249d-4d81-b679-32502ffa28c2`)
31
+ - **Worktree dependency repair now covers Bun workspace shapes and reused worktrees.** Workspace discovery accepts array and object-form manifests plus wildcard and exact paths, reused worktrees revalidate dependencies before returning, and full-suite stderr tails redact complete lines before bounded retention. (#550, issue `465f7e62-1928-4bcf-97a5-c2db05504a7e`)
32
+ - **Validation and dependency recovery gates are reproducible and fail closed.** The protected-state hook now accepts either an exact pinned-Bun transition from the committed lock or an exact clean no-lock regeneration after that transition mismatches; the regenerated lock clears all dependency advisories, every active Bun execution surface is pinned to 1.4.2, and `forge validate` gives the full suite measured capture headroom while distinguishing numeric skipped-test counts from an entirely skipped check. (#551; issues `95ed6f9c-6f23-41f4-9bc4-13177a96ccf2`, `1f7baefc-c9cc-4acf-9cad-e98c53f308ba`, `cfffed63-51dd-4145-acb2-a18f41ef2846`)
33
+ - **Bare conditional merge no longer blocks on intentionally skipped optional checks.** `checks_green` now partitions the authoritative protected context/application set from optional check runs: protected and explicit `only` checks remain strict `SUCCESS`, while terminal optional `NEUTRAL` and `SKIPPED` results no longer block. Missing, malformed, unsafe, and nonterminal evidence still fails closed. (#549, issue `fa805e7e-e718-438f-a776-bd860c80e99a`)
34
+ - **The full-suite worker budget now weights subprocess workers by real process cost.** A subprocess-lane worker owns two Windows processes (its own bun runtime plus the `bun.exe` grandchild its tests spawn), so granting three of them on a 4-vCPU runner oversubscribed the box and produced wall-clock-only failures. Grants are now made against the budget by cost (subprocess/exclusive = 2 units on `win32`, 1 elsewhere; unit = 1), the strongest lane always keeps one worker so the schedule can never stall at zero, and the plan log prints the *granted* concurrency plus the cost and budget instead of the nominal lane concurrency. Non-Windows scheduling is unchanged. (issue `9b8dfa31-4a76-4ef2-b7e9-331d248e3850`)
35
+ - **`forge push` no longer kills a passing full test suite.** The pre-push test run is budgeted from the shared full-suite budget in `scripts/test.js` instead of a hardcoded 120s cap, and that shared budget is raised from 10 to 25 minutes — the previous default sat *below* the measured healthy runtime (602.43s for 8038 tests on Windows), so it SIGKILLed good runs. The ceiling now carries >2x headroom because it exists to catch an indefinite hang, not to bound normal runtime; `FORGE_TEST_TIMEOUT_MS` still overrides. A run terminated by a timeout, signal, or spawn error now reports what happened instead of failing with no summary. (issue `e26dbb91-0443-4e53-946e-a9941ec30ca3`)
36
+ - **The targeted PR lane's full-suite fallback now uses the lane-aware runner.** When the execution planner returns `mode=full`, the follow-up job runs `scripts/test-full-suite.js` instead of a raw `bun test test/`, so subprocess-heavy files get resource-lane separation and the worker budget the full matrix already had — closing the Windows-only spawn failures that hit only this lane.
37
+ - **Full-suite validation now respects the computed worker budget.** Resource-aware lanes share the reserved worker pool by default, and `forge validate` uses that runner when available, preventing mixed unit and subprocess shards from oversubscribing Windows runners. (PR #545, issue `8cb52d50-24ea-4c69-8579-b30a0f1ee467`)
38
+ - **Windows legacy-claim repair now preserves owner-only ACL guarantees without PowerShell transport stalls.** The operator-only repair path uses bounded, privacy-safe Windows security-descriptor verification, exact owner/DACL replacement, Unicode-safe targets, transaction-isolated async hardening, and fail-closed timeout cleanup. (#538, issue `eb2c56e8-5054-4542-8f02-3f9fe635fd2d`)
39
+ - **Local full-suite validation is deterministic under Windows process pressure.** Resource-aware lanes, runtime-balanced subprocess shards, isolated coordination state, direct commitlint execution, batched Flow-monitor replay, and exact failure attribution remove rotating shared-state and child-process flakes without weakening timeouts or gates. (#538; issues `51672736-3387-4d0f-950d-4ae6e5e2c13e`, `9eb98ac0-ebe1-4604-a57a-5fefadad6682`)
40
+ - **PR lifecycle acceptance fails closed at its authority and privacy boundaries.** Every opened linkage write now proves exact live claim ownership, timed-out persistence reconciles only through bounded durable trace evidence, and bare POSIX user-home paths are rejected before WorkPacket publication. (#530, issue `50571aa3-b1cd-42f4-9c50-2c7576d1b0d4`)
41
+ - **Official skill-mirror writes retain protected-state authority.** The canonical `.agents/skills` sync now uses one-time, actor/path/content/source-HEAD/worktree-bound authorization and completion receipts, verifies byte equality with `skills/`, and continues to deny direct, stale, replayed, or foreign writes. (issue `209d80bc-f521-4947-9953-e5b5bf7020f6`)
42
+ - **Workspace lockfile proofs are path-independent.** Bun regeneration now receives the isolated proof root explicitly, preventing temporary proof paths from leaking into workspace keys. (issue `3eb1db42-eaa3-4847-9878-7b77310d1beb`)
43
+ - **Windows lockfile proofs canonicalize temporary roots.** Native path resolution prevents 8.3 TEMP aliases from changing regenerated lock bytes. (issue `3eb1db42-eaa3-4847-9878-7b77310d1beb`)
44
+ - **Linked-worktree lockfile proofs no longer mutate shared Git configuration.** Internal proof Git commands discard inherited repository-local Git environment variables while preserving the host toolchain environment. (issue `93cb615f-2e6e-45ff-90c1-6c98e47f0fff`)
45
+
46
+ ## [0.1.0-beta.5] - 2026-08-09
47
+
48
+ ### Added
49
+
50
+ - **Controlled behavioral skill evaluation.** `forge skill eval <skill> --full --tier <30|100|300>` now runs the frozen two-model × current/bounded protocol with exact-head issue/PR attribution, isolated zero-tool runtimes, privacy-safe semantic evidence, fail-closed conflict handling, and deterministic promotion scoring. Thirty cases remain instrumentation-only; evaluation never supplies merge authority. (issue `198bec40-0d65-42a8-b2c2-c682f44fdb22`)
51
+ - **Host-owned Shepherd background transport.** Session startup now forwards an explicitly supplied harness background-shell capability, runs it from the stable Git common root, and preserves the detached fallback when the capability is absent or fails. (#494, issue `60ccc100-506b-46a6-bf96-b2fce3436ed6`)
52
+ - **Critical merge-flow reliability integration plan.** Defines a deterministic safety floor, executable work contracts, configurable risk policy, zero-token owner monitoring, and a sequential exact-head merge slot without constraining model reasoning. (#493, issue `a57a2b2a-3b0d-4fce-bf13-e3e4a386f1c9`, epic `f30e5d29-9099-4029-baec-af39f08b6ee3`)
53
+ - **Model-neutral evaluation evidence and exact-SHA replay.** Adds a privacy-safe content-addressed envelope with fail-closed drift checks while excluding raw prompts, transcripts, tool payloads, secrets, and personal data. (#491, issue `02f5ea90-4a1a-462f-9b22-54eb5d37f6b3`)
54
+ - **Automatic project-local memory recall for Claude Code.** Forge now repairs and reuses its existing `SessionStart` and `UserPromptSubmit` lifecycle hooks to inject bounded Kernel memory automatically. Confirmed memories are presented as project truth; fresh suggested memories are separated and labeled for verification. Scope, staleness, supersession, and seen-key filtering happen before ranking, and privacy-safe recall telemetry records only bounded identifiers and aggregates—not prompt terms or memory bodies. (`36461e50`)
55
+
56
+ ### Changed
57
+
58
+ - **Exact-SHA npm publication evidence.** The Forge-generated publish workflow now resolves one immutable tag SHA, requires the complete repository suite and an attributable matching receipt before npm publication, and protects workflow updates with one-time Kernel capabilities instead of forgeable sidecar evidence. (issue `198bec40-0d65-42a8-b2c2-c682f44fdb22`)
59
+ - **Simplified the PR-monitor surface.** The workflow now keeps one canonical
60
+ `pr-verdict:*` label and writes detailed diagnostics to the Actions job summary
61
+ (also available via `forge shepherd --pull --json`); it no longer creates a
62
+ sticky PR comment or the neutral `forge/pr-monitor` check. The label remains a
63
+ visibility projection and never supplies merge authority. (112a348a)
64
+ - Added portable `invocation: model|user` skill metadata with omission defaulting to `model`; `ship`, `review`, and `rollback` are now explicitly user-invoked while canonical and generated skill projections remain byte-identical. (#467, `588e6973`)
65
+ - Documented why Litestream remains a disaster-recovery candidate rather than Forge's multi-machine authority; self-hosted libSQL remains the Phase 2 server target. (#463, `746d839d`)
66
+
67
+ ### Fixed
68
+
69
+ - **Windows full-suite drive classification no longer launches a redundant PowerShell probe for every child process.** Persistent mappings still use the bounded `net use` probe; an unclassified non-system drive now fails open as unknown instead of being mislabeled fixed. (#496, issue `1efe5de9-6bfb-448f-8575-624577b829f2`)
70
+ - **Injected synchronous pre-push runners no longer create real process-tracking state.** Targeted-mode unit execution keeps its command and edge-suite assertions while avoiding the Windows process-tree setup that pushed the test beyond Bun's 15-second limit. (issue `54b54219-7cbc-4262-9461-a77112a7c49b`)
71
+
72
+ ## [0.1.0-beta.4] - 2026-07-24
73
+
74
+ The **Kernel-only authority and autonomous Shepherd wave** removed the remaining live Beads runtime path while expanding Forge's portable skill and PR-monitoring surfaces.
75
+
76
+ ### Added
77
+
78
+ - Reasoning-driven skill invocation, sub-skill composition, static skill evaluation, and dedicated setup, portability, worktree, and gate skills. (#417-#419, #429-#434)
79
+ - Kernel-backed PR authority, singleton Shepherd leases, reconciliation, daemon execution, and cross-harness triggering guidance. (#420-#428)
80
+ - Query-relevant project-memory recall for supported agent sessions. (#440-#441)
81
+
82
+ ### Changed
83
+
84
+ - Issue commands, status, and dashboards now use the Forge Kernel exclusively; the live Beads backend and dashboard surfaces were retired. (#435-#439)
85
+
86
+ ### Fixed
87
+
88
+ - Targeted pre-push selection recognizes Forge CLI surfaces, and Shepherd background processes stay hidden and derive required checks consistently on Windows and CI. (#420-#421, #438)
11
89
 
12
90
  ## [0.1.0-beta.3] - 2026-07-17
13
91
 
package/CLAUDE.md CHANGED
@@ -1,13 +1 @@
1
- # Project Instructions
2
-
3
- Forge uses **[AGENTS.md](AGENTS.md)** as the single source of truth for all agent
4
- instructions: the workflow template, change classification, detailed stage
5
- instructions, git hooks and push workflow, build/shell/MCP toolchain, issue
6
- tracking, project learnings, and session completion. This file intentionally
7
- holds no content of its own — it only loads AGENTS.md.
8
-
9
1
  @AGENTS.md
10
-
11
- > **IMPORTANT**: Read [AGENTS.md](AGENTS.md) using the Read tool at the start of
12
- > every session to load the current Forge workflow contract. AGENTS.md is
13
- > authoritative; do not duplicate its content here.
@@ -0,0 +1,72 @@
1
+ # Coding Standards (read at review time)
2
+
3
+ This file is **not** loaded every turn. It is read by the review step — the
4
+ `/review` stage, the `code-review` skill, and any human or bot reviewing a diff —
5
+ and nowhere else. Everything here is a property a reviewer can check **by reading
6
+ the diff**. Rules about how an agent shapes its turn (arm the shepherd, work in a
7
+ worktree, don't stall, don't poll on a fixed timer while waiting) live in
8
+ [AGENTS.md](AGENTS.md), because no diff shows them.
9
+
10
+ **How to add to it:** when you catch an agent (or yourself) doing something wrong
11
+ in a change, add one line here, stated positively, with an evidence tag naming
12
+ where the evidence came from — `[mined: <cluster> ×N]` for the transcript-mining
13
+ counts, `[git: <pattern>]` for repository history, `[incident: <what happened>]`
14
+ for a single concrete failure. No rule without evidence; delete a rule when its
15
+ evidence stops recurring.
16
+
17
+ ---
18
+
19
+ ## Scope
20
+
21
+ 1. Every file in the diff is one the originating issue or design doc named; an
22
+ unrelated fix found along the way gets its own issue and its own PR.
23
+ `[mined: scope creep — unrelated fixes into the PR ×6]`
24
+ 2. A follow-up noted in the diff cites a kernel issue id, not a bare `TODO` or
25
+ `FIXME`. `[mined: discussed work not filed as kernel issue ×3]`
26
+
27
+ ## Gates and tests
28
+
29
+ 3. A failing check is fixed at its cause; the diff does not raise a timeout,
30
+ add a skip, loosen a threshold, or replace a real assertion with a vacuous
31
+ one to get green. `[mined: weakening gates/tests to pass ×3]`
32
+ 4. Tests synchronize on an observable condition (poll until true, await the
33
+ event), never on a fixed sleep or timer duration.
34
+ `[mined: waiting a fixed 10 min when reviewers already settled ×2]`
35
+ 5. A new or moved source path that needs targeted tests lands in both the
36
+ targetability checks in `scripts/test.js` and the `DIRECT_TEST_CANDIDATES`
37
+ mapping in `lib/commands/test.js`, so it does not silently fall into the
38
+ full-suite lane.
39
+ `[mined: slow test/CI lanes accepted as normal ×3]` `[git: 13 fix commits touch scripts/test.js]`
40
+
41
+ ## Generated artifacts and single source of truth
42
+
43
+ 6. Skills are edited in the canonical `skills/` tree and mirrors are regenerated
44
+ by `scripts/sync-agent-skills.js`; the diff never hand-edits `.agents/skills/`
45
+ or another generated mirror.
46
+ `[mined: duplicating skills per agent instead of skill-CLI generation ×4]`
47
+ `[incident: recurring skills-sync-drift failures]`
48
+ 7. Adding, deleting, or renaming a `lib/commands/*.js` file includes the
49
+ regenerated command manifest (`scripts/gen-command-manifest.js`) in the same
50
+ diff. `[git: 24 fix commits touch bin/forge.js, 15 touch lib/commands/setup.js]`
51
+
52
+ ## Product boundary
53
+
54
+ 8. Issue authority reads and writes go through the kernel; the diff adds no code
55
+ path that treats Beads or Dolt as a live backend.
56
+ `[mined: treating beads as live backend ×5]` `[decision: D45 retires Beads as a live feature]`
57
+ 9. Shipped code discovers its own paths and config; no maintainer machine path,
58
+ local username, or personal directory appears in a committed file.
59
+ `[incident: hardcoded C:\Users\<user>\Downloads\forge in .claude/settings.json]`
60
+ 10. A new runtime asset the installed package needs is added to the `files`
61
+ allowlist in `package.json` in the same diff.
62
+ `[incident: protected-paths.yaml missing from the npm files allowlist]`
63
+ 11. PR-monitoring capability is wired into the substrate — a hook, the ship
64
+ path, or a gate — not left as a step someone must remember to invoke.
65
+ `[mined: shepherd not armed/auto-attached on ship ×10]`
66
+
67
+ ## Repository hygiene
68
+
69
+ 12. Machine-local runtime state (per-session caches, saved PR diffs, symlinks
70
+ into worktrees, stray shell artifacts, and transient kernel .export.lock /
71
+ .tmp-* files) is gitignored, never committed. Deterministic .forge/kernel/
72
+ JSONL and manifest projections are tracked export/import artifacts. `[git: triage 2026-08-15 found NUL, gw/, .hermes/, .forge/kernel/, pr*.diff untracked at repo root]`
package/README.md CHANGED
@@ -89,6 +89,11 @@ truth through `forge status`, `forge prime`, and `forge orient` — so a session
89
89
  that dies at 2am resumes cleanly the next morning, on any device, with any
90
90
  agent.
91
91
 
92
+ In Claude Code, Forge also recalls relevant project-local memory automatically
93
+ through its existing lifecycle hooks. Confirmed memories arrive as project
94
+ truth; suggested memories are visibly separated and require verification.
95
+ Every injected memory is scope-checked, budgeted, and provenance-labeled.
96
+
92
97
  ### 🧹 A lifecycle that cleans up after itself
93
98
 
94
99
  Merged a PR with squash-merge? `forge clean` still knows the worktree is done —
@@ -151,7 +156,7 @@ so a claim can't quietly outrun the code. What's not delivered yet says
151
156
  | --- | --- |
152
157
  | Knowledge-graph memory (Graphiti) | `memory.backend: graphiti` in `.forge/config.yaml` — temporal, relational recall ([guide](docs/guides/memory-backends.md)) |
153
158
  | Global hooks for Codex/Hermes | `forge hooks install --global` (consent-guarded, `--dry-run` first) |
154
- | Conditional auto-merge | `forge merge --auto <pr>` — off by default, merges only when configured rules pass |
159
+ | Conditional auto-merge | `forge merge --auto <pr> --expect-head <full-sha> --issue <issue-id>` — off by default; requires exact-head and active issue-ownership leases plus protected checks |
155
160
 
156
161
  ## A workflow you own
157
162
 
@@ -261,7 +266,6 @@ Use `bunx forge ...` (or `npx forge ...`) until the `forge` bin is on your PATH.
261
266
  | `--dry-run` | Preview planned writes without touching the repo. |
262
267
  | `--symlink` | Link instruction files instead of copying, where supported. |
263
268
  | `--merge smart\|preserve\|replace` | Choose how setup handles existing instruction files. |
264
- | `--sync` | Deprecated. Removes old generated Beads/GitHub sync files; future issue sync belongs to Kernel/server authority. |
265
269
 
266
270
  ## What you get
267
271
 
package/bin/forge-cmd.js CHANGED
@@ -31,6 +31,16 @@ const VALID_COMMANDS = [
31
31
  'verify',
32
32
  ];
33
33
 
34
+ /**
35
+ * Find the planning doc for a work slug under a `docs/work` tree.
36
+ *
37
+ * Recurses into dated work directories (`YYYY-MM-DD-<slug>`) and returns the
38
+ * first `plan.md`, `design.md`, or `tasks.md` whose directory slug matches.
39
+ *
40
+ * @param {string} dir - Directory to search (typically `docs/work`).
41
+ * @param {string} slug - Work slug, without the date prefix.
42
+ * @returns {string|null} Path to the matching doc, or null when none matches.
43
+ */
34
44
  function findWorkPlanDoc(dir, slug) {
35
45
  if (!fs.existsSync(dir)) return null;
36
46
 
@@ -60,6 +70,16 @@ function legacyPlanMatchesSlug(fileName, slug) {
60
70
  return legacySlug === slug;
61
71
  }
62
72
 
73
+ /**
74
+ * Resolve the planning doc that backs a branch.
75
+ *
76
+ * Strips the conventional-commit branch prefix to get the slug, prefers a
77
+ * `docs/work/<date>-<slug>/` doc, and falls back to the legacy flat
78
+ * `docs/plans/` layout.
79
+ *
80
+ * @param {string} branch - Branch name, e.g. `feat/slice-d1-deletion`.
81
+ * @returns {string|null} Path to the planning doc, or null when none exists.
82
+ */
63
83
  function findPlanDocForBranch(branch) {
64
84
  const slug = branch.replace(/^(feat|fix|docs|refactor)\//, '');
65
85
  const workPlan = findWorkPlanDoc('docs/work', slug);