# Foxhunt Specialized Agents & Skills Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Build 12 foxhunt-aware claude agents and skills (5 auditor agents + 5 workflow skills + 2 maintenance skills) plus their PostToolUse hook router, so future sessions automatically apply accumulated `feedback_*`/`pearl_*` discipline.

**Architecture:** Pattern-cluster auditor agents (each bundles a family of related invariants) + workflow-skill templates (sp-spec, isv-slot scaffolding, pearl distillation, argo deploy, smoke pilot) + maintenance skills (memory curation, stale-worktree cleanup). All under `.claude/agents/foxhunt/` and `.claude/skills/foxhunt/`, additive to existing claude-flow / superpowers content. Hook router is warn-only PostToolUse, <200 ms, never blocks.

**Tech Stack:** Markdown (with YAML frontmatter) for agents and skills, Bash for the hook router, Node-free.

**Spec:** [`docs/superpowers/specs/2026-05-10-foxhunt-specialized-agents-design.md`](../specs/2026-05-10-foxhunt-specialized-agents-design.md)

---

## Conventions used by this plan

- **Agent files** live at `.claude/agents/foxhunt/<name>.md`. They have YAML frontmatter `name:` + `description:` and a markdown body. Claude Code dispatches them via `subagent_type: "<name>"`.
- **Skill files** live at `.claude/skills/foxhunt/<name>/SKILL.md`. They have YAML frontmatter `name:` + `description:` and a markdown body. Invoked via the `Skill` tool with `skill: "<name>"`.
- **Memory paths**: `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/`. Agents reference memory files by basename only (e.g., `feedback_no_atomicadd.md`).
- **Commit scope**: `feat(claude)` for new agents/skills; `chore(claude)` for hook plumbing. Commit message footer: `Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>`.
- **Verification**: each agent/skill is verified by an explicit dispatch on a known input. Markdown content does not have unit tests; the integration test is the dispatch.

---

## Task 1: Foundation — gitignore, hook router, settings.json hook block

**Files:**
- Create: `.claude/helpers/foxhunt-audit-router.sh`
- Modify: `.gitignore` (append `.claude/.foxhunt-audit-state`)
- Modify: `.claude/settings.json` (additive: append `PostToolUse` hook block)

- [ ] **Step 1: Add `.claude/.foxhunt-audit-state` to `.gitignore`**

Append the line `.claude/.foxhunt-audit-state` to the project-root `.gitignore` if not already present. Use Edit (read first, then add the line at the end).

- [ ] **Step 2: Create the hook router script**

Create `.claude/helpers/foxhunt-audit-router.sh` with this exact content:

```bash
#!/usr/bin/env bash
# foxhunt-audit-router.sh
#
# PostToolUse hook router. Reads Claude Code tool-input JSON from stdin,
# inspects the file path being edited, and emits at most one one-line hint
# to stdout suggesting which foxhunt-* auditor agents to dispatch.
#
# Contract:
#  - Completes in <200 ms.
#  - Never spawns agents itself.
#  - Always exits 0 (never blocks).
#  - One suggestion per (path, agent) per session, tracked in
#    .claude/.foxhunt-audit-state (gitignored, cleared at SessionStart).

set -u  # not -e; we want to exit 0 even on errors

STATE_FILE="${CLAUDE_PROJECT_DIR:-.}/.claude/.foxhunt-audit-state"
mkdir -p "$(dirname "$STATE_FILE")" 2>/dev/null || exit 0
touch "$STATE_FILE" 2>/dev/null || exit 0

# Read tool input from stdin; bail if not JSON or no file_path
INPUT="$(cat 2>/dev/null || true)"
[ -z "$INPUT" ] && exit 0

# Extract file path. Claude Code sends keys like "tool_input": {"file_path": "..."}
# Be lenient: try multiple JSON shapes via grep/sed (avoid jq dep).
PATH_FOUND="$(printf '%s' "$INPUT" | grep -oE '"file_path"[[:space:]]*:[[:space:]]*"[^"]+"' | head -1 | sed -E 's/.*"file_path"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')"
[ -z "$PATH_FOUND" ] && exit 0

# Make path repo-relative if absolute
REPO_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
case "$PATH_FOUND" in
  "$REPO_ROOT"/*) REL="${PATH_FOUND#$REPO_ROOT/}" ;;
  /*)             REL="$PATH_FOUND" ;;
  *)              REL="$PATH_FOUND" ;;
esac

# Routing table: build SUGGEST list of agent names
SUGGEST=()
case "$REL" in
  *.cu)                                  SUGGEST+=("gpu-contract-auditor") ;;
  *cuda/*.rs|*/cuda/*)                   SUGGEST+=("gpu-contract-auditor") ;;
  crates/*/build.rs)                     SUGGEST+=("gpu-contract-auditor") ;;
esac
case "$REL" in
  */experience_kernels.cu|*reward*.rs|*reward*.cu|*controller*.rs|*trader_*.rs)
    SUGGEST+=("reward-controller-auditor") ;;
esac
case "$REL" in
  *sp*_isv_slots.rs)                     SUGGEST+=("isv-discipline-auditor") ;;
  crates/ml-*/*.rs|crates/ml-*/**/*.rs)  SUGGEST+=("isv-discipline-auditor") ;;
esac
case "$REL" in
  docs/superpowers/specs/*.md|docs/plans/*.md)
    SUGGEST+=("sp-critical-reviewer") ;;
esac
case "$REL" in
  MEMORY.md|*memory/pearl_*.md|*memory/feedback_*.md)
    SUGGEST+=("memory-curator") ;;
esac
# Default for any rust file in crates/ services/ bin/ that didn't match above
case "$REL" in
  crates/*.rs|crates/**/*.rs|services/*.rs|services/**/*.rs|bin/*.rs|bin/**/*.rs)
    # Add code-hygiene unconditionally for Rust source
    SUGGEST+=("code-hygiene-auditor") ;;
esac

[ "${#SUGGEST[@]}" -eq 0 ] && exit 0

# Dedupe SUGGEST and filter against state file (one suggestion per (path, agent) per session)
EMIT=()
for AGENT in "${SUGGEST[@]}"; do
  KEY="$REL|$AGENT"
  if ! grep -Fxq "$KEY" "$STATE_FILE" 2>/dev/null; then
    echo "$KEY" >> "$STATE_FILE"
    # Dedupe within this invocation too
    case " ${EMIT[*]:-} " in *" $AGENT "*) ;; *) EMIT+=("$AGENT") ;; esac
  fi
done

[ "${#EMIT[@]}" -eq 0 ] && exit 0

# Emit single-line hint, prefixed for grep
JOINED="$(printf '%s, ' "${EMIT[@]}")"; JOINED="${JOINED%, }"
echo "[foxhunt-audit] $REL — suggest: $JOINED"
exit 0
```

Make it executable: `chmod +x .claude/helpers/foxhunt-audit-router.sh`.

- [ ] **Step 3: Add a SessionStart hook that clears the state file**

Append to `.claude/helpers/foxhunt-audit-router.sh` is not the place — add a tiny separate clear script. Create `.claude/helpers/foxhunt-audit-session-start.sh`:

```bash
#!/usr/bin/env bash
# Clear foxhunt-audit dedup state at session start.
STATE_FILE="${CLAUDE_PROJECT_DIR:-.}/.claude/.foxhunt-audit-state"
: > "$STATE_FILE" 2>/dev/null || true
exit 0
```

Then `chmod +x .claude/helpers/foxhunt-audit-session-start.sh`.

- [ ] **Step 4: Wire hooks into `.claude/settings.json` (additive merge)**

First, **read** `.claude/settings.json` to confirm its current content matches the snapshot below. The file currently has unusual indentation (`"permissions"` at column 0) — preserve it exactly.

Current content (verify before editing):

```json
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" session-restore",
            "timeout": 15
          }
        ]
      }
    ],
    "SessionEnd": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" session-end",
            "timeout": 10
          }
        ]
      }
    ]
  },
"permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)"
    ]
  }
}
```

If the file differs from this snapshot (e.g., other hooks added since plan was written), STOP and reconcile manually before continuing.

**Edit 1** — Add a second entry to the SessionStart array (router-clear hook).

`old_string`:
```
            "command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" session-restore",
            "timeout": 15
          }
        ]
      }
    ],
    "SessionEnd": [
```

`new_string`:
```
            "command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" session-restore",
            "timeout": 15
          }
        ]
      },
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/helpers/foxhunt-audit-session-start.sh\"",
            "timeout": 5
          }
        ]
      }
    ],
    "SessionEnd": [
```

**Edit 2** — Add the PostToolUse top-level array between SessionEnd and the closing of `"hooks"`.

`old_string`:
```
            "command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" session-end",
            "timeout": 10
          }
        ]
      }
    ]
  },
"permissions": {
```

`new_string`:
```
            "command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" session-end",
            "timeout": 10
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/helpers/foxhunt-audit-router.sh\"",
            "timeout": 2
          }
        ]
      }
    ]
  },
"permissions": {
```

**Verify the result** parses as valid JSON:

```bash
python3 -c 'import json,sys; json.load(open(".claude/settings.json")); print("OK")'
```

Expected: `OK`. If `JSONDecodeError`, revert via `git checkout -- .claude/settings.json` and retry the Edit pair.

- [ ] **Step 5: Manual test of the router**

Run from the repo root:

```bash
echo '{"tool_input":{"file_path":"/home/jgrusewski/Work/foxhunt/crates/ml-dqn/src/cuda/foo.cu"}}' \
  | bash .claude/helpers/foxhunt-audit-router.sh
```

