Skip to content
Open
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ something that will not fit.
|---|---|
| [`SimLoop/`](SimLoop) | The library. The only thing that is published. |
| [`simloop-starter/`](simloop-starter) | The folder teams copy: the build settings, and the example robot. |
| [`simloop-agents/`](simloop-agents/README.md) | An optional toolkit for teams programming with an AI agent: a portable `AGENTS.md`, four skills, prompts, and notes on cost. Markdown only — no build file reads it, and deleting it changes nothing. |
| [`simloop-agents/`](simloop-agents/README.md) | An optional toolkit for teams programming with an AI agent: a portable `AGENTS.md`, five skills, prompts, and notes on cost. Markdown only — no build file reads it, and deleting it changes nothing. |
| [`examples/`](examples/build.gradle) | A Gradle module with no sources of its own — it compiles the starter folder and runs its tests, so the thing teams copy cannot rot. Never published. |
| [`docs/landing-site/`](docs/landing-site/README.md) | The page that fronts `libraries.horizon36596.org`. Nothing builds it; it belongs in the `Horizon-36596.github.io` repository and is kept here so it is version-controlled somewhere. |

Expand Down
4 changes: 2 additions & 2 deletions SimLoop/docs/agents.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Using SimLoop with an AI agent

SimLoop ships a toolkit for teams who want to program with an AI coding agent: a context file that
teaches any agent how the library works, four skills for the jobs that come up, prompts to start from,
teaches any agent how the library works, five skills for the jobs that come up, prompts to start from,
and notes on spending less.

