PHARN does not scaffold your app. You create your project (e.g. with create-next-app), initialize git, then run PHARN in that directory.
| 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 (not for init --dry-run or init --yes) |
Right after the git check, before any fetch |
| Node | 24.2.0 or newer: engines.node declares it, and init / update refuse on an older Node, writing nothing |
First thing in init and update, before the git check |
| Node (floor) | The same 24.2.0 applies to the installed pharn/floor/*.mjs (import.meta.main); they refuse to run on older Node |
When you run /pharn-* pipeline commands |
.git is required for every install. So is a real terminal, for a plain pharn init: it exits 1
rather than rendering a prompt into a dead stream. Two forms need none. pharn init --dry-run previews
the install and writes nothing. pharn init --yes installs without prompts, but only into a project
where none of its files exists yet: it never answers the overwrite confirmation, so anywhere it would
overwrite something it exits 1 instead (a re-install always does — use pharn update). (pharn update
also refuses off a TTY, and update --yes is the supported way through in CI.) pharn init then detects your project's archetype(s) from
package.json dependency names plus a bounded file-tree scan — there is no stack-pack selection and no
package prerequisite to satisfy. See Troubleshooting.
PHARN installs into your existing project. Just before writing, pharn init checks which of its
actual install targets (the selected capability dirs, the product commands/hooks, the contracts, core
and floor dirs, all four trusted docs, pharn's LICENSE copy, pharn/features/README.md, and
pharn.config.json) already exist in your project. If any do, it lists them and asks you to confirm
before overwriting — default no; if none do, there is no prompt at all. Your
.claude/settings.json is never overwritten, so it is not part of the check.
The npm package name is @pharn-dev/pharn. It installs a single command, pharn.
npx @pharn-dev/pharn initnpx create-next-app@latest my-app
cd my-app
npx shadcn@latest init
git init && git add -A && git commit -m "init"
npx @pharn-dev/pharn initpharn with no subcommand runs init (same as pharn init).
pharn init is archetype-driven — there is no questionnaire:
- Detect archetypes. The CLI merges your
package.jsondependency names with a bounded, symlink-safe file-tree scan (names only, never file bodies) into an archetype set —ssr,backend,spa,lib(a project may match several, e.g. Next + Express →ssr+backend). It shows what it detected, and what triggered each one (e.g.backend ← src/app/api/). Detection is JS/TS-shaped: the signals are npm dependency names,.tsx/.jsxfiles, and — in a Next.js app only —next.config.*,app/route handlers andapp/api/pages/api; a rootapi/,migrations/and database.sqlfiles count only when the project has a rootpackage.json. A Python, Go or Rust project without one produces no signal, resolves tolib, and receives the universal capabilities only — the correct outcome, not a failure. A server framework or a runtime database driver (express,pg,prisma, …) counts asbackendonly underdependencies— a devDependency-only one (a mock server, a test database) does not — while SSR and UI frameworks count underdevDependenciestoo. If the scan stops at its bounds (50,000 entries, 24 directories deep) before its result is settled, the summary saysdetection stopped early. If detection gets your project wrong, pass the archetypes yourself:pharn init --archetype backend(seeinit). - Fetch + resolve. It downloads the newest verified release of
pharn-dev/pharn-oss— a tag pharn-oss creates only after its post-merge CI passed — as a tarball, and selects the capabilities whoseappliesisuniversalor intersects your detected archetypes — skipping the rest with a reason. If no release can be resolved it exits 1, writes nothing, and names--ref main(see No verified release could be resolved).pharn init --ref maininstalls the tip ofmaininstead — every merge, before its checks have finished — for contributors. If the fetched version declares aMIN_CLInewer than your CLI, the run stops here with a named error and writes nothing. - Confirm + install. After a summary (selected + skipped), it copies the selected capabilities plus
the fixed product surfaces (commands, hooks, contracts,
pharn-core, floor checkers, the four trusted docs, upstream'sLICENSEcopy, andpharn/features/README.md) into the mirrored layout, then writespharn.records.jsonandpharn.config.json.
To add a capability the detection didn't select — or remove one it did — use
pharn add / pharn remove afterward.
After a successful install, your project contains the selected capabilities plus the fixed product surfaces:
| Artifact | Description |
|---|---|
pharn/pharn-pipeline/grillers/<name>/, pharn/pharn-review/<name>/ |
The installed grillers + lenses, each with its evals/ |
.claude/commands/, .claude/hooks/ |
The pharn-* product slash commands + the deterministic .cjs/.mjs floor hooks |
pharn/pharn-contracts/, pharn/floor/ |
Inter-layer schemas + the floor checkers the commands invoke (minus the floor's own test files, test-fixtures/ and fixtures/) |
pharn/pharn-core/ |
The agnostic mechanism skills the commands cite (the seam resolver + its evals) |
pharn/CONSTITUTION.md, pharn/ARCHITECTURE.md |
Two of the four trusted spec docs, copied verbatim — see the layout note below |
pharn/THREAT-MODEL.md, pharn/LIMITS.md |
The other two — at the project root when the fetched pharn-oss is older than 7.0.0 (see below) |
pharn/LICENSE (flat: PHARN-LICENSE) |
PHARN's Apache-2.0 license, copied so a repo you publish carries the grant. Your own root LICENSE is never touched |
pharn/features/README.md |
The product-loop boundary contract the installed commands cite by name (project root in both layouts) |
pharn.config.json |
skillsVersion, commit SHA, detected archetypes, installed capabilities, and the layout |
pharn.records.json |
Per-file sha256 — skips unproven present edits, restores missing; --force overwrites all but unreadable |
.claude/* is layout-invariant — commands, hooks and settings.json sit at those paths either
way, and an existing .claude/settings.json is never overwritten. Everything else follows the fetched
version: the CLI mirrors whichever layout pharn-dev/pharn-oss ships and never rewrites a copied
file's contents, so the paths above are the pharn layout it installs today. The legacy flat
layout puts the same surfaces at the project root instead — pharn-pipeline/grillers/,
pharn-review/, pharn-contracts/, .dev/floor/, PHARN-LICENSE — and upstream ships no root
pharn-core/, so that one surface is simply absent there. The four trusted docs are the same set
in both layouts. A pharn install keeps all four under pharn/ from pharn-oss 7.0.0 on; an older
pharn-oss still ships THREAT-MODEL.md and LIMITS.md at the repo root, and the install mirrors that
(an ordered probe: pharn/<doc> if the fetched version has it, else the root path). A flat install
lands all four at the root. Each doc is copied only if the fetched version ships it — a clone that predates one simply
does not get it, and init says which docs it wrote and warns about any it did not. Which layout you
got is recorded as layout in pharn.config.json.
See pharn.config.json and pharn.records.json for the exact schemas. Commit both — they are your project's PHARN state.
- Open Claude Code in the project directory.
- Run
/pharn-specto capture your first feature's intent — it pins the scope and feeds/pharn-plan. This is where every run begins:/pharn-plangates on an Approved, un-driftedSPEC.mdand halts without one, so there is no entry point further down the chain.
The pipeline is eight typed stages: /pharn-spec → /pharn-plan → /pharn-grill → /pharn-test → /pharn-build → /pharn-regress → /pharn-verify → /pharn-ship. You rarely run them by hand — /pharn-ship is itself the eighth stage and orchestrates the seven before it in one pass, keeping both human gates: approve the spec before code is written, decide merge/fix/abandon after verification. /pharn-loop runs the same chain unattended — the model approves the spec and iterates build → regress → verify until green, an iteration cap, or a terminal failure — and leaves the merge/fix/abandon decision to you after the run.
Set up a test runner before your first feature. /pharn-test writes each acceptance criterion's test before the build and requires it to fail, so it needs a test script (plus test:e2e or e2e for end-to-end criteria) whose reporter writes per-test JSON, named under testResults in pharn.config.json. Without one, /pharn-test stops and asks, and /pharn-loop ends with blocked: no-test-runner. Set the runner up as its own increment (a SPEC with spec_kind: test-infra); the reporter setup is in upstream's Per-test results.
Two of the eleven installed commands sit outside the pipeline: /pharn-review runs the review lenses in parallel over any code and merges their findings (no stage invokes it), and /pharn-memory-promote promotes one lesson into memory-bank/ through a gated provenance check.
- Review what was written: pharn.config.json
- Add a capability later: add command
- Refresh to the latest skills: update command
- Prefer to ask instead of typing commands: the optional
pharn-cliagent skill checks, previews and applies updates for you