---
name: fpl-init
description: One-command project bootstrap for the ForgePlan ecosystem. Probes the forgeplan CLI, runs `forgeplan init`, wires `.mcp.json` and `.claude/settings.json`, then chains `/bootstrap` (universal CLAUDE.md template) and `/setup` (docs/agents/ wizard) so a fresh repo is fully wired in one shot. Recommends — but does not install — companion plugins (fpf, laws-of-ux, agents-core, forgeplan-workflow, forgeplan-orchestra). v2.0: Adds optional `--canonize` step that scaffolds the canonical agent layer (project-agent-matrix.yaml + project-config.yaml + Hindsight mental models) for forgeplan-aware projects per PRD-026 Phase 5. Use on a brand-new project, or on an existing project that has none of `.forgeplan/`, `CLAUDE.md`, `docs/agents/`. Triggers (EN/RU) — "fpl init", "init project", "bootstrap forgeplan", "set up everything", "full project setup", "/fpl-init", "поставь всё", "разверни проект с нуля", "инициализируй проект", "fpl init canonize", "setup agent matrix", "v2 bootstrap".
origin: forgeplan
disable-model-invocation: true
allowed-tools: Read Write Edit Bash(test *) Bash(ls *) Bash(cat *) Bash(pwd *) Bash(command *) Bash(git *) Bash(forgeplan *) Bash(mkdir *) Bash(jq *) Bash(python3 *) Bash(cp *) Bash(sed *) Bash(basename *) Bash(grep *)
---

# fpl-init — full project bootstrap

One command. Wraps the four manual steps a new ForgePlan project usually
needs (forgeplan init, MCP wiring, CLAUDE.md, docs/agents/) and runs them
end-to-end. The user only confirms once at the start; verification happens
at the end.

This skill **delegates** — it doesn't reimplement [`bootstrap`](../bootstrap/SKILL.md)
or [`setup`](../setup/SKILL.md). It probes, decides what's missing, then
calls those skills' workflows for the parts that apply.

---

## When to use

- Brand-new repo (just `git init`, no scaffolding).
- Existing repo missing the canonical baseline: no `.forgeplan/`, no
  `CLAUDE.md`, no `docs/agents/`.
- User explicitly types `/fpl-init` or asks "set up everything", "разверни
  проект с нуля", "поставь всё".

## When NOT to use

- All three baseline pieces are already present (`.forgeplan/` +
  `CLAUDE.md` + `docs/agents/`). Tell the user the project is already
  wired and route them to the targeted skill they actually need
  (`/restore`, `/briefing`, etc.).
- The user wants only one piece (e.g. just `CLAUDE.md`) — call the
  specific skill directly (`/bootstrap`).
- The cwd is a marketplace / plugin source (signature: `.claude-plugin/`
  or `plugins/*/`-like layout) — refuse, this isn't a target project.
- No git repo. The downstream skills assume git; refuse and ask the user
  to `git init -b main` first.

---

## Process

### 1. Orient

Run in parallel:

```bash
pwd
git rev-parse --show-toplevel 2>/dev/null || echo "not a git repo"
test -f CLAUDE.md && echo "CLAUDE.md exists" || echo "no CLAUDE.md"
test -d .forgeplan && echo ".forgeplan/ exists" || echo "no .forgeplan/"
test -d docs/agents && echo "docs/agents/ exists" || echo "no docs/agents/"
test -f .mcp.json && echo ".mcp.json exists" || echo "no .mcp.json"
test -f .claude/settings.json && echo ".claude/settings.json exists" || echo "no .claude/settings.json"
test -d .claude-plugin && echo "REFUSE: this is a plugin source" || true
```

Decide:

| Probe result | Action |
|---|---|
| `not a git repo` | Refuse. Ask user to run `git init -b main`. |
| `REFUSE: this is a plugin source` | Refuse. Tell the user this skill is for project repos, not plugin sources. |
| All four (`.forgeplan/`, `CLAUDE.md`, `docs/agents/`, `.mcp.json`) present | Tell the user setup is already complete; suggest `/restore` for context recall — but still offer step 8.5 (canonical agent layer) if `.forgeplan/project-agent-matrix.yaml` is absent or `--canonize` was passed. Otherwise exit. |
| Anything missing | Continue to step 2. Step 8.5 (canonical agent layer, v2.0 — PRD-026 Phase 5) runs after `/setup`. |

### 2. Probe forgeplan CLI

```bash
command -v forgeplan
forgeplan --version 2>/dev/null || true
```

If `forgeplan` is **not on `$PATH`** — refuse with install instructions:

```
forgeplan CLI is required but not found on $PATH.

Install it via one of:
  • macOS / Linux Homebrew: brew install ForgePlan/tap/forgeplan
  • From source (any platform with Rust):
      cargo install --git https://github.com/ForgePlan/forgeplan forgeplan-cli

Then re-run /fpl-init.
```

Don't try to install it yourself; this is a one-time user action.

### 3. Plan

Build a short plan from the probe results and show it to the user. **Ask
once, run end-to-end** (no per-step approvals):

```
fpl-init plan for $(basename "$PWD"):
  • forgeplan init        ← .forgeplan/ missing
  • wire .mcp.json        ← add forgeplan MCP server
  • wire .claude/settings.json  ← add forgeplan PreToolUse safety hook
  • /bootstrap            ← create CLAUDE.md from template (stack-detected)
  • /setup                ← interactive wizard for docs/agents/

Companion plugins to consider after (NOT installed by this command):
  fpf, agents-core, forgeplan-workflow, forgeplan-orchestra
  laws-of-ux (only if this repo has frontend)

Proceed? [y/n]
```

Skip the rows for pieces that already exist (e.g. don't list
`forgeplan init` if `.forgeplan/` is already there). If the user says no,
exit cleanly.

### 4. forgeplan init

If `.forgeplan/` is missing:

```bash
forgeplan init -y
```

If forgeplan's `init` command doesn't accept `-y`, fall back to
`forgeplan init` and treat any interactive prompt by passing through with
sensible defaults (the user has already approved the plan in step 3).

Verify:

```bash
test -d .forgeplan && forgeplan health 2>/dev/null | head -10 || echo "init failed"
```

If init failed — stop and surface the forgeplan output. Don't continue
through the rest of the plan with a broken artifact store.

### 5. Wire `.mcp.json`

Goal: ensure the `forgeplan` MCP server entry exists, **without overwriting existing entries**.

**Use the native command** — `forgeplan mcp install`:

```bash
forgeplan mcp install --client claude --scope project
```

This is the canonical wiring path. It is owned by forgeplan itself, smart-merge (preserves existing `hindsight`, `orch`, and any other MCP server entries), idempotent (safe to re-run), and writes the correct shape (`command: forgeplan / args: ["serve"] / transport: stdio`).

Target shape (what the command writes into `.mcp.json`):

```json
{
  "mcpServers": {
    "forgeplan": {
      "command": "forgeplan",
      "args": ["serve"],
      "transport": "stdio"
    }
  }
}
```

**Why `args: ["serve"]` not `["mcp"]`** — `forgeplan mcp` is a *parent* command with subcommands (`mcp serve`, `mcp install`, `mcp help`). Launching it without a subcommand makes the server hang waiting for one, and Claude Code reports `failed to reconnect`. The canonical MCP server command is `forgeplan serve` (stdio is the default and only transport). `forgeplan mcp install` writes the correct `["serve"]` shape automatically.

Behaviour of the native command:
- `.mcp.json` missing → creates it with the forgeplan block.
- `.mcp.json` present + `mcpServers.forgeplan` missing → merges the entry in, preserves every other server.
- `.mcp.json` present + `mcpServers.forgeplan.args == ["mcp"]` (buggy v1.6.0 historic shape) → upgrades to `["serve"]` automatically (smart-merge replaces `command/args/transport` while preserving any user-customised `env` block).
- `.mcp.json` present + already correct → no-op, exits success.

Other `--scope` values:
- `--scope project` (used here) → writes to `./.mcp.json` in the current repo. This is what greenfield bootstrap wants — the wiring travels with the repo.
- `--scope user` → writes to `~/.claude.json` (host-personal, not committed). Use when you want forgeplan available in *every* project without per-repo config.

Dry-run is supported and useful before running for the first time on a populated `.mcp.json`:

```bash
forgeplan mcp install --client claude --scope project --dry-run
```

If the command fails (rare — usually file permissions or a malformed pre-existing `.mcp.json`), the recovery is to back up and re-run:

```bash
mv .mcp.json .mcp.json.bak
forgeplan mcp install --client claude --scope project
# then manually merge any custom entries from .mcp.json.bak back in
```

This replaces the previous Python-merge approach used in `fpl-init` ≤ v1.33; the native command is the same primitive that `smith-bootstrap` Step 0b uses, eliminating drift between the two skills.

### 6. Wire `.claude/settings.json` (optional, ask first)

Goal: add a `PreToolUse:Bash` hook that warns before destructive forgeplan
commands (delete, reset, force-merge). This is a soft-default — ask the
user before adding it, since `.claude/settings.json` is host-personal.

Ask:

```
Add a PreToolUse safety hook for forgeplan? It blocks Bash commands
that look like `forgeplan delete`/`reset`/`destroy` without explicit
--yes flags. Skip this if you're already comfortable with destructive
forgeplan commands. [y/n]
```