It lives in [`simloop-agents/`](https://github.com/Horizon-36596/simloop/tree/main/simloop-agents) in the
Expand Down Expand Up @@ -31,7 +31,7 @@ Horizon uses **Claude Code**; its paths are the ones the team has exercised most
| File | What it is |
|---|---|
| `AGENTS.md` | The library overview, API inventory, simulation rules and test structure. Copy it to your repository root and add your robot's details. |
| `skills/` | Four procedures — write a sim test, add a mechanism, debug a failing sim, review sim code. Written for any agent; drop into `.claude/skills/` unmodified. |
| `skills/` | Five procedures — write a sim test, add a mechanism, debug a failing sim, review sim code, and run the edit-replay-score loop (`run-loop`, started by hand only). Written for any agent; drop into `.claude/skills/` unmodified. |
| `prompts/` | Copy-paste starting points, including one for learning and one for auditing your tests before a competition. |
| `pointers/` | One-line files for the tools that need a nudge, and for a project that already has its own instructions file. They point at `AGENTS.md` rather than copying it. |
| `token-savers.md` | Ways to keep context focused and compare usage without assuming fixed savings. |
Expand Down
2 changes: 1 addition & 1 deletion SimLoop/docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ it does **not** do is on [What it does not do](limits.md).

- A portable `AGENTS.md` that teaches an agent the library, the complete public API and the rules it gets wrong. [Using SimLoop with an AI agent](agents.md)
- Works with any coding agent: Cursor, Codex, Gemini CLI, Copilot's coding agent and others read `AGENTS.md` with no setup. Claude Code is the best-tested route. [Which tool](agents.md#which-tool)
- Four skills: write a sim test, add a mechanism, debug a failing sim, review sim code. [What is in the folder](agents.md#what-is-in-the-folder)
- Five skills: write a sim test, add a mechanism, debug a failing sim, review sim code, and run the edit-replay-score loop. [What is in the folder](agents.md#what-is-in-the-folder)
- Prompts to start from, including one for learning and one for auditing your tests before a competition. [What is in the folder](agents.md#what-is-in-the-folder)
- A flat index of these pages for agents. [Index for AI agents](llms.md)
- **Planned, not in this alpha:** give an agent your own robot's logs and it tunes the sim to match your robot.
Expand Down
2 changes: 1 addition & 1 deletion SimLoop/docs/llms.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ generated API reference before calling an API newer than your pinned tag.
| [Making your timers sim-safe](sim-safe-timers.md) | Why `ElapsedTime`, `sleep` and `System.nanoTime()` read the wrong clock in a sim, and the change that fixes each. | Timer code you can change. |
| [Running your timer code unchanged](unchanged-team-code.md) | `OpModeRunner.forTeamClass(...)`: build setup, what it rewrites, every warning and error message. | Timer code you cannot change. |
| [RUN_TO_POSITION in the sim](run-to-position.md) | What is exact (the SDK side) and approximate (hub firmware) in `FakeMotor`'s closed loops. | Using `RUN_TO_POSITION` or `setVelocity`. |
| [Using SimLoop with an AI agent](agents.md) | The `simloop-agents/` toolkit: a portable `AGENTS.md`, four skills, prompts, token notes — and the rules an agent most often gets wrong. | A team is setting up agent-assisted development, or you are one. |
| [Using SimLoop with an AI agent](agents.md) | The `simloop-agents/` toolkit: a portable `AGENTS.md`, five skills, prompts, token notes — and the rules an agent most often gets wrong. | A team is setting up agent-assisted development, or you are one. |
| [Troubleshooting](troubleshooting.md) | Failures that read like a robot-code bug and are not. | A build or run failed. |
| [Reporting a bug](support.md) | Where issues go, and what a complete report contains. | Filing something. |

Expand Down
5 changes: 3 additions & 2 deletions simloop-agents/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Programming SimLoop with an AI agent

A toolkit for teams who want to use an AI coding agent on their robot code: a context file that teaches
any agent how SimLoop works, four skills for the jobs that come up, prompts to start from, and notes on
any agent how SimLoop works, five skills for the jobs that come up, prompts to start from, and notes on
not spending more than you need to.

The toolkit is optional Markdown. No build file reads it, and removing it does not affect SimLoop.
Expand Down Expand Up @@ -62,6 +62,7 @@ your-ftc-project/.claude/skills/write-a-sim-test/SKILL.md
your-ftc-project/.claude/skills/add-a-mechanism/SKILL.md
your-ftc-project/.claude/skills/debug-a-failing-sim/SKILL.md
your-ftc-project/.claude/skills/review-sim-code/SKILL.md
your-ftc-project/.claude/skills/run-loop/SKILL.md
```

They are picked up automatically — no install step — and because they live in your repository, everyone
Expand All @@ -80,7 +81,7 @@ agent has loaded both the SimLoop guidance and your robot-specific instructions.
| File | What it is |
|---|---|
| [`AGENTS.md`](AGENTS.md) | The library overview, API inventory, simulation rules and test structure. Copy it to your repository root and add your robot's details. |
| [`skills/`](skills) | Four procedures: write a sim test, add a mechanism, debug a failing sim, review sim code. Written for any agent; drop straight into `.claude/skills/` unmodified. |
| [`skills/`](skills) | Five procedures: write a sim test, add a mechanism, debug a failing sim, review sim code, and run the edit-replay-score loop (`run-loop`, started by hand only). Written for any agent; drop straight into `.claude/skills/` unmodified. |
| [`prompts/`](prompts/README.md) | Copy-paste starting points, including one for learning and one for auditing your tests before a competition. |
| [`pointers/`](pointers) | One-line files for the tools that need a nudge, and for a project that already has its own instructions file. Deliberately thin — they point at the one copy rather than duplicating it. |
| [`token-savers.md`](token-savers.md) | Ways to keep context focused and compare usage without assuming fixed savings. |
Expand Down
140 changes: 140 additions & 0 deletions simloop-agents/skills/run-loop/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
name: run-loop
description: >-
Run SimLoop's goal-optimization loop on a team's robot code: propose one edit, replay the scenario
deterministically, score it, pass it through the acceptance gate, and keep the last-best WORKING
version until the user stops it. Use only when the user starts it with /run-loop to optimize a
robot-code goal (a faster or more reliable auto, a lower loop time, a better-tuned mechanism). It
edits code, so it never starts on its own.
disable-model-invocation: true
allowed-tools: [Read, Grep, Glob, Edit, Write, Bash, Agent]
---

# run-loop

An edit, replay, score, gate loop for FTC robot code, built on SimLoop's `loop` package
(`org.horizon36596.simloop.loop`, SimLoop `v0.2.0-alpha.2` or later). **It changes code: start it
deliberately.** Package reference: `SimLoop/docs/packages/loop.md` in the SimLoop repository.

## The engine: use it, don't re-derive it

| What | Class | What it does |
|------|-------|--------------|
| A finished run | `RunResult` | reads an `.rlog` back through decoded fields |
| What we're optimizing | `Objective` | metric + direction + scenario + budget; MINIMIZE is negated in one place, so bigger is always better |
| One envelope term | `Guardrail`, `EnvelopeGuardrails` | `HOLDS` / `VIOLATED` / `OVER_BUDGET` / **`UNKNOWN`** |
| The number | `Scorer` | `objective − Σ penalties`, returned as a breakdown, not a bare double |
| The decision | `Gate` | the four acceptance clauses below, every one reported every time |
| The bookkeeping | `LoopDriver` | owns one fixed `Scorer`, starts from a baseline run, scores every offered run itself, holds last-best, emits `Milestone`s, writes the `StopReport` |

**What stays yours, every iteration.** The engine deliberately does none of this:

1. **Propose the edit.** `LoopDriver` has no method for it, by design: a referee that picks what it
referees would be judging its own work.
2. **Run Gradle.** SimLoop never shells out. Run the team's test command and read the result.
3. **Hand the gate the two facts it cannot measure.** `Gate.SuppliedFacts` takes tests-green and
review-passed as a tri-state, with no default. Pass `Gate.Fact.NOT_CHECKED` when you did not run one;
it blocks, which is correct. **Never pass `CONFIRMED_TRUE` for a check you did not actually run.**
That is the one lie the whole structure exists to prevent.
4. **Supply a `StopReport.ScenarioReplayer`** to `LoopDriver.stopReport(...)`. A `RunResult` is a
finished log and does not carry the config that produced it, so only you can run it again.
5. **Write the objective and the envelope**, and get the human to confirm them (Intake, below).

**Engine behaviours to know before they surprise you:**
- **A candidate hands in a run, never a score.** `LoopDriver` is built with the `Scorer` and a baseline
run of the unedited code; `offer(description, run, facts)` scores the run itself. The baseline needs
both facts `CONFIRMED_TRUE` (tests ran green on the unedited code, and the human agreed it is the
starting point), or the constructor throws. The first candidate must beat the baseline. A run the
objective cannot measure (missing key, non-number, NaN) is a rejected candidate, not a crash.
- **Milestones are measured from the last milestone**, so small accepted gains add up to one.
- **Don't put `EnvelopeGuardrails.notAnswerableFromALog()` in the envelope.** Those terms are always
`UNKNOWN`, so they block every candidate. Tests-green is the gate's own clause instead.
- **`UNKNOWN` blocks.** A guardrail nobody could evaluate rejects the candidate. Don't drop the
guardrail to get past it.
- **An empty envelope also blocks**, as `UNKNOWN`. Deleting guardrails to make the envelope stop
objecting is the cheapest reward hack there is, and the gate refuses it by name.
- **The stop report reproduces before it reports.** It replays the best candidate a second time and
compares decoded fields; on a mismatch `reportedScore()` throws and the report says determinism failure.
Never quote `unreproducedScoreForDiagnosis()` as a result.

## Intake (before the first edit)

1. **Objective.** Set by the human, or proposed by you and confirmed by the human. Capture:
- **metric:** a decoded RLOG field, e.g. the time the auto's last scoring action finished, the path's
maximum cross-track error, or the mean loop period. Score decoded numeric fields, never raw log bytes.
- **direction:** maximize or minimize.
- **scenario:** which OpMode or routine, and which seeds or starting positions. Prefer several (both
alliances, a few seeds) so the loop cannot overfit one lucky replay.
- **budget:** the human's rough time or token estimate. It sets how often milestones come, nothing else.
2. **Envelope.** Invariants that must hold whatever the implementation. The loop optimizes **inside**
them and may **never** disable one to score higher. A starter set; extend it, never shrink it without
the human's review:
- the team's invariant tests are green;
- no actuator is commanded past its end-limit or configured bound;
- the robot stops safely on disable and OpMode end;
- no NaN or Inf in pose, velocity or any control output;
- the run is complete (a frame per tick) and actually did the task (an auto that skips scoring is not
"faster");
- nothing actuates real hardware unless the same code already passed in the sim.

Envelope terms are **invariants, not implementation facts.** "`kP > 0`" is not an envelope term: it
would block a legitimate swap from a PIDF controller to a motion profile.

**Two test tiers.** Invariant tests belong to the envelope and are never retired. Implementation tests
pin the current design; the loop may propose replacing one, but only as part of a redesign that a
fresh-context reviewer approves, confirming the new tests pin the new design's contract.

## The loop: repeat until the user stops it, and always leave last-best working

1. Propose **one** edit toward the objective.
2. Run the tests, then replay the scenario deterministically; read the `RunResult`s.
3. `offer` it. The **gate** accepts only if ALL hold:
1. tests green (invariant tier always; implementation tier unless legitimately retired);
2. the envelope holds, with no `VIOLATED` or `UNKNOWN` term;
3. `score(candidate) > score(last-best)` on the declared scenario, same scenario only;
4. a fresh-context review of the diff and any test changes passed (a subagent that did not write
the edit).

Fail any: discard the edit and restore the last-best code. Last-best stands.
4. Accepted: it becomes last-best. When the best improves past a threshold, or a new working capability
lands, write a **milestone** (format below). Milestones are where gaming becomes visible and where
rollback points live.

## Stop

On stop, call `stopReport(replayer)` and report **last-best** with its reproduced score and the milestone
trail. Never leave a half-applied edit.

## Milestone format

```
MILESTONE <n>: <one line on what changed>
objective: <metric> <before> -> <after> (<scenario, seeds>)
why: <the reason it is better>
envelope: <every term HOLDS; list them>
review: <who reviewed, findings>
rollback: last-best before this = MILESTONE <n-1> (commit <ref>)
```

Commit at each milestone, so every one is a working version to roll back to.

## Worked example: "fastest reliable auto"

- Objective: the auto's finish time (decoded RLOG field), minimized. Scenario: the auto on both
alliances, seeds 0-4. Envelope: the starter set, plus "scored the target count on every seed".
- Edit 1: tighten a path waypoint. 0.3 s faster, all gates pass: new last-best, below the milestone
threshold.
- Edit 2: raise the drive velocity cap. Faster on paper, but 2 of 5 seeds miss a shot, so the
"scored the target count" term is `VIOLATED`: **discarded**. This is the reward hack the envelope
exists to block.
- Edit 3: reorder two scoring actions so the shooter spins up during travel. 0.6 s faster, every seed
still scores, review passes: new last-best and **milestone**.

## Guards

- **Reward hacking:** never optimize a bare metric. Anything you would hate to lose goes in the
envelope, not a soft penalty. Reject runs with missing or short logs ("win by not logging").
- **Sim before robot:** no live-hardware actuation until the same code passed in the sim.
- **The sim is not the robot:** a sim gain is a hypothesis until it is checked on the real robot.
SimLoop is an alpha, and its physics has not yet been compared with a real robot.
- **Overfitting:** prefer several seeds and both alliances over one replay.
Loading