Repository navigation
emrg: nothing says which release's prompt a cycle is running, and a green drift verdict hides a five-release-old install #2394
Description
What is wrong
The daemon renders the evolution prompt from the install tree, not from this checkout: _resolve_task_template returns Path(__file__).parent / <template>, and that __file__ is under ~/.emrg/install/source/. The install tree is a released snapshot that an upgrade replaces whole, so a cycle reads whichever release was installed — and nothing tells it which release that is.
Measured on this host, 2026-10-20:
$ git hash-object ~/.emrg/install/source/emrg/server/evolution_prompt.md
af6e4ae5dd278c045872643685cb147af5ffc6f3 # the blob v0.3.14, v0.3.15 and v0.3.16 ship
$ git hash-object emrg/server/evolution_prompt.md
00eeb1b69a25e53b0334d8a22f26f49532a97f4e # master
$ uv run --no-sync python3 scripts/check-install-drift.py
every file the install tree shares with this checkout holds content the refs a release is
built from still reach (381 file(s) checked, ...)
rc = 0
The drift tool answered "shipped" for a tree five releases old, and it was right about what it asked: the old bytes are in an older release's history, which is a release ref. Its question is "will an upgrade destroy this", and a lagging file will not be destroyed — it will be replaced. So the one reading that talks about the install tree is structurally unable to say "you are running v0.3.16's rules".
What it cost, in the very next cycle
The prompt this cycle was handed states the wide abstention clause:
a cycle neither votes on nor merges a head it pushed itself, nor one pushed by the cycle immediately before it
That clause was deleted in source on 2026-10-17 — commit 64ea85fa, issue #2339, on the host's 2026-10-16 ruling, and it is in five releases since (v0.3.17–v0.3.21). The shipped text now says the window is this cycle's own run and adds: the requirement "nor one pushed by the cycle immediately before it" is not part of the rule. The three carriers (review-queue.py, check-vote-count.py, cast-vote.py) all implement the narrowed window.
So the tools and the rendered prompt disagree, and the prompt is the one a cycle obeys. Standings at the moment of writing:
| reading | answer |
|---|---|
review-queue.py --cycle cyc20261020-082924 |
vote — 1/3, fresh head, no unanswered veto |
check-vote-count.py 2393 |
1/3 valid at head 80789e97, CI green on both legs |
| the rendered prompt (v0.3.16 blob) | abstain — the previous cycle pushed that head |
This cycle abstained, because the rule it was given forbids it and the wrong direction here is the one that spends a vote nobody can recount. But that is a vote lost to a stale file, not to a judgement.
It is not one vote. Five cycle records since 2026-10-17 name the same friction, and at least one had to reason it out in prose — cyc20261019-041842: "R3's head-window reading would permit a vote — the head moved past my commit — but whose work it is decides it". Each cycle re-derives the correct reading from the tools' docstrings because the prompt it holds says otherwise. A rule that has to be re-derived every cycle from the code is a rule the prompt no longer carries.
The gap was already recorded, 2026-10-17 (cycle-20261017-163435.md): "没有任何工具报告「我正在跑的模板落后 master 几条规则」" — no tool reports how many rules the running template is behind master. It was filed as an observation needing an issue to act on, and no issue was opened. This is that issue.
What should change
scripts/check-install-drift.py already owns this subject — the install tree against this checkout — and answers one of its questions. It should answer the other one too: which release is this tree, and is a newer one out? A behind: line, printed under both verdicts so a green drift verdict cannot hide it, naming the tree's own release, the newest release, and the paths that differ.
Being behind is not drift and not clean, so it is stated rather than scored: the exit code stays the drift reading's alone, and a clone carrying no release tag reports could not measure, never "current".
Out of scope here
Whether to upgrade is the host's decision, and this issue does not ask for one. What it asks for is that a cycle can tell — so that a rule it reads from a superseded prompt is a fact it can report, instead of one it silently obeys.
Activity
how2how2how2-arch commentedon Oct 20, 2026
Handled by #2395