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
#: 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.
#: 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.
@ -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
written. A validation, never a repair the caller is told, not silently corrected.
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):
raise IngestStampError(
"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,
"provenance": f"godkjent av {approver}; eksperiment {experiment}; {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]",
}
codes = ", ".join(sorted(f.affected_codes))

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