feat(okf): one bundle-id rule, reconciled against the mount and origin-marked

[skip-docs] — the invariant row for this plan lands in Step 13, where the mutations
that force it have been measured. Documenting a seam before its measurement is
the claim-without-evidence class this repo writes rows against.

Co-Authored-By: Claude <claude-opus-5>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-02 21:04:04 +02:00
commit 842c51401d
5 changed files with 388 additions and 4 deletions

View file

@ -859,7 +859,12 @@ def navigator_tools(bundle_dirs: Sequence[str]) -> list[FunctionTool]:
description="Open ONE knowledge base by id and read its navigated context.",
)
def read_bundle(bundle_id: str) -> str:
return okf.bundle_context(okf.navigate_bundle(_resolve_bundle(index, bundle_id)))
bundle_dir = _resolve_bundle(index, bundle_id)
# The base is OPENED here, so this is where it is reconciled against its mount (Step 10).
# ``_bundle_index`` above stays PURE — it does no file I/O, and must not: two of its own
# arms configure directories that do not exist and expect an id error, not an I/O one.
okf.reconcile_bundle_id(bundle_dir)
return okf.bundle_context(okf.navigate_bundle(bundle_dir))
@tool(
name="read_file",

View file

@ -51,8 +51,9 @@ class Approach(BaseModel):
id: str = Field(min_length=1)
label: str = Field(min_length=1)
description: str = ""
#: Which knowledge base this approach belongs to (§ C.7), by the base's id — the directory's
#: BASENAME, exactly as ``explore._bundle_index`` names it. DEFAULTS to empty, meaning "no base
#: Which knowledge base this approach belongs to (§ C.7), by the base's id — exactly as
#: ``okf.reconcile_bundle_id`` resolves it (the base's own declaration where it makes one, the
#: mount's basename otherwise). DEFAULTS to empty, meaning "no base
#: named": a legitimate statement when the run has only one base to name, and what keeps every
#: mandate written before multi-base existed valid and dispatchable unchanged.
#:

View file

@ -846,6 +846,101 @@ def navigate_bundle(bundle_dir: str) -> Bundle:
return Bundle(dir=bundle_dir, files=tuple(files), skipped=tuple(skipped))
class BundleIdMismatch(ValueError):
"""A base declares a ``bundle_id`` its mount does not carry.
A ``ValueError`` DELIBERATELY: it must land on ``run.main``'s refusal tuple and on hosting's
400 arm rather than on the crash channel. ``ExplorationError`` is a ``RuntimeError`` and would
give an operator a traceback and an automated caller a 500 a configuration mistake dressed
as a server fault.
"""
#: Which source answered. THREE values, not a boolean (operator decision B1): a caller that cannot
#: tell "the concept said so" from "we fell back twice" has been handed a stamp it cannot audit.
BundleIdOrigin = Literal["declared-concept", "declared-index", "mount-derived"]
_BUNDLE_ID_KEY = "bundle_id"
@dataclass(frozen=True)
class ResolvedBundleId:
"""A base's id together with WHERE it came from.
``origin`` is REQUIRED WITHOUT DEFAULT, for the reason ``ProvenanceStamp.cost_baseline_anchored``
is: both defaults would lie about an event. Defaulting to ``"mount-derived"`` would let a
resolver that never read the base claim it had; defaulting to a declared value would claim a
declaration that never happened.
"""
id: str
origin: BundleIdOrigin
def _declared_bundle_id(frontmatter: dict[str, str]) -> str:
"""The declared id, de-quoted through ``unquote_scalar`` — this repo's ONE de-quoting rule."""
return unquote_scalar(frontmatter.get(_BUNDLE_ID_KEY, "")).strip()
def _reconciled(
declared: str, mount: str, origin: BundleIdOrigin, bundle_dir: str
) -> ResolvedBundleId:
if declared != mount:
raise BundleIdMismatch(
f"knowledge base {bundle_dir!r} declares bundle_id {declared!r} but is mounted as "
f"{mount!r}; an approach names a base by that id, so a run would evaluate against one "
f"and report the other (source: {origin})"
)
return ResolvedBundleId(id=declared, origin=origin)
def reconcile_bundle_id(
bundle_dir: str | Path, *, concept_name: str | None = None
) -> ResolvedBundleId:
"""Resolve a base's ``bundle_id`` against the mount it was opened from — the ONE rule.
``bundle_id`` denotes the corpus **as a mounted artefact**, never the production event that made
it (operator decision D6). That denotation cannot be changed once artefacts bear the stamp,
which is why it is written down here rather than left to each call site.
Resolution order is operator decision B1 identity is the pair ``(bundle_id, concept_id)``, and
the CONCEPT's own frontmatter is consulted first:
1. ``concept_name``'s frontmatter, when a concept is named and declares the key →
``"declared-concept"``;
2. the root ``index.md``'s frontmatter → ``"declared-index"``;
3. the mount's basename → ``"mount-derived"``.
A declared id that DISAGREES with the mount raises ``BundleIdMismatch`` at whichever source
declared it. A base whose root ``index.md`` cannot be read is **unknown, not undeclared**:
``navigate_bundle``'s fail-fast propagates unchanged, because reading an unreadable base as
"it declares nothing" would widen the answer on missing evidence.
MEASURED 2026-09-02: no file under ``shared/`` declares the key (zero ``^bundle_id`` hits
against a known-positive control of 31 files carrying ``^type:``), so every base in this repo
resolves ``mount-derived`` today and both declared branches are DEFENSIVE.
:raises BundleIdMismatch: a declared id the mount does not carry.
:raises ValueError: the root ``index.md`` is missing or unreadable.
"""
root = str(bundle_dir)
mount = Path(root).name
if concept_name is not None:
concept = _load_file(root, concept_name)
if concept is None:
raise ValueError(f"OKF bundle has no readable concept {concept_name!r}: {root!r}")
declared = _declared_bundle_id(concept.frontmatter)
if declared:
return _reconciled(declared, mount, "declared-concept", root)
index = _load_file(root, _INDEX_NAME)
if index is None:
raise ValueError(f"OKF bundle has no readable {_INDEX_NAME}: {root!r}")
declared = _declared_bundle_id(index.frontmatter)
if declared:
return _reconciled(declared, mount, "declared-index", root)
return ResolvedBundleId(id=mount, origin="mount-derived")
def bundle_context(bundle: Bundle, *, dimension: str | None = None) -> str:
"""Render a navigated bundle as agent read-context via progressive disclosure: the ``index.md``
summary, then each concept file as ``## {type}: {title}\\n{body}``. ``type: verdict`` files are

View file

@ -658,6 +658,10 @@ async def run_project(
# before the amendment (every commons-owned golden) is legitimately un-anchored -> None =
# pre-S4.0 behaviour. A baseline that exists but is malformed still raises (fail-closed).
if bundle_dir is not None:
# ONE bundle-id rule (Step 10): the base is reconciled against the mount it was opened
# from, HERE rather than in ``explore._bundle_index``, which stays pure and does no I/O.
# A base that declares an id its mount does not carry is refused before anything is spent.
okf.reconcile_bundle_id(bundle_dir)
bundle = okf.navigate_bundle(bundle_dir)
project = _project_from_bundle(bundle_dir, project_id, bundle=bundle)
baseline = okf.load_optional_cost_baseline(bundle_dir)
@ -1511,7 +1515,11 @@ async def run_mandate_across_bundles(
"""
by_id: dict[str, str] = {}
for raw in bundle_dirs:
bundle_id = Path(raw).name
# The ONE derivation rule (Step 10) — this used to be a second private copy of
# ``Path(raw).name``, free to drift from ``explore``'s. The REFUSAL below stays local:
# ``MandateRoutingError`` is this door's class, ``ExplorationError`` is explore's, and
# unifying the derivation is not the same as unifying the two doors' error vocabularies.
bundle_id = okf.reconcile_bundle_id(raw).id
if bundle_id in by_id:
# The same refusal ``explore._bundle_index`` makes, for the same reason: the id is how
# the mandate names a base, so two bases answering to one name would let an approach be