Skip to content

build-stage: add /pharn-build product command and plan-scope gates#22

Merged
PrzemekGalarowicz merged 6 commits into
mainfrom
build-stage
Jun 30, 2026
Merged

build-stage: add /pharn-build product command and plan-scope gates#22
PrzemekGalarowicz merged 6 commits into
mainfrom
build-stage

Conversation

@PrzemekGalarowicz

@PrzemekGalarowicz PrzemekGalarowicz commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add /pharn-build, the product pipeline's fourth stage (spec → plan → grill → build → …) — the first stage that writes the user's implementation files, gated by two reused floor mechanisms (no new primitive): check-plan-spec-agree.mjs (spec→plan hash chain re-verified at build time) and fix Add /pharn-eval orchestration and structural variance runner (increment 3c) #7 writes-scope (set-writes-scope.cjs --from-plan + enforce-writes-scope.cjs).
  • Document the increment under .dev/features/build-stage/ (PLAN, GRILL audit trail, regression report showing no regressions vs main).
  • Add a hook test pinning fail-closed behavior when --from-plan receives a PLAN with no parseable ## Files heading (the /pharn-plan ## Steps / Files gap).

Test plan

  • npm test — new --from-plan fail-closed test passes; no hook regressions
  • node .dev/floor/validate.mjs . — GREEN (floor capability count stays 1)
  • /pharn-dev-regressregression-report.json verdict no-regressions
  • Human review: P0 guarantee-audit wording (floor verdict vs advisory obey) and the documented ## Files scope-source gap / plan-files-scope follow-up

Made with Cursor

Summary by CodeRabbit

  • New Features
    • Added a build-stage workflow that produces scoped advisory build records and added supporting stage documentation.
    • Expanded the verification gate set to include style checks.
  • Bug Fixes
    • Enforced fail-closed behavior when plans lack a parseable ## Files scope.
    • Strengthened writes-scope derivation from plan ## Files and added coverage for invalid/placeholder inputs.
  • Documentation
    • Added/updated build, verify, regression, review, ship, and audit logs clarifying floor vs advisory outcomes and verification meaning.

