feat(import): Door C flow against an injected import gate (Phase 2 step 5)
Reads an external OKF bundle as {bundle-relative path -> document text},
hands it WHOLE to an injected gate over the guard's okf.import_bundle (a
bundle-level call: it resolves the cross-link graph across concepts), and
merges only concepts clearing the non-blocking floor. Same injection pattern
as Door B, so the core stays dependency-free while the CI channel for the
real guard is settled.
Two constraints shaped the design and are pinned by tests:
- A merged concept is written VERBATIM. Stamping provenance into it would
require round-tripping its frontmatter through this library's line-oriented
parser, which cannot represent the block lists the guard's parser accepts --
silent data loss -- and would persist bytes the guard never screened.
- Ownership is therefore proven by content identity: identical bytes at the
target name are a no-op re-merge (re-import of an unchanged bundle is
idempotent), and anything else at the name is refused. Curated content and
an updated concept are refused alike; refusing is what never destroys.
The floor is fail-closed beyond the plan's "no error" wording: an error, an
unrecognised disposition, and a concept the gate returned no verdict for are
all refusals. quarantine_review stays its own bucket, as at Door B.
origin/channel are validated against the guard's pinned vocabulary -- it
derives trust from origin by enum identity, so an unrecognised string would be
silently downgraded rather than caught.
Three primitives promoted for reuse rather than duplicated:
reduce_to_id_grammar and check_filename_length to materialize.py, and
extract.decode_text. Door C slugs the WHOLE concept path, so tables/users.md
and views/users.md stay distinct. Concept discovery folds case explicitly
rather than globbing *.md, whose case-sensitivity follows the filesystem and
would import the same bundle differently on APFS and ext4.
README's "what is gated today" section corrected: it claimed nothing is gated,
which is no longer true, but the honest statement is narrower than "the doors
are gated" -- the library cannot verify that an injected adapter is a real
guard, and a permissive stub is believed.
405 tests green; ruff, ruff format and mypy --strict clean.
This commit is contained in:
parent
d812a839be
commit
f10fc60de2
11 changed files with 1250 additions and 61 deletions
|
|
@ -20,6 +20,14 @@ Door B (bundle inbox) public surface: process_inbox plus its result types.
|
|||
Its persist gate is INJECTED -- the caller supplies a Gate adapter over
|
||||
llm-ingestion-guard and process_inbox obeys the verdict; the library imports
|
||||
no guard function itself and makes no security decision of its own.
|
||||
|
||||
Door C (external bundle import) public surface: import_bundle plus its result
|
||||
types. Its gate is injected the same way, over the guard's okf.import_bundle:
|
||||
the caller declares origin and channel at the door, the gate assesses every
|
||||
concept, and only concepts clearing the non-blocking floor are merged. Merged
|
||||
concepts are written verbatim -- ownership is proven by content identity
|
||||
rather than by a stamp, so an occupied name is only ever re-used when the
|
||||
bytes already there are identical.
|
||||
"""
|
||||
|
||||
from .errors import (
|
||||
|
|
@ -41,6 +49,16 @@ from .inbox import (
|
|||
PersistedFile,
|
||||
process_inbox,
|
||||
)
|
||||
from .importer import (
|
||||
BundleDecision,
|
||||
FailedConcept,
|
||||
ImportDecision,
|
||||
ImportGate,
|
||||
ImportResult,
|
||||
MergedConcept,
|
||||
RefusedConcept,
|
||||
import_bundle,
|
||||
)
|
||||
from .manifest import (
|
||||
Extraction,
|
||||
FileSource,
|
||||
|
|
@ -55,25 +73,33 @@ __version__ = "0.3.2"
|
|||
|
||||
__all__ = [
|
||||
"BlockedFile",
|
||||
"BundleDecision",
|
||||
"Extraction",
|
||||
"ExtractionError",
|
||||
"FailedConcept",
|
||||
"FailedFile",
|
||||
"FileSource",
|
||||
"Gate",
|
||||
"GateDecision",
|
||||
"HttpSource",
|
||||
"ImportDecision",
|
||||
"ImportGate",
|
||||
"ImportResult",
|
||||
"InboxResult",
|
||||
"IngestError",
|
||||
"IngestResult",
|
||||
"Manifest",
|
||||
"ManifestError",
|
||||
"MaterializationError",
|
||||
"MergedConcept",
|
||||
"NetworkGateError",
|
||||
"PersistedFile",
|
||||
"RefusedConcept",
|
||||
"RenderError",
|
||||
"SourceError",
|
||||
"SqlSource",
|
||||
"extract_text",
|
||||
"import_bundle",
|
||||
"load_manifest",
|
||||
"materialize_bundle",
|
||||
"process_inbox",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue