diff --git a/CHANGELOG.md b/CHANGELOG.md index 2af5290..38961d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- **Docs:** Align README, getting-started, and troubleshooting with pharn-oss 6.24.0 write-guard posture and CLI vs floor Node versions. + ## [0.7.0] — 2026-09-26 ### Changed diff --git a/README.md b/README.md index c46438e..8625cc8 100644 --- a/README.md +++ b/README.md @@ -186,13 +186,27 @@ your project already had that file, PHARN preserved it and printed a warning instead of overwriting it — so until you copy the hook wiring across, every guarantee that depends on a `PreToolUse` hook is inactive. -**Once wired, the write guard is fail-closed.** With no active scope, Claude -Code's Write/Edit/MultiEdit/NotebookEdit tools are restricted to -`pharn/features/**` and `.pharn/**`; ordinary edits to your own source are denied. That is the -intended posture — a stage sets the scope from the concrete paths your -`PLAN.md` declared — but it means the guard is not a drop-in for editing -outside a PHARN run. Clearing the scope returns to this default; it does not -re-open your source. +**Once wired, the default depends on your tree (pharn-oss 6.24.0+).** With no +active scope, `enforce-writes-scope.cjs` applies that default. + +In an **installed** project (`pharn.config.json` carries a non-empty +`skillsVersion`), you can edit ordinary application source **outside** an open +PHARN run. The narrow fail-closed posture — Claude Code's +Write/Edit/MultiEdit/NotebookEdit tools restricted to `pharn/features/**` and +`.pharn/**` — applies **only while** `/pharn-ship`, `/pharn-loop`, or +`/pharn-review` has an open marker (`.pharn///active.json`; ship +and review via `pharn/floor/run-marker.mjs`, loop via +`require-loop-record.cjs`). Outside those runs the guard **denies** PHARN's +installed surface (`pharn/**` except `pharn/features/**`, `.claude/**`, +`pharn.config.json`, and `.pharn/writes-scope.json`) and **allows** the rest of +your project, including app source. While a stage is running it still sets +explicit scope from the concrete paths your `PLAN.md` declared. + +In PHARN's own dev repo or an unsignalled tree, the pre-6.24.0 posture +remains: fail-closed everywhere with no active scope. Clearing the scope +(`set-writes-scope.cjs --clear`, or deleting `.pharn/writes-scope.json`) +returns to whichever default your tree and open-run state compute; it does not +by itself re-open source in those postures, or during an open install run. Writes issued through Bash bypass both write guards entirely. @@ -312,9 +326,13 @@ PHARN is intentionally scoped: - It targets **Claude Code today**. Codex and Cursor support are planned, not shipped. -- It requires a git-initialized project and Node >= 20.13.0 (the floor its - prompt library needs). CI runs on Node 24, and a smoke job starts the packed - CLI on exactly Node 20.13.0. +- It requires a git-initialized project. The **CLI** (`@pharn-dev/pharn`) needs + Node **>= 20.13.0** (`engines.node`; CI runs on Node 24, and a smoke job + starts the packed CLI on exactly 20.13.0). The **installed floor** + (`pharn/floor/*.mjs`) needs **Node 24.2+** for reliable checker runs + (`import.meta.main`; on older Node a guarded tool can exit 0 without running + its checks). Use 24.2+ locally for `/pharn-build`, `/pharn-verify`, and the + rest of the pipeline. - **Archetype detection is JS/TS-shaped.** The signals are `package.json` dependency names plus `next.config.*`, `app/` route handlers, `.tsx`/`.jsx`, `migrations/` and `.sql`. A Python, Go or Rust repo produces no signal, diff --git a/docs/getting-started.md b/docs/getting-started.md index e16beba..19dbf13 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -4,11 +4,12 @@ PHARN does not scaffold your app. You create your project (e.g. with `create-nex ## Prerequisites -| Requirement | How PHARN checks | When | -| -------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------- | -| Git | A `.git` directory exists in the project root | Always — checked up front, before detection | -| Interactive terminal | `process.stdin`/`stdout` are TTYs | Right after the git check, before any fetch | -| Node | `engines.node` declares `>=20.13.0` (CI exercises Node 24; a smoke job starts the CLI on 20.13.0) | By npm/npx when the package is resolved | +| Requirement | How PHARN checks | When | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| Git | A `.git` directory exists in the project root | Always — checked up front, before detection | +| Interactive terminal | `process.stdin`/`stdout` are TTYs | Right after the git check, before any fetch | +| Node (CLI) | `engines.node` declares `>=20.13.0` (CI runs on Node 24; a smoke job starts the packed CLI on 20.13.0) | By npm/npx when the package is resolved | +| Node (floor) | Installed `pharn/floor/*.mjs` needs **24.2+** (`import.meta.main`; older Node can exit 0 without running checks) | When you run `/pharn-*` pipeline commands | `.git` is required for every install. So is a real terminal: `pharn init` **exits 1** rather than rendering a prompt into a dead stream, and there is deliberately no `--yes` for it — its second prompt diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index ae6a5bc..05b5ccd 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -19,6 +19,15 @@ | User cancel at summary, or overwrite declined | 0 | | Successful install | 0 | +## Node version: CLI vs installed floor + +Two different Node floors apply: + +- **CLI (`@pharn-dev/pharn`):** `engines.node` is `>=20.13.0`. npm/npx enforces this when the package is resolved; CI smoke-tests the packed CLI on exactly 20.13.0. +- **Installed floor (`pharn/floor/*.mjs`):** pipeline checkers need **Node 24.2+** because their CLI entry points gate on `import.meta.main`. On an older Node a guarded tool can exit **0** without running its checks — a silent false green. + +If a `/pharn-*` stage reports success while something still looks wrong, check `node -v` in the environment where Claude Code runs your gates and upgrade to **24.2+** for pipeline work. + ## Streams Error-level messages go to **stderr**; normal output (notes, summaries, prompts, spinners, the