Doorman protocol
editorial(ai): strip provenance narration from doorman-protocol per register-documentation.yaml
@@ -2,7 +2,7 @@ schema: foundry-doc-v1 title: "Doorman protocol" slug: doorman-protocol short_description: "The Doorman is the sole AI request boundary through which every inference call routes, enforcing sanitise-and-rehydrate once and logging every call to an immutable audit ledger." short_description: "The Doorman is the sole AI request boundary through which every inference call routes, holding every external-model credential and logging every call to an immutable audit ledger." category: ai type: concept content_type: topic @@ -17,27 +17,29 @@ paired_with: doorman-protocol.es.md --- Every service that can call an external AI model is its own hole in the wall. Ten services with ten egress paths means ten audit surfaces, and ten places the sanitise discipline can be forgotten. Every service that can call an external AI model is its own hole in the wall. Ten services with ten egress paths means ten audit surfaces, and ten places credential handling and logging can drift out of sync. The Doorman closes the wall to a single door. [[service-slm|`service-slm`]] is the platform's sole AI request boundary; every inference call routes through one access-control gateway, and no inference call leaves the customer data vault without passing through it. At that one boundary the Doorman enforces sanitise-and-rehydrate discipline, routes the call to the appropriate compute tier, logs every event to an immutable audit ledger, and captures the training signal that compounds the platform over time. At that one boundary the Doorman holds every external-model credential, routes the call to the appropriate compute tier, logs every event to an immutable audit ledger, and captures the training signal that improves the platform over time. For a regulated buyer the consequence is concrete. No inference call leaves the data vault unlogged or unsanitised, because the discipline is a structural guarantee rather than a per-service configuration. This article defines the routing rules, the audit schema, the `moduleId` discipline, and the training-signal capture. For a regulated buyer the consequence is concrete. No inference call leaves the data vault unlogged or with a credential the Doorman doesn't control, because the boundary is a structural guarantee rather than a per-service configuration. This article defines the routing rules, the audit schema, the `moduleId` discipline, and the training-signal capture. ## Why a Doorman A customer data vault holds the customer's authoritative structured data, and external compute — large language models — cannot be trusted with raw structured facts. Without a single boundary, every service in the [[totebox-os|Totebox]] grows its own egress path, every egress path needs its own audit, and the sanitise-and-rehydrate discipline (SYS-ADR-07) becomes per-service discipline rather than substrate discipline. The Doorman centralises the boundary so the discipline is enforced once. A customer data vault holds the customer's authoritative structured data. Without a single boundary, every service in the [[totebox-os|Totebox]] grows its own egress path, every egress path needs its own audit, and credential and audit discipline becomes per-service rather than platform-wide. The Doorman centralises the boundary so the discipline is enforced once. **What the Doorman does not yet do**: it does not scrub personally identifiable information or location data from a prompt before an external call. The only sanitisation code on the platform today redacts credentials — API keys, tokens, private keys — and runs solely on the path that writes training examples into the learning corpus, never on the path to an external model. See [[sovereign-ai-routing]] for the full picture of what reaches Tier C today and what does not. ## Three-tier compute routing The Doorman routes inference calls across three compute tiers. All three are implemented in the routing code — "planned" describes activation state, not code that doesn't exist yet. The Doorman routes inference calls across three compute tiers. **Tier A — local.** Executes on the host VM using CPU and RAM, for fast, low-latency, low-cost inference on a locally hosted model. Tier A handles the majority of routing volume with no cloud spend, and is operationally verified. **Tier A — local.** Executes on the host VM using CPU and RAM, for fast, low-latency, low-cost inference on a locally hosted model. Tier A handles the majority of routing volume with no cloud spend. **Tier B — on-demand GPU pool.** Tier B routes workloads to ephemeral GPU instances ([[yoyo-compute-substrate|the Yo-Yo compute substrate]]), spun up on demand and shut down on idle (a 30-minute default idle-shutdown monitor issues the real deprovision call), with two profiles: a **trainer** instance for continued training cycles on accumulated tuples, and a **graph** instance for property-graph workloads — not an "extractor" instance as earlier documentation described. The routing logic and idle-shutdown monitor are fully wired; whether a given profile is reachable at any moment depends on its own health probe and circuit-breaker state, which the Doorman's `/readyz` endpoint reports per profile. **Tier B — on-demand GPU pool.** Tier B routes workloads to ephemeral GPU instances ([[yoyo-compute-substrate|the Yo-Yo compute substrate]]), spun up on demand and shut down on idle — a 30-minute default idle window before deprovisioning — with two profiles: a **trainer** instance for continued training cycles on accumulated tuples, and a **graph** instance for property-graph workloads. Whether a given profile is reachable at any moment depends on its own health probe and circuit-breaker state, which the Doorman's health endpoint reports per profile. **Tier C — external API proxy.** Tier C's allowlist and cost-guardrail scaffolding are implemented for narrow-precision tasks — citation grounding, graph-build assistance, entity disambiguation — but the crate's own source comments state live external API calls are not yet enabled in this version; activating them is a separate operator decision, not a missing feature. Earlier documentation claimed Tier C "injects predefined `service-content` ontologies to constrain output to canonical platform vocabulary" — no such mechanism exists in the Tier C code path; that claim is retracted here, not merely softened. **Tier C — external API proxy.** Tier C's allowlist and cost-guardrail scaffolding cover narrow-precision tasks — citation grounding, graph-build assistance, entity disambiguation. Activating live external calls is a deliberate, separate operator decision, not an in-progress build. ## The audit ledger @@ -45,9 +47,9 @@ Every inference call produces a JSONL audit-ledger entry appended to a daily fil ## The moduleId discipline `moduleId` is confirmed to serve two roles, not five: it tags audit-ledger entries for per-project cost accounting, and — since the tenant-isolation fix landed — it strictly scopes property-graph reads and writes to the caller's own module, with no cross-tenant merge. Earlier documentation additionally claimed `moduleId` selects the systemd unit handling a request, namespaces the key-value cache, and selects the adapter stack. None of those three roles has support in the current routing, caching, or adapter-hub code, so the claim is retracted here rather than carried forward unverified. `moduleId` serves two roles: it tags audit-ledger entries for per-project cost accounting, and it strictly scopes property-graph reads and writes to the caller's own module, with no cross-tenant merge. Enforcement is real but narrower than "every request needs a valid `moduleId`": the graph endpoints (`graph_query`, `graph_mutate`) reject a missing or malformed `moduleId` outright. The primary inference endpoint (`chat_completions`) rejects a malformed `moduleId`, but silently falls back to a default when the header is simply absent, logging only a warning — a real gap between the two endpoint families, not a uniform boundary. Enforcement differs by endpoint. The graph endpoints reject a missing or malformed `moduleId` outright. The primary inference endpoint rejects a malformed `moduleId`, but falls back to a default when the header is simply absent, logging only a warning — a narrower guarantee on that path than on the graph endpoints. ## Learning-pipeline routing