Introduce the product build stage (hash-chain re-check + fix #7 writes-scope)
with build-loop audit trail and a fail-closed --from-plan scope test.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8dc477e-5741-4960-9522-13e8345c6447

📥 Commits

Reviewing files that changed from the base of the PR and between 5a4eaed and 9d09315.

📒 Files selected for processing (29)
  • .claude/commands/pharn-build.md
  • .claude/commands/pharn-dev-verify.md
  • .claude/commands/pharn-plan.md
  • .claude/hooks/set-writes-scope.test.cjs
  • .dev/features/build-caveat-sync/GRILL.md
  • .dev/features/build-caveat-sync/PLAN.md
  • .dev/features/build-caveat-sync/REGRESSION.md
  • .dev/features/build-caveat-sync/REVIEW.md
  • .dev/features/build-caveat-sync/SHIP.md
  • .dev/features/build-caveat-sync/VERIFY.md
  • .dev/features/build-caveat-sync/regression-report.json
  • .dev/features/build-caveat-sync/verify-report.json
  • .dev/features/plan-files-scope/GRILL.md
  • .dev/features/plan-files-scope/PLAN.md
  • .dev/features/plan-files-scope/REGRESSION.md
  • .dev/features/plan-files-scope/REVIEW.md
  • .dev/features/plan-files-scope/SHIP.md
  • .dev/features/plan-files-scope/VERIFY.md
  • .dev/features/plan-files-scope/regression-report.json
  • .dev/features/plan-files-scope/verify-report.json
  • .dev/features/verify-style-gates/GRILL.md
  • .dev/features/verify-style-gates/PLAN.md
  • .dev/features/verify-style-gates/REGRESSION.md
  • .dev/features/verify-style-gates/REVIEW.md
  • .dev/features/verify-style-gates/SHIP.md
  • .dev/features/verify-style-gates/VERIFY.md
  • .dev/features/verify-style-gates/regression-report.json
  • .dev/features/verify-style-gates/verify-report.json
  • .dev/memory-bank/lessons-learned.md
✅ Files skipped from review due to trivial changes (17)
  • .dev/features/build-caveat-sync/verify-report.json
  • .dev/features/plan-files-scope/REGRESSION.md
  • .dev/features/build-caveat-sync/VERIFY.md
  • .dev/features/plan-files-scope/regression-report.json
  • .dev/features/build-caveat-sync/GRILL.md
  • .dev/features/plan-files-scope/verify-report.json
  • .dev/features/build-caveat-sync/REGRESSION.md
  • .dev/features/verify-style-gates/verify-report.json
  • .dev/features/verify-style-gates/regression-report.json
  • .dev/features/build-caveat-sync/regression-report.json
  • .dev/features/build-caveat-sync/REVIEW.md
  • .dev/features/verify-style-gates/REVIEW.md
  • .dev/features/verify-style-gates/PLAN.md
  • .dev/features/plan-files-scope/VERIFY.md
  • .dev/features/plan-files-scope/REVIEW.md
  • .dev/features/plan-files-scope/GRILL.md
  • .dev/features/build-caveat-sync/PLAN.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .claude/commands/pharn-build.md

📝 Walkthrough

Walkthrough

Adds build-stage command and verification docs, restructures /pharn-plan output for parseable writes-scope extraction, updates a build-caveat doc to match that behavior, and expands /pharn-dev-verify with format:check and lint:md gates plus related reports and review records.

Changes

Pipeline command and scope docs

Layer / File(s) Summary
Build-stage command and gates
.claude/commands/pharn-build.md, .dev/features/build-stage/*
Defines /pharn-build, its hash-chain and writes-scope enforcement, step sequence, and the build-stage advisory and machine-readable reports.
/pharn-plan template and writes-scope test
.claude/commands/pharn-plan.md, .claude/hooks/set-writes-scope.test.cjs, .dev/features/plan-files-scope/*
Restructures /pharn-plan into parseable ## Files output and adds regression coverage for parsing, exclusion handling, and fail-closed behavior.
Build-caveat doc sync
.dev/features/build-caveat-sync/*
Updates the build-caveat documentation to match the current /pharn-plan ## Files behavior while preserving the existing fail-closed build-stage framing.
Verify gate expansion
.claude/commands/pharn-dev-verify.md, .dev/features/verify-style-gates/*, .dev/memory-bank/lessons-learned.md
Expands /pharn-dev-verify to include format:check and lint:md, and records the related plan, review, regression, ship, verify, and lesson updates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • pharn-dev/pharn-oss#19: Shares the same set-writes-scope.cjs fail-closed test surface and writes-scope enforcement path.
  • pharn-dev/pharn-oss#20: Updates the /pharn-plan template contract that this PR further tightens for downstream scope extraction.
  • pharn-dev/pharn-oss#21: Uses the same spec↔plan hash-chain gate that /pharn-build re-checks here.

Poem

🐇 I hop through plans with tidy paws,
And sniff for ## Files without a pause.
Build stays fenced, and verify sings,
While style gates twinkle in little rings.
No drift, no guess, just paths in line—
A carrot-bright pipeline feels divine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Several docs and gate updates (build-caveat-sync, verify-style-gates, memory-bank) extend beyond the build-stage and plan-scope objectives. Split the unrelated follow-on docs and gate changes into separate PRs, or expand the PR objective to explicitly cover them.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding /pharn-build and related scope gates.
Linked Issues check ✅ Passed The build-stage work reuses existing mechanisms and stays fail-closed on invalid inputs, matching the applicable goals from [#7].
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch build-stage

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Complete the build-loop pipeline artifacts for the /pharn-build increment
and apply minor markdownlint/grill follow-up formatting fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 @.dev/features/build-stage/PLAN.md:
- Around line 78-79: The “no parseable scope → refuse” entry in the build-stage
plan is mislabeling the floor boundary by attributing fail-closed behavior to
both the setter and /pharn-build. Update the wording in the PLAN.md section so
the unique symbol set from set-writes-scope.cjs is the actual floor signal (exit
1), and describe /pharn-build as advisory orchestration that obeys it rather
than the floor itself. Keep the two-clocks distinction explicit and align this
line with the other floor/advisory terminology used in the build-stage docs.

In @.dev/features/build-stage/VERIFY.md:
- Line 23: The verifier count output description is using a stale field name and
must be aligned with the authoritative JSON shape. Update VERIFY.md to match the
actual output from count-verifiers.mjs and verify-report.json, using the same
key name consistently (either verifiers or findings), and reference the
count-verifiers.mjs output text so the documented example reflects the real
producer format.
🪄 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: 068e8a96-79d9-4ba6-b48f-12de857331dd

📥 Commits

Reviewing files that changed from the base of the PR and between 61b79df and 5a4eaed.

📒 Files selected for processing (10)
  • .claude/commands/pharn-build.md
  • .claude/hooks/set-writes-scope.test.cjs
  • .dev/features/build-stage/GRILL.md
  • .dev/features/build-stage/PLAN.md
  • .dev/features/build-stage/REGRESSION.md
  • .dev/features/build-stage/REVIEW.md
  • .dev/features/build-stage/SHIP.md
  • .dev/features/build-stage/VERIFY.md
  • .dev/features/build-stage/regression-report.json
  • .dev/features/build-stage/verify-report.json

Comment on lines +78 to +79
- the build record `features/<name>/BUILD.md` is itself fix #7-scoped (Phase-2 `--from-frontmatter … --target`) → **floor: hook (fix #7)**; its **content** (the advisory roll-up) is model work, never a self-issued "correct" / seal → **advisory** (the §6 ship-stage seal is the human's GATE-2 decision, not `/pharn-build`'s).
- no parseable scope → refuse → **floor: fail-closed** (`set-writes-scope.cjs` exit 1; `/pharn-build` refuses rather than fall through to the hook's absent-scope default-safe-set).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The "floor: fail-closed" label overstates the floor boundary.

The setter's exit 1 is floor, but /pharn-build's refusal to stop is advisory command orchestration (the two-clocks split). The GRILL.md finding correctly notes this is unlabeled here. Consider: no parseable scope → refuse → **floor signal: setter exit 1**; **advisory: command obeys it** to match the two-clocks discipline applied elsewhere.

🤖 Prompt for 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.

In @.dev/features/build-stage/PLAN.md around lines 78 - 79, The “no parseable
scope → refuse” entry in the build-stage plan is mislabeling the floor boundary
by attributing fail-closed behavior to both the setter and /pharn-build. Update
the wording in the PLAN.md section so the unique symbol set from
set-writes-scope.cjs is the actual floor signal (exit 1), and describe
/pharn-build as advisory orchestration that obeys it rather than the floor
itself. Keep the two-clocks distinction explicit and align this line with the
other floor/advisory terminology used in the build-stage docs.


## ADVISORY layer — verifiers

**No verifiers registered — floor gates only.** `node .dev/floor/count-verifiers.mjs .` → `{"registered":0,"verifiers":[]}` (deterministic frontmatter membership over `role: verifier`, never a prose grep — P5). Step 2 is a no-op; the verdict is the floor gates alone. No verifier was authored speculatively (P7).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Inconsistent field name in verifier count output description.

VERIFY.md claims count-verifiers.mjs outputs {"registered":0,"verifiers":[]}, but verify-report.json uses "findings":[] (not "verifiers":[]). If the report is authoritative, the prose has a stale field name; if count-verifiers.mjs truly emits "verifiers", then verify-report.json has a mismatch with its upstream producer. Align one to the other.

🤖 Prompt for 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.

In @.dev/features/build-stage/VERIFY.md at line 23, The verifier count output
description is using a stale field name and must be aligned with the
authoritative JSON shape. Update VERIFY.md to match the actual output from
count-verifiers.mjs and verify-report.json, using the same key name consistently
(either verifiers or findings), and reference the count-verifiers.mjs output
text so the documented example reflects the real producer format.

PrzemekGalarowicz and others added 4 commits June 30, 2026 20:05
Close the spec→plan→grill→build chain. /pharn-build derives its fix #7
writes-scope via set-writes-scope.cjs --from-plan, which needs a `## Files`
heading with back-tick paths; /pharn-plan emitted a free-text `## Steps /
Files` instead, so a stock product PLAN failed-closed and the product
pipeline could not build end-to-end (the #22-named `plan-files-scope`
follow-up).

- .claude/commands/pharn-plan.md: split the Step-4 PLAN template's
  `## Steps / Files` into an advisory `## Steps` + a parseable `## Files`
  (leading back-tick paths, angle-bracket placeholders that fail closed
  when unfilled, an `### Explicitly not touched` subsection), with guidance
  citing the set-writes-scope.cjs --from-plan contract + ARCHITECTURE §6 (P4).
- .claude/hooks/set-writes-scope.test.cjs: add the closing-the-loop test
  (a filled /pharn-plan-shaped plan → exit 0, scope = exactly the `## Files`
  paths, exclusion/steps-prose paths absent) and a producer-faithfulness
  test (the real pharn-plan.md template → exit 1, locking the placeholder
  discipline against a bare-word regression).

Reuses set-writes-scope.cjs + the fix #7 hooks unchanged (the producer is
matched to the parser, not the reverse). No new floor primitive. Floor
GREEN (1 capability); npm test 165; npm run check green.

Gated /pharn-dev-ship run; audit trail under .dev/features/plan-files-scope/
(PLAN/GRILL/REGRESSION/VERIFY/REVIEW/SHIP + reports): regress no-regressions;
verify PASS (6 gates); review GREEN (0 floor-gate findings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…es /regress + /verify) to canon

L9 records the gate-coverage gap surfaced by the plan-files-scope dogfood: an
increment's own markdown style is gated by neither /pharn-dev-regress (style gates
skip absent a shared-config change) nor /pharn-dev-verify's canonical gate map
(test/validate/lint/structural) — so it can redden `npm run check` yet pass both
stages. Remedy recorded: add format:check + lint:md to /pharn-dev-verify's gate map.

Promoted via gated /pharn-dev-memory-promote: check-provenance GREEN (valid
provenance, id L9 unique), human-accepted. Provenance points at a5de975.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… gate map (L9 remedy)

Implement L9's remedy: /pharn-dev-verify's canonical FLOOR gate set now includes
format:check + lint:md, so the verify verdict tracks the full `npm run check` and
closes L9's style-gate coverage hole AT VERIFY (an increment's own markdown style is
caught at verify, not only at the full npm run check / CI).

check-verify.mjs is UNCHANGED — it is generic over gate keys, so this is a pure
command-prose widening of .claude/commands/pharn-dev-verify.md (Step-1 gate runs +
results map + the gate enumeration + granularity/devDeps/Live-integration notes + a
new advisory-orchestration bullet + the verify-report.json example). No new floor
primitive; no new test (OQ1: P7 — check-verify is generic + already tested; the
gate-set lives in advisory command prose, labelled honestly, not floor-locked).
/pharn-dev-regress untouched.

Gated /pharn-dev-ship run; the verify stage was a DOGFOOD (the new six-gate set ran,
all exit 0). Audit trail under .dev/features/verify-style-gates/: regress
no-regressions; verify PASS; review GREEN (0 floor-gate findings, 1 advisory residual
the increment names itself, no new lesson — it is L5 applied).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Doc-sync: the Step-0 "Scope-source caveat (a current, honest limit — LIMITS.md)" in
pharn-build.md described /pharn-plan's free-text `## Steps / Files` as current and the
plan-files-scope follow-up as pending — both stale since plan-files-scope landed
(a5de975: /pharn-plan now emits a parseable `## Files`).

- Rewrote the block to "Scope-source note (resolved — plan-files-scope)": /pharn-plan
  now emits a parseable `## Files`; PRESERVED the fail-closed point — a malformed/
  incomplete plan with no parseable `## Files` still makes /pharn-build refuse rather
  than guess a scope (correct, not a bug).
- Re-anchored the inline example from "## Steps / Files" to a malformed/hand-written
  plan generally.
- Dropped the now-pointless LIMITS.md reference (grill finding: LIMITS.md carries no
  matching entry to keep in sync).

Pure prose, no behavioral change, no new floor primitive, no test (P7). Grep confirmed
pharn-build.md was the only file still calling plan-files-scope a pending follow-up.

Gated /pharn-dev-ship run; audit under .dev/features/build-caveat-sync/: regress
no-regressions; verify PASS (6 gates); review GREEN (0 findings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@PrzemekGalarowicz PrzemekGalarowicz deleted the build-stage branch June 30, 2026 18:50
@PrzemekGalarowicz PrzemekGalarowicz restored the build-stage branch June 30, 2026 18:50
@PrzemekGalarowicz PrzemekGalarowicz merged commit 31fcefb into main Jun 30, 2026
9 of 10 checks passed
@PrzemekGalarowicz PrzemekGalarowicz deleted the build-stage branch June 30, 2026 18:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant