portfolio-optimiser/tests/test_p4_honesty_sentences_loadbearing.py
Kjell Tore Guttormsen 50232fb88d feat(simulation): P4 pkt. 3+4 — demo-transkriptet pinnet, frø-setningen avledet [skip-docs]
Kriterium 6 er selv-identitet: to kjøringer av en regredert demo er like enige som
to av en riktig. Fasiten forlater derfor prosessen. stdout pinnes ORDRETT (og er
dermed demoens abortsti); stderr normaliseres på nøyaktig to MÅLTE miljø-spann —
site-packages-prefikset og temp-katalogen — med po-sim- holdt synlig, fordi det er
en egenskap ved programmet og ikke ved miljøet. Pinnet stderr = fire linjer.
Kontrollen som forbyr at masken vokser er load-bearing: en droppende normaliserer
med fasiten regenerert under seg holder BEGGE likhets-testene grønne.

Pkt. 4: planens forhåndsskrevne frø-setning sa «én av de TO tidligere dommene».
Målt mot levert VEGLYS-bundle henter Kjøring B TRE — én fulgte med kunnskapsbasen,
to er demoens egne, én per tidsskala. Splitten avledes derfor fra kjøringen; en
håndskrevet «én av tre» ville vært den andre kopien som drifter.

Fem mutasjoner alle røde + grønn kontroll (hele suiten hver gang): ett byte i en
stdout-linje · detach dempingen · over-normaliser stderr · literal splitt · detach
frø-setningens print. Byte- og detach-mutasjonene ble fanget av KUN golden-testen;
den literale splitten av KUN skille-testen.

793 -> 801 passed / 4 skipped.
2026-08-09 22:12:25 +02:00

124 lines
5.9 KiB
Python

"""P4 pkt. 4 — the two honesty sentences the demo says out loud, and why one of them is DERIVED.
The plan pre-wrote two sentences for the stage. The first is the provenance claim about the cost
numbers, already live as ``_VEGLYS_PROVENANCE`` since the GO (P3): the baseline the validator's
stage 0 reconciles against was written by a domain team, not by the demo script.
The second is the seed sentence, about where Run B's "previous verdicts" come from. **Its pre-written
wording is wrong against the delivered content and was corrected against measurement.** The plan said
"one of the TWO previous verdicts in Run B came with the example — the other is the one the demo
learned"; measured against the delivered VEGLYS bundle, Run B retrieves THREE: one seeded
(``verdict-veglys-fro.md``), and TWO the demo produced itself — one per time scale (the Step-8
promotion and the Step-7 inbox note). A sentence that says "two" would be a false claim made on
stage about a number printed one line above it.
**Why the split is computed and not written down.** The line right above already prints the retrieved
count. A hand-written "one of three" would be a second copy of that number in a different place —
the exact drift the anchored-baseline discipline (P4 pkt. 0) refuses — and it would go on being said
after a future bundle ships a second seeded verdict, silently. So the split is derived from the run,
and the classifier is the two markers the demo has been tracing all along: a retrieved verdict that
carries one of them is one the demo learned in this session; anything else came with the knowledge
base.
That classifier rests on a property of the delivered content — the seeded verdict must carry NEITHER
marker — so that property is measured here too, and not assumed.
"""
from __future__ import annotations
from pathlib import Path
from portfolio_optimiser.persona import load_persona_example
from portfolio_optimiser.simulation import (
_INBOX_MARKER,
_VEGLYS_PROVENANCE,
_delivered_bundle_dir,
_verdict_origin_line,
)
from portfolio_optimiser.verdicts import ProposalFeatures, Verdict, seed_store_from_bundle
# The Step-8 marker is the shared expert-reviewer skill's own, read at call time — the simulation
# takes it from the artifact rather than from a module constant, and so does this test.
_MARKER = load_persona_example().marker
def _verdict(vid: str, rationale: str) -> Verdict:
return Verdict(
id=vid,
proposal_features=ProposalFeatures(
affected_codes=frozenset({"ENERGI-VEGLYS-EL"}),
measure_type="LED-utskifting",
claimed_saving_nok=445500.0,
description="LED-utskifting",
),
decision="approved",
rationale=rationale,
)
def test_the_origin_line_reports_the_delivered_bundles_actual_split() -> None:
"""T-P4.4a: three retrieved, two carrying markers -> one came with the knowledge base.
This is the shape the demo prints today. RED if the classification is inverted or dropped.
"""
retrieved = [
_verdict("seeded", "frøsatt dom uten markør"),
_verdict("promoted", f"persona-dom ({_MARKER})"),
_verdict("inbox", f"driftsnotat ({_INBOX_MARKER})"),
]
line = _verdict_origin_line(retrieved, marker=_MARKER, inbox_marker=_INBOX_MARKER)
assert "1" in line and "2" in line
assert "kunnskapsbasen" in line
def test_the_split_is_computed_and_not_a_written_down_constant() -> None:
"""T-P4.4b (the distinguishing test): a bundle with a SECOND seeded verdict must move the
number.
An implementation that writes "1 of 3" into the string passes T-P4.4a and fails here — which is
the whole reason this test exists. A test that only ever sees the delivered bundle's own split
cannot tell the two implementations apart, and would prove nothing.
"""
retrieved = [
_verdict("seeded-a", "frøsatt dom uten markør"),
_verdict("seeded-b", "en annen frøsatt dom uten markør"),
_verdict("promoted", f"persona-dom ({_MARKER})"),
_verdict("inbox", f"driftsnotat ({_INBOX_MARKER})"),
]
line = _verdict_origin_line(retrieved, marker=_MARKER, inbox_marker=_INBOX_MARKER)
assert "2 av 4" in line, line
def test_both_sentences_are_in_the_pinned_transcript() -> None:
"""T-P4.4d: the two sentences are on the screen the operator has already read.
Checked against the checked-in fasit rather than by starting a fourth demo subprocess — the
fasit is byte-compared to a live run in ``test_golden_transcript_loadbearing``, so a sentence
that is in the file but no longer printed fails there, and a sentence dropped from BOTH fails
here. The provenance half needs this: the anchored-reserve test only rules the reserve's
sentence OUT, so emptying ``_VEGLYS_PROVENANCE`` would leave it green.
"""
fasit = (Path(__file__).resolve().parent / "golden" / "demo-transcript.stdout").read_text(
encoding="utf-8"
)
assert _VEGLYS_PROVENANCE in fasit
assert "med kunnskapsbasen; de øvrige" in fasit
def test_the_delivered_seed_verdict_carries_neither_marker() -> None:
"""T-P4.4c (RED-proof for the classifier): the property the split rests on, measured on the
delivered bundle rather than assumed.
If the seeded verdict's rationale ever contained one of the two markers, it would be counted as
something the demo learned, and the sentence on stage would overstate the loop by one. It would
also mean the marker was present in the knowledge base from the start — which the Step-7 and
Step-8 load-bearing tests already forbid for their own reasons, but this line depends on it too.
"""
store = seed_store_from_bundle(str(_delivered_bundle_dir()))
seeded = [v for v in store.verdicts]
assert seeded, (
"the delivered bundle ships no seeded verdict — the classifier has nothing to see"
)
for verdict in seeded:
assert _MARKER not in verdict.rationale
assert _INBOX_MARKER not in verdict.rationale