---
name: csetup
description: Initialize Correctless and run a project health check. Detects stack, configures workflow, bootstraps docs, checks security/quality/CI/testing hygiene, and offers to fix gaps. Adapts to project maturity — greenfield, early-stage, or mature.
allowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebSearch, WebFetch
interaction_mode: interactive
---

# /csetup — Initialize Correctless

> **Shared constraints apply.** Before executing, read `_shared/constraints.md` from the parent of this skill's base directory. All constraints there apply to this skill.

You are the onboarding agent. Your job is to get a project from zero to ready-to-use in one interactive conversation. Don't just run a script and dump output — guide the human through each decision.

**Setup is adaptive.** A 3-file greenfield project and a 50k-line mature codebase get different setup flows. Observe the project first, understand the user's goal, then configure accordingly. Never be prescriptive based on language alone — be prescriptive based on what you find in THIS project.

## Checkpoint Resume

If `/csetup` is interrupted (context compaction, user stops, error), save a checkpoint so re-running picks up where it left off.

**Checkpoint file:** `.correctless/artifacts/checkpoint-csetup.json`

```json
{
  "last_completed_step": 3,
  "branch": "main",
  "maturity": "early-stage",
  "user_goal": "REST API with auth",
  "detected": {
    "language": "typescript",
    "test_runner": "vitest",
    "package_manager": "pnpm"
  },
  "health_check_tier1_done": false,
  "mcp_step_completed": false,
  "timestamp": "2026-03-29T14:30:00Z"
}
```

**On startup:** Check for this file. If it exists and `timestamp` is within 24 hours **and `branch` matches the current branch**:
- "I see a previous setup was interrupted at Step {N}. Want to resume from there, or start fresh?"
- If resume: re-count source files silently. If the count has crossed a maturity boundary (e.g., was < 10 files, now has 25), warn: "Your project has grown since the last setup attempt — it was {old maturity} but now looks {new maturity}. I recommend starting fresh." Otherwise, skip completed steps, restore detected values, continue from `last_completed_step + 1`. **Note:** Step 2.5 (MCP Server Integration) uses `mcp_step_completed` as a separate boolean — if `last_completed_step` is 2 and `mcp_step_completed` is false, resume from Step 2.5. If `mcp_step_completed` is true, resume from Step 3.
- If start fresh: delete the checkpoint file, begin from Step 0
- If branch doesn't match: delete the stale checkpoint, begin from Step 0

**Update the checkpoint** after each step completes. Delete it when setup finishes successfully.

## Step 0: Understand What You're Working With

Before configuring anything, understand the project and the user's situation. This step is silent — don't narrate the counting. Just do it and present your understanding.

### Project Maturity Assessment

Count and classify silently:

1. **Source files**: Glob for language-specific patterns (`*.ts`, `*.go`, `*.py`, `*.rs`, `*.java`, `*.rb`, `*.swift`, etc.). Exclude `node_modules/`, `vendor/`, `dist/`, `build/`, `.next/`, `__pycache__/`, `target/`.
2. **Test suite**: Do test files exist? Is there a test config (jest.config, vitest.config, pytest.ini, etc.)?
3. **CI**: Do CI config files exist (`.github/workflows/`, `.gitlab-ci.yml`, etc.)?
4. **Documentation**: Does `README.md` have real content (not just framework boilerplate)? Does `.correctless/ARCHITECTURE.md` or similar exist?
5. **Git history**: How many commits? How old is the repo? Use `git rev-list --count HEAD 2>/dev/null || echo 0` and `git log --reverse --format=%ci 2>/dev/null | head -1`. If either command fails (zero-commit repo, not a git repo), treat commit count as 0 and age as "new".

Classify as:

- **Greenfield** (< 10 source files, < 10 commits): The user is starting something new. Don't overwhelm with setup. Ask what they're building. Create minimal config and get out of the way.
- **Early-stage** (10-100 source files): The project has some structure but conventions are still forming. Mine what exists, suggest gentle defaults for gaps.
- **Mature** (100+ source files, existing CI/tests/docs): The project has established patterns. Your job is to learn them, not replace them.

### Ask the User ONE Question

Based on maturity, ask exactly one question before proceeding:

- **Greenfield**: "I see a new {language} project with {N} files. What are you building? (e.g., REST API, CLI tool, web app, library) — this helps me set up sensible defaults."
- **Early-stage**: "I see a {language} project with {N} files, {test runner if detected}, {notable frameworks}. Before I scan for patterns, is there anything specific about how this project is structured that I should know?"
- **Mature**: "I see a mature {language} project with {N} files, {test framework}, and {CI system}. I'll learn your existing patterns — this takes a minute."

For mature projects, the "question" is really a notification — proceed to scanning after saying it. Don't wait for a response unless the user offers one. If the user does volunteer context about what the project is for, capture it as `user_goal`.

**The user's answer informs everything downstream.** "Building a real-time collaborative editor" means different architectural concerns than "building a CRUD API." Don't make architecture suggestions until you understand the domain.

**If `user_goal` is absent** (mature project where the user didn't volunteer context, or early-stage project where the user said "nothing specific"): downstream steps that filter by goal (Step 5) fall back to the "Generic/unclear" path — present the top 5-7 most impactful findings across all categories.

**Save the initial checkpoint immediately** with `last_completed_step: 0`, `branch` (current branch name), `maturity`, and `user_goal` (if provided). Setting `last_completed_step: 0` ensures that if setup crashes before Step 1 completes, resume starts at Step 1 — not at an undefined step.

## Progress Visibility (MANDATORY)

Setup on existing projects takes several minutes. The user must see progress throughout.

**Before starting Step 1**, create a task list adapted to maturity:

**Greenfield task list:**
1. Detect project (language, package manager)
2. Run setup script
3. Configure MCP servers (if available)
4. Confirm configuration
5. Bootstrap docs (.correctless/ARCHITECTURE.md + .correctless/AGENT_CONTEXT.md)
6. Security quick-check (secrets scan)
7. Source control defaults
8. First feature guidance

**Early-stage task list:**
1. Detect project (language, test runner, package manager)
2. Run setup script
3. Configure MCP servers (if available)
4. Confirm configuration
5. Discover architecture
6. Mine conventions
7. Bootstrap .correctless/AGENT_CONTEXT.md
8. Health check
9. Source control configuration
10. First feature guidance

**Mature task list:**
1. Detect project (language, test runner, package manager, monorepo)
2. Run setup script
3. Configure MCP servers (if available)
4. Confirm configuration
5. Discover architecture (merge mode)
6. Mine conventions (comprehensive)
7. Bootstrap .correctless/AGENT_CONTEXT.md
8. Health check (full)
9. Source control configuration
10. First feature guidance

**Between each step**, print a 1-line status: "Project detected — TypeScript with vitest. Running setup script..." During the health check, announce each category as it completes: "Security checks done — 3/4 passing. Running code quality checks..."

Mark each task complete as it finishes.

## Step 1: Detect the Project

Scan the project root silently. Then present findings conversationally:

- Language (from manifest files: go.mod, package.json, Cargo.toml, pyproject.toml)
- Test runner and commands
- Package manager (npm, pnpm, yarn, pip, cargo)
- Existing config (if `.correctless/config/workflow-config.json` already exists)

**Monorepo detection:**
- Check for: `pnpm-workspace.yaml`, `lerna.json`, `nx.json`, `turbo.json`, `rush.json`, `go.work`, `Cargo.toml` with `[workspace]`, `package.json` with `"workspaces"`
- **Greenfield monorepos** (monorepo markers present but < 10 source files): Note the monorepo type in the config (`is_monorepo: true`, `monorepo_type`), but skip per-package enumeration — there's nothing useful to detect yet. Tell the user: "Found monorepo scaffold ({type}) but packages are mostly empty. I'll set `is_monorepo: true` in the config. Re-run `/csetup` once packages have code to configure per-package commands."
- **Early-stage/Mature monorepos**: enumerate packages by scanning for manifest files (`package.json`, `go.mod`, `Cargo.toml`) under workspace roots. For each package: detect language, test runner, linter independently. Present: "Found monorepo ({type}) with {N} packages: `packages/api` (Go), `packages/web` (TypeScript). I'll configure each package's test/lint commands independently." If the user confirms: generate the `packages` section in `workflow-config.json` with per-package commands and patterns

Present: "I see a TypeScript project using pnpm with vitest. Does that look right, or should I adjust anything?"

If something looks wrong, let the human correct it before proceeding.

## Step 2: Run the Setup Script

Tell the user what this step does before running: "I'll run the setup script now — it creates the `.correctless/artifacts/` directory, registers workflow hooks, and generates a config template. It does not modify your application source code, but it creates/updates `.claude/settings.json` (hook registration) and `scripts/lib.sh` (shared utilities)."

Then run the setup script to do the mechanical work:

```bash
# Backward-compat: check correctless-lite path for users migrating from the old
# two-distribution layout. Once migration adoption is complete, remove that line.
setup_found=false
for dir in \
  ~/.claude/plugins/cache/correctless/correctless/*/ \
  ~/.claude/plugins/cache/correctless/correctless-lite/*/ \
  .claude/skills/workflow/; do
  if [ -f "${dir}setup" ]; then
    "${dir}setup"
    setup_found=true
    break
  fi
done

# If no setup script found, tell the human
if [ "$setup_found" = false ]; then
  echo "Could not find Correctless setup script. Provide the install path or run setup manually."
fi
```

## Step 2.5: MCP Server Integration (Serena + Context7)

This step offers to configure Serena (symbol-level code analysis) and Context7 (up-to-date library documentation) MCP servers. It appears between Step 2 (Run Setup Script) and Step 3 (Review Config Interactively).

### Detection

Check the following before presenting the offer:

1. **Existing `.mcp.json`**: Read the project root for `.mcp.json`. If it exists, check whether it is valid JSON. If `.mcp.json` exists but isn't valid JSON, warn the user: "`.mcp.json` exists but isn't valid JSON — I won't modify it. Fix it manually or delete it and re-run `/csetup`." Skip MCP config writing entirely. Do NOT overwrite or delete the corrupt file. If `.mcp.json` is valid JSON but has no `mcpServers` key (or the key's value is not an object), treat it as no servers configured — proceed to the Offer step and create a new `mcpServers` object when writing.