Expected output (single line):

```
[foxhunt-audit] crates/ml-dqn/src/cuda/foo.cu — suggest: gpu-contract-auditor
```

**Note**: the router assumes Claude Code's PostToolUse stdin payload has shape `{"tool_input": {"file_path": "..."}}`. If the actual payload differs (e.g., key is `"path"` or top-level), the router will silently emit nothing. After Step 6 commit, do a real edit on a `.cu` file in this session and confirm the hint appears (Task 14 Step 6 covers this). If no hint appears, log the actual stdin payload by adding `cat > /tmp/foxhunt-hook-payload.json` at the top of the router temporarily, observe one payload, then update the regex extraction in the router.

Run it a second time with the same input. Expected: empty output (dedup filter active).

Run with a non-matching path:

```bash
echo '{"tool_input":{"file_path":"/home/jgrusewski/Work/foxhunt/web-dashboard/foo.tsx"}}' \
  | bash .claude/helpers/foxhunt-audit-router.sh
```

Expected: empty output (web-dashboard is out of scope).

Time it:

```bash
time (echo '{"tool_input":{"file_path":"/home/jgrusewski/Work/foxhunt/crates/ml-dqn/src/cuda/bar.cu"}}' \
  | bash .claude/helpers/foxhunt-audit-router.sh)
```

Expected: real time well under 200 ms.

- [ ] **Step 6: Commit**

```bash
git add .gitignore .claude/helpers/foxhunt-audit-router.sh .claude/helpers/foxhunt-audit-session-start.sh .claude/settings.json
git commit -m "$(cat <<'EOF'
chore(claude): foxhunt audit hook router (warn-only PostToolUse)

Adds .claude/helpers/foxhunt-audit-router.sh that suggests foxhunt-* auditor
agents based on edited file path. Warn-only, <200ms, never blocks. Dedup
state file .claude/.foxhunt-audit-state cleared at SessionStart by sibling
script. Settings.json additive merge — existing hooks preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 2: `gpu-contract-auditor` agent

**Files:**
- Create: `.claude/agents/foxhunt/gpu-contract-auditor.md`

- [ ] **Step 1: Write the agent file**

Create `.claude/agents/foxhunt/gpu-contract-auditor.md` with this exact content:

````markdown
---
name: gpu-contract-auditor
description: Audits CUDA kernels and GPU host code in the foxhunt repo for GPU/CPU contract violations — no atomicAdd, mapped-pinned only, no nvrtc, no host branches in graph capture, fused per-group stats, build.rs rerun-if-env-changed. Read-only review; never auto-fixes; cites memory file by name on every finding.
---

# Foxhunt GPU Contract Auditor

Specialist auditor for CUDA kernels and GPU host code in the foxhunt repo. Bundles all accumulated GPU discipline. Read memory before reviewing — pearls evolve.

## Memory you MUST read first

Before reviewing any code, read these files in `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/`. If a file is missing or contradicts current code, prefer the code (per `feedback_trust_code_not_docs.md`) and note the staleness in your output.

- `feedback_cpu_is_read_only.md`
- `feedback_no_atomicadd.md`
- `feedback_no_htod_htoh_only_mapped_pinned.md`
- `feedback_no_cpu_test_fallbacks.md`
- `feedback_no_nvrtc.md`
- `feedback_cudarc_f64_f32_abi.md`
- `pearl_no_host_branches_in_captured_graph.md`
- `pearl_cold_path_no_exception_to_gpu_drives.md`
- `pearl_fused_per_group_statistics_oracle.md`
- `pearl_sp4_histogram_warp_tile_undercount.md`
- `pearl_cublas_lt_vs_classic_sgemm.md`
- `pearl_build_rs_rerun_if_env_changed.md`
- `pearl_canary_input_freshness_launch_order.md`

## When to invoke

- Edits to `**/*.cu`, `**/cuda/**/*.rs`, `crates/*/build.rs`.
- Explicit request: "audit GPU contract for <path>".

## Invariants to verify

For every file in scope, check each invariant. Number every finding; cite the originating memory filename on every finding; never give a generic complaint.

1. **No `atomicAdd`** (`feedback_no_atomicadd.md`). Block tree-reduce only. No exceptions, including in tests.
2. **No HtoD/HtoH outside mapped-pinned** (`feedback_no_htod_htoh_only_mapped_pinned.md`). `cudaMemcpy` Host↔Device or Host↔Host only allowed when host buffer is mapped-pinned. Tests are not exempt.
3. **No `nvrtc` runtime compilation** (`feedback_no_nvrtc.md`). Pre-compiled cubins only.
4. **f64/f32 ABI matches kernel signature** (`feedback_cudarc_f64_f32_abi.md`). When calling `__global__ void f(float x, ...)` from cudarc, every arg must be cast `as f32` before the launch builder.
5. **No host branches inside CUDA graph capture** (`pearl_no_host_branches_in_captured_graph.md`). `if`/`match` on host state inside the captured region breaks recording.
6. **Fused per-group statistics** (`pearl_fused_per_group_statistics_oracle.md`). For K groups × N stats, expect ONE fused kernel; multiple separate kernels for the same statistic family is a violation.
7. **`build.rs` rerun-if-env-changed paired** (`pearl_build_rs_rerun_if_env_changed.md`). Every `std::env::var()` paired with `cargo:rerun-if-env-changed=<NAME>`.
8. **Producer-before-canary launch order** (`pearl_canary_input_freshness_launch_order.md`). Canary kernels reading slot K must be launched after the producer that writes K.
9. **No CPU test fallbacks** (`feedback_no_cpu_test_fallbacks.md`). GPU oracle tests only — no CPU "reference impl" sibling kernel.
10. **No CPU compute on hot path** (`feedback_cpu_is_read_only.md`, `pearl_cold_path_no_exception_to_gpu_drives.md`). CPU is read-only for GPU drives. "Cold path" frequency does not earn an exception.

## Output format

```
[gpu-contract-auditor] reviewed: <space-separated paths>

Findings: N
1. [SEVERITY] <invariant short name> — <path>:<line>
   What: <one sentence: what is wrong>
   Memory: <feedback_*.md or pearl_*.md basename>
   Fix: <one sentence: corrective action>

2. ...

Pearls considered, no violation: <comma-separated short names>
```

Severities: BLOCKER (revert change), HIGH (fix before merge), LOW (fix-up worthy).

## What this agent does NOT do

- Does NOT write into `memory/` (only `pearl-distiller` and `memory-curator` do).
- Does NOT auto-fix code; only reports.
- Does NOT review non-GPU code (delegate to `code-hygiene-auditor`).
````

- [ ] **Step 2: Verify dispatch**

In a fresh session (or by invoking from this one), dispatch:

```
Use the gpu-contract-auditor agent on crates/ml-dqn/src/cuda/experience_kernels.cu around the reward-cap region (line ~2780-2800). The pearl pearl_symmetric_clamp_audit.md documents that this region was previously fixed for one-sided fmin → bilateral; verify the bilateral form is still in place.
```

Expected: agent output cites at least one memory file by name; uses the prescribed `[gpu-contract-auditor] reviewed:` prefix; finds either the bilateral clamp present (no findings) or correctly flags any regression.

If the agent does not load (Claude Code reports "subagent_type not found"), confirm the frontmatter `name:` field matches `gpu-contract-auditor` exactly (no quotes mismatch, no leading whitespace).

- [ ] **Step 3: Commit**

```bash
git add .claude/agents/foxhunt/gpu-contract-auditor.md
git commit -m "$(cat <<'EOF'
feat(claude): gpu-contract-auditor agent (foxhunt)

Pattern-cluster auditor for CUDA/GPU host code. Bundles 6 feedback rules and
7 pearls (no atomicAdd, mapped-pinned, no nvrtc, f64/f32 ABI, no host branches
in graph capture, fused per-group stats, build.rs rerun, canary launch order).
Read-only; cites memory file by name on every finding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 3: `isv-discipline-auditor` agent

**Files:**
- Create: `.claude/agents/foxhunt/isv-discipline-auditor.md`

- [ ] **Step 1: Write the agent file**

Create `.claude/agents/foxhunt/isv-discipline-auditor.md` with this exact content:

````markdown
---
name: isv-discipline-auditor
description: Audits foxhunt ML/RL Rust code for ISV-discipline violations — hardcoded constants that should be ISV-driven, missing first-observation bootstrap on EMAs, Wiener-α controllers without floor in non-stationary loops, blend formulas instead of max-with-floor, controller ratios without z-score normalization, per-branch budgets that should derive from per-branch flatness. Read-only review; cites memory file by name on every finding.
---

# Foxhunt ISV Discipline Auditor

Specialist auditor for adaptive bounds, controllers, and signal-driven hyperparameters. Read memory before reviewing.

## Memory you MUST read first

In `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/`:

- `feedback_isv_for_adaptive_bounds.md`
- `feedback_adaptive_not_tuned.md`
- `pearl_controller_anchors_isv_driven.md`
- `pearl_first_observation_bootstrap.md`
- `pearl_wiener_optimal_adaptive_alpha.md`
- `pearl_wiener_alpha_floor_for_nonstationary.md`
- `pearl_blend_formulas_must_have_permanent_floor.md`
- `pearl_zscore_normalization_for_magnitude_asymmetric_signals.md`
- `pearl_per_branch_c51_atom_span.md`
- `pearl_per_branch_iqn_tau_schedule.md`
- `pearl_per_branch_loss_budget.md`
- `pearl_per_branch_noisy_sigma.md`
- `pearl_per_group_adam_hyperparams.md`
- `pearl_kelly_cap_signal_driven_floors.md`
- `pearl_trail_stop_signal_driven.md`
- `pearl_adaptive_moe_lambda.md`
- `pearl_l1_lambda_grad_direction_entropy_deficit.md`
- `pearl_cold_start_exit_signal_or.md`

## When to invoke

- Edits to `crates/ml-*/**/*.rs`, `**/sp*_isv_slots.rs`.
- Explicit request: "audit ISV discipline for <path>".

## Invariants to verify

1. **Hardcoded multipliers/caps/anchors** (`feedback_isv_for_adaptive_bounds.md`, `pearl_controller_anchors_isv_driven.md`). Numeric literals used as anchor/target/cap/floor for adaptive behavior must derive from an ISV slot. Suggest a slot index and name.
2. **First-observation bootstrap on EMAs** (`pearl_first_observation_bootstrap.md`). EMA initialized to `0.0` (sentinel); first observation replaces directly, not blended. Flag any EMA initialized to a tuned constant.
3. **Wiener-α floor in non-stationary loops** (`pearl_wiener_alpha_floor_for_nonstationary.md`). Wiener-optimal α is MSE-optimal for stationary signals only. Where the target co-adapts (control loops), α must have a permanent floor (≥ 0.4 typical).
4. **Blend formulas use `max(real, floor)`** (`pearl_blend_formulas_must_have_permanent_floor.md`). Never `α·real + (1−α)·floor` — that deadlocks if real → 0.
5. **Controller ratios over magnitude-asymmetric signals z-score-normalized** (`pearl_zscore_normalization_for_magnitude_asymmetric_signals.md`, `pearl_controller_amplifies_dominant_magnitude_trap.md`). Ratios like `winner_weight = mag[c] / sum(mag)` over branches with intrinsically different magnitudes always elect the largest. Use `z[c] = mag[c] / sqrt(var[c])` instead.
6. **Per-branch C51/IQN/CQL/Ens budgets** (`pearl_per_branch_loss_budget.md`, `pearl_per_branch_c51_atom_span.md`, `pearl_per_branch_iqn_tau_schedule.md`, `pearl_per_branch_noisy_sigma.md`). Budgets and atom spans derived per-branch from per-branch flatness/skew/entropy-deficit; never shared across branches.
7. **Per-group Adam hyperparams** (`pearl_per_group_adam_hyperparams.md`). β₁/β₂/ε per param-group from grad direction-stability, not global.
8. **Kelly floors signal-driven, cross-fold-persistent** (`pearl_kelly_cap_signal_driven_floors.md`). Kelly floors derive from a cross-fold-persistent signal; sentinel-bootstrap is incompatible (don't reset at fold boundary).
9. **Trail-stop distance signal-driven** (`pearl_trail_stop_signal_driven.md`, `pearl_trail_fire_pre_vs_action_mag.md`). Per-direction trail distance signal-driven; trail filter on `pre_mag`, not `action_mag`.

## Output format

```
[isv-discipline-auditor] reviewed: <paths>

