leerness
v1.36.187
Published
The AI-coding operations layer that makes "done" require evidence — persistent memory, evidence-gated completion checks, and clean handoffs for any AI agent (Claude Code, Codex, Cursor). State lives as plain files in your repo. CLI + MCP, 0 runtime depend
Maintainers
Readme
leerness
██╗ ███████╗███████╗██████╗ ███╗ ██╗███████╗███████╗
██║ ██╔════╝██╔════╝██╔══██╗████╗ ██║██╔════╝██╔════╝
██║ █████╗ █████╗ ██████╔╝██╔██╗ ██║█████╗ ███████╗
██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║
███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║
╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝The AI-coding operations layer that makes "done" require evidence — for any language, any AI agent. leerness does not write code. It gives your AI agent persistent memory, verified completion, and clean handoffs — stored inside your repo as plain files, exposed via CLI + MCP.
·
· 0 runtime deps · 0 install scripts · offline-first · Node ≥ 18 · MIT
🇰🇷 한국어 전문: README.ko.md
Try it in 30 seconds
npx -y leerness init . --yes # adds .leerness/ memory + guard files to your project
npx leerness handoff . # everything your AI should know right now, in one callhandoff is safe to run from several AI sessions at once: by default it does not rewrite Git-tracked harness files and updates only an ignored per-session record under .leerness/cache/sessions/. Use handoff --writeback only when legacy automation explicitly needs refreshed current-state.md, environment.json, last-handoff.json, or generated graph projections.
Existing projects that still use .harness/ are upgraded to .leerness/ transactionally on the first normal command run from that project (or targeted with --path). To inspect first, run leerness migrate-workspace-dir . --dry-run; to migrate an explicit positional project path, omit --dry-run. The migration preserves the byte-for-byte legacy tree by atomically renaming it to the ignored .leerness-backup/ only after canonical copies and hashes verify, preserves an existing structured-state substrate in .leerness/, remaps old observability runs into .leerness/cache/agent-runs/, and rewrites operational path references. It fails closed when both directories contain independently live state, the backup name already exists, or a link/junction could escape the project. Arbitrary path-shaped command text is never treated as a migration target.
For Cursor, run npx leerness adapter cursor --path . once. It preserves existing project hooks and adds a local sessionStart bridge that maps Cursor's session address to LEERNESS_SESSION_ID, so concurrent Cursor/Claude/Codex sessions remain separately traceable. Cursor Cloud currently does not run sessionStart/sessionEnd hooks; in that environment the agent must provide an explicit session address or run handoff itself.
Your project now has agent-independent memory. To see the flagship feature — catching a false "done" claim:
npx leerness task add "Implement payment API" # prints the new id, e.g. T-0002 — use it below
npx leerness task update T-0002 --status done --evidence "payment.js implemented + tested"
npx leerness verify-claim T-0002 # exit 1 — payment.js does not exist. Claim rejected.Now actually write payment.js, then run the same verify-claim T-0002 → it exits 0. That is the whole idea: "done" must match reality.
Tip: if your evidence claims a specific test count (e.g. "5 tests passed"), leerness counts the test functions actually present and rejects a claim that exceeds them — so claim only what's true. That default is a static count of test declarations, not proof they pass; add
--run-tests --test-cmd "<your test cmd>"to verify they actually pass by running them.
Want a smaller footprint?
leerness init . --minimalinstalls only the core memory + verification files instead of the full set.
No terminal? Let your AI run it
You never have to type a command yourself. Paste this into Claude Code, Cursor, Codex, or any coding agent:
Set up leerness in this project by running
npx -y leerness init . --yes. From now on, runleerness handoff .at the start of every session, verify finished work withleerness verify-claim, and runleerness session close .before you finish.
The agent installs and operates it for you — leerness init also writes the instructions into CLAUDE.md / AGENTS.md so future sessions pick them up automatically.
Prefer pure natural language? leerness ships an MCP server with 98 tools (leerness mcp serve). Connect it once to Claude Desktop / Claude Code and just ask: "what was I working on?", "did the AI actually finish T-0001?"
Claude and Codex already have memory. Why leerness?
Built-in harnesses remember what the AI said. leerness verifies what the AI did — and keeps working when you switch agents.
| | Built-in (CLAUDE.md, agent memory) | leerness |
|---|---|---|
| Memory | per-agent, free-form notes | structured tasks / decisions / lessons / rules — agent-independent files in your repo |
| "Done" claims | trusted as written | evidence-gated: claimed files, test counts, and run output are checked against reality — bluffs exit 1 |
| Switching agents (Claude → Codex → Cursor) | context lost | same .leerness/ state, same one-call handoff |
| Secrets · encoding · drift guards | none | scan secrets · encoding check · drift check --auto-fix — CI-ready |
| Lock-in | one vendor | any agent, any language, 0 runtime dependencies |
Role-first model routing and fallback
Roles remain stable while providers and models are replaceable execution resources. Configure a role with a primary executor, ordered candidates, and a fallback policy, then resolve the current task against separate installation, opt-in, authentication, entitlement, quota, reachability, and policy signals:
leerness roles set coder --provider codex --model gpt-model-id \
--candidate claude:claude-model-id --policy balanced
leerness roles validate --json
leerness agents resolve "implement the API" --role coder --json
leerness agents fallback provider "implement the API" --role coder \
--provider claude --model claude-model-id --approved-by owner --json
leerness agents history --jsonResolution never silently executes a fallback. Each applied choice is bound to the role-store and availability revisions it inspected. High-risk substitutions require a visible approver, lowering detected high risk requires both --approved-by and --reason, and high-risk review is selectable only when different families can be inferred from concrete model IDs. dispatch and fallback normally prepare or record a choice with executed:false. Role-free agents multi --execute and agents bench can spawn opted-in external CLIs and record their outcomes; both reject --role because provider-default fan-out cannot prove one role/model contract.
Make it enforced, not optional
Before changing a multi-agent project's storage, inspect its actual workspace and proposed
Git-private/common scopes with leerness state inspect . --json. It is read-only: no data
migration, runtime activation, or provider calls. See the state inspection API
and the staged architecture plan.
leerness state compatibility . --json separately checks whether the observed runtime
layout permits this client's legacy writes. It creates no state and exposes bounded
failure reasons. This is a pre-migration compatibility guard, not a migration or a way
to stop older clients. See the compatibility API and limits.
By default leerness is cooperative: your AI agent runs the commands because CLAUDE.md / AGENTS.md tell it to. A determined agent could skip them. To turn the guideline into a guardrail:
leerness ci init # writes .github/workflows/leerness-gate.yml — runs `leerness gate` on every PRThe generated workflow is production-grade: it pins the leerness version (reproducible — the gate's verdict can't change from a silent upgrade), runs with least-privilege permissions (contents: read), and cancels superseded runs.
Then make that check required in GitHub branch protection. Now a PR that skips verification (or whose claims fail) cannot merge — the gate runs independently of the agent, returns a non-zero exit code, and blocks. That is the difference between a guideline and a guardrail. For exact per-claim enforcement, run leerness gate --claims — it adds a 6th check that runs verify-claim on every completed task and fails the gate if any "done" task's evidence doesn't match reality (the default 5-check gate already blocks false-done via heuristics; --claims makes it precise).
For a mature repository that predates strict claim verification, do not rewrite historical evidence merely to make the gate green. Create an explicit, reviewed debt boundary instead:
leerness verify-claim baseline create --before T-0123 --yes
leerness verify-claim --all # applies exact-match legacy debt policy
leerness verify-claim --all --raw # ignores the baseline and audits raw verdictsThe baseline stores no replacement evidence. It accepts only failures before the named tracker row whose complete row and failure reasons still match their SHA-256 fingerprint. A changed legacy row, a newly failing task, an entry at/after the boundary, or a corrupt baseline fails closed. verify-claim <T-ID> always remains raw for focused audits. Creation is one-shot: the CLI refuses to recalculate or overwrite an existing baseline, so a changed historical row cannot be relaundered by rerunning the command. The tracked .leerness/claims-baseline.json is repository policy, not a signature against a malicious repository writer: protect any removal or replacement with ordinary branch review and CODEOWNERS when the threat model requires that separation.
For secrets, pair the gate with a dedicated scanner in the same workflow. scan secrets gives your agent the same signal locally; a dedicated scanner is the hard-guarantee layer:
# add to .github/workflows/leerness-gate.yml (or a separate job)
- uses: gitleaks/gitleaks-action@v2 # dedicated scanner — the hard-guarantee layer
- run: npx leerness@<pinned-version> scan secrets . --json # same check your agent runs locallyLow-risk by design
MIT · 0 runtime dependencies · offline-first, and all state is plain files in your repo. Lock-in is near zero — if it doesn't earn its place, remove the tool and your task / decision / lesson files stay exactly where they are. Pin a version in CI so the gate's verdict can't change from a silent upgrade.
What is inside (the 60-second tour)
- Memory —
task/plan/decision/lesson/rule: canonical JSON + markdown projections, archive/restore. - Handoff —
handoff(session start context) ·session close(closing report). Survives agent swaps. - Verification —
verify-claim(evidence vs reality, stub/fake-test/inflated-count detection,--run-tests --test-cmdfor any language;--allchecks every completed claim for CI;baseline create --before <T-ID> --yesisolates fingerprint-bound legacy debt;--rawaudits the original verdicts) ·contract verify(spec ↔ impl) ·gate(one-call CI gate). - Audit —
audit·lazy detect·drift checkkeep the workspace honest over time. - Security —
scan secrets(committed-secret detection) ·encoding check(BOM/CP949) — also runs atsession close. - Visualize —
graph --htmlwrites a self-contained interactive ontology graph (leerness.html) of the whole harness (memory surfaces + skills + feature-graph) — click a node to read its content. Optional tracked auto-refresh:LEERNESS_AUTO_GRAPH=1 leerness handoff . --writeback.
Full command reference, workflows, and architecture: README.ko.md (Korean) · leerness commands · leerness help.
Links
- npm: https://www.npmjs.com/package/leerness
- Site & release videos: https://leerness.pages.dev
- Changelog: CHANGELOG.md
- How this gets tested — methodology, results, and limitations: docs/clean-room-evaluations.md
- Interoperability (MCP · ACP stance · state substrate): docs/interoperability.md
- Contributing & test tiers (
test:fast/test:core/npm test): CONTRIBUTING.md
License
MIT
Leerness Project Harness
이 프로젝트는 Leerness v1.36.187 하네스를 사용합니다. AI 에이전트는 작업 전 leerness handoff로 컨텍스트를 적재하고, 작업 후 leerness check/leerness audit/leerness session close를 수행해야 합니다.
정체성 — AI 에이전트 운영 레이어 (UR-0030)
Leerness 는 실행기/코딩 에이전트가 아니라, 어떤 AI 코딩 에이전트(Claude Code · Codex · Cursor · Goose 등) 위에도 얹는 범용 운영 레이어입니다. 5개 공통 계층을 제공합니다:
- 기억(Memory) — 프로젝트 상태/결정/진행을
.leerness/에 영속화 - 정책(Policy) — 8단계 권한 등급 + enforce (read-only→publish), MCP 호출 게이트
- 인수인계(Handoff) — 에이전트 간 컨텍스트 표준 전달 +
get_project_context1콜 온보딩 - 검증(Verification) — 근거 기반 완료 검증으로 허위 완료 감지 (권고; CI 게이트 필수화 시 차단)
- 감사(Audit) — drift/idempotency/secret/encoding 자동 감사 (self-heal: drift·idempotency --auto-fix, encoding --apply; secret 은 감지 전용)
AGENTS.md(정적 지침)을 대체하지 않고 보완합니다 — 정적 규칙은 AGENTS.md, 동적 상태·검증·인수인계는 leerness. 정체성 조회: leerness about (MCP leerness_about).
Core Commands
leerness handoff . # 세션 시작 컨텍스트 자동 로드
leerness status . # 설치 상태
leerness verify . # 필수 파일 검증
leerness audit . # 일관성·계획-진행 정렬 감사
leerness scan secrets . # 시크릿 패턴 스캔
leerness encoding check . # UTF-8 / BOM / NUL / .bat 인코딩 검사
leerness lazy detect . # 게으름 방지 자동 평가
leerness memory search "키" # 결정/이력 검색
leerness session close . # 세션 종료 + handoff 자동 작성
leerness update . # 자동 버전 감지 + 마이그레이션Memory Surface CRUD (5 surfaces × add/list/drop)
# Tasks
leerness task add "T-9999 작업 제목"
leerness task list --json
# Decisions
leerness decision add "결정 제목" --reason "이유"
leerness decision list --query "키워드" # 1.9.139
# Rules (영구 자연어 룰)
leerness rule add "매 commit마다 changelog 갱신" --trigger every-commit
leerness rule list
# Plan (milestones)
leerness plan add "M-XXXX 계획" --next "다음 단계"
leerness plan list
# Lessons (영구 교훈)
leerness lesson save "교훈 본문" --tag perf
leerness lesson list --query "키워드" # 1.9.139
# DELETE → RESTORE (1.9.126~128)
leerness memory archive list . --query "키워드" # 1.9.138
leerness memory restore decision <date|title>MCP server (외부 AI 통합)
Leerness v1.36.187는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 98개 도구를 노출:
// 카테고리별
// • Core: handoff / drift_check / audit / health / verify_claim / contract_verify
// • Memory READ: task_list / decision_list / lesson_list / plan_list / rule_list / memory_status
// • Memory WRITE: task_add / decision_add / lesson_save / plan_add / rule_add
// • Memory DELETE: task_drop / decision_drop / lesson_drop / plan_remove / rule_remove
// • Skill: skill_match / skill_list / skill_search / skill_info / skill_suggest
// • Insight: lessons / lessons_auto / brainstorm / retro / benchmark / lazy_detect
// • Workflow: session_close / agents_list / task_export / env_check / usage_stats / reuse_map / whats_new
// MCP server 실행: leerness mcp serve
// tools/list 응답: 98 도구Autonomous mode (자율 모드)
<<autonomous-loop-dynamic>> 신호만 보내면 AI가:
- 다음 라운드 후보 선정 → 2) 코드 변경 → 3) 회귀 테스트 갱신 → 4) 전체 e2e 스위트 통과 → 5) npm publish + git tag → 6) main push → 7) session close → 8) 다음 라운드 예약.
현재 누적: v1.9.x → 1.36.187 릴리스 태그 이력 (수백 라운드) · _reports/는 비공개 보존.
성능 가이드
leerness handoff .— 평균 ~1.5s (캐시 워밍업 후 ~0.6s)leerness memory status --json— 평균 ~250msleerness task list --json— 평균 ~200msleerness drift check --json— 평균 ~400ms- MCP
tools/list응답 — 평균 ~150ms - usage-stats / lessons / listAllSkills 모두 메모리 캐싱
빠른 시작
# 1. 설치 (글로벌)
npm install -g leerness
# 2. 프로젝트에 하네스 설치
cd my-project && leerness init . --yes --skills recommended
# 3. AI 세션 시작 시
leerness handoff . # 컨텍스트 자동 로드
# 4. 세션 종료 시
leerness session close . # 9 카테고리 + 룰 검증 + 다음 라운드 추천
# 5. release 자동화 (main 자동 push 포함)
leerness release pack --close --auto-main-pushPlanning Files
.leerness/plan.md: 전체 목표, milestone, 제외/드랍 범위.leerness/progress-tracker.md: 요청 단위 상태와 증거.leerness/current-state.md: 지금 이어서 할 작업.leerness/session-handoff.md: 다음 세션 인수인계 (자동 작성).leerness/lessons.md/decisions.md/rules.md: 영구 메모리 (5 surface)
Last synced by Leerness v1.36.187: 2026-09-06
