Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,24 @@ evals/*
!.github/workflows/*.yml
!templates/
!templates/*
!skills/
!skills/*
!skills/*/*
!scripts/
!scripts/*
!spec-kit-bridge/
!spec-kit-bridge/*
!spec-kit-bridge/*/*
!studio/
!studio/*
!studio/assets/
!studio/assets/*
!.markdownlint.json
!evals/*.yaml
!evals/*.py
!evals/llm-judge/
!evals/llm-judge/*
!evals/llm-judge/*/*
!agent-harness/
!agent-harness/*
!memory-layer-spec.md
223 changes: 189 additions & 34 deletions README.md

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions agent-harness/EVALUATOR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# EVALUATOR.md — The Third Role ⚖️

> The evaluator is a **separate agent/session** from the coder.
> Same repo, same PROGRESS.md — different hands, different eyes.
> Its job is not to grade effort. Its job is to **test the live app and kill
> self-grading bias**.

## When the evaluator runs 🔁

After the coder finishes an iteration (or after the final feature), the
evaluator gets a fresh session with the same PROMPT discipline — but a
different mission: **prove the app works, or prove it doesn't.**

```
1. READ <run-dir>/PROGRESS.md (context) — but TRUST NOTHING in it.
2. START the app yourself (docker / npm / python / whatever FEATURES.md says).
3. TEST the newly-built feature against its native-tongue assertions —
the real UI, the real API, the real binary. Click it. Curl it. Break it.
4. RUN the full test suite. Note every failure with terminal evidence.
5. WRITE eval/eval-<NN>.md with: verdict, evidence, reproduction steps.
6. UPDATE state.json: append to `evaluations`, set phase to
"evaluating" (→ coder gets another shot) or "done".
```

## The checklist ✅

| # | Check | How | Pass bar |
|---|-------|-----|----------|
| 1 | **It runs** | Fresh clone / fresh shell, follow the documented start command | Zero manual patching needed |
| 2 | **Feature works live** | Exercise the actual feature, not the demo path | Matches FEATURES.md acceptance criteria |
| 3 | **No regressions** | Full test suite green | Previously-✅ features still work |
| 4 | **Precision compliance** | Read the diff of the iteration | No placeholders, no TODOs, no hardcoded secrets |
| 5 | **State honesty** | Diff PROGRESS.md claims vs what you observed | Every claim backed by evidence, or flagged |

## Verdicts 🎯

- **✅ PASS** — ship it. Next coder iteration takes the next feature.
- **🔁 RETRY** — real bugs found. Send back to coder with the eval report
attached. Coder fixes ONLY what the report lists.
- **❌ FAIL** — iteration cap hit, or the feature is unfixable in this
design. Record in FEATURES.md + PROGRESS.md; the loop stops for humans.

## Hard iteration caps ⛔

| Limit | Value | Why |
|-------|-------|-----|
| Max coder iterations per run | **10** | Bounded cost; 10 full sessions is enough to ship or to learn |
| Max retries per single feature | **3** | A feature that fails 3 evals is a design problem, not a bug |
| Max consecutive coder failures | **2** | Two dead sessions in a row → pause the loop, human reviews |

These caps live in `state.json` (`max_iterations`). Hitting any cap sets
`phase: "done"` and the loop stops — **the evaluator never negotiates with itself.**

## Stop conditions 🛑

Stop the whole loop when ANY of these is true:

1. All FEATURES.md items are ✅ DONE and the final eval is ✅ PASS.
2. An iteration cap above is hit (record why, then stop).
3. The evaluator finds the mission itself is wrong (wrong product, wrong
stack) — this is a human decision, never an agent override.
4. Cost/time budget exhausted (set your own before starting; write it in
PROGRESS.md mission brief).

## The anti-bias rule 🛡️

The coder's session log is **evidence input, not a grade**. The evaluator's
verdict comes only from what the evaluator's own hands observed on the live
app. If the coder wrote "tested ✅" and the app crashes on boot, the verdict
is ❌ FAIL — and the discrepancy itself goes in the eval report. That's the
whole point of the third role.

## Eval report template 📄

```markdown
# eval-<NN> — <feature name> — <date>

**Verdict:** ✅ PASS | 🔁 RETRY | ❌ FAIL
**Iteration tested:** <N>
**Coder claims (from PROGRESS.md):** <quote them>

## Evidence
- <terminal output / screenshot / curl result — real artifacts>

## Reproduction
1. <exact steps to reproduce any failure>

## Sent back to coder (if RETRY)
- <precise, minimal fix list — nothing else>
```
39 changes: 39 additions & 0 deletions agent-harness/PROGRESS-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# PROGRESS — Ralph-loop run state contract

> ⚡ **READ THIS FIRST, every session.** This file is the coder's ground truth.
> Whatever is here is what happened. The coder updates it before stopping.
> The evaluator never trusts it — the evaluator tests the LIVE app.

- **Run name:** {{RUN_NAME}}
- **Started (UTC):** {{STARTED_UTC}}
- **Mission:** _(one-line goal — edit me during initialization)_
- **Current iteration:** 0
- **Max iterations:** 10
- **Current phase:** `initialized` (initialized → coding → evaluating → done)

## 🎯 Mission brief

_(2–4 sentences: what we are building, who it's for, what "done" looks like.)_

## ✅ Completed features

- _(none yet)_

## 🔨 In-progress feature

- _(none yet — topmost ⬜ in FEATURES.md)_

## 📋 Decisions & constraints

- _(architecture choices, libraries, ports — anything a future session must not re-derive)_
- _(example: "API on port 3100, SQLite at data/app.db — don't move them")_

## ⚠️ Known issues / debt

- _(anything half-broken the next session must know about)_

## 📓 Session log (append, newest last)

### Iteration 0 — initialization

- `{{STARTED_UTC}}` — Run scaffolded by init.sh. FEATURES.md checklist pending.
58 changes: 58 additions & 0 deletions agent-harness/PROMPT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# PROMPT.md — The Fixed Mission Prompt ⚡

> This is the **one prompt** that starts every Ralph-loop session.
> Fixed, versioned, unchanging. The mission changes (FEATURES.md);
> the discipline doesn't. When the loop is finished, THIS is what you hand
> to the coder at the top of a fresh session or a fresh agent.

---

## The prompt (copy-paste into your coding agent)

```text
***[AgentName] (RTX⚡)*** — Ralph-loop session start.

You are the CODER in an RTX Ralph-loop harness (see agent-harness/README.md).

1. READ <run-dir>/PROGRESS.md completely. That file is the ground truth —
what is there is what happened. If it says a feature is DONE, it is done.
Do NOT re-derive architecture, do NOT re-plan from scratch.

2. OPEN <run-dir>/FEATURES.md. Take the TOPMOST feature still marked ⬜ TODO.
Mark it 🔨 IN PROGRESS in FEATURES.md. You build exactly ONE feature this session.

3. BUILD it — production-grade, no placeholders, no TODO comments left behind.
Follow the repo's Precision Protocol: native-tongue assertions first,
then code. Run every relevant test. If tests don't exist, write the
critical ones for your feature.

4. VERIFY against real evidence: terminal output, test results, screenshots —
never your own summary of what "should" work. If it doesn't run, it doesn't ship.

5. UPDATE, in this order, before you stop:
a. FEATURES.md — flip your feature to ✅ DONE (or ❌ FAILED + note).
b. PROGRESS.md — append a session-log entry: what was built, files changed,
test evidence, any new decisions or known issues.
c. state.json — bump `iteration`, set `current_feature`, `phase: "coding"`.

6. STOP after one feature. Do not reach for the next one. The EVALUATOR goes next.

Hard rules:
- Never break a DONE feature to build a new one. Regression = failure.
- If you are stuck for more than 3 consecutive failed attempts at the same
error, write the blocker in PROGRESS.md and STOP. The loop will route you.
- Language: RTX Universal Output Protocol applies to everything you report.
```

---

## Why fixed? 🤔

Long-running autonomous builds fail when every session re-derives the mission
from scratch — that's the "agentic drift" the recon measured (sessions
re-architecting each other into incoherence). A fixed mission prompt plus an
on-disk state contract means:

- **Session N+1 starts where session N stopped** — no re-planning tax.
- **One feature per session** — bounded blast radius, reviewable diffs.
- **The evaluator can't be gamed** — it tests the live app, not the prompt.
115 changes: 115 additions & 0 deletions agent-harness/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# 🤖 agent-harness/ — The RTX Ralph Loop

> **The X pillar, made executable.** Philosophy says *"Never stop until the
> goal is achieved"* — this directory is the machinery that actually does it:
> a fixed mission prompt, an initializer, a coder, and a separate evaluator,
> looping over an on-disk state contract until the build is done or the caps
> hit. Boss, ye sirf autonomy ki baat nahi — ye autonomy ka engine hai. ⚙️⚡

## The three roles 🔱

```
┌─────────────┐
│ INITIALIZER │ one-shot: ./init.sh <run-name>
│ (you) │ scaffolds run-<name>/{PROGRESS.md, FEATURES.md, state.json, eval/}
└──────┬──────┘
▼
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ CODER │──▶│ EVALUATOR │──▶│ CODER │──▶ ...
│ 1 feature / │ │ tests LIVE │ │ next │
│ session │ │ app, verdict │ │ feature │
└─────────────┘ └──────────────┘ └─────────────┘
each session starts with PROMPT.md + PROGRESS.md
```

1. **Initializer** — runs `init.sh` once. Fills in FEATURES.md. Sets the
iteration caps in `state.json`. Human (or orchestrator) job, takes minutes.
2. **Coder** — autonomous agent session. Reads PROGRESS.md, builds the ONE
topmost ⬜ TODO feature, updates all three state files, stops.
Mission prompt: **PROMPT.md** (fixed — never improvised).
3. **Evaluator** — a *separate* agent/session from the coder. Tests the LIVE
app against the feature's assertions, writes `eval/eval-<NN>.md`, and
issues ✅ PASS / 🔁 RETRY / ❌ FAIL. Kills self-grading bias: the coder's
claims are evidence input, never the grade.

## Quick start 🚀

```bash
# 1. Initialize the run
./init.sh my-app

# 2. Edit the mission + features
nano run-my-app/FEATURES.md # list features, one per row
nano run-my-app/PROGRESS.md # write the mission brief

# 3. Start the loop: hand PROMPT.md to your coding agent
# (paste PROMPT.md at the top of a fresh session, point it at run-my-app/)

# 4. After each coder session, run the evaluator (separate session):
# "You are the EVALUATOR (agent-harness/EVALUATOR.md). Test run-my-app."

# 5. Repeat coder → evaluator until all features ✅ + final eval PASS,
# or an iteration cap stops the loop.
```

## The state contract 📁

| File | Who writes | Who reads | Purpose |
|------|-----------|-----------|---------|
| `PROGRESS.md` | coder (append-only log + status) | coder, evaluator, human | Living ground truth of the run |
| `FEATURES.md` | initializer (list), coder (ticks) | coder, evaluator | One-feature-per-row checklist |
| `state.json` | coder, evaluator | tooling, orchestrator | Machine-readable: iteration, phase, caps, eval history |
| `eval/eval-<NN>.md` | evaluator only | coder (on RETRY), human | Verdicts with real evidence |

## Worked mini-example 🧪

Mission: a CLI todo app (`todo` command, JSON storage).

```bash
./init.sh todo-cli
# ✅ RTX run initialized: ./run-todo-cli
```

`run-todo-cli/FEATURES.md`:

| # | Feature | Status | Notes |
|---|---------|--------|-------|
| 1 | `todo add "task"` writes to todos.json | ✅ DONE | eval-01 PASS |
| 2 | `todo list` prints numbered tasks | ✅ DONE | eval-02 PASS |
| 3 | `todo done <n>` marks complete | 🔨 IN PROGRESS | coder session 3 |
| 4 | `todo rm <n>` deletes a task | ⬜ TODO | |

**Session 3 (coder):** reads PROGRESS.md → sees features 1–2 DONE, picks
feature 3 → implements `todo done` → runs tests → updates FEATURES.md (✅),
appends session log to PROGRESS.md → stops.

**Evaluator session:** boots the real CLI, runs `todo add` / `todo done 1` /
`todo list` against a scratch file → writes `eval/eval-03.md`:

> **Verdict:** 🔁 RETRY — `todo done 99` on an empty list prints `undefined`
> instead of an error. Evidence: `$ todo done 99` → `undefined`.

**Session 4 (coder):** reads eval-03, fixes only the reported bug, re-runs
tests, updates state. **Session 5 (evaluator):** PASS → feature 4 unlocked.

The loop ends when feature 4 passes eval, or `max_iterations: 10` is hit —
whichever comes first. No vibes, no drift, no "trust me it works". ⚡

## Design rules (non-negotiable) 🛡️

- **One feature per session.** Bounded blast radius, reviewable diffs.
- **The evaluator never trusts PROGRESS.md.** It tests the live app.
- **Caps are hard.** 10 iterations/run, 3 retries/feature, 2 consecutive
failures → human review. See EVALUATOR.md.
- **State files are append-mostly.** History is the memory; never rewrite it.
- **Artifacts over assertions.** Terminal output, test results, screenshots —
never the agent's self-report.

## Mapping to RTX 📖

| Harness piece | RTX section |
|---------------|-------------|
| PROMPT.md | ULTRON Agent (autonomous starter), Precision Protocol |
| init.sh / PROGRESS-template.md | Initialization & Boot Protocol |
| EVALUATOR.md | Universal Output Protocol (evidence rule), X pillar |
| The loop itself | Task Execution Workflow: Explore → Plan → Execute → Verify → Summarize |
Loading
Loading