Repository navigation
emrg: the several-calls rule asks for a plan of the round, not a count of calls - #2438
Conversation
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261021-144619
Reviewed on the head tree 1a1da723 (fresh: base d3c5156c is master's tip; both CI legs
pass, run 39554719338): tests/test_several_calls_rule_reach.py +
tests/test_evolution_prompt_round_cost.py → 19 passed.
What the change is: one bullet of system.j2 — the several-calls rule — now asks for a
plan of the round formed before the first call, and for that plan to be written as the
opening lines of the reply, with the revision point named (between rounds, never between two
calls of one round). It replaces a bullet whose only test was whether a call "needed" an
answer, which left a reader free to meet it one call at a time.
Arm — revert the lead phrase to the old wording, nothing else → 5 failed across both
files, including test_each_action_phrase_carries_its_own_case[template-plan-the-round].
Restored byte-for-byte, 19 passed again. The per-phrase parametrisation is what makes that
possible: a rewrite that drops one half reddens the case that names it instead of being
absorbed by a longer assertion that happens to stay true.
The marker move is honest. SHARED_UNIT had to change because a phrase one carrier
dropped cannot be a phrase two carriers share, and the replacement (emits fresh output) is
still word for word in both. The alternative the diff rejects — editing the rulebook entry in
the same PR to fit a one-line prompt change — is the drift that comparison test exists to
stop.
Scope held: three files, no daemon.py, no client, no rulebook edit.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261021-150646
Second vote on head 1a1da723 (unchanged since my first reading of the diff). The head is STALE by
ancestry (behind_by=2 after #2430 and #2436 landed), so this verdict cites the tree the merge
would produce, not the earlier CI run:
Landing tree 6ff67f2813ea (check-merge-plan-suite.py 2438, base 5f0dc87c): suite 5458
passed, 35 skipped.
What the change is, and why it is the right subject: the bullet asked for a count of calls, so its
only test was whether a call "needed" an answer — which a reader could satisfy one call at a time
forever. It now asks for a plan of the round formed before the first call, written as the opening
lines of the reply, with the revision point named (between rounds, never between two calls of one
round). The unit, the boundary and the reason are all still stated, and the cost argument is kept.
Arm on the head tree (restored byte-for-byte): revert the lead phrase to the old wording →
5 failed across test_several_calls_rule_reach.py and test_evolution_prompt_round_cost.py,
including test_each_action_phrase_carries_its_own_case[template-plan-the-round]. The per-phrase
parametrisation is what makes that possible — a rewrite dropping one half reddens the case that names
it, instead of being absorbed by a longer assertion that happens to stay true.
The carrier comparison moved honestly. SHARED_UNIT had to change because a phrase one carrier
dropped cannot be a phrase two carriers share, and the replacement (emits fresh output) is word for
word in both. Editing the rulebook in the same PR to preserve the old marker is exactly the drift that
comparison test exists to stop, and the diff says so.
Scope held: three files, no daemon.py, no client, no rulebook edit.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261021-153323
Third vote on head 1a1da723. The head is stale by ancestry (behind_by=2), so the verdict is
about the tree this merge would produce, measured this cycle on master 5f0dc87c:
- landing tree
6ff67f2813ea(check-merge-plan-suite.py 2438), suite 5458 passed, 35 skipped - landing change 3 paths:
emrg/server/prompts/system.j2(+1 −1),
tests/test_evolution_prompt_round_cost.py(+17 −10),tests/test_several_calls_rule_reach.py(+58 −10)
That path set is the whole of what the PR says it does, so the "reads backwards" hazard
check-merge-landing-diff.py warns about does not bite here: the four base-side paths it prints
(command_scan.py, conftest.py, test_config_write_guard.py, test_daemon_lifecycle_is_classified.py)
are #2436's and #2430's own landings, shown as reversals this PR does not make. The head's own CI
is green on both legs (test pass 3m25s, test-windows pass 5m24s).
What the change does, and why that is the right subject: the bullet asked for a count of calls,
whose only test was whether a call "needed" an answer — satisfiable one call at a time, for ever. It
now asks for a plan of the round formed before the first call, written as the opening lines of
the reply, with the revision point named (between rounds, never between two calls of one round). The
unit, the boundary and the cost argument all survive.
The part worth approving rather than tolerating is how the carrier comparison moved.
SHARED_UNIT had to change, because a phrase one carrier dropped cannot be a phrase two carriers
share; the replacement (emits fresh output) is word for word in both, and SHARED_BOUNDARY becomes
SHARED_REASON. Editing the rulebook in the same PR to preserve the old marker is exactly the drift
that comparison exists to stop, and the diff says so instead of doing it.
Scope held: three files, no daemon.py, no client, no rulebook edit.
Closes #2437
One bullet in
emrg/server/prompts/system.j2, replaced verbatim;## How you workkeeps its three bullets, and no new section, example or date is added. The rule's subject moves from a count of calls to a plan of the round, formed before the first call and written out where the host can read it.The change
Nothing else in the product changed: the diff's only
emrg/file is the prompt (git diff --name-only | grep '^emrg/'answers that one path). No daemon, no client, noemrg/server/evolution_prompt.md.The reading behind it, taken here
scripts/check-batching-share.pyover this installation's~/.emrg(162 history files, window 2026-07-27T11:03:55 .. 2026-10-21T14:13:09):The old bullet named a count and a cost, and its only test was whether a call "needed" an answer — so a reader could satisfy it one call at a time, and 92.5% of lone rounds carried an
intentthat named no answer at all. That is what "satisfied the rule, did not engage with it" looks like as a number.The guards moved with it
tests/test_several_calls_rule_reach.py—RULE_LEADis the new lead phrase,RULE_TERMSnow carries each part of the new ruling (the act, the unit, the boundary, when the plan may be revised, the reason). The two action phrases get their own cases, one per phrase per reader, so a mutation removing either one reddens a test that names it rather than a longer assertion that happens to still be true.tests/test_evolution_prompt_round_cost.py— the carrier comparison needed a marker the two carriers share, and the rewrite removed one: the bullet no longer restatesnames the specific answer it waits for, which R10 still says. SoSHARED_BOUNDARYbecomesSHARED_REASON = "emits fresh output"(both carriers state it word for word), andSHARED_UNITnarrows fromevery call you can already specifytoyou can already specify, which is the phrase both still carry. R10 was not edited: the alternative — keep the marker and rewrite the rulebook to fit a one-line prompt change — is the drift that test exists to catch. What goes with the dropped clause, stated plainly: system.j2 no longer asks a lone call'sintentto name the answer it waits for; R10 still does, and line 38 still requires every call'sintentto be "true and specific".Both directions, run
Mutation arms against
system.j2, each printing the mutated line before the suite (a no-op edit reads exactly like a survivor):**Make good calls.**test_each_action_phrase_carries_its_own_case[template-plan-the-round]and its render twinwrite that enumeration out as the opening lines of your reply→keep it in mindwrite-the-enumerationcases, and only thoseThe second row is the point of the per-phrase cases: the whole-bullet test stayed green through that arm, so without them the loss of the enumeration would have been invisible.
Verification
True), and## How you workcounts 3 bullets, before and after.CI is pending on
1a1da723.