diff --git a/CLAUDE.md b/CLAUDE.md index 329868e..e49710a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -50,6 +50,11 @@ an agent. pytest auto-captured. - **Red→green surfacing** (`newly_passing`), **restore deletion-handling** (strays removed on restore), **LLM retry/backoff**, **CI** (GitHub Actions). +- **P4 is COMPLETE** (keyless skill mode): the deterministic core is exposed as CLI + verbs (`src/pandavas/spine.py`) and a `/pandavas` command + skill ships for Claude + Code and Cursor, so the system runs with no API key on the host harness's model. + Strictly additive; the `run` path is unchanged. See `docs/SKILL_MODE.md` and + `docs/SPEC.md` §12. - **Quality posture:** keep the suite green (`python -m pytest`), keep CLI stdout ASCII-only (Windows-first), no hardcoded paths, real `.env` never committed. diff --git a/README.md b/README.md index 049e71e..f4b9fd5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ The name comes from the five Pandava brothers of the Mahabharata. Each agent is mapped to the brother whose strongest trait fits the job, which also fixes the hierarchy for free: the orchestrator is the eldest brother the others answer to. +Two ways to run it: **standalone** (`python -m pandavas run`, your own API key) or +**keyless** as a `/pandavas` command inside Claude Code / Cursor, where the host +harness's model plays the agents. See [Skill mode](#skill-mode-keyless-in-editor). + ## The core idea LLM coding agents fail in a predictable way. The agent summarizes the code, the @@ -95,7 +99,8 @@ That installs the runtime dependencies (`langgraph`, `openai`, `pydantic`, ## Configuration -pandavas uses your own API keys and is built to run on free inference tiers. Copy +**Standalone mode** uses your own API keys and is built to run on free inference +tiers. (Skill mode needs no key — see [Skill mode](#skill-mode-keyless-in-editor).) Copy the template: ```bash @@ -234,7 +239,10 @@ The system is complete end to end: the deterministic executor, three real LLM agents (research, worker, judge), the non-LLM test runner, and the state-machine orchestrator are wired into the convergence loop, with regression-aware testing, a CLI that does JSON reporting and token accounting, git delivery of a converged -change, and CI. What it deliberately does not do: +change, and CI. It also runs **keyless** as a `/pandavas` skill in Claude Code and +Cursor — the host harness's model plays the agents while the deterministic verbs gate +correctness (see [Skill mode](#skill-mode-keyless-in-editor)). What it deliberately +does not do: - **Output isn't deterministic.** The contract is moved from generation to acceptance: *produces a change that passes the gate, or reports that it could diff --git a/docs/HANDOVER.template.md b/docs/HANDOVER.template.md index 9bb7d8e..1daf290 100644 --- a/docs/HANDOVER.template.md +++ b/docs/HANDOVER.template.md @@ -35,5 +35,5 @@ ## Scope reminder -- Active phase: **P0 / v0** unless the user has explicitly lifted the scope lock - (see `CLAUDE.md`). Do not drift into P1+ work. +- Check `CLAUDE.md` for the live scope state. As of this writing P0–P3 and P4 (skill + mode) are complete; confirm there before assuming anything is in or out of scope. diff --git a/docs/SPEC.md b/docs/SPEC.md index e85e87d..1ffd218 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -19,6 +19,12 @@ and loops until the change passes or it honestly reports that it could not. The name maps the five agents to the five Pandava brothers (see §3). The hierarchy is encoded for free: the orchestrator is the eldest brother the others obey. +**Two ways to run it (see §12).** *Standalone* — `python -m pandavas run`, a LangGraph +orchestrator driven by pandavas's own LLM client and API key (the CI-able reference). +*Skill mode* — a keyless `/pandavas` command inside a coding harness (Claude Code, +Cursor) where the host harness's model plays the LLM agents and deterministic CLI +verbs own the gates. Both modes share one deterministic core. + **What pandavas is not** — see §11 Non-Goals. Read that section before assuming a capability. @@ -46,6 +52,10 @@ capability. `did not converge`, with the remaining failures surfaced for the user to finish. It is never presented as success. +In **skill mode (§12)** the same loop runs, but the host harness's model performs the +Research / Worker / Judge steps while the orchestrator's deterministic decisions are +CLI verbs the host calls via the shell. + --- ## 3. Agents @@ -234,7 +244,8 @@ to *acceptance* — the correct contract for an autonomous coding agent. - **Budget:** zero. Free inference tiers (e.g. Groq / Gemini free tiers); optional OpenRouter for model choice. The **client supplies their own API keys** via `.env`. Ship `.env.example` only; gitignore the real `.env`; **no hardcoded - machine paths** (no `D:\...`, no `C:\Users\...`). + machine paths** (no `D:\...`, no `C:\Users\...`). In **skill mode (§12) there is no + API key at all** — inference runs on the host harness's own model. - **Dev environment:** Windows. - **Delivery:** public repo; the client clones it and runs with their own keys. - **Scope:** repositories the user already has locally. @@ -243,8 +254,8 @@ to *acceptance* — the correct contract for an autonomous coding agent. ## 10. Phase Plan -> **P0 is the ONLY currently in-scope phase.** Do not implement P1–P3 until the -> scope lock in `CLAUDE.md` is explicitly lifted. +> **Status: P0–P3 and P4 (skill mode) are COMPLETE.** The phase plan below is kept as +> the historical roadmap; `CLAUDE.md` holds the live scope state. - **P0 / v0 (IN SCOPE)** — Skeleton first, muscle later. - Deterministic **executor**: detect + run the local test command, capture @@ -260,6 +271,10 @@ to *acceptance* — the correct contract for an autonomous coding agent. full convergence / oscillation / cap logic. - **P3** — Reproducibility hardening, no-tests robustness, multi-language detection, CLI/UX, client setup docs. +- **P4 — Skill mode (keyless).** Expose the deterministic core as CLI verbs and ship a + `/pandavas` command + skill for Claude Code and Cursor, so the system runs with no + API key on the host harness's model. Strictly additive — the standalone `run` path + is unchanged. Full design in §12. --- @@ -273,3 +288,57 @@ to *acceptance* — the correct contract for an autonomous coding agent. - **Does not guarantee a fix exists** for every task — it reports honest failure rather than faking success. - **Not a multi-repo / org-wide tool** — one local repo per run. + +--- + +## 12. Skill Mode (keyless, in-editor) + +An **additive** second way to run the system, with **no API key**: a `/pandavas` +command installed into a coding harness (Claude Code, Cursor). It does not replace +standalone `run`; both share the same deterministic core, and `run` stays the CI-able +hard-determinism reference. Operational detail lives in [`SKILL_MODE.md`](SKILL_MODE.md); +this section records the design decision. + +### 12.1 The split across the process boundary + +A subprocess cannot borrow the harness's model, so skill mode does not run the agents +as a subprocess. The work is split instead: + +- **The host harness's model owns the LLM-shaped steps** — Nakula (research), Arjuna + (worker), Sahadeva (the judge's reasoning). +- **The deterministic decisions stay in pandavas's Python**, exposed as LLM-free CLI + verbs the host calls via the shell: the resolve gate, the regression-aware test + verdict (Bhima), oscillation, the iteration cap, best-attempt restore, and git + delivery (Yudhishthira's control logic). + +The model is the hands and eyes; the verbs are the rules. The verbs reuse the exact +functions `run` is CI-tested against, so a fix delivered in skill mode is gated by the +same regression-aware logic. + +### 12.2 Verbs and state + +Verbs (`src/pandavas/spine.py`): `baseline`, `resolve-brief`, `run-tests`, +`judge-gate`, `decide`, `diff`, `restore`, `commit`, `apply-edits`. Each prints one +ASCII JSON line and sets a process exit code the host branches on (0 ok / converged, +10 continue, 20 stop, 30 judge auto-reject, 1 error). State persists between the +stateless verb calls in a gitignored `.pandavas/` directory under the target repo; +`decide` is the sole writer of the loop state and recomputes diffs / signatures from +snapshots, so a fabricated model diff cannot game the loop. + +### 12.3 Fresh-context judge, per harness + +Behind the deterministic `judge-gate`, **Claude Code** spawns a `pandavas-judge` +**subagent** with only the acceptance criteria, the cumulative diff, and the +still-failing tests — genuine fresh context (§3.5). **Cursor** has no equal subagent +primitive, so the judge degrades to a fresh-pass self-review in shared context +(honestly weaker). The deterministic gates are identical on both harnesses. + +### 12.4 Honest limitation — soft vs. hard determinism + +In standalone `run`, the process calls Yudhishthira unconditionally; the gates cannot +be skipped. In skill mode the host model must *choose* to call the verbs and *obey* +their exit codes — it cannot be structurally forced. Mitigations: the skill's Iron Law +and mandatory procedure, a proof step that pastes real exit codes, `commit` gated +behind `decide` exit 0 plus human approval, and `decide` recomputing from snapshots. +**`python -m pandavas run` remains the hard-determinism contract; `/pandavas` is the +keyless ergonomic path.** diff --git a/examples/demo.py b/examples/demo.py index fbf73fd..d1f2c3a 100644 --- a/examples/demo.py +++ b/examples/demo.py @@ -1,7 +1,7 @@ """Standalone demo: a real red -> green fix on the sample fixture. Run with `python examples/demo.py`. The worker here is a scripted demo (it -hardcodes the fix), NOT a real agent — the real worker arrives in P1. +hardcodes the fix), NOT a real agent — the real LLM worker (Arjuna) runs in standalone `pandavas run` and in skill mode. """ import shutil diff --git a/src/pandavas/cli.py b/src/pandavas/cli.py index 7e1d4ab..c7a4ddc 100644 --- a/src/pandavas/cli.py +++ b/src/pandavas/cli.py @@ -1,7 +1,8 @@ """Command-line entrypoint for pandavas. -Exposes a single `run` subcommand that drives the orchestrator loop and prints an -ASCII-only run report (Windows-first). With --offline the stub research/worker/ +Exposes the `run` subcommand that drives the standalone orchestrator loop and prints +an ASCII-only run report (Windows-first), plus the keyless skill-mode verbs wired in +from `spine.py` (`baseline`, `run-tests`, `decide`, ...; see `docs/SKILL_MODE.md`). With --offline the stub research/worker/ judge nodes are injected so no LLM (and no API key) is needed -- useful for an install/wiring check; the real executor still runs the tests. On a converged real run it can also commit the change to a new git branch.