lukaszraczylo 7ddda26bb4 feat: task_completed signal — post-task skill capture (v0.3.2)
Adds an 11th signal type emitted when a run of work (between two
UserPromptSubmit events) crosses three quality gates:
  - >=5 tool calls (TASK_TOOL_MIN)
  - >=3 distinct tool kinds (TASK_DIVERSITY_MIN, filters single-tool
    sweeps like "wrote 5 files")
  - 0 correction signals during the run (filters tasks where the user
    pushed back; correction-during-task disqualifies the recipe)

Payload carries tool_count, tool_kinds, active_skills, active_agents
so the agent can cluster by sorted tool-kind tuple and route through
the existing skill-overlap rule (skill_new vs skill_edit).

Importantly: cross_session_evidence is FALSE on first occurrence,
so resulting skill_new proposals always queue for review — they only
auto-apply when the same multi-tool recipe recurs in a second session
(then the existing rubric kicks in). Post-task creation captures novel
patterns while preserving the rule "auto-apply requires cross-session".

Hook adds state fields: task_tool_count, task_tool_kinds, task_corrections.
All reset on UserPromptSubmit boundary and on session change.

Agent gets one new signal-types-table row and one clustering bullet
referencing the existing skill-overlap rule.

3 new tests (30 passed, 0 failed):
  - 5 tools + 5 kinds + 0 corrections fires task_completed
  - 5 tools + 1 kind (Edit only) does NOT fire (diversity gate)
  - 5 tools + 3 kinds + correction-on-closing-prompt does NOT fire
2026-05-10 22:34:33 +01:00
2026-05-10 02:41:58 +01:00

claude-adam

Self-improvement layer for Claude Code that observes friction signals during your sessions and proposes targeted improvements (new skills, memory entries, agent edits) which you can review and apply.

What's new

  • v0.3.1 — code review pass: bug fixes (errorFingerprint no longer false-positives on is_error: false, archive script handles same-millisecond duplicates correctly, tool_window now clears on session change, nudge filters proposal filenames by pattern), prose conciseness cuts, hardened install.sh with curl one-liner + settings.json merge, adam-uninstall.sh, isolated test harness (no longer pollutes live ~/.claude/adam/ state).
  • v0.3.0 — causal diagnosis: every proposal carries a # Diagnosis block (Trigger/Action/Mismatch/Outcome with verbatim transcript quote) before drafting, plus optional contradiction_flag heuristic that vetoes auto-apply on obviously-conflicting skill_edit additions.
  • v0.2.1 — win signals (correction_free_streak, clean_recovery) feed skill_edit auto-apply under a strict gate (≤30 LOC, ≤2× byte cap, 7d cooldown, 30d blacklist on rejection).
  • v0.2.0 — actioned-entry archival via adam-archive.mjs; cursor field deprecated.

What it does

A lightweight Node.js hook (adam-observe.mjs) runs on UserPromptSubmit, PreToolUse, and PostToolUse events. It detects:

Signal Trigger
correction User prompt contains "no", "stop", "wrong", "actually", etc. after a tool call
retry_loop Same tool + same args called 3× in a 10-event window
weak_agent Same subagent dispatched 2× in last 5 tool calls
tool_error_loop Same error fingerprint appears 3× in a 5-event ring
dead_end 8 PostToolUse events without a UserPromptSubmit between them
edit_churn Same file edited 4× in a window
build_loop 2× build/test/compile commands fail in same session
subagent_dispatch_pattern Same subagent dispatched ≥3× cumulatively
correction_free_streak 5 clean UserPromptSubmits in a row (no correction phrase) — feeds skill_edit reinforcement
clean_recovery 3 clean PostToolUse events after a struggle signal — feeds skill_edit reinforcement

Detection is local, regex-based, zero LLM cost. Signals append to ~/.claude/adam/journal.jsonl.

When you run /reflect, the adam subagent reads the journal, clusters signals, scores them against a deterministic rubric, and emits proposal files to ~/.claude/adam/proposals/. Auto-applied proposals only ship for low-blast types (memory, new skills) backed by cross-session evidence; everything else queues for your manual approve/reject/edit walk.

Why

LLM coding sessions reveal repeated friction the moment you stop and look. ADAM looks so you don't have to.

Layout

~/.claude/
├── hooks/
│   ├── adam-observe.mjs      # signal collector
│   └── adam-nudge.mjs        # SessionStart reminder when ≥3 proposals queued
├── agents/adam.md            # analyst subagent (system prompt + rubric)
├── skills/adam-self-improvement/SKILL.md  # /reflect protocol
├── commands/reflect.md       # /reflect slash command
└── adam/
    ├── journal.jsonl         # append-only signal log (active observations)
    ├── journal/              # rotated daily logs + actioned-<id>.jsonl per applied/rejected proposal
    ├── state.json            # per-session counters
    ├── usage.json            # skill/agent invocation tallies + payload visibility counters
    ├── proposals/            # queued, awaiting review
    ├── applied/              # approved + auto-applied archive
    ├── rejected/             # rejected (with reason)
    ├── trash/                # soft-deleted artifacts (recoverable)
    ├── scripts/              # adam-archive.mjs (called by skill on apply/reject)
    └── tests/run-tests.sh    # 27 verification tests (isolated tmpdir; never touches live state)

Install

curl -fsSL https://raw.githubusercontent.com/lukaszraczylo/claude-adam/main/install.sh | bash

Pin a release for reproducibility:

curl -fsSL https://raw.githubusercontent.com/lukaszraczylo/claude-adam/v0.3.1/install.sh \
  | VERSION=v0.3.1 bash

The installer clones the repo to /tmp, copies files into ~/.claude/, and offers to merge ADAM's hook entries into your ~/.claude/settings.json (with a diff preview and [y/N] confirmation — your existing hooks are preserved). Pass --yes to skip the prompt; --dry-run to preview without writing.

Requires git, curl, jq, and node 18+.

From a clone

git clone https://github.com/lukaszraczylo/claude-adam
cd claude-adam
./install.sh

Upgrade-safe

These files are never overwritten if they already exist:

  • ~/.claude/adam/journal.jsonl — your observation log
  • ~/.claude/adam/state.json — session counters
  • ~/.claude/adam/usage.json — invocation tallies

If you've locally edited any installed file (e.g. agents/adam.md), the installer writes the new version to <file>.adam-new and warns you instead of clobbering.

After install: run bash ~/.claude/adam/tests/run-tests.sh to verify (expect 27 passed, 0 failed), start a fresh Claude Code session, then run /reflect.

Requirements

  • Claude Code v2.1.0+ (for auto skill hot-reload; older versions need session restart after skill_new proposals are applied)
  • Node.js 18+ (for the hook; tested on v22)
  • Bash 4+, git, curl, jq (for installer + test harness)

Platform support

Tested on macOS (Darwin / BSD coreutils) and Linux (Alpine, glibc + musl). The install / uninstall / test scripts are written to be portable: stat uses BSD -f with GNU -c fallback, mktemp -d -t prefix.XXXXXX works on both, no GNU-only flags. CI smoke verified 27 passed, 0 failed under alpine:latest.

Confidence rubric

Sum:
+2  Signal repeated ≥3× across ≥2 sessions
+2  Struggle signal appearing ≥1× within a single session (does not stack)
+2  Transcript contains positive endorsement near related action
+1  Multi-axis cluster (≥2 distinct struggle types in same session)
-1  Type-bias penalty (≥3 rejections, applied:rejected <1:2)
+1  Blast radius low (memory or new isolated skill)
 0  Blast radius medium (new agent, new hook, edit existing skill)
-1  Blast radius high (CLAUDE.md, settings hooks, edit agent, deletion)
+1  Surgical (one file, ≤50 LOC for non-skill_new; ≤80 LOC for skill_new)
-3  Touches deny-list (settings.json hooks/permissions, CLAUDE.md, deletions)

auto_apply_eligible requires ALL:
  confidence ≥ 4
  blast_radius == low
  type ∈ {memory, skill_new, skill_edit}     # skill_edit also passes the win-driven gate
  cross_session_evidence == true (single-session-only proposals always queue)

skill_edit additionally requires (v0.2.1+):
  win-signal evidence (correction_free_streak / clean_recovery cites target skill)
  diff is append-only, ≤30 LOC, resulting size ≤2× original
  no auto-edit to same target in past 7 days (cooldown)
  no rejection-blacklist on target in past 30 days
  contradiction heuristic does not flag (v0.3.0+)
  # Diagnosis section present + structurally valid (v0.3.0+)

Lifecycle: how proposals become permanent

Every proposal records the journal entry timestamps that fed its cluster (source_entries in frontmatter). When you apply or reject a proposal, the skill calls adam/scripts/adam-archive.mjs which moves matching entries from journal.jsonl to journal/actioned-<id>.jsonl. Effects:

  • The journal.jsonl stays bounded by active observations only.
  • The next /reflect reads applied/ + rejected/ frontmatter, builds an excluded-timestamps set, and skips any leftover journal entries that were already actioned.
  • Rule changes (e.g. lowering a threshold) immediately re-evaluate the remaining active observations — no manual cursor rewind needed.

What it will not do

  • No background LLM spend. The analyst runs only when you invoke /reflect.
  • No retroactive transcript mining beyond the journal cursor.
  • No hard rm of any artifact. Deletions are soft (mv to trash/<ts>/).
  • No autonomous edits to CLAUDE.md, agents, hooks, or settings.json — these always queue for review regardless of confidence.
  • No proposal that matches a previously-rejected idea (≥2 token overlap with rejection's # Why).
  • No invented trigger phrases for new skills — every trigger comes from observed user input.

Uninstall

One-shot:

curl -fsSL https://raw.githubusercontent.com/lukaszraczylo/claude-adam/main/adam-uninstall.sh | bash

The uninstaller archives ~/.claude/adam/ to ~/.claude/adam.bak.<ts>/ (preserving your journal/proposals data), removes ADAM files, and offers to strip ADAM hook entries from ~/.claude/settings.json with a diff prompt. Pass --yes to skip the prompt; --purge to delete the data archive instead of preserving it.

Manual:

mv ~/.claude/adam ~/.claude/adam.bak.$(date +%s)
rm -f ~/.claude/hooks/adam-*.mjs ~/.claude/agents/adam.md ~/.claude/commands/reflect.md
rm -rf ~/.claude/skills/adam-self-improvement

Then remove the four adam-* hook entries from ~/.claude/settings.json.

License

MIT — © 2026 Lukasz Raczylo

Languages
JavaScript 50.6%
Shell 49.4%