---
name: eck:audit-current-project
version: "0.7.4"
description: Quick health check and drift detection for managed projects — compares deployed infrastructure against global catalog checksums.
disable-model-invocation: false
---

# Audit Current Project

Quick health check for managed projects already tracked in the registry. Compares deployed infrastructure against `global-catalog.yaml` checksums, detects drift, and updates `project-catalog.yaml`.

Unlike `/eck:audit-unmanaged-project` (which discovers and registers new projects), this skill operates on the **current working directory** and assumes the project is already managed.

---

## Visual Framework

Follow these conventions for all terminal output displayed to the user via the Bash tool.

### Output Mode Awareness

Before producing output, read the user's preferred output mode:

```bash
cat $ECK_HOME/user-preferences.json 2>/dev/null
```

Extract the `outputMode` field and adapt verbosity:

- **guided** — Add explanatory prose after key steps. Describe what is happening and why.
- **standard** (default) — Balanced. Show steps with brief context for non-obvious decisions.
- **concise** — Steps and summary box only. No prose, no explanations.

If the file is missing or `outputMode` is absent, use **standard**.

### ANSI Colors

Declare these variables at the top of **every** Bash tool call (shell state does not persist between calls):

```bash
source $ECK_HOME/colors.sh
```

Every color sequence **must** end with `${RESET}`. No exceptions.

### Stage Banners

Mark major stage transitions with a clean bold header. One blank line before and after.

```bash
echo ""
printf '%b\n' "${ORANGE}${BOLD}Stage Name${RESET}"
echo ""
```

### Status Symbols

| Symbol | Meaning          | Color       |
| ------ | ---------------- | ----------- |
| `[*]`  | Active / running | `${CYAN}`   |
| `[x]`  | Completed        | `${GREEN}`  |
| `[!]`  | Error            | `${RED}`    |
| `[-]`  | Skipped          | `${DIM}`    |
| `[>]`  | In progress      | `${YELLOW}` |
| `[ ]`  | Pending          | `${DIM}`    |

```bash
printf '%b\n' "${GREEN}[x]${RESET} Step completed"
printf '%b\n' "${RED}[!]${RESET} Something failed"
```

No emoji in output. Use only these bracket symbols for status.

### Summary Blocks

Display at checkpoints and at the end of the skill. One blank line before and after.

```bash
echo ""
printf '%b\n' "${ORANGE}${BOLD}Title${RESET}"
echo ""
printf '%b\n' "Label: Value"
echo ""
```

### Error Format

```bash
printf '%b\n' "${RED}[!]${RESET} Error message here"
printf '%b\n' "    ${DIM}Recovery guidance here.${RESET}"
```

### Spacing Rules

- One blank line before and after stage banners and summary boxes.
- No blank lines within step lists.
- Maximum output line width: 70 characters.

### Statusline Stage Updates

At the **start** of each stage, update the statusline:

```bash
bash $ECK_HOME/update-stage.sh "{Statusline text from table}"
```

At **skill completion** (success or error), reset:

```bash
bash $ECK_HOME/update-stage.sh
```

---

## Task Registration

| Stage | Subject                       | Active Form             | Statusline      |
| ----- | ----------------------------- | ----------------------- | --------------- |
| 1     | Stage 1: Pre-Flight           | Verifying prerequisites | Preflight (1/5) |
| 2     | Stage 2: Scan Project         | Scanning project        | Scan (2/5)      |
| 3     | Stage 3: Compare with Catalog | Comparing with catalog  | Compare (3/5)   |
| 4     | Stage 4: Score                | Scoring project         | Score (4/5)     |
| 5     | Stage 5: Update Tracking      | Updating tracking       | Tracking (5/5)  |

## Usage

```bash
/eck:audit-current-project                    # Audit current directory
```

**Read-write** — updates `project-catalog.yaml` and `registry.yaml`.

---

## Stage 1: Pre-Flight

### Inputs

- Current working directory (project root)
- `.claude/project-catalog.yaml` (managed project indicator)
- `$ECK_HOME/global-catalog.yaml`
- `$ECK_HOME/registry.yaml` (optional)

### Activities

### Requirements