2. **Already configured check**: If `.mcp.json` exists and is valid JSON, check the `mcpServers` object for key presence of `serena` and `context7`. Check for the key's *presence* in the `mcpServers` object, not its *value* — a user with a custom Serena config (different args, different transport) should not have their config overwritten by the default. If both keys are present, skip the MCP offer and report: "Serena ✓ Context7 ✓ (already configured)". If only one server key is present in `mcpServers`, skip the offer for the already-configured server. Present a two-option offer for the missing one: "install {missing server}" or "skip". Report the present server as "✓ (already configured)" before the offer.

3. **Tooling detection**: Check for `uv` (or `uvx`) and `npx` binaries in PATH. Serena requires `uv`/`uvx`, Context7 requires `npx`.

4. **Serena usefulness check**: Serena's value depends on both language support AND project size. Assess before offering:

   **Strong recommendation** (offer Serena by default) — project language is Python, TypeScript/JavaScript, Go, Rust, Java, C#, C/C++, Ruby, PHP, Kotlin, Scala, or Swift, AND the project has 20+ source files. These languages have mature language servers and enough code to benefit from symbol-level navigation.

   **Available but limited** (offer with caveat) — project language is Bash, Lua, Dart, Elixir, Haskell, Erlang, F#, Clojure, OCaml, Perl, R, Zig, or another language with Serena language server support, OR the project has fewer than 20 source files in a supported language. Show: "Serena supports {language} but symbol-level analysis is most valuable in larger codebases. Your project has {N} source files — it may not save much over grep/read at this size. Want to try it anyway?"

   **Not useful** (skip Serena offer entirely) — `project.language` is `"other"` with no recognizable language, OR the project is primarily Markdown/config/prose with fewer than 10 source code files. Do not offer Serena — it won't provide value. Only offer Context7 (if applicable). Tell the user: "Serena provides symbol-level code analysis but isn't useful for this project type. Skipping. Context7 (library docs) is still available."

### Offer

When **neither** server is configured and Serena passes the usefulness check, present MCP as a single decision with numbered options:

```
MCP server integration:
  1. Both Serena + Context7 (recommended) — symbol analysis and library docs
  2. Just Serena — symbol-level code analysis only
  3. Just Context7 — up-to-date library documentation only
  4. Skip — no MCP servers

  Or type your own: ___
```

When Serena does not pass the usefulness check, present only: **Context7** or **skip**. When only one server is already configured, present a two-option offer for the missing one (as described in the Detection section above). The offer only appears when at least one server is not yet configured AND the required tooling is available.

### Tooling Prerequisites

If `uv` is not installed and the user wants Serena, print installation instructions but do NOT attempt to install `uv` automatically — system-level package installation is the user's responsibility. Same for `npx`/Node.js and Context7.

### Writing `.mcp.json`

When writing `.mcp.json` in the project root, use this template with version-pinned dependencies:

```json
{
  "mcpServers": {
    "serena": {
      "command": "uvx",
      "args": [
        "-p", "3.13",
        "--from", "git+https://github.com/oraios/serena@v0.1.4",
        "serena-mcp-server",
        "--transport", "stdio"
      ]
    },
    "context7": {
      "command": "npx",
      "args": [
        "-y",
        "@context7/mcp@2.1.6"
      ]
    }
  }
}
```

**Version pins are mandatory.** Unpinned dependencies pull latest on every invocation, which can break without warning. When Serena or Context7 releases a new version, update the pins in this skill file after testing.