If yes, merge into `.claude/settings.json` (creating the file if needed):

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "case \"$CLAUDE_TOOL_INPUT_command\" in *'forgeplan delete'*|*'forgeplan reset'*|*'forgeplan destroy'*) [[ \"$CLAUDE_TOOL_INPUT_command\" == *'--yes'* ]] || { echo 'destructive forgeplan op without --yes; aborting'; exit 2; };; esac"
          }
        ]
      }
    ]
  }
}
```

Use the same Python merge approach as in step 5: load → merge into
`hooks.PreToolUse[]` (append, don't replace) → write. If the user already
has a `PreToolUse:Bash` hook, append a sibling `hooks` entry instead of
replacing the matcher.

If the user says no — skip this step entirely, don't print warnings.

### 7. Run `/bootstrap` flow

If `CLAUDE.md` is missing, invoke the bootstrap workflow inline (don't
spawn a sub-session — this skill IS the orchestrator):

1. Run the stack-detection probes from
   [`bootstrap`](../bootstrap/SKILL.md) step 3.
2. **Read the template file** at
   `../bootstrap/resources/templates/CLAUDE.md.template`. This is
   **mandatory**, not aspirational:
   - Use `Read` to load the template literally. Don't summarize, don't
     paraphrase, don't write a "better version from memory".
   - If the file doesn't exist, **abort step 7** and surface the path
     you tried. Do not invent a replacement CLAUDE.md.
3. Substitute placeholders in the loaded text:
   - Replace every `{{VAR}}` with the value detected in step 7.1.
   - For each `{{IF_X}}…{{/IF_X}}` block: keep inner content if `X` is
     true (e.g. `IF_LANG_TS` when TypeScript was detected), drop the
     entire block (markers included) if false.
   - Inline `{{IF_X}}…{{/IF_X}}` markers (used inside list items and
     tables for one-line additions) follow the same rule.
   - Replace `<PROJECT_NAME>` with `basename "$PWD"`.
   - Anything you can't determine → leave the placeholder visible
     (`{{VAR}}`) with a HTML comment line above it:
     `<!-- /fpl-init: could not detect — fill manually -->`.
     **Never guess** — a visible placeholder gets fixed once; a wrong
     guess gets propagated.
4. Write the rendered output verbatim to `./CLAUDE.md`. The structure
   (red-lines section first, non-goals last, the section ordering) is
   load-bearing — see `bootstrap/resources/guides/CLAUDE-MD-GUIDE.ru.md`
   for why. Do not reorder, omit, or "improve" sections.

Use **append mode** if `CLAUDE.md` already exists — the user may have a
custom file they care about. Default to append, never replace. Append
means adding a `## Reference` block pointing to fpl-skills, not pasting
the whole template.

Don't copy the optional `guides/` folder unless the user explicitly asked
for it — that's `bootstrap`'s decision and most projects don't need
those Russian author-guides.

**Anti-pattern to avoid**: writing a thin 60-line CLAUDE.md "from
scratch" because the template seems too verbose. The verbosity is the
point — the U-curve attention model needs primacy/recency zones to be
populated. A thin file silently strips guard rails.

### 7-bis. Inject forgeplan operating contract into CLAUDE.md (v3 — Phase 2 complete)

If forgeplan CLI is on `$PATH` (probed in step 2), append the **operating contract** to CLAUDE.md. This makes forgeplan-aware behaviour the default for every session in the project — without it, agents revert to general heuristics and skip artifact-graph operations under context pressure.

**Contract version history**:
- `v1` (PRD-018) — initial CLI-only contract
- `v2` (PRD-021) — MCP-first preferences with shell fallback
- `v3` (PRD-022 Phase 2 COMPLETE + PRD-026) — 16/22 skills MCP-first + 6 Tier B classified, 17 canonical agents with B2 paradigm, CRUD-R-A profile matrix awareness

**Idempotency check** — read CLAUDE.md and look for **any** marker:

| Marker found | Action |
|---|---|
| `<!-- forgeplan-operating-contract:v3 -->` | ✓ Latest version present — skip silently, continue to step 8 |
| `<!-- forgeplan-operating-contract:v2 -->` (only) | Prior version present (PRD-021 era; pre-Phase 2 closure). Prompt user to **upgrade to v3** (one yes/no). On yes: replace `:v2` block with `:v3` block. On no: leave alone, continue. |
| `<!-- forgeplan-operating-contract:v1 -->` (only) | Legacy version (PRD-018 era; pre-MCP). Prompt user to **upgrade to v3** (skips v2). On yes: replace `:v1` block with `:v3` block. On no: leave alone, continue. |
| Neither present | Prompt user once (default yes per step-3 plan approval) to inject `:v3` block fresh |

```
Inject the forgeplan operating contract into CLAUDE.md (v3 — Phase 2 complete + canonical agents)?
It tells future agents to use forgeplan as source-of-truth on every non-trivial
task — search before creating, claim before working, evidence after finishing,
preferring mcp__forgeplan__* tools over shell, and dispatching to canonical
B2-paradigm agents (Profile A creator / B reviewer / C-coder / D maintainer)
when artifact lifecycle operations are needed. [y/n]
```

