feat(inbox): surface adjudication state and its dwell time
This commit is contained in:
parent
233cdc5671
commit
a60312a5f3
9 changed files with 219 additions and 9 deletions
|
|
@ -194,6 +194,19 @@ def render_inbox_concept(
|
|||
frontmatter[policy.offset_key] = _render_flow_list([str(offset) for offset in segment.span])
|
||||
if segment.parent_id is not None:
|
||||
frontmatter["parent"] = segment.parent_id
|
||||
if policy.adjudication_key is not None:
|
||||
# The per-entry verdict IS the discriminator. A plan-level
|
||||
# `adjudicated: true` with no record for THIS entry leaves it
|
||||
# `proposed`: B2 forbids the ratified state without the three keys
|
||||
# beside it, so a flag alone cannot promote a segment.
|
||||
verdict = segment.adjudication
|
||||
if verdict is None:
|
||||
frontmatter[policy.adjudication_key] = ADJUDICATION_PROPOSED
|
||||
else:
|
||||
frontmatter[policy.adjudication_key] = ADJUDICATION_ADJUDICATED
|
||||
frontmatter["adjudicated_by"] = verdict.adjudicated_by
|
||||
frontmatter["adjudicated_at"] = verdict.adjudicated_at
|
||||
frontmatter["adjudication_dwell_s"] = str(verdict.adjudication_dwell_s)
|
||||
return f"---\n{profile.frontmatter.emit(frontmatter)}\n---\n\n{_normalize_body(text)}"
|
||||
|
||||
|
||||
|
|
@ -847,6 +860,23 @@ def process_inbox(
|
|||
)
|
||||
|
||||
|
||||
#: The adjudication states a segment concept may carry, and the whole set.
|
||||
#: CLOSED on purpose (PM decision B2, `docs/plan/office-intake.md` § 5): a
|
||||
#: value outside it is an error, not an extension point. The consumer's half of
|
||||
#: the same contract is that ABSENCE of the key means `unknown` -- an older
|
||||
#: bundle -- never a collapse to `absent`, so a producer emitting the key
|
||||
#: inconsistently would make that distinction unmeasurable on their side.
|
||||
ADJUDICATION_PROPOSED = "proposed"
|
||||
ADJUDICATION_ADJUDICATED = "adjudicated"
|
||||
ADJUDICATION_STATES = (ADJUDICATION_PROPOSED, ADJUDICATION_ADJUDICATED)
|
||||
|
||||
#: Written beside the state when, and only when, it is `adjudicated`. The dwell
|
||||
#: time travels WITH the verdict: a ratified flag carrying no per-item time is
|
||||
#: unfalsifiable, and it is the same number that makes adjudication throughput
|
||||
#: measurable at all.
|
||||
ADJUDICATION_COMPANION_KEYS = ("adjudicated_by", "adjudicated_at", "adjudication_dwell_s")
|
||||
|
||||
|
||||
def _validate_facets(structure: DocumentStructure, profile: BundleProfile) -> None:
|
||||
"""Refuse a document whose values cannot be rendered as index facets.
|
||||
|
||||
|
|
@ -859,8 +889,22 @@ def _validate_facets(structure: DocumentStructure, profile: BundleProfile) -> No
|
|||
markers are this library's own tokens.
|
||||
"""
|
||||
assert profile.index.facets is not None
|
||||
values = structure_frontmatter(structure, profile.index.facets.keys)
|
||||
policy = profile.segmentation
|
||||
key = None if policy is None else policy.adjudication_key
|
||||
# Refused HERE rather than at reprojection, for the reason above: the only
|
||||
# adjudication value that can be wrong is one the producer declared in the
|
||||
# dropped document itself, and refusing it per file keeps a single bad
|
||||
# document from failing the index for every other one.
|
||||
if key is not None and key in values and values[key] not in ADJUDICATION_STATES:
|
||||
raise MaterializationError(
|
||||
f"frontmatter key {key!r} carries {values[key]!r}, which is outside the closed "
|
||||
f"set {ADJUDICATION_STATES} — the adjudication state is a contract, not an "
|
||||
"extension point",
|
||||
code="index_facet_invalid",
|
||||
)
|
||||
try:
|
||||
profile.index.facets.render(structure_frontmatter(structure, profile.index.facets.keys))
|
||||
profile.index.facets.render(values)
|
||||
except ValueError as exc:
|
||||
raise MaterializationError(str(exc), code="index_facet_invalid") from exc
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue