config-audit/commands/discover.md
Kjell Tore Guttormsen acd1cf1248 fix(commands): stop writing files no later step can read, and payloads nobody asked for
Dogfooding the four read commands (posture, tokens, manifest, whats-active)
surfaced four defect classes, all in the seam between what a command template
promises and what the scanner behind it actually does.

M-BUG-40, fifth arm: posture wrote four temp files it could never read back.
#49 closed the $$/cross-block class in four commands, but posture survived it —
and so did the guard written to prevent exactly this. The guard compared each
$$ path to the block that created it, so a path written once and then read via
prose had no second occurrence to flag. Measured live: written from PID 21614,
read attempted from PID 23772. The invariant is now blanket (no $$ in any temp
path), which also caught fix.md and feature-gap.md.

M-BUG-43: 6 of 7 scanners write their payload to stdout when --raw/--json is
set even when --output-file was given, and the templates redirected only
stderr. Measured: posture 255 182 B, whats-active 35 922 B, drift 28 316 B,
manifest 23 825 B, tokens 8 768 B. fix and feature-gap never read the file they
wrote, so both recovered one letter grade from a quarter-megabyte dump.

tokens swallowed --json and --with-telemetry-recipe: documented, never
threaded, so --json returned the humanized payload where the docs promise
byte-stable v5.0.0 output.

M-BUG-42: manifest's render contract asked for {load}; the payload carries
loadPattern, so the Load column rendered blank for all 96 rows.

Four new tests (1449 -> 1453), each verified red before the fix. The
render-contract test checks {field} names against a live payload from a
fixture, since a hardcoded key list would drift. Frozen v5.0.0 snapshots
untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VGCk9o27eWo9uXLjkZTXEq
2026-08-01 20:40:07 +02:00

148 lines
5.5 KiB
Markdown

---
name: config-audit:discover
description: Phase 1 - Initialize session, auto-detect scope, and discover config files
argument-hint: "[current|repo|home|full] [--delta]"
allowed-tools: Read, Write, Edit, Glob, Grep, Agent, AskUserQuestion, Bash
model: opus
---
# Config-Audit: Discover (Phase 1)
Initialize a new audit session and discover all Claude Code configuration files.
## Usage
```
/config-audit discover # Auto-detect scope
/config-audit discover current # Force current directory scope
/config-audit discover repo # Force git repository scope
/config-audit discover home # Force home/global scope
/config-audit discover full # Force full machine scope
/config-audit discover --delta # Incremental re-scan (changed files only)
```
## Implementation
### Step 1: Initialize session and greet
Generate session ID (`YYYYMMDD_HHmmss`), create directories:
```bash
mkdir -p ~/.claude/config-audit/sessions/{session-id}/findings 2>/dev/null
```
### Step 2: Determine scope
If the user provided a scope argument, use it. Otherwise, auto-detect:
1. Run `git rev-parse --show-toplevel 2>/dev/null`
2. If inside a git repo → **repo** scope
3. If pwd is `$HOME`**home** scope
4. Otherwise → **current** directory scope
Tell the user:
```
## Configuration Discovery
**Scope:** {Repository|Home|Current directory|Full machine} — `{path}`
Finding all Claude Code configuration files (CLAUDE.md, settings, hooks, rules, MCP servers)...
```
### Step 3: Resolve paths
| Scope | What gets scanned |
|-------|-------------------|
| `current` | Current directory + parent CLAUDE.md files up to root + `~/.claude/` |
| `repo` | Git repo root + `~/.claude/` |
| `home` | `~/.claude/` only |
| `full` | `~/.claude/` (depth 10), managed paths, all dev dirs under $HOME |
### Step 4: Delta mode (if --delta)
If `--delta` flag:
1. Find previous baseline from `~/.claude/config-audit/sessions/*/discovery.json`
2. If no previous: "No previous scan found. Running full discovery instead."
3. Compare file mtimes/sizes to classify as changed/new/deleted/unchanged
4. Only scan changed + new files
### Step 5: Run discovery
Run the scan orchestrator silently to discover and scan files. Default mode emits humanized JSON — each finding in `scan-results.json` carries `userImpactCategory`, `userActionLanguage`, and `relevanceContext` alongside the v5.0.0 fields. Pass `--raw` through if the user requested it (produces v5.0.0 verbatim envelope; humanizer fields absent).
```bash
RAW_FLAG=""
if echo "$ARGUMENTS" | grep -q -- "--raw"; then RAW_FLAG="--raw"; fi
# Set to the flag itself for full/home scope, otherwise leave empty. Never pass
# a placeholder wrapped in square brackets: it does not start with a dash, so
# the orchestrator's arg loop takes it as the SCAN TARGET and silently scans a
# path that does not exist.
SCOPE_FLAGS="" # e.g. SCOPE_FLAGS="--full-machine" or SCOPE_FLAGS="--global"
node ${CLAUDE_PLUGIN_ROOT}/scanners/scan-orchestrator.mjs <target-path> --output-file ~/.claude/config-audit/sessions/{session-id}/findings/scan-results.json $SCOPE_FLAGS $RAW_FLAG >/dev/null 2>/dev/null; echo $?
```
Check exit code: 0/1/2 → normal. 3 → "Discovery encountered an error. Try a narrower scope."
### Step 6: Save scope and state
Write `scope.yaml` and `state.yaml` to session directory. Update state with all four fields `.claude/rules/state-management.md` requires: `current_phase: "discover"`, `completed_phases: [discover]`, `next_phase: "analyze"`, and `updated_at`. The last two are what make an interrupted run resumable.
### Step 7: Present summary
Read the scan results file using the Read tool. When you surface initial findings, group them by `userImpactCategory` and lead each line with `userActionLanguage` rather than raw severity prefiks — the humanizer already mapped severity to plain-language phrasing ("Fix this now", "Fix soon", "Fix when convenient", "Optional cleanup", "FYI") so the rest of the toolchain sees consistent wording.
**Full scan:**
```markdown
### Discovery Complete
**{scope_type}** scope — found {total_files} configuration files:
| Type | Count |
|------|-------|
| CLAUDE.md | {n} |
| Settings | {n} |
| MCP configs | {n} |
| Rules | {n} |
| Hooks | {n} |
| Other | {n} |
Initial scan found {finding_count} items to review (grouped by impact: {comma-separated counts per userImpactCategory}).
**Next:** Run `/config-audit analyze` to generate your analysis report.
```
**Delta scan:**
```markdown
### Delta Discovery Complete
Compared against baseline from {previous-session-id}:
| Status | Files |
|--------|-------|
| Changed | {n} |
| New | {n} |
| Deleted | {n} |
| Unchanged | {n} |
Only {changed+new} file(s) scanned (vs {total} full scan).
**Next:** Run `/config-audit analyze` to generate your analysis report.
```
## Config File Patterns
| Pattern | Description |
|---------|-------------|
| `**/CLAUDE.md` | Project instructions |
| `**/CLAUDE.local.md` | Local overrides |
| `**/.claude/settings.json` | Project settings |
| `**/.mcp.json` | MCP servers |
| `**/.claude/rules/*.md` | Modular rules |
For global: `~/.claude/CLAUDE.md`, `~/.claude/settings.json`, `~/.claude.json`, `~/.claude/agents/*.md`
## Error Handling
- If scanner fails, report to user in plain language and suggest narrower scope
- If path doesn't exist, tell user and suggest alternatives
- If git command fails for `repo` scope, silently fall back to `current`
- If no config files found, explain: "No Claude Code configuration files found. Start with `/config-audit feature-gap` to see what's recommended."