feat(okf): den erklaerte bundle_id-en er identiteten - mountet er en filsystem-tilfeldighet
S7a-3 pkt. 1. Til i dag NEKTET reconcile_bundle_id en base som erklaerte en id katalogen ikke bar. Maalt mot K2 - den foerste leverte basen som erklaerer sin egen id (618 av 630 konseptfiler + rot-index, alle "k2-trinn1-20260903", levert som "K2-bundle-20260903") - betydde det at basen ikke kunne aapnes slik den var levert, og at eneste botemiddel var aa montere den paa nytt for haand, en gang per leveranse. PM-beslutning: konsumenten slakker. - Erklaert vinner (B1s rekkefoelge uroert), avviket REGISTRERES: ResolvedBundleId.mount + ProvenanceStamp.bundle_id_source + DryRunReport.bundle_id_source + run.bundle_id_notice (None ved enighet). Stempel-feltet er PAAKREVD uten default: None er en VERDI (veg-stien). - Det som fortsatt nekter er den EKTE kollisjonen: to KONSEPTER i en base som erklaerer ULIKE id-er (okf.assert_declared_ids_agree, kalt ved hver doer som aapner en base). Rot-index er IKKE med i enighets-settet - konsept-slaar-index er en presedens-regel, saa en index i utakt er fallbacken som taper. - KONSEKVENS, ikke scope-krype: explore._bundle_index loeser naa den erklaerte id-en. Den brukte Path(raw).name mens dispatcheren brukte reconcile...id; med erklaert-vinner ville explore() myntet approaches som navngir MOUNTET mens dispatcheren ruter paa ERKLAERINGEN - en utforskning med uruterbart mandat. Load-bearing MAALT: 10 mutasjoner alle roede mot HELE suiten, groenn kontroll 1243 passed / 5 skipped og golden demo-transcript.stdout byte-uendret (shasum -a 1 = ea8c534773acdbe41ae68f2c55724d69aaf8be4f). M1 1 / M2 1 / M3 1 / M4 9 / M5 2 / M6 1 / M7 1 / M8 2 / M9 2 / M11 1. Tre armer i test_bundle_id_reconciliation_loadbearing er SKREVET OM (ikke slettet) - de pinnet nekten beslutningen fjernet. (j) ble skarpere enn den den erstattet: erklaert id ruter, mountet nektes. Kontrakt: docs/okf-konsum-kontrakter.md § 3.1. Invariantrad i CLAUDE.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
5adb1cca62
commit
baae7507a9
14 changed files with 708 additions and 73 deletions
|
|
@ -749,15 +749,32 @@ def load_parked(payload: Mapping[str, Any]) -> ParkedExploration:
|
|||
|
||||
|
||||
def _bundle_index(bundle_dirs: Sequence[str]) -> dict[str, str]:
|
||||
"""Map each knowledge base's id to its directory. The id is the directory's BASENAME.
|
||||
"""Map each knowledge base's id to its directory — the DECLARED id where the base declares one,
|
||||
the directory's basename otherwise (``okf.reconcile_bundle_id``'s rule, S7a-3 pkt. 1).
|
||||
|
||||
A duplicate basename is REFUSED rather than resolved by order: the id is what the manager
|
||||
**Why this door resolves the declaration at all — a CONSEQUENCE of the slacken, not scope
|
||||
creep.** This used to be ``Path(raw).name`` while ``run_mandate_across_bundles`` used
|
||||
``reconcile_bundle_id(raw).id``. While a declared id that disagreed with its mount was refused
|
||||
outright the two could not differ. With declared-wins they can, and then ``explore()`` mints
|
||||
approaches naming the MOUNT while the dispatcher routes by the DECLARATION — an exploration
|
||||
whose own mandate is unroutable.
|
||||
|
||||
**Unreadable falls back to the basename rather than raising, and that is measured.**
|
||||
``test_explore_loadbearing.py`` configures ``/tmp/base-a`` and ``/tmp/one/shared-name`` —
|
||||
directories that do not exist — and expects an ExplorationError about IDs, not an I/O error.
|
||||
Nothing is widened by the fallback: this index answers "which ids may be NAMED", and a base
|
||||
nobody can read is refused a moment later by whichever door actually opens it.
|
||||
|
||||
A duplicate id is REFUSED rather than resolved by order: the id is what the manager
|
||||
names a base by, and two bases answering to one name would let it read A while believing it
|
||||
read B — the S3.2 key-collision class, one layer up.
|
||||
"""
|
||||
index: dict[str, str] = {}
|
||||
for raw in bundle_dirs:
|
||||
bundle_id = Path(raw).name
|
||||
try:
|
||||
bundle_id = okf.reconcile_bundle_id(raw).id
|
||||
except ValueError:
|
||||
bundle_id = Path(raw).name
|
||||
if bundle_id in index:
|
||||
raise ExplorationError(
|
||||
f"two knowledge bases share the id {bundle_id!r} ({index[bundle_id]!r} and "
|
||||
|
|
@ -883,11 +900,12 @@ def navigator_tools(bundle_dirs: Sequence[str]) -> list[FunctionTool]:
|
|||
)
|
||||
def read_bundle(bundle_id: str) -> list[dict[str, Any]]:
|
||||
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)
|
||||
bundle = okf.navigate_bundle(bundle_dir)
|
||||
# The base is OPENED here, so this is where it must be able to say what it IS (S7a-3
|
||||
# pkt. 1). A declared id that disagrees with the MOUNT is no longer refused — that is a
|
||||
# filesystem accident, recorded by the run rather than blocked here — but two concepts
|
||||
# declaring two different corpora is a base no fallback can settle.
|
||||
okf.assert_declared_ids_agree(bundle)
|
||||
# ``context_files``, NEVER ``files``: it is the property that drops the ``type: verdict``
|
||||
# layer AND nested ``index.md`` at every level. Building from ``files`` would put prior
|
||||
# verdicts in front of the navigator around the gated ExpeL fold (målbilde §4), and the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue