Skip to content

Repository files navigation

star-loop — Patrick does the work. Sandy checks it.

An autonomous coding loop for Grok Build.

One fresh agent per iteration until the task is genuinely finished — and every claim of
"done" re-checked by a different agent that re-runs your test suite from scratch.

ci release runtime deps engine license

/star-loop Build a REST API for todos. CRUD, validation, tests. --max-iterations 20

No bash, no jq, no perl, no Python, no Node. The whole engine is one Rhai file, and Rhai is Grok's own scripting language — so there is nothing to install beyond the plugin and nothing to be incompatible with.


The cast

The loop is named for Patrick Star on the same logic that made Ralph Wiggum the mascot of the original technique — cheerful, relentless persistence, undamaged by failure. But Patrick has never once successfully marked his own homework, and that turns out to be the whole design.

Agent Runs Job
🔍 Recon once, first Read-only survey. Finds your real quality gates, checks the branch and tree, writes the plan. Changes nothing.
Patrick every iteration Implements exactly one unit of work. Fresh context every time — he remembers nothing, so the repo has to.
🔬 Sandy on every claim The scientist. Re-runs the gates herself, reads the diff, and tries to prove Patrick wrong. Has no stake in him being right.

Patrick is why the loop makes progress. Sandy is why you can believe it.


Why the second agent matters

Every other Ralph implementation lets the agent grade its own work. Anthropic's plugin ships a paragraph asking the model not to lie:

✓ Do NOT output false statements to exit the loop
✓ Do NOT lie even if you think you should exit

That is a request, not a control. An agent that has been failing for six iterations has every incentive to decide the tests "basically pass."

So star-loop doesn't ask. When Patrick claims something is finished, Sandy starts with a clean context and an adversarial brief:

  • re-runs every gate herself — a reported pass is exactly what she's there to falsify
  • reads git show HEAD and checks the diff does what was claimed in the source, not just in a test
  • hunts the specific ways loops fake success — tests deleted or .skipped, assertions loosened, snapshots regenerated instead of bugs fixed, stubs standing in for behaviour, gates that "passed" because they matched no files
  • confirms protected paths, secrets and history are untouched

A rejection is fed back verbatim to the next iteration, and the loop keeps going. Patrick is told up front that this happens — which is the point. It makes an honest complete=false the better move even for an agent optimising only its own scorecard.


How a run flows

flowchart LR
    R["<b>RECON</b><br/>read-only survey<br/><small>finds your real quality gates</small>"]

    subgraph LOOP ["one iteration, repeated"]
        direction LR
        P["<b>PATRICK</b><br/>implements ONE<br/>unit of work"]
        S["<b>SANDY</b><br/>re-runs the gates<br/>reads the diff"]
        P -->|"claims it's done"| S
        S -->|"rejected — fed back verbatim"| P
    end

    RPT["<b>REPORT</b><br/>stop reason<br/>+ journal"]
    H(["pause and ask you"])

    R ==> LOOP
    LOOP ==>|verified| RPT
    R -.->|"on main, or dirty tree"| H
    LOOP -.->|"3 iterations, no commit"| H

    classDef patrick fill:#EE8B6E,stroke:#D9714F,color:#3A2318
    classDef sandy fill:#5FA8A0,stroke:#3F8880,color:#08302C
    classDef halt fill:#8A93A6,stroke:#6B7382,color:#12151C
    class P patrick
    class S sandy
    class H halt
    style LOOP fill:#8A93A61A,stroke:#8A93A688,stroke-dasharray:4 4
Loading

Patrick's only memory is the filesystem: the working tree, git log, .star/journal.md, AGENTS.md, and prd.json. Context rot is real; git is not lossy.


What a run looks like

Condensed from an actual run against a repo whose test suite genuinely failed — one unimplemented function, five tests, three of them red. Log lines are verbatim; the verifier's evidence is trimmed:

$ /star-loop --prd --max-iterations 2

  star-loop starting — mode=prd max_iterations=2 verify=completion stall_after=3

  Gates discovered:
    python -m unittest discover -v

  Iteration 1/2 — budget remaining 7
    patrick-1   US-001 Implement multiply
    sandy-1     verifying the claim…

  Verified:
    Command: python -m unittest discover -v.  Exit 0.  Ran 5 tests — OK.
    calc.py: raise NotImplementedError -> return a * b.
    git diff HEAD^ -- test_calc.py  →  empty.  No skips/xfails, no loosened
    assertions, suite actually collected 5 tests.
    Reflog: normal commit, not amend/rebase.  No .env/credential files.
    Files in commit: .star/journal.md (A), AGENTS.md (A), calc.py (M), prd.json (M).

  star-loop completed after 1 iteration(s); 0 stories remaining

Sandy's line about git diff HEAD^ -- test_calc.py being empty is the one that matters. Nobody asked her to check that specific file — she went looking for tampering because that is her job, and reported the evidence either way.


Install

grok plugin marketplace add MrBeldum/star-loop
grok plugin install star-loop --trust

Or straight from the repo:

grok plugin install MrBeldum/star-loop --trust

That's the whole install. The /star-loop skill launches the workflow by path, so the version you run is always the version in the plugin.

Optional — register the workflow by name

To also launch it as /workflow star-loop, copy the script into your user workflows directory:

# Unix
cp workflows/star-loop.rhai ~/.grok/workflows/star-loop.rhai

# Windows PowerShell
Copy-Item workflows\star-loop.rhai $HOME\.grok\workflows\star-loop.rhai

Grok only discovers workflows from .grok/workflows/ and ~/.grok/workflows/, never from a plugin — which is why path-launching is the default.


Quick start

💬 Prompt mode

Run from the project root, on a working branch:

/star-loop Build a REST API for todos. CRUD, input validation, tests.
           --max-iterations 20 --completion-promise COMPLETE

The task never changes between iterations. The loop maintains a checklist at .star/plan.md, takes the first unticked item each time, implements it, runs the gates, commits, and ticks it. It finishes when every item is ticked and the gates pass on a clean tree.

📋 PRD mode

For anything bigger than one sitting, give it a real backlog:

/prd Add task priority        →  writes tasks/prd-task-priority.md
/star-prd                     →  converts it to prd.json
/star-loop --prd              →  works it story by story

One user story per iteration, lowest priority number first. A story flips to "passes": true only after its gates pass and Sandy agrees. Failures are written into that story's notes, so the next iteration starts informed rather than starting over.

See examples/prd.json.example.

🔍 Look before you leap

/star-loop --prd --dry-run

Recon only. Reports the branch, the gates it found, the backlog, an execution plan and the biggest risk it can see. Changes nothing, spends one agent.


Commands

Command What it does
/star-loop Start the loop — prompt mode or PRD mode
/star-status Where the loop got to, and whether the journal matches git
/cancel-star Stop the run — never touches your commits
/prd Interview, then write a loop-sized PRD
/star-prd Convert that PRD into prd.json

Note

/star-loop is not /loop — that's Grok's recurring scheduler.


Options

Flag Default Meaning
--max-iterations N 20 Hard cap 100. 0 means the cap.
--completion-promise TEXT Phrase that must be true inside <promise> tags to finish.
--prd / --prd-path PATH prd.json PRD mode.
--verify off|completion|every completion When Sandy runs.
--stall-after N 3 Iterations without verifiable progress before acting.
--on-stall pause|stop|continue pause What to do about it.
--gate off Pause after every accepted unit of work.
--gate-every N off Pause every N iterations.
--protect GLOB Paths the loop must not modify. Repeatable.
--allow-default-branch off Permit running on main/master.
--allow-dirty off Permit starting with modified tracked files.
--allow-push off Permit git push. Never --force, ever.
--skip-recon off Skip the read-only survey.
--dry-run off Plan only. Changes nothing.
--agent-budget N auto Grok's own cap on total child agents.

JSON works too, for scripting or /workflow:

/workflow star-loop {"prompt":"Fix the flaky auth tests","max_iterations":10,"verify":"every"}

Every argument is documented in examples/args.json.example.


What one iteration actually does

  1. A fresh agent starts with no memory of the last one. Its memory is the working tree, git log, .star/journal.md, AGENTS.md, and prd.json in PRD mode.
  2. It picks one unit of work — the next plan item, or the highest-priority unpassed story. One. Not three half-finished ones.
  3. It searches before it writes, because re-implementing something the repo already has is the most common way an iteration is wasted.
  4. It runs the gates recon discovered. It may not weaken, skip, or delete a test to make them pass.
  5. Gates pass → commit, tick the item, append to the journal.
    Gates fail → no commit, no passes: true, write down what was tried and what was ruled out. A failed iteration that records a dead end is useful. A false pass is not.
  6. If it claims completion, Sandy verifies before the loop accepts it.