If user says no — skip; do not warn again.

If yes — append the following `:v3` block (or replace `:v1`/`:v2` block if upgrading):

```markdown
<!-- forgeplan-operating-contract:v3 -->
## Forgeplan operating contract (this project)

Forgeplan is the source of truth for artifacts in this project. On every non-trivial task you MUST follow this workflow.

**Tool selection** — if Claude Code's deferred-tools list contains `mcp__forgeplan__*` tools (forgeplan MCP server wired in `.mcp.json` and reachable), **prefer the MCP path** over shell. MCP returns typed dicts and includes a `_next_action` field on every response — relay that to your reports. If MCP tools are absent, fall back to shell `forgeplan` CLI. If neither works (`command -v forgeplan` fails), warn once at session start and proceed without artifact ops.

**Before** — `forgeplan_search` (or shell `forgeplan search`) then `forgeplan_list status=draft`. Find related artifacts before creating new ones.
**During** (multi-agent / artifact-driven) — `forgeplan_claim id=<ID> agent=<name>` per teammate before they start; `forgeplan_dispatch agents=N` for parallel-safe wave grouping.
**After** — `forgeplan_new kind=evidence title=...` + `forgeplan_link source=EVID-MMM target=<ARTIFACT-ID> relation=informs` + `forgeplan_score id=<ARTIFACT-ID>` + `forgeplan_activate id=<ARTIFACT-ID>` if R_eff > 0.

**Agent dispatch** — for artifact lifecycle operations, prefer dispatching the right canonical agent (PRD-026, B2 paradigm with `disallowedTools` denylist) over doing the work yourself. Profile A creators (artifact-author, adr-architect, specification, architecture, brief-intake, goal-planner, evidence-recorder) for CREATE; Profile B reviewers (artifact-reviewer, code-reviewer, security-expert, architect-reviewer, tester, system-dev, guardian-gate) for REVIEW+EVID; Profile C-coder (coder) for source-file mutations only; Profile D maintainer (artifact-maintainer) for in-place artifact metadata fixes. See `plugins/fpl-skills/AGENT-AUTHORING-GUIDE.md` for the full CRUD-R-A matrix.

**Skill awareness** — 16 of 22 fpl-skills are MCP-first with CLI fallback (audit, autorun, briefing, build, c4-diagram, ddd-decompose, diagnose, fpl-init, gh-project, refine, research, restore, rfc, riper, shape, sprint). 6 are explicitly classified as no-forgeplan (do, team, bootstrap, setup, forge-report, migrate-from-dev-toolkit) — they delegate or operate on local files only.

This is enforcement, not recommendation. Skipping leaves the artifact graph empty — `forgeplan_health` will flag orphans / missing evidence / stale stubs.
```

The marker `<!-- forgeplan-operating-contract:v3 -->` is **load-bearing**: re-running `/fpl-init` keys off this marker to detect already-current state. The `:v1`/`:v2` → `:v3` upgrade path preserves user-customised content above/below the contract block by replacing only the marker-delimited region.

**Migration implementation** (Python — same pattern as `.mcp.json` merge):

