Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .claude/commands/pharn-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ There is **no `--yolo`** and no self-approving mode — see "What `/pharn-loop`
slug.
- **`--max-iter N`** sets the cap `M` (a positive integer). **Absent ⇒ default `M = 3`.** The cap is the
deterministic bound; `check-loop.mjs` enforces it structurally (`iter >= cap` → `STOP_CAP`). A config-file
cap key (`pharn.config.json`) is **deferred** (P7 — no project config consumer exists yet; the floor bound
is identical either way).
cap key (`pharn.config.json`) is **deferred** (P7 — no real need has surfaced, and the floor bound is
identical either way: `check-loop.mjs` reads `--cap`, whatever set it). Note the deferral rests on P7
alone, **not** on the absence of a config consumer — `/pharn-build` already reads the `seam` block and
`/pharn-ship` reads `ship.requireAttestation` from that file.

### Step 1b — read the PRIOR record for this slug, if one exists (context only; it gates NOTHING)

Expand Down
6 changes: 4 additions & 2 deletions .claude/commands/pharn-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,10 @@ chain to `/pharn-grill` or `/pharn-build` (later stages). **End your turn.**
`enforce-writes-scope.cjs` pin the one declared path).
- **"The plan carries `spec_content_hash` forward"** → a **deterministic copy** of a floor-verified
value into the PLAN.md frontmatter — checkable in principle; **not** independently floor-checked at
this stage (the consumer that re-verifies spec↔plan is a later stage, not built yet — P7). Honest
label: deterministic, not yet re-verified.
this stage. The consumer that re-verifies spec↔plan is a later stage and **is built**:
`pharn/floor/check-plan-spec-agree.mjs`, run by `/pharn-grill` (the first re-verifier), then again by
`/pharn-build`, `/pharn-regress` and `/pharn-verify`. Honest label: deterministic, **not re-verified at
THIS stage** — the pin is checked downstream, never here.
- **"The plan's CONTENT is correct / complete"** → **ADVISORY**. Model judgment; downstream
grill / build / verify check it. Claiming `/pharn-plan` "ensures a correct plan" would be the disease —
struck.
Expand Down
4 changes: 3 additions & 1 deletion .claude/commands/pharn-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ scanner binding, consistency-tested by `lens-scanner-map.test.mjs`):
target** (an honestly-labeled advisory bound, not a floor claim).

The scanner's **output** is FLOOR (a deterministic regex verdict); using it to **choose the slice** is
**advisory orchestration** (the isolated per-lens runner is deferred, P7 — as for every lens today).
**advisory orchestration** — nothing on the floor forces the slice to be derived this way, or at all.
(The isolated per-lens runner itself is **not** deferred: Step 4 below spawns one subagent per lens. The
per-GRILLER runner remains deferred, P7 — `/pharn-grill` applies a griller inline.)

## Step 3b — Discover the user's installed skills (ADVISORY context for the lenses; enumeration gates nothing)

Expand Down
9 changes: 8 additions & 1 deletion .claude/commands/pharn-ship.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Run the PRODUCT pipeline in order so a PHARN user need not re-type or memorize it: /pharn-spec → [human approves the SPEC] → /pharn-plan → /pharn-grill → /pharn-build → /pharn-regress → /pharn-verify → [human decides merge/fix/abandon]. The seventh, terminal pipeline stage (pharn/ARCHITECTURE.md §6), realized as a GATED meta-orchestrator over stages 1–6 — the agent INVOKES each stage (advisory); WHETHER to proceed past a stage is read from that stage's STRUCTURAL floor verdict (check-spec-approved / check-plan-spec-agree exits, the build project-gate exit, regression-report.json .verdict, verify-report.json .verdict), NEVER the agent's judgment. Reuses the six product stage commands and their existing floor checkers; reimplements none. Two human gates — SPEC approval (Draft→Approved) and the post-verify decision — are NON-NEGOTIABLE; NO --yolo, NO self-approval. Gated mode with at most ONE bounded build-completion retry on an INCOMPLETE verify (Step 2b — a single re-build, NOT a loop; the ≤1 bound is structural, the firing reads /pharn-verify's deterministic INCOMPLETE verdict); --loop is still a separate follow-up increment. At GATE 2 (Step 2c), also renders `features/<name>/BRIEFING.md` — a deterministic, cross-file-verified 'what/why/does-it-match' summary assembled by pharn/floor/render-ship-briefing.mjs from committed sources (never a self-issued seal, never a GATE-2 precondition; see pharn/pharn-contracts/ship-briefing.md). FLOOR verdicts; ADVISORY orchestration. '/pharn-ship reached the end' NEVER means 'the feature is good' — it means the deterministic gates passed and the human approved intent (P0)."
description: "Run the PRODUCT pipeline in order so a PHARN user need not re-type or memorize it: /pharn-spec → [human approves the SPEC] → /pharn-plan → /pharn-grill → /pharn-build → /pharn-regress → /pharn-verify → [human decides merge/fix/abandon]. The seventh, terminal pipeline stage (pharn/ARCHITECTURE.md §6), realized as a GATED meta-orchestrator over stages 1–6 — the agent INVOKES each stage (advisory); WHETHER to proceed past a stage is read from that stage's STRUCTURAL floor verdict (check-spec-approved / check-plan-spec-agree exits, the build project-gate exit, regression-report.json .verdict, verify-report.json .verdict), NEVER the agent's judgment. Reuses the six product stage commands and their existing floor checkers; reimplements none. Two human gates — SPEC approval (Draft→Approved) and the post-verify decision — are NON-NEGOTIABLE; NO --yolo, NO self-approval. Gated mode with at most ONE bounded build-completion retry on an INCOMPLETE verify (Step 2b — a single re-build, NOT a loop; the ≤1 bound is structural, the firing reads /pharn-verify's deterministic INCOMPLETE verdict); --loop is still a separate follow-up increment (the bounded auto-iteration capability itself ships today as the separate /pharn-loop command). At GATE 2 (Step 2c), also renders `features/<name>/BRIEFING.md` — a deterministic, cross-file-verified 'what/why/does-it-match' summary assembled by pharn/floor/render-ship-briefing.mjs from committed sources (never a self-issued seal, never a GATE-2 precondition; see pharn/pharn-contracts/ship-briefing.md). FLOOR verdicts; ADVISORY orchestration. '/pharn-ship reached the end' NEVER means 'the feature is good' — it means the deterministic gates passed and the human approved intent (P0)."
kind: pharn-owned
trust: trusted
model_tier: sonnet
Expand Down Expand Up @@ -485,6 +485,13 @@ Then **end your turn** at the human gate. `/pharn-ship` does not merge, push, or

## `/pharn-ship --loop` — deferred to a separate increment (NOT built here)

> **The capability is NOT unavailable — it is a different command.** `/pharn-loop`
> (`.claude/commands/pharn-loop.md`) **is built** and iterates the product pipeline's
> `build → regress → verify` middle to a floor-grade stop, with both human gates preserved. What does not
> exist is a **`--loop` flag on `/pharn-ship`**. Reach for `/pharn-loop` when you want bounded
> auto-iteration; its stop core is the tested `pharn/floor/check-loop.mjs` (Design B, retryable-only —
> it CONTINUEs only on `/pharn-verify`'s `INCOMPLETE`), **not** `check-ship.mjs`.

`--loop` (iterate `build → regress → verify` to a floor-grade stop, then present) is a **separate follow-up
increment** — the same split `/pharn-dev-ship` used (gated first, `--loop` second). It is **not** part of this
command. When built, it would reuse the **already-existing, tested** `pharn/floor/check-ship.mjs` stop core
Expand Down
113 changes: 113 additions & 0 deletions .dev/features/forward-looking-claims-sweep/GRILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# GRILL — forward-looking-claims-sweep

Advisory interrogation of the approved `PLAN.md` before `/pharn-dev-build`. **This stage gates
nothing** (`grill.md`) — it surfaces concerns; the build proceeds regardless. Findings below use the
enum-gated / free-text split (`pharn/pharn-contracts/finding-shape.md`, cited not restated — P4).

## Verdict

**PROCEED.** Four findings, all resolved or converted into build constraints before the build ran.
No finding invalidates the plan's enumeration; one (G2) independently **strengthens** its largest
class.

---

## G1 — the plan's `## Files` omits `docs/capabilities/**`, and the risk is real but does not bite

- type: `gap`
- rule_id: `CLAUDE.md docs:check`
- severity: `advisory`
- file: `.dev/features/forward-looking-claims-sweep/PLAN.md`

**problem** (free-text, untrusted): `docs/capabilities/**` is a GENERATED region guarded by
`npm run docs:check` at byte-equality, and it renders **37** pages including a page for every lens
and griller this increment edits. The plan's `## Files` names none of them. If the catalog embedded
body prose, all 31 edits would drift the catalog and RED the `docs:check` gate — with the writes-scope
simultaneously denying the regeneration write.

**evidence**: `docs/capabilities/` contains 37 files (`a11y.md`, `copy-paste-drift.md`,
`injection.md`, …). `head -20 docs/capabilities/injection.md` shows the rendered page carries
**frontmatter fields only** — Role / Kind / Version / Applies / Coupling / Enforces / Model tier —
plus the one-line `purpose`, and is 23 lines total.

**resolution**: `grep -rl "isolated lens runner|runner yet invokes" docs/` returns **nothing**. The
catalog does not render body prose, so body-only edits cannot drift it.

**Converted into a BUILD CONSTRAINT:** every edit in this increment must stay **below the
frontmatter fence**. Touching `purpose:` or any rendered field turns G1 from theoretical into a RED.
`npm run docs:check` is run at the end regardless (it is inside `npm run check`), so the constraint
is verified, not merely intended.

---

## G2 — Class A's premise was single-sourced; a second independent witness now confirms it

- type: `unstated-assumption`
- rule_id: `P6`
- severity: `advisory`
- file: `.dev/features/forward-looking-claims-sweep/PLAN.md`

**problem** (free-text, untrusted): Class A (20 sites — the largest in the increment) rests on the
claim "the isolated lens runner landed." The plan evidenced this from **one** file — `pharn-review.md`
Step 4. If "the review stage" in the lens prose meant `/pharn-dev-review` rather than `/pharn-review`,
and `/pharn-dev-review` applied the 22 lenses inline, the lens sentences would be **correct** and
Class A would be a 20-file over-edit — by far the worst outcome available in this increment.

**evidence**: `.claude/commands/pharn-dev-review.md:109-110` states directly: _"the
`pharn/pharn-review/*` **code** lenses over a code increment … use **`/pharn-review`** — it runs them
as parallel subagents and merges deterministically (`count-lenses` + …)"_.

**resolution**: **CONFIRMED, from the opposite direction.** `/pharn-dev-review` does **not** apply the
22 lenses; it explicitly delegates them to `/pharn-review`, and describes that command as running them
as parallel subagents. So both candidate readings of "the review stage" agree the isolated runner
exists. Class A stands on two independent witnesses.

---

## G3 — the lens/griller prose has multiple spellings; a blanket replace would be the L33 defect again

- type: `risk`
- rule_id: `L33`
- severity: `advisory`
- file: `pharn/pharn-review/`

**problem** (free-text, untrusted): The plan states the classes but not the **edit method**. The
26 body edits (19 lenses + 7 grillers) are near-duplicates, which invites a scripted
find-and-replace. That is precisely how this defect class propagates: `coupling` already proves the
spelling varies (`no **live** runner yet invokes it`), and the griller class has at least three
distinct phrasings. A single replacement string would silently skip the variants — reproducing L33
inside L33's own remedy.

**resolution / BUILD CONSTRAINT**: each of the 26 files is **read and edited individually** against
its own wording. After the build, a re-scan with the same whitespace-normalized scanner must report
**zero** surviving sites in Classes A–F — a post-condition, not an intention.

---

## G4 — "no floor check" is a P7 judgment the plan argues but cannot discharge

- type: `unresolved-tension`
- rule_id: `L20`
- severity: `advisory`
- file: `.dev/features/forward-looking-claims-sweep/PLAN.md`

**problem** (free-text, untrusted): L20's trigger has fired — this class recurred, inside the
increment that named it. The plan declines the checker on P7 grounds (the manifest is a separate axis
of change) and records `forward-looking-claims-manifest` as a follow-up. That reasoning is sound but
**self-issued**: the same argument would justify deferring the checker indefinitely, one increment at
a time. Nothing structural forces the follow-up to ever land.

**Not resolvable at this stage, and deliberately not resolved.** It was surfaced to the human at
GATE 1 with an explicit offer to re-plan and fold the checker in; the human approved the plan as
written. Recorded here so the deferral is auditable rather than invisible — and so the second
recurrence, if it comes, has this note to point at.

---

## What this grill did NOT check

- Whether each of the 31 rewritten sentences is **true**. That is `/pharn-dev-verify`'s floor gates
and `/pharn-dev-review`'s lenses, and ultimately the human's — a grill reads the plan, not the diff.
- Whether the enumeration is **complete**. G3 constrains the method and adds a post-condition
re-scan, but a claim spelled in a way no pattern anticipated survives both. The plan's own
guarantee audit states this; the grill confirms it is stated, not that it is solved.
Loading