The journal is the part people underestimate. It's why iteration 11 doesn't re-litigate what iteration 4 already ruled out.


Safety

An autonomous loop that commits on its own needs boundaries, so these are defaults rather than options:

Boundary
🌿 Branch isolation. Refuses to start on main, master, develop, trunk, dev, or the detected default branch.
🧹 Clean start. Refuses to start with modified tracked files, so its work stays distinguishable from yours.
📌 Explicit staging. No git add -A, git add . or git commit -a. Stray untracked files cannot be swept into a commit.
🚫 No pushing. No git push unless you pass --allow-push. No --force, ever.
🕰 No history rewriting. No reset --hard, rebase, checkout ., clean -fd.
🔑 No secrets. Never reads, writes, commits or prints .env*, credentials, tokens or keys. A task that appears to need one is reported blocked.
🛡 Protected paths. --protect marks paths off-limits, and Sandy checks they weren't touched.
♻️ Cancelling never destroys. /cancel-star stops the run and leaves every commit and branch where it is. Unwinding is your call, with the diff in front of you.

Stopping

Outcome Cause
complete Everything done, gates pass, Sandy agrees
🌀 stalled No verifiable progress for --stall-after iterations
blocked Genuinely needs a human — missing credentials, contradictory requirements
🔢 max-iterations Hit the cap
💰 budget Grok's agent budget ran out

Each writes a report naming the stop reason, what was accepted, what Sandy rejected, and what remains. /workflow pause star-loop, resume and stop work throughout; a paused run keeps its place.


Writing a task the loop can finish

The model matters less than the prompt. In rough order of impact:

Give it a way to know it's done. "Make the app better" runs until the iteration cap. "All four endpoints return the documented shape and pnpm test passes" terminates.

Give it gates. A loop with no tests can't verify itself and neither can Sandy. If the project has none, the honest first task is adding them.

Size the work. An iteration is one context window. "Add authentication" is not one iteration; "add the users table and its migration" is. Oversized work is the most common cause of a stalled run — it fails, gets picked up again, and fails the same way.

Say what's out of bounds. --protect, and a sentence about what not to touch, is cheaper than reviewing what it did touch.

Let it fail honestly. A blocked report after three iterations is worth more than fifteen iterations of confident nonsense. That's exactly what Sandy buys you.

Longer version: docs/PROMPTING.md · Design and internals: docs/ARCHITECTURE.md


When not to use it

Loops are good at grinding toward a checkable target. They're bad at judgement.

Don't use one for design decisions, product tradeoffs, anything needing taste, one-shot operations, work with no automated verification, or production debugging where you need to understand the problem rather than make a symptom go away.


Requirements

  • Grok Build, with workflows enabled (GROK_WORKFLOWS=1, the default)
  • git — required for PRD mode, strongly recommended otherwise
  • Automated quality gates in the project. Optional, but the loop is running blind without them and will say so.
Repository layout
.grok-plugin/          plugin + marketplace manifests
plugin.json
workflows/
  star-loop.rhai       the entire engine
skills/
  star-loop/           /star-loop
  star-status/         /star-status
  cancel-star/         /cancel-star
  prd/                 /prd
  star-prd/            /star-prd
examples/              prd.json and full argument reference
docs/                  architecture, prompting guide
tools/rhai-check/      CI syntax gate (not needed to run star-loop)

Contributing, and the three testing tiers: CONTRIBUTING.md.


Credits

Standing entirely on other people's work:

  • Geoffrey Huntley — the Ralph technique. Fresh context per iteration, files as memory, and the observation that the operator's skill matters more than the model's.
  • snarktank/ralphprd.json, story-by-story execution, the progress log, and story sizing.
  • Anthropic's ralph-wiggum plugin — the /ralph-loop flag surface and completion promises, which this keeps compatible on purpose.
  • mikeyobrien/ralph-orchestrator — for taking orchestration, metrics and checkpointing seriously first.

Patrick Star and Sandy Cheeks are characters from SpongeBob SquarePants, created by Stephen Hillenburg and owned by Paramount. This project is an unaffiliated homage that borrows two names and no artwork.

License

MIT — see LICENSE.

About

Autonomous coding loop for Grok Build. One fresh agent per iteration until the work is genuinely done — every completion claim re-checked by an independent verifier that re-runs your gates. Pure Rhai, zero dependencies.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages