plan-stage: add /pharn-plan product command and Approved-input gate#20
Conversation
Scopes the increment that adds /pharn-plan and the check-spec-approved floor gate. Co-authored-by: Cursor <cursoragent@cursor.com>
📝 WalkthroughWalkthroughAdds the Changesplan-stage: Approved-input gate, command spec, and process artifacts
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Build the product /pharn-plan command (the pipeline's plan stage after /pharn-spec): a deterministic Approved-input gate that refuses to plan from a Draft or a drifted SPEC, plus an advisory PLAN.md carrying spec_id + spec_content_hash forward (ARCHITECTURE 6, fix #4). /pharn-plan is the first downstream consumer that ENFORCES /pharn-spec's pin, making the pin non-decorative (the disease P0 exists to prevent: a guarantee written but never enforced). - .claude/commands/pharn-plan.md: the product command (mirrors /pharn-spec; no role:; discovery-first, halt-and-ask; runs the gate, emits PLAN.md) - .dev/floor/check-spec-approved.mjs: the gate, reuses check-spec.mjs (shape + content-hash) via CLI subprocess and adds the state==Approved assertion; exit 0 iff Approved + un-drifted + well-shaped, else 1 - .dev/floor/check-spec-approved.test.mjs: 7 black-box tests (Draft->1, Approved+match->0, drift->1, malformed->1, missing-section->1, needle->0, usage->1) FLOOR: the input gate (state==Approved enum + the content-hash pin). ADVISORY: the plan's content (downstream grill/build/verify check it), and the two-clocks split (the checker verdict is floor; the command invoking it is advisory orchestration). Gated /pharn-dev-ship run (audit trail under .dev/features/plan-stage/): build validate GREEN (1 capability) - regress no-regressions - verify PASS (test/validate/lint=0, 0 verifiers) - review GREEN / 0 floor-gate findings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/commands/pharn-plan.md:
- Around line 84-120: The plan flow currently rereads SPEC.md after the approval
gate, which can let Step 4 copy spec_id and spec_content_hash from a different
SPEC state than the one that passed Step 2. Update pharn-plan so it freezes the
SPEC bytes once before gating, runs check-spec-approved.mjs against that frozen
snapshot, and then carries spec_id and spec_content_hash forward from the same
snapshot when writing PLAN.md. Use the Step 2 gate and Step 4 frontmatter copy
logic in pharn-plan as the place to fix this.
In @.dev/features/plan-stage/SHIP.md:
- Around line 30-38: Keep SHIP.md as a pointer-only document and remove the
restated advisory details currently embedded in the advisory pointers section.
Update the SHIP.md content around the REVIEW.md and GRILL.md references so it
simply directs readers to those source docs, preserving the unique identifiers
like REVIEW.md, GRILL.md, and the “Advisory pointers” section without
duplicating their findings.
In @.dev/floor/check-spec-approved.mjs:
- Around line 81-105: The validation flow in check-spec-approved.mjs re-reads
specPath after check-spec.mjs has already validated it, so a concurrent edit can
change the file between checks and make readState pass on different bytes than
the ones that were verified. Fix this by freezing the SPEC contents once in the
main flow and using that same snapshot for both the check-spec.mjs invocation
and the later state validation, updating the logic around spawnSync,
readFileSync, and readState so they all operate on the same in-memory text
rather than reopening specPath.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1ef0469c-4ff5-489b-a3eb-ebd72f002285
📒 Files selected for processing (11)
.claude/commands/pharn-plan.md.dev/features/plan-stage/GRILL.md.dev/features/plan-stage/PLAN.md.dev/features/plan-stage/REGRESSION.md.dev/features/plan-stage/REVIEW.md.dev/features/plan-stage/SHIP.md.dev/features/plan-stage/VERIFY.md.dev/features/plan-stage/regression-report.json.dev/features/plan-stage/verify-report.json.dev/floor/check-spec-approved.mjs.dev/floor/check-spec-approved.test.mjs
Summary
/pharn-plan(second stage of the product spine after/pharn-spec)..dev/floor/check-spec-approved.mjsthat shells tocheck-spec.mjsand assertsstate === "Approved", so planning only proceeds from approved, un-drifted intent./pharn-planwill emitfeatures/<name>/PLAN.mdcarryingspec_id+spec_content_hashforward; plan content remains advisory.Test plan
.dev/features/plan-stage/PLAN.md(GATE 1 already approved 2026-06-30)/pharn-dev-buildon this plan (follow-up increment) — implementpharn-plan.md,check-spec-approved.mjs, and testsnpm testgreen after buildnode .dev/floor/validate.mjs .still reports floor capability count unchanged (1)Made with Cursor
Summary by CodeRabbit
New Features
Bug Fixes