run-goldens — run the golden LLM tests against a real model, by choice
Golden tests (@GoldenLlmTest-style) exercise an LLM surface — routing,
strict-JSON extraction, synthesis grounding — against a real local model,
asserting structure, not exact text. They are opt-in (a GOLDEN_LLM gate),
skipped in CI, and slow (a real model call per assertion), so you run the ones
that touch what you changed — not the whole suite reflexively.
Procedure
- Discover the goldens. Find the repo's golden classes — grep for the golden
marker (this repo family uses
@GoldenLlmTest):
grep -rl "@GoldenLlmTest" --include=*.java (adapt the marker/glob to the
repo's language). Group the hits by module (the Maven -pl path / package
root) so each has a runnable address.
- Present the inventory + get a scope. Show the discovered classes grouped by
module and ask which to run: one class, several (comma-separated), a
whole module, or all. You can narrow to a single method with
Class#method. Prefer the smallest scope that covers the surface just changed.
- Check prerequisites. The golden lane needs a real model. Use the repo's
golden runner (
scripts/golden.sh in this repo family) — it auto-starts the
local inference engine + an LLM gateway pointed at it, sets GOLDEN_LLM=true,
and handles model quirks (e.g. suppressing "thinking" so a call is seconds not
minutes). The required model must already be pulled; the runner names the pull
command rather than downloading multi-GB blobs unasked. Do NOT hand-roll the
env — go through the runner so the setup stays identical to everyone else's.
- Run the chosen scope through the runner, e.g.:
- one class:
scripts/golden.sh -pl <module> -Dtest=<GoldenClass>
- several:
scripts/golden.sh -pl <module> -Dtest='<GoldenA>,<GoldenB>'
- one method:
scripts/golden.sh -pl <module> -Dtest=<GoldenClass>#<method>
- all: run per module (loop the
-pl <module> -Dtest=<its Golden*> addresses).
The runner leaves the engine + gateway up, so the next run is instant.
- Read the result — real regression vs flaky case. On failure, extract only
the failing assertion (e.g.
«…» should route to 'finance' but went to 'tasks'),
not the full log. Then apply the flakiness rule below before calling it a bug.
- Report. A short per-class pass/fail; for each failure, the assertion + a
verdict: real regression (stable, reproducible) or flaky borderline case
(input too ambiguous for the model — tighten the test, not the product).
Flakiness — the rule that keeps goldens trustworthy
A small local model is non-deterministic on borderline inputs — a phrasing
sitting between two domains can route one way now and another next run. So:
- A golden case must be crisp: unambiguous intent, one obvious answer. Vague
or "clever" phrasings belong in exploratory notes, not a must-pass golden.
- On a failure, re-run that case once before concluding. If the verdict flips
between identical runs, the case is too borderline — fix the test input
(make it crisp) rather than chasing the model or loosening the assertion. Only a
stable, reproducible failure is a real regression to investigate in the
product (prompt / manifest / router).
- When you add a golden case, run it twice to confirm it is stable before
committing — a flaky green is a debt that fails someone else later.
When NOT to reach for this
- You changed only non-LLM code (plumbing, DB, config with no prompt/router
effect) — there is no LLM surface to re-validate; the normal unit/slice tests
cover it.
- You just want the fast inner loop — goldens are the real-model gate, not the
iterate loop. Use mocked slice tests while iterating; run the goldens before the
PR for the surface you touched.
Triggering contract (examples)
SHOULD fire: "прогони голдены по роутингу", "run the finance golden", "проверь,
не сломал ли я синтез на реальной модели", "run all the goldens before I open the
PR". SHOULD NOT fire: "run the unit tests" (not the real-model gate), "why is my
build failing" (compile, not goldens), "add a golden test" (that is authoring —
new-skill / write the test; this skill only runs them).
1---2name: run-goldens3description: Use when you want to run the golden LLM tests against a real model — one, a few, or all. Fires on: "прогони голдены" / "run the goldens", "прогони golden тесты", "проверь роутинг/синтез на реальной модели", "did my prompt/skill/router change break the goldens", after editing a prompt, SKILL.md, classifier, or any LLM surface. Discovers the repo's golden tests, lets you pick a scope, runs them through the repo's golden runner, and reads the result (real regression vs flaky borderline case).4---56# run-goldens — run the golden LLM tests against a real model, by choice78Golden tests (`@GoldenLlmTest`-style) exercise an **LLM surface** — routing,9strict-JSON extraction, synthesis grounding — against a **real local model**,10asserting *structure, not exact text*. They are **opt-in** (a `GOLDEN_LLM` gate),11skipped in CI, and slow (a real model call per assertion), so you run the ones12that touch what you changed — not the whole suite reflexively.1314## Procedure15161. **Discover the goldens.** Find the repo's golden classes — grep for the golden17 marker (this repo family uses `@GoldenLlmTest`):18 `grep -rl "@GoldenLlmTest" --include=*.java` (adapt the marker/glob to the19 repo's language). Group the hits by module (the Maven `-pl` path / package20 root) so each has a runnable address.212. **Present the inventory + get a scope.** Show the discovered classes grouped by22 module and ask which to run: **one** class, **several** (comma-separated), a23 whole **module**, or **all**. You can narrow to a single method with24 `Class#method`. Prefer the smallest scope that covers the surface just changed.253. **Check prerequisites.** The golden lane needs a real model. Use the repo's26 golden runner (`scripts/golden.sh` in this repo family) — it auto-starts the27 local inference engine + an LLM gateway pointed at it, sets `GOLDEN_LLM=true`,28 and handles model quirks (e.g. suppressing "thinking" so a call is seconds not29 minutes). The required model must already be pulled; the runner names the pull30 command rather than downloading multi-GB blobs unasked. Do NOT hand-roll the31 env — go through the runner so the setup stays identical to everyone else's.324. **Run the chosen scope** through the runner, e.g.:33 - one class: `scripts/golden.sh -pl <module> -Dtest=<GoldenClass>`34 - several: `scripts/golden.sh -pl <module> -Dtest='<GoldenA>,<GoldenB>'`35 - one method: `scripts/golden.sh -pl <module> -Dtest=<GoldenClass>#<method>`36 - all: run per module (loop the `-pl <module> -Dtest=<its Golden*>` addresses).37 The runner leaves the engine + gateway up, so the next run is instant.385. **Read the result — real regression vs flaky case.** On failure, extract only39 the failing assertion (e.g. `«…» should route to 'finance' but went to 'tasks'`),40 not the full log. Then apply the flakiness rule below before calling it a bug.416. **Report.** A short per-class pass/fail; for each failure, the assertion + a42 verdict: *real regression* (stable, reproducible) or *flaky borderline case*43 (input too ambiguous for the model — tighten the test, not the product).4445## Flakiness — the rule that keeps goldens trustworthy4647A small local model is **non-deterministic on borderline inputs** — a phrasing48sitting between two domains can route one way now and another next run. So:4950- A golden case must be **crisp**: unambiguous intent, one obvious answer. Vague51 or "clever" phrasings belong in exploratory notes, not a must-pass golden.52- On a failure, **re-run that case once** before concluding. If the verdict flips53 between identical runs, the case is too borderline — **fix the test input**54 (make it crisp) rather than chasing the model or loosening the assertion. Only a55 **stable, reproducible** failure is a real regression to investigate in the56 product (prompt / manifest / router).57- When you *add* a golden case, run it **twice** to confirm it is stable before58 committing — a flaky green is a debt that fails someone else later.5960## When NOT to reach for this6162- You changed only non-LLM code (plumbing, DB, config with no prompt/router63 effect) — there is no LLM surface to re-validate; the normal unit/slice tests64 cover it.65- You just want the fast inner loop — goldens are the real-model gate, not the66 iterate loop. Use mocked slice tests while iterating; run the goldens before the67 PR for the surface you touched.6869## Triggering contract (examples)7071SHOULD fire: "прогони голдены по роутингу", "run the finance golden", "проверь,72не сломал ли я синтез на реальной модели", "run all the goldens before I open the73PR". SHOULD NOT fire: "run the unit tests" (not the real-model gate), "why is my74build failing" (compile, not goldens), "add a golden test" (that is authoring —75`new-skill` / write the test; this skill only *runs* them).