-
Notifications
You must be signed in to change notification settings - Fork 0
fix(docs): document Mode-B ## Files exclusion-cue caveat in /pharn-plan #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # GRILL — f13-modeb-cue | ||
|
|
||
| Plan under interrogation: `.dev/features/f13-modeb-cue/PLAN.md` (option A, approved by the human at | ||
| GATE 1). Spec-hash check: **MATCH** — `sha256(pharn/ARCHITECTURE.md)` recomputed live as | ||
| `8f5ec002e3b18cbfd2f094b08a3671f7ed42a05a3fbaf01a11bbbd28da30fb52`, identical to the plan's | ||
| `spec_content_hash`. No drift; `/pharn-dev-build`'s floor-gate (fix #4) will pass this check too. | ||
|
|
||
| Griller discovery (`node pharn/floor/count-grillers.mjs .`): 13 `role: griller` capabilities | ||
| registered (a11y, architecture, comprehension, coupling, documentation, error-handling, i18n, | ||
| migrations, observability, performance, privacy, security, testability). This increment adds no | ||
| application code (no SSR/SPA/backend surface), so the `applies: ["ssr","spa"]` (a11y, i18n) and | ||
| `applies: ["backend","ssr"]` (migrations) grillers have no target to interrogate — their axis does not | ||
| exist for a `.claude/commands/*.md` prose edit, and running them would manufacture findings against | ||
| nothing. The `applies: ["universal"]` grillers were interrogated against the plan below, keyed by the | ||
| principle each `enforces`. | ||
|
|
||
| ## Findings | ||
|
|
||
| ```yaml | ||
| - type: FINDING | ||
| rule_id: "P5" | ||
| severity: minor | ||
| file: ".dev/features/f13-modeb-cue/PLAN.md (build-prompt provenance, not a PLAN.md line)" | ||
| problem: "The build prompt's 'Write procedure' step for option (A) says to scope with `set-writes-scope.cjs --from-frontmatter <scratch> --allow-claude-dir` for `.claude/commands/pharn-plan.md`, but `--allow-claude-dir` is only required for CONTROL_SURFACE entries (`.claude/settings.json`, `.claude/settings.local.json`, and the three hook scripts) — `.claude/commands/pharn-plan.md` is not one of them, and the setter's header states command files are deliberately exempt from the opt-in flag." | ||
| evidence: "'set a writes-scope with set-writes-scope.cjs --from-frontmatter <scratch> --allow-claude-dir for .claude/commands/pharn-plan.md, CHANGELOG.md, SKILLS_VERSION'" | ||
| ``` | ||
|
|
||
| Non-blocking: harmless if followed literally (the flag is simply a no-op when no CONTROL_SURFACE path | ||
| is in scope), and moot under `/pharn-dev-ship`/`/pharn-dev-build` regardless — `/pharn-dev-build`'s own | ||
| Step 0 scopes from the approved `PLAN.md`'s `## Files` via `--from-plan`, which already authorizes | ||
| exactly `.claude/commands/pharn-plan.md`, `CHANGELOG.md`, and `SKILLS_VERSION` with no flag needed. | ||
| Flagged only so the human isn't surprised if they later run the manual procedure by hand outside | ||
| `/pharn-dev-ship`. | ||
|
|
||
| No other findings. Specifically checked and clean: | ||
|
|
||
| - **P0 (guarantee-audit completeness):** every claim in the plan's Guarantee audit section either | ||
| names a floor primitive (`check-version-badge.mjs`'s narrowed scope, `set-writes-scope.test.cjs` | ||
| unchanged-and-green) or is explicitly labeled `advisory` (the caveat's prose guidance). Nothing reads | ||
| as a guarantee without a reduction. | ||
| - **P1 (eval coverage):** correctly scoped as not applicable — `/pharn-plan.md` is a command doc, not a | ||
| `role:`-bearing Capability (`pharn/ARCHITECTURE.md §3.1`), so P1's per-Capability eval requirement does | ||
| not attach to it. No new `rule_id` is introduced by this increment for a testability griller to check | ||
| binding on. | ||
| - **P2 (trust propagation):** correctly marked not applicable — no untrusted artifact is ingested by | ||
| the increment's own work (the build prompt's task description contains no instruction-looking content | ||
| beyond ordinary prose). | ||
| - **P3 (one axis of change / no sibling imports):** the three touched files (`pharn-plan.md`, | ||
| `CHANGELOG.md`, `SKILLS_VERSION`) are one coherent change-reason (documenting a caveat + its mandatory | ||
| version/changelog bookkeeping under this repo's own SKILLS_VERSION discipline) — not two unrelated | ||
| reasons bundled. No sibling-module reference is introduced; a command doc is not part of the | ||
| `pharn-contracts` layer tree. | ||
| - **P5 (determinism):** both prior open questions (option A vs B; the 2.5.1-vs-2.5.2 version-base | ||
| discrepancy) were resolved by asking the human at GATE 1, not guessed. The plan's own remaining | ||
| branches (which file gets which edit) are fixed, not classified. | ||
| - **P7 (honest scope / no speculation):** the plan explicitly excludes touching | ||
| `set-writes-scope.cjs` (option B) and `pharn-dev-plan.md` (no parity edit requested by the build | ||
| prompt) under `### Explicitly not touched`, with reasons — the smallest coherent increment, not two | ||
| bundled. The lesson L18 citation is genuinely on-point (same code path, adjacent failure mode), not a | ||
| padded citation. | ||
| - **Architecture/coupling axis:** no new module, no layer crossing; a `.claude/commands/*.md` edit is | ||
| outside `pharn/ARCHITECTURE.md §4`'s capability layer tree entirely, so there is nothing to couple. | ||
| - **Security/privacy axis:** no secret, credential, or PII-shaped content is added or handled; the | ||
| caveat text is pure process documentation. | ||
| - **Documentation/comprehension axis:** the plan's stated placement (after rule 3, before the closing | ||
| `## Steps` sentence, in the existing "Three rules keep it parseable" blockquote) keeps the new caveat | ||
| co-located with the rules it qualifies, and the plan separately calls out correcting the adjacent | ||
| "only back-tick paths become the build's scope" sentence so the new caveat doesn't read as | ||
| contradicting it — a comprehension-griller-shaped concern the plan already anticipated and handled. | ||
|
|
||
| ## Summary | ||
|
|
||
| The plan is narrowly scoped, cites a genuinely relevant lesson (L18) with a substantive rather than | ||
| decorative explanation of the connection, and its guarantee audit is honest about what is advisory | ||
| (the prose caveat) versus what reduces to floor (the unchanged hook, checked by the unmodified test | ||
| suite). The single finding above is a minor discrepancy in the build prompt's own suggested | ||
| write-procedure command, not in the plan; it does not affect what `/pharn-dev-build` will actually do | ||
| under `/pharn-dev-ship`, where scope is set programmatically from the plan's `## Files`, not by hand. | ||
|
|
||
| **ADVISORY VERDICT: 1 concern raised (0 blocking-severity, 1 minor) — for the human to weigh before | ||
| `/pharn-dev-build`. This is advisory input, not a gate; `/pharn-dev-build`'s own floor-gates (spec-hash | ||
| re-check, fix #4; writes-scope, fix #7) are what actually enforce anything here.** | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # PLAN — F13: document the Mode-B `## Files` exclusion-cue caveat | ||
|
|
||
| - spec_content_hash: 8f5ec002e3b18cbfd2f094b08a3671f7ed42a05a3fbaf01a11bbbd28da30fb52 | ||
| - applied_lessons: [L18] | ||
| - increment: Document, in `/pharn-plan.md`'s `## Files` contract blockquote, that a bare non-blockquote prose line under `## Files` containing exclusion-style wording (`not touch/writ/modif/edit/chang`, `explicitly excluded`, `out of scope`, `off limits`) truncates the authorized list at that line — and tell the author to use a blockquote, a path-item description, or the `### Explicitly not touched` heading instead. No code change to `set-writes-scope.cjs`. | ||
| - layer(s): `.claude/` product command surface (not a `pharn-contracts` layer — a command doc, per `pharn/ARCHITECTURE.md §4`'s command/hook split) | ||
| - constitution_refs: [P0, P5, P6, P7] | ||
|
|
||
| ## Applied lessons | ||
|
|
||
| - L18 — L18 established that Boundary 1 (a real markdown heading) is the structural, wording-independent mechanism for a PLAN's exclusion block, and that the free-text Boundary-2 cue's vocabulary is deliberately narrow (so a differently-worded real exclusion can miss it and fail OPEN). That is the exact asymmetry this increment weighs: narrowing the cue to stop today's false-positive (an innocent sentence, fail-CLOSED) risks recreating L18's fail-OPEN failure mode for a real exclusion phrased outside the narrowed pattern. L18's own remedy was "use the heading form" — which is precisely what this increment tells the author to do, in the one place (`/pharn-plan.md`'s `## Files` blockquote) an author reads before writing a plan. This confirms option (A) — document and steer authors to the heading — over option (B) — narrow the regex — because (B) is the code-side echo of the mistake L18 already showed is dangerous. | ||
|
|
||
| ## Files | ||
|
|
||
| - `.claude/commands/pharn-plan.md` — add a short caveat to the existing "`## Files` is the PARSEABLE writes-scope" blockquote (after rule 3, before the closing sentence about `## Steps`): a bare, non-blockquote prose line under `## Files` that reads like an exclusion truncates the authorized list at that line; put narrative in a blockquote or a path-item description, and use `### Explicitly not touched` for real exclusions. Also rephrases the blockquote's closing "only `## Files` back-tick paths become the build's scope" sentence so it does not read as "non-path lines are harmless." | ||
| - `CHANGELOG.md` — add an `[Unreleased]` entry under `### Fixed` (a doc clarification, framed honestly as such — no behavioral change) recording the caveat and the `SKILLS_VERSION` bump. | ||
| - `SKILLS_VERSION` — bump `2.5.2` → `2.5.3` (patch). | ||
| - `README.md` — update the shields version badge (line 13) from `pharn-2.5.2-blue` to `pharn-2.5.3-blue`, | ||
| so it agrees with the bumped `SKILLS_VERSION` (`.dev/floor/check-version-badge.mjs`'s live invariant). | ||
| Added after `/pharn-dev-regress` caught this omission as a real, deterministic regression | ||
| (`.dev/floor/check-version-badge.test.mjs`'s live self-check against this repo) — not a speculative | ||
| addition (P7): the failure was observed, not hypothesized. | ||
|
|
||
| ### Explicitly not touched | ||
|
|
||
| - `.claude/hooks/set-writes-scope.cjs` — reused as-is; Boundary 1 and Boundary 2 (including the exclusion-cue regex) are unchanged. This plan implements option (A) from the build prompt (document), not option (B) (narrow the regex). | ||
| - `.claude/hooks/set-writes-scope.test.cjs` — no behavior changed, so no new/updated assertions are required; existing tests continue to pass unmodified. | ||
| - `.claude/commands/pharn-dev-plan.md` — this command's own `## Files` template is simpler (no equivalent "Three rules" blockquote) and is not named by the build prompt's scope; out of scope for this increment (P7 — no speculative parity edit not triggered by a real failure). | ||
|
|
||
| ## Contracts satisfied | ||
|
|
||
| - No `pharn-contracts` schema is touched — this is a product-command documentation fix, not a Capability, contract, or floor checker change. `pharn/ARCHITECTURE.md §4`'s layer tree does not apply to `.claude/commands/*.md`; the relevant governing doc is CLAUDE.md's "SKILLS_VERSION discipline" (product-surface bump rules) and "Writes-scope" (fix #7) sections, cited not restated. | ||
|
|
||
| ## Evals to write (P1) | ||
|
|
||
| - None. `/pharn-plan.md` is a command doc, not a `role:`-bearing Capability (`pharn/ARCHITECTURE.md §3.1`), so P1's eval requirement does not apply. No `rule_id` is introduced. | ||
|
|
||
| ## Guarantee audit (P0) | ||
|
|
||
| - "The `## Files` blockquote now documents the exclusion-cue truncation behavior" → **advisory** (prose guidance for a human author; nothing on the floor enforces that an author reads or follows it). | ||
| - "The truncation _behavior itself_ is unchanged" → reduces to the existing floor: `set-writes-scope.cjs` Boundary 1 (structural heading match) and Boundary 2 (the unchanged regex cue) are untouched code, verified by re-running the existing `.claude/hooks/set-writes-scope.test.cjs` suite unmodified and green, plus a live re-run of the repro command from the build prompt showing identical output before and after this change. | ||
| - "`SKILLS_VERSION` correctly reflects that product-surface bytes changed" → **floor, narrowed**: `.dev/floor/check-version-badge.mjs` only checks the README badge agrees with `SKILLS_VERSION`; it does not check that a bump was _warranted_ — that judgment is CLAUDE.md's bump-discipline rules, applied here by hand (a `.claude/commands/*.md` non-`pharn-dev-` file is bump-triggering product surface per CLAUDE.md). | ||
|
|
||
| ## Trust audit (P2) | ||
|
|
||
| Not applicable — no untrusted artifact is ingested by this increment. The build prompt (this plan's own input) is treated as `trust: untrusted` per `/pharn-dev-plan`'s standing instruction, but it contains no instruction-looking content beyond ordinary task description; nothing in it is executed as a directive outside the human-gated plan/build/review loop. | ||
|
|
||
| ## Open questions (HALT) | ||
|
|
||
| - Confirm the resolution: option (A) document-only (recommended by the build prompt and reinforced by L18) vs option (B) narrow the regex. This plan is drafted for (A); if the human selects (B) instead, the plan must be revised (different `## Files`, different guarantee audit, different tests) before approval. | ||
| - The build prompt states "currently `SKILLS_VERSION 2.5.1`", but live discovery (Step 1) found `SKILLS_VERSION` is already `2.5.2` (an unrelated prior fix, per `CHANGELOG.md`'s `[Unreleased]` section, already landed on `main`). This plan bumps from the live `2.5.2` to `2.5.3`, not from `2.5.1` — confirm this is expected and not a sign the prompt was written against a stale checkout. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| # REGRESSION — f13-modeb-cue | ||
|
|
||
| **Base:** `HEAD` (auto-detected — the working tree was dirty at run time, so the baseline is the | ||
| pre-build commit `84c6f15`, checked out into a detached `git worktree`). | ||
|
|
||
| **Inside (the changed scope):** | ||
|
|
||
| - `.claude/commands/pharn-plan.md` | ||
| - `.dev/features/f13-modeb-cue/GRILL.md` (this feature's own artifact — exempt from the escape check | ||
| via `--feature f13-modeb-cue`) | ||
| - `.dev/features/f13-modeb-cue/PLAN.md` (same exemption) | ||
| - `CHANGELOG.md` | ||
| - `SKILLS_VERSION` | ||
| - `README.md` (added mid-run — see "First pass" below) | ||
|
|
||
| **Declared (`PLAN.md`'s `## Files`):** `.claude/commands/pharn-plan.md`, `CHANGELOG.md`, | ||
| `SKILLS_VERSION`, `README.md` — `escaped: []`. No write left the plan's declared scope. | ||
|
|
||
| **Style gates skipped:** `inside` touches no shared style config (`eslint.config.mjs`, | ||
| `.prettierrc.json`, `.prettierignore`, `.markdownlint-cli2.jsonc`), so `lint` / `format:check` / | ||
| `lint:md` cannot flip over the outside files and were not run (deterministic skip rule). | ||
|
|
||
| ## First pass — a real regression, since corrected | ||
|
|
||
| The plan's first draft bumped `SKILLS_VERSION` to `2.5.3` without declaring `README.md`. That run's | ||
| `tests` gate flipped GREEN (base) → RED (head): | ||
|
|
||
| ```text | ||
| test at .dev/floor/check-version-badge.test.mjs:311:1 | ||
| ✖ the checker is GREEN against this repo | ||
| AssertionError [ERR_ASSERTION]: VERSION-BADGE: RED — 1 finding(s) | ||
| - [DRIFT] README.md | ||
| the badge reads "2.5.2" but SKILLS_VERSION is "2.5.3" | ||
| ``` | ||
|
|
||
| `check-version-badge.test.mjs` runs live against this repo's actual `README.md` / `SKILLS_VERSION` (not | ||
| a fixture); the regression was real and directly caused by this feature's incomplete `## Files`. Per | ||
| the human's direction, `PLAN.md` was amended to add `README.md` (updating the shields badge to | ||
| `2.5.3`), the build was re-run for the added file, and `/pharn-dev-regress` was re-run in full below. | ||
|
|
||
| ## Outside-gate results (base → head, final run) | ||
|
|
||
| | gate | base | head | flipped? | | ||
| | --------------------------------------- | ---- | ---- | -------- | | ||
| | `tests` | 0 | 0 | no | | ||
| | `validate` | 0 | 0 | no | | ||
| | `structural:expected-injection-comment` | 0 | 0 | no | | ||
|
|
||
| **REGRESSIONS: none — no deterministically-detectable breakage outside the feature.** | ||
|
|
||
| **Honest residual (P7):** this report certifies only what its gate set covers — `node --test` over the | ||
| listed outside test files, `validate.mjs`, and one `structural:*` eval pair. It does not certify that | ||
| nothing else broke; it certifies that no _covered_ gate flipped. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Reconcile the final scope with the grill gate.
The final plan contains
README.md, but the grill analyzes only three files. The shipment record confirms that the file was added after the grill and that no grill rerun occurred..dev/features/f13-modeb-cue/GRILL.md#L48-L60: reviewREADME.mdor record an approved post-grill scope amendment..dev/features/f13-modeb-cue/GRILL.md#L71-L82: update the summary and verdict to cover the final scope..dev/features/f13-modeb-cue/SHIP.md#L18-L30: rerun the grill or record the required human approval before closing the chain.📍 Affects 2 files
.dev/features/f13-modeb-cue/GRILL.md#L48-L60(this comment).dev/features/f13-modeb-cue/GRILL.md#L71-L82.dev/features/f13-modeb-cue/SHIP.md#L18-L30🤖 Prompt for AI Agents