Findings: N
1. [SEVERITY] <invariant short name> — <path>:<line>
   What: <one sentence>
   Memory: <feedback_*.md or pearl_*.md basename>
   Fix: <one sentence; if ISV-slot needed, suggest slot name and bump>

Pearls considered, no violation: <comma-separated short names>
```

## What this agent does NOT do

- Does NOT scaffold the ISV slot — that's the `isv-slot-scaffolder` skill.
- Does NOT write into `memory/`.
- Does NOT block; warn-only.
````

- [ ] **Step 2: Verify dispatch**

Dispatch the agent on a known target:

```
Use the isv-discipline-auditor agent on the SP15 plan v2 doc + crates/ml-dqn/src/cuda/experience_kernels.cu (the reward and trail regions). Confirm it cites pearl_kelly_cap_signal_driven_floors.md and pearl_trail_stop_signal_driven.md by name in any finding it produces.
```

Expected: agent output uses the `[isv-discipline-auditor] reviewed:` prefix and cites at least one memory file by name on each finding.

- [ ] **Step 3: Commit**

```bash
git add .claude/agents/foxhunt/isv-discipline-auditor.md
git commit -m "$(cat <<'EOF'
feat(claude): isv-discipline-auditor agent (foxhunt)

Pattern-cluster auditor for ISV-driven adaptive bounds, controller anchors,
EMA bootstrap, Wiener-α floors, blend formulas, per-branch budgets, per-group
Adam, Kelly floors, trail-stop. Bundles 2 feedback rules and 16 pearls.
Read-only; cites memory file by name on every finding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 4: `reward-controller-auditor` agent

**Files:**
- Create: `.claude/agents/foxhunt/reward-controller-auditor.md`

- [ ] **Step 1: Write the agent file**

Create `.claude/agents/foxhunt/reward-controller-auditor.md` with this exact content:

````markdown
---
name: reward-controller-auditor
description: Audits foxhunt reward kernels and controllers for clamp symmetry, structural-activation bounds, asymmetric-bounded clamp where unboundedness was implicit asymmetry, event-driven reward density alignment, one-unbounded-multiplicand rule, Thompson-vs-argmax selectors, trail filter on pre_mag, Adam-normalized loss-weight no-ops. Read-only review; cites memory file by name on every finding.
---

# Foxhunt Reward & Controller Auditor

Specialist auditor for reward composition and controller mechanics. Bundles the SP11→SP12 reward-discipline pearls and the controller-design pearls.

## Memory you MUST read first

In `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/`:

- `pearl_audit_unboundedness_for_implicit_asymmetry.md`
- `pearl_event_driven_reward_density_alignment.md`
- `pearl_symmetric_clamp_audit.md`
- `pearl_one_unbounded_signal_per_reward.md`
- `pearl_bounded_modifier_outputs_require_structural_activation.md`
- `pearl_loss_balance_controller.md`
- `pearl_engagement_rate_self_correction.md`
- `pearl_learned_gate_subsumes_handcoded.md`
- `pearl_controller_amplifies_dominant_magnitude_trap.md`
- `pearl_per_bar_vs_segment_pnl_signal_mismatch.md`
- `pearl_thompson_for_distributional_action_selection.md`
- `pearl_trail_fire_pre_vs_action_mag.md`
- `pearl_adam_normalizes_loss_weights.md`
- `pearl_separate_aux_trunk_when_shared_starves.md`
- `pearl_imbalance_bar_ewma_washes_out_configured_threshold.md`
- `pearl_intent_dist_freeze_resolved.md`
- `pearl_reward_shape_drives_quality_over_quantity.md` (deprecated; check for back-compat regressions)

## When to invoke

- Edits to `**/cuda/experience_kernels.cu`, `**/reward*.{rs,cu}`, `**/controller*.rs`, `**/trader_*.rs`.
- Explicit request: "audit reward/controller for <path>".

## Invariants to verify

1. **Bilateral clamps** (`pearl_symmetric_clamp_audit.md`). Kernel-derived bounded scalars use `fmaxf(lo, fminf(x, hi))`; one-sided `fminf` or `fmaxf` is a violation — leaves an unbounded tail that contaminates downstream EMAs.
2. **Bounded modifier outputs use structural activation** (`pearl_bounded_modifier_outputs_require_structural_activation.md`). Spec-bounded model outputs feeding multiplicative modifiers use sigmoid/tanh, not runtime clamps.
3. **Asymmetric bounded clamp where unboundedness was implicit asymmetry** (`pearl_audit_unboundedness_for_implicit_asymmetry.md`). When adding bounds to fix a stability bug, audit whether the unboundedness was implicitly providing behavioral asymmetry; preserve via asymmetric clamp (loss > win caps for loss aversion).
4. **Event-driven reward density alignment** (`pearl_event_driven_reward_density_alignment.md`). For event-driven objectives (trade close), reward density must match objective density. Per-step dense shaping creates exposure-positive bias. Use eligibility traces / TD(λ) / decomposition, not per-step shaping.
5. **One unbounded multiplicand per reward term** (`pearl_one_unbounded_signal_per_reward.md`). Exactly one — more produces compounding tail risk.
6. **Thompson selector for action selection** (`pearl_thompson_for_distributional_action_selection.md`). Train AND eval; argmax only for the Bellman target.
7. **Trail filter on `pre_mag`** (`pearl_trail_fire_pre_vs_action_mag.md`). Trail filter reads prior position magnitude, not the proposed action magnitude.
8. **Per-loss weight changes flagged as Adam-normalized no-ops** (`pearl_adam_normalizes_loss_weights.md`). Adam's `m/sqrt(v)` makes per-loss weight lifts no-ops at convergence. Suggest per-group LR or loss-function changes instead.
9. **Per-bar vs segment-PnL win-rate alignment** (`pearl_per_bar_vs_segment_pnl_signal_mismatch.md`). Win-rate predicates for trade-close objectives must read segment-level realized P&L, not per-bar `step_ret > 0` (per-bar at close includes tx_cost deduction → systematically negative on winning trades).
10. **Imbalance-bar threshold not washed out by EWMA** (`pearl_imbalance_bar_ewma_washes_out_configured_threshold.md`). `ImbalanceBarSampler::new_with_ewma()` with α=0.1 washes the configured threshold within ~5 bars. Use `new()` if you need the threshold to stick.
11. **Aux supervision trunk separation** (`pearl_separate_aux_trunk_when_shared_starves.md`). When aux CE plateaus at ln(K), give aux supervision its own trunk with independent Adam + stop-grad at encoder boundary.
12. **Controller magnitude-trap** (`pearl_controller_amplifies_dominant_magnitude_trap.md`). `winner_weight = ratio` with intrinsically-asymmetric magnitudes always elects the largest. Z-score-normalize first.