If `.mcp.json` already exists with other MCP server entries, merge the new entries into the existing `mcpServers` object. Existing entries are never overwritten or removed — only new keys are added. Use `jq` if available: `jq '.mcpServers = ({"serena": {...}, "context7": {...}} + .mcpServers)' .mcp.json > .mcp.json.tmp && mv .mcp.json.tmp .mcp.json` (in jq's `+` for objects, the right-hand side wins on collision — existing entries are preserved). If `jq` is not available, use the Read tool to read the file, then Write to output the merged result.

### Creating `.serena.yml`

If Serena is selected, create `.serena.yml` in the project root with:

```yaml
project_name: "{project name detected in Step 1 from the manifest file}"
language: "{detected language from Step 1}"
read_only: false
enable_memories: true
```

Set `project_name` to the project name detected in Step 1 (from the manifest file: `package.json` name, `go.mod` module, `Cargo.toml` package name, `pyproject.toml` project name, etc.), not from `workflow-config.json` which may not be confirmed yet.

Set `language` to the language detected in Step 1. Must be one of Serena's supported language identifiers: `python`, `typescript`, `go`, `rust`, `java`, `c_sharp`, `c_cpp`, `ruby`, `php`, `kotlin`, `scala`, `swift`, `bash`, `lua`, `dart`, `elixir`, `haskell`, etc. **This field is required** — Serena crashes without it.

### `.correctless/` Gitignore Decision

Ask the user whether to gitignore `.correctless/` using structured decision format:

1. **No** (recommended) — keep `.correctless/` tracked in git for team visibility
2. **Yes** — add `.correctless/` to `.gitignore` (specs, decisions, and config will not be committed)

If the user chooses yes, add `.correctless/` to `.gitignore`.

### `.gitignore` Update

Add `.serena/` to `.gitignore` if not already present (Serena stores working data in this directory).

### Updating `workflow-config.json`

After writing MCP configs, update the existing `mcp` section in `workflow-config.json`: set `serena` to `true` if Serena was installed, set `context7` to `true` if Context7 was installed. Use the Edit tool to change the specific flag values. The templates already include `"mcp": {"serena": false, "context7": false}`, so do not add a duplicate section — only update the existing boolean values.

```json
"mcp": {
  "serena": true,
  "context7": true
}
```

Set each flag to `true` only for the servers the user chose to install. Skills read `mcp.serena` and `mcp.context7` as feature flags — boolean values only, no version numbers, no server URLs, no connection details. If the user skipped both, leave the flags as `false`.

## Step 2.6: Scaffold test-features baseline.md (idempotent)

Copy `templates/test-features/baseline.md` from the Correctless distribution to `.correctless/test-features/baseline.md` if and only if the destination does not already exist. This template is consumed by `/cmodelupgrade --capture-baseline` (harness-fingerprint spec) as the controlled-baseline reference feature.

```bash
mkdir -p .correctless/test-features
if [ ! -f .correctless/test-features/baseline.md ]; then
  src=""
  for candidate in \
    "$SCRIPT_DIR/../templates/test-features/baseline.md" \
    "$SCRIPT_DIR/templates/test-features/baseline.md" \
    "$REPO_ROOT/.correctless/templates/test-features/baseline.md"; do
    if [ -f "$candidate" ]; then src="$candidate"; break; fi
  done
  [ -n "$src" ] && cp "$src" .correctless/test-features/baseline.md
fi
```

Idempotency is mandatory — never overwrite an existing baseline.md the user may have customized.

## Step 3: Confirm Configuration

Read the generated `.correctless/config/workflow-config.json`. Present the detected config as a single summary — not field-by-field:

```
Here's what I detected:
- Language: TypeScript
- Test runner: vitest (`pnpm test`)
- Linter: eslint (`pnpm lint`)
- Build: `pnpm build`
- Package manager: pnpm

Does this look right, or should I change anything?
```

If the user says "looks good" — move on immediately. Don't ask about each field. Only dig into details if the user flags something wrong.

**Greenfield**: The config may only have language and package manager detected — no test runner, no build command, no linter. That's fine. Present what was detected and note the gaps: "Language: TypeScript, Package manager: pnpm. No test runner or linter detected yet — these will be configured as you add them." Don't present empty fields.

**Monorepo**: if `is_monorepo` is true, include per-package commands in the summary: "Package `api` — `go test ./...` / `golangci-lint run`. Package `web` — `pnpm test` / `pnpm lint`." One confirmation for all, not per-package interrogation.

**At high+ intensity**: if the config has `workflow.intensity`, include it in the summary: "Intensity: standard (standard skips STRIDE, high adds fail-closed, critical requires formal modeling)." Let the user change it if they want — don't force a question about it.

## Step 4: Discover and Bootstrap .correctless/ARCHITECTURE.md

This step adapts to project maturity.

### Greenfield Projects

Don't try to populate .correctless/ARCHITECTURE.md from a handful of files. A 3-file project doesn't have architecture yet.

**However:** Even with < 10 files, check if there's enough structure to describe. A project with 5 files might have `src/server.ts`, `src/routes/`, `src/db/` — that's a clear layered structure worth capturing. Use judgment: if you can describe the architecture in 2+ meaningful sentences, do it. If all you can say is "there's one file," don't.

If there isn't enough structure:
"Your project is just getting started — I won't try to document architecture from {N} files. As you build features with `/cspec`, patterns will emerge and I'll capture them."

**Important:** Do not leave .correctless/ARCHITECTURE.md with `{PLACEHOLDER}` or `{PROJECT_NAME}` template markers — downstream skills (`/cspec`, `/ctdd`, `/cverify`) treat these markers as a signal that setup was never run and will push the user into an unwanted remediation detour. Instead, write a minimal but real .correctless/ARCHITECTURE.md:

```markdown
# Architecture — {actual project name}

> This project is in early development. Architecture documentation will be populated as patterns emerge through feature development.

## Key Components

*To be documented after initial features are built.*

## Design Patterns

*No established patterns yet.*
```

Update `setup.architecture_state` to `"deferred"` in `workflow-config.json` so subsequent `/csetup` runs know this was intentional, not an error.

If there IS meaningful structure even in a small project, present what you see and ask: "Even though this is a new project, I can already see a {pattern}. Want me to document this in .correctless/ARCHITECTURE.md, or wait until more code exists?" If the user approves and you write content beyond the minimal stub, update `setup.architecture_state` to `"existing"` instead of `"deferred"`.

### Early-stage Projects

Scan the codebase, present findings, but frame as observations — not prescriptions:

"I see you're using {pattern} in {N} files. Should I document this as an established pattern, or is it still evolving?"

Run the scanning protocol (below) but present results with humility. Early-stage projects are still finding their shape — the agent shouldn't lock in patterns prematurely.

After writing .correctless/ARCHITECTURE.md for an early-stage project, update `setup.architecture_state` to `"existing"` in `workflow-config.json` so subsequent runs use merge mode.

### Mature Projects

Full scan + merge mode. This is the existing behavior and it's correct.

Read `.correctless/config/workflow-config.json` field `setup.architecture_state` to determine mode:
- `template` or `missing` → **full bootstrap**: scan the codebase and populate from scratch
- `existing` → **merge mode**: scan, compare with existing content, propose only additions
- `deferred` → **merge mode**: the project was greenfield when last set up and .correctless/ARCHITECTURE.md has minimal content. Scan the codebase and propose additions alongside the existing minimal content. Update the field to `existing` after writing.
- `null` or field absent (older config, or jq was missing at setup time) → **detect manually**: check if .correctless/ARCHITECTURE.md exists and contains real content (no `{PLACEHOLDER}` or `{PROJECT_NAME}` markers). If real content, use merge mode. If template/missing, use full bootstrap.

**For existing projects, tell the user:** "Your project already has an .correctless/ARCHITECTURE.md. I'll scan the codebase and suggest Correctless-specific sections to add alongside your existing content. This may take a moment — I'm learning your project."

### Scanning Protocol

Run these scans in parallel where possible:

**1. Directory structure scan:**
- Glob for structural directories: `src/*/`, `lib/*/`, `internal/*/`, `pkg/*/`, `app/*/`, `packages/*/`, `cmd/*/`
- For each candidate directory, read the directory listing and any index/barrel file to determine its purpose
- Look for architectural layers: `controllers/`, `services/`, `repositories/`, `middleware/`, `models/`, `handlers/`, `routes/`, `utils/`, `hooks/`, `components/`

**2. Pattern mining scan** (grep for these signals):
- **Validation**: zod, joi, yup, class-validator, pydantic, validator imports — note WHERE validation happens (route handlers? middleware? service layer?)
- **Error handling**: custom error classes (`extends Error`, `class.*Error`), error middleware, centralized error handlers
- **Database access**: ORM imports (prisma, sequelize, typeorm, sqlalchemy, gorm, diesel) — is access centralized or scattered?
- **Auth**: JWT, session, OAuth, auth middleware — how does auth flow through the request lifecycle?
- **Config**: `process.env`, `os.Getenv`, `os.environ` — centralized config module or scattered env reads?
- **Logging**: logger imports, `console.log` vs structured logging (winston, pino, slog, logrus)
- **State management**: Redux, Zustand, Context, signals, stores
- **API patterns**: Express/Fastify routes, gin/echo handlers, Flask/Django views — how are routes organized?

**3. Test infrastructure scan:**
- Where are test files? Co-located with source, or separate directories?
- Test utilities/helpers: `test/utils/`, `test/fixtures/`, `test/factories/`
- Mock patterns: jest.mock, vitest.mock, httptest, unittest.mock, gomock
- Configuration: jest.config, vitest.config, pytest.ini, conftest.py

### Full Bootstrap Mode (template/missing)

Populate the entire .correctless/ARCHITECTURE.md from scan results:
1. **Key Components table**: one row per significant directory/module discovered
2. **Design Patterns** (PAT-xxx format): one entry per detected pattern
3. **Conventions**: naming, file organization, import patterns discovered
4. Present the complete draft: "Here's what I found in your codebase. Review and correct anything that's wrong."
5. Write approved version

### Merge Mode (existing)

Read the existing .correctless/ARCHITECTURE.md fully. Then:
1. **Compare scan results against what's already documented.** If the existing doc already describes the repository pattern in prose and you find Prisma repos in `src/db/repos/`, don't add a second section — instead note: "Your existing docs already cover database access patterns. I'd add a Correctless-structured ID (PAT-001) to your existing section for reference by other skills. Here's how that would look."
2. **Identify missing Correctless sections**: Design Patterns with PAT-xxx numbering, Conventions, Trust Boundaries (at high+ intensity). Propose each as an addition that respects the user's existing structure — don't impose the template's format on top of it.
3. **Never delete or rewrite existing content.** Only append new sections or annotate existing ones.
4. Present proposed additions for approval. If there are 3 or fewer additions, present each separately. If more than 3, batch related additions (e.g., all Design Pattern entries together, all Convention entries together) and present each batch for approval — don't generate 10+ sequential approval requests.

## Step 5: Mine and Capture Conventions

**Greenfield projects:** Skip this step entirely. There are no conventions to mine from < 10 files. Say: "Convention mining isn't useful yet — you don't have enough code for patterns to emerge. After your first 2-3 features, re-run `/csetup` and I'll capture the conventions that have formed."

**Early-stage and Mature projects:** Mine conventions, but filter results based on the user's stated goal.

**Don't ask the user to describe conventions from memory. Mine the codebase first, then confirm.** Describing your own conventions from memory is hard — you forget things, you describe what you wish the conventions were rather than what they are. Being shown what the codebase actually does and saying "yes that's right" or "no, that's a mistake we should fix" is fast and accurate.

### Goal-Aware Filtering

Mine all conventions, but prioritize what you present based on the user's goal from Step 0:

**REST API / web server**: Prioritize API route organization, error response format consistency, auth middleware patterns, database access patterns, input validation patterns, response shapes.

**CLI tool**: Prioritize command structure and argument parsing, error output format, config file handling, exit code conventions, help text patterns.

**Web app / frontend**: Prioritize component organization, state management patterns, routing, styling approach, API client patterns, form handling.

**Library / SDK**: Prioritize public API surface, error types, documentation patterns, versioning, backward compatibility, export structure.

**Generic / unclear**: Present the top 5-7 most impactful findings across all categories. Don't dump 20 findings about naming conventions when the user probably cares more about their error handling or data access patterns.

### Convention Mining Scan

Before asking the user anything, scan the codebase for implicit conventions:

**1. Naming conventions:**
- Sample up to 20 source files (or all files if fewer than 20 exist): are they `camelCase.ts`, `kebab-case.ts`, `snake_case.ts`, `PascalCase.ts`?
- Check directory naming: singular (`model/`) vs plural (`models/`)
- Check exported function/class naming: camelCase vs snake_case vs PascalCase

**Surface inconsistencies as findings:** If 18/20 files use camelCase but 2 use kebab-case, that's a convention with violations: "18/20 files use camelCase naming. 2 files deviate: `old-utils.ts`, `legacy-helper.ts`. Is camelCase the convention? If so, these are cleanup candidates."

**2. Import/module conventions:**
- Barrel files (`index.ts`, `__init__.py`, `mod.rs`): used consistently?
- Path aliases (`@/`, `~/`, `#`) in tsconfig.json or package.json
- Import ordering: eslint rules or visible grouping pattern?

**3. Error handling conventions:**
- Custom error classes: centralized or scattered?
- Error response shapes in API handlers: consistent format? If half the routes return `{ error: "message" }` and half return `{ error: { code: "X", message: "Y" } }`, surface it: "I see two different error response formats in your API routes. Want to pick one as the convention?"
- Error logging: structured vs console, consistent vs ad-hoc

**4. Testing conventions:**
- Co-located tests (same directory as source) vs separate test directories
- Test utilities/helpers: shared fixtures, factories, builders
- Mock patterns: what's mocked, what uses real implementations
- Naming: `describe/it` nesting, "should..." vs "when..." conventions

**5. Git conventions:**
- Run `git log --oneline -30`: detect conventional commits, Jira prefixes, ticket numbers, capitalization, tense
- Check for `.commitlintrc`, `commitlint.config.js`

**6. Configuration:**
- `.editorconfig` (indentation, line endings)
- Prettier/biome/eslint configs for formatting rules
- tsconfig.json strictness settings

### Present Mining Results

Present findings as a categorized summary filtered by goal relevance: "I scanned your codebase and found these conventions:" with the most relevant findings first. For each finding, ask: "Is this intentional? Should I document it?"

**Anti-conventions are valuable too.** If you find inconsistent patterns (two error formats, mixed naming styles, different test approaches in different directories), surface them explicitly: "I see two different patterns for X. Want to pick one as the convention? I'll add it to .correctless/ARCHITECTURE.md and future specs will enforce it." This turns convention capture into a mini-audit for free.

### Then Ask for Undocumented Conventions

After presenting mining results, follow up:

```
Those are the conventions I detected from code. Are there additional ones not visible in the codebase?

Things like:
- Architecture decisions that aren't reflected in file structure
- "Never do X" rules that everyone just knows
- API versioning or pagination standards
- Database migration patterns
- Deployment conventions

You can paste a doc, point me to a file, or describe them.
```

### Where conventions go

Different conventions go to different files because different agents read them at different times:

| Convention type | Goes in | Why there |
|----------------|---------|-----------|
| Architecture patterns (service layer, repository, middleware, data flow) | `.correctless/ARCHITECTURE.md` — Design Patterns section | Spec agents write specs that compose with these. Verify/audit agents check compliance. |
| Coding style (naming, formatting, import ordering, comments) | `CLAUDE.md` | Read at start of every session. Always in context. |
| Error handling (propagation, logging, response format, retry policy) | `.correctless/ARCHITECTURE.md` — Design Patterns section | These are architectural decisions. Spec agents need them to write correct invariants. |
| Testing conventions (what to mock, naming, fixtures, frameworks) | `CLAUDE.md` | Test agents read CLAUDE.md before writing tests. |
| API conventions (versioning, pagination, error shapes, auth) | `.correctless/ARCHITECTURE.md` — Design Patterns, with summary in `.correctless/AGENT_CONTEXT.md` | Spec agents need these to write rules matching existing API behavior. |
| Git/workflow conventions (branch naming, commit messages, PR templates) | `CLAUDE.md` | Affects how the agent interacts with git throughout the workflow. |
| Project prohibitions (never use X, never call Y directly, never store Z) | `.correctless/ARCHITECTURE.md` — Prohibitions section AND `CLAUDE.md` | .correctless/ARCHITECTURE.md is where `/cverify` checks enforcement. CLAUDE.md ensures agents see it in every session. Write to both. |

### How to process conventions

**If the user pastes a document or points to a file:**
1. Read the source material
2. Classify each convention by type
3. Draft entries for each destination file
4. Present each entry one at a time: "I'd put this in .correctless/ARCHITECTURE.md under Design Patterns. Look right?"
5. Write approved entries

**If the user describes them conversationally:**
1. Capture each convention
2. Ask clarifying questions if ambiguous ("When you say 'repository pattern' — does all database access go through repo structs, or just queries?")
3. Classify, draft, present, write

**If the user skips:**
Fine. After the first 2-3 features, suggest formalizing patterns that have appeared consistently across specs: "I've seen the service → repository → database pattern in 3 specs. Want me to add it to .correctless/ARCHITECTURE.md?"

### Examples

**User says:** "All database queries go through repo structs in `internal/repo/`. Never raw SQL in handlers."

**.correctless/ARCHITECTURE.md** gets:
```markdown
### PAT-001: Repository Pattern
- All database access through repository structs in `internal/repo/`
- Never import database packages from HTTP handlers or service layer
- Each entity gets its own repo file: `internal/repo/user.go`
- Repos accept and return domain types, not database row types
```

**CLAUDE.md** gets:
```markdown
## Database Access
All database queries go through repository structs in `internal/repo/`.
Never use raw SQL or import database packages outside the repo layer.
```

---

**User says:** "Error responses always look like `{"error": {"code": "INVALID_INPUT", "message": "...", "details": [...]}}`"

**.correctless/ARCHITECTURE.md** gets a PAT-xxx entry. **.correctless/AGENT_CONTEXT.md** Quick Reference gets the format.

---

**User says:** "Never use console.log. Use the logger from src/lib/logger.ts."

**CLAUDE.md** gets a summary: "Use the logger from `src/lib/logger.ts` — never use `console.log` directly." **.correctless/ARCHITECTURE.md** gets a Prohibitions section entry: "PROHIBIT: Direct `console.log` usage. Use `src/lib/logger.ts` instead." Both writes are needed — CLAUDE.md ensures agents see it in every session, and .correctless/ARCHITECTURE.md's Prohibitions section is where `/cverify` checks enforcement.

## Step 6: Bootstrap .correctless/AGENT_CONTEXT.md

**Greenfield projects:** Create a minimal .correctless/AGENT_CONTEXT.md. Skip the deep codebase sections — there's nothing to summarize. The minimal version MUST contain at least:

1. **Project description** — from Step 0's question (e.g., "REST API for recipe sharing"). If the user didn't provide a goal, write "New {language} project — goal not yet specified."
2. **Detected tooling** — language, package manager, test runner (if any)
3. **Quick Reference command table** — test command, lint command, build command from `workflow-config.json`. For commands not yet configured, write `(not configured)` rather than omitting the row — this tells downstream skills the command is absent, not that the table is incomplete.

This minimum schema ensures downstream skills (`/cspec`, `/ctdd`) that unconditionally read .correctless/AGENT_CONTEXT.md get usable context rather than an empty file.

After writing the greenfield .correctless/AGENT_CONTEXT.md, update `setup.agent_context_state` to `"existing"` in `workflow-config.json` so subsequent runs use merge mode.

**Early-stage and Mature projects:**

Read `.correctless/config/workflow-config.json` field `setup.agent_context_state` to determine mode:
- `template` or `missing` → draft a populated version from scratch
- `existing` → read existing content, propose only missing Correctless sections (Quick Reference table with commands, Common Pitfalls if absent)
- `null` or field absent → detect manually: check if .correctless/AGENT_CONTEXT.md exists and contains real content (no `{PLACEHOLDER}` markers). If real content, use merge mode. If template/missing, use full bootstrap.

For template/missing, populate based on:
- Codebase scan results from Step 4
- .correctless/ARCHITECTURE.md entries just created
- Conventions captured in Step 5
- Config file (test/lint/build commands)
- Recent git history (`git log --oneline -20` — skip if no commits exist yet)

For existing files: read fully, identify what's already covered, propose only additions. Never replace existing content.

Present the draft (or proposed additions) for approval. Write after approval.

After writing .correctless/AGENT_CONTEXT.md, update `setup.agent_context_state` to `"existing"` in `workflow-config.json` — this mirrors the pattern used for `setup.architecture_state` and ensures subsequent runs use merge mode instead of re-detecting.

## Step 7: Project Health Check

This step adapts to project maturity. The full health check has 19 items, but not all run for every maturity level — greenfield projects get only the critical security subset, while early-stage and mature projects get the full set with tiered presentation.

### Greenfield Projects

Most health checks aren't relevant for a project with < 10 files. Run only the essential checks:

1. **Secrets in source** (Security) — always check this, even for 1 file
2. **`.gitignore` coverage** (Security) — ensure `.env`, credential files, OS files are covered
3. **Lock file committed** (Git Hygiene) — if a package manager is in use

Present a brief summary: "Your project is brand new — I ran the security essentials. No secrets found, `.gitignore` looks good. Run `/csetup` again once you have more code for the full health check."

Then proceed to Step 8 for minimal source control configuration.

### Early-stage and Mature Projects

Run all 19 checks but present results in tiers. Don't dump everything at once.

**Tier 1 — Critical security (show immediately):**
- Hardcoded secrets in source
- Committed credentials or private keys
- Missing `.gitignore` for sensitive files (`.env`, credential files)

If Tier 1 has issues: present them, offer to fix, and **complete fixes before showing more**. A hardcoded API key takes priority over missing linter config.

**After Tier 1 completes** (whether issues were found and fixed, or all checks passed): set `health_check_tier1_done: true` in the checkpoint. This way, if setup is interrupted during Tier 2, resuming skips the already-completed Tier 1 security checks.

**Tier 2 — Everything else (show after Tier 1 is clear):**

After Tier 1: "Your project passes the critical security checks. Want to see the full health card? It covers code quality, testing, CI/CD, and documentation."

If the user says yes — show the full health card (below). If the user says "not now" — fine. They can re-run `/csetup` later.

**On checkpoint resume:** If `health_check_tier1_done` is `true` and `last_completed_step` is 6 (Step 7 was in progress but not complete), skip Tier 1 and go straight to Tier 2. Note: `last_completed_step` must remain 6 until the entire Step 7 completes — do not advance it to 7 after Tier 1 alone. Only update `last_completed_step` when the full step is done.

### Detect Existing Tooling First

Before running checks, scan for existing tool configurations. This changes how findings are reported — acknowledge what exists rather than suggesting duplicates.

**Hook systems:**
- Check for: `.husky/` directory, `husky` in package.json, `.lintstagedrc*` or `lint-staged` in package.json, `.pre-commit-config.yaml`, `lefthook.yml`
- If ANY hook system exists: the "Pre-commit hooks" check should acknowledge it. Correctless hooks are Claude Code PreToolUse hooks (registered in `.claude/settings.json`), not git hooks — they coexist without conflict. Note: "Found: husky + lint-staged. Correctless hooks are separate (they gate Claude's file operations, not git commits). No conflict. Consider adding gitleaks to your lint-staged config for secret scanning if not present."

**CI enrichment:**
- When CI files are found, actually read them. Grep for: test commands, lint commands, coverage steps, security scanning, dependency scanning.
- Map CI coverage to health check items. If CI runs `npm test -- --coverage`, mark coverage as `Found (via CI)`.

**Coverage config detection:**
- Check for: `jest.config.*` with `coverageThreshold`, `.coveragerc`, `.nycrc`, `pyproject.toml [tool.coverage]`, `tarpaulin.toml`, `vitest.config.*` coverage settings

**Test pattern validation:**
- Glob for test files broadly: `**/*.test.*`, `**/*.spec.*`, `**/*_test.*`, `**/test_*.*`, `__tests__/**/*`, `tests/**/*`
- Compare found files against `workflow-config.json`'s `patterns.test_file`
- If files exist that don't match the config pattern: "Found 23 test files in `__tests__/` but your config only matches `*.test.ts`. The workflow gate may misclassify these. Want me to update the test pattern?" This prevents frustration during the first `/ctdd` run.

### Health Check Status Vocabulary

Use richer status values than binary pass/fail:
- `Found` — detected and correctly configured
- `Found (via CI)` — not a local tool but CI handles it
- `Found (equivalent)` — using a different tool that serves the same purpose (e.g., husky instead of pre-commit)
- `Missing` — not found, recommend adding
- `Partial` — found but incomplete (e.g., linter exists but no config)
- `N/A` — not applicable to this project type

The score denominator should subtract N/A items: a Go project with 15 applicable checks scoring 12/15 is more meaningful than 12/19.

### Security

**Dependency vulnerability scanning:**
- Check for: `.github/dependabot.yml`, `.snyk`, `socket.yml`, Renovate config (`renovate.json`, `.renovaterc`), npm audit in CI
- If missing: offer to generate a Dependabot config tailored to the project's package ecosystem

**Secret scanning:**
- Check for: `.pre-commit-config.yaml` with gitleaks or truffleHog hook, git-secrets config
- If missing: the primary recommendation is the gitleaks pre-commit hook (see pre-commit section below). This catches secrets BEFORE they enter the repo. GitHub's built-in scanning is a good second layer but it's reactive — it notifies after the secret is already committed.

**Secrets in source (ALWAYS check this):**
- Grep tracked files for patterns: `sk-live-`, `sk_live_`, `AKIA`, `-----BEGIN (RSA|EC|OPENSSH) PRIVATE KEY-----`, password/secret/token assignments that aren't env vars, connection strings with embedded credentials, `sk-ant-` (Anthropic), `sk-proj-` (OpenAI), `ghp_`/`ghs_`/`github_pat_` (GitHub tokens), `xox[baprs]-` (Slack), `SG\.` (SendGrid)
- Report findings with file:line — these are "fix now" urgency
- This catches the most common vibe-coding mistake: hardcoding a Stripe key or DB password during development

**If secrets are found, explain secrets management to the user.** Many developers who hardcode secrets have never heard of secrets management. Don't just say "use environment variables" — explain the options, starting with free and simple:

Present this guide (adapt to their stack):

**Level 1 — Environment variables (free, start here):**
Move secrets out of source code into a `.env` file. The app reads them via `process.env.STRIPE_KEY` (Node), `os.Getenv("STRIPE_KEY")` (Go), `os.environ["STRIPE_KEY"]` (Python). The `.env` file goes in `.gitignore` so it's never committed. Create a `.env.example` with placeholder values so other developers know which variables are needed. Offer to do this migration for them — move each hardcoded secret to `.env`, replace with env var reference, add `.env` to `.gitignore`, generate `.env.example`.

**Level 2 — Platform secrets (free with most hosts):**
Most deployment platforms have built-in secret management:
- **Vercel/Netlify/Railway/Render**: environment variables in the dashboard (encrypted at rest, injected at deploy)
- **GitHub Actions**: repository secrets for CI (`${{ secrets.STRIPE_KEY }}`)
- **Docker**: `docker secret` or env files not baked into the image
- **Fly.io/Heroku**: `fly secrets set` / `heroku config:set`

These are free, require zero infrastructure, and are the right answer for most projects. The secret never touches source code or git history.

**Level 3 — Secret scanning prevention (free):**
Even after moving to env vars, prevent future accidents:
- **GitHub secret scanning**: free for public repos, catches known secret patterns on push
- **git-secrets** (AWS, free): pre-commit hook that blocks commits containing secret patterns
- **pre-commit framework** with `detect-secrets` hook: scans staged files before commit

Offer to set up one of these.

**Level 4 — Dedicated secret managers (for teams/production):**
Only mention these if the project looks like it has production infrastructure:
- **Infisical** (open source, free tier): centralized secrets with rotation, audit logs, injected at runtime
- **Doppler** (free for individuals): syncs secrets across environments
- **SOPS** (free, Mozilla): encrypts secret files so they CAN be committed (encrypted values in git, decrypted at deploy)
- **1Password CLI / Bitwarden Secrets Manager**: if they already use a password manager

Don't mention HashCorp Vault, AWS Secrets Manager, or GCP Secret Manager unless the project is clearly enterprise-scale — these are overkill for most projects and cost money.

**If secrets are already in git history:** warn the user that removing them from source isn't enough — they're still in git history. Anyone who clones the repo can find them with `git log -p`.

Two things must happen:

1. **Rotate the secret (most important).** Generate a new API key / password / token from the provider's dashboard and revoke the old one. No amount of history scrubbing helps if the old key is already compromised. Walk the user through where to rotate each secret found (e.g., "Go to Stripe Dashboard → Developers → API Keys → Roll Key").

2. **Scrub git history.** Offer to do this for the user. Use `git filter-repo` (preferred) or `BFG Repo-Cleaner`:

```bash
# Install git-filter-repo if needed
pip install git-filter-repo

# Remove the file(s) that contained secrets from all history
git filter-repo --invert-paths --path src/config.ts --force

# OR replace specific strings across all history
git filter-repo --replace-text <(echo 'sk-live-ACTUAL_KEY_HERE==>REDACTED') --force
```

After scrubbing:
- Force push: `git push --force-with-lease`
- Tell all collaborators to re-clone (their local copies still have the old history)
- If the repo was ever public, assume the secret was scraped — rotation is non-negotiable

Offer to handle the full process: identify which files/strings to scrub, run the filter, verify the secret is gone from history, and remind the user to force push and rotate.

**Gitignore coverage:**
- Check `.gitignore` includes: `.env`, `.env.*`, credential files, private keys, OS files (`.DS_Store`, `Thumbs.db`), IDE configs
- Offer to add missing entries

### Code Quality

**Linter:**
- Check for: eslint config, golangci-lint config, pylint/ruff/flake8, clippy
- If missing: offer to generate a starter config for the detected framework
- If present: run lint command and report if it passes

**Formatter:**
- Check for: prettier config, gofmt (built-in), black/ruff format, rustfmt
- If missing: offer to set up the standard formatter

**Type checking:**
- TypeScript: is `strict: true` in tsconfig.json? If not, flag it
- Python: mypy/pyright configured?
- Go: does `go vet` pass?
- If strict mode off: explain what it catches, offer to enable (warn about error flood)

**Pre-commit hooks (via [pre-commit.com](https://pre-commit.com) framework):**

Pre-commit hooks catch problems BEFORE they enter the repo. A health check finding "2 hardcoded secrets" is already too late — they're in git history. A pre-commit hook rejects the commit before the secret ever lands.

- Check for: `.pre-commit-config.yaml` in project root
- If missing: offer to generate one tailored to the project's stack

**Be opinionated.** Don't ask the user to pick hooks. Detect the stack and generate the right config. The user can remove what they don't want.

**Core hooks (every project, regardless of language):**
```yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-json
      - id: check-merge-conflict
      - id: check-added-large-files
        args: ['--maxkb=500']
      - id: detect-private-key
      - id: check-case-conflict

  # Secret scanning — the most important hook
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.22.1
    hooks:
      - id: gitleaks

  # Typos in code and docs
  - repo: https://github.com/crate-ci/typos
    rev: v1.28.4
    hooks:
      - id: typos
```

**Language-specific hooks (added based on detected stack):**

Go:
```yaml
  - repo: https://github.com/TekWizely/pre-commit-golang
    rev: v1.0.0-rc.1
    hooks:
      - id: go-fmt
      - id: go-vet
```

Python:
```yaml
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.8.6
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format
```

TypeScript/JavaScript:
```yaml
  - repo: https://github.com/biomejs/pre-commit
    rev: v0.6.1
    hooks:
      - id: biome-check
        additional_dependencies: ["@biomejs/biome@latest"]
```
**Important:** Before generating, check the project's installed Biome version (from `biome.json` `$schema` URL, `package.json` devDependencies, or `biome --version`). If found, pin to that version instead of `latest`. Biome 1.x and 2.x configs are incompatible — pinning the wrong major version will silently apply wrong formatting rules or fail outright.

(If project already uses eslint+prettier, use husky+lint-staged for JS hooks and layer pre-commit on top for secrets/universal hooks.)

Rust:
```yaml
  - repo: local
    hooks:
      - id: cargo-fmt
        name: cargo fmt
        entry: cargo fmt --
        language: system
        types: [rust]
```

Shell scripts:
```yaml
  - repo: https://github.com/shellcheck-py/shellcheck-py
    rev: v0.10.0.1
    hooks:
      - id: shellcheck
```

Conventional commits (if detected/configured):
```yaml
  - repo: https://github.com/commitizen-tools/commitizen
    rev: v4.1.1
    hooks:
      - id: commitizen
```

**After generating the config:**
1. Write `.pre-commit-config.yaml`
2. Run `pre-commit install` to activate hooks
3. Run `pre-commit run --all-files` once — this surfaces existing issues (trailing whitespace, formatting, maybe a private key in a fixture). Fixing these in one commit establishes a clean baseline.

**Relationship to CI:** Add `pre-commit run --all-files` as the first step in the generated CI workflow. This catches any commits that bypassed local hooks via `git commit --no-verify`.

### Testing

**Test runner:**
- Check for test config and test files
- If zero tests: flag prominently — "This project has zero tests. Correctless will help you write them, but the current state is high-risk."
- If tests exist: run them and report pass/fail count

**Coverage:**
- Check for coverage config in test runner or CI
- If missing: offer to add coverage reporting (even without threshold — knowing the number matters)

**Race detector (Go only — reported inline under Test runner):**
- Check for `-race` flag in test commands
- If missing: note it in the Test runner health card row (e.g., "Found: go test (47 tests, no -race flag — recommend adding)") and offer to add `go test -race ./...`
- This is not a separate health card row — it's a sub-check of the Test runner item

### CI/CD

**CI pipeline:**
- Check for: `.github/workflows/`, `.gitlab-ci.yml`, `Jenkinsfile`, `.circleci/`, `bitbucket-pipelines.yml`
- If missing: offer to generate a GitHub Actions workflow with: `pre-commit run --all-files` (first step), install, lint, type-check, test, build

**CI on PRs:**
- If CI exists: does it trigger on pull requests? Check trigger config.
- If only on push to main: flag — issues should be caught on the PR

**Branch protection:**
- Check if branch protection is configured (GitHub API or `.github/settings.yml`)
- If not: recommend, provide direct link to settings. Can't set this programmatically.

### Documentation

**README:**
- Check if README.md exists and has content beyond framework boilerplate
- If boilerplate: flag — "Your README is the default framework template"

**.env.example:**
- If .env exists but .env.example doesn't: offer to generate from .env with values redacted
- Critical for onboarding — without it, developers don't know which env vars are needed

**LICENSE:**
- If missing: note it. Don't generate — the license choice is the human's.

### Git Hygiene

**.gitignore completeness:**
- Check against known list for the stack
- Flag missing entries, offer to add

**Committed artifacts:**
- Check if tracked: `node_modules/`, `dist/`, `build/`, `.next/`, `__pycache__/`, vendor/ (unless Go vendor mode), binary files
- If found: flag with removal instructions

**Lock file:**
- Check if lock file is committed (package-lock.json, yarn.lock, pnpm-lock.yaml, go.sum, Cargo.lock)
- If not committed: flag — should be committed for reproducible installs

**Large files:**
- Quick scan for files >5MB that might be accidentally committed
- If found: suggest git-lfs or .gitignore

### Present the Health Card

Format the results as a health card using the status vocabulary above:

```
Project Health Check — {project-name} ({language}/{framework})

Security:
  {✓/✗/—} Dependency scanning: {Found|Found (via CI)|Missing|N/A}
  {✓/✗/—} Secret scanning: {Found|Found (equivalent: husky+gitleaks)|Missing}
  {✓/✗/—} No secrets in source: {Found: clean|FOUND: N secrets — fix now}
  {✓/✗/—} .gitignore covers sensitive files: {Found|Partial|Missing}

Code Quality:
  {✓/✗/—} Linter: {Found: eslint|Found (via CI)|Missing}
  {✓/✗/—} Formatter: {Found: prettier|Missing}
  {✓/✗/—} Type checking: {Found: strict|Partial: not strict|N/A}
  {✓/✗/—} Pre-commit hooks: {Found: pre-commit|Found (equivalent: husky)|Missing}

Testing:
  {✓/✗/—} Test runner: {Found: jest (47 tests)|Missing: zero tests}
  {✓/✗/—} Coverage reporting: {Found (via CI)|Partial: no threshold|Missing}

CI/CD:
  {✓/✗/—} CI pipeline: {Found: GitHub Actions (runs tests, lint)|Missing}
  {✓/✗/—} Branch protection: {Found|Missing}

Documentation:
  {✓/✗/—} README: {Found|Partial: boilerplate|Missing}
  {✓/✗/—} .env.example: {Found|Missing|N/A: no .env}
  {✓/✗/—} LICENSE: {Found|Missing}

Git Hygiene:
  {✓/✗/—} .gitignore complete: {Found|Partial}
  {✓/✗/—} No committed build artifacts: {Found: clean|FOUND: node_modules/ tracked}
  {✓/✗/—} Lock file committed: {Found|Missing}
  {✓/✗/—} No large files (>5MB): {Found: clean|FOUND: N files — consider git-lfs}

Score: X/Y checks passing (Y = applicable checks, excluding N/A)
```

### Prioritize and Offer Fixes

Group issues by urgency:

1. **Fix now** (security): hardcoded secrets, missing .gitignore for .env, committed credentials
2. **Fix soon** (quality): no linter, no CI, no tests, committed build artifacts
3. **Recommended** (hygiene): no pre-commit hooks, no coverage, no .env.example, no LICENSE

For each issue: explain what it is (one sentence), why it matters (one sentence), and offer to generate the fix. The human picks which fixes to apply.

**What to generate when asked:**

| Fix | Generated file | Tailored to |
|-----|---------------|-------------|
| Dependabot config | `.github/dependabot.yml` | Package ecosystems detected |
| CI workflow | `.github/workflows/ci.yml` | Language, test runner, linter, build command, `pre-commit run --all-files` as first step |
| Pre-commit config | `.pre-commit-config.yaml` | Core hooks (gitleaks, typos, file hygiene) + language-specific hooks |
| Coverage config | Updated test script + CI step | Test runner detected |
| .env.example | `.env.example` with redacted values | Current .env file |
| .gitignore additions | Updated `.gitignore` | Stack-specific entries |
| Linter config | `.eslintrc.*` or equivalent | Framework detected |
| Formatter config | `.prettierrc` or equivalent | Language detected |

Every generated file includes: `# Generated by Correctless /csetup — review and customize as needed`

After applying fixes, re-run the health card to show progress.

## Step 8: Source Control Configuration

**Greenfield projects:** Keep this light. Confirm the default branch name and write sensible defaults to `workflow-config.json` under the `workflow` key: `workflow.branching_strategy: "feature-branches"`, `workflow.merge_strategy: "squash"`. These defaults are read by `workflow-advance.sh init` and `/caudit` — if left absent, those tools fail silently. Tell the user: "I've set feature branches with squash merge as defaults. You can change these later by re-running `/csetup`." Skip PR template, commit convention detection, and branch protection — there's no commit history to analyze yet. Mention: "Once you have your first PR, re-run `/csetup` to set up PR templates and branch protection."

**Early-stage and Mature projects:**

### Statusline

If the Correctless statusline hook exists at `.correctless/hooks/statusline.sh`, check whether it's already registered in `.claude/settings.json`:

- **Already registered** (setup script did this in Step 2): Confirm: "Statusline is active. You'll see workflow phase, cost, and context % in the status bar."
- **Not yet registered** (e.g., hooks were copied but registration was skipped): Offer to activate it: "Correctless includes a workflow-aware statusline that shows your current phase (RED/GREEN/QA), session cost, and context usage. Want me to register it?" If yes, add the statusLine hook entry to `.claude/settings.json`.

### Source Control

Detect and configure source control preferences. Check what's already configured before asking.

**Auto-detect first:**
- Git remote: GitHub, GitLab, Bitbucket? (determines CLI tool and PR template location)
- CLI tools: is `gh` or `glab` in PATH?
- Existing PR template: `.github/pull_request_template.md` or equivalent?
- Existing commit convention: scan recent commits for patterns (conventional commits, Jira prefixes)
- Default branch name: main vs master vs other
- Branch protection: check if configured (via `gh` if available)

**Present detected values, then ask what's missing:**

```
Source Control — detected:
  ✓ Remote: GitHub
  ✓ Default branch: main
  ✓ gh CLI: installed
  ✓ Commit style: conventional commits (detected from history)
  ✗ PR template: none found → I can generate one
  ✗ Branch protection: not configured → recommend enabling

Branching strategy:
  1. Feature branches (recommended) — branch per feature, merge via PR
  2. Trunk-based — short-lived branches, commit to main frequently

  Or type your own: ___

Merge strategy:
  1. Squash (recommended) — clean history, one commit per feature
  2. Merge commit — preserves branch history
  3. Rebase — linear history, no merge commits

  Or type your own: ___
```

**Where answers go:**

| Setting | Stored in | Read by |
|---------|-----------|---------|
| Branching strategy | `workflow-config.json` | `workflow-advance.sh init`, `/caudit` |
| Merge strategy | `workflow-config.json` (`workflow.merge_strategy`) | `/ctdd done`, `/caudit` |
| PR CLI tool | `CLAUDE.md` | Every session |
| Commit format | `CLAUDE.md` | Every session |
| PR template | `.github/pull_request_template.md` | Agent pre-fills on PR creation |

**If no PR template exists**, offer to generate one with Correctless sections:
```markdown
## Description
<!-- What does this change do? -->

## Spec
<!-- Link: .correctless/specs/xxx.md -->

## Testing
<!-- Coverage? All rules covered? -->

## Checklist
- [ ] Tests pass
- [ ] Spec rules covered
- [ ] /cverify passed
- [ ] Documentation updated
```


**PR CLI tool goes to CLAUDE.md.** If `gh` is detected: write `Use \`gh\` for GitHub operations (PRs, issues, checks).` If `glab` is detected: write `Use \`glab\` for GitLab operations (MRs, issues, pipelines).` This ensures every downstream skill that creates PRs knows which tool to use.

**Commit format goes to CLAUDE.md.** If conventional commits:
```markdown
## Commit Messages
Use conventional commits: feat:, fix:, test:, docs:, refactor:, chore:
During TDD: test(feature): ..., feat(feature): ..., fix(feature): per QA finding
During audit: fix(audit-qa-r2): finding-id — description
```

## Step 9: First Feature Guidance

End with clear, maturity-appropriate next steps.

**Greenfield:**
"You're set up. Your project is new, so setup was minimal — Correctless will learn your patterns as you build.

Start your first feature:
1. `git checkout -b feature/my-feature`
2. Run `/cspec` — I'll walk you through writing your first spec

The workflow guides you from there: spec → review → tests → implementation → QA → verify → docs."

**Early-stage:**
"You're set up. Your existing code is untouched — Correctless only activates on feature branches. The conventions I found will inform specs and reviews going forward.

Start a feature:
1. `git checkout -b feature/my-feature`
2. Run `/cspec`

Check workflow state anytime: `.correctless/hooks/workflow-advance.sh status`"

**Mature:**
"You're set up. I've learned your project's conventions and they'll inform every spec, review, and verification.

Start a feature: `git checkout -b feature/my-feature` then `/cspec`.
Or review a PR: `/cpr-review {number}`.

Current commands: `/csetup`, `/cspec`, `/creview`, `/creview-spec`, `/cmodel`, `/ctdd`, `/cverify`, `/caudit`, `/cupdate-arch`, `/cdocs`, `/cpostmortem`, `/cdevadv`, `/credteam`, `/crefactor`, `/cpr-review`, `/ccontribute`, `/cmaintain`, `/cstatus`, `/csummary`, `/cmetrics`, `/cdebug`, `/chelp`, `/cwtf`, `/cquick`, `/crelease`, `/cexplain`, `/cauto`, `/carchitect`, `/cmodelupgrade`, `/cdashboard`, `/ctriage`, `/cprune`
Check workflow state: `.correctless/hooks/workflow-advance.sh status`"

If the human says they want to start a feature, ask what they want to build and suggest they run `/cspec`. **Do not auto-invoke `/cspec`.**

**Delete the checkpoint file** — setup is complete.

## Subsequent Runs

When `/csetup` is run on a project that's already configured:

1. **Re-assess maturity** (the project may have grown since last setup)
2. **Handle maturity transitions** — if maturity has increased, run the steps that were previously skipped:
   - **Greenfield → Early-stage**: Run convention mining (Step 5) for the first time — this isn't "re-mining," it's the initial scan. Run the full health check (Step 7) instead of the security-only subset. Offer source control configuration (Step 8) if only defaults were set. Tell the user: "Your project has grown past the greenfield stage. I'll now scan for conventions and run the full health check."
   - **Early-stage → Mature**: Re-scan architecture (Step 4) in merge mode. Re-mine conventions comprehensively. The existing health check and source control config can be updated in place.
   - **Same maturity**: Follow the standard subsequent-run flow below.
3. **Re-run health checks** appropriate to the current maturity level
4. Show what improved since last run, what's new, what's still missing
5. Only offer to fix new or unresolved issues — don't re-prompt for things already declined
6. Re-detect tools (mutation testing, Alloy, external model CLIs) and offer to enable newly found ones
7. Re-mine conventions if the project has grown significantly within the same maturity tier — "You had 30 source files last time, now you have 120. Want me to rescan for new patterns?"

## Claude Code Feature Integration

### Task Lists
See "Progress Visibility" section above — task creation and narration are mandatory.

## If Something Goes Wrong

- **Setup is idempotent** — the bash script skips files that already exist and never overwrites user-edited content. Re-running is safe.
- **Checkpoint resume** — if interrupted, re-running detects the checkpoint and offers to continue from the last completed step.
- **The interactive skill (Steps 3-9) asks before writing.** If interrupted without checkpoint, re-run. Already-completed steps (config review, health check) will re-run but won't overwrite previous choices.
- **If the health check is wrong**: The health check reads your project state at that moment. If you've fixed something, re-run `/csetup` to get an updated health card.

## Constraints

- **Be conversational, not transactional.** Don't dump a wall of config at the human.
- **Ask permission before writing content decisions.** "Can I update .correctless/ARCHITECTURE.md with these entries?" (Exception: Step 2's setup script creates mechanical scaffolding — directories, hooks, config templates — after announcing what it will do. This doesn't require per-file approval.)
- **One topic at a time.** Don't ask 10 unrelated questions in one message. Related items (e.g., a batch of Design Pattern entries for merge-mode approval) can be presented together as a single decision.
- **Accept defaults gracefully.** If the human says "looks fine" to the config review, move on — don't force them to confirm every field.
- **Respect maturity.** Greenfield projects get a fast, minimal setup. Mature projects get thorough discovery. Don't run the mature flow on a greenfield project — it wastes time and produces empty results. Don't run the greenfield flow on a mature project — it misses conventions that matter.
- **Don't be preachy about the health card.** Present facts, offer fixes, let the human decide. A project with 5/19 checks passing isn't "bad" — it might be an early prototype.
- **One exception: hardcoded secrets are always urgent.** Flag them prominently regardless of project context or maturity.
- **All generated files inside the project directory.** Never /tmp.
- **Never auto-invoke the next skill.** Tell the human what comes next and let them decide when to run it. Suggest `/cspec` — don't start it.
