docs(mandate): how a domain expert commissions a run — and one honesty fix the run itself exposed
`docs/bestille-en-kjoring.md` is the commissioning half of the expert-facing pair (`ekspert-svar.md` is the judging half): the mandate file field by field, how to run it, and — separated deliberately — what a commission does NOT do. It directs what is evaluated, never what is approved. Registered in _LIVE_DOCS, so it cannot silently fall behind the code. The example output in it is COPIED FROM A REAL RUN, not composed, and running that run is what found the defect fixed here: three approaches against the same cost line each validated at 30000 NOK, and the settlement printed "Validated total: 90000 NOK". Commissioned approaches are ALTERNATIVES — they usually attack the same line — so summing them reports money the project cannot realise. A domain expert reading that total would reasonably believe the run found 90k. The settlement now reports how many approaches held and which one the run carries: a selection, not an arithmetic claim. That also removes the last money addition from this module, which is the right place for it not to be. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ULCqjLF61rehj5cZmdUoR3
This commit is contained in:
parent
b9d795307a
commit
30bcdd3544
5 changed files with 174 additions and 10 deletions
|
|
@ -50,6 +50,7 @@ _LIVE_DOCS = (
|
|||
"README.md",
|
||||
"docs/extending.md",
|
||||
"docs/ekspert-svar.md",
|
||||
"docs/bestille-en-kjoring.md",
|
||||
"docs/knowledge-base-recipe.md",
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -260,11 +260,29 @@ def test_settle_carries_the_rejection_reason() -> None:
|
|||
assert "claimed 200000 exceeds feasible 90000" in settle(_ROWS)
|
||||
|
||||
|
||||
def test_settle_totals_only_the_validated_savings() -> None:
|
||||
"""The total is what passed the validator — never the claimed sum of everything attempted."""
|
||||
def test_settle_never_sums_alternative_approaches() -> None:
|
||||
"""Commissioned approaches are ALTERNATIVES, not additive savings — several of them usually
|
||||
attack the same cost line. Summing them would report a figure the project cannot realise.
|
||||
|
||||
MEASURED on a real run: three approaches against one cost line each validated at 30000 and the
|
||||
settlement claimed a 90000 total. What is honest is how many passed and which one the run
|
||||
carries — a selection, not an arithmetic claim.
|
||||
"""
|
||||
rows = (
|
||||
ApproachOutcome(id="a", label="A", status="validated", saving_nok=30_000.0),
|
||||
ApproachOutcome(id="b", label="B", status="validated", saving_nok=20_000.0),
|
||||
)
|
||||
text = settle(rows)
|
||||
assert "50000" not in text # the sum is never formed
|
||||
assert "30000" in text # the best one is named
|
||||
assert "2 of 2" in text
|
||||
|
||||
|
||||
def test_settle_counts_the_rejected_out_of_the_validated_tally() -> None:
|
||||
"""A rejected approach counts toward how many were commissioned, never toward how many held."""
|
||||
text = settle(_ROWS)
|
||||
assert "30000" in text
|
||||
assert "200000 NOK" not in text # the rejected claim is never folded into a total
|
||||
assert "1 of 3" in text
|
||||
assert "200000 NOK" not in text # the rejected claim is never presented as a saving
|
||||
|
||||
|
||||
def test_settle_states_whether_the_target_was_reached() -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue