# Apply procedures by proposal type Read this file before any apply in SKILL.md §3a (auto-apply) or §4 (walk the queue). Every check here is mandatory. Section numbers (§N) refer to SKILL.md. ## Contents - Karpathy constraints (every apply) - §3a auto-apply, per type - §3a after each auto-apply: move, A/B tracking, archive - §4 approve, per type - §4 reject and edit ## Karpathy constraints (you must enforce on each apply) Before writing any proposal: - Confirm `# Assumptions` section is non-empty. - Confirm `# Diagnosis` section exists and contains all four labelled lines (`Trigger:`, `Action:`, `Mismatch:`, `Outcome:`) AND at least one backtick-wrapped quote ≤80 chars in the Outcome line. Refuse if missing or malformed — agent must redraft per the "Diagnosis drafting protocol" in `agents/adam.md`. - Confirm `# Success criterion` section is non-empty and runnable. - Confirm change is ≤50 LOC for non-`skill_new`, or ≤80 LOC for `skill_new` body. If larger, ask the user once: "this proposal is N LOC — proceed?" - For `claude_md_edit`: confirm 3+ distinct cwds in the `# Why` section. - For `deletion`: confirm both criteria (a) and (b) from the agent's special handling are documented in the proposal. - For `skill_new`: confirm the slug doesn't collide with any existing skill in `~/.claude/skills/`. If it does, refuse and ask user to rename. - For `skill_edit`: confirm the diff is append-only (no `-` lines that remove existing content) and that target SKILL.md exists. When auto-applying, ALSO re-verify the eligibility gate steps in §3 (cooldown, blacklist, byte cap) before any `Edit` call — never trust frontmatter alone. - For `skill_edit` with `auto_apply_eligible: true`: confirm `contradiction_flag` is absent or null in frontmatter. Refuse auto-apply if `contradiction_flag` is set with any non-empty value (treat the agent's flag as a hard veto on auto-apply; user can still manually approve in walk-the-queue if they disagree with the heuristic). - For `memory`: confirm `# Proposed change` body starts with `---` frontmatter matching the live auto-memory schema — top-level `name` (the slug) + `description`, plus a `metadata:` block with `node_type: memory`, `type`, and `originSessionId`. Cross-check the shape against an existing file in the target memory dir. Refuse if frontmatter is flat (`type:`/`originSessionId:` at top level) or missing the `metadata:` block — agent must redraft per the Memory drafting protocol. - For `harness_edit`: confirm `auto_apply_eligible: false` (never auto-apply). Confirm `confidence ≥ 5`. Confirm `# Test verification` section names the test command. Confirm diff is ≤30 LOC and targets a single allowed harness file (see `agents/adam.md` §"Harness self-modification"). Run test suite before AND after applying — revert on any regression. - Confirm `source_entries` is present in proposal frontmatter as a non-empty list (used for archive). Warn (do not refuse) if missing — legacy proposals from before v0.2.0 won't have it. If any check fails, refuse to apply and ask the user how to proceed. ## §3a auto-apply, per type For each id that passed §3 verification, print `id`, `target`, `confidence`, `blast_radius`, `cross_session_evidence`, `auto_apply_eligible`. Then apply: - **`skill_new`**: `mkdir -p ~/.claude/skills//`, then `Write` the proposal's `# Proposed change` body to `~/.claude/skills//SKILL.md`. After write, print: "skill `` written to `~/.claude/skills//SKILL.md` — activates immediately — Claude Code v2.1.0+ auto-hot-reloads user-level skills, no restart needed." - **`memory`**: `Write` the proposal's `# Proposed change` body (which MUST include the auto-memory frontmatter — see "Memory drafting protocol" in `agents/adam.md`) to the path in `target`. Then update `MEMORY.md` index with a one-line pointer. - **`nudge`**: low-blast auto-apply path. Single-session evidence is sufficient — skip the cross-session gate. Apply by invoking the helper (do NOT hand-write the JSON — the helper builds the message and the `cue` deterministically from frontmatter): ```bash node ~/.claude/adam/scripts/adam-apply-nudge.mjs ~/.claude/adam/proposals/-*.md --home ~/.claude ``` The proposal frontmatter MUST carry `type: nudge`, `source_session`, and `cwd` (the cluster's dominant `cwd`, from `adam-batch.mjs`'s per-batch `cwds`), plus `dead_end_count`. The helper appends one entry to `~/.claude/adam/active-nudges.json` (creating it if absent) with `cue: {cwd}` populated — so the reminder is query-conditioned: it surfaces at SessionStart *and* mid-session (via `adam-observe.mjs`) only when the user is working in that codebase. Output: `{"status":"applied"|"gated", ...}` — on `gated` leave the proposal in `proposals/`, on `applied` continue to archive. Do NOT modify any skill, memory, agent, or CLAUDE.md. Tell user: "nudge queued — surfaces when you return to `` (expires in 7 days)." - **`reinforcement`**: gated by `confidence >= 4 AND blast_radius == low` (same as memory). Apply by invoking the helper: ```bash node ~/.claude/adam/scripts/adam-apply-reinforcement.mjs ~/.claude/adam/proposals/-*.md --home ~/.claude ``` The helper reads the proposal frontmatter (`skill_slug`, `count`, `source_session`) and appends one JSON line to `~/.claude/adam/reinforcements.jsonl`. No code/memory/skill modifications. Output: `{"status":"applied"|"gated", ...}`. On `gated`, leave the proposal in `proposals/` (the helper failed its own re-check). On `applied`, continue to the archive step. Tell user: "reinforcement logged for `` (count=) — appended to reinforcements.jsonl." - **`skill_edit`**: enforce the apply-time gate before writing. 1. Verify proposal frontmatter has `auto_apply_eligible: true`. If not, abort and queue for review. 2. Read `target` SKILL.md, capture `current_bytes` from a fresh stat — do NOT trust frontmatter `bytes_before`. 3. Verify diff in `# Proposed change`: unified-diff format, zero `-` lines on existing SKILL.md content (additions only), total `+` lines ≤ 30. If any check fails, print one-line refusal reason, leave proposal in `proposals/`, continue. 4. Cooldown re-check: run `node ~/.claude/adam/scripts/adam-cooldown.mjs --skill --fingerprint ` (both fields come from proposal frontmatter; missing fingerprint → "legacy"). Refuse if the script returns `status: cooldown` OR `status: blacklisted`. This per-(skill, fingerprint) gate replaces the previous coarse per-skill scan — proposals for the same skill with a different fingerprint are NOT blocked by an older entry. `adam-cooldown.mjs` returns `blacklisted` when `auto_apply_blacklist: true` is found in `rejected/` within 30 days for the same (skill, fingerprint). 5. Apply via `Edit` tool (append the new section per the diff). Never use `Write` on existing SKILL.md. 6. Re-stat target. If new size exceeds `2 * current_bytes` (captured in step 2), revert via `Edit` (remove the just-appended section) and refuse — print refusal reason. 7. Add `last_auto_edit: ` to the proposal frontmatter before moving it. 8. Tell user: "skill `` extended (added lines) — auto-applied via win-evidence gate." ## §3a after each auto-apply: move, A/B tracking, archive 1. Move proposal to `~/.claude/adam/applied/-.md`. 2. **A/B tracking append** (skip for `reinforcement` — positive-only ledger, intentionally not A/B-tracked per `agents/adam.md` §"`reinforcement` proposals"): as a separate atomic step right after the move, append one JSON line to `~/.claude/adam/ab-tracking.jsonl` (create with empty contents if absent). Read fields from the proposal's frontmatter (`proposal_fingerprint`, `originating_signals` — both populated per `agents/adam.md`; `originating_signals` is a list of `{type, count, session_ids}` objects). Schema: ```json { "applied_at": , "proposal_id": "", "proposal_type": "skill_edit|skill_new|memory|nudge", "target_skill": "", "proposal_fingerprint": "", "originating_signals": [{"type":"","count":,"session_ids":[...]}], "pre_window_days": 7 } ``` `adam-ab-measure.mjs` consumes this entry on later `/reflect` runs to compute pre/post signal-count deltas. See `agents/adam.md` §"A/B effectiveness". If the append fails (disk-full etc.), log a warning but do NOT abort the apply path — A/B is observability, not a gate. 3. **Archive consumed journal entries**: `node ~/.claude/adam/scripts/adam-archive.mjs ~/.claude/adam/applied/-.md`. This moves the entries listed in the proposal's `source_entries` from `journal.jsonl` to `journal/actioned-.jsonl`, so later `/reflect` runs do not re-cluster them. After all ids, print: `auto-applied N proposals: [ids]`. ## §4 approve, per type - **`claude_md_edit`**: back up first with `cp ~/.claude/CLAUDE.md ~/.claude/adam/applied/-claude-md-backup.md`. - **`deletion`**: `mkdir -p ~/.claude/adam/trash/`, then `mv` the artifact into it. Print the restoration command. - **`skill_new`**: `mkdir -p ~/.claude/skills//`, then write the `# Proposed change` body to `/SKILL.md`. Tell user: "skill `` written — activates immediately (CC v2.1.0+ auto-hot-reload)." - **`skill_edit`**: apply the unified diff in `# Proposed change` to the existing SKILL.md at `target` (append-only — never replace existing content). - **`memory`**: write the `# Proposed change` body (must include auto-memory frontmatter) to `target` and update the `MEMORY.md` index with a one-line pointer. - **`harness_edit`** (MOSS §1): apply the unified diff to the target harness file. **Before applying**: 1. Run `bash ~/.claude/adam/tests/run-tests.sh` — capture pass count. 2. Apply the diff via `Edit`. 3. Run `bash ~/.claude/adam/tests/run-tests.sh` again — verify pass count is equal or higher and 0 failures. 4. If test regression: revert the edit, print "harness_edit reverted — test regression detected", leave proposal in `proposals/`. 5. If tests pass: tell user "harness edit applied to `` — tests pass ( passed)." - **All other types**: apply via Write/Edit per the proposal's `# Proposed change`. Then: 1. Move proposal to `~/.claude/adam/applied/-.md`. 2. Archive: `node ~/.claude/adam/scripts/adam-archive.mjs ~/.claude/adam/applied/-.md`. ## §4 reject and edit - **Reject**: ask for the reason in one line. Append `# Reason\n` to the proposal body. If the proposal `type` is `skill_edit`, ALSO add `auto_apply_blacklist: true` to its frontmatter (so future reflects skip auto-apply on this target for 30 days). Move to `~/.claude/adam/rejected/.md`. Archive: `node ~/.claude/adam/scripts/adam-archive.mjs ~/.claude/adam/rejected/.md`. - **Edit**: ask the user for the change, edit the proposal in place, then loop back to §4 step a for that same id.