- Current directory has `.claude/project-catalog.yaml` (managed project indicator)
- Read access to global catalog: `$ECK_HOME/global-catalog.yaml`
- Read access to registry: `$ECK_HOME/registry.yaml`

### Verification

```bash
# Check project is managed
ls .claude/project-catalog.yaml

# Check global catalog exists
ls $ECK_HOME/global-catalog.yaml

# Check registry exists (optional — will create entry if missing)
ls $ECK_HOME/registry.yaml
```

**If `.claude/project-catalog.yaml` not found:**

Display via Bash tool:

```bash
source $ECK_HOME/colors.sh
printf '%b\n' "${RED}[!]${RESET} No project-catalog.yaml found in current directory."
printf '%b\n' "    ${DIM}This project doesn't appear to be managed by evolv-coder-kit.${RESET}"
echo ""
printf '%b\n' "    ${DIM}Options:${RESET}"
printf '%b\n' "    ${DIM}- Run /eck:audit-unmanaged-project to discover and register${RESET}"
printf '%b\n' "    ${DIM}- Run /eck:new-project to scaffold a new managed project${RESET}"
printf '%b\n' "    ${DIM}- Run /eck:migrate-project to onboard an existing project${RESET}"
```

**If global catalog not found:**

Display via Bash tool:

```bash
source $ECK_HOME/colors.sh
printf '%b\n' "${RED}[!]${RESET} Global catalog not found."
printf '%b\n' "    ${DIM}Run: npx @evolvconsulting/evolv-coder-kit --global${RESET}"
```

STOP after displaying the error.

### Outputs

- Confirmed project is managed; global catalog and registry accessibility resolved

### Exit Criteria

- `project-catalog.yaml` found; global catalog accessible; skill may proceed

---

## Stage 2: Load & Scan

### Inputs

- Global catalog from Stage 1
- Project catalog from Stage 1
- Registry from Stage 1 (if present)
- All deployed infrastructure files in current directory

### Activities

### 2.1: Load References

Read and parse:

1. `$ECK_HOME/global-catalog.yaml` — canonical component definitions
2. `.claude/project-catalog.yaml` — last-known project state
3. `$ECK_HOME/registry.yaml` — project registry entry (if exists)

### 2.2: Scan Deployed Files

For every component listed in `global-catalog.yaml`, check the corresponding file in the current project:

```bash
# Root infrastructure files
ls CLAUDE.md development-workflow.md workflow-diagrams.md workflow-quick-reference.md project-constitution.md

# .claude/ config files
ls .claude/settings.json .claude/project-constants.md

# .claude/ infrastructure
ls .claude/agents/ .claude/skills/ .claude/hooks/ .claude/primitives/ .claude/context/
```

Compute SHA-256 checksums for every file found (normalizing CRLF→LF for platform stability):

```bash
tr -d '\r' < <file> | shasum -a 256
```

### Outputs

- SHA-256 checksums for all deployed files; all three catalog/registry sources loaded

### Exit Criteria

- All deployed files scanned and checksums computed

---

## Stage 3: Compare & Classify

### Inputs

- Checksums from Stage 2
- Global catalog component list and checksums
- Project catalog (last-known state)
- `.claude/project-constants.md` (for placeholder map)

### Activities

### 3.1: Placeholder-Aware Comparison via Template Engine

Use the template engine to perform placeholder-aware comparison between the global catalog source and the deployed project files. This prevents false positives from correctly-installed placeholder substitutions (e.g., `<PROJECT_KEY_LOWERCASE>` → `myapp`).

```bash
node "$(npm root -g)/@evolvconsulting/evolv-coder-kit/bin/template-cli.js" \
  changeset $ECK_HOME/.claude {TARGET_PATH}/.claude \
  --values {TARGET_PATH}/.claude/project-constants.md \
  --format json
```

The changeset command returns a JSON object with `added`, `removed`, `modified`, and `identical` arrays. Each entry includes a `classification` field:

- `identical` — raw checksums match
- `placeholder-only` — resolved template checksum matches deployed (correctly installed, not a real change)
- `formatting` — whitespace-only differences
- `content` — genuine content differences

### 3.2: Classify Components

Map the template engine classifications to audit statuses:

