feat(s2c): debatten navigerer basen i stedet for aa faa den utlevert [skip-docs]

MAJOR-3/S7a-3 gjorde utforskningen billig og lot pipelinen staa. Maalt paa K2
(630 konsepter, S7bs eget instrument, kjent-positiv-kontrollen reprodusert
eksakt FOER bruk): okf.bundle_context er 648 962 o200k-tokens og rir i TRE
kopier = 1 947 342 = 99,1 % av en kjoerings prompt-tokens.

Et premiss i maaledokumentet ble presisert foerst: de tre kopiene er tre
DEBATT-turer (proposer x2, checker x1), mens genererings-prompten er 156
tokens, fordi gen_context = debate_output or context. Det avgjorde formen -
generering trengte ingen egen soem, for aa binde `context` binder
siste-utvei-fallbacken ved konstruksjon.

run_project sender naa en PEKER (fast tekst + erklaert bundle_id + antall
konseptdokumenter i scope + stigen, O(1) i korpuset) og gir debatten de SAMME
fire verktoeyene utforskningen bruker - explore.navigator_tools gjenbrukt,
aldri en andre kopi av policyen.

Etter: 753 tokens like-for-like (samme manus, samme fire prompter, -99,96 %)
og 8 942 med en debatt som faktisk gaar stigen (-99,5 %), mot operatoerens
terskel 195 000 = 4,6 % av taket. Validert besparelse og validatorens dom er
UENDRET (850 000 NOK av 3 852 500, 2 av 5 felt paa stage 4 og 5, samme
dom-noekkel), og utforskningens 18 355 er uendret til tokenet.

§4.1a maatte flytte, ikke forsvinne: dimensjonsfilteret bodde i renderingen og
bor naa i VERKTOEYENE, paa begge trinn - en listing som skjuler et fremmed
dokument mens read_file serverer det paa sti er et filter i navnet alene.
okf.in_dimension er eneste predikat.

Sporet er kaller-eid (ExplorationToolRecorder -> RunResult.debate_tool_calls ->
{run_id}-debate.json fra en finally) og skrives ogsaa TOMT: en debatt som
navigerer ingenting ER S2c-regresjonen, saa den maa kunne leses.

Load-bearing MAALT: aatte mutasjoner roede mot HELE suiten, groenn kontroll
1306/5 (fra 1295/5), golden demo-transcript.stdout BYTE-UENDRET
(shasum -a 1 av innholdet = ea8c534773acdbe41ae68f2c55724d69aaf8be4f).
M7 falsifiserte seg selv, ikke gaten - staar som maalt.

Maaling: docs/2026-09-04-s2c-debatt-k2.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-04 18:04:21 +02:00
commit da5f10f140
13 changed files with 1044 additions and 98 deletions

View file

@ -442,16 +442,25 @@ def test_a_step_naming_an_unknown_key_is_refused_by_name(tmp_path, capsys) -> No
assert "result" in err, err
def test_a_step_list_is_refused_for_a_debate_role(tmp_path, capsys) -> None:
"""The list form is the EXPLORATION's, and is refused elsewhere by name rather than accepted
and quietly ignored. The debate's proposer is driven by ``generate``'s own call, not by an
agent loop that would invoke a tool between turns, so a script of calls there would describe a
rehearsal that cannot happen.
def test_a_step_list_is_accepted_for_a_debate_role(tmp_path) -> None:
"""REWRITTEN at S2c, not deleted: this arm used to pin the refusal of a step list for the
debate's roles, on the ground that the proposer answers ``generate``'s own call rather than an
agent loop that could invoke a tool between turns. Since S2c the proposer and the checker ARE
agents holding the four navigator tools, so that ground is measurably false and the refusal
would have kept the free half of the measurement ladder away from the very seam S2c builds
the identical vacuity MAJOR-1 closed for the navigator.
What replaces it is the positive: a scripted proposer opens the base, and the debate's own
artefact names WHICH document. RED if the list form is refused for a debate role again, and RED
if the debate's ``ExplorationToolRecorder`` is detached (the run succeeds, the trace is empty).
"""
replies = _replies_file(
tmp_path,
{
"proposer": [{"call": "retrieve_cost_docs", "args": {"query": "x"}}],
"proposer": [
{"call": "read_bundle", "args": {"bundle_id": "bygg-energi-mikro"}},
_PROPOSER_REPLY,
],
"checker": "VERDICT: APPROVE",
"manager": list(_MANAGER_STAGES),
"navigator": "NAVIGATOR: read the index.",
@ -461,6 +470,12 @@ def test_a_step_list_is_refused_for_a_debate_role(tmp_path, capsys) -> None:
rc = run.main(_explore_argv(tmp_path, replies, "scripted-debate-list"))
assert rc == 1
err = capsys.readouterr().err
assert "run refused" in err and "proposer" in err, err
assert rc == 0
payload = json.loads(
(tmp_path / "outbox" / "scripted-debate-list-debate.json").read_text(encoding="utf-8")
)
assert payload["tool_calls"][0] == {
"name": "read_bundle",
"bundle_id": "bygg-energi-mikro",
"path": "",
}, payload["tool_calls"]