```bash
python3 - <<'PY'
import re, pathlib

V3_BLOCK = '''<!-- forgeplan-operating-contract:v3 -->
## Forgeplan operating contract (this project)

Forgeplan is the source of truth for artifacts in this project. On every non-trivial task you MUST follow this workflow.

**Tool selection** — if Claude Code's deferred-tools list contains `mcp__forgeplan__*` tools (forgeplan MCP server wired in `.mcp.json` and reachable), **prefer the MCP path** over shell. MCP returns typed dicts and includes a `_next_action` field on every response — relay that to your reports. If MCP tools are absent, fall back to shell `forgeplan` CLI. If neither works (`command -v forgeplan` fails), warn once at session start and proceed without artifact ops.

**Before** — `forgeplan_search` (or shell `forgeplan search`) then `forgeplan_list status=draft`. Find related artifacts before creating new ones.
**During** (multi-agent / artifact-driven) — `forgeplan_claim id=<ID> agent=<name>` per teammate before they start; `forgeplan_dispatch agents=N` for parallel-safe wave grouping.
**After** — `forgeplan_new kind=evidence title=...` + `forgeplan_link source=EVID-MMM target=<ARTIFACT-ID> relation=informs` + `forgeplan_score id=<ARTIFACT-ID>` + `forgeplan_activate id=<ARTIFACT-ID>` if R_eff > 0.

**Agent dispatch** — for artifact lifecycle operations, prefer dispatching the right canonical agent (PRD-026, B2 paradigm with `disallowedTools` denylist) over doing the work yourself. Profile A creators (artifact-author, adr-architect, specification, architecture, brief-intake, goal-planner, evidence-recorder) for CREATE; Profile B reviewers (artifact-reviewer, code-reviewer, security-expert, architect-reviewer, tester, system-dev, guardian-gate) for REVIEW+EVID; Profile C-coder (coder) for source-file mutations only; Profile D maintainer (artifact-maintainer) for in-place artifact metadata fixes. See `plugins/fpl-skills/AGENT-AUTHORING-GUIDE.md` for the full CRUD-R-A matrix.

**Skill awareness** — 16 of 22 fpl-skills are MCP-first with CLI fallback (audit, autorun, briefing, build, c4-diagram, ddd-decompose, diagnose, fpl-init, gh-project, refine, research, restore, rfc, riper, shape, sprint). 6 are explicitly classified as no-forgeplan (do, team, bootstrap, setup, forge-report, migrate-from-dev-toolkit) — they delegate or operate on local files only.

This is enforcement, not recommendation. Skipping leaves the artifact graph empty — `forgeplan_health` will flag orphans / missing evidence / stale stubs.'''

p = pathlib.Path("CLAUDE.md")
txt = p.read_text() if p.exists() else ""

if "<!-- forgeplan-operating-contract:v3 -->" in txt:
    print("v3 already present, no change")
elif "<!-- forgeplan-operating-contract:v2 -->" in txt:
    # Replace v2 block (marker through end of contract section)
    pattern = r'<!-- forgeplan-operating-contract:v2 -->.*?(?=\n---|\n## (?!Forgeplan)|\Z)'
    new_txt = re.sub(pattern, V3_BLOCK, txt, count=1, flags=re.DOTALL)
    p.write_text(new_txt)
    print("upgraded :v2 → :v3")
elif "<!-- forgeplan-operating-contract:v1 -->" in txt:
    # Replace v1 block — skip v2 intermediate
    pattern = r'<!-- forgeplan-operating-contract:v1 -->.*?(?=\n---|\n## (?!Forgeplan)|\Z)'
    new_txt = re.sub(pattern, V3_BLOCK, txt, count=1, flags=re.DOTALL)
    p.write_text(new_txt)
    print("upgraded :v1 → :v3 (skipped v2)")
else:
    p.write_text(txt.rstrip() + "\n\n" + V3_BLOCK + "\n")
    print("v3 injected fresh")
PY
```

**Verify**: `grep -q 'forgeplan-operating-contract:v3' CLAUDE.md` returns 0. Echo "✓ operating contract v3 injected" / "✓ upgraded v2 → v3" / "✓ upgraded v1 → v3" / "✓ v3 already present, skipped" depending on path taken.

### 8. Run `/setup` flow

If `docs/agents/` is missing, invoke the setup wizard inline. Per
[`setup`](../setup/SKILL.md):

1. Section A — issue tracker (probe Orchestra/GitHub/Linear/local).
2. Section B — build & test commands (auto-detect from `package.json` /
   `Cargo.toml` / `pyproject.toml` / `Makefile`).
3. Section C — project paths (RFC dir, TODO file, ADR dir, docs).
4. Section D — domain glossary (offer to create starter `CONTEXT.md`).

Each section gets one user confirmation. The user already approved the
overall flow in step 3, so don't re-ask "shall we run setup?" — just go
through the sections.

At the end, append the `## Agent skills` block to `CLAUDE.md` (with user
yes; that's setup's final step).

### 8.5. Canonical agent layer (v2.0 — PRD-026 Phase 5)

Optional, additive. Scaffolds the **canonical agent layer** for
forgeplan-aware projects: `project-agent-matrix.yaml` (phase × agent ×
methodology dispatch rules) + `project-config.yaml` (depth defaults,
quality-gate thresholds, autonomy levels) + Hindsight bank baseline. See
PRD-026 Journey 2 for the full vision.

This is **additive to v1**: if the user runs `/fpl-init` without
`--canonize` and answers "n" to the prompt below, behaviour is identical
to v1 — no new files written.

#### 8.5.1 — Decision: skip or apply?

| Project condition | Action |
|---|---|
| `.forgeplan/project-agent-matrix.yaml` exists | Skip (don't overwrite — user's customisation) |
| `forgeplan` MCP tools not detected (`mcp__forgeplan__*` absent from deferred-tools) | Skip (canonical layer requires forgeplan MCP) |
| User explicitly passed `--no-canonize` | Skip |
| User explicitly passed `--canonize` | Apply (forced) |
| Default (none of above) | Ask user: "Scaffold canonical agent layer (project-agent-matrix.yaml + project-config.yaml)? [Y/n]" |

If skipping for any reason — print one line ("canonical layer: skipped (<reason>)") and continue to step 9. Do not warn or re-prompt.

#### 8.5.2 — Copy templates

