Pipeline step 4 dogfood. `/config-audit rollback` could not see a single one of
the four real backups on this machine, and reported "Backup not found" for one
that was sitting right there.
Four defects, one root: nothing agreed on where a backup lives or what its
manifest looks like.
- M-BUG-22 `lib/backup.mjs` resolved `~/.config-audit/backups` (pre-v2.2.0)
while every command, agent and doc uses `~/.claude/config-audit/backups`.
The auto-backup hook and fix-cli wrote to the first, implement to the second,
rollback read only the first. Canonical root now, with the legacy root kept
readable so older backups stay listable and restorable (`legacy: true`).
- M-BUG-25 `parseManifest` understood only the engine's quoted `original_path:`
spelling, but implement hand-builds its manifest with `- backup:`/`original:`/
`sha256:`. Every implement-made backup parsed to zero files and restoreBackup
returned `{restored: [], failed: []}` — a success-shaped no-op. Both formats
parse now, and a manifest with unparseable entries throws instead of
pretending to succeed.
- M-BUG-23 both session hooks watched `~/.config-audit/sessions`, which does not
exist; sessions live under `~/.claude/`. "Check for active sessions" had never
fired once. It fires now.
- M-BUG-24 the suite called createBackup() against the developer's real home —
it had left nine stray backups there, and cleanupOldBackups() deletes past ten.
Root is overridable via CONFIG_AUDIT_BACKUP_ROOT; both test files use it.
Rollback still cannot delete files implement CREATED — no backup can hold a file
that never existed. It no longer does so silently: manifests carry a `created:`
list, restoreBackup returns `createdNotRemoved`, and rollback.md requires the
report. Automatic deletion is a destructive action and needs its own design.
Verified against backup 20260717_032636 on a throwaway copy: all three files
restore byte-exact (sha256 match), zero writes outside the copy, backup dir
unmodified. Suite 1382 -> 1398/0; frozen v5.0.0 snapshots untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SejM9RQAa1Hfuq7Ek2WfFr
162 lines
4.9 KiB
Markdown
162 lines
4.9 KiB
Markdown
---
|
|
name: config-audit:implement
|
|
description: Phase 5 - Execute action plan with backups and verification
|
|
allowed-tools: Read, Write, Edit, Bash, Agent, AskUserQuestion
|
|
model: opus
|
|
---
|
|
|
|
# Config-Audit: Implementation (Phase 5)
|
|
|
|
Execute the action plan with full backup, verification, and rollback support.
|
|
|
|
## Prerequisites
|
|
|
|
- Must have completed Phase 4 (plan)
|
|
- Action plan at `~/.claude/config-audit/sessions/{session-id}/action-plan.md`
|
|
|
|
## Arguments
|
|
|
|
- `$ARGUMENTS` may contain `--raw` to forward to the implementer-agent's instructions; in `--raw` mode the agent renders v5.0.0 verbatim severity prefiks instead of humanized `userActionLanguage` urgency phrasing.
|
|
|
|
## Implementation
|
|
|
|
### Step 1: Parse flags, load and verify
|
|
|
|
```bash
|
|
RAW_FLAG=""
|
|
if echo "$ARGUMENTS" | grep -q -- "--raw"; then RAW_FLAG="--raw"; fi
|
|
```
|
|
|
|
Find the most recent session with a plan. If none: "No action plan found. Run `/config-audit plan` first."
|
|
|
|
Use the Read tool on the action plan and count actions. Tell the user:
|
|
|
|
```
|
|
## Implementing Action Plan
|
|
|
|
Found {N} actions to execute across {M} files.
|
|
A backup will be created before any changes are made.
|
|
```
|
|
|
|
### Step 2: Get user approval
|
|
|
|
```
|
|
AskUserQuestion:
|
|
question: "Ready to implement {N} actions? Backup created automatically — you can roll back with one command."
|
|
options:
|
|
- "Yes, proceed"
|
|
- "Review plan first" (then show the plan file path)
|
|
- "Cancel"
|
|
```
|
|
|
|
### Step 3: Create backup
|
|
|
|
Create backup silently:
|
|
|
|
```bash
|
|
mkdir -p ~/.claude/config-audit/backups/$(date +%Y%m%d_%H%M%S)/files/ 2>/dev/null
|
|
```
|
|
|
|
Copy each file to be modified. Generate `manifest.yaml` with checksums.
|
|
|
|
The manifest is what `/config-audit rollback` reads, so it MUST carry both lists:
|
|
|
|
```yaml
|
|
files: # pre-existing files this run will MODIFY
|
|
- backup: files/root/CLAUDE.md
|
|
original: /abs/path/CLAUDE.md
|
|
sha256: <sha256 of the pre-change content>
|
|
created: # files this run will CREATE (no backup can exist)
|
|
- /abs/path/.claude/rules/post-quality.md
|
|
```
|
|
|
|
Record every `create`-type action under `created:`. Rollback cannot restore a
|
|
file that never existed, but it must be able to tell the user which files it is
|
|
leaving behind — a half-restored target is only dangerous when it is silent.
|
|
|
|
Tell the user: **"Backup created. Implementing actions..."**
|
|
|
|
### Step 4: Execute actions
|
|
|
|
Group actions by dependencies. For each group, spawn implementer agents (batch of 3):
|
|
|
|
```
|
|
Agent(subagent_type: "config-audit:implementer-agent")
|
|
model: sonnet
|
|
prompt: |
|
|
Execute action: {action-id}
|
|
File: {file-path}, Type: {create|modify|delete}
|
|
Mode: $RAW_FLAG (empty = humanized progress prose; "--raw" = v5.0.0 verbatim)
|
|
Details: {changes}
|
|
Verify backup exists, make change, validate syntax.
|
|
When logging progress, use the humanized title/userActionLanguage
|
|
fields from the action plan (the planner already rendered them) —
|
|
do not re-derive severity prose. Append result to:
|
|
~/.claude/config-audit/sessions/{session-id}/implementation-log.md
|
|
Append with Bash `>>` (heredoc) — NEVER the Write tool on this log;
|
|
parallel agents share it and a full-file Write clobbers their entries.
|
|
```
|
|
|
|
Show progress between groups using the humanized titles already present in the action plan:
|
|
|
|
```
|
|
Action 1/N: {humanized title} — done
|
|
Action 2/N: {humanized title} — done
|
|
...
|
|
```
|
|
|
|
### Step 5: Verify results
|
|
|
|
Spawn verifier agent:
|
|
|
|
```
|
|
Agent(subagent_type: "config-audit:verifier-agent")
|
|
model: sonnet (note: using sonnet, not haiku)
|
|
prompt: |
|
|
Verify all changes from implementation:
|
|
1. Modified files exist and are syntactically valid
|
|
2. New files created correctly
|
|
3. No new conflicts introduced
|
|
Report to: ~/.claude/config-audit/sessions/{session-id}/implementation-log.md
|
|
```
|
|
|
|
If verifier finds issues: one retry with implementer agent. If still failing: report and suggest rollback.
|
|
|
|
### Step 6: Present results
|
|
|
|
```markdown
|
|
### Implementation Complete
|
|
|
|
**{succeeded} succeeded** | {failed} failed | {skipped} skipped
|
|
|
|
{If score improved, run quick posture and show:}
|
|
Score impact: {old_grade} → {new_grade} (+{delta} points)
|
|
|
|
{If failed > 0:}
|
|
{failed} action(s) couldn't be completed — see log for details.
|
|
|
|
**Backup location:** `~/.claude/config-audit/backups/{timestamp}/`
|
|
**Rollback:** `/config-audit rollback {timestamp}`
|
|
**Full log:** `~/.claude/config-audit/sessions/{session-id}/implementation-log.md`
|
|
```
|
|
|
|
### Step 7: Update state
|
|
|
|
Update `state.yaml` with `current_phase: "implement"`, `next_phase: null`.
|
|
|
|
## Rollback
|
|
|
|
If the user requests rollback at any point:
|
|
1. Read `manifest.yaml` from backup
|
|
2. Restore each file and verify checksums
|
|
3. Delete newly created files
|
|
4. Update state to `rolled_back`
|
|
|
|
## Error Handling
|
|
|
|
| Error | What happens |
|
|
|-------|-------------|
|
|
| Permission denied | Skip action, log it, continue with others |
|
|
| File not found | Skip action, log it, continue |
|
|
| Invalid syntax after edit | Rollback that single file, log, continue |
|
|
| Critical failure | Offer full rollback |
|