feat(p21): the PROJECT carries the price, so a run against a road normal can be anchored

Four paid stress rounds ran entirely UN-ANCHORED, all of them, because the one file
loader reads cost-baseline.json out of the BUNDLE and no vegnormal ships one: N100,
N200, N500 and R761 are knowledge, and knowledge carries requirements, never amounts.
The validator's stage 0 -- the one stage that tells an invented cost line from a line
this project actually buys -- was skipped in every single run, so "validated" could not
mean what it says. P20 G1/G2 measured real R761 process numbers (12.11 three times on
Soraasen, 1.1.1 on Lindaas) validating with amounts nobody had anywhere.

--cost-baseline FILE is PM decision (e), taken over the three alternatives P20 wrote
down. A LOADED object, never a path (prepass_payload's rule): the CLI owns the file and
loads it ONCE, so the notice, the stamp and every base of an --across-bundle pass all
descend from one read. ONE parse, two doors -- load_cost_baseline delegates to
load_cost_baseline_file -- while safe_resolve stays on the bundle door alone, because a
project's own schedule is legitimately outside every base. No tolerant twin: this path
exists only because an operator NAMED a file.

DEL B: five anchored context sets, a1-a3 with their line and a4 with none, so stage 0 is
what catches the falsification arm. THE ORDER'S OWN ARM (h) WAS FELLED BY MEASUREMENT:
"no baseline code is a requirement number the base declares" is measured 0 of 4 on the
project-coded sets and 5 of 5 on kontrakt-sorasen -- which is what R761 Prosesskoden IS,
a bill of quantities priced BY process code. The complement keeps both, and the order's
own mutation still bites.

DEL B3: the judge reports anchored (off the run's own stamp), priced per row, and WHICH
falsifier caught the falsification arm.

Load-bearing MEASURED, five mutations all red against the WHOLE suite, green control
1850/5 (from 1809/5, superset, 0 removed), golden byte-unchanged:
A3(i) the flag is read but the baseline is unused (3 red) . A3(ii) only the first base
gets it (1) . A3(iii) report_forbidden drops it (1) . B2(i) a4 gets a line (1, arm (g)
alone) . B2(ii) a code swapped to 12.11 (2, arms (f) and (h)).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-15 10:49:10 +02:00
commit 7b4f85d77c
20 changed files with 1259 additions and 15 deletions

View file

@ -46,6 +46,7 @@ import pytest
from pydantic import ValidationError
from portfolio_optimiser import okf
from portfolio_optimiser.ir import CostBaseline, CostBaselineLine
from portfolio_optimiser.mandate import load_mandate
from portfolio_optimiser.stress import read_bundle_declarations
@ -492,3 +493,169 @@ def test_the_fasit_titles_are_distinct_not_the_collapsed_sources_title(set_dir:
"okf.parse_frontmatter collapsed these titles onto the sources block again — the P15 fix "
"in okf._frontmatter_from_text has regressed"
)
# --------------------------------------------------------------------------------------------
# (f) + (g) + (h): the set is ANCHORED (P21 B2).
#
# The measured reason these exist. Four paid rounds ran entirely un-anchored, because the only
# file loader reads ``cost-baseline.json`` out of the BUNDLE and no road normal carries prices — a
# vegnormal is knowledge, the price belongs to the PROJECT. With ``--cost-baseline`` the project
# supplies its own schedule, so the validator's stage 0 judges again: (f) every answerable approach
# has a line to reconcile against, and (g) the falsification arm has NONE, so the code it proposes
# is refused as "not in the project's cost baseline" — by stage 0, the one stage that can tell an
# invented line from a real one, instead of by the weaker downstream gates.
#
# (f) and (g) are SEPARATE arms rather than one loop over all approaches, because they are opposite
# claims about opposite rows: a single arm asserting "exactly the non-refuse codes are present"
# would go red for either defect and name neither.
# --------------------------------------------------------------------------------------------
def _set_baseline(set_dir: Path) -> CostBaseline:
return okf.load_cost_baseline_file(str(set_dir / "cost-baseline.json"))
@pytest.mark.parametrize("set_dir", _SETS, ids=_SET_IDS)
def test_f_every_answerable_approach_has_a_cost_line(set_dir: Path) -> None:
"""Unconditional — the schedule is the PROJECT's and needs no knowledge base to read.
The total is asserted against the approach's own estimate as well as the code's presence:
``SavingsProposal`` refuses ``claimed_saving_nok > sum(affected_items.total)``, so a line that
exists but is smaller than the saving commissioned against it would make the approach
unbuildable a set that looks anchored and cannot be run.
"""
baseline = _set_baseline(set_dir)
assert 4 <= len(baseline.items) <= 8, (
f"{set_dir.name}: {len(baseline.items)} cost lines — the order asks for 4-8"
)
assert baseline.project_id == set_dir.name, (
f"{set_dir.name}: the schedule names project {baseline.project_id!r}"
)
fasit = json.loads((set_dir / "fasit.json").read_text(encoding="utf-8"))
refused = {row["approach_id"] for row in fasit["must_refuse"]}
for approach in load_mandate(set_dir / "mandate.json").approaches:
if approach.id in refused:
continue
missing = [c for c in approach.affected_codes if c not in baseline.items]
assert not missing, (
f"{set_dir.name}: {approach.id} is answerable but {missing} carry no line in the "
f"project's schedule ({sorted(baseline.items)})"
)
total = sum(
baseline.items[c].quantity * baseline.items[c].unit_cost
for c in approach.affected_codes
)
assert approach.claimed_saving_nok is not None
assert total >= approach.claimed_saving_nok, (
f"{set_dir.name}: {approach.id} claims {approach.claimed_saving_nok:g} against lines "
f"totalling {total:g} — no proposal on it can satisfy claimed <= total"
)
@pytest.mark.parametrize("set_dir", _SETS, ids=_SET_IDS)
def test_g_the_falsification_arm_has_no_cost_line(set_dir: Path) -> None:
"""The ``must_refuse`` approach's code is ABSENT, so stage 0 is what catches it.
This is the half that makes the anchoring worth measuring rather than just present: rule U
already says the base carries no GROUND for that line, and P7's stage 0b says the identifier is
ungrounded in the delivered input but neither of those is the stage that knows what this
project actually buys. Stage 0 is, and it can only speak when the schedule exists.
"""
baseline = _set_baseline(set_dir)
fasit = json.loads((set_dir / "fasit.json").read_text(encoding="utf-8"))
by_id = {a.id: a for a in load_mandate(set_dir / "mandate.json").approaches}
assert fasit["must_refuse"], f"{set_dir.name} declares no falsification arm"
for row in fasit["must_refuse"]:
approach = by_id[row["approach_id"]]
carried = [c for c in approach.affected_codes if c in baseline.items]
assert not carried, (
f"{set_dir.name}: the falsification arm {approach.id} carries {carried} in the "
"project's schedule, so stage 0 would ACCEPT the line it exists to refuse"
)
@pytest.mark.parametrize("set_dir", _SETS, ids=_SET_IDS)
def test_h_no_cost_line_smuggles_in_an_uncommissioned_requirement_number(set_dir: Path) -> None:
"""No line of the schedule is a reference number the base declares AND nobody commissions.
**The order words this arm as "no baseline code is a requirement number the base declares", and
that rule was FELLED BY MEASUREMENT before anything was built on it.** Measured 15.09 against
``okf.declared_reference_numbers`` over the four mounted bases: the four project-coded sets
carry 0 such codes, and ``kontrakt-sorasen-2027`` carries FIVE of five ``12.1``, ``12.12``,
``22.1``, ``52.11``, ``51.1`` are real R761 ``prosessnr``. That is not an accident in the set;
it is what R761 Prosesskoden IS. A Norwegian road contract's bill of quantities is priced BY
process code, so the project's schedule and the corpus's vocabulary share an identifier
namespace by design and the order's rule would have forced a rewrite of the ONE set P20's
decision (e) was chosen to preserve.
The COMPLEMENT keeps both: a schedule may price what the commission names, and may not
INTRODUCE a corpus identifier as a cost line nobody ordered. The order's own mutation still
bites swapping a code for ``12.11`` (a declared ``prosessnr`` no approach commissions) goes
red here while the five real process codes pass because an approach names each of them.
Needs the base (the vocabulary is the base's), so it SKIPS with the root named.
"""
baseline = _set_baseline(set_dir)
commissioned = {
code
for approach in load_mandate(set_dir / "mandate.json").approaches
for code in approach.affected_codes
}
declared: set[str] = set()
concepts = 0
for block in read_bundle_txt(set_dir / "bundle.txt"):
bundle = okf.navigate_bundle(str(_require_base(block)))
for f in bundle.context_files:
concepts += 1
declared |= set(okf.declared_reference_numbers(f))
assert concepts >= 100, (
f"{set_dir.name}: scanned {concepts} concepts — too few to be the base(s)"
)
assert declared, f"{set_dir.name}: the base(s) declare NO reference numbers — nothing to test"
smuggled = sorted(c for c in baseline.items if c in declared and c not in commissioned)
assert not smuggled, (
f"{set_dir.name}: cost line(s) {smuggled} are reference numbers the knowledge base "
"declares and no approach commissions — the schedule would be introducing the corpus's "
"own identifiers as prices nobody ordered"
)
def test_known_positive_f_a_missing_cost_line_is_caught(tmp_path: Path) -> None:
baseline = _set_baseline(_CONTEXT_ROOT / "gate-nordvik-2027")
assert "GATE-KRYSS-01" in baseline.items
stripped = CostBaseline(
project_id=baseline.project_id,
items={k: v for k, v in baseline.items.items() if k != "GATE-KRYSS-01"},
)
assert "GATE-KRYSS-01" not in stripped.items
def test_known_positive_g_a_line_for_the_falsification_arm_is_caught() -> None:
"""The order's mutation (i): give a4 a line, and (g)'s assertion must fail on this set."""
baseline = _set_baseline(_CONTEXT_ROOT / "gate-nordvik-2027")
priced = dict(baseline.items)
priced["GATE-GANG-ENHET"] = CostBaselineLine(quantity=6, unit_cost=50_000.0)
fasit = json.loads((_CONTEXT_ROOT / "gate-nordvik-2027" / "fasit.json").read_text("utf-8"))
by_id = {
a.id: a
for a in load_mandate(_CONTEXT_ROOT / "gate-nordvik-2027" / "mandate.json").approaches
}
for row in fasit["must_refuse"]:
carried = [c for c in by_id[row["approach_id"]].affected_codes if c in priced]
assert carried == ["GATE-GANG-ENHET"]
def test_known_positive_h_an_uncommissioned_requirement_number_is_caught() -> None:
"""The order's mutation (ii): swap a code for ``12.11``.
Driven against a KNOWN vocabulary rather than the mounted base, so this known-positive runs
unconditionally a control that skipped with the base would leave the arm's discriminator
unproven on exactly the machines that cannot run the arm.
"""
declared = {"12.1", "12.11", "12.12"}
commissioned = {"12.1", "12.12"}
assert sorted(c for c in {"12.1", "12.12"} if c in declared and c not in commissioned) == []
assert sorted(c for c in {"12.1", "12.11"} if c in declared and c not in commissioned) == [
"12.11"
]