The loop and the rule
The seven stages, and the one rule that decides what belongs to code.
You do not drive ROSE. You work normally, and it runs in hooks.
| When | What happens | Model calls |
|---|---|---|
| you submit a prompt | matching lessons are injected as context | 0–1, cached |
| context is about to compact | the record of what you were shown is cleared | 0 |
| a substantial turn ends | a reflector runs off-thread: did anything teach us something, and which lessons actually mattered | 1–2, detached |
| you teach it something | rose add records it immediately, reconciled against what is known | 1–2 |
| the session ends | the transcript is judged, lessons minted, compression attempted, selection rules written | 2–4, detached |
Everything expensive is detached — spawned as a separate process
that outlives the hook. Spawned agents get ROSE_CHILD=1, which
makes ROSE's own hooks no-op; without it a reflector would trigger
reflectors forever.
The governing rule#
The harness owns the graph, the traversal, budgets, caches, the schemas
answers must fit, and whether to ask at all. The model owns every
question about meaning, each behind a JSON schema, cached so nothing is
judged twice. There are exactly five semantic calls in the system
(rose/judge.py):
| Call | Question |
|---|---|
relevance | which remembered lessons bear on this prompt? |
related | which existing lessons cover the same subject as this new one? |
scope | does this lesson belong to this repo, or everywhere? |
assess | how did this session go, and which lessons actually bore on it? |
rank_repairs | which dropped detail explains this failure? |
Plus four more: select (which lessons this work needs), compress, replay-probe, and the replay judge.
What stays in code, and why that is not a violation#
Counting an observed outcome is evidence — a success rate, a rescue count, how often two lessons were used together on work that succeeded. Computing how alike two texts are is a proxy standing in for a judgement, and must be a model call. The test is what question the number answers, not where it came from.
This was learned the hard way. Retrieval was originally Jaccard
similarity, contradictions were found with a KEY=value regex,
and session outcomes came from phrase banks with hand-tuned weights. All
of it looked structural and all of it was a lookup table wearing a
judgement's clothes.