| Status       | Condition                                                                                                      |
| ------------ | -------------------------------------------------------------------------------------------------------------- |
| **synced**   | File in `identical` array, OR classification is `placeholder-only`                                             |
| **modified** | Classification is `content` AND deployed checksum differs from project-catalog.yaml last-known state           |
| **outdated** | Classification is `content` AND deployed checksum matches project-catalog.yaml but differs from global-catalog |
| **missing**  | File in global-catalog.yaml but in the `removed` array (not found in project)                                  |
| **custom**   | File in the `added` array from target side (exists in project but NOT in global-catalog.yaml)                  |

> **Note:** The `contains_placeholders` flag in global-catalog.yaml is informational. The template engine always attempts placeholder resolution for all files regardless of the flag.

For **modified** files, the diff content is available from the template source vs deployed file for deeper analysis.

### 3.3: Agent-Assisted Diff Analysis

When modified files are detected (modified count > 0), dispatch an agent for deeper classification.

**When to dispatch:**

- One or more files classified as `modified`
- Skip when no modified files exist (all synced/outdated/missing)

1. **MUST** dispatch `code-explorer` agent via `agent:dispatch`. Do NOT skip agent analysis when modified files exist:
   - **Prompt:** "Analyze the diff between the deployed file and the canonical template. Classify the modification as improvement (benefits all projects), project-specific (tailored to this project), or regression (removes functionality). Provide a brief rationale."
   - **Context per file:**
     - File path and category
     - Diff output (template vs deployed)
     - Project name and key from project-constants.md
   - **Expected output per file:**
     - Classification: `improvement` / `project-specific` / `regression`
     - Confidence: `high` / `medium` / `low`
     - Brief rationale (1 sentence)

2. Merge agent findings into the report:
   - Agent classification is used for the "Modified Components" display section
   - Agent results feed into `pull_candidates` classification in Stage 5
   - If agent is unavailable or fails, fall back to reporting modifications without sub-classification
   - Log: `"Agent-assisted analysis: {available/unavailable}"`

**Graceful fallback:** If agent dispatch fails or times out, continue with diff-only reporting. Log a warning but do not STOP the audit.

### Outputs

- Each component classified as `synced`, `modified`, `outdated`, `missing`, or `custom`; agent-assisted diff analysis for modified files

### Exit Criteria

- All global catalog components classified; modified files analyzed

---

## Stage 4: Health Scoring

### Inputs

- Component classification counts from Stage 3 (synced, modified, outdated, missing, custom)

### Activities

Calculate health score:

```
score = (synced_count / total_tracked_count) * 100
```

Health grades:
| Grade | Score |
|-------|-------|
| A | 90-100% |
| B | 75-89% |
| C | 60-74% |
| D | 40-59% |
| F | 0-39% |

### Report Output

Display report via Bash tool:

```bash
source $ECK_HOME/colors.sh

echo ""
printf '%b\n' "${ORANGE}${BOLD}Project Health Check${RESET}"
echo ""
printf '%b\n' "Project: {PROJECT_NAME}"
printf '%b\n' "Health: {GRADE} ({SCORE}%)"
echo ""

printf '%b\n' "${BOLD}Component Status${RESET}"
printf '%b\n' "${GREEN}[x]${RESET} Synced:    {N}"
printf '%b\n' "${YELLOW}[>]${RESET} Modified:  {N}"
printf '%b\n' "${CYAN}[*]${RESET} Outdated:  {N}"
printf '%b\n' "${RED}[!]${RESET} Missing:   {N}"
printf '%b\n' "${DIM}[-]${RESET} Custom:    {N}"
echo ""

# If outdated components exist:
printf '%b\n' "${BOLD}Outdated Components${RESET} ${DIM}(upstream updates available)${RESET}"
printf '%b\n' "${CYAN}[*]${RESET} {file}: v{old} -> v{new}"
echo ""

# If modified components exist:
printf '%b\n' "${BOLD}Modified Components${RESET} ${DIM}(local changes detected)${RESET}"
printf '%b\n' "${YELLOW}[>]${RESET} {file}: {diff_summary}"
echo ""

# If missing components exist:
printf '%b\n' "${BOLD}Missing Components${RESET}"
printf '%b\n' "${RED}[!]${RESET} {file}: {description}"
echo ""

printf '%b\n' "${BOLD}Recommendations${RESET}"
printf '%b\n' "${DIM}  - Run /eck:pull-from-global-catalog to apply {N} updates${RESET}"
printf '%b\n' "${DIM}  - Review {N} modified files for /eck:push-to-user-catalog${RESET}"
```

### Outputs

- Health score (percentage) and grade (A-F); health report displayed to user

### Exit Criteria

- Score and grade computed; report displayed

---

## Stage 5: Update Tracking

### Inputs

- Classification results and checksums from Stage 3
- Health score and grade from Stage 4
- `$ECK_HOME/registry.yaml` (if project entry exists)

### Activities

### 5.1: Update project-catalog.yaml

Write updated `.claude/project-catalog.yaml` with current checksums and statuses for all tracked components.

### 5.2: Update Registry

**Reference:** `ops:registry-update` primitive for the canonical read-modify-write procedure.

Update the project's entry in `$ECK_HOME/registry.yaml`:

- `last_audit.date`: current timestamp
- `last_audit.health_score`: calculated score
- `last_audit.health_grade`: calculated grade
- `last_audit.synced`, `last_audit.modified`, `last_audit.outdated`, `last_audit.missing`, `last_audit.custom`: component counts
- `audit_status`: based on health_score (`>=75` → `"passing"`, `<75` → `"failing"`)
- `pull_candidates`: classify modified files as improvement/project-specific/regression
  - Each entry: `{ file, type: custom|improvement, confidence: high|medium|low, description }`

If project entry doesn't exist in registry:

- Only `/eck:new-project`, `/eck:audit-unmanaged-project`, and `/eck:migrate-project` may create new entries
- Log warning: "Project not found in registry. Run /eck:new-project or /eck:audit-unmanaged-project to register it."
- Skip registry update and continue with project-catalog.yaml update only

Set `last_modified_at` to current ISO-8601 date.

Merge `pull_candidates` per the `ops:registry-update` primitive Step 4.5 (merge by file path, preserve reviewed items).

Recompute `project_summary` per the `ops:registry-update` primitive.

Copy `registry.yaml` to `registry.yaml.bak`.

Atomic write: write to `registry.yaml.tmp`, then rename to `registry.yaml`.

### 5.3: Summary

Display via Bash tool:

```bash
source $ECK_HOME/colors.sh

echo ""
printf '%b\n' "${ORANGE}${BOLD}Audit Complete${RESET}"
echo ""

printf '%b\n' "${ORANGE}${BOLD}Audit Summary${RESET}"
echo ""
printf '%b\n' "Health: {GRADE} ({SCORE}%)"
printf '%b\n' "Catalog: Updated"
printf '%b\n' "Registry: Updated"
echo ""

printf '%b\n' "${GREEN}[x]${RESET} .claude/project-catalog.yaml (checksums refreshed)"
printf '%b\n' "${GREEN}[x]${RESET} $ECK_HOME/registry.yaml (health: {GRADE} {SCORE}%)"
```

### Outputs

- `project-catalog.yaml` updated with current checksums and statuses; registry updated with audit results and `pull_candidates`

### Exit Criteria

- `project-catalog.yaml` written; registry updated atomically (or skipped with warning); statusline reset; skill complete

---

## Error Handling

| Error                  | Recovery                                                     |
| ---------------------- | ------------------------------------------------------------ |
| Global catalog missing | Run `npx @evolvconsulting/evolv-coder-kit --global`          |
| Project not managed    | Run `/eck:audit-unmanaged-project` or `/eck:migrate-project` |
| Registry write fails   | Report error, continue with project-catalog.yaml update only |
| Checksum mismatch      | Re-scan specific file, report if persistent                  |

---

## Related Documents

- [Audit Unmanaged Project](../audit-unmanaged-project/SKILL.md)
- [Pull From Global Catalog](../pull-from-global-catalog/SKILL.md)
- [Push To User Catalog](../push-to-user-catalog/SKILL.md)
- [Project Status](../project-status/SKILL.md)
- [Global Catalog]($ECK_HOME/global-catalog.yaml)
