Files
claude-adam/skills/adam-self-improvement/apply-by-type.md
T
lukaszraczylo 67e8eede85 refactor(skill): move apply procedures to apply-by-type.md
SKILL.md loads into context on every /reflect turn. The per-type apply
steps, the A/B tracking append and the Karpathy constraints are needed
only when a proposal is applied. Move them to apply-by-type.md and read
that file before any apply in 3a or 4.

The move keeps the July changes: the nudge helper, the reinforcement
A/B skip and the metadata memory schema. Tighten the adam agent routing
description.

Claude-Session: https://claude.ai/code/session_014prTNuJnKuwcAd28vUZAnN
2026-09-25 02:38:38 +01:00

11 KiB

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/<slug>/, then Write the proposal's # Proposed change body to ~/.claude/skills/<slug>/SKILL.md. After write, print: "skill <slug> written to ~/.claude/skills/<slug>/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):

    node ~/.claude/adam/scripts/adam-apply-nudge.mjs ~/.claude/adam/proposals/<id>-*.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 <cwd basename> (expires in 7 days)."

  • reinforcement: gated by confidence >= 4 AND blast_radius == low (same as memory). Apply by invoking the helper:

    node ~/.claude/adam/scripts/adam-apply-reinforcement.mjs ~/.claude/adam/proposals/<id>-*.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 <skill_slug> (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 <target_skill> --fingerprint <proposal_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: <iso8601 utc now> to the proposal frontmatter before moving it.
    8. Tell user: "skill <slug> 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/<UTC-ts>-<id>.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:

    {
      "applied_at": <unix_ms now>,
      "proposal_id": "<id>",
      "proposal_type": "skill_edit|skill_new|memory|nudge",
      "target_skill": "<slug or target basename>",
      "proposal_fingerprint": "<hash>",
      "originating_signals": [{"type":"<signal>","count":<N>,"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/<UTC-ts>-<id>.md. This moves the entries listed in the proposal's source_entries from journal.jsonl to journal/actioned-<id>.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/<ts>-claude-md-backup.md.
  • deletion: mkdir -p ~/.claude/adam/trash/<ts>, then mv the artifact into it. Print the restoration command.
  • skill_new: mkdir -p ~/.claude/skills/<slug>/, then write the # Proposed change body to <slug>/SKILL.md. Tell user: "skill <slug> 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 <target> — tests pass ( passed)."
  • All other types: apply via Write/Edit per the proposal's # Proposed change.

Then:

  1. Move proposal to ~/.claude/adam/applied/<ts>-<id>.md.
  2. Archive: node ~/.claude/adam/scripts/adam-archive.mjs ~/.claude/adam/applied/<ts>-<id>.md.

§4 reject and edit

  • Reject: ask for the reason in one line. Append # Reason\n<reason> 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/<id>.md. Archive: node ~/.claude/adam/scripts/adam-archive.mjs ~/.claude/adam/rejected/<id>.md.
  • Edit: ask the user for the change, edit the proposal in place, then loop back to §4 step a for that same id.