Templates ship with the `fpl-skills` plugin at
`fpl-skills/templates/`. Locate them via `$CLAUDE_PLUGIN_ROOT` if
available; fall back to the marketplace install path:

```bash
# Locate templates (installed via fpl-skills plugin)
PLUGIN_TEMPLATES="${CLAUDE_PLUGIN_ROOT:-}/templates"
# Fallback: search marketplace plugin install location
if [ ! -d "$PLUGIN_TEMPLATES" ]; then
    PLUGIN_TEMPLATES="$HOME/.claude/plugins/marketplaces/ForgePlan-marketplace/plugins/fpl-skills/templates"
fi

mkdir -p .forgeplan

# Copy if templates exist; warn clearly otherwise
if [ -f "$PLUGIN_TEMPLATES/project-agent-matrix.yaml" ]; then
    cp "$PLUGIN_TEMPLATES/project-agent-matrix.yaml" .forgeplan/project-agent-matrix.yaml
    echo "✓ project-agent-matrix.yaml copied"
else
    echo "WARN: template not found at $PLUGIN_TEMPLATES/project-agent-matrix.yaml"
    echo "      please copy manually from fpl-skills/templates/ in the marketplace repo"
fi

if [ -f "$PLUGIN_TEMPLATES/project-config.yaml" ]; then
    cp "$PLUGIN_TEMPLATES/project-config.yaml" .forgeplan/project-config.yaml
    echo "✓ project-config.yaml copied"
else
    echo "WARN: template not found at $PLUGIN_TEMPLATES/project-config.yaml"
    echo "      please copy manually from fpl-skills/templates/"
fi
```

Do **not** embed full YAML heredocs in this skill body — that would
duplicate the templates and defeat the purpose of shipping them with the
plugin. The WARN messages point to the canonical location.

Immediately after copying, stamp a marker comment so future `/fpl-init`
runs detect prior canonize:

```bash
# Stamp v2.0 marker at top of project-agent-matrix.yaml.
# Use a quoted heredoc + os.environ to avoid shell injection from $STAMP content.
export FPL_INIT_STAMP="# Created by fpl-init v2.0 / $(date -u +%Y-%m-%dT%H:%M:%SZ)"
python3 - <<'PY'
import os, pathlib
p = pathlib.Path(".forgeplan/project-agent-matrix.yaml")
if p.exists():
    txt = p.read_text()
    if "Created by fpl-init v2.0" not in txt:
        p.write_text(os.environ["FPL_INIT_STAMP"] + "\n" + txt)
PY
unset FPL_INIT_STAMP
```

#### 8.5.3 — Customise (interactive — orchestrator asks user)

After copying, prompt the user for the four values the templates
parameterise. Use sensible defaults so a quick-bootstrap user can just
hit Enter four times:

| Prompt | Default | Choices |
|---|---|---|
| `project_name` | `basename "$PWD"` | (free text) |
| `domain` | `fullstack` | backend / frontend / fullstack / mobile / data / embedded / other |
| `language` | (detect from `package.json`/`Cargo.toml`/`pyproject.toml`; else `other`) | typescript / python / go / rust / java / other |
| `autonomy.default_level` | `3` | 1=ask-everything / 2=ask-major / 3=mostly-autonomous / 4=autonomous-with-checkpoints / 5=fully-autonomous |

Then patch both YAML files with the user's choices. Prefer `python3` for
the patch (it round-trips YAML safely; `sed` works for simple key:value
swaps but corrupts nested structures):

```bash
# Export user choices as environment variables so the Python patch script can read
# them via os.environ — quoted heredoc prevents shell interpolation into Python regex,
# which would corrupt the regex if a value contained quotes, dollar signs, or backslashes.
export PROJECT_NAME="${PROJECT_NAME:-$(basename "$PWD")}"
export DOMAIN="${DOMAIN:-fullstack}"
export LANGUAGE="${LANGUAGE:-other}"
export AUTONOMY="${AUTONOMY:-3}"
# Derive Hindsight bank_id from project_name (kebab-case, org-prefixed if applicable).
export BANK_ID="${BANK_ID:-$(echo "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-\|-$//g')}"

python3 - <<'PY'
import os, pathlib, re

PROJECT_NAME = os.environ["PROJECT_NAME"]
DOMAIN       = os.environ["DOMAIN"]
LANGUAGE     = os.environ["LANGUAGE"]
AUTONOMY     = os.environ["AUTONOMY"]
BANK_ID      = os.environ["BANK_ID"]

def replace_re(txt, pattern, replacement):
    return re.sub(pattern, replacement, txt, count=1, flags=re.MULTILINE)

# project-agent-matrix.yaml: project_name + domain + language + hindsight.bank_id
p = pathlib.Path(".forgeplan/project-agent-matrix.yaml")
if p.exists():
    txt = p.read_text()
    txt = replace_re(txt, r'^(project_name:\s*).*$',         f'\\g<1>"{PROJECT_NAME}"')
    txt = replace_re(txt, r'^(domain:\s*).*$',               f'\\g<1>{DOMAIN}')
    txt = replace_re(txt, r'^(language:\s*).*$',             f'\\g<1>{LANGUAGE}')
    txt = replace_re(txt, r'^(\s*bank_id:\s*).*$',           f'\\g<1>"{BANK_ID}"')
    p.write_text(txt)

# project-config.yaml: autonomy.default_level
p = pathlib.Path(".forgeplan/project-config.yaml")
if p.exists():
    txt = p.read_text()
    txt = replace_re(txt, r'^(\s*default_level:\s*).*$', f'\\g<1>{AUTONOMY}')
    p.write_text(txt)
PY

unset PROJECT_NAME DOMAIN LANGUAGE AUTONOMY BANK_ID
```

If the user passed `--canonize --yes` (or hit Enter four times), use the
defaults silently — don't dump a "4 prompts answered" block.

#### 8.5.4 — Hindsight bank baseline (optional)

If `mcp__plugin_fpl-hsmem_hindsight__*` tools are available in the
deferred-tools list (Hindsight MCP wired), set the bank's persona once:

```
memory_set_mission(
  content="Forgeplan-aware project: <project_name>. Domain: <domain>. Language: <language>."
)
```

This is a **one-time** call per project bank — re-running `/fpl-init`
later should skip (mission already set). Check via `memory_status` first
if you want to be defensive.

The orchestrator should be aware of **5 baseline mental models** that
agents create lazily on first need (per Hindsight v2.0 convention — do
**not** pre-create empty ones here):

| Mental model ID | Purpose | Created by (lazy) |
|---|---|---|
| `mm-pipeline-methodology` | Execution-flow reasoning | Profile B execution reviewers |
| `mm-gate-failures` | Prior gate decisions | Profile B gate-style reviewers |
| `mm-fpf-examples` | FPF Abduction-Deduction-Induction cycle examples | Profile A creators |
| `mm-agent-selection` | When to dispatch which agent | Matrix dispatcher |
| `mm-branch-decision` | Git branch decisions (feat/fix/chore mapping) | Branch-deciding agents |

Print the list to the user so they know what will appear in their bank
over time:

```
Hindsight bank: mission set. 5 baseline mental models will be created
lazily by agents on first need (mm-pipeline-methodology, mm-gate-failures,
mm-fpf-examples, mm-agent-selection, mm-branch-decision). No action needed.
```

If Hindsight MCP is not wired — skip this sub-step silently.

#### 8.5.5 — Project-scoped agents (deferred to Phase 6)

Document but **don't yet implement**: `.claude/agents/<name>.md` copies
of marketplace agents for project-scoped customisation. This is Phase 6
work (orchestrator integration — see PRD-026 Phase 6). For now, projects
rely on marketplace pack agents via `agents-pro:<name>` dispatch through
the matrix.

Print one line so the user isn't surprised when `.claude/agents/` stays
empty:

```
Project-scoped agents: not copied (Phase 6 work). Marketplace pack
agents (agents-pro, agents-core, ...) dispatched via project-agent-matrix.yaml.
```

#### 8.5.6 — Validate

```bash
# Verify the 2 YAML files parse
python3 -c "import yaml; yaml.safe_load(open('.forgeplan/project-agent-matrix.yaml'))" && echo "✓ matrix OK"
python3 -c "import yaml; yaml.safe_load(open('.forgeplan/project-config.yaml'))" && echo "✓ config OK"

# If forgeplan CLI available: forgeplan health (picks up the new files)
command -v forgeplan >/dev/null 2>&1 && forgeplan health 2>/dev/null | head -10
```

If either YAML fails to parse — surface the error, back up the broken
file to `.forgeplan/<name>.yaml.bak`, and tell the user to re-copy
manually from `fpl-skills/templates/`. Don't continue to step 9 with a
broken matrix; downstream `/forge-cycle` runs would fail at Step 0.5.

### 9. Recommend companion plugins

**Print, don't install.** Show the user a copy-paste block:

```
Recommended companion plugins (run these manually if you want them):

  /plugin install fpf@ForgePlan-marketplace
      First Principles Framework — pairs with /refine and /diagnose.

  /plugin install agents-core@ForgePlan-marketplace
      11 baseline subagents — /audit and /sprint use them when present.

  /plugin install forgeplan-workflow@ForgePlan-marketplace
      /forge-cycle and /forge-audit — tighter forgeplan-only flow.

  /plugin install forgeplan-orchestra@ForgePlan-marketplace
      /sync and /session — multi-session coordination.

  /plugin install laws-of-ux@ForgePlan-marketplace
      Frontend UX reviewer — /audit will spawn it when changesets are
      frontend-heavy. Skip if this repo is backend-only.
```

