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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 28 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<command>/<name>/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.

Expand Down Expand Up @@ -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,
Expand Down
11 changes: 6 additions & 5 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading