feat(verdicts): promoted verdicts carry a verified field with the actor verbatim

Co-Authored-By: Claude <claude-opus-5>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-02 20:29:32 +02:00
commit 3d76a46d76
3 changed files with 170 additions and 1 deletions

View file

@ -19,12 +19,13 @@ from __future__ import annotations
import ast
import itertools
import shutil
import tempfile
from pathlib import Path
import pytest
from portfolio_optimiser import okf
from portfolio_optimiser import okf, verdicts
from portfolio_optimiser.okf import _read_body, parse_frontmatter
_OKF_SOURCE = Path(okf.__file__)
@ -509,3 +510,122 @@ def test_a_human_LAST_entry_still_resolves_to_human_reviewed() -> None:
)
== "machine-confirmed"
)
# --- Step 6: the writers emit `verified`, with the actor verbatim ------------------------------
_ENERGI_BUNDLE = Path(__file__).resolve().parents[1] / "shared" / "examples" / "bygg-energi-mikro"
def _bundle_copy(tmp_path: Path) -> str:
"""Promotion WRITES into the bundle, so every arm works on a throwaway copy — the shared,
pull-only framework-neutral fixture is never mutated (the Step-8 discipline)."""
dst = tmp_path / "bundle"
shutil.copytree(_ENERGI_BUNDLE, dst)
return str(dst)
def _approved(bundle_dir: str) -> verdicts.Verdict:
return verdicts.Verdict(
id="PROVENANCE-ROUNDTRIP",
proposal_features=verdicts.bundle_candidate_features(bundle_dir),
decision="approved",
rationale="godkjent",
)
def test_verified_field_emits_the_spec_shorthand_exactly() -> None:
"""(a) The §5.2 single-verifier flow shorthand, byte for byte."""
assert (
okf.verified_field("persona", "2026-06-30T09:00:00Z")
== "{ by: persona, at: 2026-06-30T09:00:00Z }"
)
@pytest.mark.parametrize("actor", ["a,b", "a{b", "a}b", "a[b", "a]b", "a\nb", "a: b"])
def test_verified_field_refuses_an_actor_that_would_restructure_the_value(actor: str) -> None:
"""(d) The unsafe set, and ``": "`` is in it for a reason that is NOT decoration.
``decode_flow_value`` splits pairs on colon-SPACE. An actor containing it would be written out
cleanly and then MIS-DECODED on the way back the writer and the reader must agree on the
unsafe set, or the round trip lies while every byte looks fine.
"""
with pytest.raises(ValueError):
okf.verified_field(actor, "2026-06-30T09:00:00Z")
def test_a_promoted_verdict_round_trips_to_machine_confirmed(tmp_path: Path) -> None:
"""(b) Write with ``promote_verdict``, read with ``read_provenance``, tier with ``trust_tier``.
A plain approver lands in ``machine-confirmed``, and that is TRUE of it: the demo passes
``"ekspert-persona (sim)"``, a scripted stand-in, and prefixing it with ``human:`` on the
caller's behalf would mint a human sign-off nobody gave — the fabricated-provenance defect one
layer up.
"""
bundle_dir = _bundle_copy(tmp_path)
path = verdicts.promote_verdict(
bundle_dir,
_approved(bundle_dir),
approver="ekspert-persona (sim)",
experiment="exp-B",
timestamp="2026-06-30T09:00:00Z",
)
raw = path.read_text(encoding="utf-8")
assert "verified: { by: ekspert-persona (sim), at: 2026-06-30T09:00:00Z }" in raw
entries = okf.read_provenance(path, "verified")
assert entries == ({"by": "ekspert-persona (sim)", "at": "2026-06-30T09:00:00Z"},)
assert okf.trust_tier(entries) == "machine-confirmed"
def test_a_human_prefixed_approver_reaches_the_human_tier(tmp_path: Path) -> None:
"""(b, second half) The ``human-reviewed`` tier is reached by a CALLER saying so."""
bundle_dir = _bundle_copy(tmp_path)
path = verdicts.promote_verdict(
bundle_dir,
_approved(bundle_dir),
approver="human:ktg",
experiment="exp-B",
timestamp="2026-06-30T09:00:00Z",
)
assert okf.trust_tier(okf.read_provenance(path, "verified")) == "human-reviewed"
@pytest.mark.parametrize(
("bad", "marker"),
[
("{ by: a, at: b }\n{ by: c, at: d }", "one line"),
("- { by: a, at: b }", "neither a flow sequence nor a flow mapping"),
("[ a.pdf ]", "bare scalar"),
],
)
def test_write_concept_file_refuses_a_verified_value_outside_the_subset(
tmp_path: Path, bad: str, marker: str
) -> None:
"""(c) Validation, never repair — and NOTHING is written.
``render_frontmatter`` collapses newlines for every key, which for ``verified`` would turn a
block value into a single line that decodes to something nobody wrote. The refusal is scoped
to ``verified`` BY NAME; every other key keeps the old collapsing behaviour, and that is stated
rather than hidden by the control arm below.
"""
with pytest.raises(okf.FlowDecodeError) as excinfo:
okf.write_concept_file(str(tmp_path), "c.md", {"type": "concept", "verified": bad}, "b\n")
# The marker pins that the writer's refusal IS the reader's refusal, not a second rule beside
# it — a hand-rolled copy here would refuse with words of its own and be free to drift.
assert marker in str(excinfo.value)
assert not (tmp_path / "c.md").exists(), "the refusal wrote a file anyway"
def test_the_refusal_is_scoped_to_verified_and_other_keys_are_untouched(tmp_path: Path) -> None:
"""CONTROL — a refusal that fired on every key would break `render_frontmatter`'s contract for
the whole repo, and a refusal that fired on nothing would be worthless. Both are excluded."""
path = okf.write_concept_file(
str(tmp_path),
"c.md",
{"type": "concept", "provenance": "line one\nline two", "verified": "{ by: p, at: t }"},
"body\n",
)
written = path.read_text(encoding="utf-8")
assert "provenance: line one line two" in written, "an unrelated key stopped being collapsed"
assert "verified: { by: p, at: t }" in written