Commit Graph

6 Commits

Author SHA1 Message Date
lukaszraczylo a48c705c0a feat(adam): smarter signals & clustering
- New signal types in hooks/adam-observe.mjs:
  - silent_drift: 5 consecutive read-only PostToolUse without an action tool
  - error_after_recovery: same error fingerprint returns within 5 events of clean_recovery
- Severity-weighted scoring in adam/scripts/adam-score.mjs:
  - SEVERITY_DIVISORS exported per struggle signal type
  - Per-session severity_sum + severity_by_type added to JSON output
- Skill-attribution clustering in agents/adam.md:
  - Sub-cluster struggle signals on active_skills[0]
  - New struggle-driven skill_edit variant (always queues, never auto-applies)
- Rubric updates:
  - +1 for cluster severity-sum >= 10, additional +1 for >= 32
  - +1 for skill-attributed sub-cluster naming an existing skill
  - silent_drift + error_after_recovery added to struggle signal list
- Window: silent_drift 14d, error_after_recovery 30d
- Tests: 94 passing (78-82 new)

Backward compat: entries without count default to severity 1. Existing
win-driven skill_edit gate untouched. No journal migration.
2026-05-13 19:21:59 +01:00
lukaszraczylo 012c40b9ab chore(v0.3.3): analyst observability, A/B measurement, journal hygiene
Storage/window/exclusion split (#7): ISO-week journal rotation with safety
fuse replaces size-based rotation (fixes silent under-counting when clusters
straddle boundaries). Per-signal sliding windows via adam-window.mjs guard
against stale signal accumulation. Legacy YYYY-MM-DD-<ts>.jsonl files remain
readable.

Error fingerprint normalization (#3): adam-observe.mjs extracts canonical
error codes (ENOENT, ECONNREFUSED, etc.) and normalizes paths/timestamps/hex
before hashing. 'Connection refused' and 'ECONNREFUSED' now cluster identically.

Correction corpus expansion (#1): strong tokens (stop, wrong, undo, try again,
different approach, etc.) fire on any occurrence. Weak tokens (no, actually,
wait) require negation/contrast co-occurrence within 8 tokens. Kills the
'actually, I think...' false positive.

Analyst observability (#6): mandatory clustering trace block; adam-explain.mjs
parses to summary/full/json. Cluster decisions now surface rejection reasons
(threshold, contradiction, window). Persisted to ~/.claude/adam/last-trace.txt.

Dead_end nudge proposal type (#2): single-session auto-apply gate (>=3
dead_end events). Action appends to active-nudges.json, surfaced via
adam-nudge.mjs at next SessionStart. Lower blast than skill_edit.

Per-(skill, fingerprint) cooldown (#4): adam-cooldown.mjs replaces coarse
per-skill check. proposal_fingerprint = djb2(skill_slug + cluster_id +
normalized_diff_body). Legacy applied/rejected records gate via 'legacy'
fingerprint fallback through resolveSkill helper (handles target_skill,
skill, or target: <path>).

task_completed scoring integration (#8): adam-score.mjs computes per-session
urgency dampener (3 task_completed -> 0.5) and reinforcement candidates
(skills cited in >=3 clean completions). New 'reinforcement' proposal type
appends to reinforcements.jsonl on apply (no code/memory mutation).

A/B effectiveness measurement (#5): every auto-applied edit appends to
ab-tracking.jsonl. adam-ab-measure.mjs computes 7d pre/post signal-count
delta per entry (improved / neutral / regressed / no_baseline / pending).
Analyst surfaces regressions at top of /reflect output.

Upgrade UX overhaul (#9): adam-upgrade.mjs implements --list/--diff/--accept
/--accept-all. SessionStart nudge prints pending-merge warning when
.adam-new files exist (latency ~20ms via fixed shortlist). install.sh
emits unmissable final-message hint after creating any .adam-new file.

Simplify pass: adam-utils.mjs deduplicates readJsonlSafe / listJsonlFiles /
parseFrontmatter across 8 scripts. Net -46 LOC.

Test coverage: 30 -> 87 tests. Every new feature has feature-validating
assertions (false-case coverage included). T77 statically verifies install.sh
references every adam-*.mjs source script (would have caught the missing
adam-utils inclusion that review #2 surfaced).
2026-05-13 01:02:33 +01:00
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
lukaszraczylo 6d8ff37cb2 v0.3.1: code review pass + DX overhaul
Bug fixes (HIGH):
- adam-observe.mjs: errorFingerprint no longer false-positives when
  toolResponse.is_error === false; ERROR_RE only used as fallback when
  is_error is undefined.
- adam-observe.mjs: resetSessionLocal now clears tool_window so retry_loop
  cannot fire on the first tool of a new session by matching prior session.
- adam-archive.mjs: ts dedup uses Map<ts, count> instead of Set<ts>; two
  journal entries sharing a millisecond are no longer both archived when
  only one is referenced in source_entries.
- adam-nudge.mjs: only counts proposal filenames matching
  /^\d{4}-\d{2}-\d{3}-/ pattern; README/notes in proposals/ no longer bump.
- skills/adam-self-improvement/SKILL.md: contradiction_flag veto now applied
  at apply time (carry-over from earlier review).

Test isolation:
- adam/tests/run-tests.sh: ALWAYS runs against an isolated $HOME under
  mktemp -d. Previously truncated live ~/.claude/adam/journal.jsonl on
  every run — destructive on production state.

Conciseness:
- agents/adam.md: -19 LOC (cuts: vestigial cursor sentence, duplicate
  not-do bullets, blast-radius bullet collapse, Inputs paths delegate to
  SKILL.md, win-cluster-vs-struggle-cluster commentary already enforced
  by cluster-key separation, # Overlap section spec compressed).
- skills/adam-self-improvement/SKILL.md: -4 LOC (framing paragraph, dead
  catch-all bullet for non-eligible types).

Auto-prune script DELETED:
- The cumulative-count primitive cannot distinguish "never used" from
  "used before tracking began"; mtime gate is meaningless for installed
  files. Auto-prune deferred to v0.4 with a per-key lastSeen schema.

Cross-platform:
- macOS (BSD coreutils) and Linux (Alpine, glibc + musl) verified.
- All scripts use portable forms (stat -f || stat -c, mktemp -d -t).
- README documents platform support explicitly.

DX overhaul:
- install.sh: hardened — supports `curl | bash` via auto-clone,
  --version=vX.Y.Z pinning, --yes / --dry-run flags, jq-based
  settings.json merge with diff prompt and backup, conservative file
  copy that detects local mtime drift and writes <file>.adam-new
  instead of clobbering, idempotent across re-runs.
- adam-uninstall.sh: NEW. Soft-archives ~/.claude/adam/ to .bak.<ts>/
  by default; --purge to delete; --yes for non-interactive; jq-based
  settings.json cleanup with diff prompt.
- README.md: curl one-liner install + version-pinned variant at top,
  What's New section through v0.3.1, upgrade-safe data files callout,
  uninstaller documentation, platform support note, expanded rubric
  showing skill_edit gate.

Test count: 27 passed, 0 failed (was 27 — no regression).
2026-05-10 21:33:17 +01:00
lukaszraczylo 2dc76bf203 feat: lessons-learned loop — win signals + skill_edit auto-apply
Adds two new hook signal types:
- correction_free_streak: 5 consecutive UserPromptSubmits without a correction phrase
- clean_recovery: 3 clean PostToolUse events after a struggle signal
  (tool_error_loop / dead_end / retry_loop)

Both carry active_skills/active_agents payloads computed from a 10-event
activity ring, so ADAM can attribute wins to whichever skill was active
during the streak/recovery.

Promotes skill_edit to auto-apply under a strict gate (all required):
- conf >= 4 + cross-session evidence (existing rules)
- # Why cites a win-signal entry whose active_skills includes target
- diff append-only, +lines <= 30
- resulting SKILL.md size <= 2x current size
- 7-day cooldown per target (last_auto_edit in applied/ frontmatter)
- 30-day blacklist on user rejection (auto_apply_blacklist in rejected/)

Skill enforces the gate at apply time as defense in depth: re-stats target,
re-checks cooldown and blacklist, verifies append-only, reverts and refuses
on byte-cap breach. User-rejected skill_edit proposals automatically write
auto_apply_blacklist: true.

Win signals participate in the existing v0.2.0 source_entries archive
lifecycle, so already-applied evidence does not re-cluster.

Test suite: +5 cases (5 new asserts pass), 27 total passing.

Spec:  ~/.claude/docs/superpowers/specs/2026-05-10-adam-proactive-design.md
Plan:  ~/.claude/docs/superpowers/plans/2026-05-10-adam-proactive.md
2026-05-10 20:51:12 +01:00
lukaszraczylo 78bf0f1e1e Initial commit: ADAM self-improvement layer for Claude Code
- 8 friction signals via lightweight hook (correction, retry_loop, weak_agent,
  tool_error_loop, dead_end, edit_churn, build_loop, subagent_dispatch_pattern)
- Deterministic confidence rubric with cross-session evidence gate
- /reflect skill to dispatch the analyst subagent and walk the queue
- Skill overlap detection (prefer skill_edit over skill_new on collision)
- Solution synthesis from transcript context for new skill drafts
- Soft-delete trash, never hard rm
- 18 tests covering all signals
2026-05-10 02:32:13 +01:00