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.
124 lines
5.9 KiB
Python
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
|