feat(explore): U4 kallsted 3 - demo-scenarioet, naabart ved NAVN og bare der (ORDRE 20260823T204216Z) [skip-docs]

Kallsted (3), siste av oerkt 57s fire.

simulate_exploration er et TREDJE scenario ved siden av simulate_learning_loop, og
bevisst ikke en del av det: demoens stdout og stderr er begge byte-pinnede fasiter,
og laeringsgjennomgangens paastand (en dom krysser to kjoeringer) er en ANNEN
paastand enn denne (en prompt + en kunnskapsbase blir et mandat pipelinen
evaluerer). Aa slaa dem sammen ville flyttet et pinnet transkript av en grunn som
ikke har noe med det transkriptet pinner aa gjoere. main() kaller det ikke - og at
golden-transkriptet er byte-uendret ETTER at scenarioet ble lagt til er selve
maalingen av det (ea8c534773acdbe41ae68f2c55724d69aaf8be4f).

VAKUITETS-VAKTEN er den baerende delen: en label kunnskapsbasen ALLEREDE oppgir
ville naadd hypotese-prompten som ordinaer navigert kontekst enten utforskningen
kjoerte eller ei, saa scenarioets egen assert ville holdt mot en implementasjon som
aldri wiret mandatet. Refusert, ikke demonstrert - noeyaktig samme vakt
simulate_learning_loop raiser paa naar de to markoerene faller sammen.

Manager-manuset noekles paa PROMPT-STADIET, ikke paa prosjekt-ID-en, og det er ikke
et unntak fra scripted_proposer-regelen: manageren faar FEM ulike spoersmaal (fakta,
plan, progress ledger, replan, sluttsvar), og hvilket det er er det eneste et svar
KAN noekles paa - prosjekt-ID-en er konstant over alle fem og ville valgt ingenting.

Aerlighets-grense, samme som resten av demoen (maalbilde §1): hvert svar er skriptet,
saa det som vises er at roerleggingen lukkes - at en formet retning faktisk blir en
Approach proposeren blir spurt om - aldri at en levende modell ville formet en god en.

Load-bearing MAALT (tests/test_explore_callsites_loadbearing.py, 2 nye tester), to
mutasjoner begge roede mot HELE suiten + groenn kontroll 998/5: detach mandate= fra
scenarioets run_project (1 roed) - detach vakuitets-vakten (1 roed).

mypy + ruff rene.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRZhBJcxqTcqWyMW6hBttx
This commit is contained in:
Kjell Tore Guttormsen 2026-08-25 09:38:30 +02:00
commit 118eabf9db
2 changed files with 247 additions and 1 deletions

View file

@ -37,7 +37,7 @@ import pytest
from agent_framework import BaseChatClient
import portfolio_optimiser
from portfolio_optimiser import explore, hosting, okf, run
from portfolio_optimiser import explore, hosting, okf, run, simulation
from portfolio_optimiser.budget import BudgetExceeded
from portfolio_optimiser.explore import ExplorationContract, ExplorationTrace
from portfolio_optimiser.mandate import Approach, Mandate
@ -685,3 +685,47 @@ async def test_the_hosted_door_refuses_by_name_on_the_callers_channel(payload, e
with pytest.raises(ValueError) as excinfo:
await hosting.invoke(_hosted_payload(**payload))
assert expected in str(excinfo.value)
# ---------------------------------------------------------------------------------------------
# 5. The demo scenario — a THIRD entry, reachable only by name
# ---------------------------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_the_demo_scenario_lets_a_shaped_direction_reach_the_hypothesis(tmp_path) -> None:
"""S1: the offline walkthrough of U4 — a prompt and a knowledge base become a mandate, and the
direction the loop shaped reaches the proposer VERBATIM.
The same honesty limit the rest of the demo carries applies here and is worth restating: this
proves the plumbing and that the data flow closes, NOT that a live model would shape a good
direction. Every reply is scripted.
Detach point: drop ``mandate=`` from the scenario's ``run_project`` call → RED.
"""
result = await simulation.simulate_exploration(str(_BUNDLE_DIR), str(tmp_path), max_rounds=3)
assert result.label_in_bundle is False, "the control the scenario refuses on"
assert [a.label for a in result.exploration.mandate.approaches] == [result.label]
assert result.label_in_generation_prompt, (
"the shaped direction never reached the hypothesis prompt — the demo would show a mandate "
"the pipeline ignored"
)
assert result.trace.ledger, "the exploration recorded no rounds"
@pytest.mark.asyncio
async def test_a_direction_the_base_already_states_is_refused_as_vacuous(tmp_path) -> None:
"""S2: a label the knowledge base ALREADY contains is refused, not demonstrated.
Exactly the guard ``simulate_learning_loop`` raises on when its two markers coincide: the
scenario's whole claim is that the direction came from the LOOP, and a label the bundle states
on its own would reach the prompt as ordinary context a demonstration that demonstrates
nothing, which is this repo's vacuous-gate class in demo form.
Detach point: drop the guard RED.
"""
stated = "LED-retrofit" # present in the bundle's own text
with pytest.raises(ValueError) as excinfo:
await simulation.simulate_exploration(str(_BUNDLE_DIR), str(tmp_path), label=stated)
assert stated in str(excinfo.value)