diff --git a/README.md b/README.md
index 98f0699..5c216c5 100644
--- a/README.md
+++ b/README.md
@@ -1,159 +1,260 @@
+
+
+

+
# claude-adam
-Self-improvement layer for [Claude Code](https://claude.com/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.
+**A self-improvement layer for [Claude Code](https://claude.com/claude-code).**
-## What's new
+Watches the friction in your coding sessions, clusters the signals via an LLM analyst, and proposes targeted improvements — new skills, memory entries, agent edits — that you review and apply.
-- **v0.3.3** — analyst observability, A/B measurement, journal hygiene. Storage/window/exclusion split: ISO-week journal rotation with safety fuse (replaces size-based, fixes silent under-counting); per-signal sliding windows via new `adam-window.mjs` (`dead_end` 7d, `correction` 30d, reinforcement signals 60d). Error fingerprint normalization — `ECONNREFUSED` and `"Connection refused"` cluster identically. Correction corpus expanded (`wait`, `hold on`, `try again`, `different approach`); weak tokens (`no`, `actually`, `wait`) require negation co-occurrence within 8 tokens to fire — kills the `"actually, I think..."` false positive. Mandatory clustering trace + new `adam-explain.mjs --mode summary|full|json`. New `nudge` proposal type (single-session auto-apply, low blast) for repeated `dead_end`. Per-(skill, fingerprint) cooldown via `adam-cooldown.mjs` (replaces coarse per-skill gate). `task_completed` scoring: urgency dampener + reinforcement candidates. A/B effectiveness measurement on auto-applied edits (`adam-ab-measure.mjs`, 7d pre/post window). Upgrade UX overhaul: `adam-upgrade.mjs --list/--diff/--accept` + SessionStart pending-merge warning. Shared helper module `adam-utils.mjs` deduplicates journal-reading and frontmatter parsing across scripts. 87 tests (up from 30).
-- **v0.3.2** — `task_completed` signal: post-task skill capture for downstream reinforcement scoring (consumed in v0.3.3).
-- **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.
+[](LICENSE)
+[](https://github.com/lukaszraczylo/claude-adam/releases)
+[](./adam/tests/run-tests.sh)
+[](https://nodejs.org)
+[]()
-## 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 |
+## The story behind Adam
+
+Adam is my newborn son.
+
+Watching him over the last few months — the way he observes the world, tries something, watches what happens, adjusts, and tries again — I realised that the most powerful learning loop in nature is also one of the simplest. No grand theory. No instruction manual. Just relentless feedback and pattern recognition, applied to every waking moment.
+
+LLMs can learn the same way. Give them a hook into the real friction of your work — the corrections, the dead-ends, the moments you say *"no, try again"* — and let them propose improvements grounded in **what actually happened**. Not what they assume might help. What you actually struggled with.
+
+**claude-adam** is that loop, wired into Claude Code. It's named after Adam because the methodology is his.
+
+---
+
+## Highlights
+
+- 🔍 **Zero LLM cost at observation time.** Deterministic regex + counter detection in a Node hook. The analyst only runs when you invoke `/reflect`.
+- 📡 **11 signal types.** Friction (`correction`, `tool_error_loop`, `dead_end`, `edit_churn`, …) + reinforcement (`task_completed`, `correction_free_streak`, `clean_recovery`) + meta.
+- 🛡️ **Tight auto-apply gates.** Confidence ≥ 4, cross-session evidence, contradiction veto, per-(skill, fingerprint) cooldown. Most things queue for your manual review.
+- 📊 **A/B effectiveness measurement.** Every auto-applied edit gets a 7-day pre/post signal-count delta. If a proposed fix made things worse, the next `/reflect` says so.
+- ⏳ **Per-signal sliding windows.** Stale friction doesn't accumulate forever. `dead_end` 7d, `correction` 30d, reinforcement signals 60d.
+- 🔬 **Observable.** Every clustering decision (passed / threshold-blocked / window-filtered / contradiction-vetoed) emits a trace. `/reflect --explain` shows it.
+- 📦 **Pure Node.** Zero npm dependencies. Runs on macOS and Linux (Alpine smoke-tested).
+
+## Quick start
+
+```sh
+curl -fsSL https://raw.githubusercontent.com/lukaszraczylo/claude-adam/main/install.sh | bash
+```
+
+The installer copies files into `~/.claude/`, offers to merge ADAM's hook entries into `~/.claude/settings.json` (with a diff preview and `[y/N]` confirm), and preserves any local edits via `.adam-new` sidecar files. Pass `--yes` to skip prompts, `--dry-run` to preview.
+
+Then:
+
+```sh
+bash ~/.claude/adam/tests/run-tests.sh # expect: 87 passed, 0 failed
+# … start a fresh Claude Code session …
+/reflect # walks the proposal queue
+/reflect --explain # also shows the analyst's clustering trace
+```
+
+Pin a release for reproducibility:
+
+```sh
+curl -fsSL https://raw.githubusercontent.com/lukaszraczylo/claude-adam/v0.3.3/install.sh \
+ | VERSION=v0.3.3 bash
+```
+
+## How it works
+
+```
+┌─────────────────────────────────────────────────────────────────────┐
+│ Observation (deterministic) │
+│ │
+│ Tool event / user prompt ──▶ adam-observe.mjs ──▶ journal.jsonl│
+│ (regex, counters, │
+│ ring buffers) │
+└─────────────────────────────────────────────────────────────────────┘
+ │
+ ▼ user runs /reflect
+┌─────────────────────────────────────────────────────────────────────┐
+│ Analysis (LLM, only on demand) │
+│ │
+│ adam-window.mjs ─▶ per-signal sliding window filter │
+│ adam-score.mjs ─▶ task_completed dampener + reinforcement │
+│ adam-ab-measure.mjs─▶ 7d pre/post deltas on prior auto-applies │
+│ │
+│ ┌──────────────────┐ │
+│ filtered ────▶ │ adam (subagent) │ ──▶ proposals/ + trace │
+│ inputs │ cluster + score │ adam-explain.mjs renders │
+│ └──────────────────┘ │
+└─────────────────────────────────────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ Review + apply │
+│ │
+│ auto-apply gates ──▶ applied/ + ab-tracking.jsonl │
+│ (low-blast only, │
+│ conf ≥ 4, etc.) │
+│ │
+│ everything else ──▶ walk-the-queue: approve / reject / edit │
+└─────────────────────────────────────────────────────────────────────┘
+```
+
+The observation layer is a 350-line Node hook. Pure regex, counters, ring buffers — no LLM in the hot path. Signals append one JSONL line per detection to `~/.claude/adam/journal.jsonl`.
+
+The analysis layer is an LLM subagent invoked by `/reflect`. Before the analyst runs, three deterministic pre-processors filter and enrich the journal: `adam-window.mjs` drops stale entries per per-signal age, `adam-score.mjs` computes per-session urgency dampeners + reinforcement candidates, and `adam-ab-measure.mjs` checks whether previously auto-applied edits actually reduced their originating signal.
+
+The analyst clusters signals, scores them against a deterministic rubric (see below), and emits proposal markdown files to `~/.claude/adam/proposals/`. Each proposal carries a `# Diagnosis` block (Trigger / Action / Mismatch / Outcome with a verbatim transcript quote), a `# Success criterion`, and the source journal-entry timestamps it clustered.
+
+Auto-apply runs only for low-blast types (memory entries, new skills, ephemeral nudges, reinforcement logs) backed by cross-session evidence. Everything else queues for your manual approve / reject / edit walk.
+
+## Signals
+
+| Signal | Trigger | Window* |
+|---|---|---|
+| `correction` | Strong tokens (`stop`, `wrong`, `undo`, …) OR weak tokens (`no`, `actually`, `wait`) with negation/contrast nearby | 30d |
+| `retry_loop` | Same tool + same args called 3× in a 10-event window | 14d |
+| `weak_agent` | Same subagent dispatched 2× in last 5 tool calls | 30d |
+| `tool_error_loop` | Same error fingerprint 3× in a 5-event ring (fingerprints normalised — `ECONNREFUSED` and `"Connection refused"` cluster) | 30d |
+| `dead_end` | 8 PostToolUse events without a UserPromptSubmit between them | 7d |
+| `edit_churn` | Same file edited 4× in a window | 14d |
+| `build_loop` | 2× build/test/compile commands fail in same session | 30d |
+| `subagent_dispatch_pattern` | Same subagent dispatched ≥ 3× cumulatively | 30d |
+| `correction_free_streak` | 5 clean UserPromptSubmits in a row — reinforcement input | 60d |
+| `clean_recovery` | 3 clean PostToolUse events after a struggle signal — reinforcement input | 60d |
+| `task_completed` | 5 tools / 3 kinds / 0 corrections — fed into the urgency dampener + reinforcement candidates | 60d |
+
+\* Per-signal sliding window for `/reflect` analysis. See `SIGNAL_WINDOWS_DAYS` in `adam/scripts/adam-window.mjs`.
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.
+## Auto-apply rubric
-## Why
+```
+Sum:
++2 Signal repeated ≥ 3× across ≥ 2 sessions (within signal's window)
++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)
+```
-LLM coding sessions reveal repeated friction the moment you stop and look. ADAM looks so you don't have to.
+Modifiers applied at scoring time:
+
+- × `dampener` from `adam-score.mjs` (0.5 / 0.75 / 1.0 based on session's `task_completed` count) — sessions that net-succeeded score lower urgency.
+
+`auto_apply_eligible` requires **all** of:
+
+- `confidence ≥ 4`
+- `blast_radius == low`
+- `type ∈ {memory, skill_new, nudge, reinforcement}` (or `skill_edit` via the win-driven gate)
+- `cross_session_evidence == true` (except `nudge`, which is single-session by design)
+- `adam-cooldown.mjs` returns `cool` for `(target_skill, proposal_fingerprint)`
+- `contradiction_flag` unset
+
+`skill_edit` additionally requires:
+
+- 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 (per-fingerprint cooldown)
+- No rejection-blacklist on target in past 30 days
+- `# Diagnosis` section present + structurally valid
+
+Everything else queues.
+
+## Lifecycle: from signal to permanent improvement
+
+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-archive.mjs` which moves matching entries from `journal.jsonl` to `journal/actioned-