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:
parent
587480f050
commit
7b4f85d77c
20 changed files with 1259 additions and 15 deletions
|
|
@ -82,9 +82,27 @@ def _minibase(root: Path) -> Path:
|
|||
return base
|
||||
|
||||
|
||||
def _context(root: Path, *, must_refuse: bool = True) -> Path:
|
||||
def _context(
|
||||
root: Path, *, must_refuse: bool = True, schedule: dict[str, float] | None = None
|
||||
) -> Path:
|
||||
ctx = root / "ctx"
|
||||
(ctx / "docs").mkdir(parents=True)
|
||||
if schedule is not None:
|
||||
# P21 B3: the PROJECT's own price schedule, which is the file a run is handed with
|
||||
# ``--cost-baseline`` and the one the judge measures ``priced`` against.
|
||||
(ctx / "cost-baseline.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"project_id": "proj",
|
||||
"items": {
|
||||
code: {"quantity": 1.0, "unit_cost": unit}
|
||||
for code, unit in schedule.items()
|
||||
},
|
||||
},
|
||||
indent=2,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
(ctx / "bundle.txt").write_text("name: minibase\nbundle_id: minibase\n", encoding="utf-8")
|
||||
approaches = [
|
||||
{
|
||||
|
|
@ -149,6 +167,8 @@ def _write_outbox(
|
|||
citation_snippet: str = "Body of the good one.",
|
||||
decision: str = "validated",
|
||||
tool_calls: list[dict[str, str]] | None = None,
|
||||
anchored: bool = False,
|
||||
reason: str = "no",
|
||||
) -> None:
|
||||
outbox.mkdir(parents=True, exist_ok=True)
|
||||
codes = ["CODE-1"] if codes is None else codes
|
||||
|
|
@ -181,7 +201,7 @@ def _write_outbox(
|
|||
"role": "proposer",
|
||||
"validator_decision": decision,
|
||||
"token_usage": 10,
|
||||
"cost_baseline_anchored": False,
|
||||
"cost_baseline_anchored": anchored,
|
||||
"bundle_id_source": None,
|
||||
"external_calls": [],
|
||||
},
|
||||
|
|
@ -196,7 +216,7 @@ def _write_outbox(
|
|||
"run_id": run_id,
|
||||
"approach_id": approach_id,
|
||||
"outcome_type": "validated" if decision == "validated" else "rejected",
|
||||
**({"reason": "no"} if decision != "validated" else {}),
|
||||
**({"reason": reason} if decision != "validated" else {}),
|
||||
"checker_verdict": None,
|
||||
"verdict_id": "vid",
|
||||
},
|
||||
|
|
@ -216,7 +236,12 @@ def _opened(path: str) -> list[dict[str, str]]:
|
|||
|
||||
def _judge(tmp_path: Path, **kw: object) -> stress.ContextSetVerdict:
|
||||
base = _minibase(tmp_path)
|
||||
ctx = _context(tmp_path, must_refuse=bool(kw.pop("must_refuse", False)))
|
||||
schedule = kw.pop("schedule", None)
|
||||
ctx = _context(
|
||||
tmp_path,
|
||||
must_refuse=bool(kw.pop("must_refuse", False)),
|
||||
schedule=schedule, # type: ignore[arg-type]
|
||||
)
|
||||
outbox = tmp_path / "out"
|
||||
_write_outbox(outbox, "r1", approach_id="a1", **kw) # type: ignore[arg-type]
|
||||
return stress.score_context_set(ctx, outbox, "r1", base)
|
||||
|
|
@ -629,3 +654,100 @@ def test_the_cli_refuses_to_guess_which_base_a_multi_base_outbox_is_for(
|
|||
|
||||
assert stress.main([*argv, "--bundle", "nowhere"]) == 1
|
||||
assert "nowhere" in capsys.readouterr().err
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# P21 B3: the judge reports what the run was ANCHORED on, which codes the project actually PRICES,
|
||||
# and WHICH falsifier caught the falsification arm.
|
||||
#
|
||||
# The measured reason. Rounds 1-4 all ran un-anchored — a vegnormal ships no ``cost-baseline.json``
|
||||
# and the only file loader read one out of the bundle — so stage 0 never spoke and the ``a4`` arm
|
||||
# fell, when it fell, on P7's grounding check. "It was refused" and "the stage that knows what this
|
||||
# project buys refused it" are different facts, and only the second is what anchoring bought.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_p21_priced_is_true_when_the_project_schedule_carries_the_code(tmp_path: Path) -> None:
|
||||
verdict = _judge(tmp_path, schedule={"CODE-1": 2000.0})
|
||||
assert verdict.approaches[0].priced is True
|
||||
|
||||
|
||||
def test_p21_priced_is_false_for_a_code_the_project_does_not_buy(tmp_path: Path) -> None:
|
||||
"""The discriminator: the SAME schedule, a proposal on a code it does not carry."""
|
||||
verdict = _judge(tmp_path, schedule={"CODE-1": 2000.0}, codes=["CODE-9"])
|
||||
assert verdict.approaches[0].priced is False
|
||||
# ... and the control, so the arm cannot be green by measuring nothing.
|
||||
assert (
|
||||
_judge(tmp_path / "b", schedule={"CODE-9": 2000.0}, codes=["CODE-9"]).approaches[0].priced
|
||||
is True
|
||||
)
|
||||
|
||||
|
||||
def test_p21_priced_is_false_without_a_project_schedule(tmp_path: Path) -> None:
|
||||
"""Every round before P21: no schedule, so nothing is priced — reported, never guessed."""
|
||||
assert _judge(tmp_path).approaches[0].priced is False
|
||||
|
||||
|
||||
def test_p21_anchored_follows_the_runs_own_stamp(tmp_path: Path) -> None:
|
||||
"""Read off ``provenance.cost_baseline_anchored``, not re-derived from the set's files.
|
||||
|
||||
Both arms, because a field that is constant is not a measurement: an artefact stamped
|
||||
un-anchored must report ``False`` EVEN WHEN the set ships a schedule — the judge says what the
|
||||
run did, and a run that was never given the file is not anchored by the file existing.
|
||||
"""
|
||||
assert _judge(tmp_path, anchored=True, schedule={"CODE-1": 2000.0}).anchored is True
|
||||
assert _judge(tmp_path / "b", anchored=False, schedule={"CODE-1": 2000.0}).anchored is False
|
||||
|
||||
|
||||
def test_p21_the_falsification_arm_reports_which_stage_caught_it(tmp_path: Path) -> None:
|
||||
"""``stage0-baseline`` is the answer anchoring buys; ``stage0b-grounding`` is what round 4 got.
|
||||
|
||||
Driven through the whole judge rather than through ``rejection_stage`` alone, because the
|
||||
seam being gated is that the judge READS the arm's own outcome artefact — a classifier that
|
||||
was never called would leave every arm reporting ``""`` and the arms below still green.
|
||||
"""
|
||||
base = _minibase(tmp_path)
|
||||
ctx = _context(tmp_path, must_refuse=True, schedule={"CODE-1": 2000.0})
|
||||
outbox = tmp_path / "out"
|
||||
_write_outbox(outbox, "r1", approach_id="a1", tool_calls=_opened(_GOOD))
|
||||
_write_outbox(
|
||||
outbox,
|
||||
"r1",
|
||||
approach_id="a4",
|
||||
codes=["CODE-4"],
|
||||
decision="rejected",
|
||||
reason=("unknown cost code 'CODE-4': not in project proj's cost baseline (1 known codes)"),
|
||||
)
|
||||
verdict = stress.score_context_set(ctx, outbox, "r1", base)
|
||||
assert [(r.approach_id, r.passed, r.stage) for r in verdict.must_refuse] == [
|
||||
("a4", True, "stage0-baseline")
|
||||
]
|
||||
|
||||
other = tmp_path / "b"
|
||||
base2 = _minibase(other)
|
||||
ctx2 = _context(other, must_refuse=True)
|
||||
outbox2 = other / "out"
|
||||
_write_outbox(outbox2, "r1", approach_id="a1", tool_calls=_opened(_GOOD))
|
||||
_write_outbox(
|
||||
outbox2,
|
||||
"r1",
|
||||
approach_id="a4",
|
||||
codes=["CODE-4"],
|
||||
decision="rejected",
|
||||
reason="ungrounded identifier 'CODE-4': it appears nowhere in the input (10 chars)",
|
||||
)
|
||||
assert stress.score_context_set(ctx2, outbox2, "r1", base2).must_refuse[0].stage == (
|
||||
"stage0b-grounding"
|
||||
)
|
||||
|
||||
|
||||
def test_p21_a_validated_falsification_arm_reports_no_stage(tmp_path: Path) -> None:
|
||||
"""``""`` when nothing refused it — an honest absence, never a stage nobody reached."""
|
||||
base = _minibase(tmp_path)
|
||||
ctx = _context(tmp_path, must_refuse=True)
|
||||
outbox = tmp_path / "out"
|
||||
_write_outbox(outbox, "r1", approach_id="a1", tool_calls=_opened(_GOOD))
|
||||
_write_outbox(outbox, "r1", approach_id="a4", codes=["CODE-4"])
|
||||
verdict = stress.score_context_set(ctx, outbox, "r1", base)
|
||||
assert verdict.must_refuse[0].passed is False
|
||||
assert verdict.must_refuse[0].stage == ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue