diff --git a/site/index.html b/site/index.html
index ae5c849..7c76cc2 100644
--- a/site/index.html
+++ b/site/index.html
@@ -171,7 +171,7 @@
"name": "What do the spend numbers mean?",
"acceptedAnswer": {
"@type": "Answer",
- "text": "Watch and the report card show two numbers when they differ: list (public API rates, including prompt-cache) and billed (what the runtime invoice says). $0 on a subscription quota is billed $0, not free. Budget caps use billed when you are on PAYG and list when the invoice is $0."
+ "text": "Watch and the report card show two numbers when they differ: list (public API rates, including prompt-cache) and billed (what the runtime invoice says). $0 on a subscription quota is billed $0, not free. Budget caps use billed when you are on PAYG and list when the invoice is $0. OpenCode Go and Cline Pass model lists and list prices come from models.dev; unknown but well-formed slugs soft-gate — warn at loop start, show $0 until priced. Budget caps still reject unpriced worker or escalate models."
}
}
]
@@ -395,7 +395,7 @@
What if verify fails because my environment is broken?
What do the spend numbers mean?
- Watch and the report card show two numbers when they differ: list (public API rates, including prompt-cache) and billed (what the runtime invoice says). $0 on a subscription quota is billed $0, not “free.” Budget caps use billed when you are on PAYG and list when the invoice is $0.
+ Watch and the report card show two numbers when they differ: list (public API rates, including prompt-cache) and billed (what the runtime invoice says). $0 on a subscription quota is billed $0, not “free.” Budget caps use billed when you are on PAYG and list when the invoice is $0. OpenCode Go and Cline Pass model lists and list prices come from models.dev; unknown but well-formed slugs soft-gate — warn at loop start, show $0 until priced. Budget caps still reject unpriced worker or escalate models.
@@ -409,7 +409,7 @@ How it works
Your agent writes GOAL.md and a deterministic check that the feature really works.
Optional setup.sh (or setup in loop.json) runs once before the first worker — setup failure does not spawn a worker.
A fresh worker loops until that check passes — optional judge / reviewGate only on serious findings.
- After each visit the harness restores frozen specs if a worker edited them.
+ After each visit the harness restores frozen specs if a worker edited them — and removes any frozen basename they planted (like setup.sh) so it cannot carry into the next run.
Progress lives in git and files, not chat memory.
diff --git a/site/index.md b/site/index.md
index 1c03f95..03db381 100644
--- a/site/index.md
+++ b/site/index.md
@@ -50,11 +50,11 @@ When the check fails because something on your machine is missing or broken —
## What do the spend numbers mean?
-Watch and the report card show two numbers when they differ: **list** (public API rates, including prompt-cache) and **billed** (what the runtime invoice says). `$0` on a subscription quota is billed `$0`, not “free.” Budget caps use billed when you are on PAYG and list when the invoice is `$0`.
+Watch and the report card show two numbers when they differ: **list** (public API rates, including prompt-cache) and **billed** (what the runtime invoice says). `$0` on a subscription quota is billed `$0`, not “free.” Budget caps use billed when you are on PAYG and list when the invoice is `$0`. OpenCode Go and Cline Pass model lists and list prices come from [models.dev](https://models.dev/api.json); unknown but well-formed slugs soft-gate — warn at loop start, show `$0` until priced. Budget caps still reject unpriced worker or escalate models.
## How it works
-Your agent writes `GOAL.md` and a deterministic check. Optional `setup.sh` (or `setup` in `loop.json`) runs once before the first worker — setup failure does not spawn a worker. A fresh worker loops until the check passes. After each visit the harness restores frozen specs if a worker edited them.
+Your agent writes `GOAL.md` and a deterministic check. Optional `setup.sh` (or `setup` in `loop.json`) runs once before the first worker — setup failure does not spawn a worker. A fresh worker loops until the check passes. After each visit the harness restores frozen specs if a worker edited them — and removes any frozen basename they planted (like `setup.sh`) so it cannot carry into the next run.
## How is Agent Looper different from looping in chat?
diff --git a/site/llms.txt b/site/llms.txt
index 26f488c..b5bb5d3 100644
--- a/site/llms.txt
+++ b/site/llms.txt
@@ -6,7 +6,7 @@ When to use Agent Looper: a human wants a feature finished without babysitting C
When not to use Agent Looper: there is no deterministic check (pure taste with no script or vision gate); you need a team-ops factory, shared org cloud, or multi-repo orchestration; you want the model to grade itself as “done.”
-How an agent should call it: install `@dancingteeth/agent-looper`, ask the human what they want, then implement the feature with Agent Looper (set up the loop, write GOAL.md and verify.sh, run until green). Or from the terminal: `pnpm exec agent-loop-setup` (one-screen setup wizard — recap plus current question) then `pnpm exec agent-loop-prompt --out .cursor/loops/`, then `pnpm exec agent-loop run .cursor/loops/ --runtime `. Optional `--review-gate` re-opens the loop only on blocking review findings. If verify fails because the environment is broken, the loop waits instead of burning another worker. CLI binaries: `agent-loop`, `agent-loop-prompt`. Current npm: **0.6.1** (supported line **0.6.x**).
+How an agent should call it: install `@dancingteeth/agent-looper`, ask the human what they want, then implement the feature with Agent Looper (set up the loop, write GOAL.md and verify.sh, run until green). Or from the terminal: `pnpm exec agent-loop-setup` (one-screen setup wizard — recap plus current question) then `pnpm exec agent-loop-prompt --out .cursor/loops/`, then `pnpm exec agent-loop run .cursor/loops/ --runtime `. Optional `--review-gate` re-opens the loop only on blocking review findings. If verify fails because the environment is broken, the loop waits instead of burning another worker. After each visit the harness restores frozen specs and removes any frozen basename a worker planted (e.g. `setup.sh`) so it cannot persist. OpenCode Go and Cline Pass model lists and list prices come from models.dev; unknown well-formed slugs warn at start and read `$0` until priced — budget caps still reject unpriced worker or escalate models. CLI binaries: `agent-loop`, `agent-loop-prompt`. Current npm: **0.6.1** (supported line **0.6.x**).
## Developer resources
diff --git a/src/site/landingAgentReadiness.test.ts b/src/site/landingAgentReadiness.test.ts
index c16776a..dfe48d2 100644
--- a/src/site/landingAgentReadiness.test.ts
+++ b/src/site/landingAgentReadiness.test.ts
@@ -652,7 +652,7 @@ describe('landing agent readiness', () => {
}
})
- it('names 0.6.0 setup wizard, env-wait, harness setup, frozen restore, and DSH 4.1 Flash opt-in', () => {
+ it('names 0.6.1 setup wizard, env-wait, harness setup, frozen restore, plant block, models.dev soft-gate, and DSH 4.1 Flash opt-in', () => {
const html = readSite('index.html')
const md = readSite('index.md')
const llms = readSite('llms.txt')
@@ -683,6 +683,9 @@ describe('landing agent readiness', () => {
const envWaitBeat = 'waits for you instead of sending another worker'
const setupBeat = 'setup.sh'
const frozenBeat = 'restores frozen specs'
+ const plantBeat = 'removes any frozen basename'
+ const modelsDevBeat = 'models.dev'
+ const softGateBeat = 'soft-gate'
const flashOptIn = 'deepseek-flash'
const flashLabel = '4.1 Flash'
@@ -691,17 +694,30 @@ describe('landing agent readiness', () => {
expect(surface).toContain(envWaitBeat)
expect(surface).toContain(setupBeat)
expect(surface).toContain(frozenBeat)
+ expect(surface).toContain(plantBeat)
+ expect(surface).toContain(modelsDevBeat)
+ expect(surface).toContain(softGateBeat)
expect(surface).not.toContain('0.5.0')
expect(surface).not.toMatch(/\bInk\b/i)
+ expect(surface).not.toMatch(/Current npm.*0\.6\.0/i)
}
expect(llms).toContain('Current npm: **0.6.1**')
expect(llms).toContain('0.6.x')
expect(llms).not.toContain('0.5.0')
+ expect(llms).not.toContain('Current npm: **0.6.0**')
expect(llms).toContain(setupWizardBeat)
+ expect(llms).toContain(plantBeat)
+ expect(llms).toContain(modelsDevBeat)
+
+ const spendQuestion = faq?.mainEntity?.find(
+ (q) => q.name === 'What do the spend numbers mean?',
+ )
expect(promptQuestion?.acceptedAnswer?.text).toContain(setupWizardBeat)
expect(envQuestion?.acceptedAnswer?.text).toContain(envWaitBeat)
+ expect(spendQuestion?.acceptedAnswer?.text).toContain(modelsDevBeat)
+ expect(spendQuestion?.acceptedAnswer?.text).toContain(softGateBeat)
const dshCard =
harnessHtml.match(