## Output format

```
[reward-controller-auditor] reviewed: <paths>

Findings: N
1. [SEVERITY] <invariant short name> — <path>:<line>
   What: <one sentence>
   Memory: <pearl_*.md basename>
   Fix: <one sentence>

Pearls considered, no violation: <comma-separated short names>
```

## What this agent does NOT do

- Does NOT review non-reward CUDA kernels (delegate to `gpu-contract-auditor`).
- Does NOT write into `memory/`.
- Does NOT block; warn-only.
````

- [ ] **Step 2: Verify dispatch**

Dispatch the agent on a known target:

```
Use the reward-controller-auditor agent on crates/ml-dqn/src/cuda/experience_kernels.cu line ~2788 (the reward-cap region) and on the trail-stop logic in trader code. Confirm it cites pearl_symmetric_clamp_audit.md and pearl_trail_fire_pre_vs_action_mag.md if relevant.
```

Expected: prefixed output, memory citations on each finding, no false BLOCKERs.

- [ ] **Step 3: Commit**

```bash
git add .claude/agents/foxhunt/reward-controller-auditor.md
git commit -m "$(cat <<'EOF'
feat(claude): reward-controller-auditor agent (foxhunt)

Pattern-cluster auditor for reward composition and controller mechanics:
bilateral clamps, structural activations, asymmetric bounded clamps, event-
driven density alignment, one-unbounded-multiplicand, Thompson selector,
trail-on-pre_mag, Adam-normalized loss weights, per-bar vs segment PnL,
imbalance-bar EWMA wash-out, aux trunk separation, magnitude-trap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 5: `code-hygiene-auditor` agent

**Files:**
- Create: `.claude/agents/foxhunt/code-hygiene-auditor.md`

- [ ] **Step 1: Write the agent file**

Create `.claude/agents/foxhunt/code-hygiene-auditor.md` with this exact content:

````markdown
---
name: code-hygiene-auditor
description: Audits foxhunt Rust code for hygiene violations — stubs, TODO/FIXME/XXX, _ hiding, #[allow] suppression, legacy aliases, enable_*/use_* feature flags, partial refactors, observed-value tests instead of invariant tests, quick-fixes, deferral of complementary fixes. Read-only review; cites memory file by name on every finding.
---

# Foxhunt Code Hygiene Auditor

Specialist auditor for general code-quality discipline across the workspace.

## Memory you MUST read first

In `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/`:

- `feedback_no_stubs.md`
- `feedback_no_todo_fixme.md`
- `feedback_no_hiding.md`
- `feedback_no_legacy_aliases.md`
- `feedback_no_feature_flags.md`
- `feedback_no_quickfixes.md`
- `feedback_no_functionality_removal.md`
- `feedback_no_partial_refactor.md`
- `feedback_wire_everything_up.md`
- `feedback_v7_gem_methodology.md`
- `feedback_magnitude_must_be_useful.md`
- `feedback_fix_everything_aggressively.md`
- `pearl_tests_must_prove_not_lock_observations.md`
- `pearl_no_deferrals_for_complementary_fixes.md`
- `feedback_trust_code_not_docs.md`

## When to invoke

- Edits to `crates/**/*.rs`, `services/**/*.rs`, `bin/**/*.rs`, `testing/**`.
- Explicit request: "audit code hygiene for <path>".

## Invariants to verify

1. **No stubs** (`feedback_no_stubs.md`). Return-zero stubs, dead params, unused fields. Wire it for real or delete.
2. **No TODO/FIXME/XXX** (`feedback_no_todo_fixme.md`). Complete or rewrite; never leave the marker.
3. **No `_var` hiding or `#[allow]` suppression** (`feedback_no_hiding.md`). Wire up or delete.
4. **No legacy aliases** (`feedback_no_legacy_aliases.md`). No `*_legacy`, `*_v1`, deprecated wrappers; rename call sites directly.
5. **No `enable_*`/`use_*` feature flags** (`feedback_no_feature_flags.md`). All features unconditional.
6. **No partial refactors** (`feedback_no_partial_refactor.md`). When a contract changes, every consumer migrates atomically.
7. **No quick-fixes** (`feedback_no_quickfixes.md`). Every issue gets a proper fix per established patterns.
8. **No functionality removal** (`feedback_no_functionality_removal.md`, `feedback_magnitude_must_be_useful.md`). Never delete features/branches; fix what's broken.
9. **Wire everything up** (`feedback_wire_everything_up.md`). New kernels/modules must be wired in the same commit; no orphans.
10. **V7-gem methodology for unused code** (`feedback_v7_gem_methodology.md`). Unused code → measure before delete or wire (3-step).
11. **Tests assert invariants, not observed values** (`pearl_tests_must_prove_not_lock_observations.md`). Boundedness, monotonicity, fixed-points — not "this returned 0.42 last run".
12. **No deferrals of complementary fixes** (`pearl_no_deferrals_for_complementary_fixes.md`). When two fixes attack distinct mechanisms with non-overlapping refactor scopes, combine into one plan.
13. **Trust code, not docs** (`feedback_trust_code_not_docs.md`). When memory and code disagree, code wins.

## Output format

```
[code-hygiene-auditor] reviewed: <paths>

Findings: N
1. [SEVERITY] <invariant short name> — <path>:<line>
   What: <one sentence>
   Memory: <feedback_*.md or pearl_*.md basename>
   Fix: <one sentence>

Hygiene rules considered, no violation: <comma-separated short names>
```

## What this agent does NOT do

- Does NOT review for ISV/GPU/reward-specific patterns (delegate).
- Does NOT write into `memory/`.
- Does NOT block; warn-only.
````

- [ ] **Step 2: Verify dispatch**

```
Use the code-hygiene-auditor agent on a recent commit's diff (e.g., HEAD~5..HEAD on the sp15 branch). Confirm it produces output in the prescribed format and cites memory files by name.
```

Expected: prefixed output, citations.

- [ ] **Step 3: Commit**

```bash
git add .claude/agents/foxhunt/code-hygiene-auditor.md
git commit -m "$(cat <<'EOF'
feat(claude): code-hygiene-auditor agent (foxhunt)

Pattern-cluster auditor for general code-quality rules: no stubs, no TODO,
no hiding, no legacy aliases, no feature flags, no partial refactors,
v7-gem methodology, invariant tests not observed-value tests, no deferrals
of complementary fixes. Bundles 12 feedback rules and 3 pearls.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 6: `sp-spec-writer` skill

**Files:**
- Create: `.claude/skills/foxhunt/sp-spec-writer/SKILL.md`

- [ ] **Step 1: Write the skill file**

Create `.claude/skills/foxhunt/sp-spec-writer/SKILL.md` with this exact content:

````markdown
---
name: sp-spec-writer
description: Produces a foxhunt SP design spec at docs/superpowers/specs/YYYY-MM-DD-spXX-<topic>-design.md following the established format — Problem, Pearl/feedback grounding, Approach, Phases A/B/C, ISV slots required, Smoke gate, Anti-patterns avoided, Pearl-distill hook. Use when starting a new sprint plan or revising one.
---

# Foxhunt SP Spec Writer

Templatizes the SP design spec format. Reuses the canonical structure from prior specs in `docs/superpowers/specs/`.

## When to invoke

- "Write SP spec for <topic>".
- "Start SP-N spec".

## Inputs you must collect first

Ask the user (one at a time):

1. **SP number**. Look at `docs/superpowers/specs/` and propose the next free integer.
2. **Topic** (short slug, kebab-case).
3. **Problem statement** — one paragraph. Symptoms or metrics required.
4. **Pearl/feedback grounding** — which memory files motivate this work? At least one required (per `feedback_isv_for_adaptive_bounds.md` etc.).
5. **Sister-fix check** (`pearl_no_deferrals_for_complementary_fixes.md`). Ask: "Is there a complementary fix that should ride along in this spec?" If yes, integrate; if no, document why.

## Spec template

Render a new file at `docs/superpowers/specs/YYYY-MM-DD-spN-<topic>-design.md` with:

```markdown
# SP-N: <Topic>

| | |
|---|---|
| **Date** | <today YYYY-MM-DD> |
| **Author** | <user> |
| **SP** | N |
| **Branch** | sp<N>-<topic> |

## 1. Problem

<One paragraph; symptoms, metrics, or repro.>

## 2. Pearl/feedback grounding

- `<memory_file_1.md>` — <one sentence>
- `<memory_file_2.md>` — <one sentence>

## 3. Approach

<Root-cause framing. Why this fix, not another.>

## 4. Phases

### Phase A — <name>
- A.1 <step>
- A.2 <step>
…

### Phase B — <name>
- B.1 <step>
…

### Phase C (smoke + close-out)
- C.1 Smoke launch (`scripts/argo-train.sh ...`)
- C.2 Smoke gate: <kill conditions>
- C.3 Close-out doc + pearl distillation

## 5. ISV slots required

| Slot index | Name | Purpose | Source pearl |
|---|---|---|---|
| <S> | <NAME> | <purpose> | <pearl> |

`ISV_TOTAL_DIM` bump: OLD → NEW.

## 6. Smoke gate

| Anomaly | Detection | Action |
|---|---|---|
| <e.g., NaN loss> | <log signal> | kill within <K> steps |

## 7. Anti-patterns avoided

- <which feedback rules this spec is honoring; e.g., feedback_no_stubs.md, feedback_isv_for_adaptive_bounds.md>

## 8. Pearl-distill hook

After close-out, distill a pearl for: <expected pattern>.
```

## Discipline enforced by this skill

- The spec MUST cite at least one memory file in §2.
- The spec MUST list ISV slots in §5 (or explicitly state "no new slots needed").
- The spec MUST list smoke kill conditions in §6 (or explicitly state "no smoke required").
- The spec MUST list which `feedback_*.md` rules it honors in §7.
- Sister-fix check is mandatory; the user must answer the question.

## After writing

Suggest invoking `foxhunt-sp-critical-reviewer` for the v2 critical-review pass before promoting the spec to plan.
````

- [ ] **Step 2: Verify (dry-run, no file written)**

```
Use the sp-spec-writer skill in dry-run mode for a fictitious SP-99 on topic "dummy-verification". Show the template-rendered file content as output; do NOT write the file.
```

Expected: skill output shows the complete spec content with all 8 sections present, in the canonical template shape — but the file does not appear under `docs/superpowers/specs/`. Confirm with `ls docs/superpowers/specs/ | grep sp99` returning nothing.

- [ ] **Step 3: Commit**

```bash
git add .claude/skills/foxhunt/sp-spec-writer/SKILL.md
git commit -m "$(cat <<'EOF'
feat(claude): sp-spec-writer skill (foxhunt)

Templatizes the SP design spec format used in docs/superpowers/specs/.
Enforces pearl/feedback grounding, ISV-slot enumeration, smoke kill conditions,
sister-fix check (no-deferrals-for-complementary-fixes pearl).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 7: `isv-slot-scaffolder` skill

**Files:**
- Create: `.claude/skills/foxhunt/isv-slot-scaffolder/SKILL.md`

- [ ] **Step 1: Write the skill file**

Create `.claude/skills/foxhunt/isv-slot-scaffolder/SKILL.md` with this exact content:

````markdown
---
name: isv-slot-scaffolder
description: Scaffolds new ISV slots — generates crates/.../spN_isv_slots.rs with named constants in [START..END), bumps ISV_TOTAL_DIM at canonical location, registers slots for fold-boundary reset, emits the canonical commit message shape. Use when adding ISV-driven adaptive bounds for a new SP.
---

# Foxhunt ISV Slot Scaffolder

Templatizes the ISV-slot scaffolding step that runs early in every SP that introduces adaptive bounds.

## When to invoke

- "Add ISV slots for SP-N".
- "Scaffold spN_isv_slots.rs".

## Reference: canonical example

The most recent example is commit `c146c4fff`:

```
feat(sp15): scaffold sp15_isv_slots.rs with 46 slots [397..443) — ISV_TOTAL_DIM 396→443
```

Reproduce that shape exactly. The plan must:

1. Discover the current `ISV_TOTAL_DIM` value (grep for `ISV_TOTAL_DIM` in `crates/`).
2. Discover the next free index (= current `ISV_TOTAL_DIM`).
3. Receive a list of `(SLOT_NAME, purpose)` from the user.
4. Compute the new range `[START..END)` and new `ISV_TOTAL_DIM`.

## Inputs you must collect first

1. SP number (N).
2. List of slot names + purposes. Names are `SCREAMING_SNAKE_CASE`.
3. Optional: explicit indices (else assigned sequentially from current `ISV_TOTAL_DIM`).

## What this skill produces

1. New file `crates/<crate>/src/isv/sp<N>_isv_slots.rs`:

```rust
//! SP-<N> ISV slots — [<START>..<END>)
//!
//! Adaptive bounds and signals for SP-<N>.
//! Source pearl: <link to spec §5>.

pub const ISV_<NAME_1>: usize = <S>;
pub const ISV_<NAME_2>: usize = <S>+1;
// ...

pub const SP<N>_SLOTS_START: usize = <S>;
pub const SP<N>_SLOTS_END: usize = <E>;
```

2. Edit at canonical `ISV_TOTAL_DIM` site:

```rust
pub const ISV_TOTAL_DIM: usize = <NEW>;  // bumped from <OLD> by SP-<N> (+<K> slots)
```

3. Edit at fold-boundary reset registration site to register `SP<N>_SLOTS_START..SP<N>_SLOTS_END`.

4. Suggested commit message (use heredoc):

```
feat(sp<N>): scaffold sp<N>_isv_slots.rs with <K> slots [<S>..<E>) — ISV_TOTAL_DIM <OLD>→<NEW>
```

## Discipline

- All slots must be referenced by at least one consumer in a follow-up commit (per `feedback_wire_everything_up.md`).
- Slot names must be domain-meaningful — no `SP15_X1`, `SP15_X2` placeholders.
- ISV_TOTAL_DIM bump must match the slot count exactly. Verify before committing.

## After scaffolding

Suggest invoking `foxhunt-isv-discipline-auditor` to verify the new slots aren't shadowing existing ones with semantically-similar purposes.
````

- [ ] **Step 2: Verify**

```
Use the isv-slot-scaffolder skill to plan (do not execute) scaffolding for one fictitious slot for SP-99. Verify the output: file path, ISV_TOTAL_DIM bump arithmetic, commit message shape.
```

Expected: skill produces a complete plan including current `ISV_TOTAL_DIM` (discovered via grep), proposed new value, new file content, registration edit, commit message in canonical shape. Do NOT actually create SP-99 files.

- [ ] **Step 3: Commit**

```bash
git add .claude/skills/foxhunt/isv-slot-scaffolder/SKILL.md
git commit -m "$(cat <<'EOF'
feat(claude): isv-slot-scaffolder skill (foxhunt)

Templatizes the ISV-slot scaffolding step. Reproduces the c146c4fff commit
shape: spN_isv_slots.rs with named constants, ISV_TOTAL_DIM bump at canonical
site, fold-boundary reset registration. Enforces wire-everything-up discipline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 8: `pearl-distiller` skill

**Files:**
- Create: `.claude/skills/foxhunt/pearl-distiller/SKILL.md`

- [ ] **Step 1: Write the skill file**

Create `.claude/skills/foxhunt/pearl-distiller/SKILL.md` with this exact content:

````markdown
---
name: pearl-distiller
description: Distills a memory pearl from a close-out finding. Creates ~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/pearl_<topic>.md with structured body and updates MEMORY.md index in the right section. One of only two skills that may write into memory/. Use post-close-out, never proactively.
---

# Foxhunt Pearl Distiller

Authoritative writer for new memory pearls. The other authorized writer is `memory-curator` (which can delete/archive). All other agents and skills are read-only on `memory/`.

## When to invoke

- After SP close-out, when a finding warrants distillation.
- Explicit request: "distill pearl from <topic>".

## Inputs you must collect first

1. **Topic** — short kebab-case identifier (becomes filename: `pearl_<topic>.md`).
2. **One-line description** — for `MEMORY.md` index entry.
3. **Pattern statement** — one paragraph: what was discovered.
4. **Detection signal** — how to recognize this pattern in code or behavior.
5. **Fix** — what to do when the pattern is detected.
6. **Canonical reference** — commit SHA + `path:line` where the pattern was first fixed.
7. **Related pearls** — links to existing pearls.
8. **Section in `MEMORY.md`** — pick from existing sections (Controllers and signals, Bootstrap and smoothing, Architectural constraints, Distributional Q / action selection, Optimization, GPU mechanics, Testing discipline, Spec/plan scoping, Close-out / sweep records, Active Project State).

## What this skill produces

1. **New file** at `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/pearl_<topic>.md`:

```markdown
---
name: <topic readable>
description: <one-line; same as MEMORY.md hook>
type: pearl
---

# Pearl: <Topic Readable>

## Pattern

<One paragraph: what was discovered.>

## Detection signal

<How to recognize this in code or runtime behavior.>

## Fix

<What to do when detected.>

## Canonical reference

- Commit: `<SHA>`
- File: `<path>:<line>`
- Spec: `<docs/superpowers/specs/...>`

## Related pearls

- `<related_pearl_1.md>` — <one-sentence relation>
- `<related_pearl_2.md>` — <one-sentence relation>
```

2. **Edit `MEMORY.md`** to add the index line under the right section:

```markdown
- [pearl_<topic>.md](pearl_<topic>.md) — <one-line hook>
```

The line must be ≤150 characters (per the auto-memory rules in the system prompt).

## Discipline

- Only invoke after a close-out doc exists. Do not distill speculative pearls.
- Reuse existing sections in `MEMORY.md`; do not invent a new section without explicit user approval.
- If a similar pearl already exists, ask the user whether to merge instead of creating a new one (delegate to `memory-curator` for merges).
- The pearl content must be specific enough that an auditor agent can cite it by name in a finding.

## After distilling

If the pearl supersedes a prior pearl, mark the old one DEPRECATED in its frontmatter and add a "Superseded by: <new pearl>" note. Do not delete the old pearl — `memory-curator` handles archival.
````

- [ ] **Step 2: Verify**

```
Use the pearl-distiller skill to draft (do not write) a hypothetical new pearl based on the docs/superpowers/specs/2026-05-06-trader-discipline-and-recovery-design.md spec. Confirm the output structure matches the template and the MEMORY.md index line is ≤150 characters.
```

Expected: full pearl file content + index line, both shown in skill output but not actually written.

- [ ] **Step 3: Commit**

```bash
git add .claude/skills/foxhunt/pearl-distiller/SKILL.md
git commit -m "$(cat <<'EOF'
feat(claude): pearl-distiller skill (foxhunt)

One of two authorized writers into memory/ (the other is memory-curator).
Templatizes new-pearl creation: structured body (pattern / detection signal /
fix / canonical commit:file:line / related pearls) + MEMORY.md index entry
in the right section, ≤150 chars.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 9: `argo-deploy-helper` skill

**Files:**
- Create: `.claude/skills/foxhunt/argo-deploy-helper/SKILL.md`

- [ ] **Step 1: Write the skill file**

Create `.claude/skills/foxhunt/argo-deploy-helper/SKILL.md` with this exact content:

````markdown
---
name: argo-deploy-helper
description: Constructs and validates a vetted invocation of scripts/argo-train.sh or scripts/argo-compile-deploy.sh. Enforces push-before-deploy, default L40S pool (ci-training-l40s) unless overridden, mandatory --mbp10-data-dir + --trades-data-dir, --per-enabled, H100 max-utilization flags when H100 chosen. Use when deploying training to argo.
---

# Foxhunt Argo Deploy Helper

Wraps the existing `scripts/argo-train.sh` and `scripts/argo-compile-deploy.sh` with foxhunt deploy discipline pre-flight.

## When to invoke

- "Deploy training X to argo".
- "Run smoke for SP-N on the cluster".

## Pre-flight checklist (BLOCK on any fail)

Before constructing the invocation, run each check. If any fails, do not proceed — report the failure and stop.

1. **Push before deploy** (`feedback_push_before_deploy.md`).
   ```bash
   LOCAL=$(git rev-parse HEAD)
   REMOTE=$(git rev-parse @{u} 2>/dev/null || echo "")
   if [ "$LOCAL" != "$REMOTE" ]; then
     echo "BLOCKED: HEAD ($LOCAL) not pushed to upstream ($REMOTE). Run 'git push' first."
     exit 1
   fi
   ```

2. **MBP10 + trades data dirs mandatory for SP-chain training** (`feedback_mbp10_mandatory.md`).
   - Confirm `--mbp10-data-dir` and `--trades-data-dir` are present in the proposed flag list.
   - If absent, BLOCK and ask the user to provide them.

3. **PER enabled** (`feedback_always_per.md`).
   - Confirm `--per-enabled` is present (or that the script defaults it to true). PER is always on.

## Default GPU pool (`feedback_default_to_l40s_pool.md`)

Default to `--gpu-pool ci-training-l40s`. Add only if the user did not specify a pool. If the user specifies H100, also enforce H100 max-utilization flags (`feedback_h100_gpu.md`):

- Hard error on under-utilization (script-side flags or env vars per the existing argo-train.sh contract).
- Pass the canonical H100 batch-size + grad-accumulation flags.

## What this skill produces

A complete invocation, ready to run, in the form:

```bash
./scripts/argo-train.sh \
  --branch <branch> \
  --commit <sha> \
  --gpu-pool <pool> \
  --mbp10-data-dir <path> \
  --trades-data-dir <path> \
  --per-enabled \
  <other flags>
```

Plus a one-line summary of the pre-flight checks that passed.

## Anti-pattern this skill avoids

- Deploying with HEAD ahead of upstream (un-pushed commits aren't reproducible from the remote).
- H100 deploys without max-utilization flags (waste of expensive node).
- Defaulting to H100 when L40S would do (`feedback_default_to_l40s_pool.md` overrides the older H100-by-default rule).
- Layering Bash run_in_background Monitor on top of argo logs (`feedback_no_redundant_monitor.md`). Stream logs via `argo logs -f`, not via custom shell redirection.

## After deploy

Suggest invoking `foxhunt-smoke-pilot` to monitor the smoke and kill on first useful anomaly signal.
````

- [ ] **Step 2: Verify**

```
Use the argo-deploy-helper skill to plan (do not execute) a smoke deploy for the current branch. Verify the pre-flight checks fire correctly when HEAD is ahead of upstream (test by intentionally not pushing a no-op commit, then plan; should BLOCK).
```

Expected: skill BLOCKS with the exact "HEAD not pushed" message; produces no command. After pushing, skill produces a complete `./scripts/argo-train.sh ...` invocation defaulting to L40S.

- [ ] **Step 3: Commit**

```bash
git add .claude/skills/foxhunt/argo-deploy-helper/SKILL.md
git commit -m "$(cat <<'EOF'
feat(claude): argo-deploy-helper skill (foxhunt)

Wraps scripts/argo-train.sh with deploy discipline pre-flight: push-before-
deploy gate, mandatory --mbp10-data-dir/--trades-data-dir, --per-enabled,
default L40S unless overridden, H100 max-utilization when chosen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 10: `smoke-pilot` skill

**Files:**
- Create: `.claude/skills/foxhunt/smoke-pilot/SKILL.md`

- [ ] **Step 1: Write the skill file**

Create `.claude/skills/foxhunt/smoke-pilot/SKILL.md` with this exact content:

````markdown
---
name: smoke-pilot
description: Monitors a running argo workflow smoke; auto-kills on first useful anomaly signal (NaN loss, magnitude collapse, EVAL_DIST anomalies, return-explosion, controller saturation) per stop-on-anomaly + kill-quickly discipline. Pairs with argo-deploy-helper. Streams logs via argo logs -f, never via Bash run_in_background Monitor.
---

# Foxhunt Smoke Pilot

Watches an in-flight smoke training and applies the kill-fast-on-anomaly rule.

## When to invoke

- "Monitor smoke for workflow <wf-name>".
- After invoking `argo-deploy-helper`.

## Memory you MUST read first

In `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/`:

- `feedback_stop_on_anomaly.md`
- `feedback_kill_runs_on_anomaly_quickly.md`
- `feedback_no_redundant_monitor.md`
- `project_metric_pipeline_inflation_audit.md` (honest meters; what *isn't* an anomaly)
- All `project_*.md` files documenting prior anomalies (these are signal libraries).

## What this skill does

1. Streams workflow logs:
   ```bash
   argo logs -f <workflow-name>
   ```
   Do NOT layer Bash `run_in_background` Monitor on this stream (`feedback_no_redundant_monitor.md`).

2. Watches each log line for known anomaly patterns:

   | Anomaly | Signal | Kill window |
   |---|---|---|
   | NaN loss | `loss = NaN` or `loss = inf` | immediate |
   | Magnitude collapse | EVAL_DIST Quarter pinned at 1.0 with no Kelly cap context | within 200 steps |
   | Return explosion | `Return = 1e29%` or similar (per project_metric_pipeline_inflation_audit) | immediate |
   | Controller saturation | `α = 1.0` or `α = 0.0` for >100 steps | within 500 steps |
   | Aux CE plateau at ln(K) | `aux_ce ≈ <ln(K)>` for >100 steps | warn but don't kill (per pearl_separate_aux_trunk_when_shared_starves — fix is structural) |
   | Reward distribution corruption | one-sided clamp regression | within 100 steps |

3. On detected anomaly:
   ```bash
   argo terminate <workflow-name>
   ```
   Then summarize the anomaly with the originating memory file cited.

## Discipline

- **Always cite the originating memory file** when killing — "Killed at step 230: NaN loss, per `feedback_stop_on_anomaly.md`".
- **Never kill on a noisy single-step blip**. Use a 3-of-5 confirmation window for non-immediate anomalies.
- **Never silently survive** an anomaly that warrants a kill. The whole point of this skill is `feedback_kill_runs_on_anomaly_quickly.md`: kill at first useful signal, diagnose, fix, re-run.
- **Inflation is not anomaly**. Per `project_metric_pipeline_inflation_audit.md`, several metrics are display caps or annualization conventions, not bugs. Read that file first; do not flag those as anomalies.

## After kill

Suggest:
1. Save the failing log slice for analysis.
2. Open a fresh investigation (likely brainstorming → spec).
3. Re-run only after the fix is committed and pushed.
````

- [ ] **Step 2: Verify**

```
Use the smoke-pilot skill on a hypothetical workflow that emits "loss = NaN" at step 100. Verify it issues 'argo terminate <wf>' (or describes the action) and cites feedback_stop_on_anomaly.md by name.
```

Expected: kill action with citation; reference to project_metric_pipeline_inflation_audit.md for the inflation distinction.

- [ ] **Step 3: Commit**

```bash
git add .claude/skills/foxhunt/smoke-pilot/SKILL.md
git commit -m "$(cat <<'EOF'
feat(claude): smoke-pilot skill (foxhunt)

Monitors argo smoke training; kills on first useful anomaly signal per
stop-on-anomaly + kill-quickly discipline. Distinguishes anomaly from
metric-pipeline inflation. Streams via argo logs -f, no run_in_background
Monitor layering.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 11: `memory-curator` skill

**Files:**
- Create: `.claude/skills/foxhunt/memory-curator/SKILL.md`

- [ ] **Step 1: Write the skill file**

Create `.claude/skills/foxhunt/memory-curator/SKILL.md` with this exact content:

````markdown
---
name: memory-curator
description: Audits MEMORY.md and the memory/ directory against current code. Flags stale references (file/symbol/flag no longer present), duplicates, fully-superseded pearls, project-state files where the project is now merged. Proposes deletes and merges; never auto-deletes. Use monthly or when pearls feel out of date.
---

# Foxhunt Memory Curator

Read-and-propose audit of the memory/ corpus. One of two authorized writers into memory/ (the other is `pearl-distiller`); this one only deletes/archives, with explicit user confirmation.

## When to invoke

- "Audit memory" (explicit).
- SessionStart hint when `memory/MEMORY.md` `mtime` > 30 days (advisory only — never auto-runs).

## What this skill does

1. **Enumerate** all memory files:
   ```bash
   ls ~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/*.md
   ```

2. **For each file**, run staleness checks:

   | Check | How |
   |---|---|
   | File reference still exists | Path mentioned in the pearl → does it still exist in the repo? |
   | Symbol reference still exists | Function/struct name mentioned → grep the repo |
   | Commit SHA still in history | `git cat-file -e <sha>` |
   | Flag/feature still wired | grep for the flag name |
   | Project status fresh | For `project_*.md`, is the project-of-interest still the current focus? |

3. **Group findings**:
   - **Stale** — referenced thing is gone; pearl needs an update or archival.
   - **Duplicate** — two pearls cover the same pattern; propose merge.
   - **Superseded** — a newer pearl replaces this one (frontmatter says DEPRECATED or another pearl says "supersedes <this>").
   - **Orphan** — pearl in `memory/` but missing from `MEMORY.md` index.
   - **Index-orphan** — line in `MEMORY.md` index referencing a missing file.

4. **Produce a curation report**:

   ```
   [memory-curator] audited <N> files in memory/

   Stale: <list with reasons>
   Duplicates: <list with proposed merges>
   Superseded: <list with replacement pearl>
   Orphans: <list>
   Index-orphans: <list>

   Proposed actions:
   1. <ARCHIVE | MERGE | UPDATE | INDEX-ADD | INDEX-REMOVE> <file> — <rationale>
   2. ...
   ```

## Discipline

- **Never auto-delete or auto-archive.** The user confirms each action one at a time.
- **Archive ≠ delete.** Archived pearls move to `memory/archive/` with a frontmatter note `archived: <YYYY-MM-DD>` and `archived_reason: <reason>`. They remain searchable.
- **Index integrity.** After any add/remove, verify `MEMORY.md` index lines stay ≤150 characters and live under the right section.
- **No new section without user approval.** Existing `MEMORY.md` sections (per the spec §3.3) are canonical.

## After curation

If any deprecated pearls were superseded by newer ones, the newer pearl frontmatter should explicitly say `supersedes: pearl_<old>.md`. Suggest invoking `pearl-distiller` if a new pearl is needed to replace an archived one.
````

- [ ] **Step 2: Verify**

```
Use the memory-curator skill in dry-run mode on the foxhunt memory directory. Confirm it produces the prescribed report format and identifies at least the known case: pearl_reward_shape_drives_quality_over_quantity.md is marked DEPRECATED.
```

Expected: report includes the DEPRECATED entry under "Superseded"; lists the replacing pearl `pearl_audit_unboundedness_for_implicit_asymmetry.md`. No actions taken without confirmation.

- [ ] **Step 3: Commit**

```bash
git add .claude/skills/foxhunt/memory-curator/SKILL.md
git commit -m "$(cat <<'EOF'
feat(claude): memory-curator skill (foxhunt)

Audits memory/ corpus: stale references (gone files/symbols/flags/commits),
duplicates, superseded pearls, orphans (file vs MEMORY.md index drift).
Proposes archive/merge/update; never auto-deletes. Archive ≠ delete.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 12: `stale-worktree-cleaner` skill

**Files:**
- Create: `.claude/skills/foxhunt/stale-worktree-cleaner/SKILL.md`

- [ ] **Step 1: Write the skill file**

Create `.claude/skills/foxhunt/stale-worktree-cleaner/SKILL.md` with this exact content:

````markdown
---
name: stale-worktree-cleaner
description: Identifies stale git worktrees in .claude/worktrees/ and the workspace, including [gone] tracking refs and merged branches. Produces a per-worktree cleanup plan; user confirms each git worktree remove individually before any destructive operation.
---

# Foxhunt Stale Worktree Cleaner

Destructive op — explicit invoke only, with per-action user confirmation.

## When to invoke

- "Clean stale worktrees".
- Periodically when `.claude/worktrees/` has many entries.

## What this skill does

1. **Enumerate** all worktrees:
   ```bash
   git worktree list
   ls -la .claude/worktrees/
   ```

2. **For each worktree**, classify staleness:

   | Class | Detection |
   |---|---|
   | NO-COMMITS | No commits in N days (default 30); branch unchanged |
   | GONE | Tracking ref `[gone]` (deleted upstream) — `git fetch -p` then `git branch -vv` |
   | MERGED | Branch fully merged into `main` (`git merge-base --is-ancestor`) |
   | UNCOMMITTED | Has uncommitted changes — DO NOT propose cleanup; flag only |
   | ACTIVE | Recent commits, not merged, tracking ref alive |

3. **Produce a per-worktree cleanup plan**:

   ```
   [stale-worktree-cleaner] enumerated <N> worktrees

   Class NO-COMMITS (<K> entries):
   1. <path> — branch <name>, last commit <date>, status <merged|alive>
      Action: git worktree remove <path>; git branch -d <name>

   Class GONE (<K> entries):
   ...

   Class UNCOMMITTED (<K> entries — flag only, no action proposed):
   ...
   ```

4. **Confirm each action individually** before running. Never bulk-execute.

## Discipline

- **NEVER `git worktree remove --force` without confirmation.** `--force` discards uncommitted work.
- **NEVER `git branch -D`** (force delete) — only `git branch -d` (allows refusal on unmerged).
- **Compose the existing `commit-commands:clean_gone` skill** when applicable (it handles GONE-class branches).
- **NetBird/Tailscale/CI worktrees** (if any) — leave alone unless explicitly named by the user.
- **Worktrees referenced by a running agent** must not be removed. Check `.claude/worktrees/*` against any active session metadata.

## Output format

```
[stale-worktree-cleaner] proposal:

Will remove (after your per-item confirmation):
- <path 1> [<class>] — <why>
- <path 2> [<class>] — <why>

Skipped (require manual review):
- <path 3> [UNCOMMITTED] — has unstaged changes
```

User confirms each removal individually before any destructive command runs.
````

- [ ] **Step 2: Verify**

```
Use the stale-worktree-cleaner skill in dry-run mode on the current foxhunt repo. Expect at least one entry in .claude/worktrees/ to be classified; verify no destructive command is run without confirmation.
```

Expected: classification table; no `git worktree remove` actually executed.

- [ ] **Step 3: Commit**

```bash
git add .claude/skills/foxhunt/stale-worktree-cleaner/SKILL.md
git commit -m "$(cat <<'EOF'
feat(claude): stale-worktree-cleaner skill (foxhunt)

Classifies worktrees (NO-COMMITS / GONE / MERGED / UNCOMMITTED / ACTIVE) and
proposes cleanup. User confirms each removal individually; never --force,
never -D. Composes commit-commands:clean_gone where applicable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 13: `sp-critical-reviewer` agent

This agent composes the four auditor agents from Tasks 2-5, so it is built last.

**Files:**
- Create: `.claude/agents/foxhunt/sp-critical-reviewer.md`

- [ ] **Step 1: Write the agent file**

Create `.claude/agents/foxhunt/sp-critical-reviewer.md` with this exact content:

````markdown
---
name: sp-critical-reviewer
description: Performs the second/third critical-review pass on a freshly written SP spec or plan. Cites every claim against a memory file by name; enforces no-deferrals-for-complementary-fixes; verifies smoke kill conditions, ISV-slot enumeration, and anti-pattern callouts. Composes the four foxhunt auditor agents (gpu-contract, isv-discipline, reward-controller, code-hygiene) for domain-specific verification.
---

# Foxhunt SP Critical Reviewer

Replicates the user's "fix N issues from second/third critical review" iteration cycle (visible in commits like `eb5e19d67`, `35935ae44`, `5417e2756`).

## When to invoke

- After `sp-spec-writer` produces a v1, before promoting to plan.
- After plan v1, before starting implementation.
- Edits to `docs/superpowers/specs/*-design.md` or `docs/plans/*.md`.

## Memory you MUST read first

In `~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/`:

- `pearl_no_deferrals_for_complementary_fixes.md`
- `feedback_no_quickfixes.md`
- `feedback_no_partial_refactor.md`
- `feedback_isv_for_adaptive_bounds.md`
- `feedback_wire_everything_up.md`
- `feedback_kill_runs_on_anomaly_quickly.md`
- `feedback_stop_on_anomaly.md`
- All `pearl_audit_*.md` files (audit methodology).

## Composition

This agent dispatches the four domain auditors when the spec/plan claims involve those domains:

| Spec/plan claim | Dispatch |
|---|---|
| Mentions a CUDA kernel or GPU host code | `gpu-contract-auditor` on the implicated kernel |
| Mentions ISV slots or adaptive bounds | `isv-discipline-auditor` on the proposed approach |
| Mentions reward composition or controller mechanics | `reward-controller-auditor` |
| Anywhere else in `crates/`/`services/` | `code-hygiene-auditor` |

Findings from sub-auditors are aggregated under the corresponding spec/plan section.

## Critical-review checklist

For every spec/plan, verify:

1. **Pearl/feedback grounding present** (§2 of the spec template). Every motivation cites a memory file.
2. **Sister-fix question answered** (`pearl_no_deferrals_for_complementary_fixes.md`). The spec explicitly says "yes, sister-fix X integrated" or "no, here's why no sister-fix exists".
3. **ISV slots enumerated** (§5 of the spec template). Either a non-empty table, or an explicit "no new slots needed" with rationale.
4. **Smoke kill conditions explicit** (§6). Each anomaly has a detection signal and a kill window.
5. **Anti-patterns avoided enumerated** (§7). The relevant `feedback_*.md` rules are listed.
6. **Pearl-distill hook stated** (§8). The expected close-out pearl is named.
7. **Phase wire-up complete** (`feedback_wire_everything_up.md`). Every kernel/module introduced has a wire-up phase.
8. **Quickfixes flagged** (`feedback_no_quickfixes.md`). No "we'll just clamp this" without root-cause framing.
9. **Partial refactor flagged** (`feedback_no_partial_refactor.md`). When a contract changes, every consumer is in the plan.

## Output format

```
[sp-critical-reviewer] reviewed: <path-to-spec-or-plan>

Issues found: N (numbered, severity-tagged)

1. [SEVERITY] <category> — §<section>
   Issue: <one sentence>
   Memory: <feedback_*.md or pearl_*.md basename>
   Fix: <one-sentence corrective action; e.g., "add §5 with empty-set rationale">

2. ...

Sub-auditor findings (aggregated):
- gpu-contract-auditor: <count> findings — see appended report
- isv-discipline-auditor: <count> findings — see appended report
- reward-controller-auditor: <count> findings — see appended report
- code-hygiene-auditor: <count> findings — see appended report
```

Severities: BLOCKER (rewrite spec), HIGH (fix before plan), LOW (fix-up worthy). Match the user's `eb5e19d67` "16 issues" iteration shape.

## What this agent does NOT do

- Does NOT auto-edit the spec/plan; only reports.
- Does NOT write into `memory/`.
- Does NOT block; produces an issue list for the user to act on.
````

- [ ] **Step 2: Verify (composes four auditors)**

```
Use the sp-critical-reviewer agent on docs/superpowers/specs/2026-05-10-foxhunt-specialized-agents-design.md. Confirm:
1. It dispatches the relevant sub-auditors (likely none: this spec is about claude-tooling, not foxhunt code).
2. It produces issues numbered with severity tags.
3. It cites memory files by name.
```

Expected: an issues list, possibly empty if the spec is well-formed.

- [ ] **Step 3: Commit**

```bash
git add .claude/agents/foxhunt/sp-critical-reviewer.md
git commit -m "$(cat <<'EOF'
feat(claude): sp-critical-reviewer agent (foxhunt)

Replicates the user's second/third critical-review iteration cycle. Cites
every claim against a memory file. Enforces no-deferrals-for-complementary-
fixes, ISV-slot enumeration, smoke kill conditions, anti-pattern callouts.
Composes the four foxhunt auditor agents for domain-specific verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 14: End-to-end acceptance check

**Files:** none (verification only)

This task verifies all acceptance criteria from the spec §6.

- [ ] **Step 1: Hook router latency check**

```bash
for i in 1 2 3 4 5; do
  echo "{\"tool_input\":{\"file_path\":\"/home/jgrusewski/Work/foxhunt/crates/ml-dqn/src/cuda/test_$i.cu\"}}" \
    | /usr/bin/time -f "%e seconds" bash .claude/helpers/foxhunt-audit-router.sh 2>&1
done
```

Expected: every invocation under 0.2 seconds (200 ms).

- [ ] **Step 2: All five agents dispatch successfully**

Test each:

```
1. Use the gpu-contract-auditor agent to do a sanity check on crates/ml-dqn/src/cuda/experience_kernels.cu lines 2780-2820.
2. Use the isv-discipline-auditor agent on the SP15 plan v2 (docs/plans/...).
3. Use the reward-controller-auditor agent on the same kernel region as #1.
4. Use the code-hygiene-auditor agent on a recent ml-dqn change (HEAD~3..HEAD).
5. Use the sp-critical-reviewer agent on docs/superpowers/specs/2026-05-10-foxhunt-specialized-agents-design.md.
```

Expected for each: prefixed output (e.g., `[gpu-contract-auditor] reviewed:`); at least one citation to a memory file by name; exit without error.

- [ ] **Step 3: All seven skills invoke successfully**

Test each in dry-run mode (do not actually create or modify files):

```
1. Skill foxhunt-sp-spec-writer: scaffold a fictitious SP-99 (don't write).
2. Skill foxhunt-isv-slot-scaffolder: plan slots for SP-99 (don't write).
3. Skill foxhunt-pearl-distiller: draft a hypothetical pearl (don't write).
4. Skill foxhunt-argo-deploy-helper: plan a deploy (do pre-flight, do not run).
5. Skill foxhunt-smoke-pilot: classify a synthetic anomaly log line ("loss = NaN at step 100").
6. Skill foxhunt-memory-curator: produce a dry-run audit report.
7. Skill foxhunt-stale-worktree-cleaner: produce a dry-run worktree classification.
```

Expected for each: structured output matching the skill's prescribed format; no destructive operations executed.

- [ ] **Step 4: Memory-write invariant**

Verify that no agent has written into `memory/` during testing:

```bash
find ~/.claude/projects/-home-jgrusewski-Work-foxhunt/memory -mtime -1 -type f
```

Expected: empty output (no files modified in the last day) — unless `pearl-distiller` or `memory-curator` were explicitly invoked with intent to write.

- [ ] **Step 5: Settings.json additive merge preserved**

```bash
jq '.hooks.SessionStart | length' .claude/settings.json
jq '.hooks.SessionEnd | length' .claude/settings.json
jq '.hooks.PostToolUse | length' .claude/settings.json
jq '.permissions.deny' .claude/settings.json
```

Expected: SessionStart length ≥ 2 (existing + new), SessionEnd length ≥ 1 (existing preserved), PostToolUse length = 1 (new), permissions.deny preserved.

- [ ] **Step 6: Hint format spot-check**

Pick a real edit you make in this session (e.g., touch a `.cu` file, save). Confirm the resulting hook hint matches:

```
[foxhunt-audit] <relative path> — suggest: <agent-list>
```

- [ ] **Step 7: No regressions in pre-commit hooks**

```bash
git status
# Make a no-op change to any tracked file
echo "" >> some_existing_file.txt   # trivial example
git add some_existing_file.txt
git diff --cached
git commit -m "test: pre-commit smoke" --dry-run
```

Expected: existing `.claude/helpers/pre-commit` runs cleanly; no new failures attributable to this plan's changes. Then `git checkout -- some_existing_file.txt` to discard.

- [ ] **Step 8: Final commit (acceptance summary)**

If everything passed, no commit is needed (this task is verification only). If any check failed, fix in-place and commit per the failing task's pattern. If a substantive change to any agent/skill is needed, the relevant Task's commit message convention applies.

Optionally, write a short close-out note to `docs/superpowers/results/2026-05-10-foxhunt-specialized-agents-rollout.md` summarizing what works and what required adjustment, then commit:

```bash
git add docs/superpowers/results/2026-05-10-foxhunt-specialized-agents-rollout.md
git commit -m "$(cat <<'EOF'
docs(claude): foxhunt agents & skills rollout — close-out

Phase 1 implementation complete: 5 auditor agents + 5 workflow skills + 2
maintenance skills + warn-only PostToolUse hook router. All acceptance
criteria from the design doc verified.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Implementation summary

| Task | Type | File(s) | Commit scope |
|---|---|---|---|
| 1 | Foundation | hook router + settings + gitignore | `chore(claude)` |
| 2 | Agent | `gpu-contract-auditor.md` | `feat(claude)` |
| 3 | Agent | `isv-discipline-auditor.md` | `feat(claude)` |
| 4 | Agent | `reward-controller-auditor.md` | `feat(claude)` |
| 5 | Agent | `code-hygiene-auditor.md` | `feat(claude)` |
| 6 | Skill | `sp-spec-writer/SKILL.md` | `feat(claude)` |
| 7 | Skill | `isv-slot-scaffolder/SKILL.md` | `feat(claude)` |
| 8 | Skill | `pearl-distiller/SKILL.md` | `feat(claude)` |
| 9 | Skill | `argo-deploy-helper/SKILL.md` | `feat(claude)` |
| 10 | Skill | `smoke-pilot/SKILL.md` | `feat(claude)` |
| 11 | Skill | `memory-curator/SKILL.md` | `feat(claude)` |
| 12 | Skill | `stale-worktree-cleaner/SKILL.md` | `feat(claude)` |
| 13 | Agent | `sp-critical-reviewer.md` | `feat(claude)` |
| 14 | Verification | none | `docs(claude)` (optional close-out) |

Tasks 2–5 can be done in parallel (independent files, independent agents). Tasks 6–8 likewise. Tasks 9–10 likewise. Tasks 11–12 likewise. Task 13 must come after Tasks 2–5 (composition). Task 14 must come last.

## Dependencies

- No new package dependencies (Bash + markdown only).
- No changes to Cargo.toml, package.json, or any build configuration.
- Adds two helper scripts under `.claude/helpers/` (the directory already exists with similar scripts).
- Adds one PostToolUse hook entry in `.claude/settings.json` (additive).
- Adds one SessionStart hook entry in `.claude/settings.json` (additive — clears state file).

## Out of scope (Phase 2)

Per the design doc §7, these are deferred:

- `crate-graph-auditor` (workspace-level orphan detection).
- Splitting `reward-controller-auditor` into `reward-shape-auditor` + `controller-design-auditor` (only if the file grows past ~400 lines).
- `web-dashboard-debugger` (explicitly removed from the backlog).
