diff --git a/docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md b/docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md new file mode 100644 index 000000000..04dec4840 --- /dev/null +++ b/docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md @@ -0,0 +1,186 @@ +--- +date: 2026-05-06 +topic: ce-replan-beta-skill +revision: 2 +supersedes: docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md +--- + +# `ce-replan-beta` Skill + +## Summary + +`ce-replan-beta` is a beta skill that, when an existing PR's approach has been outgrown by new learnings, runs a two-phase **re-brainstorm → re-plan** cycle and produces fresh artifacts that always start from `main`. Phase one forks the original requirements doc into a new dated version with R-IDs carried forward stably; phase two derives a full-redo plan from the updated requirements. The original PR, plan, and brainstorm are preserved untouched — the new artifacts supersede them by reference. The skill performs no Git operations; the user starts a fresh branch from `main` themselves. + +The shape closes a compounding loop. Each revolution sharpens the requirements layer (with stable R-IDs serving as anchors across revisions) and produces a new plan that traces back to those requirements. After many revolutions, the latest brainstorm + latest plan are the live source of truth, and the chain of supersedes-links lets a reader walk back through the history. + +--- + +## Problem Frame + +A long-running PR is a snapshot of one moment of understanding. Reviewers find issues, the user reads more code, an adjacent brainstorm surfaces an alternative — the original plan's framing slowly stops fitting. By the time the user knows what they should have planned, they're stuck in one of two failure modes: + +- **Re-running `/ce-plan` from scratch.** Loses every good thing the PR has accumulated and treats the original work as wasted, even though much of it is still right. +- **Patching the existing plan in place.** Silently inherits the framing and scope assumptions that should have been re-questioned. The new "plan" is the old plan with edits, not a rethink. + +Both failures share a root cause: the **requirements layer rots**. The original `*-requirements.md` was written before the new learnings; if it isn't refreshed, every downstream plan reasons against stale framing. v1 of this skill (shipped on PR #785) tried to compensate by annotating requirements *inside the new plan doc* — but that conflated WHAT and HOW into a single artifact, and left the original brainstorm untouched, so future planning runs would still find the stale doc. + +The first real run of v1 (cora session `10b929fb-c03f-4daf-b675-32c00ac44b43` on PR #2382) surfaced the issue cleanly. v1 produced a delta-shaped plan against `brief-view`'s tree — units referencing post-pivot code that didn't exist on `main`. ce-work caught the mismatch and asked the user to choose a branch base; the user replied **"no it replan so start from main no base don we redo the full plan."** The verb *replan*, in the user's mental model, means *redo from main with the latest understanding folded in* — not *adjust forward from where the PR is*. + +v2 takes that signal seriously. It does what the verb says. + +--- + +## Actors + +- A1. **User invoking the skill.** Has decided the PR's approach needs rethinking and wants the skill to walk them from rethink → fresh requirements → fresh plan. +- A2. **`ce-replan-beta` skill.** Discovers context inside the working repo (PR, original plan, original brainstorm, prior conversation), runs the re-brainstorm and re-plan phases, and writes two new dated artifacts. +- A3. **Downstream `ce-work`.** Consumes the new plan to drive execution against a fresh branch from `main`. Out of scope to build, but the handoff must commit to a branch base so ce-work doesn't re-ask the user. + +--- + +## Key Flows + +- F1. **Replan with original brainstorm available.** + - **Trigger:** User invokes `/ce-replan-beta` (blank or with a PR number) on a PR whose plan was derived from a `*-requirements.md`. + - **Actors:** A1, A2. + - **Steps:** + 1. Skill detects the PR (auto or explicit) and discovers the original plan, original brainstorm, recent brainstorm activity, PR review threads, and prior conversation. + 2. **Phase 2a — re-brainstorm.** Skill re-derives the problem frame from user discussion language, walks every original requirement and assigns `[unchanged]` / `[revised]` / `[discarded]` with reasoning, lists new requirements, and presents a synthesis at the requirements scope. + 3. **Phase 3a — re-brainstorm synthesis checkpoint.** User confirms or revises (interactive); pipeline mode skips the prompt. + 4. **Phase 4a — write forked brainstorm.** Skill writes a new dated `*-requirements.md` with stable R-IDs, `supersedes:` and `revision:` frontmatter, and a `## Discarded Requirements` section that preserves the gap-with-reason. + 5. **Phase 2b — re-plan.** Skill derives a fresh plan from the forked brainstorm, with units written for the from-`main` baseline. Cherry-pick guidance names what to preserve from the original PR. + 6. **Phase 3b — re-plan synthesis checkpoint.** User confirms or revises; pipeline mode skips the prompt. + 7. **Phase 4b — write plan.** Skill writes the new plan with R-ID references back to the forked brainstorm. + 8. **Phase 5 — handoff.** Skill commits to `main` as the branch base and presents three options: start `ce-work`, open in Proof, or done. ce-work invocation passes the plan path and the branch base forward. + - **Outcome:** Two new dated artifacts in `docs/brainstorms/` and `docs/plans/`. Original PR, plan, and brainstorm are untouched. + - **Covered by:** R1, R2, R4–R12, R14, R16 + +- F2. **Replan with no original brainstorm.** + - **Trigger:** User invokes `/ce-replan-beta` on a PR whose plan was written from scratch (no `origin:` link, no matching `docs/brainstorms/` doc). + - **Actors:** A1, A2. + - **Steps:** Skill skips Phase 2a / 3a / 4a entirely. Re-plan phase derives directly from the original plan + PR + learnings. Output is one artifact: the new plan. + - **Outcome:** One new dated plan in `docs/plans/`. No brainstorm is synthesized out of thin air. + - **Covered by:** R3, R12 + +- F3. **No PR found.** + - **Trigger:** User invokes `/ce-replan-beta` with no argument and no PR exists for the current branch, or with an explicit PR number that doesn't exist or is inaccessible. + - **Actors:** A1, A2. + - **Steps:** Skill writes nothing, explains that `ce-replan-beta` is anchored to existing PRs, and routes the user to `ce-plan` or `ce-brainstorm`. + - **Outcome:** No artifacts written. + - **Covered by:** R17 + +--- + +## Requirements + +**Skill identity** +- R1. Standalone beta skill named `ce-replan-beta` under `plugins/compound-engineering/skills/`. Frontmatter sets `disable-model-invocation: true` and an `argument-hint` of `[PR number, or blank for current branch's PR]`. Description is `[BETA]`-prefixed per the beta-skills framework. + +**Two-phase flow** +- R2. The skill runs as two sequential phases: re-brainstorm followed by re-plan. The shape mirrors `ce-brainstorm` → `ce-plan` but is anchored to existing artifacts and learnings. +- R3. When no original brainstorm exists for the PR, the re-brainstorm phase is skipped and the skill proceeds directly to re-plan. The skill does not synthesize a brainstorm out of thin air. +- R4. Each phase has its own synthesis checkpoint in interactive mode. They are presented sequentially, not combined — confirming requirement edits and plan units in the same breath conflates WHAT and HOW. +- R5. In pipeline mode (LFG / `disable-model-invocation`), both phases run silently. Inferred bets route to a `## Assumptions` section in each artifact. Neither phase blocks. + +**Re-brainstorm phase — fork, never mutate** +- R6. The phase forks a new dated `docs/brainstorms/YYYY-MM-DD--rebrainstorm-requirements.md` that supersedes the original by reference. The original brainstorm is **never edited or deleted on disk**. +- R7. **R-IDs carry forward stably.** Original IDs preserved; revisions keep the ID with new wording; discards leave a gap (R3 absent is fine — gaps are how the loop stays auditable). New requirements get the next-unused R-ID. No renumbering, ever. +- R8. Forked brainstorm frontmatter names the original via `supersedes:` (path) and includes `revision:` (integer that increments each revolution). +- R9. Each carried-forward requirement is annotated `[unchanged from rev N]` or `[revised from rev N]` inline. Discarded requirements move to a `## Discarded Requirements` section with the original wording and a one-line reason — they leave their gap in the active list, but the gap is documented. + +**Re-plan phase — always full redo from `main`** +- R10. The plan derives from the freshly-forked brainstorm (or from the original brainstorm when re-brainstorm was skipped per R3). Plan units cite R-IDs from whichever brainstorm fed them. +- R11. The output plan is a **full redo from `main`**, not a delta layered on the existing PR's tree. Plan units must not reference code, IDs, files, or designs that exist only on the original PR's branch unless explicitly named in the Cherry-Pick Guidance section as targets to preserve. +- R12. The plan doc contains: a Re-Grounded Problem Frame, Requirements (referenced by R-ID, no annotation block — that lives in the forked brainstorm now), Discarded Approaches with reasoning, Cherry-Pick Guidance (files / commits / IDs / designs from the original PR worth preserving, with rationale), Supersedes (original PR + plan), New Learnings inventory, then the standard `ce-plan` body sections. + +**Discovery** +- R13. The skill discovers context inside the working repo without user help: PR (auto-detect from current branch or explicit number), original plan, original brainstorm, recent brainstorm activity in `docs/brainstorms/`, PR review threads, prior conversation. +- R14. Discovery categorizes prior plans by merge state. A plan whose commits are all reachable from `main` is treated as merged context; plans with unmerged units must be folded into the new plan's coverage so a full-redo doesn't lose in-flight work. The cora session had two prior plans where some units had landed and some hadn't — the new plan needs to know. + +**Preservation discipline** +- R15. The skill performs no Git operations: no branch creation, no cherry-picking, no force-push, no PR closure or draft-marking. It writes new files; it never modifies originals. +- R16. The handoff phase commits to `main` as the branch base for downstream `ce-work` and passes that base forward when invoking ce-work, so ce-work does not re-ask the user. The plan also names a suggested fresh branch name; the user creates the branch themselves. +- R17. When invoked without a discoverable PR, the skill writes no artifacts. It explains that `ce-replan-beta` is anchored to existing PRs and routes the user to `ce-plan` for fresh planning or `ce-brainstorm` if the work is upstream of planning. + +**Discovery-script reliability** +- R18. `scripts/fetch-pr-context.sh` surfaces missing-key conditions structurally. Use `// null` defaults or per-key probes so a missing field produces an explicit null rather than empty stdout the agent has to silently absorb. (Three jq exit-5 errors in the cora run; synthesis recovered, but a different shape of missing data could have produced wrong output.) + +**Anti-patterns made explicit** +- R19. The skill does not emit unsolicited "what is not in this plan" summaries after writing artifacts. Write the artifacts, present the handoff options, stop. (Cora session emitted one alongside a self-edit, making the transcript hard to reason about.) + +--- + +## Acceptance Examples + +- AE1. **Covers R1, R2, R4.** Given an existing PR with a discoverable original brainstorm, when the user invokes `/ce-replan-beta` interactively, the skill produces two synthesis checkpoints in sequence (re-brainstorm, then re-plan) and writes two output artifacts. +- AE2. **Covers R3.** Given a plan with no `origin:` link and no matching brainstorm, when `/ce-replan-beta` runs, the skill skips Phase 2a / 3a / 4a and writes only a new plan. +- AE3. **Covers R6, R7, R8, R9.** Given an original brainstorm with R1–R6, when the re-brainstorm phase decides to revise R3, discard R5, and add a new requirement, the forked brainstorm carries R1, R2, R3 (revised wording with `[revised from rev 1]` marker), R4, R6, R7 (new). R5 is absent from the active list and present in `## Discarded Requirements` with the original wording. Frontmatter has `supersedes: ` and `revision: 2`. +- AE4. **Covers R10, R11.** Given a PR's branch contains code at `app/foo.rb` that does not exist on `main`, when the re-plan phase runs, plan unit `Files:` and `Approach:` references treat `app/foo.rb` as something the new branch will create (potentially via cherry-pick from the original PR), not as something already in the tree. +- AE5. **Covers R5.** Given the skill is invoked from LFG (pipeline mode), when both phases run, the synthesis prompts are skipped and Inferred bets land in a `## Assumptions` section in each output artifact. +- AE6. **Covers R16.** Given the user selects "Start ce-work" from the handoff menu, when ce-work begins, it does not re-ask which branch base to use — the base is `main`, committed by the replan handoff. +- AE7. **Covers R17.** Given the user runs `/ce-replan-beta` on a branch with no PR, the skill writes no artifacts and emits a redirect message naming `ce-plan` and `ce-brainstorm`. + +--- + +## Success Criteria + +- A user can replan a long-running PR and produce both a refreshed requirements doc and a from-`main` plan in one skill invocation, without hand-stitching artifacts or re-reading PR threads. +- After several revolutions of the loop, walking the chain of `supersedes:` links lets a reader trace requirements (by R-ID) and approach decisions all the way back to v1. +- The new plan gives `ce-work` everything it needs to execute on a fresh branch — including which existing PR commits or files to cherry-pick — without asking the user about branch base or sequencing. +- The original PR remains discoverable from the new artifacts and unmodified on disk and on GitHub. Same for the original plan and original brainstorm. + +--- + +## Scope Boundaries + +- **No Git execution.** Branch creation, cherry-picking commits, force-push, PR closure or draft-marking — all out of scope. The skill writes files and stops. +- **No mutation of original artifacts.** Original brainstorm, original plan, and original PR are referenced but never edited or deleted. +- **No combined synthesis.** Re-brainstorm and re-plan checkpoints are sequential, not merged into one. The brainstorm/plan separation is what the loop relies on for clean R-ID anchoring. +- **No synthesized brainstorm for plans without one.** When there's no upstream brainstorm, the skill skips Phase 2a entirely. It does not invent a brainstorm. +- **No delta-shaped plans.** Plan units are written for the from-`main` baseline. Code on the original PR's branch must be named in Cherry-Pick Guidance to be referenced. +- **No multi-PR consolidation.** One PR in, one set of artifacts out. +- **No re-grounding-quality-gate.** The skill trusts that the user invoking it has decided replanning is appropriate. It does not push back on the decision. +- **No legacy-plan support beyond v1's R-ID format.** Original brainstorms must follow the project's R-ID convention; older brainstorms without IDs require the agent to derive implicit IDs first (documented as a fallback in the re-brainstorm workflow reference). + +### Deferred to Follow-Up Work + +- Promotion path from `ce-replan-beta` to a stable `ce-replan`: separate PR after the v2 has matured against real branches. The promotion checklist already exists at `docs/solutions/skill-design/beta-skills-framework.md`. +- LFG / `slfg` orchestration that auto-routes from `ce-brainstorm` (or from a new brainstorm doc that visibly supersedes a current PR's plan) into `ce-replan-beta` without manual invocation. + +--- + +## Key Decisions + +- **Always full redo from `main`.** No shape question. The verb "replan" maps to "redo from main" in user mental models — confirmed by the cora session. A shape question would let the failure mode resurface; defaulting to delta-shape silently is what produced the cora friction. +- **Two-phase, sequential synthesis.** Mirrors the original `ce-brainstorm` → `ce-plan` separation. The R-ID anchor at the requirements layer is what makes the compounding loop work; without it, plan-unit traceability degrades each revolution. +- **Fork the brainstorm, never mutate.** Symmetric with how the skill treats the original PR and original plan. Each forked brainstorm is dated and links back to its predecessor via `supersedes:`. After many revolutions, the chain itself is a useful artifact. +- **R-ID stability is load-bearing.** Original IDs carry across the fork; revisions keep their ID with new wording; discards leave gaps; new IDs continue from max+1. The discipline echoes how `ce-plan`'s U-IDs survive plan edits. +- **Two new artifacts, not one combined doc.** Trying to fit requirements + plan into a single output (v1's mistake) collapses WHAT and HOW into the same surface. Two docs is more output but matches the rest of the workflow's separation. +- **Skip the brainstorm phase when there's nothing to fork.** Synthesizing a brainstorm out of thin air for a plan that never had one would be inventing requirements after the fact. Better to be honest: if there was no brainstorm, the new plan has no brainstorm to derive from either. + +--- + +## Dependencies / Assumptions + +- The user's repo follows the project's `docs/brainstorms/` and `docs/plans/` conventions, including the R-ID format. Brainstorms without R-IDs are handled via a derivation fallback documented in the re-brainstorm workflow reference. +- `gh` CLI is available and authenticated for PR + thread discovery (same dependency `ce-resolve-pr-feedback` already carries). +- The user has read access to PR review threads on the relevant PR. +- The `main` branch (or repo default branch) is the canonical baseline. The skill resolves the default branch via `git symbolic-ref refs/remotes/origin/HEAD`; `main` is just shorthand throughout the docs. + +--- + +## Outstanding Questions + +### Resolve Before Planning + +None. All v1 open questions were resolved by the cora-session learnings: +- *How aggressively should the re-brainstorm interrogate original requirements?* — Walk every requirement explicitly, default to `[unchanged]`. The discipline is to never silently drop a requirement. +- *Filename convention for the forked brainstorm?* — `-rebrainstorm-requirements.md` suffix to disambiguate when two revolutions happen on the same day. Frontmatter (`supersedes:`, `revision:`) carries the lineage. +- *One synthesis or two?* — Two, sequential. WHAT and HOW are different scope levels. + +### Deferred to Planning + +- **Discovery heuristics for matching original brainstorms to PRs** — likely walk: PR-body link → original-plan's `origin:` frontmatter → recency in `docs/brainstorms/`. Resolve at script-write time once `gh` and filesystem outputs are in front of the implementer. +- **Cherry-pick guidance representation** — per-commit table, per-file inventory, or per-concern grouping. Decide based on what reads cleanly when populated against a real PR with multiple commits. +- **Whether the re-brainstorm phase reuses any of `ce-brainstorm`'s reference content** — Probably no: cross-skill `references/` traversal is banned by AGENTS.md, and re-brainstorming is shaped enough by the existing-artifacts anchor that a bespoke `references/rebrainstorm-workflow.md` is faster to load. Confirm at implementation time. +- **Whether the re-plan phase needs its own re-grounding reference** — The re-grounding logic mostly moved up to the re-brainstorm phase. The re-plan phase may not need a dedicated workflow reference at all; the `ce-plan`-style template might be sufficient. Decide once the re-plan phase is wired. diff --git a/docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md b/docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md new file mode 100644 index 000000000..9659351c1 --- /dev/null +++ b/docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md @@ -0,0 +1,220 @@ +--- +date: 2026-05-06 +topic: ce-replan-beta-skill +--- + +# `ce-replan-beta` Skill + +> **⚠ Superseded.** This document is the v1 design. Live design lives in `docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md` (`revision: 2`). Kept here as the historical snapshot that drove the v1 implementation on PR #785; the v2 Shape section below also captures the cora-session reasoning that motivated the rewrite. + +## Summary + +A new beta skill (`ce-replan-beta`) that, when an existing PR's approach has been outgrown by new learnings, runs a two-phase **re-brainstorm → re-plan** cycle and produces a fresh plan that always starts from `main`. Phase one forks the original `*-requirements.md` into a new dated requirements doc, carrying R-IDs forward stably so traceability survives across revolutions of the loop. Phase two derives a full-redo plan from the updated requirements. Original PR, plan, and brainstorm are preserved as superseded artifacts; no Git execution. Ships under the plugin's beta-skills framework so the contract can mature before promotion to a stable `ce-replan`. + +> **v2 Update (2026-05-06):** This summary reflects the post-cora-session shape. The first real run on `cora` PR #2382 surfaced that v1's delta-shaped output didn't match the user's verb — they corrected with *"no it replan so start from main no base don we redo the full plan."* v1 produced one combined plan doc with re-grounding sections. v2 splits requirements and plan into two artifacts (mirroring `ce-brainstorm` → `ce-plan`), always does a full redo from main, and forks the brainstorm so the compounding loop has a stable source of truth at the requirements layer. The v1 design below is preserved as historical context; the **v2 Shape** section captures the deltas. + +--- + +## v2 Shape — Always Full Redo + Re-Brainstorm Phase + +Source: cora session `10b929fb-c03f-4daf-b675-32c00ac44b43` (PR #2382, 2026-05-06). v1 of the skill produced a delta-shaped plan against the existing PR's tree; the user corrected with *"no it replan so start from main no base don we redo the full plan."* v2 makes "always full redo" the only shape and adds a re-brainstorm phase so the compounding loop has a stable source of truth at the requirements layer. + +### v2 Requirements (additions and revisions) + +The IDs below extend the v1 list. Where v2 supersedes a v1 requirement, the v1 ID is left in place and a `v2` note points to the replacement so traceability is preserved. + +**Two-phase flow** +- R11. The skill runs as two sequential phases: **re-brainstorm** (re-question the requirements) followed by **re-plan** (derive the implementation plan from the updated requirements). The shape mirrors the original `ce-brainstorm` → `ce-plan` handoff but is anchored to existing artifacts and learnings. +- R12. Each phase has its own synthesis checkpoint in interactive mode. They are presented sequentially, not combined — confirming requirement edits and plan units in the same breath conflates WHAT and HOW, which the brainstorm/plan separation exists to prevent. +- R13. In pipeline mode (LFG / `disable-model-invocation`), both phases run silently. Inferred bets route to a `## Assumptions` section in each artifact (the new requirements doc and the new plan doc). Neither phase blocks. + +**Re-brainstorm phase — fork, not mutate** +- R14. The re-brainstorm phase forks a new dated `docs/brainstorms/YYYY-MM-DD--requirements.md` that supersedes the original by reference. The original brainstorm is **never edited or deleted on disk**, mirroring how the skill already preserves the original plan and PR. +- R15. **R-IDs carry forward stably across the fork.** R1 in the original stays R1 in the v2 brainstorm; revised requirements keep their ID with updated wording; discarded requirements leave a gap (R3 absent is fine — gaps are how the loop stays auditable). New requirements get the next-unused R-ID, never a renumber. +- R16. The forked brainstorm's frontmatter names the original via `supersedes:` (filename or path) and includes `revision:` (e.g., `2`) so the loop's revolution count is visible. +- R17. When no original brainstorm exists for the PR (plans coming from scratch are valid), the re-brainstorm phase is skipped and the skill proceeds directly to re-plan, matching v1 behavior. The skill does not synthesize a brainstorm out of thin air for a plan that never had one. + +**Re-plan phase — always full redo (supersedes v1's R-grounding-in-plan model)** +- R18. The re-plan phase derives the new plan from the freshly-forked brainstorm (or from the original, when the re-brainstorm phase was skipped per R17). The output plan is a **full redo from `main`**, not a delta layered on the existing PR's tree. +- R19. Plan units **must not** reference code, IDs, or designs that exist only on the existing PR's branch unless explicitly identified as cherry-pick targets. The cora session failed exactly this constraint: v1's units referenced post-pivot code that did not exist on `main`, and ce-work caught the mismatch. +- R20. The Cherry-Pick Guidance section (carried from v1's R6) names what to preserve from the existing PR, but each unit's `Files:`, `Approach:`, and code references are written for the from-`main` baseline. A unit may say "create file X" when X exists on the PR's branch but not on `main` — the unit produces it from cherry-picking, the plan does not assume X is already there. + +**Discovery for full-redo** +- R21. The discovery phase categorizes prior plans by merge state. A plan whose commits are all reachable from `main` is treated as merged context; plans with unmerged units must be folded into the new plan's coverage so a full-redo doesn't lose in-flight work. The cora session had two prior plans (May 4 sidecar + May 5 collapse), and the second's units were partially landed on the PR but not on `main` — the new plan needed to acknowledge both. + +**Polish from cora session** +- R22. `scripts/fetch-pr-context.sh` surfaces missing-key conditions in its jq processing rather than emitting empty stdout that the agent silently absorbs. Use `// null` defaults or per-key probes so a missing field produces a structured note instead of a silent gap. (Three jq exit-5 errors during the cora run; synthesis recovered, but a different shape of missing data could have produced wrong output.) +- R23. The handoff phase commits to a branch base for downstream `ce-work` (always `main`, per R18) and does not present a sequencing question that ce-work then re-asks. The cora run had near-duplicate questions from both layers; the second one drew the user's correction. +- R24. The skill does not volunteer an unsolicited "what is not in this plan" summary after writing the doc. The cora run produced one and accompanied it with a self-edit ("Plan updated to reflect option 2"), making the transcript hard to reason about. Write the artifacts, present the handoff options, stop. + +**Effect on v1 requirements** +- R3 (re-derive problem frame) and R4 (synthesis checkpoint) are now scoped per-phase: each of the re-brainstorm and re-plan phases performs them, gated independently. +- R5 (single combined plan doc) is **superseded by R11/R14/R18**: v2 produces two artifacts (forked brainstorm + new plan), not one combined doc. +- R10 (no silent inheritance — every original requirement annotated) **moves up** to the re-brainstorm phase. The forked brainstorm is the surface where requirements are marked unchanged/revised/discarded, with stable R-IDs (R15). The plan doc no longer carries the per-requirement annotation block; it just references R-IDs from the forked brainstorm. + +### v2 Acceptance Examples (additions) + +- AE6. **Covers R11, R12.** Given an existing PR with a discoverable original brainstorm, when the user invokes `/ce-replan-beta`, the skill produces two synthesis checkpoints in sequence (re-brainstorm synthesis, then re-plan synthesis) and writes two output artifacts. +- AE7. **Covers R14, R15, R16.** Given an original brainstorm at `docs/brainstorms/2026-05-04-cora-v2-briefed-requirements.md` with R1–R6, when the re-brainstorm phase decides to revise R3, discard R5, and add a new requirement, the forked brainstorm at `docs/brainstorms/2026-05-06-cora-v2-briefed-requirements.md` carries R1, R2, R3 (revised wording), R4, R6, R7 (new). The gap at R5 is preserved. Frontmatter names the original via `supersedes:` and `revision: 2`. +- AE8. **Covers R17.** Given a plan with no origin brainstorm, when `/ce-replan-beta` runs, the skill skips the re-brainstorm phase and writes only a new plan doc. +- AE9. **Covers R18, R19.** Given a PR's branch contains code at `app/foo.rb` that does not exist on `main`, when the re-plan phase runs, plan unit `Files:` and `Approach:` references treat `app/foo.rb` as something the new branch will create (potentially via cherry-pick from the original PR), not as something already in the tree. +- AE10. **Covers R23.** Given the user invokes `/ce-replan-beta` and selects "Start ce-work" from the handoff menu, when ce-work begins, it does not re-ask which branch base to use — the base is `main`, committed by the replan handoff. + +### v2 Scope Boundaries (additions) + +- Mutating the original brainstorm in place is out of scope. Forking is the contract. +- Combining the re-brainstorm and re-plan synthesis checkpoints into a single confirmation is out of scope. They are sequential by design. +- Synthesizing a brand-new brainstorm for a PR that never had one is out of scope. The skill operates on existing artifacts; if there's no brainstorm, it goes straight to re-plan. +- Delta-shaped plans (units written against the existing PR's tree) are out of scope. Always full redo from `main`. +- Editing the original requirements doc is out of scope (parallel to the existing rule about original plan and PR being read-only). + +### v2 Key Decisions + +- **Always full redo, no shape question.** The verb "replan" maps to "redo from main" in user mental models. The cora session confirmed it. Adding a shape question would let the failure mode resurface; defaulting to delta-shape silently is what produced the cora friction in the first place. +- **Two-phase: re-brainstorm + re-plan, sequential synthesis.** Mirrors the original brainstorm → plan separation. The R-ID anchor at the requirements layer is what makes the compounding loop work; without it, plan-unit traceability degrades each revolution. +- **Fork the brainstorm, don't mutate.** Symmetric with how the skill treats the original PR and original plan. Preserves a trail of revolutions; each forked brainstorm is dated and links back to its predecessor. +- **R-ID stability is load-bearing.** Original IDs carry across the fork. Discards leave gaps. New IDs get the next-unused number. The discipline echoes how `ce-plan`'s U-IDs survive plan edits. + +### v2 Open Questions + +- **Filename convention for the forked brainstorm.** Most natural is the same `docs/brainstorms/YYYY-MM-DD--requirements.md` shape with today's date and the original topic; the `supersedes:` and `revision:` frontmatter handles the lineage. Alternative: encode revision in the filename (`-v2-requirements.md`). Pick when implementing — both work. +- **What if the discovery phase finds multiple original brainstorms** (e.g., the topic has been brainstormed twice)? Default: pick the one most recently linked from a plan that the existing PR derives from. Resolve at script-write time. +- **Where does the re-brainstorm workflow live?** Likely `references/rebrainstorm-workflow.md` (paralleling `regrounding-workflow.md`'s shape) — short, anchored to artifacts, with the R-ID stability rule and worked example. Decide at implementation time whether to merge or keep them as separate references. + +--- + +## Problem Frame + +Long-running PRs accumulate decisions that compound on each other. By the time real understanding emerges — through review back-and-forth, code reading, a new brainstorm, or a moment of "this could be much simpler" — the existing plan is grounded in assumptions that no longer hold. Two recovery moves are available today, and both are bad: + +- Run `ce-plan` from scratch — loses every good thing the PR has accumulated (designs, IDs, working code, migrations) and treats the original work as wasted. +- Patch the existing plan in place — silently inherits the original framing and scope assumptions, which are exactly what should have been re-questioned. + +The pain is most visible on branches that have lived through several rounds of conversation and partial implementation. The `~/cora origin/brief-view` branch is the canonical example: an original plan, conversational iteration, and emergent learnings have stacked up, and the simpler approach is now visible — but neither recovery move captures it cleanly. + +The cost shape is invisible work: re-stitching the new plan by hand, re-reading PR threads to remember which decisions still hold, and either over-preserving the existing approach (because backing it out feels expensive) or under-preserving it (because rebuilding from scratch is the only way to break free of inherited framing). + +--- + +## Actors + +- A1. **User invoking the skill**: A developer who has decided the PR's approach needs rethinking and wants a fresh plan that respects the work done so far without inheriting its assumptions. +- A2. **`ce-replan-beta` skill**: Discovers context inside the working repo (original plan, PR threads, recent brainstorms, conversation), re-grounds at the user-story tier, surfaces what it re-derived for confirmation, then writes the new plan doc. +- A3. **Downstream `ce-work`**: Consumes the new plan to drive execution against a fresh branch. Out of scope to build, but the doc must hand off cleanly. + +--- + +## Key Flows + +- F1. **Replan from current branch's PR** + - **Trigger:** User invokes `/ce-replan-beta` on a branch with an open PR after new learnings have emerged. + - **Actors:** A1, A2 + - **Steps:** + 1. Skill detects the current branch's PR (mirroring `ce-resolve-pr-feedback` discovery). + 2. Skill scans the working repo for original plan doc, PR review threads, recent brainstorm docs, and prior conversation context. + 3. Skill re-grounds at the brainstorm tier: re-walks the user story, re-questions original requirements, surfaces what it re-derived as a synthesis checkpoint. + 4. User confirms or corrects the re-grounding. + 5. Skill writes the new plan doc to `docs/plans/`, dated, with the four extra sections layered over a normal `ce-plan` body. + 6. Skill suggests a fresh branch name and points to `ce-work` for handoff. + - **Outcome:** A new dated plan doc exists in `docs/plans/`. The original plan and PR are untouched. + - **Covered by:** R1, R2, R3, R5, R7, R8 + +- F2. **Replan with explicit PR number** + - **Trigger:** User invokes `/ce-replan-beta 1234` to target a specific PR. + - **Actors:** A1, A2 + - **Steps:** Same as F1, but PR is taken from argument rather than auto-detected. + - **Outcome:** Same as F1. + - **Covered by:** R1, R2 + +- F3. **No PR found** + - **Trigger:** User invokes `/ce-replan-beta` with no argument and no PR exists for the current branch. + - **Actors:** A1, A2 + - **Steps:** + 1. Skill detects no PR. + 2. Skill explains that `ce-replan` is anchored to existing PRs and points the user to `ce-plan` for fresh planning or `ce-brainstorm` if the work is upstream of planning. + - **Outcome:** No doc is written; user is redirected. + - **Covered by:** R9 + +--- + +## Requirements + +**Invocation and inputs** +- R1. The skill is invokable as `/ce-replan-beta` with an optional PR number argument; without an argument it auto-detects the current branch's PR. The skill ships with `disable-model-invocation: true` per the plugin's beta-skills framework so it does not auto-trigger; only direct user invocation runs it. +- R2. The skill auto-discovers contextual inputs inside the working repo: original plan doc(s) in `docs/plans/`, PR review threads, recent docs in `docs/brainstorms/`, and prior conversation context. The user is not required to pass these explicitly. +- R9. When invoked without a discoverable PR, the skill does not produce a plan doc; it explains the constraint and routes the user to `ce-plan` or `ce-brainstorm`. + +**Re-grounding behavior** +- R3. The skill re-derives the problem frame and user story from scratch using PR + plan + learnings as evidence to reason against, not as authoritative framing to inherit. +- R4. When invoked interactively, the skill presents its re-derived framing (problem frame, re-questioned requirements, what changed in the user's understanding) as a synthesis checkpoint and waits for explicit user confirmation before writing the plan doc. +- R10. The skill does not silently propagate original requirements. Each requirement carried from the original plan must be either visibly re-affirmed or visibly revised in the new doc. + +**Output document** +- R5. The skill writes a single fresh plan doc to `docs/plans/`, dated, that combines re-grounded framing at the top with a normal `ce-plan` body below. +- R6. The plan doc contains four sections specific to a replan: discarded approaches with reasoning, cherry-pick guidance (designs, IDs, code, migrations worth preserving with rationale), supersedes link + diff from the original plan, and a new learnings inventory. +- R7. The plan doc names the original PR and original plan doc by reference; neither is edited or deleted. +- R8. The plan doc instructs the user to start a fresh branch from `main` and names a suggested branch name. The doc does not perform Git operations. + +--- + +## Acceptance Examples + +- AE1. **Covers R1.** Given a branch with an open PR, when the user runs `/ce-replan-beta` with no argument, the skill targets the current branch's PR. +- AE2. **Covers R3, R4, R10.** Given an original plan that asserts "we need a new database table for X", when learnings reveal an existing table can be repurposed, the re-grounding surface presents the original requirement as something to revise — not as an inherited fact — and the user explicitly confirms the revision before the doc is written. +- AE3. **Covers R6.** Given an original PR with three commits (one introducing migrations now deemed unnecessary, one introducing UI components still useful, one mixed), the cherry-pick guidance section names the UI commit as worth preserving with rationale, names the migration commit as discarded, and flags the mixed commit for surgical extraction at execution time. +- AE4. **Covers R7, R8.** Given a fresh plan doc has been written, the original plan file at `docs/plans/.md` is unchanged on disk, the original PR is untouched on GitHub, and the new doc names a fresh branch (e.g., `replan/`) for the user to create. +- AE5. **Covers R9.** Given the user runs `/ce-replan-beta` on a branch with no PR, the skill responds with a redirect to `ce-plan` or `ce-brainstorm` and writes no doc. + +--- + +## Success Criteria + +- A user can replan a long-running branch and produce a plan that respects existing work without inheriting framing assumptions, in a single skill invocation rather than several manual steps. +- The new plan doc gives `ce-work` everything it needs to execute on a fresh branch — including which existing PR commits or files to cherry-pick — without re-reading the original PR threads. +- A future reader of the new plan doc can answer two questions from the doc alone: "what are we no longer doing, and why" and "what from the original PR is still good, and why." +- The original PR remains discoverable from the new plan and unmodified on disk and on GitHub. + +--- + +## Scope Boundaries + +- No Git execution: branch creation, cherry-picking, force-push, PR closure, or draft-marking are all out of scope. The skill writes a doc and stops. +- No non-PR variant in v1. Rethinking a plan that was never PR'd stays in `ce-plan`. +- No multi-PR consolidation. One PR in, one plan out. +- No paired execution skill. Handoff to existing `ce-work` is sufficient. +- No auto-decision about whether replanning is the right move. The user invoking the skill has already decided. +- No editing of the original plan doc or PR. They are preserved as superseded artifacts by reference. + +--- + +## Key Decisions + +- **Replan is anchored to a PR, not to a plan doc**: Distinguishes the rethink-with-existing-implementation case from the rethink-with-only-a-plan case. The latter is what `ce-plan` already handles. +- **Re-grounding is the core move, not a side-effect**: The failure mode this skill exists to prevent is silent inheritance of original framing. Without forced re-grounding, the skill would degenerate into an in-place plan edit and stop being valuable. +- **Single combined output doc, not separate brainstorm + plan**: A reader needs the rethink rationale and the new plan together. Splitting them creates the lookup tax this skill is supposed to remove. +- **Original artifacts are preserved by reference, never modified**: Keeps replanning low-risk and reversible. If the replan turns out wrong, the original PR is still the source of truth. +- **Discovery mirrors `ce-resolve-pr-feedback`**: PR-anchored skills already share a discovery pattern; reusing it keeps the user's mental model consistent. +- **Ships as a beta skill (`ce-replan-beta`)**: Re-grounding behavior, discovery heuristics, and doc shape will need iteration based on real use. The beta framework prevents accidental auto-triggering (`disable-model-invocation: true`) and signals to users that the contract may change. Promotion to a stable `ce-replan` happens once the workflow has matured against real branches. + +--- + +## Dependencies / Assumptions + +- The user's repo follows this plugin's `docs/brainstorms/` and `docs/plans/` conventions, or close enough that auto-discovery has reasonable hit rates. When discovery fails, the skill should ask rather than guess. +- `gh` CLI is available and authenticated for PR + thread discovery (same dependency `ce-resolve-pr-feedback` already carries). +- The user has read access to PR review threads on the relevant PR. + +--- + +## Outstanding Questions + +### Resolve Before Planning + +- [Affects R4][User decision] How aggressively should the re-grounding interrogate original requirements vs. take them as soft anchors? Specifically: should the synthesis checkpoint always ask the user to revisit each original requirement, or only ones the agent flags as suspect based on learnings? +- [Affects R5][User decision] Filename and location convention for the new plan doc — same `docs/plans/YYYY-MM-DD-.md` shape as `ce-plan`, with a suffix (e.g., `-replan`) or marker in the topic, or no marker at all? + +### Deferred to Planning + +- [Affects R2][Technical] Auto-discovery heuristics for matching original plan docs to PRs — branch-name match, in-PR-body link, recency, or some combination. +- [Affects R6][Technical] How cherry-pick guidance is structured in the doc when the original PR has many commits — per-commit table, per-file inventory, or per-concern grouping. +- [Affects R3][Needs research] Whether the re-grounding phase reuses `ce-brainstorm` content (loaded as a reference) or specifies its own lighter facilitation pattern. Reuse is cleaner; bespoke is faster to read for the agent. diff --git a/docs/plans/2026-05-06-001-feat-ce-replan-beta-plan.md b/docs/plans/2026-05-06-001-feat-ce-replan-beta-plan.md new file mode 100644 index 000000000..50540002e --- /dev/null +++ b/docs/plans/2026-05-06-001-feat-ce-replan-beta-plan.md @@ -0,0 +1,563 @@ +--- +title: "feat: Add ce-replan-beta skill for PR-anchored replanning with re-grounding" +type: feat +status: active +date: 2026-05-06 +origin: docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md +--- + +# `ce-replan-beta` Skill + +> **⚠ Superseded.** This document is the v1 plan. Live plan lives in `docs/plans/2026-05-06-002-replan-ce-replan-beta-beta-plan.md`. Kept here as the historical snapshot of what shipped to PR #785; the v2 Implementation Adjustments section below captured the post-cora-session reasoning that motivated the rewrite. + +## Summary + +Build a new beta skill at `plugins/compound-engineering/skills/ce-replan-beta/` that, when an existing PR's approach has been outgrown by new learnings, runs a two-phase **re-brainstorm → re-plan** cycle and produces a fresh plan that always starts from `main`. Phase one forks the original `*-requirements.md` into a new dated requirements doc with R-IDs carried forward stably. Phase two derives a full-redo plan from the updated requirements. Original PR, plan, and brainstorm are preserved untouched. Ships under the plugin's beta-skills framework with `disable-model-invocation: true`. + +> **v2 Update (2026-05-06):** This summary reflects the post-cora-session shape. The v1 implementation (units U1–U6) shipped a delta-shaped single-plan-doc skill; the first real run on cora PR #2382 surfaced that the user's verb maps to "redo from main," not "delta on the PR's tree." See `docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md` § *v2 Shape* for the requirements rationale. The **v2 Implementation Adjustments** section below extends and revises U1–U6. + +--- + +## v2 Implementation Adjustments + +Source: cora session `10b929fb-c03f-4daf-b675-32c00ac44b43`, brainstorm § *v2 Shape* (R11–R24, AE6–AE10). v1 units U1–U6 are already shipped on PR #785; v2 layers new units on top and revises a few of the existing ones. U-IDs continue from `U7`; gaps are not introduced. + +### Revisions to existing units + +- **U3 (`references/regrounding-workflow.md`)** — split into per-phase guidance. The four-step pattern stays, but step 3 (re-question requirements with `[unchanged]/[revise]/[discard]`) **moves up to the re-brainstorm phase** (U7 below). What remains in U3 is the re-grounding-from-artifacts pattern that informs the re-brainstorm's synthesis. Document the load order: re-brainstorm phase reads the rebrainstorm reference (U7), re-plan phase reads the regrounding reference (U3) for any plan-tier re-derivation that doesn't belong in the requirements layer. +- **U4 (`references/doc-template.md`)** — drop the `[unchanged]/[revise]/[discard]` requirements block from the plan template. The plan now references R-IDs from the forked brainstorm; per-requirement disposition lives in the brainstorm. Cherry-Pick Guidance, Discarded Approaches, Supersedes, and New Learnings sections stay. Filename pattern unchanged. Add an explicit rule: plan units treat `main` as the baseline; code, IDs, or designs that exist only on the original PR's branch must be named in Cherry-Pick Guidance or created by a unit, never assumed present. +- **U5 (SKILL.md body)** — restructure Phase 2 into two phases: Phase 2a (re-brainstorm, loads U7) and Phase 2b (re-plan-side re-grounding, loads U3). Phase 3 (synthesis) becomes Phase 3a (re-brainstorm synthesis) and Phase 3b (re-plan synthesis); they fire **sequentially** in interactive mode, both silently in pipeline mode. Phase 4 splits: Phase 4a writes the forked brainstorm, Phase 4b writes the new plan. Phase 5 (handoff) commits to `main` as the branch base; ce-work invocation passes the base forward so ce-work doesn't re-ask. Drop any unsolicited "what is not in this plan" emission. + +### New units + +- U7. **Re-brainstorm workflow reference** + +**Goal:** Document the re-brainstorm phase pattern in `references/rebrainstorm-workflow.md`. Loaded on demand when the skill enters Phase 2a. + +**Requirements:** R11, R14, R15, R16 + +**Dependencies:** U1, U2, U3 (script outputs feed re-brainstorm phase) + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-workflow.md` + +**Approach:** +- Four steps: (1) read original brainstorm + PR threads + recent learnings + commits; (2) re-derive problem frame from user discussion language; (3) walk every original requirement and assign `[unchanged]/[revise]/[discard]` with reasoning, plus list new requirements; (4) compose a Stated/Inferred/Out three-bucket synthesis at the requirements scope (not the plan scope). +- Document the R-ID stability rule explicitly: original IDs carry through, revisions keep their ID with new wording, discards leave a gap, new IDs continue from max+1. No renumbering, ever. +- Document frontmatter contract for the forked brainstorm: `supersedes:` (path or filename) and `revision:` (integer, increments on each revolution). +- Anti-patterns: do not mutate the original brainstorm; do not re-derive WHAT and HOW in one synthesis; do not synthesize a brainstorm out of thin air when none exists upstream. +- Worked example based on the cora `brief-view` scenario: original sidecar requirements R1–R6, learnings reveal saved-view pivot, output marks R3 `[revise]` with new wording, R5 `[discard]`, adds R7 (post-collapse correctness gaps). +- Keep under 200 lines. + +**Patterns to follow:** +- Three-bucket synthesis from `plugins/compound-engineering/skills/ce-brainstorm/references/synthesis-summary.md` +- Anti-pattern callouts from `plugins/compound-engineering/skills/ce-replan-beta/references/regrounding-workflow.md` (U3, already shipped) +- Frontmatter shape from existing brainstorms in `docs/brainstorms/` + +**Test scenarios:** +- Happy path: agent reads the reference and produces a forked brainstorm with stable R-IDs against the cora scenario (manual eval via skill-creator). +- Edge case: an original brainstorm with R1, R2, R5 (gaps already exist) produces a fork that preserves the gaps and continues from R6 for new requirements. +- Edge case: when no original brainstorm exists, the agent skips Phase 2a entirely (covered by R17; verified by U5 routing). + +**Verification:** +- Reference loads via backtick path from SKILL.md without resolution errors. +- Markdown lints clean. +- Sample populated brainstorm carries R-IDs correctly across revisions. + +--- + +- U8. **Brainstorm output template reference** + +**Goal:** Document the forked-brainstorm output template in `references/brainstorm-template.md`. Loaded on demand when Phase 4a writes the doc. + +**Requirements:** R14, R15, R16 + +**Dependencies:** U1, U7 + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/references/brainstorm-template.md` + +**Approach:** +- Follows the existing `ce-brainstorm` requirements template (Summary, Problem Frame, Requirements with R-IDs, Scope Boundaries, etc.) with these v2 additions: + - Frontmatter includes `supersedes:` and `revision:`. + - Each carried-forward R-ID has a one-line marker `[unchanged from rev N]` or `[revised from rev N]` so the loop's history is visible inline. Discarded R-IDs are listed in a `## Discarded Requirements` section with the original wording and the reason — they leave a gap in the active list, but the gap is documented. + - `## New Learnings` section names the sources that drove this revision (PR thread URLs, brainstorm doc paths, conversation references). +- Filename convention: `docs/brainstorms/YYYY-MM-DD--requirements.md` with today's date. Topic stays the same as the original; `supersedes:` and `revision:` carry the lineage. +- Repo-relative paths only; no absolute paths. + +**Patterns to follow:** +- `plugins/compound-engineering/skills/ce-brainstorm/references/requirements-capture.md` for the canonical template shape. +- v1's `references/doc-template.md` (U4) for the supersedes/learnings idioms. + +**Test scenarios:** +- Happy path: a populated brainstorm template against the cora scenario produces a doc with stable R-IDs and visible lineage (manual eval). +- Edge case: original brainstorm with no R-IDs (older format) — the re-brainstorm phase derives implicit R-IDs first, then forks. Document the fallback in this reference. +- Integration: forked brainstorm passes through `ce-doc-review` cleanly (manual eval). + +**Verification:** +- Reference loads via backtick path from SKILL.md. +- Sample populated brainstorm is consumable by `ce-plan` (or `ce-replan-beta`'s Phase 2b) without re-asking the user. + +--- + +- U9. **Surface jq failures in `fetch-pr-context.sh`** + +**Goal:** Eliminate silent jq exit-5 failures in PR context fetching, so downstream synthesis sees structured signals rather than empty stdout. + +**Requirements:** R22 + +**Dependencies:** U2 + +**Files:** +- Modify: `plugins/compound-engineering/skills/ce-replan-beta/scripts/fetch-pr-context.sh` + +**Approach:** +- Audit the existing jq filter for keys that may not always be present (review threads with empty `comments.nodes`, PRs with no reviews, no commits, etc.). Three jq calls in the cora run exited with code 5; document which keys were missing and add `// null` defaults or `// empty` filters as appropriate. +- Where a key is genuinely optional, prefer `// null` so the consumer (the agent reading the JSON) sees an explicit null rather than absence. +- For required keys that genuinely shouldn't be missing on a valid PR (`pr.number`, `pr.url`), keep the strict access — a missing required key should still surface as an error, just with a clearer message. +- Do not swallow real errors. The fix is "no silent gaps," not "no errors at all." + +**Patterns to follow:** +- Existing jq idioms in `plugins/compound-engineering/skills/ce-resolve-pr-feedback/scripts/get-pr-comments`. + +**Test scenarios:** +- Happy path: against a real PR with full data, the script's output is unchanged. +- Edge case: against a PR with no review threads, the `review_threads` key in the output is `[]`, not missing. +- Edge case: against a PR with no top-level reviews, the `review_bodies` key is `[]`. +- Error path: against a PR the user lacks access to, the script exits non-zero with a clear `gh` error on stderr. + +**Verification:** +- Re-run against the cora `brief-view` PR. Confirm zero jq errors on a normal invocation. +- Sample output against a freshly-opened PR with no reviews yet; confirm structured empty arrays. + +--- + +- U10. **Handoff cleanup — commit to branch base, drop unsolicited essay** + +**Goal:** Phase 5 of the skill commits to `main` as the branch base and hands off cleanly to `ce-work` without ce-work re-asking. The unsolicited "what is not in this plan" emission from the cora run is removed. + +**Requirements:** R23, R24 + +**Dependencies:** U5 + +**Files:** +- Modify: `plugins/compound-engineering/skills/ce-replan-beta/SKILL.md` (Phase 5 section) + +**Approach:** +- Phase 5's handoff menu remains three options: Start `ce-work` / Open in Proof / Done. Wording and routing stay; the skill-invocation primitive call to `ce-work` carries the new plan path AND the branch base (`main`). +- Document explicitly: do not emit unsolicited summaries about what is excluded from the plan after writing it. The plan doc itself is the artifact; commentary belongs in chat earlier or not at all. +- Add a discipline check at the end of Phase 4b: confirm the plan doc was written with `Files:` references against `main`, not against the existing PR's branch. The check fires before the handoff menu. + +**Patterns to follow:** +- Inline post-menu routing pattern from `plugins/compound-engineering/skills/ce-plan/SKILL.md` Phase 5.4. + +**Test scenarios:** +- Happy path: invoke skill, accept synthesis, write doc, select "Start ce-work." ce-work begins with `main` as base, no branch-base question to the user. +- Edge case: select "Open in Proof" — branch base is irrelevant; doc loads in Proof for review. +- Edge case: select "Done" — skill ends cleanly; no unsolicited essay. + +**Verification:** +- Manual eval against the cora scenario via skill-creator. +- Confirm transcript has no "Plan updated to reflect option 2" or similar self-edits between menu render and user selection. + +--- + +### Sequencing + +1. U7 (re-brainstorm workflow) and U8 (brainstorm template) can land in parallel — independent references. +2. U9 (jq fix) is independent of U7/U8; can land any time. +3. U3, U4, U5 revisions land **after** U7 and U8 because U5 imports U7 and U4 references the new brainstorm template's R-ID conventions. +4. U10 (handoff cleanup) lands with U5 since both modify SKILL.md. +5. README and validation (analogous to v1's U6) updates in the same PR; no new skill name, no count change. + +### Validation strategy + +Same as v1: behavioral testing manual via skill-creator. The cora scenario serves as the canonical regression check — re-running v2 against `brief-view` should produce a forked brainstorm with stable R-IDs and a from-`main` plan whose units don't reference post-pivot code. + +--- + +## Problem Frame + +Long-running PRs accumulate decisions that compound. By the time real understanding emerges through review back-and-forth or a new brainstorm, the existing plan is grounded in assumptions that no longer hold — and the two recovery moves available today are bad: running `ce-plan` from scratch loses every good thing the PR has accumulated, and patching the existing plan in place silently inherits the original framing. Origin doc captures the pain in detail (`docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md`). + +--- + +## Requirements + +- R1. Invokable as `/ce-replan-beta` with optional PR number argument; auto-detects current branch's PR when blank. Skill ships with `disable-model-invocation: true`. +- R2. Auto-discovers contextual inputs in the working repo: original plan(s) in `docs/plans/`, PR review threads via `gh`, recent docs in `docs/brainstorms/`, and prior conversation context. +- R3. Re-derives the problem frame and user story from scratch using PR + plan + learnings as evidence, not as authoritative framing to inherit. +- R4. When invoked interactively, presents re-derived framing as a synthesis checkpoint and waits for user confirmation before writing the plan. +- R5. Writes a single fresh plan doc to `docs/plans/` using the `-beta-plan.md` suffix convention, dated and sequenced. +- R6. Plan doc contains four sections specific to a replan: discarded approaches with reasoning, cherry-pick guidance, supersedes link + diff from original plan, and new learnings inventory. +- R7. Plan doc names the original PR and original plan by reference; neither is edited or deleted on disk or on GitHub. +- R8. Plan doc instructs user to start a fresh branch from `main` and names a suggested branch name. Skill performs no Git operations. +- R9. When invoked without a discoverable PR, skill writes no plan and routes user to `ce-plan` or `ce-brainstorm`. +- R10. Skill does not silently propagate original requirements. Each requirement carried from the original plan is either visibly re-affirmed or visibly revised in the new doc. + +**Origin actors:** A1 (User invoking the skill), A2 (`ce-replan-beta` skill), A3 (Downstream `ce-work`) +**Origin flows:** F1 (Replan from current branch's PR), F2 (Replan with explicit PR number), F3 (No PR found) +**Origin acceptance examples:** AE1 (covers R1), AE2 (covers R3, R4, R10), AE3 (covers R6), AE4 (covers R7, R8), AE5 (covers R9) + +--- + +## Scope Boundaries + +- No Git execution: branch creation, cherry-picking, force-push, PR closure, draft-marking are all out of scope. +- No non-PR variant in v1. +- No multi-PR consolidation. +- No paired execution skill — handoff to existing `ce-work` is sufficient. +- No editing of original plan doc or PR — preserved by reference only. +- No automatic conversion to other agent platforms beyond what `bun run release:validate` exercises (skills auto-convert). + +### Deferred to Follow-Up Work + +- Promotion path from `ce-replan-beta` to a stable `ce-replan`: separate PR after the beta has matured against real branches. Promotion checklist already exists at `docs/solutions/skill-design/beta-skills-framework.md`. +- LFG / `slfg` integration (auto-routing into the replan flow): out of v1; beta is manual-invocation only by framework default. +- `ce-brainstorm` handoff into `ce-replan-beta` when a new brainstorm clearly supersedes an existing PR's plan: future enhancement once invocation contract is stable. + +--- + +## Context & Research + +### Relevant Code and Patterns + +- `plugins/compound-engineering/skills/ce-plan/SKILL.md` — canonical planning skill structure; `ce-replan-beta` reuses its synthesis discipline and doc template, layered with replan-specific sections. +- `plugins/compound-engineering/skills/ce-plan/references/synthesis-summary.md` — synthesis pattern that re-grounding mirrors (three-bucket scope summary, prose lead-in). +- `plugins/compound-engineering/skills/ce-plan/references/requirements-capture.md` — base plan-doc template the replan extends with four extra sections. +- `plugins/compound-engineering/skills/ce-resolve-pr-feedback/SKILL.md` and its `scripts/` directory — canonical pattern for PR-anchored skills: auto-detect PR, dispatch parallel work, gh-CLI shell scripts for read-only PR data fetching. +- `plugins/compound-engineering/skills/ce-resolve-pr-feedback/scripts/get-pr-comments` — script-first architecture for `gh`-CLI shell operations; ce-replan-beta needs a similar fetch script. +- `plugins/compound-engineering/skills/ce-polish-beta/` — reference for an existing beta skill's frontmatter shape and references/scripts split. +- `plugins/compound-engineering/skills/ce-brainstorm/SKILL.md` — re-grounding logic mirrors brainstorm-tier facilitation, but anchored to existing artifacts. The skill loads its own slimmed re-grounding workflow rather than re-using ce-brainstorm wholesale (decision rationale below). + +### Institutional Learnings + +- `docs/solutions/skill-design/beta-skills-framework.md` — load-bearing for this plan: directory naming, frontmatter shape (`-beta` suffix, `[BETA]` description prefix, `disable-model-invocation: true`), plan-file naming convention (`-beta-plan.md`), promotion path. +- `docs/solutions/skill-design/script-first-skill-architecture.md` — guidance on extracting shell-heavy logic into `scripts/` rather than inlining in SKILL.md. +- `docs/solutions/skill-design/post-menu-routing-belongs-inline-2026-04-28.md` — relevant for the skill's handoff menu (route action, don't just announce). +- `docs/solutions/skill-design/pass-paths-not-content-to-subagents-2026-03-26.md` — relevant if discovery dispatches subagents. +- The plugin's own `AGENTS.md` (`plugins/compound-engineering/AGENTS.md`) — adding-components checklist and stable/beta sync rule. + +### External References + +- None warranted — beta-skills framework, ce-plan/ce-resolve-pr-feedback patterns, and `gh` CLI usage all have multiple direct examples in this repo. + +--- + +## Key Technical Decisions + +- **Beta skill, not direct-to-stable**: Re-grounding behavior, discovery heuristics, and doc shape need real-branch iteration before the contract stabilizes. Beta framework prevents accidental auto-triggering and signals contract instability to users. +- **Re-grounding workflow lives in the skill, not as a `ce-brainstorm` import**: ce-brainstorm assumes greenfield exploration; ce-replan-beta needs to anchor to existing artifacts and explicitly *re-question* them. Importing ce-brainstorm wholesale would require the agent to reason against its facilitation rules to skip irrelevant phases. A bespoke, lighter `references/regrounding-workflow.md` is faster to read and avoids the cross-skill `references/` reference (banned by AGENTS.md "File References in Skills"). +- **Script-first for PR + plan discovery**: Shell operations (`gh pr view`, `gh api repos/.../pulls/N/comments`, glob `docs/plans/`) live in `scripts/` rather than inlined in SKILL.md. Mirrors `ce-resolve-pr-feedback`'s pattern. Keeps SKILL.md lean and lets the skill re-run discovery deterministically. +- **Plan filename uses the `-beta-plan.md` suffix from the framework**: e.g., `docs/plans/YYYY-MM-DD-NNN-feat--beta-plan.md`. Avoids collision with stable `ce-plan` outputs. +- **Synthesis checkpoint reuses the three-bucket pattern (Stated / Inferred / Out)**: Same shape as ce-plan and ce-brainstorm. The user already knows how to read it; consistency lowers cognitive load. +- **Pipeline-mode behavior mirrors ce-plan**: Skip the interactive synthesis; route Inferred bets to a `## Assumptions` section in the output doc; never block. Lets `ce-replan-beta` participate in LFG-style flows when called manually. +- **Discovery is opportunistic, not strict**: When a heuristic fails (no original plan found, branch-name doesn't match, PR has no review threads), the skill notes the gap in the synthesis and proceeds rather than blocking. Failure to discover is an information signal, not an error. + +--- + +## Open Questions + +### Resolved During Planning + +- *How aggressively the re-grounding interrogates original requirements*: All original requirements are surfaced for re-affirm-or-revise as a default. Agent flags requirements as `[suspect]` when learnings directly contradict them, but the user controls each decision. This satisfies origin's R10 (no silent inheritance) without demanding wholesale re-derivation. +- *Filename convention for the new plan doc*: Use the beta-skills framework's existing `-beta-plan.md` suffix (e.g., `2026-05-06-002-feat--beta-plan.md`). Same date-and-sequence shape as `ce-plan`. + +### Deferred to Implementation + +- Exact heuristic order for matching original plan docs to PRs (branch-name, PR-body link, recency). Resolved at script-write time once `gh` output shape is in front of the implementer. +- Cherry-pick guidance representation (per-commit table vs. per-file inventory vs. per-concern grouping). Decide based on what reads cleanly when populated against a real PR with multiple commits. +- Whether the synthesis section in the output plan doc is named `## Re-Grounded Framing` or absorbed into `## Problem Frame` + `## Requirements` like a normal plan. Decide at template-design time after writing one against the brief-view example. + +--- + +## Output Structure + + plugins/compound-engineering/skills/ce-replan-beta/ + ├── SKILL.md + ├── references/ + │ ├── regrounding-workflow.md + │ └── doc-template.md + └── scripts/ + ├── detect-pr.sh + ├── fetch-pr-context.sh + └── find-original-plan.sh + +--- + +## Implementation Units + +- U1. **Skill scaffold and frontmatter** + +**Goal:** Create the directory, SKILL.md skeleton, and frontmatter following the beta-skills framework so the skill is discoverable but model-invocation-disabled. + +**Requirements:** R1 + +**Dependencies:** None + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/SKILL.md` + +**Approach:** +- Frontmatter: `name: ce-replan-beta`, `description: "[BETA] ..."` (intended-stable description prefixed with `[BETA]` per framework), `disable-model-invocation: true`, `argument-hint: "[PR number, or blank for current branch's PR]"`. +- Description names what the skill does (replan from PR + accumulated learnings) and when to use it (PR has been outgrown). Stay under 1024 chars. +- SKILL.md body uses imperative voice, mirrors ce-resolve-pr-feedback's section structure (Mode Detection, phases), and references `references/regrounding-workflow.md` and `references/doc-template.md` via backtick paths. +- No cross-skill `../` references, no absolute paths. + +**Patterns to follow:** +- `plugins/compound-engineering/skills/ce-polish-beta/SKILL.md` for beta-skill frontmatter shape. +- `plugins/compound-engineering/skills/ce-resolve-pr-feedback/SKILL.md` for PR-anchored skill body structure. + +**Test scenarios:** +- Happy path: `tests/frontmatter.test.ts` passes after the new skill is added (description ≤1024 chars, `name` matches directory, `ce-` prefix present). +- Edge case: skill is listed by `bun run release:validate` without errors. +- Test expectation: behavioral testing of the skill itself is manual (per AGENTS.md, behavioral changes to skills evaluate via the `skill-creator` skill, not unit tests). + +**Verification:** +- Frontmatter test suite passes. +- `bun run release:validate` reports the new skill manifest without drift. +- Listing the skill via the plugin's marketplace JSON reveals it (auto-counted on validate). + +--- + +- U2. **PR and context discovery scripts** + +**Goal:** Provide deterministic shell scripts for PR detection, PR review thread fetching, and original plan discovery. Keeps SKILL.md lean and makes discovery reproducible. + +**Requirements:** R2, R9 + +**Dependencies:** U1 + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/scripts/detect-pr.sh` +- Create: `plugins/compound-engineering/skills/ce-replan-beta/scripts/fetch-pr-context.sh` +- Create: `plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-plan.sh` + +**Approach:** +- `detect-pr.sh`: Accepts an optional PR number argument. If absent, runs `gh pr view --json number,url,title,body,headRefName,baseRefName` for the current branch. If no PR is associated, exits with code `2` and a structured "no PR" sentinel — calling skill body branches to F3 (No PR found) routing. +- `fetch-pr-context.sh`: Takes a PR number. Emits a JSON-shaped bundle covering PR metadata (title, body, head ref), review threads (`gh api repos/{owner}/{repo}/pulls/{n}/comments`), top-level review summaries, and the list of commit SHAs/messages. Single-purpose, no chaining, no error suppression beyond exit-code handling. +- `find-original-plan.sh`: Takes a branch name (or PR head ref). Globs `docs/plans/*.md` and scores candidates by (a) PR body hyperlink match, (b) branch-name fragment match in filename, (c) recency. Emits the top match's path or empty if no candidate clears a confidence threshold. Empty output is not an error — synthesis surfaces it. +- All scripts begin with `#!/usr/bin/env bash`, `set -e`, and follow the `gh`-CLI usage pattern from `ce-resolve-pr-feedback/scripts/get-pr-comments`. + +**Patterns to follow:** +- `plugins/compound-engineering/skills/ce-resolve-pr-feedback/scripts/get-pr-comments` for `gh` CLI invocation, owner/repo detection, and argument parsing. + +**Test scenarios:** +- Happy path: `detect-pr.sh` on a branch with a PR returns the PR's JSON; with `--help` or invalid args, exits non-zero with usage. +- Edge case: `detect-pr.sh` on a branch with no PR exits with code 2 and an empty/structured no-PR sentinel. +- Edge case: `find-original-plan.sh` against a branch with no matching plan emits empty output and exits 0. +- Error path: `fetch-pr-context.sh` against a PR the user lacks access to returns the underlying `gh` error message verbatim — caller is responsible for handling. +- Integration scenario: shell scripts are individually invokable by hand from the skill directory (manual smoke). + +**Verification:** +- Each script is executable (`chmod +x`). +- `bash scripts/detect-pr.sh` from the plugin's skill directory works against a real branch in this repo. +- Scripts have no `&&`-chained actions, no `2>/dev/null`, and no shell traps beyond `set -e` per AGENTS.md. + +--- + +- U3. **Re-grounding workflow reference** + +**Goal:** Document the brainstorm-tier re-derivation pattern in `references/regrounding-workflow.md`. Loaded on demand when the skill enters the synthesis phase. + +**Requirements:** R3, R4, R10 + +**Dependencies:** U1 + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/references/regrounding-workflow.md` + +**Approach:** +- The reference describes a four-step re-derivation: + 1. Read PR (title, body, threads, commits) + original plan + recent brainstorms + conversation context. Pass paths, not content, when dispatching subagents (per `pass-paths-not-content-to-subagents-2026-03-26`). + 2. Re-derive problem frame from artifacts: what is the user trying to do, in their words from the discussion threads, NOT from the original plan's framing. + 3. List original requirements, mark each `[unchanged]` / `[revise]` / `[discard]` based on learnings. Default to `[unchanged]`; require explicit reasoning for revise/discard. This satisfies R10 — no silent inheritance. + 4. Compose a Stated / Inferred / Out three-bucket synthesis (mirrors ce-plan/ce-brainstorm) and present for confirmation. +- Reference includes a "what re-grounding is NOT" anti-pattern list: not a diff against the plan; not a critique of the original work; not a fresh ce-brainstorm-from-zero. The agent treats the original artifacts as evidence to interrogate, not as a starting point to extend. +- Includes one worked example based on the `~/cora origin/brief-view` scenario from the origin doc — concrete enough to anchor agent behavior, generic enough to apply elsewhere. + +**Patterns to follow:** +- Three-bucket synthesis structure from `plugins/compound-engineering/skills/ce-plan/references/synthesis-summary.md`. +- Anti-pattern callouts in the style of `plugins/compound-engineering/skills/ce-brainstorm/references/synthesis-summary.md`'s "synthesis as proposal-pitch" warning. + +**Test scenarios:** +- Happy path: The reference is < 200 lines so it loads cheaply (per AGENTS.md "Conditional and Late-Sequence Extraction" guidance — re-grounding always runs, but its content is the bulk of the skill's prose, so referencing it via backtick path is correct). +- Edge case: The agent, given the brief-view scenario, marks at least one requirement `[revise]` with an explicit learning reference (manual eval via `skill-creator`). +- Test expectation: behavioral testing manual via skill-creator. + +**Verification:** +- Reference loads via backtick path from SKILL.md without resolution errors. +- Markdown lints clean. +- Sample prose tested by reading the file fresh and confirming an agent could execute the four-step re-derivation without reading SKILL.md first. + +--- + +- U4. **Plan doc template and four extra sections** + +**Goal:** Document the output plan-doc template in `references/doc-template.md`, including the four replan-specific sections (discarded approaches, cherry-pick guidance, supersedes link + diff, learnings inventory) layered onto the standard `ce-plan` template. + +**Requirements:** R5, R6, R7, R8 + +**Dependencies:** U1 + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/references/doc-template.md` + +**Approach:** +- Reference contains a single canonical template the skill writes to disk. Sections, in order: + 1. Frontmatter (`title`, `type: replan`, `status: active`, `date`, `original_pr`, `original_plan`, `supersedes`). + 2. `## Summary` — forward-looking 1-3 line gloss of the new approach. + 3. `## Re-Grounded Problem Frame` — backward-looking; pulled from re-derivation, not inherited from original plan's framing. + 4. `## Requirements` — explicit `[unchanged]` / `[revise]` / `[discard]` annotations on each carried requirement; new requirements added below. + 5. `## Discarded Approaches` — 2-4 named approaches from the original PR with the specific learning that ruled each out. + 6. `## Cherry-Pick Guidance` — table or list of files/commits/designs/IDs/migrations from the original PR worth preserving, with rationale. + 7. `## Supersedes` — `Original PR: #N`, `Original plan: docs/plans/...`, plus a 2-3 sentence diff describing what's changed in approach. + 8. `## New Learnings` — inventory of what changed in understanding (PR threads, code reading, new brainstorm, conversation), each with a source pointer. + 9. Standard `ce-plan` body sections from there: Scope Boundaries, Context & Research, Key Technical Decisions, Implementation Units, etc. + 10. `## Suggested Branch Name` — proposes `replan/` (or similar) and instructs user to `git checkout -b ` themselves. +- Filename pattern documented: `docs/plans/YYYY-MM-DD-NNN-replan--beta-plan.md`. Per beta-skills framework `-beta-plan.md` suffix. +- Repo-relative paths only. +- Original PR and original plan referenced by relative path / PR number; the doc instructs the agent to leave them untouched. + +**Patterns to follow:** +- Plan template from `plugins/compound-engineering/skills/ce-plan/SKILL.md` Phase 4.2 Core Plan Template. +- Frontmatter shape from existing plans in `docs/plans/`. + +**Test scenarios:** +- Happy path: A populated example template fills cleanly without missing sections (manual eval). +- Edge case: When the original PR has no review threads, the New Learnings section accommodates "from local conversation only" without breaking the template. +- Edge case: When the original plan doc cannot be located, frontmatter `original_plan:` is set to `null` and the Supersedes section explains the gap. +- Integration scenario: An output doc passes through `ce-doc-review` cleanly when run against the standard plan-doc rubric (manual eval). +- Covers AE3 (cherry-pick guidance representation), AE4 (supersedes link + originals untouched), AE7/AE8 implicit through frontmatter. + +**Verification:** +- Reference loads via backtick path from SKILL.md. +- Sample populated template against the brief-view scenario produces a doc that another agent can execute against without re-asking the user. + +--- + +- U5. **SKILL.md body: phases, mode detection, handoff routing** + +**Goal:** Wire the discovery, re-grounding, and write phases into SKILL.md, including mode detection (PR # vs blank vs no-PR) and the handoff menu after writing. + +**Requirements:** R1, R2, R4, R5, R7, R8, R9 + +**Dependencies:** U2, U3, U4 + +**Files:** +- Modify: `plugins/compound-engineering/skills/ce-replan-beta/SKILL.md` + +**Approach:** +- Phase 0: Mode detection (mirror `ce-resolve-pr-feedback`'s argument table). Modes: PR number provided, blank (auto-detect), no PR (route to ce-plan/ce-brainstorm per F3 / R9). +- Phase 1: Discovery via `bash scripts/detect-pr.sh`, `bash scripts/fetch-pr-context.sh`, `bash scripts/find-original-plan.sh`. Run in parallel where independent. Pass-through outputs to the agent for synthesis. +- Phase 2: Re-grounding — read `references/regrounding-workflow.md` and execute the four-step re-derivation. +- Phase 3: Synthesis checkpoint (interactive: present three-bucket synthesis using `AskUserQuestion` per AGENTS.md cross-platform interaction rules; pipeline mode: skip prompt, route Inferred to `## Assumptions`). +- Phase 4: Write output plan doc using `references/doc-template.md` to `docs/plans/YYYY-MM-DD-NNN-replan--beta-plan.md`. +- Phase 5: Handoff menu — options to start `/ce-work` against the new plan, open in Proof, or done. Route the action inline (per `post-menu-routing-belongs-inline-2026-04-28`). +- All file paths repo-relative; no absolute paths in SKILL.md or output doc. +- Honor the platform-variable fallback rule: scripts referenced by relative path, no `${CLAUDE_PLUGIN_ROOT}`-only assumptions without graceful fallback. + +**Execution note:** Test the flow against the actual `~/cora origin/brief-view` scenario via skill-creator before declaring U5 complete — the skill's value rests on producing a sane plan against that real branch. + +**Patterns to follow:** +- Mode-detection table in `plugins/compound-engineering/skills/ce-resolve-pr-feedback/SKILL.md`. +- Handoff menu and inline-routing pattern in `plugins/compound-engineering/skills/ce-plan/SKILL.md` Phase 5.4. +- `AskUserQuestion` schema-load pattern from any ce-plan / ce-brainstorm SKILL.md. + +**Test scenarios:** +- Happy path: Invoked on a branch with a PR, the skill detects the PR, fetches threads, locates the original plan, runs re-grounding, presents synthesis, writes the doc to the correct path. (Manual eval via skill-creator + brief-view scenario.) Covers AE1, AE2, AE3, AE4. +- Edge case: Invoked on a branch with no PR, the skill emits the F3 routing message and writes no doc. Covers AE5. +- Edge case: Invoked with explicit PR number on a branch unrelated to that PR, the skill targets the explicit PR (not the current branch). +- Edge case: Original plan is not discoverable. Skill notes the gap in synthesis, frontmatter `original_plan: null`, plan still gets written with degraded supersedes section. +- Edge case: Pipeline mode invocation (e.g., from a script). Skill skips synthesis prompt, writes `## Assumptions` section in the output, exits without handoff menu. +- Error path: `gh` not authenticated. Scripts return upstream error verbatim; SKILL.md instructs agent to surface the error to the user and abort cleanly. +- Integration scenario: Output doc handed to `/ce-work` produces an actionable execution session (manual eval). + +**Verification:** +- Skill-creator eval against brief-view scenario produces a usable plan. +- Frontmatter test suite still passes. +- No regressions in `ce-plan` or `ce-resolve-pr-feedback` (both untouched per scope). + +--- + +- U6. **Marketplace, README, and cleanup-registry updates** + +**Goal:** Surface the new skill in plugin metadata, README, and cleanup registries per the plugin's adding-components checklist. + +**Requirements:** R1 (skill must be discoverable in the marketplace and listed in README) + +**Dependencies:** U1, U2, U3, U4, U5 + +**Files:** +- Modify: `plugins/compound-engineering/README.md` (Beta Skills section + skill count) +- Modify: `plugins/compound-engineering/.claude-plugin/plugin.json` (description/counts auto-computed by `release:validate` — verify, do not hand-bump version) +- Verify (no manual edit unless validate flags drift): `.claude-plugin/marketplace.json`, `.cursor-plugin/marketplace.json`, `.agents/plugins/marketplace.json` +- No edits required to `STALE_SKILL_DIRS` — skill is being added, not removed + +**Approach:** +- Add `ce-replan-beta` to the README's Beta Skills table (existing section since `ce-polish-beta` and `ce-work-beta` live there). One-line description matching the SKILL.md frontmatter description. +- Update the README's skill-count line if it mentions a number. +- Run `bun run release:validate` and `bun test`. Both must pass before the unit is verified complete. +- Per AGENTS.md "Versioning Requirements", do NOT manually bump any plugin.json `version` field — release-please owns it. +- No additions to `src/utils/legacy-cleanup.ts` or `src/data/plugin-legacy-artifacts.ts` (those track removals, not additions). + +**Patterns to follow:** +- Existing Beta Skills entries in `plugins/compound-engineering/README.md`. + +**Test scenarios:** +- Happy path: `bun run release:validate` passes after additions. +- Happy path: `bun test` passes (frontmatter, schema, conversion). +- Edge case: A converter run (e.g., `bun run convert --to opencode --from plugins/compound-engineering`) emits the new skill in target output without errors. +- Test expectation: covered by existing test suites; no new test files required. + +**Verification:** +- `bun run release:validate` reports clean (no manifest drift). +- `bun test` green. +- Skill visible in README's Beta Skills section. + +--- + +## System-Wide Impact + +- **Interaction graph:** New skill is invoked manually only (`disable-model-invocation: true`). It does not extend ce-brainstorm or ce-plan handoffs. ce-work consumes the output plan doc through the same path it consumes any plan — no ce-work changes needed. +- **Error propagation:** Discovery scripts surface `gh` errors verbatim. The skill aborts cleanly when `gh` is unauthenticated or the PR is inaccessible. No silent fallback that produces a degraded plan against missing data — better to fail loudly. +- **State lifecycle risks:** None. The skill is read-only against the working tree (writes one new file under `docs/plans/`). Original plan and PR are explicitly preserved. +- **API surface parity:** Skill ships across Claude Code, Cursor, Codex, and OpenCode via standard skill conversion. No skill-specific converter logic required — the converter copies skill directories as units. +- **Integration coverage:** A populated output plan must be consumable by `ce-work` without modification. Verified manually via skill-creator eval, not by automated test (per AGENTS.md "Validating Agent and Skill Changes"). +- **Unchanged invariants:** `ce-plan`, `ce-brainstorm`, `ce-resolve-pr-feedback`, `ce-work`, and LFG remain untouched. The beta-skills framework explicitly states orchestration is unaffected by beta additions. + +--- + +## Risks & Dependencies + +| Risk | Mitigation | +|------|------------| +| Re-grounding is verbose enough that users abandon it for a fast `/ce-plan`. | Keep `references/regrounding-workflow.md` short (< 200 lines); pipeline mode skips the prompt entirely; iteration during beta period addresses friction empirically. | +| Discovery heuristics for `find-original-plan.sh` produce wrong matches against branches with messy plan-naming history. | Synthesis surfaces the matched plan path; user can correct in the synthesis checkpoint. Pipeline mode notes the assumption in `## Assumptions`. | +| Beta-skills framework promotion path requires manual rename across many places (directory, frontmatter, references, README, cleanup registries). | Documented at `docs/solutions/skill-design/beta-skills-framework.md`; promotion is a separate PR after validation. | +| Output doc collides with stable `ce-plan` output naming. | Beta-skills framework's `-beta-plan.md` suffix prevents collision. Verified at U6 by `release:validate`. | +| `gh` CLI not authenticated in user's environment. | Scripts surface upstream `gh` error verbatim; SKILL.md instructs agent to surface and abort. Same dependency posture as `ce-resolve-pr-feedback`. | +| Behavioral changes to a skill cache at session start (per plugin AGENTS.md "Validating Agent and Skill Changes"). | Iteration uses the `skill-creator` skill, which spawns a generic subagent that reads current source from disk. Documented; not a code-level mitigation. | + +--- + +## Documentation / Operational Notes + +- README's Beta Skills section gets a new row. +- No CHANGELOG edit (release-please owns it). +- No docs/solutions entry needed — beta-skills framework already documents the pattern. +- After the skill has been used against 2-3 real branches and the doc shape has stabilized, schedule a follow-up to begin the promotion path (`ce-replan-beta` → `ce-replan`). Promotion is out of scope for this plan. + +--- + +## Sources & References + +- **Origin document:** `docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md` +- Beta-skills framework: `docs/solutions/skill-design/beta-skills-framework.md` +- Script-first architecture: `docs/solutions/skill-design/script-first-skill-architecture.md` +- Inline post-menu routing pattern: `docs/solutions/skill-design/post-menu-routing-belongs-inline-2026-04-28.md` +- Pattern reference (PR-anchored skills): `plugins/compound-engineering/skills/ce-resolve-pr-feedback/` +- Pattern reference (planning skill): `plugins/compound-engineering/skills/ce-plan/` +- Pattern reference (existing beta skill): `plugins/compound-engineering/skills/ce-polish-beta/` +- Plugin contributor instructions: `plugins/compound-engineering/AGENTS.md` +- Repo-root contributor instructions: `AGENTS.md` diff --git a/docs/plans/2026-05-06-002-replan-ce-replan-beta-beta-plan.md b/docs/plans/2026-05-06-002-replan-ce-replan-beta-beta-plan.md new file mode 100644 index 000000000..20dad5892 --- /dev/null +++ b/docs/plans/2026-05-06-002-replan-ce-replan-beta-beta-plan.md @@ -0,0 +1,511 @@ +--- +title: "feat: ce-replan-beta v2 — two-phase re-brainstorm + re-plan from main" +type: replan +status: active +date: 2026-05-06 +origin: docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md +supersedes: docs/plans/2026-05-06-001-feat-ce-replan-beta-plan.md +original_pr: 785 +--- + +# `ce-replan-beta` v2 + +## Summary + +Restructure the `ce-replan-beta` skill from v1's single-doc delta-replan into a two-phase **re-brainstorm → re-plan** flow that always produces a from-`main` plan. Phase one forks the original `*-requirements.md` into a new dated requirements doc (R-IDs carried forward stably); phase two derives a fresh plan from the forked brainstorm. Original PR (#785), original plan, and original brainstorm are preserved — the new artifacts supersede them by reference. v1's discovery scripts and frontmatter survive as cherry-picks; the SKILL.md body and reference layer are rewritten. + +--- + +## Re-Grounded Problem Frame + +v1 of `ce-replan-beta` shipped on PR #785 with a six-phase flow that produced a single combined plan doc. The intent was to mark every original requirement `[unchanged]/[revise]/[discard]` *inside the new plan* and emit cherry-pick guidance against the existing PR's tree. + +The first real run on `cora` PR #2382 (session `10b929fb-c03f-4daf-b675-32c00ac44b43`, 2026-05-06) surfaced two structural problems: + +- The plan units referenced post-pivot code that lived only on `brief-view`, not on `main`. ce-work caught the mismatch and asked the user about branch base. The user replied **"no it replan so start from main no base don we redo the full plan"** — *replan*, in their mental model, is a from-main rewrite, not a forward-delta on the PR's tree. +- The original `*-requirements.md` was left untouched. Annotating requirements *inside the plan doc* didn't refresh the requirements layer. Future planning runs would still find the stale brainstorm. + +The v2 brainstorm (`docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md`) addresses both: split the work into a re-brainstorm phase (forks the requirements doc, R-IDs carry stably) and a re-plan phase (full redo from `main`). This plan implements that shape. + +--- + +## Requirements + +This plan satisfies all requirements R1–R19 from `docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md`. Per-unit traceability appears in each implementation unit's `Requirements:` line below. The grouping below maps requirements to implementation areas: + +- **Skill identity (R1):** U1. +- **Two-phase flow (R2, R4, R5):** U6. +- **Skip-brainstorm fallback (R3):** U6. +- **Re-brainstorm phase, fork-not-mutate, R-ID stability (R6, R7, R8, R9):** U3, U4, U6. +- **Re-plan phase, full redo from `main` (R10, R11, R12):** U5, U6. +- **Discovery (R13, R14):** U2. +- **Preservation discipline (R15, R16):** U6. +- **No-PR routing (R17):** U6. +- **Discovery-script reliability (R18):** U2. +- **Anti-patterns (R19):** U6. + +**Origin actors:** A1 (User), A2 (`ce-replan-beta`), A3 (`ce-work`). +**Origin flows:** F1 (replan with brainstorm), F2 (replan without brainstorm), F3 (no PR found). +**Origin acceptance examples:** AE1–AE7. + +--- + +## Discarded Approaches + +- **Single combined plan doc (v1's shape).** Conflated WHAT and HOW into one artifact and left the original brainstorm to rot. The cora session showed this directly. Replaced by two-artifact output: forked brainstorm + new plan. +- **Per-requirement annotation block inside the plan doc (v1's R10).** The right place for `[unchanged]/[revise]/[discard]` is the requirements layer, not the plan. The plan now references R-IDs and the disposition lives in the forked brainstorm. +- **Delta-shape plan units (v1 implicit default).** Plan units written against the existing PR's tree referenced files and IDs that didn't exist on `main`, forcing ce-work to ask sequencing questions the user didn't think should exist. Replaced by the from-`main` baseline rule (R11): cherry-pick targets must be named explicitly, never assumed. +- **Optional "shape question" (proposed mid-design then rejected).** Adding "delta vs full-redo?" as an interactive question would let the v1 failure mode resurface. The verb *replan* means full-redo; the skill defaults to it without asking. +- **Mutating the original brainstorm in place.** Considered as a simpler alternative to forking. Rejected: the original is a historical snapshot; rewriting it deletes audit trail and breaks the symmetry with how the skill already preserves the original PR and original plan. +- **Combined re-brainstorm + re-plan synthesis.** Considered as a one-prompt simplification. Rejected: collapsing scope levels is what the brainstorm/plan separation exists to prevent. Sequential synthesis is the cost the loop pays for clean R-ID anchoring. +- **Unsolicited "what is not in this plan" emission after Phase 4 (v1 behavior).** The cora run produced one and accompanied it with a self-edit ("Plan updated to reflect option 2"). Removed entirely; write the artifacts, present the handoff, stop. + +--- + +## Cherry-Pick Guidance + +What to preserve from PR #785, with rationale: + +| Item | Type | Source | Why preserve | +|------|------|--------|--------------| +| `plugins/compound-engineering/skills/ce-replan-beta/SKILL.md` frontmatter | Skill frontmatter (4 lines) | PR #785 commit `9c1d439` | `name`, `[BETA]` description, `disable-model-invocation: true`, `argument-hint` are correct and follow the beta-skills framework. Body is rewritten in U6; frontmatter survives verbatim. | +| `plugins/compound-engineering/skills/ce-replan-beta/scripts/detect-pr.sh` | Script | PR #785 commit `8bba1cd` | Auto-detect / explicit PR with exit-code-2 sentinel for no-PR routing works correctly against real PRs. Cherry-pick verbatim. | +| `plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-plan.sh` | Script | PR #785 commit `8bba1cd` + autofix `3f6b835` | Branch-fragment scoring + PR-body link discovery works. The `tr` range bug was fixed via autofix on the same PR. Cherry-pick the autofixed version. | +| `plugins/compound-engineering/skills/ce-replan-beta/scripts/fetch-pr-context.sh` | Script (with fix) | PR #785 commit `8bba1cd` | Core GraphQL fetch shape is correct. Cherry-pick with the `// null` jq surfacing fix per R18 — see U2. | +| `plugins/compound-engineering/skills/ce-replan-beta/references/regrounding-workflow.md` content | Reference content | PR #785 commit `27ddf04` | The four-step pattern, anti-pattern callouts, and brief-view worked example port up into U3's new `rebrainstorm-workflow.md` at the requirements scope. Original file is deleted; content is rehomed. | +| `plugins/compound-engineering/skills/ce-replan-beta/references/doc-template.md` content | Template content | PR #785 commit `b3f0bfd` | Sections (Discarded Approaches, Cherry-Pick Guidance, Supersedes, New Learnings, Suggested Branch Name) are reusable in U5's new `replan-template.md`. The per-requirement annotation block is dropped (now in U4). | +| `plugins/compound-engineering/README.md` Beta Skills entry for `ce-replan-beta` | README row | PR #785 commit `332e46f` | Description still applies. May need light wording update to reflect two-phase shape; see U7. | + +What is **not** worth preserving from PR #785: + +- v1's SKILL.md body (rewritten in U6 — phase structure changed). +- v1's `references/regrounding-workflow.md` as a standalone file (content rehomed to U3; file is removed). +- v1's `references/doc-template.md` as a standalone file (content rehomed to U5; file is removed). + +--- + +## Supersedes + +- **Original PR:** #785 (the v1 implementation). Left open and untouched in this plan; the user decides whether to close it as superseded, force-push v2 over it, or land v1 first and follow with v2 as a separate PR. **Recommendation:** force-push v2 onto the same branch (`feat/ce-replan-beta`) so the PR's history shows the iteration. The branch is the right granularity — the skill is being shipped fresh. +- **Original plan:** `docs/plans/2026-05-06-001-feat-ce-replan-beta-plan.md`. Marked superseded; not edited. +- **Original brainstorm:** `docs/brainstorms/2026-05-06-ce-replan-skill-requirements.md`. Marked superseded; not edited. + +**Diff from the original plan.** v1 had 6 implementation units producing a single-doc skill with delta-shaped output. v2 has 7 units producing a two-phase skill with two artifacts and a from-`main` baseline. Three v1 units (U1 frontmatter, U2 scripts, U6 README) survive as cherry-picks; three (U3 regrounding, U4 doc-template, U5 SKILL.md body) are replaced by U3, U4, U5, U6 in v2. + +--- + +## New Learnings + +- **`cora` session `10b929fb-c03f-4daf-b675-32c00ac44b43`** (2026-05-06, PR #2382). The v1 skill produced a delta-shaped plan; the user's correction *"no it replan so start from main no base don we redo the full plan"* is the load-bearing source for the always-full-redo decision. +- **Slack thread with Trevin** (2026-05-06): "the trick is the plan doc references requirements by ID if it was derived from a brainstorm requirements doc." Source for R-ID stability being load-bearing — without stable IDs, plan-unit traceability degrades each revolution and the compounding loop breaks. +- **PR #785's autofix of the `tr` range bug in `find-original-plan.sh`.** The bug only mattered for branches with uppercase or digit fragments, but it surfaced from inline review of the v1 implementation and is worth carrying as a lesson: bash `tr` SETs interpret `-` between characters as a range. Always put `-` first in a SET if you want it literal. + +--- + +## Scope Boundaries + +- No Git execution at any phase. +- No mutation of the original brainstorm, original plan, or original PR. +- No combined synthesis (re-brainstorm and re-plan checkpoints stay sequential). +- No synthesized brainstorm for plans without one (Phase 2a/3a/4a are skipped per R3). +- No delta-shaped plans (units are always written for the from-`main` baseline). +- No multi-PR consolidation. +- No automatic conversion to other agent platforms beyond what `bun run release:validate` exercises. + +### Deferred to Follow-Up Work + +- Promotion path from `ce-replan-beta` to a stable `ce-replan`: separate PR after v2 has matured against real branches. +- LFG / `slfg` orchestration that auto-routes from `ce-brainstorm` (or from a new brainstorm doc that visibly supersedes a current PR's plan) into `ce-replan-beta` without manual invocation. +- Multi-PR consolidation (one replan covering several PRs being unified into one). + +--- + +## Context & Research + +### Relevant Code and Patterns + +- `plugins/compound-engineering/skills/ce-brainstorm/SKILL.md` and `references/synthesis-summary.md` — three-bucket synthesis pattern that the re-brainstorm phase mirrors. +- `plugins/compound-engineering/skills/ce-brainstorm/references/requirements-capture.md` — canonical brainstorm-doc template that U4's `rebrainstorm-template.md` extends. +- `plugins/compound-engineering/skills/ce-plan/SKILL.md` — canonical plan-doc structure that U5's `replan-template.md` extends. Especially the U-ID stability rule (carried over for R-ID stability in U4). +- `plugins/compound-engineering/skills/ce-resolve-pr-feedback/scripts/get-pr-comments` — pattern for `gh`-based PR data fetching that U2's discovery scripts already follow. +- v1 of this skill on branch `feat/ce-replan-beta` (PR #785) — primary cherry-pick source for U1 and U2. + +### Institutional Learnings + +- `docs/solutions/skill-design/beta-skills-framework.md` — directory naming, frontmatter shape, plan-file naming convention. Already followed in v1; v2 maintains conformance. +- `docs/solutions/skill-design/script-first-skill-architecture.md` — guidance on extracting shell-heavy logic into `scripts/`. v1 followed this; v2 extends with the brainstorm-finder logic. +- `docs/solutions/skill-design/post-menu-routing-belongs-inline-2026-04-28.md` — relevant for U6's handoff menu (route the action inline, don't just announce). +- `docs/solutions/skill-design/pass-paths-not-content-to-subagents-2026-03-26.md` — relevant for U6 when discovery dispatches subagents to read PR data. +- The plugin's own `AGENTS.md` — adding-components checklist, file-references rules, cross-platform interaction patterns. + +### External References + +None warranted. + +--- + +## Key Technical Decisions + +- **Cherry-pick v1's discovery scripts; rewrite the SKILL.md body.** The scripts are correct and orthogonal to the phase structure; the SKILL.md body is where v2's two-phase shape lives. Splitting the work this way minimizes churn and makes the diff between v1 and v2 readable. +- **One reference per phase**: `rebrainstorm-workflow.md` for re-brainstorm, `replan-template.md` for the new plan output. v1's `regrounding-workflow.md` is deleted — its content rehomes to the rebrainstorm reference because re-grounding is fundamentally a requirements-layer activity. +- **Force-push v2 onto branch `feat/ce-replan-beta` over PR #785.** The skill is shipping fresh; the branch is the right granularity. Force-push preserves the PR thread and reviewer context. Alternative considered: open a new PR. Rejected because it produces two open PRs implementing overlapping skills, which confuses reviewers. +- **R-ID derivation fallback for legacy brainstorms** (no R-IDs in the original) is documented in U3's reference, not enforced by U6 SKILL.md logic. Keeps SKILL.md lean; the agent reads the fallback when the situation arises. +- **Branch-base committed in handoff (R16)** is implemented as a structured argument passed to the `ce-work` skill invocation, not as an instruction to the user. The user only sees the menu options; the base is wired through the skill-invocation primitive. + +--- + +## Open Questions + +### Resolved During Planning + +- *Should v1 and v2 ship as separate PRs?* — No. Force-push v2 onto branch `feat/ce-replan-beta`. The branch is the right granularity; opening a second PR confuses reviewers. +- *Where does the re-grounding logic live in v2?* — Inside the re-brainstorm phase reference (U3), at the requirements scope. The re-plan phase doesn't need its own re-grounding workflow — it derives from a freshly-forked brainstorm and follows the standard `ce-plan`-flavored template. + +### Deferred to Implementation + +- **Discovery heuristic order** for matching original brainstorms to PRs (PR-body link → original-plan's `origin:` frontmatter → recency in `docs/brainstorms/`). Decide at U2 implementation time once the actual `gh` and filesystem outputs are visible. +- **Cherry-pick guidance representation** in the U5 template (per-commit table vs per-file inventory vs per-concern grouping). Decide based on what reads cleanly when populated against a real PR. +- **Plan-merge-state classification** (R14): probe each prior plan's commits with `git merge-base --is-ancestor` against `main`, or check the plan's frontmatter `status:` field, or both. Decide at U2 implementation time. + +--- + +## Output Structure + + plugins/compound-engineering/skills/ce-replan-beta/ + ├── SKILL.md # frontmatter cherry-picked, body rewritten (U1, U6) + ├── references/ + │ ├── rebrainstorm-workflow.md # new (U3) + │ ├── rebrainstorm-template.md # new (U4) + │ └── replan-template.md # new, replaces v1's doc-template.md (U5) + └── scripts/ + ├── detect-pr.sh # cherry-picked verbatim (U2) + ├── fetch-pr-context.sh # cherry-picked + jq surfacing fix (U2) + ├── find-original-plan.sh # cherry-picked verbatim (U2) + └── find-original-brainstorm.sh # new (U2) + +Removed from v1: `references/regrounding-workflow.md` (content rehomed to U3), `references/doc-template.md` (content rehomed to U5). + +--- + +## Implementation Units + +- U1. **Skill scaffold and frontmatter (cherry-pick + intro rewrite)** + +**Goal:** Carry v1's frontmatter forward verbatim and rewrite the SKILL.md intro paragraph to reflect the two-phase shape. + +**Requirements:** R1 + +**Dependencies:** None + +**Files:** +- Modify: `plugins/compound-engineering/skills/ce-replan-beta/SKILL.md` (frontmatter cherry-picked from v1; body rewritten in U6 — this unit just lays the scaffold) + +**Approach:** +- Frontmatter stays: `name: ce-replan-beta`, `[BETA]`-prefixed description, `disable-model-invocation: true`, `argument-hint: "[PR number, or blank for current branch's PR]"`. +- Update the description to reflect two-phase output: "...runs re-brainstorm → re-plan to produce fresh requirements + plan that always start from main..." Keep under 1024 chars. +- Intro paragraph (the prose under `# Replan from an Existing PR (Beta)`) rewritten to introduce the two phases. Detailed phase content lands in U6. +- No raw angle-bracket tokens in the description (Cowork validator rule). + +**Patterns to follow:** +- Existing v1 SKILL.md frontmatter layout. +- `plugins/compound-engineering/skills/ce-polish-beta/SKILL.md` for beta-skill frontmatter idioms. + +**Test scenarios:** +- Happy path: `tests/frontmatter.test.ts` passes (description ≤1024 chars, `name` matches directory, `ce-` prefix). +- Edge case: description doesn't contain raw `<...>` tokens. + +**Verification:** +- `bun test tests/frontmatter.test.ts` green. +- Manual eyeball: intro paragraph names both phases without prescribing implementation. + +--- + +- U2. **Discovery scripts (cherry-pick + jq fix + new brainstorm finder)** + +**Goal:** Carry v1's three discovery scripts forward, fix the silent-jq-failure issue surfaced by the cora run, and add a new script for finding the original brainstorm linked from the original plan. + +**Requirements:** R13, R14, R18 + +**Dependencies:** U1 + +**Files:** +- Cherry-pick (verbatim from PR #785): + - `plugins/compound-engineering/skills/ce-replan-beta/scripts/detect-pr.sh` + - `plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-plan.sh` +- Cherry-pick + modify: + - `plugins/compound-engineering/skills/ce-replan-beta/scripts/fetch-pr-context.sh` — add `// null` defaults to jq filters for keys that may legitimately be absent (`reviewThreads.edges`, `comments.nodes`, `reviews.nodes`, `commits.nodes`). Goal: explicit nulls in output rather than empty stdout. +- Create: + - `plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-brainstorm.sh` — given a plan path, parse its frontmatter for an `origin:` field; if present and the file exists, emit the path. If absent, fall back to scoring `docs/brainstorms/*-requirements.md` by topic-fragment match against the plan's filename topic. + +**Approach:** +- `find-original-brainstorm.sh` argument: a path to the original plan file (already discovered by `find-original-plan.sh`). Parse `origin:` from frontmatter using a small awk/sed snippet — no jq dependency. If the field is missing or the path doesn't exist, fall back to filename-fragment scoring against `docs/brainstorms/`. +- Plan-merge-state probe (R14) is implemented as inline logic in U6 SKILL.md (not a separate script): for each candidate prior plan, run `git merge-base --is-ancestor main` or check the plan's frontmatter `status:` field. Prefer status-field check first; fall back to git probe only if status is missing or unclear. + +**Patterns to follow:** +- v1's existing scripts in PR #785 for shell idioms (`set -e`, `#!/usr/bin/env bash`, owner/repo detection). +- `plugins/compound-engineering/skills/ce-resolve-pr-feedback/scripts/get-pr-comments` for jq filter shape. + +**Test scenarios:** +- Happy path: against a real PR with full data, `fetch-pr-context.sh` output is structurally identical to v1. +- Edge case: against a PR with no review threads, `review_threads` is `[]` (not missing). +- Edge case: `find-original-brainstorm.sh` against a plan with `origin:` set returns that path; against a plan without `origin:`, falls back to topic match. +- Error path: `find-original-brainstorm.sh` against a plan whose `origin:` points to a nonexistent file falls back to topic match (does not exit non-zero). + +**Verification:** +- Re-run `fetch-pr-context.sh` against the cora `brief-view` PR. Confirm zero jq exit-5 errors. +- `find-original-brainstorm.sh` against `docs/plans/2026-05-06-002-replan-ce-replan-beta-beta-plan.md` returns `docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md`. + +--- + +- U3. **Re-brainstorm workflow reference** + +**Goal:** Document the re-brainstorm phase pattern in `references/rebrainstorm-workflow.md`. Loaded on demand when the skill enters Phase 2a. + +**Requirements:** R6, R7, R9 + +**Dependencies:** U1 + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-workflow.md` +- Delete: `plugins/compound-engineering/skills/ce-replan-beta/references/regrounding-workflow.md` (content moves to this new reference) + +**Approach:** +- Four-step pattern at requirements scope: + 1. Read artifacts in order — PR threads first, original plan, original brainstorm last (so the original framing doesn't anchor the agent's thinking). + 2. Re-derive the problem frame from user discussion language. + 3. Walk every original requirement: assign `[unchanged]` / `[revised]` (with reasoning + new wording) / `[discarded]` (with reasoning, moves to `## Discarded Requirements`). + 4. Compose a Stated/Inferred/Out three-bucket synthesis at the requirements scope. +- R-ID stability rule: original IDs preserved, revisions keep ID with new wording, discards leave gaps, new IDs continue from max+1. Never renumber. +- Anti-pattern callouts (port from v1's `regrounding-workflow.md`): no diff-against-the-plan thinking, no critique-mode, no brainstorm-from-zero, no preserving the original framing's language verbatim. +- Worked example: brief-view scenario from v1, retold at the requirements layer (R3 `[revised]`, R5 `[discarded]`, new R7 added, etc.). +- Legacy fallback: if the original brainstorm has no R-IDs, derive implicit ones first (one R-ID per bullet in its Requirements section), then proceed. +- Keep under 200 lines. + +**Patterns to follow:** +- Three-bucket synthesis from `plugins/compound-engineering/skills/ce-brainstorm/references/synthesis-summary.md`. +- Anti-pattern callout format from v1's `regrounding-workflow.md`. + +**Test scenarios:** +- Happy path: agent reads the reference and produces a forked brainstorm with stable R-IDs against the cora scenario (manual eval via skill-creator). +- Edge case: original brainstorm with R1, R2, R5 (gaps already exist) — fork preserves the gaps and continues from R6 for new requirements. +- Edge case: original brainstorm with no R-IDs — agent derives implicit R-IDs first, then proceeds. + +**Verification:** +- Reference loads via backtick path from SKILL.md. +- Manual eval: agent given just this reference + the brief-view artifacts can produce a sensible forked brainstorm. + +--- + +- U4. **Re-brainstorm output template reference** + +**Goal:** Document the forked-brainstorm output template in `references/rebrainstorm-template.md`. Loaded on demand when Phase 4a writes the doc. + +**Requirements:** R6, R7, R8, R9 + +**Dependencies:** U1 + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-template.md` + +**Approach:** +- Frontmatter contract: + ``` + --- + date: YYYY-MM-DD + topic: + revision: + supersedes: + --- + ``` +- Sections in order: Summary, Re-Grounded Problem Frame, Actors, Key Flows (when relevant), Requirements (with stable R-IDs + `[unchanged from rev N]` / `[revised from rev N]` markers), Acceptance Examples, Success Criteria, Scope Boundaries, Key Decisions, Dependencies / Assumptions, Outstanding Questions, **`## Discarded Requirements`** (new section unique to forked brainstorms). +- `## Discarded Requirements` format: each entry shows the original R-ID, the original wording, and a one-line reason for discard. The R-ID is preserved here so the gap in the active list is documented, not implied. +- Filename pattern: `docs/brainstorms/YYYY-MM-DD--rebrainstorm-requirements.md` (today's date; topic matches the original or the latest fork). The `-rebrainstorm-` infix disambiguates when multiple revolutions happen on the same day. +- Repo-relative paths only. + +**Patterns to follow:** +- `plugins/compound-engineering/skills/ce-brainstorm/references/requirements-capture.md` for canonical section structure. +- v1's `references/doc-template.md` for the supersedes/learnings idioms (not the full template). + +**Test scenarios:** +- Happy path: a populated template against the cora scenario produces a doc with stable R-IDs, `## Discarded Requirements` for R5, and `revision: 2` frontmatter. +- Edge case: forked brainstorm passes through `ce-doc-review` cleanly (manual eval). +- Integration: forked brainstorm is consumable by `ce-plan` (Phase 2b in U6) without re-asking the user. + +**Verification:** +- Reference loads via backtick path from SKILL.md. +- Sample populated brainstorm has visible `[unchanged from rev N]` / `[revised from rev N]` markers on every carried-forward R-ID. + +--- + +- U5. **Re-plan output template reference** + +**Goal:** Document the new plan output template in `references/replan-template.md`, replacing v1's `doc-template.md`. + +**Requirements:** R10, R11, R12 + +**Dependencies:** U1 + +**Files:** +- Create: `plugins/compound-engineering/skills/ce-replan-beta/references/replan-template.md` +- Delete: `plugins/compound-engineering/skills/ce-replan-beta/references/doc-template.md` (content rehomed into this new reference, with the per-requirement annotation block dropped) + +**Approach:** +- Frontmatter contract: + ``` + --- + title: "" + type: replan + status: active + date: YYYY-MM-DD + origin: + supersedes: + original_pr: + --- + ``` +- Sections in order: Summary, Re-Grounded Problem Frame, Requirements (cite R-IDs from `origin:`; **no per-requirement annotation block** — that lives in the forked brainstorm), Discarded Approaches (with reasoning), Cherry-Pick Guidance (table or list of files / commits / IDs / designs from the original PR worth preserving, with rationale), Supersedes (links to original PR + plan + brainstorm), New Learnings inventory, Scope Boundaries, Context & Research, Key Technical Decisions, Implementation Units (standard `ce-plan` shape with U-IDs), Suggested Branch Name, Sources & References. +- **Always-from-`main` rule** documented prominently: plan units' `Files:`, `Approach:`, and code references must be written for the from-`main` baseline. Code that exists only on the original PR's branch must be named in Cherry-Pick Guidance to be referenced. +- Filename pattern: `docs/plans/YYYY-MM-DD-NNN-replan--beta-plan.md`. The `-beta-plan.md` suffix is mandated by the beta-skills framework. Topic is derived from the new approach. +- Repo-relative paths only. + +**Patterns to follow:** +- Plan template from `plugins/compound-engineering/skills/ce-plan/SKILL.md` Phase 4.2. +- v1's `doc-template.md` for the Discarded-Approaches / Cherry-Pick / Supersedes / New-Learnings idioms. + +**Test scenarios:** +- Happy path: populated template against the cora scenario produces a doc whose units don't reference post-pivot code that doesn't exist on `main`. +- Edge case: when `origin:` is the original brainstorm (no fork because Phase 2a was skipped per R3), R-ID references in the plan resolve against the original. +- Integration: an output plan handed to `/ce-work` produces an actionable execution session (manual eval). + +**Verification:** +- Reference loads via backtick path from SKILL.md. +- Sample plan against the brief-view scenario has zero unit references to code that doesn't exist on `main`. + +--- + +- U6. **SKILL.md body — two-phase rewrite** + +**Goal:** Rewrite SKILL.md body for the two-phase flow. The frontmatter cherry-picked in U1 is unchanged; the entire body below the frontmatter is rewritten. + +**Requirements:** R2, R3, R4, R5, R10, R11, R15, R16, R17, R19 + +**Dependencies:** U2, U3, U4, U5 + +**Files:** +- Modify: `plugins/compound-engineering/skills/ce-replan-beta/SKILL.md` (body) + +**Approach:** +- Phase 0 — Mode detection (PR# / blank / no-PR routing). Same shape as v1; surface `` and route. Per R17, no-PR exits cleanly with a redirect message. +- Phase 1 — Discovery via the four scripts (detect-pr, fetch-pr-context, find-original-plan, find-original-brainstorm) plus the inline plan-merge-state probe. When no original brainstorm is found, branch the flow to skip Phases 2a/3a/4a per R3. +- Phase 2a — Re-brainstorm: load `references/rebrainstorm-workflow.md`. Run the four-step pattern. Output: a synthesis at the requirements scope. +- Phase 3a — Re-brainstorm synthesis checkpoint: present synthesis as prose. Wait for confirmation in interactive mode; skip prompt in pipeline mode and route Inferred bets to `## Assumptions` in the forked brainstorm. **Do not present a menu** — option sets bias the answer. +- Phase 4a — Write forked brainstorm: load `references/rebrainstorm-template.md`. Compose and write to `docs/brainstorms/YYYY-MM-DD--rebrainstorm-requirements.md`. Discipline check before write: every original R-ID is annotated or moved to `## Discarded Requirements`; no silent drops. +- Phase 2b — Re-plan: derive the new plan from the forked brainstorm (or from the original brainstorm when Phase 2a was skipped, or from the original plan when neither brainstorm exists per R3). Cite R-IDs from `origin:`. +- Phase 3b — Re-plan synthesis checkpoint: present synthesis. Same interactive-vs-pipeline behavior as Phase 3a. +- Phase 4b — Write plan: load `references/replan-template.md`. Compose and write to `docs/plans/YYYY-MM-DD-NNN-replan--beta-plan.md`. Discipline check before write per R11: plan units' `Files:` and `Approach:` references treat `main` as baseline; any reference to original-PR-only code is named in Cherry-Pick Guidance. +- Phase 5 — Handoff: + - Three options via `AskUserQuestion`: Start `ce-work` against the new plan / Open in Proof / Done. + - Option 1 dispatches `ce-work` via the platform skill-invocation primitive, passing both the plan path **and** the branch base (`main`) so ce-work doesn't re-ask (R16). + - **No unsolicited "what is not in this plan" emission** (R19). Write the artifacts, present the menu, route the choice. Stop. +- Cross-platform interaction: name `AskUserQuestion` (Claude Code) plus `request_user_input`/`ask_user`/`ask_user` for Codex/Gemini/Pi at every blocking question site. +- All file paths repo-relative. + +**Patterns to follow:** +- v1 SKILL.md from PR #785 for mode-detection and discovery-dispatch shape (carries forward where unchanged). +- `plugins/compound-engineering/skills/ce-plan/SKILL.md` Phase 5.4 for inline post-menu routing. +- `plugins/compound-engineering/skills/ce-resolve-pr-feedback/SKILL.md` for the PR-anchored skill body structure. + +**Execution note:** Test the full flow against the actual `~/cora origin/brief-view` scenario via skill-creator before declaring U6 complete. The skill's value rests on producing both a sensible forked brainstorm and a from-`main` plan against that real branch. + +**Test scenarios:** +- Happy path: invoked on a PR with discoverable original plan + brainstorm, the skill produces two artifacts and dispatches ce-work with the plan path + branch base. Covers AE1, AE6. +- Edge case: original brainstorm not discoverable — Phase 2a/3a/4a skipped, only the plan is written. Covers AE2. +- Edge case: re-brainstorm produces R3 `[revised]`, R5 `[discarded]`, new R7. Forked brainstorm has the markers, gap, and frontmatter `revision: 2`. Covers AE3. +- Edge case: original PR's branch contains code at a path that doesn't exist on `main`. Plan unit references treat that path as a cherry-pick target, not as already-present. Covers AE4. +- Edge case: pipeline-mode invocation (LFG). Synthesis prompts skipped, Inferred bets in `## Assumptions` in each artifact. Covers AE5. +- Edge case: no PR found. No artifacts written; user redirected. Covers AE7. +- Error path: `gh` not authenticated — scripts surface the error verbatim; SKILL.md instructs the agent to surface and abort. + +**Verification:** +- skill-creator eval against the brief-view scenario produces a usable forked brainstorm + plan. +- Frontmatter test suite still passes. +- No regressions in `ce-plan` or `ce-resolve-pr-feedback` (both untouched). +- Transcript of a real run does not contain unsolicited "what is not in this plan" emissions or self-edit lines. + +--- + +- U7. **README + validation** + +**Goal:** Surface the v2 shape in the plugin README (light wording update) and confirm the plugin still validates cleanly. + +**Requirements:** R1 (skill discoverability) + +**Dependencies:** U1, U2, U3, U4, U5, U6 + +**Files:** +- Modify: `plugins/compound-engineering/README.md` (Beta Skills row for `ce-replan-beta` — wording reflects two-phase output) + +**Approach:** +- Update the Beta Skills row's description: "Replan from an existing PR — re-brainstorm + re-plan from main, with R-IDs carried forward stably across the loop." +- Run `bun run release:validate` and `bun test`. Both must pass. +- Per AGENTS.md, do not manually bump any plugin.json `version` field — release-please owns it. +- No additions to `STALE_SKILL_DIRS` (skill is not being removed, just iterated). + +**Patterns to follow:** +- Existing Beta Skills entries in `plugins/compound-engineering/README.md`. + +**Test scenarios:** +- Happy path: `bun run release:validate` passes after wording update. +- Happy path: `bun test` passes. +- Edge case: a converter run emits the updated skill in target output. + +**Verification:** +- `bun run release:validate` clean. +- `bun test` green. +- README's Beta Skills section accurately describes two-phase shape. + +--- + +## System-Wide Impact + +- **Interaction graph:** Skill is invoked manually only (`disable-model-invocation: true`). It does not extend `ce-brainstorm` or `ce-plan` handoffs. `ce-work` consumes the new plan via the same path it consumes any plan; ce-work also receives the branch base argument, which is a new contract for the ce-work invocation site. +- **Error propagation:** Discovery scripts surface `gh` errors verbatim; the skill aborts cleanly when `gh` is unauthenticated or the PR is inaccessible. `fetch-pr-context.sh`'s jq surfacing means missing-key conditions produce structured nulls instead of silent gaps (R18). +- **State lifecycle risks:** None. The skill is read-only against the working tree; it writes two new files (forked brainstorm + new plan) and stops. Original artifacts are explicitly preserved. +- **API surface parity:** Skill ships across Claude Code, Cursor, Codex, and OpenCode via standard skill conversion. No skill-specific converter logic required. +- **Integration coverage:** Forked brainstorm must be consumable by `ce-plan`. Plan must be consumable by `ce-work` with the new branch-base argument. Verified manually via skill-creator (per AGENTS.md "Validating Agent and Skill Changes"). +- **Unchanged invariants:** `ce-plan`, `ce-brainstorm`, `ce-resolve-pr-feedback`, `ce-work`, and LFG remain unchanged. The branch-base argument to ce-work is additive — ce-work continues to work without it. + +--- + +## Risks & Dependencies + +| Risk | Mitigation | +|------|------------| +| Two synthesis checkpoints feel like two prompts to confirm. Users abandon the flow midway. | Pipeline mode skips both prompts. In interactive mode, each synthesis is short and scoped to its own layer. The cora session showed users accept synthesis confirmations quickly when the synthesis is sound; the friction was structural (wrong shape), not cognitive (too many prompts). | +| Forked brainstorm filename collisions when two revolutions happen on the same day. | The `-rebrainstorm-` infix disambiguates. Frontmatter `supersedes:` and `revision:` carry the lineage independently. Future revisions can extend with `-rebrainstorm-rev3-` if needed. | +| Plan-merge-state classification (R14) is brittle if neither `status:` frontmatter nor merge-base probing produces clear answers. | The agent surfaces uncertainty in the synthesis ("two prior plans found; could not determine merge state for plan X"). Pipeline mode notes the assumption in `## Assumptions`. The classification is best-effort, not blocking. | +| Force-push v2 onto branch `feat/ce-replan-beta` over PR #785 loses v1's commit history. | The git log preserves v1's commits in reflog and on the branch's existing commits before force-push. The PR history of comments/reviews is preserved on the GitHub side. Reviewers can read the v1-then-v2 transition through the commit list and PR description. | +| Original brainstorm has no R-IDs (older format) — re-brainstorm phase has nothing to anchor on. | Documented fallback in U3: derive implicit R-IDs from the Requirements section's bullets, then proceed. Surface the derivation in the synthesis so the user can correct any misreading. | +| Behavioral changes to the skill cache at session start. | Iteration uses the `skill-creator` skill, which spawns a generic subagent that reads current source from disk. Documented in plugin AGENTS.md. | + +--- + +## Documentation / Operational Notes + +- README's Beta Skills row gets a wording update. +- No CHANGELOG edit (release-please owns it). +- No `docs/solutions/` entry needed beyond the existing beta-skills framework doc. +- After v2 has been used against 2-3 real branches and the doc shapes have stabilized, schedule a follow-up to begin the promotion path (`ce-replan-beta` → `ce-replan`). + +--- + +## Sources & References + +- **Origin requirements:** `docs/brainstorms/2026-05-06-ce-replan-skill-rebrainstorm-requirements.md` +- **Superseded plan:** `docs/plans/2026-05-06-001-feat-ce-replan-beta-plan.md` +- **Original PR:** #785 (`feat/ce-replan-beta` branch) +- **Cora session driving the rewrite:** `~/.claude/projects/-Users-kieranklaassen-cora/10b929fb-c03f-4daf-b675-32c00ac44b43.jsonl` +- **Beta-skills framework:** `docs/solutions/skill-design/beta-skills-framework.md` +- **Pattern reference (PR-anchored skills):** `plugins/compound-engineering/skills/ce-resolve-pr-feedback/` +- **Pattern reference (planning skill):** `plugins/compound-engineering/skills/ce-plan/` +- **Pattern reference (existing beta skill):** `plugins/compound-engineering/skills/ce-polish-beta/` +- **Plugin contributor instructions:** `plugins/compound-engineering/AGENTS.md` diff --git a/plugins/compound-engineering/README.md b/plugins/compound-engineering/README.md index 666052139..1a7df99f0 100644 --- a/plugins/compound-engineering/README.md +++ b/plugins/compound-engineering/README.md @@ -97,6 +97,7 @@ For `/ce-optimize`, see [`skills/ce-optimize/README.md`](./skills/ce-optimize/RE | Skill | Description | |-------|-------------| | `ce-polish-beta` | Human-in-the-loop polish phase after /ce-code-review — verifies review + CI, starts a dev server from `.claude/launch.json`, generates a testable checklist, and dispatches polish sub-agents for fixes. Emits stacked-PR seeds for oversized work | +| `ce-replan-beta` | Replan from an existing PR after new learnings — runs a two-phase re-brainstorm + re-plan flow, forking the original requirements doc with R-IDs carried forward stably and producing a fresh full-redo plan from main. Original PR, plan, and brainstorm preserved as superseded artifacts | | `/lfg` | Full autonomous engineering workflow | ## Agents diff --git a/plugins/compound-engineering/skills/ce-demo-reel/references/tier-browser-reel.md b/plugins/compound-engineering/skills/ce-demo-reel/references/tier-browser-reel.md index 6b7b65a7b..acab70a73 100644 --- a/plugins/compound-engineering/skills/ce-demo-reel/references/tier-browser-reel.md +++ b/plugins/compound-engineering/skills/ce-demo-reel/references/tier-browser-reel.md @@ -18,7 +18,10 @@ If `agent-browser` is not installed, inform the user: "`agent-browser` is not in - Check `Gemfile` for Rails (`bin/rails server`) or Sinatra - Check for running processes on common ports (3000, 5000, 8080) -If the server is not running, tell the user what start command was detected and ask them to start it. Do not start it automatically (it may require environment variables, database setup, etc.). +If the server is not running: + +- **Headless / background mode** (no blocking question tool available): try starting the server automatically using the detected start command in a background process. For Rails apps, run `bin/dev` or `bin/rails server` in the background. Poll until port 3000 (or the detected port) is accepting connections (max 30s). If it doesn't come up, fall back to static screenshots tier. Track the server PID so you can stop it in Step 4 cleanup. +- **Interactive mode**: tell the user what start command was detected and ask them to start it. Do not start it automatically (it may require environment variables, database setup, etc.). If the server cannot be reached after the user confirms it should be running, fall back to static screenshots tier. @@ -115,6 +118,6 @@ python3 scripts/capture-demo.py stitch --duration 2.0 [RUN_DIR]/demo.gif [RUN_DI Before uploading, inspect the final GIF for any credential material visible on-screen. If any appears, discard the GIF and recapture with the offending page or state routed out of frame. Do not upload, do not blur. -After a clean GIF is confirmed, remove individual PNG frames. Keep only the final GIF for upload. +After a clean GIF is confirmed, remove individual PNG frames. Keep only the final GIF for upload. If you auto-started the dev server in Step 1 (headless mode), stop it now using the tracked PID. Proceed to `references/upload-and-approval.md`. diff --git a/plugins/compound-engineering/skills/ce-demo-reel/references/upload-and-approval.md b/plugins/compound-engineering/skills/ce-demo-reel/references/upload-and-approval.md index 44b883628..9243d2533 100644 --- a/plugins/compound-engineering/skills/ce-demo-reel/references/upload-and-approval.md +++ b/plugins/compound-engineering/skills/ce-demo-reel/references/upload-and-approval.md @@ -2,6 +2,13 @@ Upload a temporary preview for the user to review, then either promote to permanent hosting or save locally based on user choice. +## Headless / Background Mode + +If no blocking question tool is available (Codex running autonomously, background agent, or any mode where there is no synchronous user), skip Steps 1–2 and go straight to headless upload: + +1. **R2 available** (`R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET`, `R2_ENDPOINT`, `R2_PUBLIC_URL` all set): upload to R2 and use the public URL. Proceed to Step 3-R2. +2. **R2 not available**: upload directly to catbox permanent hosting without a preview step. Proceed to Step 3. + ## Step 1: Preview Upload (Temporary) Upload the evidence file (GIF or PNG) to litterbox for a temporary 1-hour preview: @@ -23,16 +30,21 @@ Present the preview URL to the user and ask how to handle the evidence. Use the **Question:** "Evidence preview (1h link): [PREVIEW_URL]. Where should the evidence go?" **Options:** -1. **Upload to catbox (public URL)** -- promote to permanent hosting for PR embedding -2. **Save locally** -- save to a stable OS-temp path (/tmp/compound-engineering/ce-demo-reel/) -3. **Recapture** -- provide instructions on what to change -4. **Proceed without evidence** -- set evidence to null and proceed +1. **Upload to R2 (public URL)** -- upload to Cloudflare R2 for permanent PR embedding (available when R2 env vars are set) +2. **Upload to catbox (public URL)** -- promote to catbox permanent hosting for PR embedding +3. **Save locally** -- save to a stable OS-temp path (/tmp/compound-engineering/ce-demo-reel/) +4. **Recapture** -- provide instructions on what to change +5. **Proceed without evidence** -- set evidence to null and proceed + +Omit option 1 if R2 env vars (`R2_ACCESS_KEY_ID`, `R2_BUCKET`, `R2_ENDPOINT`, `R2_PUBLIC_URL`) are not set. -If the question tool is unavailable (headless/background mode), present the numbered options and wait for the user's reply before proceeding. +### On "Upload to R2 (public URL)" + +Proceed to Step 3-R2: R2 Upload. ### On "Upload to catbox (public URL)" -Proceed to Step 3: Promote to Permanent Hosting. +Proceed to Step 3: Promote to Permanent Hosting (catbox). ### On "Save locally" @@ -46,7 +58,7 @@ Return to the tier execution step. The user's instructions guide what to change Set evidence to null and proceed. The preview link expires on its own. -## Step 3: Promote to Permanent Hosting +## Step 3: Promote to Permanent Hosting (catbox) After the user selects "Upload to catbox", upload to permanent catbox hosting. The command accepts either the preview URL (preferred) or the local file path (fallback): @@ -60,6 +72,27 @@ The last line of output is the permanent URL (e.g., `https://files.catbox.moe/ab For multiple files, promote each separately. +## Step 3-R2: R2 Upload + +Upload the artifact to Cloudflare R2 using the AWS CLI: + +```bash +KEY="ce-demo-reel/$(date +%Y%m%d-%H%M%S)-$(basename [ARTIFACT_PATH])" +AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY_ID" \ +AWS_SECRET_ACCESS_KEY="$R2_SECRET_ACCESS_KEY" \ +aws s3 cp [ARTIFACT_PATH] "s3://$R2_BUCKET/$KEY" \ + --endpoint-url "https://$R2_ENDPOINT" \ + --content-type "image/gif" +``` + +Adjust `--content-type` to `image/png` for static screenshots. + +The permanent public URL is: `$R2_PUBLIC_URL/$KEY` + +**If upload fails** (aws CLI not available, credentials invalid), fall back to catbox (Step 3) and note the fallback reason. + +For multiple files, upload each separately with a unique key. + ## Step 3b: Local Save After the user selects "Save locally", save the artifact to the default OS-temp path using the pipeline script: @@ -78,7 +111,7 @@ For multiple files (static screenshots tier), save each file separately. ## Step 4: Return Output -Return the structured output defined in the SKILL.md Output section: `Tier`, `Description`, and either `URL` (permanent catbox URL) or `Path` (local file path). The caller formats the evidence into the PR description. ce-demo-reel does not generate markdown. +Return the structured output defined in the SKILL.md Output section: `Tier`, `Description`, and either `URL` (permanent public URL) or `Path` (local file path). The caller formats the evidence into the PR description. ce-demo-reel does not generate markdown. ## Step 5: Cleanup diff --git a/plugins/compound-engineering/skills/ce-replan-beta/SKILL.md b/plugins/compound-engineering/skills/ce-replan-beta/SKILL.md new file mode 100644 index 000000000..cc309a5c2 --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/SKILL.md @@ -0,0 +1,177 @@ +--- +name: ce-replan-beta +description: "[BETA] Replan from an existing PR after new learnings have emerged. Runs as a two-phase re-brainstorm + re-plan flow: phase one forks the original requirements doc with R-IDs carried forward stably; phase two derives a fresh full-redo plan that always starts from main. Original PR, plan, and brainstorm are preserved as superseded artifacts; no Git execution. Use when a PR's approach has been outgrown by review back-and-forth, code reading, or a new brainstorm. Invoke with /ce-replan-beta [PR number, or blank for current branch's PR]." +disable-model-invocation: true +argument-hint: "[PR number, or blank for current branch's PR]" +allowed-tools: Bash(bash *detect-pr.sh), Bash(bash *fetch-pr-context.sh), Bash(bash *find-original-plan.sh), Bash(bash *find-original-brainstorm.sh) +--- + +# Replan from an Existing PR (Beta) + +`ce-brainstorm` defines **WHAT** to build. `ce-plan` defines **HOW** to build it. `ce-work` executes. `ce-replan-beta` is for the moment when an existing PR's approach has been outgrown by new learnings — review back-and-forth, code reading, a new brainstorm, or a "this could be much simpler" realization — and the original requirements and plan are grounded in assumptions that no longer hold. + +The skill runs as two sequential phases. **Phase one (re-brainstorm)** re-questions the original requirements with the new learnings folded in; it forks the original `*-requirements.md` into a new dated revision with R-IDs carried forward stably. **Phase two (re-plan)** derives a fresh plan from the forked brainstorm — always a full redo from `main`, never a delta layered on the existing PR's tree. + +The skill performs no Git operations. The original PR, original plan, and original brainstorm remain untouched on disk and on GitHub; the new artifacts supersede them by reference. The user starts a fresh branch from `main` themselves. + +## Interaction Method + +When asking the user a question, use the platform's blocking question tool: `AskUserQuestion` in Claude Code (call `ToolSearch` with `select:AskUserQuestion` first if its schema isn't loaded), `request_user_input` in Codex, `ask_user` in Gemini, `ask_user` in Pi (requires the `pi-ask-user` extension). Fall back to numbered options in chat only when no blocking tool exists in the harness or the call errors. Never silently skip the question. + +Synthesis checkpoints are presented as **prose**, not menus — option sets bias the answer at the synthesis layer. + +## Pipeline Mode + +When invoked from an automated workflow such as LFG or any `disable-model-invocation` context, run non-interactively: skip both synthesis prompts (Phase 3a and Phase 3b) and skip the handoff menu (Phase 5). Inferred bets route to a `## Assumptions` section in each artifact (the forked brainstorm and the new plan) so downstream review can scrutinize them. + +## Phase 0 — Mode detection + +Read `` to determine the mode: + +| Argument | Mode | Action | +|----------|------|--------| +| Blank | **Auto-detect** | Continue to Phase 1; PR is the current branch's PR | +| PR number (e.g., `1234`) | **Explicit** | Continue to Phase 1; PR is the explicit number | + +If the user provided something that is not a PR number and not blank (URL, branch name, path), surface the input and ask which PR they meant before continuing. + +## Phase 1 — Discovery + +Run the discovery scripts and probe prior plans for merge state. Use the platform's parallel execution where independent calls are supported. + +### 1.1 PR detection + +```bash +bash "${CLAUDE_SKILL_DIR}/scripts/detect-pr.sh" "$PR_NUMBER" +``` + +- Argument is the explicit PR number, or empty for auto-detect. +- Exit code `0` with JSON on stdout: PR found. Capture the PR's `number`, `url`, `title`, `body`, and `headRefName` (branch). +- Exit code `2`: no PR found for current branch. **Route to no-PR redirect**: write nothing, tell the user `ce-replan-beta` is anchored to existing PRs, and point them to `ce-plan` (fresh planning) or `ce-brainstorm` (work upstream of planning). End the skill. +- Exit code `1`: gh CLI error. Surface the error verbatim and end the skill — do not produce degraded artifacts against missing data. + +### 1.2 PR context fetch + +```bash +bash "${CLAUDE_SKILL_DIR}/scripts/fetch-pr-context.sh" "$PR_NUMBER" +``` + +- Returns a JSON bundle with PR metadata, review threads, review bodies, top-level comments, and commits. Missing keys produce explicit empty arrays / nulls (no silent gaps). +- Save the output to a temporary file via `mktemp -d -t ce-replan-XXXXXX` and pass the **path** (not the content) to subagents during re-brainstorming. + +### 1.3 Original plan discovery + +Write the PR body from 1.1 to a temp file, then: + +```bash +bash "${CLAUDE_SKILL_DIR}/scripts/find-original-plan.sh" "$HEAD_REF" "$PR_BODY_FILE" +``` + +- Empty stdout means no candidate cleared the heuristic. Continue without an original plan; surface the gap in the synthesis (the forked brainstorm and new plan can still be produced — the skill explains the absence). +- Non-empty stdout: a repo-relative path. Read the candidate plan doc. + +### 1.4 Original brainstorm discovery + +If 1.3 returned a plan path: + +```bash +bash "${CLAUDE_SKILL_DIR}/scripts/find-original-brainstorm.sh" "$ORIGINAL_PLAN_PATH" +``` + +- Prefers the plan's `origin:` frontmatter; falls back to topic-fragment scoring against `docs/brainstorms/`. +- Empty stdout means no upstream brainstorm — Phase 2a/3a/4a are **skipped** (per R3 / R17 in the brainstorm). The re-plan phase runs against the original plan + PR + learnings; no fork is produced. +- Non-empty stdout: a repo-relative path to the brainstorm. Read it. + +### 1.5 Recent brainstorm scan + +Use the native file-search tool (e.g., `Glob` in Claude Code) to list `docs/brainstorms/*-requirements.md` files modified in the last 30 days. Read any whose topic plausibly matches the PR's. Brainstorms that postdate the original are often *the* new learning. + +### 1.6 Plan-merge-state probe + +For each prior plan discovered (the original found in 1.3, plus any sibling plans in `docs/plans/` that share the topic), categorize merge state: + +1. Read the plan's frontmatter `status:` field. `status: completed` indicates merged work. +2. When status is `active` or absent, probe the commits the plan references via `git merge-base --is-ancestor main` for each `` named in the plan's body or in PR commits that landed before the plan was opened. The classification is best-effort. + +Carry the categorization forward into the re-brainstorm and re-plan synthesis. **Plans with unmerged units must be folded into the new plan's coverage** so the full-redo doesn't lose in-flight work. + +## Phase 2a — Re-brainstorm + +**Skip this phase when 1.4 found no original brainstorm.** Continue directly to Phase 2b. + +Read `references/rebrainstorm-workflow.md` for the four-step pattern, R-ID stability rule, anti-patterns, and worked example. Execute the four steps against the artifacts gathered in Phase 1: + +1. Read artifacts in order — PR threads first, original brainstorm last. +2. Re-derive the problem frame from user discussion language. +3. Walk every original requirement assigning `[unchanged]` / `[revised]` / `[discarded]` with reasoning. R-IDs carry stably; gaps preserved. +4. Compose a Stated / Inferred / Out three-bucket synthesis at the **requirements scope** (not the plan scope). + +## Phase 3a — Re-brainstorm synthesis checkpoint + +Present the Phase 2a synthesis as prose. Wait for confirmation, revision, or redirect before writing the forked brainstorm. + +If the user revises, integrate the change and re-present the revised synthesis. Phase 4a fires only on explicit confirmation. + +**Pipeline mode:** skip this phase entirely. Inferred bets route to a `## Assumptions` section in the forked brainstorm written in Phase 4a. + +## Phase 4a — Write forked brainstorm + +**Skip this phase when 1.4 found no original brainstorm** (matching the Phase 2a skip). + +Read `references/rebrainstorm-template.md` for filename conventions, frontmatter contract, section order, and discipline checks. Then: + +1. Determine the output filename: `docs/brainstorms/YYYY-MM-DD--rebrainstorm-requirements.md`. Today's date; topic matches the original brainstorm's. +2. Compose the doc per the template — frontmatter (`supersedes:`, `revision:`), Summary, Re-Grounded Problem Frame, Actors / Flows / Acceptance Examples (when applicable, with disposition markers), Requirements (with `[unchanged from rev N]` / `[revised from rev N]` markers, gaps where requirements were discarded), `## Discarded Requirements` (for each discarded item, with original wording and reason), Success Criteria, Scope Boundaries, Key Decisions, Dependencies / Assumptions, Outstanding Questions. +3. Run the discipline checks listed at the end of `references/rebrainstorm-template.md` before writing — every original R-ID accounted for, no silent drops, frontmatter `supersedes:` resolves on disk, repo-relative paths only. +4. Use the Write tool to save the file. +5. Confirm the path back to the user (absolute path so the reference is clickable in modern terminals). + +The original brainstorm is **never** edited or deleted. + +## Phase 2b — Re-plan + +Derive the new plan from the forked brainstorm produced in Phase 4a (or, when Phase 2a was skipped, from the original brainstorm or directly from the original plan + PR + learnings). + +Plan units cite **R-IDs from `origin:`** (the doc that fed this phase). The plan does not carry per-requirement disposition markers — those live in the forked brainstorm. + +**Always-from-`main` baseline** (load-bearing): plan units' `Files:`, `Approach:`, and `Test scenarios:` are written for the `main` baseline. Code, IDs, files, or designs that exist only on the original PR's branch must be named in `## Cherry-Pick Guidance` and referenced from units explicitly. + +## Phase 3b — Re-plan synthesis checkpoint + +Present the Phase 2b synthesis as prose. Wait for confirmation, revision, or redirect before writing the plan. + +**Pipeline mode:** skip this phase entirely. Inferred bets route to a `## Assumptions` section in the new plan written in Phase 4b. + +## Phase 4b — Write new plan + +Read `references/replan-template.md` for filename conventions, frontmatter contract, the always-from-`main` rule, full section order, and discipline checks. Then: + +1. Determine the output filename: `docs/plans/YYYY-MM-DD-NNN-replan--beta-plan.md`. Today's date; next sequence number for the day starting at `001`; `` is a kebab-cased short label from the new approach. +2. Compose the doc per the template — frontmatter (`type: replan`, `origin:` to the forked brainstorm or original brainstorm, `supersedes:` to the original plan, `original_pr:`), Summary, Re-Grounded Problem Frame, Requirements (cite R-IDs from `origin:`), Discarded Approaches with reasoning, Cherry-Pick Guidance, Supersedes, New Learnings inventory, Scope Boundaries, Context & Research, Key Technical Decisions, Implementation Units (with U-IDs), Suggested Branch Name, Sources & References. +3. Run the discipline checks at the end of `references/replan-template.md` — every plan unit's `Files:` / `Approach:` references treat `main` as baseline; no silent assumption that PR-branch code is on `main`; original artifacts referenced but not edited. +4. Use the Write tool to save the file. +5. Confirm the path back to the user (absolute path). + +## Phase 5 — Handoff + +**Pipeline mode:** skip this phase. Return control to the caller after the artifacts are written. Do not emit unsolicited summaries. + +**Interactive mode:** present the handoff menu using the platform's blocking question tool (load `AskUserQuestion` via `ToolSearch` first in Claude Code if its schema isn't loaded). + +**Question:** "Replan written. Forked brainstorm: ``. New plan: ``. What would you like to do next?" + +**Options:** + +1. **Start `/ce-work` against the new plan** (recommended) — invoke the `ce-work` skill via the platform's skill-invocation primitive (`Skill` in Claude Code, equivalents on Codex / Gemini / Pi), passing the new plan path **and** the branch base (`main`) as arguments so `ce-work` does not re-ask the user about branch base. Do not merely tell the user to type a command — fire the invocation. +2. **Open both artifacts in Proof for review** — load the `ce-proof` skill in HITL-review mode for the forked brainstorm and the new plan. +3. **Done for now** — display a brief confirmation and end the turn. + +For free-text revisions outside the three options, accept the input, apply the revision to the relevant doc, and loop back to this menu. + +**Hard rule (R19):** do not emit an unsolicited "what is not in this plan" summary or "things to consider" essay before, during, or after the menu render. Write the artifacts, present the menu, route the choice. Stop. + +**Completion check:** the skill is not complete until the post-write menu has been presented, the user has selected an option, and the inline routing for that option has been executed. + +--- + +> **Note:** This is a beta skill. The invocation contract, doc shapes, and discovery heuristics may change before promotion to a stable `ce-replan`. See `docs/solutions/skill-design/beta-skills-framework.md` for the framework and promotion path. diff --git a/plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-template.md b/plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-template.md new file mode 100644 index 000000000..61a939ba5 --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-template.md @@ -0,0 +1,183 @@ +# Forked Brainstorm Output Template + +Loaded by `ce-replan-beta`'s Phase 4a. The skill writes the forked brainstorm to `docs/brainstorms/` using the filename and frontmatter conventions documented here. The original brainstorm is **never** edited or deleted. + +## Filename pattern + +``` +docs/brainstorms/YYYY-MM-DD--rebrainstorm-requirements.md +``` + +- `YYYY-MM-DD` — today's date. +- `` — kebab-cased; matches the original brainstorm's topic so the relationship is visible at a glance. When the original was, e.g., `2026-05-04-cora-v2-briefed-requirements.md`, the fork is `2026-05-06-cora-v2-briefed-rebrainstorm-requirements.md`. +- `-rebrainstorm-` infix disambiguates when multiple revolutions happen on the same day (the date alone is not enough). + +## Frontmatter contract + +``` +--- +date: YYYY-MM-DD +topic: +revision: +supersedes: +--- +``` + +- `revision:` increments by 1 from the source's `revision:`. If the original lacks the field, treat it as `revision: 1` and write `revision: 2` here. +- `supersedes:` names the immediately-prior brainstorm (the one this fork re-brainstormed against), not the chain root. Walking the chain of `supersedes:` links provides full history. + +## Section order + +The forked brainstorm follows the standard `ce-brainstorm` requirements-doc structure with one new section unique to forks (`## Discarded Requirements`). + +```markdown +--- +date: YYYY-MM-DD +topic: +revision: +supersedes: +--- + +# + +## Summary + +[1-3 line forward-looking gloss of the new requirements shape. Not a diff against the prior revision — a self-contained summary of what the requirements say now.] + +--- + +## Re-Grounded Problem Frame + +[Backward-looking, situational. Re-derived from PR discussion language and learnings, NOT inherited from the original brainstorm's framing. Names the moment of pain, what the user thought before, and what changed in their understanding.] + +--- + +## Actors + +[If the original had Actors, carry them forward. Each carries an `[unchanged from rev N]` or `[revised from rev N]` marker. New actors get the next-unused A-ID.] + +- A1. **** [unchanged from rev 1]: +- A2. **** [revised from rev 1]: + +--- + +## Key Flows + +[Same disposition discipline as Actors. Discarded flows move to a `## Discarded Flows` section if any exist.] + +- F1. **** [unchanged from rev 1] + - **Trigger:** ... + - **Steps:** ... + - **Outcome:** ... + - **Covered by:** R1, R2 + +--- + +## Requirements + +[Every requirement carries an `[unchanged from rev N]` or `[revised from rev N]` marker inline. Discarded requirements do **not** appear here — they move to `## Discarded Requirements` below. R-IDs are stable: gaps are preserved.] + +**** + +- R1. [unchanged from rev 1] +- R2. [unchanged from rev 1] +- R4. [revised from rev 1]. Was: . Why revised: . + +*(Note R3 absent — moved to Discarded Requirements.)* + +**** + +- R7. [new in rev 2] + +--- + +## Discarded Requirements + +[Each entry preserves the original R-ID (so the gap in the active list above is documented), the original wording, and a one-line reason for discard. The `[discarded from rev N]` marker indicates which revision the requirement was last active in.] + +- R3. [discarded from rev 1]. Why discarded: . +- R5. [discarded from rev 1]. Why discarded: . + +--- + +## Acceptance Examples + +[Acceptance examples follow the same disposition discipline. Carried-forward AEs keep their AE-ID with `[unchanged from rev N]` or `[revised from rev N]` markers; discarded AEs move to a `## Discarded Acceptance Examples` section if any exist.] + +- AE1. **Covers R1, R2.** Given ..., when ..., outcome. [unchanged from rev 1] + +--- + +## Success Criteria + +[Forward-looking, fresh prose. Not necessarily annotated — these are statements about the new shape, not carried-forward items.] + +- ... + +--- + +## Scope Boundaries + +[Apply the disposition rules where boundaries carry forward. New exclusions tied to discarded requirements are noted as `[new in rev 2]`.] + +- [unchanged from rev 1] +- [new in rev 2] + +### Deferred to Follow-Up Work + +- + +--- + +## Key Decisions + +[Forward-looking — the decisions that shape the new revision. Not annotated with disposition; the rationale lines say enough.] + +- : + +--- + +## Dependencies / Assumptions + +- ... + +--- + +## Outstanding Questions + +### Resolved Before Planning + +[Questions that the new learnings or the re-brainstorm phase resolved. Note the resolution.] + +- ... + +### Deferred to Planning + +[Questions still open; the re-plan phase or its downstream work will address them.] + +- ... +``` + +## Discipline checks + +Before writing the forked brainstorm to disk, verify: + +- Every original R-ID is accounted for: present in the active Requirements list (with `[unchanged]` / `[revised]` marker) **or** in `## Discarded Requirements` (with `[discarded]` marker). No silent drops. +- New R-IDs continue from the highest used original ID + 1; no reuse of discarded IDs. +- Frontmatter `supersedes:` is the immediately-prior brainstorm (path verified to exist on disk). `revision:` is exactly one higher than the source's. +- Re-grounded problem frame uses user discussion language, not paraphrase of the original brainstorm. +- Filename matches `docs/brainstorms/YYYY-MM-DD--rebrainstorm-requirements.md`. +- Topic in the filename matches the original (or the latest fork in the chain). Walking the chain via `supersedes:` should reach the chain root cleanly. +- All paths in the doc are repo-relative, never absolute. + +## Special cases + +- **Original had no R-IDs** (legacy fallback per `references/rebrainstorm-workflow.md` § Legacy fallback). Surface the derived IDs in the synthesis before writing the fork; once confirmed, treat them as if they had been there all along. +- **No new requirements.** A forked brainstorm with only `[unchanged]` and `[revised]` markers — and possibly `[discarded]` items — is valid. The `## Discarded Requirements` section may be present without new R-IDs above. Surface this in the synthesis so the user knows the fork is purely a refinement. +- **Many discards.** A forked brainstorm where most original R-IDs are discarded is a signal that the topic itself may have shifted. Surface in the synthesis; consider whether the user wanted to start a fresh brainstorm rather than fork. Default behavior: still write the fork; don't second-guess the discipline. + +## Non-goals for this template + +- Producing a plan. The plan is downstream; this template only covers the brainstorm fork. +- Capturing implementation details (file paths, exact code shapes). Those belong in the plan; the brainstorm stays at the requirements layer. +- Preserving an unstable diff against the original. The fork is the new source of truth at this revision; the original is preserved separately by reference, not by interleaved annotation. diff --git a/plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-workflow.md b/plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-workflow.md new file mode 100644 index 000000000..c217856f0 --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/references/rebrainstorm-workflow.md @@ -0,0 +1,124 @@ +# Re-Brainstorm Workflow + +Loaded by `ce-replan-beta`'s Phase 2a. Re-brainstorming is the load-bearing move that separates a replan from an in-place plan edit. The original brainstorm and PR are **evidence to interrogate**, not authoritative framing to inherit. + +The output of this phase is a forked `*-requirements.md` doc, not a new plan. The plan is derived from the forked brainstorm in the next phase (Phase 2b). + +## Four steps + +### 1. Read artifacts in this order + +Order matters. Read in the sequence below specifically — the goal is to absorb the user's discussion language before the original brainstorm's distillation of it. + +1. **PR review threads, comments, and review submissions.** The user's actual back-and-forth is where the original requirements got tested. Pay attention to where reviewers pushed back, where the user changed their mind, and where confusion accumulated. Use `scripts/fetch-pr-context.sh`'s output (passed as a path, not inlined) when dispatching subagents. +2. **Recent docs in `docs/brainstorms/`.** Any brainstorm that postdates the original is a likely source of new framing. Scan for topic-related material. +3. **Prior conversation context.** Whatever the user said in the current session that prompted the replan. +4. **Original plan doc.** Read for what was decided, but treat the framing as a hypothesis under review. +5. **Original brainstorm.** Read **last**. The risk of reading it first is that its prose anchors the agent's re-derivation; reading it last means the new framing is shaped by the discussion before being cross-checked against the original. + +### 2. Re-derive the problem frame from user discussion language + +Compose a fresh problem-frame paragraph using the **user's words from the discussion**, not from the original brainstorm's polished prose. Specifically: + +- Quote or close-paraphrase what the user said about the pain in PR threads or recent conversation. +- Identify the moment of pain: what triggered the replan? A specific reviewer comment, a code-reading discovery, a brainstorm doc, a "this could be much simpler" realization? +- State what the user thought before the new learnings, and what they think now. The **delta** is the reason the replan exists. + +Where the new problem frame agrees with the original, that's fine — the original wasn't wrong, it was incomplete. The discipline is to derive independently first, then notice the agreements, rather than copying the original framing verbatim. + +### 3. Walk every original requirement + +For each requirement in the original brainstorm, assign one of three dispositions: + +- **`[unchanged]`** — the requirement still holds as stated. Default for requirements where no learning contradicts them. No further reasoning needed; the requirement carries forward in the forked brainstorm under its original R-ID. +- **`[revised]`** — the requirement still has real intent behind it, but the learnings reshape what it should say. The R-ID carries forward; the wording is updated; the disposition marker becomes `[revised from rev N]` in the forked brainstorm. Capture both the original wording and the specific learning that drove the change so future readers see the lineage. +- **`[discarded]`** — the requirement was tied to an approach the replan abandons, and there is no underlying intent worth carrying forward. The R-ID is **not reused** for new content; it leaves a gap in the active list and moves to a `## Discarded Requirements` section in the forked brainstorm with the original wording and a one-line reason. + +This step satisfies the no-silent-inheritance rule: every original requirement is touched explicitly, and the disposition is visible in the forked output. Default to `[unchanged]` is intentional — the agent does not invent reasons to revise. But never silently drop a requirement, even one the new approach makes obviously irrelevant: surface it as `[discarded]` with a one-line rationale. + +After requirements, perform the same pass on: + +- **Scope boundaries** — is anything previously excluded now in scope? Is anything previously in scope now out? +- **Key decisions** — which decisions still hold? Which need revisiting? +- **Outstanding questions** — which were resolved by the learnings? Which still apply? Are there new questions? + +### 4. R-ID stability rule (load-bearing) + +R-IDs are the anchor that makes the compounding loop work. The rules: + +- **Original IDs preserved.** R1 in the original stays R1 in the forked brainstorm, regardless of whether it was `[unchanged]`, `[revised]`, or `[discarded]`. +- **Revisions keep their ID** with new wording. The marker `[revised from rev N]` (where N is the original brainstorm's revision number, defaulting to `1`) makes the change visible inline. +- **Discards leave gaps.** R5 absent from the active list is fine — gaps are how the loop stays auditable. R5 appears in `## Discarded Requirements` with the original wording, one-line reason, and `[discarded from rev N]` marker. +- **New requirements get the next-unused R-ID.** Never reuse a discarded ID for new content. If the original had R1–R6 and R5 is discarded, new requirements continue from R7. +- **No renumbering, ever.** Reordering, splitting, and discarding all preserve R-IDs in place. The forked brainstorm's active list may have gaps; that is correct. + +The discipline echoes how `ce-plan`'s U-IDs survive plan edits. + +### 5. Compose a three-bucket synthesis at the requirements scope + +Mirror the synthesis pattern used by `ce-plan` and `ce-brainstorm`. Format: + +``` +Based on the PR, original requirements, and new learnings, here's the scope I'm proposing for the forked brainstorm: + +[1-3 line prose summary — what's changing in the requirements layer, in plain language. Forward-looking.] + +**Stated** (carried forward from the PR, original brainstorm, and learnings): +- [item] + +**Inferred** (gaps I filled with assumptions — flag anything I got wrong): +- [item] + +**Out of scope** (deliberately excluded — including things the original had that the replan drops): +- [item] +``` + +Use prose for the user response (no `AskUserQuestion` menu) — option sets bias the answer. The user confirms, revises, or redirects. **In pipeline mode**, skip the prompt and route Inferred bets to a `## Assumptions` section in the forked brainstorm. + +## Anti-patterns + +- **Diff-against-the-original-brainstorm thinking.** Do not treat re-brainstorming as "what changed in the requirements." Re-derive the user story first, then let requirement changes fall out. A diff mentality preserves the original framing's blind spots. +- **Preserving the original brainstorm's framing language.** If the new problem-frame paragraph reads like a paraphrase of the original, the inheritance has already happened. Use the user's discussion language instead. +- **Critique-mode.** This is not a review of the original brainstorm's quality. It is a re-derivation in light of new information. The original was correct given what was known then; the replan exists because the world changed. +- **Skipping requirements.** "All the original requirements obviously still hold" is a tell that step 3 was not actually performed. Each requirement gets an explicit `[unchanged]` / `[revised]` / `[discarded]` disposition, not a blanket assumption. +- **Brainstorm-from-zero.** The opposite failure: ignoring the original artifacts entirely and re-deriving from scratch. The original PR's working code, designs, and IDs are real evidence of what the user wanted; re-brainstorming refines that, doesn't throw it away. +- **Renumbering R-IDs.** Even when discards leave large gaps, do not renumber. The gaps are how the loop's history stays auditable. + +## Legacy fallback — original brainstorm has no R-IDs + +Older brainstorms (or brainstorms produced by hand) may not have explicit R-IDs in their Requirements section. When the original lacks R-IDs: + +1. Derive implicit R-IDs first by numbering the original's Requirements bullets in order (top to bottom, left to right). R1 = first bullet, R2 = second, etc. Group headers don't take an ID; only the bullets within do. +2. Surface the derived R-IDs explicitly in the synthesis ("the original had no R-IDs; I've assigned them as: R1 = [first bullet], R2 = [second bullet], ...") so the user can correct any misreading before the fork is written. +3. Once confirmed, carry the derived IDs forward as if they had been there all along. + +The forked brainstorm's `revision: 2` frontmatter still applies; the original is treated as `revision: 1` even though the file itself didn't claim that. + +## Worked example: the brief-view scenario + +A long-running PR (`origin/brief-view`) introduced a new sidecar table for tracking briefed-state transitions. The original brainstorm had R1–R6 covering the sidecar approach. After several rounds of review, the user discovered that an existing saved-view system (`action == brief AND has INBOX`) could provide the same tracking without any new tables. + +A naive replan would say: "drop the sidecar requirements, add a saved-view requirement, keep the rest." That misses the point — it's an in-place edit of the requirements list, not a re-derivation. + +A re-brainstorming pass instead asks: + +1. **Artifacts read** — PR threads (where reviewers questioned the sidecar's necessity), the new brainstorm noting the saved-view alternative, prior conversation, original plan, original brainstorm. +2. **Re-derived problem frame** — the user wanted to track when emails became "briefed" so list counts and chips updated correctly. They thought a sidecar table was needed because they didn't yet know the saved-view system existed. The new framing is "track briefed transitions"; the storage choice (sidecar vs saved-view) is downstream. +3. **Requirement walk:** + - R1 (track briefed transitions) → `[unchanged]`. Still required. + - R2 (update list counts on briefing) → `[unchanged]`. Still required. + - R3 (sidecar table for transitions) → `[discarded]`. The underlying intent (R1) is preserved separately; the table itself is gone. Reason: saved-view repurposing eliminates the need. + - R4 (mailer hook on briefing) → `[revised]`. Still required, but now hooks into saved-view machinery instead of sidecar. New wording captures the saved-view dependency. + - R5 (ERD entry for sidecar) → `[discarded]`. Tied to R3; same reason. + - R6 (migration for sidecar) → `[discarded]`. Tied to R3; same reason. + - **New R7** (saved-view dependency must remain stable across schema migrations) → next-unused ID. +4. **Three-bucket synthesis at the requirements scope**: + - **Stated**: track briefed transitions (R1), list count updates (R2), mailer behavior (R4 revised), saved-view stability dependency (R7 new). + - **Inferred**: saved-view repurposing is the right approach for v1 (the user said "I think this works" but did not test it under load). + - **Out**: sidecar table, ERD entry, migration. The *approach* is gone; the *intent* (R1, R2) carries forward via a different mechanism. + +The forked brainstorm has R1, R2, R4, R7 in its active list, with R3, R5, R6 in `## Discarded Requirements`. Frontmatter has `supersedes: docs/brainstorms/.md` and `revision: 2`. + +The new plan (Phase 2b's job, not this phase's) then derives from the forked brainstorm's active R-IDs and produces from-`main` units that may cherry-pick designs, IDs, or UI components from the original PR. + +The level of detail in this example is illustrative — actual replans will have shorter and longer cases. diff --git a/plugins/compound-engineering/skills/ce-replan-beta/references/replan-template.md b/plugins/compound-engineering/skills/ce-replan-beta/references/replan-template.md new file mode 100644 index 000000000..713ecbd7a --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/references/replan-template.md @@ -0,0 +1,229 @@ +# Replan Output Template + +Loaded by `ce-replan-beta`'s Phase 4b. The skill writes the new plan to `docs/plans/` using the filename and frontmatter conventions documented here. The original plan and PR are **never** edited. + +## Always-from-`main` rule (load-bearing) + +Plan units must be written for the **`main` baseline**, not the existing PR's branch. Specifically: + +- `Files:` references treat `main` as the starting point. Any file that exists only on the original PR's branch (and not on `main`) must be named in `## Cherry-Pick Guidance` — the unit that depends on it either creates the file fresh or cherry-picks it from the original PR. +- `Approach:` paragraphs do not assume any code, IDs, helpers, or designs from the original PR are already in place. If a unit reuses something from the PR, the reuse is named explicitly: *"Reuses `path/to/file.tsx` from PR #N commit `` — see Cherry-Pick Guidance."* +- Plan units' `Test scenarios:` are written for the from-`main` baseline. They do not reference test setup that exists only on the PR's branch. + +The cora session (`10b929fb-c03f-4daf-b675-32c00ac44b43`, PR #2382) failed this rule and forced ce-work to ask the user about branch base. Adhering to the rule here prevents the same failure mode. + +## Filename pattern + +``` +docs/plans/YYYY-MM-DD-NNN-replan--beta-plan.md +``` + +- `YYYY-MM-DD` — today's date. +- `NNN` — three-digit sequence number for the day, starting at `001`. Check existing files for today's date to determine the next number. +- `replan-` prefix marks this as replan output (parallel to `feat-`, `fix-`, `refactor-`). +- `` — kebab-cased short label derived from the new approach (3-5 words). +- `-beta-plan.md` suffix is mandated by the beta-skills framework so output never collides with stable `ce-plan` output. + +Example: `docs/plans/2026-05-06-002-replan-ce-replan-beta-beta-plan.md` + +## Frontmatter contract + +``` +--- +title: "" +type: replan +status: active +date: YYYY-MM-DD +origin: +supersedes: +original_pr: +--- +``` + +- `type: replan` distinguishes the doc from regular `feat`/`fix`/`refactor` plans for downstream tooling. +- `origin:` is the **forked brainstorm** when the re-brainstorm phase ran, or the original brainstorm when it was skipped (no upstream brainstorm existed). The `find-original-brainstorm.sh` script's output feeds this field for the skipped case. +- `supersedes:` and `original_pr:` carry the lineage so the chain of revolutions stays walkable. + +## Section order + +```markdown +--- +title: "" +type: replan +status: active +date: YYYY-MM-DD +origin: docs/brainstorms/... +supersedes: docs/plans/... +original_pr: +--- + +# + +## Summary + +[1-3 line forward-looking gloss of the new approach. Names what the replan does, not what the original PR was doing.] + +--- + +## Re-Grounded Problem Frame + +[Backward-looking. Re-derived from PR discussion + new learnings. Names the moment of pain that motivated the replan, what the user thought before, and what changed in their understanding.] + +--- + +## Requirements + +[Cite R-IDs from `origin:` (the forked brainstorm or original brainstorm). NO per-requirement [unchanged]/[revised]/[discarded] annotation block — that lives in the forked brainstorm at the requirements scope.] + +- R1, R2, R4, R7 (active R-IDs from `origin:`). + +**Origin actors:** A1 (..., from origin) +**Origin flows:** F1 (..., from origin) +**Origin acceptance examples:** AE1, AE3, AE4 (from origin) + +--- + +## Discarded Approaches + +[2-4 named approaches from the original PR that the replan abandons. Each entry names the approach, the specific learning that ruled it out, and where its artifacts (commits, files, designs) are addressed downstream — typically in Cherry-Pick Guidance for what survives, or simply marked obsolete for what doesn't.] + +- ****: **Why discarded**: + +--- + +## Cherry-Pick Guidance + +[Concrete list of files, commits, designs, IDs, or migrations from the original PR worth preserving. **The canonical place to name code that exists only on the original PR's branch — units below that reference these items must do so by linking back here, never by assuming the items are already on `main`.**] + +| Item | Type | Source | Why preserve | +|------|------|--------|--------------| +| `path/to/file.tsx` | UI component | PR #N commit `` | Visual/functional layer is independent of the storage choice. | +| Migration `2026XXXXXXXXXX_create_thing.rb` | Schema | PR #N commit `` | Already shipped to staging; safe to keep. | +| Issue tracker IDs `CE-1234`, `CE-1235` | Tracking | PR description | Reuse so the replan inherits the existing trail. | + +--- + +## Supersedes + +- **Original PR:** # () — left open and untouched on GitHub. The user decides whether to close the original as superseded, force-push the replan over it, or land the original first. +- **Original plan:** <repo-relative path> +- **Original brainstorm:** <repo-relative path, when applicable> +- **Diff from original**: [2-3 sentences describing what is changing in approach. Not a summary of the new plan — a contrast with the old.] + +--- + +## New Learnings + +[Inventory of what changed in understanding since the original plan was written. Each entry names the source so future readers can verify.] + +- **<Learning, in plain language>** — Source: <PR thread URL, commit SHA, brainstorm path, or "current session conversation"> + +--- + +## Scope Boundaries + +[Carry forward original scope where still relevant; mark new exclusions tied to discarded approaches.] + +- <Excluded item> +- <Newly excluded item, tied to a discarded approach> + +### Deferred to Follow-Up Work + +- <Plan-local follow-up work split into a separate PR> + +--- + +## Context & Research + +### Relevant Code and Patterns + +- <Existing files to follow> + +### Institutional Learnings + +- <Relevant `docs/solutions/` insight> + +### External References + +- <Used only when external research was warranted> + +--- + +## Key Technical Decisions + +- <Decision>: <Rationale; reference the original plan's decision when this overrides it> + +--- + +## Implementation Units + +[Standard `ce-plan` format. Each unit gets a stable U-ID. When a unit reuses code from the original PR, name it in the unit's `Approach:` field and link back to Cherry-Pick Guidance.] + +- U1. **<Name>** + +**Goal:** <What this unit accomplishes> + +**Requirements:** <R-IDs from `origin:`, e.g., R1, R4> + +**Dependencies:** <None / U-IDs / external prerequisite> + +**Files:** +- Create: `path/to/new_file` +- Modify: `path/to/existing_file` +- Test: `path/to/test_file` + +**Approach:** +- <Key decision> +- <Cherry-pick reference: "Reuses `path/...` from original PR commit `<sha>` — see Cherry-Pick Guidance."> + +**Patterns to follow:** +- <Existing file or convention> + +**Test scenarios:** +- <Scenario> + +**Verification:** +- <Outcome that should hold when this unit is complete> + +--- + +## Suggested Branch Name + +`replan/<topic-slug>` — start the new branch from `main`: + +``` +git checkout main +git pull +git checkout -b replan/<topic-slug> +``` + +The user runs the above; this skill performs no Git operations. + +--- + +## Sources & References + +- **Origin (forked brainstorm or original brainstorm):** <repo-relative path> +- **Original PR:** #<N> <title> — <URL> +- **Original plan:** <repo-relative path> +- **Re-grounding context:** <PR threads, brainstorm paths, conversation references that drove the replan> +``` + +## Discipline checks + +Before writing the plan to disk, verify: + +- Every plan unit's `Files:` and `Approach:` references treat `main` as baseline. Code on the original PR's branch is named in Cherry-Pick Guidance — never silently assumed. +- Discarded Approaches each name a specific learning, not generic "wasn't quite right" rationale. +- Cherry-Pick rows specify what to preserve and why — not just "keep the UI work." +- Original PR, original plan, and original brainstorm are referenced but not edited. +- Suggested branch name does not match the original PR's branch. +- All file paths are repo-relative, never absolute. +- Filename uses the `replan-<topic>-beta-plan.md` shape. +- R-ID references point to the doc named in `origin:` (forked brainstorm or original); they resolve cleanly. + +## Non-goals for this template + +- Per-requirement annotation. That lives in the forked brainstorm; the plan only references R-IDs. +- Carrying forward implementation units from the original plan verbatim. Units are derived fresh from the (forked) brainstorm; if a v1 unit's work is still right, it's still re-stated as a unit here, not "carried forward." +- Documenting the verb-level decision to replan. The skill's user has decided; the plan is the artifact, not the justification. diff --git a/plugins/compound-engineering/skills/ce-replan-beta/scripts/detect-pr.sh b/plugins/compound-engineering/skills/ce-replan-beta/scripts/detect-pr.sh new file mode 100755 index 000000000..70f662011 --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/scripts/detect-pr.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# +# detect-pr.sh — Detect the PR that ce-replan-beta should target. +# +# Usage: +# detect-pr.sh # auto-detect from current branch +# detect-pr.sh PR_NUMBER # use the explicit PR number +# detect-pr.sh PR_NUMBER OWNER/REPO +# +# Exits with: +# 0 — PR found, JSON metadata emitted on stdout +# 1 — gh CLI error (auth, network, etc.); error message on stderr +# 2 — no PR found for current branch (sentinel for the "F3 / no-PR" route) + +set -e + +PR_NUMBER="${1:-}" + +if [ -n "$2" ]; then + OWNER=$(echo "$2" | cut -d/ -f1) + REPO=$(echo "$2" | cut -d/ -f2) + REPO_FLAG=(--repo "$OWNER/$REPO") +else + REPO_FLAG=() +fi + +# JSON fields requested for the PR. Keep this list intentionally small — +# downstream phases (fetch-pr-context.sh) cover deep data. +PR_FIELDS="number,url,title,body,headRefName,baseRefName,state,isDraft,author" + +if [ -z "$PR_NUMBER" ]; then + # Auto-detect: query current branch's PR. gh exits non-zero when no PR exists. + if ! OUTPUT=$(gh pr view --json "$PR_FIELDS" "${REPO_FLAG[@]}" 2>&1); then + # Distinguish "no PR" from real errors. gh's "no pull requests found" message + # is the no-PR case; anything else propagates as a hard error. + if echo "$OUTPUT" | grep -qE "no pull requests found|no open pull requests"; then + exit 2 + fi + echo "$OUTPUT" >&2 + exit 1 + fi + echo "$OUTPUT" + exit 0 +fi + +# Explicit PR number path. +if ! gh pr view "$PR_NUMBER" --json "$PR_FIELDS" "${REPO_FLAG[@]}"; then + exit 1 +fi diff --git a/plugins/compound-engineering/skills/ce-replan-beta/scripts/fetch-pr-context.sh b/plugins/compound-engineering/skills/ce-replan-beta/scripts/fetch-pr-context.sh new file mode 100755 index 000000000..0cc838889 --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/scripts/fetch-pr-context.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +# +# fetch-pr-context.sh — Fetch PR metadata, review threads, top-level review +# bodies, and commit list for ce-replan-beta's discovery phase. +# +# Usage: +# fetch-pr-context.sh PR_NUMBER [OWNER/REPO] +# +# Output: a single JSON object on stdout with keys: +# pr — top-level PR metadata (number, url, title, body, headRefName, baseRefName) +# review_threads — review threads (resolved + unresolved), with comment bodies and authors +# review_bodies — review submission bodies with non-empty text +# pr_comments — top-level PR conversation comments (excludes PR author and codecov) +# commits — list of commits with sha, message subject, and author +# +# This is read-only context for the agent's re-grounding phase. Filtering is +# minimal — the agent decides what's signal and what's noise. + +set -e + +if [ $# -lt 1 ]; then + echo "Usage: fetch-pr-context.sh PR_NUMBER [OWNER/REPO]" >&2 + exit 1 +fi + +PR_NUMBER=$1 + +if [ -n "$2" ]; then + OWNER=$(echo "$2" | cut -d/ -f1) + REPO=$(echo "$2" | cut -d/ -f2) +else + OWNER=$(gh repo view --json owner -q .owner.login) + REPO=$(gh repo view --json name -q .name) +fi + +if [ -z "$OWNER" ] || [ -z "$REPO" ]; then + echo "Error: Could not detect repository. Pass OWNER/REPO as second argument." >&2 + exit 1 +fi + +gh api graphql \ + -f owner="$OWNER" \ + -f repo="$REPO" \ + -F pr="$PR_NUMBER" \ + -f query=' +query FetchPRContext($owner: String!, $repo: String!, $pr: Int!) { + repository(owner: $owner, name: $repo) { + pullRequest(number: $pr) { + number + url + title + body + headRefName + baseRefName + author { login } + reviewThreads(first: 50) { + edges { + node { + id + isResolved + isOutdated + path + line + comments(first: 20) { + nodes { + author { login } + body + createdAt + url + } + } + } + } + } + comments(first: 100) { + nodes { + author { login } + body + createdAt + } + } + reviews(first: 50) { + nodes { + author { login } + body + state + submittedAt + } + } + commits(first: 100) { + nodes { + commit { + oid + messageHeadline + messageBody + author { name } + } + } + } + } + } +}' | jq '.data.repository.pullRequest as $pr | + ["codecov"] as $ci_bots | + # Use // [] defaults on every collection traversal so missing keys produce + # explicit empty arrays rather than triggering jq exit code 5 (which is + # silent at the agent layer — see R18 in the v2 brainstorm). Same defense + # for nullable user fields like .author.login on deleted accounts. + { + pr: { + number: $pr.number, + url: $pr.url, + title: $pr.title, + body: $pr.body, + headRefName: $pr.headRefName, + baseRefName: $pr.baseRefName, + author: ($pr.author.login // null) + }, + review_threads: [(($pr.reviewThreads.edges) // [])[] + | { resolved: .node.isResolved, + outdated: .node.isOutdated, + path: .node.path, + line: .node.line, + comments: [((.node.comments.nodes) // [])[] + | { author: (.author.login // null), body: .body, createdAt: .createdAt, url: .url }] }], + review_bodies: [(($pr.reviews.nodes) // [])[] + | select(.body != null and .body != "") + | select((.author.login // "") as $l | $ci_bots | index($l) | not) + | { author: (.author.login // null), body: .body, state: .state, submittedAt: .submittedAt }], + pr_comments: [(($pr.comments.nodes) // [])[] + | select((.author.login // "") != ($pr.author.login // "")) + | select((.author.login // "") as $l | $ci_bots | index($l) | not) + | select(.body | test("^\\s*$") | not) + | { author: (.author.login // null), body: .body, createdAt: .createdAt }], + commits: [(($pr.commits.nodes) // [])[] + | { sha: .commit.oid, + subject: .commit.messageHeadline, + body: .commit.messageBody, + author: (.commit.author.name // null) }] + }' diff --git a/plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-brainstorm.sh b/plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-brainstorm.sh new file mode 100755 index 000000000..d38a57b8e --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-brainstorm.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# +# find-original-brainstorm.sh — Locate the brainstorm doc that an existing +# plan derived from, if one is discoverable in the working repo. +# +# Usage: +# find-original-brainstorm.sh PLAN_PATH +# +# Strategy: +# 1. If PLAN_PATH's frontmatter has an `origin:` field pointing to a +# docs/brainstorms/*-requirements.md path, prefer that. +# 2. Otherwise, score docs/brainstorms/*-requirements.md filenames against +# the plan's topic fragments (extracted from the plan filename), the +# same way find-original-plan.sh scores plan candidates against branch +# fragments. +# +# Output: +# The repo-relative path of the most likely original brainstorm, or empty +# when no candidate clears the heuristic. Empty output is not an error — +# callers must check stdout, not exit code. + +set -e + +PLAN_PATH="${1:-}" + +if [ -z "$PLAN_PATH" ]; then + echo "Usage: find-original-brainstorm.sh PLAN_PATH" >&2 + exit 1 +fi + +REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) +if [ -z "$REPO_ROOT" ]; then + echo "Error: not inside a git repository." >&2 + exit 1 +fi + +# Resolve PLAN_PATH to absolute (accept both repo-relative and absolute). +if [ -f "$PLAN_PATH" ]; then + PLAN_ABS="$PLAN_PATH" +elif [ -f "$REPO_ROOT/$PLAN_PATH" ]; then + PLAN_ABS="$REPO_ROOT/$PLAN_PATH" +else + echo "Error: plan file not found at $PLAN_PATH" >&2 + exit 1 +fi + +# Step 1 — try the plan's own frontmatter first. +ORIGIN=$(awk ' + /^---[[:space:]]*$/ { in_fm = !in_fm; next } + in_fm && /^origin:/ { + sub(/^origin:[[:space:]]*/, "") + gsub(/^["'\'']/, "") + gsub(/["'\''][[:space:]]*$/, "") + print + exit + } +' "$PLAN_ABS") + +if [ -n "$ORIGIN" ] && [ -f "$REPO_ROOT/$ORIGIN" ]; then + echo "$ORIGIN" + exit 0 +fi + +# Step 2 — fall back to topic-fragment scoring against docs/brainstorms/. +BRAINSTORMS_DIR="$REPO_ROOT/docs/brainstorms" +if [ ! -d "$BRAINSTORMS_DIR" ]; then + exit 0 +fi + +# Strip the standard plan filename shape: +# YYYY-MM-DD-NNN-<type>-<topic>-plan.md +# We want the <topic> portion as our scoring source. The simplest portable +# approach is: drop the date+seq prefix (first three dash-separated tokens), +# drop the trailing "-plan.md", and treat the rest as the topic. Any leading +# type like feat/fix/refactor/replan is also dropped to widen fragment match. +PLAN_BASENAME=$(basename "$PLAN_ABS") +TOPIC=$(echo "$PLAN_BASENAME" | sed -E 's/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]+-(feat|fix|refactor|replan|chore|docs)-//; s/-(beta-)?plan\.md$//') + +# Split the topic into fragments. Put '-' first in the tr SET so it is +# literal (otherwise tr reads '/-_+.' as a range from / to _, which silently +# eats uppercase letters and digits). Filter to fragments at least 4 chars. +FRAGMENTS=$(echo "$TOPIC" | tr -- '-/_+.' '\n\n\n\n\n' | awk 'length($0) >= 4') + +if [ -z "$FRAGMENTS" ]; then + exit 0 +fi + +# Score each *-requirements.md by the number of fragments matched in its +# basename. Tie-break by mtime (newer wins). +BEST=$( + find "$BRAINSTORMS_DIR" -maxdepth 1 -type f -name '*-requirements.md' -print0 | + while IFS= read -r -d '' brainstorm; do + basename=$(basename "$brainstorm") + score=0 + while IFS= read -r frag; do + [ -z "$frag" ] && continue + if echo "$basename" | grep -qiF "$frag"; then + score=$((score + 1)) + fi + done <<<"$FRAGMENTS" + if [ "$score" -gt 0 ]; then + mtime=$(stat -f %m "$brainstorm" 2>/dev/null || stat -c %Y "$brainstorm" 2>/dev/null || echo 0) + relpath=${brainstorm#"$REPO_ROOT/"} + printf '%d\t%d\t%s\n' "$score" "$mtime" "$relpath" + fi + done | sort -k1,1nr -k2,2nr | head -n 1 +) + +if [ -z "$BEST" ]; then + exit 0 +fi + +# Surface the top candidate. False positives are caught at the synthesis +# checkpoint where the user confirms or corrects the discovered original +# brainstorm before it is relied on. +echo "$BEST" | cut -f3 diff --git a/plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-plan.sh b/plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-plan.sh new file mode 100755 index 000000000..5c7bb8722 --- /dev/null +++ b/plugins/compound-engineering/skills/ce-replan-beta/scripts/find-original-plan.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +# +# find-original-plan.sh — Locate the original plan doc that an existing PR +# was implementing, if one exists in the working repo's docs/plans/ tree. +# +# Usage: +# find-original-plan.sh BRANCH_NAME [PR_BODY_FILE] +# +# Inputs: +# BRANCH_NAME — head ref of the PR (used to score filename matches) +# PR_BODY_FILE — optional path to a file containing the PR body. When +# provided, the script scans the body for explicit +# 'docs/plans/...' references and prefers them. +# +# Output: +# The repo-relative path of the most likely original plan, or empty when +# no candidate clears a minimum confidence threshold. +# +# Exit code is always 0 when the script ran successfully — empty output is +# not an error. Callers must check for empty stdout, not exit code, to +# detect "no match found". + +set -e + +BRANCH_NAME="${1:-}" +PR_BODY_FILE="${2:-}" + +if [ -z "$BRANCH_NAME" ]; then + echo "Usage: find-original-plan.sh BRANCH_NAME [PR_BODY_FILE]" >&2 + exit 1 +fi + +REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) +if [ -z "$REPO_ROOT" ]; then + echo "Error: not inside a git repository." >&2 + exit 1 +fi + +PLANS_DIR="$REPO_ROOT/docs/plans" +if [ ! -d "$PLANS_DIR" ]; then + # No plans directory at all — emit empty output and exit cleanly. + exit 0 +fi + +# Step 1: explicit PR-body link wins. +if [ -n "$PR_BODY_FILE" ] && [ -f "$PR_BODY_FILE" ]; then + LINKED=$(grep -oE 'docs/plans/[A-Za-z0-9._/-]+\.md' "$PR_BODY_FILE" | head -n 1 || true) + if [ -n "$LINKED" ] && [ -f "$REPO_ROOT/$LINKED" ]; then + echo "$LINKED" + exit 0 + fi +fi + +# Step 2: score filenames by branch-name fragment matches. +# Strip common branch prefixes (feat/, fix/, refactor/, replan/) and split on -/_/+/. +NORMALIZED_BRANCH=$(echo "$BRANCH_NAME" | sed -E 's@^(feat|fix|refactor|replan|chore|docs)/@@') + +# Build a list of fragments at least 4 characters long to avoid noisy short tokens. +# Note: '-' is placed first in the tr set so it is literal — putting it between +# '/' and '_' would have made tr read it as the range '/'..'_' (which includes +# uppercase letters and digits) and silently destroy fragments for branches +# like JIRA-123-bug. +FRAGMENTS=$(echo "$NORMALIZED_BRANCH" | tr -- '-/_+.' '\n\n\n\n\n' | awk 'length($0) >= 4') + +if [ -z "$FRAGMENTS" ]; then + # Branch name was too generic to score against. + exit 0 +fi + +# For each plan file, count how many fragments appear in the basename. +# Output: SCORE\tPATH (tab-separated). Sort descending by score, then by mtime. +BEST=$( + find "$PLANS_DIR" -maxdepth 1 -type f -name '*.md' -print0 | + while IFS= read -r -d '' plan; do + basename=$(basename "$plan") + score=0 + while IFS= read -r frag; do + [ -z "$frag" ] && continue + if echo "$basename" | grep -qiF "$frag"; then + score=$((score + 1)) + fi + done <<<"$FRAGMENTS" + if [ "$score" -gt 0 ]; then + mtime=$(stat -f %m "$plan" 2>/dev/null || stat -c %Y "$plan" 2>/dev/null || echo 0) + relpath=${plan#"$REPO_ROOT/"} + printf '%d\t%d\t%s\n' "$score" "$mtime" "$relpath" + fi + done | sort -k1,1nr -k2,2nr | head -n 1 +) + +if [ -z "$BEST" ]; then + exit 0 +fi + +# Emit the top candidate when at least one fragment matched. False positives +# are caught at the synthesis checkpoint where the user confirms or corrects +# the discovered original plan before it is relied on. +PATH_OUT=$(echo "$BEST" | cut -f3) +echo "$PATH_OUT"