# morph-spec

> Spec-driven development framework for multi-stack projects. Turns feature requests into implementation-ready code through structured, AI-orchestrated phases.

**Package:** `@polymorphism-tech/morph-spec`
**Version:** 8.37.1  
**Requires:** Node.js 22+, Claude Code

---

## What it does

morph-spec enforces a spec-first development workflow. When you ask for a feature, it does not write code immediately. It runs through structured phases (proposal, plan, implement) with approval gates before a single line of implementation is generated. Each phase produces traceable output files. Every decision is documented.

It integrates natively with Claude Code: skills become slash commands, agents become native subagents, hooks inject state context automatically, and rules enforce standards based on file paths.

---

## Requirements

- [Claude Code](https://claude.ai/code) (latest)
- Node.js 22+
- npm 9+ or pnpm

---

## Installation

Install the CLI globally:

```bash
npm install -g @polymorphism-tech/morph-spec@latest --prefer-online
```

Then initialize in your project:

```bash
morph-spec init
```

### Init options


| Flag         | Description                           |
| ------------ | ------------------------------------- |
| `--force`    | Overwrite existing installation       |
| `--skip-mcp` | Skip MCP configuration prompt         |
| `--path`     | Target directory (default: cwd)       |


After init, open the project in Claude Code. The framework activates automatically via `.claude/settings.local.json`.

---

## Project structure (after init)

```
your-project/
├── CLAUDE.md                        # AI instructions for this project
├── .morph/
│   ├── config/
│   │   └── config.json              # Project configuration
│   ├── framework/
│   │   ├── agents.json              # 8 domain personas (READ-ONLY)
│   │   ├── standards/               # Coding and architecture standards (READ-ONLY)
│   │   └── templates/               # Code and IaC templates (READ-ONLY)
│   ├── context/                     # Project context (README.md, standards.md)
│   ├── features/                    # Active features
│   │   └── {feature}/
│   │       ├── 0-proposal/          # Problem statement + acceptance criteria
│   │       ├── 1-design/            # UI/UX design (optional, UI-heavy features)
│   │       ├── 2-plan/              # spec.md + mandate.md + tasks.json
│   │       ├── 3-implement/         # Recap and implementation notes
│   │       └── 4-review/            # Review report + Gate 3
│   └── state.json                   # READ-ONLY — managed by CLI only
└── .claude/
    ├── commands/                    # Slash commands
    ├── skills/                      # Framework skills (flat .md files)
    ├── agents/                      # Native subagents (one morph-{id}.md per persona)
    ├── rules/                       # Stack-aware, path-scoped standards rules
    └── settings.local.json          # Hooks configuration
```

---

## Phase workflow

Features move through structured phases. Some are optional depending on feature type.

```
proposal → [uiux] → plan → implement → review
```

`uiux` is optional — applies only to UI-heavy features.

### Phase outputs


| Phase     | Directory       | Key files                                                          |
| --------- | --------------- | ------------------------------------------------------------------ |
| Proposal  | `0-proposal/`   | `proposal.md`, `stack-scan.md`, `migration-plan.md` (optional)     |
| Design    | `1-design/`     | `design-system.md`, `mockups.md`, `components.md`, `flows.md`      |
| Plan      | `2-plan/`       | `spec.md`, `mandate.md`, `tasks.json`, `decisions.md`              |
| Implement | `3-implement/`  | `recap.md` + source code                                           |
| Review    | `4-review/`     | `review-report.md`                                                 |


### Approval gates

- **Gate 1 (Proposal)** — Problem statement must be approved before plan.
- **Gate 2 (Plan)** — Spec + mandate + tasks must be approved before implement.
- **Gate 3 (Review)** — Review report must be approved before archive.

In `trust: "auto"` mode (default), gates auto-pass without risk signals. See `framework/MORPH.md` for risk-signal details.

Check gate status:

```bash
morph-spec approval-status {feature}
```

---

## Work-type routing & worktrees

Not every change deserves the full pipeline. Every feature is born with a **work type** — `feature`, `bug`, `chore`, or `hotfix` — set via `morph-spec create {feature} --type <type>` or classified from free text with `--request "<text>"`. The type dimensions the pipeline: `feature` runs the full proposal → [uiux] → plan → implement → review sequence; `bug` runs a lean proposal/plan; `chore` skips straight to implement (Gates 1/2 stamped by policy at birth); `hotfix` runs scout (read-only root-cause) → surgical fix → test loop, and its Gate 3 always pauses for a human even under `trust: auto`. Change the type mid-flight with `morph-spec retype {feature} {newType}` (undoes only policy-stamped gates, preserves human approvals, blocked after Gate 3).

Independent features can also be developed **in parallel, each isolated in its own git worktree** — one feature, one worktree, one Claude Code instance. `morph-spec create {feature} --worktree` (or `morph-spec worktree setup {feature}`) creates `worktrees/{feature}/` on branch `morph/{feature}`. The authoritative `feature.json` travels committed on the branch; shared infra (`node_modules`, `.claude`, `.morph/framework`) is linked via junctions (`morph-spec worktree link --all` repairs it if missing). Close out with `morph-spec worktree finish {feature}` (merges `--no-ff` back into the clean primary root) followed by `morph-spec archive {feature}` at the root; `morph-spec worktree list` shows every active worktree with its phase and gate status.

---

## Slash commands

These commands are available inside Claude Code after init.


| Command                       | Description                                             |
| ------------------------------ | ---------------------------------------------------------- |
| `/morph-proposal {feature}`    | Business understanding + plan (Gates 1 and 2)                |
| `/morph-apply {feature}`       | Autonomous execution + review (Gate 3)                        |
| `/morph-hotfix {feature}`      | Surgical hotfix ADW — scout → fix → human Gate 3 → ship         |
| `/morph-status [feature]`      | Status of the active (or specified) feature                      |
| `/morph-archive {feature}`     | Archive **without integrating** (legacy feature / cleanup); normal close is `morph-spec finish --pr\|--merge` |
| `/morph-preflight`             | Pre-deploy validation (specs, contracts, tests, infra)                |
| `/morph-troubleshoot [error]`  | Root-cause diagnosis for .NET/Next.js errors                            |


---

## CLI reference

### Project management

```bash
morph-spec init                        # Initialize MORPH in current project
morph-spec init --force                # Overwrite existing installation
morph-spec update                      # Update framework files and re-analyze project
morph-spec doctor                      # Check installation health
morph-spec doctor --full               # Full health check (all file verifications)
```

### Feature workflow

```bash
morph-spec fleet                              # Every active feature (root + worktrees): phase, gates, activity
morph-spec status {feature}                    # Feature status dashboard
morph-spec approve {feature} {gate}            # Approve a phase gate (proposal, plan, review)
morph-spec advance {feature}                   # Approve the current gate and scaffold the next phase folder
morph-spec approval-status {feature}           # Show approval status for all gates
morph-spec finish {feature} --pr|--merge       # Close a feature: archive + integrate (PR or local merge) + teardown
morph-spec archive {feature}                   # Archive WITHOUT integrating (legacy feature / cleanup)
```

`finish` is the normal close for both flows: it archives (committing the move inside `morph/{feature}`), then integrates — `--merge` merges `--no-ff` into the default branch locally; `--pr` pushes the branch and runs `gh pr create` (needs `origin` + authenticated `gh`) — and tears down the worktree if there is one. Plain `archive` is reserved for legacy features (born before every feature had a `morph/{feature}` branch) and cleanup.

Task progress within a feature is recorded in `tasks.json` — Claude writes the mutable `status`/`outputs`/`notes` fields as it goes, and there is no separate CLI command for starting or finishing a task.

### Validation

```bash
morph-spec validate                    # Run all validators
morph-spec validate {validator}        # Run specific validator
morph-spec validate-feature {feature}  # Content-aware feature validation
morph-spec verify {feature} [task]     # Deterministic build+tests+validators chain, before the LLM judge
```

### Work-type routing

```bash
morph-spec create {feature} --type feature|bug|chore|hotfix --description "<what/why>"   # Explicit birth: type dimensions the pipeline, description is required
morph-spec create {feature} --request "<free text>"           # Detector classifies the type AND seeds the description
morph-spec retype {feature} {newType}                          # Change work type mid-flight (blocked after Gate 3)
morph-spec dag {feature} [--mermaid]                            # DAG dispatch decision; --mermaid emits a flowchart
```

### Worktrees (parallel development)

```bash
morph-spec create {feature} --description "<what/why>" --worktree   # Birth the feature already isolated in its own worktree
morph-spec worktree setup {feature}      # Create worktrees/{feature}/ on branch morph/{feature}
morph-spec worktree link [--all]         # Relink shared infra (node_modules, .claude, .morph/framework)
morph-spec worktree list [--json]        # List active feature worktrees with phase/gate status
# Close a worktree feature with `morph-spec finish {feature} --pr|--merge` (see Feature workflow) — it absorbed `worktree finish`.
```

**Codebase graph** — optional, fail-open. `init` installs [graphify](https://pypi.org/project/graphifyy/) (pinned 0.9.50) when a Python toolchain is available and writes a stack-aware `.graphifyignore`; without one, it records the fact and moves on. Everything degrades to grep.

```bash
morph-spec graph build                       # Extract the graph (local AST, zero tokens)
morph-spec graph status                      # Size, freshness, sanitizer health
morph-spec graph affected {symbol} --uses-only  # Who actually uses it (not who implements it)
morph-spec graph explain {symbol}            # Neighbourhood, cited file:line
```

The gain is **precision, not recall**: the graph finds nothing grep would miss, but it drops 58% of the noise and tells you *what kind* of relationship each hit is — the difference between "20 types implement this interface" and "2 actually use it". The graph is never consumed raw: a sanitizing layer fixes the C# namespace-scope resolution gap that would otherwise report **zero** consumers where two exist.

---

## Agent model

morph-spec dispatches 8 flat domain personas — no tiers, no hierarchy — defined in `.morph/framework/agents.json` (single source of truth) and installed identically to `.claude/agents/morph-{id}.md`. Claude picks the right persona per task from the domains/keywords in `agents.json`, then dispatches it via the `Agent` tool.

| Persona          | Domain                                | Model  |
| ---------------- | -------------------------------------- | ------ |
| `dotnet-senior`   | Backend (.NET, VSA)                    | sonnet |
| `ef-modeler`      | EF Core / Postgres modeling            | sonnet |
| `maf-expert`      | Microsoft Agent Framework               | sonnet |
| `nextjs-expert`   | Frontend (Next.js/React)                | sonnet |
| `ui-designer`     | UI/UX, design systems                    | sonnet |
| `infra-engineer`  | Jobs, deployment, observability          | sonnet |
| `evaluator`       | Independent code/architecture review (Gate 3) | opus |
| `scout`           | Read-only codebase diagnosis             | haiku  |

`morph-spec doctor` detects drift between `agents.json` and the generated `.claude/agents/morph-*.md` files — never hand-edit the generated files.

---

## Hooks

Guardrail hooks are installed into `.claude/settings.local.json` across 7 event bindings. All are **fail-open** — they check that state exists first and silently no-op on missing/corrupt state; they never throw, write state, or orchestrate.


| Event                      | Hook(s)                                                              | Purpose                                                                     |
| --------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `SessionStart`              | `worktree-context.js`                                                   | Injects feature identity (worktree) or active-feature summary (root)           |
| `PreToolUse` (Write\|Edit)  | `protect-spec-files.js`, `enforce-phase-writes.js`                       | Blocks edits to the frozen plan contract post-Gate-2; enforces phase folders    |
| `PreToolUse` (Bash)         | `pre-bash-denylist.js`                                                   | Detects destructive shell patterns                                              |
| `PostToolUse`               | `post-edit-typecheck.js`, `tasks-json-guard.js`, `trace-autogen.js`       | Stack-aware typecheck; guards `tasks.json` plan-contract edits; auto-generates execution traces |
| `PostToolUse`               | `state-sync.js`, `gate-guard.js`, `loop-detect.js`                        | Syncs feature state; enforces gate ordering; detects repeated-action loops       |
| `Stop`                      | `validate-completion.js`                                                  | Warns about incomplete tasks, missing outputs, or pending approval gates         |


Protected files (via `permissions.deny`):

- `.morph/state.json` — never edited directly, derived from `feature.json` files
- `.morph/framework/` — read-only framework content

---

## Rules

Rules are installed to `.claude/rules/` based on your detected stack (`stacks:` frontmatter, same tagging mechanism as agents and templates) and activate automatically based on file path patterns (`paths:` frontmatter). A subset of the current set:

| Rule file                     | Applies to                                     | Stack     |
| ----------------------------- | ------------------------------------------------- | --------- |
| `morph-workflow.md`           | Always active — spec-first mandate                 | any       |
| `csharp-standards.md`         | `**/*.cs`, `**/*.csproj`                            | dotnet    |
| `frontend-standards.md`       | `**/*.tsx`, `**/*.css`, `**/*.scss`                 | nextjs    |
| `nextjs-standards.md`         | Next.js-specific patterns                           | nextjs    |
| `ai-agents-standards.md`      | `**/Agents/**`, `**/*Agent*.cs`                     | dotnet    |
| `infrastructure-standards.md` | `**/Dockerfile*`, `**/docker-compose*`, `**/.github/**` | docker |


---

## Stack support


| Technology                                  | Support                                                    |
| ------------------------------------------- | ------------------------------------------------------------- |
| .NET 10 / ASP.NET Core                      | Full — VSA with direct handlers, result pattern, Minimal API   |
| EF Core / Neon (Postgres)                   | Full — migrations, Neon Auth (Better Auth)                     |
| Next.js / React / TypeScript                | Full — components, routing, state management                  |
| Microsoft Agent Framework (MAF)             | Full — single-agent + structured output + tools + RAG          |


TypeScript strict mode is enforced by default. See `.morph/framework/standards/` for all coding standards.

---

## Update

To update the framework files in an existing project:

```bash
morph-spec update
```

This re-syncs `.morph/framework/`, `.claude/skills/`, `.claude/agents/`, `.claude/rules/`, and `CLAUDE.md` with the installed package version. Your `.morph/config/config.json`, `.morph/context/`, and feature outputs are not touched.

After updating, run `morph-spec doctor` to confirm the installation is healthy.

---

## Key rules

**Never skip phases.** Every feature starts with a proposal. No code is written until the design is approved and a task list exists.

**Never edit protected files directly:**

- `.morph/state.json` — derived automatically from `feature.json`; use `morph-spec approve`/`advance`/`score`/`gate-decision` to change feature state
- `.morph/framework/` — read-only, updated by `morph-spec update`

**Always document decisions.** Each feature can have a `2-plan/decisions.md`. Architectural choices go there, not in commit messages.

**Validators run after every task.** `morph-spec verify` runs the build + test + validator chain relevant to your stack; `morph-eval` scores the result — a score below 9 triggers an autonomous correction loop rather than a pause.

---

## Troubleshooting

### `morph-spec: command not found`

The installer automatically adds the npm global directory to your PowerShell `$PROFILE`. Open a **new terminal** after installing. If it still doesn't work, add it manually:

```bash
npm config get prefix
# Add {prefix} to your PATH
```

### `morph-spec doctor` reports issues

Run doctor to see all checks:

```bash
morph-spec doctor
```

Common fixes:

- **Missing `.claude/agents/`** — run `morph-spec update` to reinstall agents
- **Missing `.claude/rules/`** — run `morph-spec update` to reinstall rules
- **State version mismatch** — state auto-migrates on next CLI command; if it fails, back up and re-init
- **Hooks not firing** — confirm `.claude/settings.local.json` exists and contains the `hooks` key

### EPERM on Windows global install

Windows may block global npm installs without elevated permissions. Options:

1. Run terminal as Administrator (not recommended long-term)
2. Change npm global prefix to a user-writable directory:

```bat
mkdir %APPDATA%\npm-global
npm config set prefix %APPDATA%\npm-global
:: Add %APPDATA%\npm-global to your PATH
npm install -g @polymorphism-tech/morph-spec@latest --prefer-online
```

1. Open a new terminal (the installer adds npm to your PATH automatically)

### Hook not triggering on SessionStart

Ensure `.claude/settings.local.json` is not gitignored in your project. The file must be present for Claude Code to load hooks. If it is missing, re-run `morph-spec setup-infra` or `morph-spec init --force`.

---

## Standards

The framework ships 60 registered standards across 7 categories (`ai-agents`, `architecture`, `backend`, `data`, `frontend`, `infrastructure`, `integration`), stored in `.morph/framework/standards/STANDARDS.json`. Standards are looked up on demand (by keyword/alias) rather than preloaded wholesale into context, and enforced via stack-aware, path-scoped rules installed to `.claude/rules/` during `morph-spec init`.

---

## License

Proprietary — see [LICENSE](./LICENSE).

Code generated by morph-spec (contracts, templates, implementation output) belongs to you.

---

*morph-spec v8.37.1 by [Polymorphism Tech](https://polymorphism.tech)*