Don't try to detect "is this a frontend repo" beyond a one-line probe
(`test -f package.json && grep -q -E '(react|vue|svelte|angular|next|nuxt)' package.json`).
If unsure, leave laws-of-ux in the list with the caveat.

### 10. Verify

Run a final health check:

```bash
forgeplan health 2>/dev/null | head -10
ls docs/agents/ 2>/dev/null
head -20 CLAUDE.md 2>/dev/null
test -f .mcp.json && echo "✓ .mcp.json wired"
```

Expected: forgeplan reports healthy, `docs/agents/` has 4 files
(issue-tracker / build-config / paths / domain), `CLAUDE.md` first lines
show project name, `.mcp.json` exists.

### 11. Report

Final summary in a single block:

```
✓ forgeplan init           done · .forgeplan/ created · X artifacts
✓ .mcp.json                wired (forgeplan + N existing servers preserved)
✓ .claude/settings.json    safety hook added       (or "skipped per user")
✓ CLAUDE.md                created from template   (or "appended")
✓ Operating contract       injected into CLAUDE.md (or "already present" / "skipped per user")
✓ docs/agents/             configured (4 files)
✓ CONTEXT.md               created starter         (or "skipped — exists")
✓ Canonical agent layer    project-agent-matrix.yaml + project-config.yaml (or "skipped per user / already present / no forgeplan MCP")
✓ Hindsight bank mission   set                     (or "skipped — Hindsight MCP not wired")

Next steps:
  /restore        — recover context after a break
  /briefing       — today's tasks from your tracker
  /research <q>   — deep multi-agent research
  /refine <plan>  — sharpen an RFC or implementation plan
  /sprint <task>  — wave-based execution
  /audit          — multi-expert code review
  /diagnose <bug> — disciplined 6-phase debug loop
  /autorun <task> — overnight autopilot

Optional companion plugins listed above. Run them at your own pace.
```

If any step in the plan failed — replace its ✓ with ✗ and show the error.

---

## Idempotency

`/fpl-init` should be safe to re-run. Re-runs:

- Detect what's already in place (step 1) and skip those branches.
- Never overwrite existing `CLAUDE.md` content (always append).
- Operating contract injection (step 7-bis) keys off markers `<!-- forgeplan-operating-contract:v2 -->` (current) or `<!-- forgeplan-operating-contract:v1 -->` (legacy — prompts user to upgrade) — re-runs detect and skip without prompting if v2 already present.
- Never overwrite existing `.mcp.json` entries (always merge).
- Never overwrite existing `docs/agents/*.md` (`/setup` re-prompts).
- Canonical agent layer (step 8.5) keys off `.forgeplan/project-agent-matrix.yaml` existence + the `# Created by fpl-init v2.0` stamp — re-runs detect and skip the copy. Re-canonize requires manual deletion of the matrix file or explicit `--canonize` (which currently still skips if the file exists — to force overwrite, delete it first).

If everything is already in place, the skill prints "already initialized"
and exits without changes.

## Errors and recovery

| Symptom | Action |
|---|---|
| `forgeplan` not on `$PATH` | Print install instructions (step 2) and stop. |
| `forgeplan init` fails | Surface stderr; stop before the rest of the plan. Don't try to wire MCP for a broken artifact store. |
| `.mcp.json` is invalid JSON | Don't merge — back up to `.mcp.json.bak`, write a fresh minimal version, tell the user to merge their old config back in. |
| Stack detection in step 7 returns nothing | Leave placeholders visible (`{{LANG}}`, `{{PKG_MANAGER}}`) — better than guessing. |
| User aborts at step 3 | Exit cleanly, no files touched. |
| User aborts mid-flow | Stop after the current step; don't roll back already-written files. Print "partial init: completed steps X, Y; skipped Z. Re-run /fpl-init when ready." |

## Related skills

- [`bootstrap`](../bootstrap/SKILL.md) — `/fpl-init` calls bootstrap's
  workflow inline. Use `/bootstrap` directly for CLAUDE.md only.
- [`setup`](../setup/SKILL.md) — same. Use `/setup` directly to (re)run
  the docs/agents wizard.
- [`restore`](../restore/SKILL.md) — first thing to run after `/fpl-init`
  in subsequent sessions to recover context.

## Anti-patterns

- ❌ Don't install companion plugins automatically. `/plugin install` is
  host-level; the user must approve each one.
- ❌ Don't pause for approval at every substep. The user approved the
  whole flow in step 3; subsequent pauses just slow them down.
- ❌ Don't overwrite `.mcp.json` blindly — always merge.
- ❌ Don't run on a marketplace/plugin source. The signature
  (`.claude-plugin/` or `plugins/*/`) is your guard rail.
- ❌ Don't fabricate forgeplan output. If `forgeplan health` errors,
  show the actual error rather than a green checkmark.
