feat(inbox): mirror bundle_id and segment keys into concept frontmatter

This commit is contained in:
Kjell Tore Guttormsen 2026-09-01 00:06:05 +02:00
commit f6e5ec9305
2 changed files with 200 additions and 1 deletions

View file

@ -37,8 +37,10 @@ from .materialize import (
write_bytes,
)
from .profiles import DEFAULT, BundleProfile
from .segmentation import SegmentEntry
from .structure import (
DocumentStructure,
_render_flow_list,
derive_document_structure,
facet_values,
resolve_structure,
@ -100,6 +102,8 @@ def render_inbox_concept(
ingested_at: str,
profile: BundleProfile = DEFAULT,
structure: DocumentStructure | None = None,
segment: SegmentEntry | None = None,
bundle_id: str | None = None,
) -> str:
"""Frame extracted text as an inbox concept file with its provenance layer.
@ -107,7 +111,22 @@ def render_inbox_concept(
cannot drift onto the extracted text. Fail-fast on an invalid
`ingested_at`, on the reserved verdict layer, and on a title or
`source_file` that would break an index link or inject frontmatter lines.
`segment` and `bundle_id` carry the 1-to-N identity layer and are read ONLY
when the profile declares the segmentation capability. A concept the plan
does not cover keeps today's rule verbatim, and the four shipped profiles
emit the bytes they always did `emit` sorts unnamed keys into the tail, so
a key added unconditionally here would churn every golden.
"""
segmented = profile.segmentation is not None and segment is not None
if segmented:
assert segment is not None
# The PLAN's timestamp, never the call's. A plan replays an
# adjudication, so a rebuild months later has to reproduce the bytes of
# the round that first wrote the concept -- a call-level `ingested_at`
# would make every rebuild differ from every incremental update, which
# is precisely the invariant S7 exists to hold.
ingested_at = segment.ingested_at
validate_ingested_at(ingested_at)
# The verdict layer is RESERVED: the promotion gate is the only path into
@ -145,6 +164,20 @@ def render_inbox_concept(
}
if structure is not None and profile.index.facets is not None:
frontmatter.update(structure_frontmatter(structure, profile.index.facets.keys))
if segmented:
assert segment is not None
policy = profile.segmentation
assert policy is not None
# AFTER the structure update, and that order is the rule rather than an
# accident: a plan's `parent_id` is DECLARED by the adjudicator, while
# `structure`'s `parent` is DERIVED from a document number. Declared
# beats derived, so the authored hierarchy wins over the inferred one.
if bundle_id is not None:
frontmatter[policy.bundle_id_key] = bundle_id
frontmatter[policy.segment_id_key] = segment.segment_id
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
return f"---\n{profile.frontmatter.emit(frontmatter)}\n---\n\n{_normalize_body(text)}"