feat(okf): adjudication_for names the unknown state and a tool carries it
Co-Authored-By: Claude <claude-opus-5>
This commit is contained in:
parent
d62e89935c
commit
ccd65d3b01
3 changed files with 191 additions and 1 deletions
|
|
@ -455,6 +455,60 @@ def trust_tier(entries: tuple[dict[str, str], ...] | None) -> TrustTier:
|
|||
return "machine-confirmed"
|
||||
|
||||
|
||||
class AdjudicationValueError(ValueError):
|
||||
"""A concept declares an ``adjudication`` value outside the closed vocabulary.
|
||||
|
||||
A ``ValueError`` subclass (the ``IngestStampError`` precedent) so a malformed knowledge base
|
||||
reaches the CLI's refusal tuple and hosting's 400 arm rather than the crash channel."""
|
||||
|
||||
|
||||
#: Whether a concept has been ADJUDICATED, per the cross-repo contract. The value set on the wire
|
||||
#: is CLOSED (``proposed`` | ``adjudicated``); the third token is this consumer's, and it is what
|
||||
#: absence means. See ``docs/okf-konsum-kontrakter.md`` § 2, which is the source for this rule.
|
||||
AdjudicationState = Literal["proposed", "adjudicated", "unknown"]
|
||||
|
||||
#: The closed on-the-wire vocabulary. ``unknown`` is deliberately NOT in it: it is what this reader
|
||||
#: concludes from absence, never something a document may declare.
|
||||
_ADJUDICATION_WIRE_VALUES = ("proposed", "adjudicated")
|
||||
|
||||
|
||||
def adjudication_for(path: str | Path) -> AdjudicationState:
|
||||
"""Read a concept's adjudication state, with absence as a FIRST-CLASS state.
|
||||
|
||||
A concept that does not carry the key is ``unknown`` — *we did not learn whether this was
|
||||
adjudicated*, which is what an older bundle looks like. **Collapsing that into ``absent``**
|
||||
(*it was not adjudicated*) **is the same defect as collapsing ``unreadable`` into ``absent``**
|
||||
one layer up, and the same defect removed from ``RunResult.verdict``.
|
||||
|
||||
A value outside the two named ones is **refused by name**, never mapped to ``unknown``:
|
||||
validation, never repair. An EMPTY value is refused for the same reason — present-but-empty is
|
||||
a different fact from absent, and folding it in would recreate the collapse this function
|
||||
exists to prevent.
|
||||
|
||||
**Read through ``parse_frontmatter``, NOT ``evidence_for`` — and that is a MEASUREMENT, not a
|
||||
preference.** The plan specified ``evidence_for(path, key="adjudication")``; the contract as
|
||||
delivered makes ``adjudication`` a plain SCALAR, and ``evidence_for`` routes its value through
|
||||
``decode_flow_value``. Measured 2026-09-02: BOTH valid values come back as an identical
|
||||
``state='unreadable', reason='unsupported-flow'`` record, so that route cannot tell ``proposed``
|
||||
from ``adjudicated`` at all. ``parse_frontmatter`` is the repo's scalar reader over the SAME
|
||||
``_split_frontmatter`` scan, so this is a second READER of one parse — never a second parser,
|
||||
which is the rule that route was reaching for.
|
||||
|
||||
Gated by ``tests/test_falsification_verdict_loadbearing.py``."""
|
||||
raw = parse_frontmatter(path).get("adjudication")
|
||||
if raw is None:
|
||||
return "unknown"
|
||||
value = unquote_scalar(raw)
|
||||
if value not in _ADJUDICATION_WIRE_VALUES:
|
||||
raise AdjudicationValueError(
|
||||
f"{value!r} is not an `adjudication` value — the vocabulary is closed to "
|
||||
f"{' | '.join(_ADJUDICATION_WIRE_VALUES)}, and mapping an unrecognised one to "
|
||||
"`unknown` would invent the very state that token exists to keep honest"
|
||||
)
|
||||
# ``value`` is one of the wire literals, which the Literal type also admits.
|
||||
return value # type: ignore[return-value]
|
||||
|
||||
|
||||
#: What a document says about ONE provenance key. Three states, and the third is the whole point:
|
||||
#: collapsing ``unreadable`` into ``absent`` turns a verdict on missing evidence into evidence of
|
||||
#: absence.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue