feat(fase1): dimension-free dedup key + cross-dimension overlap flag (F1)
This commit is contained in:
parent
13905193f7
commit
e0778d2230
2 changed files with 149 additions and 14 deletions
78
tests/test_ledger_loadbearing.py
Normal file
78
tests/test_ledger_loadbearing.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
"""Load-bearing seams for the savings ledger (Fase 1 — SC4/SC5/SC6/SC8).
|
||||
|
||||
Step 5 (SC4) — the dimension-free dedup gate: the same underlying candidate (same codes+measure+
|
||||
amount) realized under two dimensions counts ONCE in the portfolio sum — double-counting across
|
||||
dimensions is the exact error SC4 warns against — while the overlap is FLAGGED (never silently
|
||||
merged). RED if the dimension-free sum-key dedup is detached (the sum doubles). Inverse control:
|
||||
two DISTINCT realizations with the same codes+measure but a different amount stay SEPARATE (a
|
||||
magnitude-free identity would collide them).
|
||||
|
||||
(Step 6 extends this file with the fail-closed ``realize`` gate + øre-boundary tests; Step 8 adds
|
||||
the goal-stop detach.)
|
||||
|
||||
Pattern: ``tests/test_step8_promotion_loadbearing.py:77`` (fail-closed gate trio).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from portfolio_optimiser.ledger import (
|
||||
LedgerEntry,
|
||||
SavingsLedger,
|
||||
_candidate_identity,
|
||||
stamp,
|
||||
)
|
||||
|
||||
_TS = "2026-07-06T00:00:00Z"
|
||||
_CODES = frozenset({"ENERGI-TOTAL-EL"})
|
||||
_MEASURE = "energy_efficiency"
|
||||
|
||||
|
||||
def _identity(amount_ore: int) -> str:
|
||||
return _candidate_identity(affected_codes=_CODES, measure_type=_MEASURE, amount_ore=amount_ore)
|
||||
|
||||
|
||||
def _entry(dimension: str, *, amount_ore: int) -> LedgerEntry:
|
||||
return LedgerEntry(
|
||||
project_id="P1",
|
||||
dimension=dimension,
|
||||
candidate_identity=_identity(amount_ore),
|
||||
amount_ore=amount_ore,
|
||||
verdict_id="v1",
|
||||
provenance=stamp(approver="ekspert", experiment="sim", timestamp=_TS),
|
||||
)
|
||||
|
||||
|
||||
def test_same_candidate_two_dimensions_counts_once_and_flags_overlap() -> None:
|
||||
"""LOAD-BEARING (SC4): the same underlying candidate realized under two dimensions contributes
|
||||
ONCE to the portfolio sum, and the overlap is flagged. RED if the dimension-free sum-key dedup
|
||||
is detached in ``_dedup_amount`` (the sum then doubles to 10000)."""
|
||||
ledger = SavingsLedger()
|
||||
assert ledger.add_realized(_entry("energi", amount_ore=5000)) is True
|
||||
# Same candidate identity (same codes+measure+amount), a DIFFERENT dimension -> distinct full
|
||||
# key -> stored, so the overlap is visible; the sum must still count it once.
|
||||
assert ledger.add_realized(_entry("asfalt", amount_ore=5000)) is True
|
||||
|
||||
assert ledger.portfolio_total() == 5000, (
|
||||
"double-counted the same candidate across dimensions (SC4)"
|
||||
)
|
||||
assert ledger.per_project_total("P1") == 5000
|
||||
assert ledger.overlaps() == [("P1", _identity(5000))]
|
||||
|
||||
|
||||
def test_distinct_amounts_same_codes_measure_are_not_collided() -> None:
|
||||
"""INVERSE CONTROL (fixes the magnitude-free collision): two DISTINCT realizations with the same
|
||||
codes+measure but a different amount are separate candidates -> both counted, no overlap."""
|
||||
ledger = SavingsLedger()
|
||||
assert ledger.add_realized(_entry("energi", amount_ore=5000)) is True
|
||||
assert ledger.add_realized(_entry("energi", amount_ore=7000)) is True # distinct identity
|
||||
|
||||
assert ledger.portfolio_total() == 12000 # both counted (no collision)
|
||||
assert ledger.overlaps() == [] # single dimension -> no cross-dimension overlap
|
||||
|
||||
|
||||
def test_exact_full_key_duplicate_is_not_stored_twice() -> None:
|
||||
"""An exact (project, dimension, candidate) re-add is a no-op — storage keys on the full key."""
|
||||
ledger = SavingsLedger()
|
||||
assert ledger.add_realized(_entry("energi", amount_ore=5000)) is True
|
||||
assert ledger.add_realized(_entry("energi", amount_ore=5000)) is False # exact duplicate
|
||||
assert ledger.portfolio_total() == 5000
|
||||
Loading…
Add table
Add a link
Reference in a new issue