Security boundary and current qualification
Tychora's supported host is one embedded workspace owner with local HTTP/MCP bearer grants. The HTTP server binds loopback, checks the exact Host and optional Origin, and narrows each token to the owner's scope. Do not put multiple Uvicorn workers over one embedded workspace. Source text is evidence data: search returns cited material, never an LLM-authored answer or instruction to an agent. An application that sends retrieved text to an LLM must retain the distinction between source text and its own instructions.
External provider configuration does not grant upload consent. The default collection denies upload until its owner uses the public provider-upload-consent management operation; that grant becomes effective for the default owner after reopen. Revocation changes the current policy epoch and prevents queued or retried provider work from dispatching with a stale grant. Narrower caller and bearer scopes cannot be widened by owner policy. Offline execution does not construct an external provider. Credentials and original bytes are scoped independently of search. Published source examples, docs and fixtures use synthetic data. Distribution allowlists remain a separate release gate.
Local acquisition is limited to configured roots and validated URLs. Repository excludes accept the subset whose Git capture and local dirty checks agree; unsupported bracket negation and POSIX classes are rejected at admission. Archive extraction, redirects, path traversal, body size, and token/response budgets have separate guards and tests. This is not a claim of arbitrary live-host network qualification. Native graph and vector indexes are derived from canonical records, and the canonical access/policy decision governs public retrieval and inspection.
The documents and full extras pin BSD-3-Clause pypdf==6.19.0 for a metadata-only PDF resource preflight. Before Docling conversion, it follows bounded page/Form XObjects and separately referenced /SMask and /Mask image dimensions, rejecting malformed or cyclic references and masks above the per-image 40-million-pixel limit. Valid small masks remain accepted. This limit is not a total native-memory ceiling. The optional PDF dependency is required for PDF conversion; without it the parser returns CAPABILITY_MISSING. A package-only public advisory query for pinned pypdf on 2026-10-06 found no known advisories; the installed-environment Chroma/OAuthlib scan below remains nonclean.
Isolated synthetic PDF, DOCX, OCR, and selected-region cases ran under a calibrated macOS process-local IP-outbound deny boundary with a native connect() observer. The known TCP control was denied, Unix IPC succeeded, and those runs recorded no calls through the observed connect() symbol. The boundary does not observe every native networking API or helpers outside the child. Both nested oversized-mask probes were rejected before converter entry, while an ordinary rich PDF still converted. This is scoped macOS qualification, not proof of no possible native outbound attempt or a portable network guarantee.
Published graph relationship paths preserve native direction, assertion IDs, predicate, support IDs, status, and confidence. QueryService rechecks all endpoints and supports against the pinned eligibility view and excludes blocked assertions; response assembly retains only paths connected to finally delivered matched evidence after budget fitting. Checks can be disabled without erasing the provenance of a graph-expanded result. Relation paths count toward each rendered transport's output cap. Retrieval without a graph, and exact-only retrieval, return no relation paths.
For new sources, schema-validated metadata keys edition, publication_date, effective_start, effective_end, and approval bind the immutable revision's edition, dates, and declared review state. Dates must be strict ISO calendar dates; the effective interval is half-open. Absent or null dates remain unknown, and absent approval remains unreviewed. Publishing a second edition of the same source retains the first edition in the new snapshot while the latest publication becomes the default; a refresh of the same edition replaces only that edition's active member. Existing revision IDs whose retained fields differ from this projection fail with IDEMPOTENCY_CONFLICT and remain unchanged; publish a new edition or changed metadata to obtain a new revision ID. Historical snapshots and receipts are not rewritten.
The reserved metadata.scope.global_facets list declares exactly which registered source facets may match when their source value is missing and a query sets include_global=true. For example, "global_facets":["project"] binds the registered scope.project facet; it does not make other filters global or bypass access, review, dates, source selection, or child-unit narrowing. Registered scalar metadata.* source bindings become immutable revision facets; arbitrary custom metadata does not become a filter. New declarations normalize allowed aliases to canonical keys before revision identity and carry a verified per-revision artifact binding the keys and facet semantics. Duplicate, unknown, and nonglobal facet declarations are rejected. Old nonempty declarations without that binding, or old revision identities missing a required registered facet value, fail closed with PROFILE_INCOMPATIBLE; use a new edition or changed metadata to publish a new identity. Alias remapping cannot reinterpret a retained canonical declaration. Backup and restore include and verify the binding artifact before activation.
The locked all-extras/audit environment was scanned with pip-audit --local on 2026-10-05. After targeted PyJWT and urllib3 updates, it still reports six rows across five unique ChromaDB/OAuthlib advisory IDs; the scan is not clean. The four Chroma findings concern unauthenticated create-collection code injection, authenticated update-collection code injection, SimpleRBAC resource-scope failure, and cross-tenant authorization. The OAuthlib finding concerns an authorization server's PKCE verifier comparison. The supported adapter uses embedded Chroma PersistentClient with fixed collection configuration and embedding_function=None, and sends computed embeddings. Tychora exposes no Chroma HTTP server, collection-configuration passthrough, or Chroma SimpleRBAC tenant service. Its MCP/HTTP host uses local bearer grants and provides no OAuthlib PKCE authorization server. Those reported entry paths are therefore outside this supported composition. A separately exposed Chroma server, caller-selected embedding function, multi-tenant Chroma RBAC, remote Chroma backend, or OAuth authorization server requires a new assessment. Installed vulnerable dependencies remain present; this boundary assessment does not patch them. This installed-environment scan cannot certify every optional extra or platform.
Crash acceptance kills test-owned subprocesses at ten mapped application boundaries and reopens the real canonical and native stores. It demonstrates prior-or-complete-new snapshot visibility and retry mechanics for the synthetic cases, not power-loss durability. The combined Chroma/graph test isolates each owner process; a deliberately overlapping externally injected Chroma client reproduced a native Error finding id, so arbitrary concurrent clients sharing one Chroma path are outside the qualified profile. Graph projection v2 stabilizes new generation proofs across process hash seeds. Historical v1 proofs retain their exact bytes and fail closed on mismatch; native rebuild alone cannot upgrade a v1 proof. A new v2 generation requires verified retained canonical inputs.
New query-run history scope proofs use a v2 digest that sorts unordered grant sets, so inspection, discovery, and retained replay survive process hash-seed changes. Historical v1 run proofs are accepted only if the caller's current typed scope serializes to the exact old digest; an old run may remain unavailable after an ordering change because the original ordered scope projection was not retained. No permutation search or principal-only fallback widens access. In-memory eligibility keys and client-held source cursors also use separate v2 digest domains over that stable projection. Old in-memory cache keys naturally expire, and old v1 source cursors receive an invalid-cursor error; neither is a durable authorization proof.