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

@ -371,6 +371,43 @@ class SkippedLink:
reason: SkipReason reason: SkipReason
#: Characters an actor may not contain, because each would RESTRUCTURE the flow mapping it is
#: written into. ``": "`` is in the set for a reason that is not decoration: ``decode_flow_value``
#: splits pairs on colon-SPACE, so an actor carrying it would be written out cleanly and then
#: mis-decoded on the way back. The writer and the reader must agree on this set, or the round trip
#: lies while every byte looks fine.
_VERIFIED_UNSAFE_TOKENS = (",", "{", "}", "[", "]", "\n", "\r", ": ")
def verified_field(actor: str, at: str) -> str:
"""Compose the SPEC §5.2 single-verifier flow shorthand ``{ by: <actor>, at: <at> }``.
The ENCODER half of this seam, and a separately named function on purpose: it gives the
round-trip property one site to be measured at, and ``render_frontmatter`` cannot serve
it collapses every newline to a space and therefore cannot emit block form at all.
**The actor is written VERBATIM and is never prefixed with ``human:``.** A caller reaches the
human tier by saying so; minting the prefix on their behalf would fabricate a sign-off nobody
gave.
**Honesty limit, stated:** only ``actor`` is checked against the unsafe set. ``at`` is an ISO
timestamp in every caller today and is not validated here a deliberate scope line, not an
oversight, and the place to revisit it is the invariant record rather than a silent widening.
Raises ``FlowDecodeError`` the same named refusal the reader raises, which is what makes
"the writer refuses exactly what the reader cannot read" structural rather than a convention.
Gated by ``tests/test_provenance_decoder_loadbearing.py``."""
for token in _VERIFIED_UNSAFE_TOKENS:
if token in actor:
raise FlowDecodeError(
f"the actor {actor!r} contains {token!r}, which would restructure the `verified` "
"flow mapping — refusing to write a provenance record that parses cleanly into "
"something no one wrote"
)
return f"{{ by: {actor}, at: {at} }}"
#: A concept's trust level, derived from its ``verified`` actors (SPEC §5.3), lowest to highest. #: A concept's trust level, derived from its ``verified`` actors (SPEC §5.3), lowest to highest.
#: Derived, never stored: OKF records objective signals and refuses to persist a subjective score, #: Derived, never stored: OKF records objective signals and refuses to persist a subjective score,
#: so this is a reading of the actors and not a field any document carries. #: so this is a reading of the actors and not a field any document carries.
@ -744,6 +781,14 @@ def write_concept_file(bundle_dir: str, name: str, frontmatter: dict[str, str],
a frontmatter carrying the complete ingest stamp raises ``IngestStampError`` and NOTHING is a frontmatter carrying the complete ingest stamp raises ``IngestStampError`` and NOTHING is
written. A validation, never a repair the caller is told, not silently corrected. written. A validation, never a repair the caller is told, not silently corrected.
Returns the written path.""" Returns the written path."""
verified = frontmatter.get("verified")
if verified is not None:
# Validation, never repair, and NOT a second copy of the rule: the check IS
# ``decode_flow_value``, so the writer refuses exactly what the reader cannot read. A
# duplicated rule here would be free to drift, and the drifted copy would decide what gets
# written. Scoped to ``verified`` BY NAME — ``render_frontmatter`` keeps collapsing
# newlines for every other key, which this step deliberately does not change.
decode_flow_value(verified, key="verified")
if _carries_complete_ingest_stamp(frontmatter): if _carries_complete_ingest_stamp(frontmatter):
raise IngestStampError( raise IngestStampError(
"refusing to write a curated concept file carrying the COMPLETE ingest ownership stamp " "refusing to write a curated concept file carrying the COMPLETE ingest ownership stamp "

View file

@ -697,6 +697,10 @@ def promote_verdict(
"verdict_id": verdict.id, "verdict_id": verdict.id,
"provenance": f"godkjent av {approver}; eksperiment {experiment}; {timestamp}", "provenance": f"godkjent av {approver}; eksperiment {experiment}; {timestamp}",
"timestamp": timestamp, "timestamp": timestamp,
# SPEC §5.2 provenance, reusing the EXISTING required ``timestamp`` keyword so no
# wall-clock default sneaks in. The approver is written verbatim: a scripted stand-in lands
# in ``machine-confirmed``, which is true of it.
"verified": okf.verified_field(approver, timestamp),
"tags": "[verdict, promoted, HITL]", "tags": "[verdict, promoted, HITL]",
} }
codes = ", ".join(sorted(f.affected_codes)) codes = ", ".join(sorted(f.affected_codes))

View file

@ -19,12 +19,13 @@ from __future__ import annotations
import ast import ast
import itertools import itertools
import shutil
import tempfile import tempfile
from pathlib import Path from pathlib import Path
import pytest import pytest
from portfolio_optimiser import okf from portfolio_optimiser import okf, verdicts
from portfolio_optimiser.okf import _read_body, parse_frontmatter from portfolio_optimiser.okf import _read_body, parse_frontmatter
_OKF_SOURCE = Path(okf.__file__) _OKF_SOURCE = Path(okf.__file__)
@ -509,3 +510,122 @@ def test_a_human_LAST_entry_still_resolves_to_human_reviewed() -> None:
) )
== "machine-confirmed" == "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