Building versioned document agents begins by separating three things that a conventional RAG application often blends together: a document's stable identity, the immutable evidence release currently attached to it, and the shared runtime that answers questions. In this Cloudflare implementation, one Worker serves many logical document agents while each document remains independently versionable, promotable, inspectable, and routable.
Federated retrieval is the next consequence of that separation. Each document publishes a compact routing card, a bounded router selects the agents justified by the question, and those agents return evidence bundles rather than competing prose answers. The federation is therefore a controlled selection and evidence-aggregation process, not a group chat among models and not a search across every document on every request.
This article explains how that design was built: the repository and language boundaries, how a document becomes a signed release, what each Cloudflare service owns, how a single document agent retrieves canonical evidence, how Hermes calls it, and how the router coordinates multi-document questions. Part 1 explains what changes relative to a conventional FastAPI and PostgreSQL stack and where the trade-offs sit.
The implementation is live in a development environment and its principal paths have been exercised with a large data-science textbook and five Edmonton bylaws. It is not yet production-certified. That distinction is important because the engineering choices are worth studying even where the performance and evaluation work remains unfinished.
The Cloudflare development deployment described here was built and exercised using resources available on Cloudflare's free tier. Its observed performance and answer quality should be read in the context of those model choices, quotas, and service limits rather than as the ceiling of the platform.

First principle: a document agent is not a Worker per document
"One book, one agent" sounds as though every book requires a separate deployment. That would create unnecessary code duplication, configuration drift, and operational clutter. We instead separated the agent's logical identity from the runtime that executes it.
A document agent consists of a stable document identifier, an active immutable release, a routing card, retrieval and answer policies, exact-reading capabilities, and durable state when a session requires it. A shared Worker contains the implementation. The active release tells that implementation which normalized sections, chunks, embeddings, and metadata belong to the agent.
This distinction lets one Worker serve many document agents while each agent remains independently routable, versioned, inspectable, and promotable. It also makes replication practical: publishing another book or bylaw is a data-and-contract operation, not a new application project.
The other critical principle is that full source text does not live in the Hermes profile. Hermes receives a thin skill containing the document's table of contents, structural maps, summaries, routing hints, and instructions for using the remote tools. Cloudflare stores and retrieves the full evidence. The profile remains lightweight while still understanding how to navigate the document.
Establishing the project boundary
The first setup decision was organizational rather than technical: this system became its own repository instead of a branch or miscellaneous folder inside Hermes. The resulting repository contains the Worker runtime, shared TypeScript contracts, the Python publisher, evaluation assets, OpenSpec changes, operational scripts, and the thin Hermes integration. Hermes is a consumer and orchestrator; it is not the owner of the Cloudflare deployment.
That boundary reduced a growing form of friction. Changes to document parsing and publication could evolve without treating the Hermes runtime as their release vehicle, while the Hermes integration remained versioned beside the service it calls. The repository now has explicit homes for the edge runtime, generated contracts, build tooling, evaluations, specifications, and integration assets.
The build plane uses Python 3.12. The edge runtime uses TypeScript on Node 22 and pnpm. Python was the practical choice for PDF extraction, tabular inspection, Pydantic models, batch mutation, and document-quality analysis. TypeScript was the natural choice for Workers, the Agents SDK, Durable Objects, and MCP. Forcing both planes into one language would have simplified the toolchain diagram while making at least one side worse.
A bootstrap script installs the locked JavaScript and Python dependencies, installs pre-commit hooks, and refreshes the local code graph. A separate quality script runs Prettier, ESLint, TypeScript type checking, unit tests and build; Black, Flake8, Ruff, strict MyPy, and pytest; contract-drift detection; strict OpenSpec validation; a Skylos diff gate; and Graphify's code-graph update. This is more than formatting machinery. It makes cross-language drift and incomplete proposal work visible before deployment.
Secrets are local configuration, not repository content. Account identifiers, tokens, Access credentials, Langfuse keys, and private endpoints stay in an ignored environment file or Cloudflare secret storage. The public configuration exposes variable names and safe limits, never their values. Cloudflare Access service tokens protect machine-to-machine calls; interactive OAuth and account-wide administrative access are separate concerns.

The Python build plane: compile meaning before embedding text
The pipeline starts by acquiring a source document and recording provenance. It then extracts layout and text, constructs a section hierarchy, identifies tables and nested processes, classifies indexable content, creates retrieval units, runs structural assurance, and packages the result as a release. Embeddings come late because embedding malformed structure only makes the error easier to retrieve.
Keep the baseline parser stable
Docling became the stable baseline parser because it preserved document structure more faithfully than faster text-only extraction in our governance-document tests. On one hostile document, Docling took 22.812 seconds; PyMuPDF took 0.134 seconds but produced weaker structural fidelity; Marker took roughly 21 to 35 seconds and did not preserve the required list-item structures. Speed mattered, but not enough to justify losing the hierarchy that downstream retrieval depended on.
The baseline was deliberately kept general. When a municipality or document type produced a recurring anomaly, the pipeline classified that anomaly before adding a scoped formatter. A City of Edmonton formatter can recognize a measured Edmonton-specific construction pattern without teaching the baseline parser that every PDF in the world is an Edmonton bylaw. The same extension point can host a document-type formatter when the anomaly follows the form rather than the jurisdiction.
This is a useful rule for document pipelines: stabilize the general parser, measure anomalies, and make exceptions explicit. Otherwise, each successful fix quietly degrades the next document family.
Build and validate a hierarchy in memory
Regular expressions help recognize numbering, but they cannot be the authority for a legal or technical hierarchy. A line beginning with "3.2.1" may be a heading, a nested procedural step, a table cell, or text in a footer. The parser therefore builds a runtime document tree with typed nodes and parent-child relationships. Nodes carry their heading path, source range, node type, order, and lineage. Lists preserve nesting and ordinal relationships rather than becoming disconnected paragraphs.
The pipeline validates that tree before it declares extraction complete. It checks continuity, parent existence, ordering, source coverage, orphaned nodes, suspicious depth changes, and table boundaries. This made extraction quality numerical instead of intuitive. Across the five Edmonton bylaws, the latest assurance run accounted for 421 of 423 expected nodes—99.5272 percent—and all 413 expected sections. The agreed operational threshold is 95 percent for now, with flagged anomalies retained for review rather than hidden.
Cheap LLM adjudication remains an escalation path, not the default parser. The system can calculate an anomaly rate and invoke adjudication only when deterministic confidence falls below a threshold or the anomaly class requires semantic judgment. That avoids paying a model to confirm the 95-plus percent of the document that deterministic parsing already understands.
Chunk by section, then preserve neighbourhood
The primary retrieval unit is the section hierarchy, not a page or an arbitrary character window. Sections and paragraphs cross page boundaries, especially in long books. Splitting on page edges would sever definitions from formulas and procedural steps from their conditions.
Each chunk therefore belongs to a section and carries the complete heading path, its order within that section, source character or page ranges, and previous/next relationships. The heading path is prepended to the retrieval text so a semantically ambiguous passage retains its subject. Oversized sections may be divided into smaller chunks, but the pipeline never forgets their common section identity or neighbourhood.
At generation time, sections are classified as indexable or do-not-index. Covers, copyright pages, some tables of contents, bibliographies, and appendices can remain in the canonical release without consuming the semantic index. Query-time metadata filters enforce the classification again. Publication, creation, and modification dates are carried as metadata, and freshness can break a retrieval tie; freshness never overrules a clearly stronger relevance signal.
Publication is a transaction even when the stores are different
The release package contains the normalized hierarchy, section and chunk artifacts, routing material, manifests, hashes, and signatures. Releases are immutable. A book agent's identity remains stable while its active release pointer changes.
Publication proceeds in stages. The client first runs preflight checks against hard limits and configured budgets. It uploads immutable evidence objects to R2, registers the release and inventory in D1, generates or accepts embeddings, upserts the active retrieval units into Vectorize, publishes the routing card, and then promotes the release with compare-and-swap semantics. A final read-back verifies that the stores agree about the active version.
This order protects readers from half-published documents. Uploading objects is not the same as making them live. If Vectorize upsert fails, the old release remains active. If promotion encounters an unexpected current version, compare-and-swap refuses to overwrite it. The publisher can resume idempotently, retry transient failures with exponential backoff, and distinguish a retryable provider failure from a contract violation.
Vector metadata deserves special attention because vector databases often do not support convenient in-place mutation. We built a reusable batch migration path that downloads vector records, transforms their metadata in a dataframe, validates the result, and upserts in efficient batches with retries and backoff. The operation is timed from download through final response. That capability is not an excuse to mutate releases casually; it is a controlled repair mechanism for a recurring vector-store limitation.
Only one active vector representation should exist for a document in each environment. Historical source releases can remain immutable in R2 and registered in D1 without leaving duplicate active embeddings in Vectorize. We learned this through capacity inspection: development experiments can quietly consume the next scarce resource even when object storage remains inexpensive.

What each Cloudflare service owns
The architecture becomes easier to reason about when every service has one dominant responsibility. Ambiguity between stores creates duplicated truth; narrow ownership creates verifiable handoffs.
Workers: the request and policy boundary
The Worker receives authenticated requests, exposes the MCP tools, validates generated request types, applies budgets and policy, invokes document agents or the federated router, and returns a stable response envelope. It is the edge application, not the evidence database.
One shared deployment serves many logical agents. Environment bindings connect it to D1, R2, Vectorize, Workers AI, and Durable Object namespaces. Explicit limits constrain prompt bytes, response bytes, documents per route, candidate counts, sections per exact read, and daily request budgets. These are product safeguards as much as cost controls.
Access: the machine identity boundary
Cloudflare Access protects the remote MCP endpoint. Hermes authenticates as a service identity rather than passing a broad Cloudflare administration token to ordinary book queries. Authentication and authorization happen before a document or vector search begins. In a customer-owned deployment, this boundary belongs in the customer's account.
R2: canonical evidence
R2 stores immutable sources, complete normalized sections, chunks, manifests, and signatures. It is the final authority for the text placed in an answer prompt or returned by the exact-section reader. Because the retrieved ranges are hash-verified, a citation points back to the release that actually supplied the evidence.
This design is intentionally stricter than letting the vector index return text directly. Vector metadata is optimized for discovery and may be truncated, stale, or transformed. R2 evidence is what the system is willing to quote.
D1: registry and control plane
D1 records documents, releases, routing cards, promotion state, inventory, and other relational control data. It answers questions such as which release is active, which environment owns it, which routing card describes the agent, and whether publication completed. It does not become a second copy of every book's full text.
Cloudflare describes D1 as managed serverless SQL with SQLite semantics, Worker and HTTP access, and built-in recovery. Those characteristics suit catalogue and release state, while keeping large immutable artifacts in object storage.
Vectorize: discovery, not proof
Vectorize stores embeddings and filterable metadata for active retrieval units. A query embedding returns semantically related candidates; metadata filters remove do-not-index sections, inactive releases, wrong documents, and other out-of-scope records. Lexical retrieval remains useful alongside it, especially for model numbers, legal clauses, acronyms, and exact technical terminology.
The most important rule is negative: a Vectorize result cannot support a citation by itself. It identifies which canonical evidence should be fetched.
Workers AI: three different model jobs
The runtime uses separate model calls for query embedding, reranking, and answer generation. In the current development configuration, a Qwen3 embedding model creates 1,024-dimensional vectors, BGE reranker base reorders candidates, and Mistral Small 3.1 24B produces the final answer. Keeping these jobs distinct lets the team change one model without pretending that embedding quality, reranking quality, and prose quality are the same problem.
Each job now receives its values from one versioned RAG policy rather than unrelated code constants or provider defaults. Pydantic is the editable contract authority; generated TypeScript validators carry it into the Worker. The policy covers query-planning breadth, lexical and semantic top-k, semantic thresholds, candidate quotas, adjacency and freshness, reranker bounds, evidence and prompt limits, rank-fusion weights, document fan-out, clarification behavior, and the generation controls actually supported by Mistral. Environment variables remain a harder layer that fixes approved model IDs and maximum tokens, bytes, candidates, and cost.
This separation creates three honest labels. A provider default is whatever the hosted API applies when a value is omitted. A baseline is a complete reviewed policy checked into the repository and chosen to preserve known behavior. A tuned policy is an immutable candidate that passed a representative experiment, exact citation and routing gates, minimum unique cases and repetitions, cost and latency comparison, human review, compare-and-swap activation, and read-back. The current committed policies are baselines; the ANOVA matrix is useful smoke evidence but is intentionally too narrow to confer the tuned label.
Workers AI is serverless and usage-priced, but model latency remains a first-class concern. AI Gateway could later add caching, retry, rate-limit, and fallback controls; it is not required to understand the core architecture described here.
Durable Objects and Agents SDK: identity and session state
Durable Objects give each logical agent or federated search session a globally addressable identity with strongly consistent attached storage. The Agents SDK provides the higher-level runtime concepts—agent identity, state, sessions, routing, recovery, and observability—on top of Cloudflare's execution model.
The document agent uses this state sparingly. The federated router needs more: selected agents, evidence bundles, clarification state, rejected interpretations, intent revisions, correlation identifiers, and cancellation or completion status. Durable session state is what allows the user to say "no, that is not what I meant" without restarting the search as though the first turn never happened.
MCP: the contract presented to Hermes
Model Context Protocol is the remote tool boundary. Cloudflare supports remote MCP over Streamable HTTP with authorization, and its own guidance recommends a small set of tools optimized for user goals rather than a thin wrapper around every API endpoint. That principle shaped this server.
Hermes does not need low-level tools for querying Vectorize, reading D1 rows, or fetching arbitrary object keys. It needs tools such as list available books, ask a book, get a definition or citation, read one to eight complete sections in order, start a federated search, continue it with user feedback, inspect sanitized state, and cancel the session.
The single-document retrieval loop
A normal question begins with the thin Hermes skill. Its table of contents, concept maps, aliases, and summaries help the profile formulate a better request and choose a likely document. Those assets are not discarded after publication; they inform query planning and routing. The full source remains remote.
Inside the Worker, the query planner derives lexical terms, semantic intent, possible section hints, and the requested answer mode. Candidate generation combines skill-informed lexical discovery with a Vectorize query. Metadata filters enforce the active release, document identity, indexability, and any date or scope constraints. The reranker scores the bounded candidate set against the actual question.
Reranking order is useful for selection but wrong for reading. Once the system chooses the surviving chunks, it restores their order inside each book. This prevents the answer model from seeing a worked example before the definition that explains it or step seven before step three. Neighbour expansion can include adjacent chunks when the selected evidence crosses a chunk boundary.
The evidence layer then fetches the exact R2 ranges and verifies their hashes. The prompt contains every selected, verified chunk that survives the final evidence budget. The answer instruction asks the model to explain what the book says as a capable university professor might—faithful to the source, able to simplify or modernize language, and able to format worked examples—without forcing one rigid response template onto every topic.
The output always passes through a response-repair module. The repairer can unwrap provider envelopes, extract JSON from Markdown fences, repair common structural defects, or wrap a legitimate plain-text answer in the expected object. It cannot turn a provider error into a valid answer. HTTP status, provider code, retryability, null values, and causal information are preserved in a typed internal error object so downstream callers can distinguish a valid empty search from an invalid empty response.
An exact-read request takes a shorter path. It resolves one to eight requested sections, orders them, fetches and verifies the R2 artifacts, and returns the original text without invoking the answer model. This is the correct tool when the user asks to read a complete section verbatim or when latency and interpretive risk matter more than synthesis.

Hermes is the orchestrator, not the document store
The Hermes profile carries a thin wrapper skill named for the document domain. It knows what the book covers, how it is organized, when to ask for a synthesized answer, and when to request exact sections. It also knows how to interpret the response disposition. A not_covered result means that the bounded retrieval attempt did not find enough evidence; it does not prove that the concept is absent from the source.
This arrangement preserves the best feature of the original book-to-skill process: rapid navigation through a document's structure. The table of contents, aliases, topic maps, and summaries help the agent move intelligently. What changed is the storage responsibility. Hundreds of pages of source text no longer accumulate in the global Hermes skills directory.
The "Ops Knowledge Ledger" profile owns the repeatable publishing capability. Once a new source has been compiled, assured, signed, published, and verified, the generated thin skill can be assigned to a profile of like name. The workflow is designed so a future document follows the pipeline rather than receiving an ad hoc summary edit.
Federated routing: choose agents before asking them
A library of document agents creates a new problem. A business owner may ask, "What are the requirements for ramp access to a physical location?" without knowing which bylaw applies. Blindly querying every bylaw would waste tokens, increase latency, and amplify irrelevant evidence.
Each document agent therefore publishes a compact routing card. The card describes jurisdiction, document type, topics, obligations, exclusions, effective dates, aliases, and other high-level signals. The federated router compares the request with the catalogue and activates a bounded subset of agents. Routing is a cheap selection problem before it becomes an expensive evidence problem.
Selected agents return typed evidence bundles rather than final, competing answers. A separate adjudicator evaluates which bundles apply, whether they agree or conflict, whether the jurisdiction and dates are compatible, and whether enough evidence exists to answer. The final response preserves document-level citations and can state that several documents apply.
Insufficient evidence does not end the conversation. The router can ask a targeted clarification derived from the candidate documents—for example, whether the location is a new development, an existing business, or a particular occupancy type. If the user rejects the interpretation, the session records that rejection, revises the intent, and can widen or redirect the next routing pass. This is more useful than repeating the same vector search with slightly different wording while forgetting why the first result failed.
The router state is versioned. Requests and responses carry correlation and session identifiers. Continuation calls operate against an expected revision so simultaneous updates cannot silently overwrite one another. Cancellation and sanitized inspection are explicit operations rather than incidental states hidden in logs.

Programming decisions that kept the system coherent
The architecture crossed Python, TypeScript, multiple managed stores, MCP, Hermes, and several model providers. Without a single definition of the data crossing those boundaries, the system would eventually accept one shape, store another, and return a third.
Pydantic v2 is therefore the only editable source of truth for request, response, stored, agent, MCP, telemetry, evaluation, and error objects. JSON Schema, TypeScript types, Worker validators, and stable error-code catalogues are generated from the Python models. A drift check fails when generated artifacts no longer match their source. The decision slightly privileges the build plane, but it turns cross-language consistency into a testable property.
Custom error classes exist at every major logic junction and external integration. Errors carry a stable application code, retryability, provider response code where available, correlation ID, and causal chain. Python logging is equally deep: acquisition, parsing, hierarchy decisions, classification, packaging, uploads, database operations, vector batches, promotion, and verification all produce structured events. Logging redacts credentials, private prompts, user text, and complete source passages. Observability that leaks the library is not defensible observability.
Release immutability and response repair solve different forms of uncertainty. Immutable releases make it possible to identify exactly which source supported an answer. Response repair contains the variability of language-model adapters without erasing real service failures. Exact section reads bypass generation when interpretation is unnecessary. Budget gates reject operations that would exceed configured resource or request limits. Together, these choices make failure explicit rather than optimistic.
Development process also became part of the architecture. Each OpenSpec proposal was implemented on its own feature branch. HANDOFF.md carried lessons, mistakes, final code, and contract changes into the next proposal so later work could detect specification drift caused by earlier implementation. After verification and merge, the feature branch was pruned. Independent adversarial review and a Skylos review were limited to one post-review fix round per proposal to preserve forward motion without abandoning quality.
What the tests taught us
The most expensive lessons came from assuming that a successful component meant a successful answer.
Early retrieval could find passages mentioning a target topic, but the answer was underspecified and included a hallucinated sentence. Adding semantic retrieval was not enough. Reranking helped selection, yet an overly aggressive score threshold could produce no hits. The system also had to ensure that every selected chunk reached the model and that chunks were restored to source order after relevance ranking.
Model tests exposed another boundary. Qwen generated accurate but weakly composed answers that over-weighted the first passage. GLM produced grounded raw text but took roughly 129 seconds in one test and failed the enforced schema path. Gemma returned an empty schema result and failed to produce a useful final answer in the raw trial. Llama 3.3 produced useful prose in 20.38 seconds but invalid JSON. Mistral offered the best balance in our trials, completing once in 21.5 seconds and later in 38.748 seconds on the live MCP path, though it still introduced a formula-label defect.
The response-repair layer emerged from those tests. So did the decision to improve the prompt without demanding a universal essay structure. A document agent should faithfully explain the supplied source and format its worked examples; it should not force every definition, procedure, and legal clause into the same rhetorical template.
Document parsing produced a parallel lesson. Regex-only heading recognition was insufficient for sections, deeply nested procedures, and tables. Yet endlessly tuning the baseline parser to each troublesome page would have created a local optimum. The stable-parser-plus-scoped-formatter design delivered 99.5272 percent aggregate structural coverage across the bylaw sample while preserving a clear anomaly path.
The final lesson is operational: development and live resources accumulate unless the release model says what may coexist. The current rule permits one active vector set per document in each environment. Old development vectors should be pruned after promotion or replacement; immutable source history can remain in the cheaper evidence and registry layers.
What the observed answer shape costs
The live long-book answer provides a useful consumption envelope as long as it is not mistaken for an invoice or a field benchmark. Its 8,394 Mistral input tokens and 880 output tokens consumed about 312 neurons for generation. Adding one bounded BGE rerank and a short Qwen3 query embedding produces a conservative planning envelope of roughly 321 neurons and $0.00354 per interpreted answer before free allocation, at Workers AI's current published rate of $0.011 per 1,000 neurons.
| Monthly interpreted questions | AI list-price envelope before free allocation | Plan implication | Modeled Cloudflare cash cost |
|---|---|---|---|
| 500 | ~$1.77 | Fits the daily free neuron allowance (10,000/day) when evenly distributed and remains inside the current 25-request-per-day guard | ~$0 incremental AI cost |
| 2,500 | ~$8.84 | Exceeds the daily free allowance and current development guard; requires Workers Paid ($5/month minimum) and an approved cap increase | ~$10.53 including the $5 plan minimum and ~$5.53 AI overage |
At these volumes, the current index's Vectorize queries, R2 reads, D1 operations, Worker requests, and Durable Object calls remain inside the relevant included allocations. Traffic shape still matters: the allowance resets daily, so a concentrated burst can exhaust the free tier even when the monthly total appears modest. The model also holds the current small index constant; a much larger corpus changes the fixed Vectorize dimension component.
Current status and the work that remains
The development system can publish signed document releases, retrieve and rerank candidates, verify R2 evidence, answer through Mistral, return exact sections without model interpretation, expose MCP tools to Hermes, and coordinate a federated search across document agents. A data-science book and five Edmonton bylaws have exercised the main paths. The September deployment also verified negotiated staged delivery through a separate authenticated endpoint and retained Cloudflare-native Worker traces; this does not yet constitute live Langfuse export.
That is meaningfully live, but it is not the same as production readiness. The observed 38.748-second answer violates the field-service latency target. The full evaluation matrix needs representative technician, compliance, exact-read, ambiguous, adversarial, and cross-document questions. Production needs a separate environment, load and rollback exercises, resource alarms, a documented recovery objective, and end-to-end measurements from actual phones and networks.
Langfuse credentials and integration planning exist, but tracing should remain described as parked until the free or approved budget path is completed and verified. Standard platform logging and evaluator-only retrieval inspection records provide current visibility into original guidance, unranked candidates, reranked candidates, selected evidence, source order, prompt inclusion, token use, and final output. A future telemetry layer should preserve those distinctions without recording private source content.
Predictive evidence caching is another proposed extension. Work-order data could identify likely equipment manuals, procedures, and safety sections one or two days ahead, then prepare authorized evidence bundles at job, shift, and fleet tiers. The design must preserve tenant isolation or database row-level security and should cache evidence rather than model-written answers. It is promising because it attacks latency before the technician asks, but it is not part of the live implementation described here.
A practical build order
Engineers reproducing this architecture should resist beginning with the answer model. Start with the boundary that makes a citation trustworthy.
First, define typed contracts and error semantics. Next, build a document compiler that can prove its hierarchy and preserve source lineage. Package immutable releases and make publication resumable. Assign narrow responsibilities to R2, D1, and Vectorize. Implement exact reads before synthesized answers. Add hybrid retrieval, metadata filters, reranking, source-order restoration, and hash verification. Only then tune answer generation and repair. Once a single document is reliable, publish routing cards, introduce bounded agent selection, and add a stateful adjudication loop. Finally, integrate the thin Hermes skill and measure the entire experience from the user's device.
This order is slower than a vector-database demo and faster than debugging an untraceable production answer. It makes each new capability depend on evidence that already has an identity, lineage, and failure mode.
The larger architectural lesson
Cloudflare's agent ecosystem makes a document-agent architecture unusually compact. Workers provide the edge boundary; Agents SDK and Durable Objects provide identity and state; D1 records control data; Vectorize discovers candidates; R2 preserves evidence; Workers AI performs embedding, reranking, and synthesis; Access protects the endpoint; and MCP gives Hermes a small, durable tool contract.
The useful part is not the service count. It is the way responsibilities can be arranged so discovery never impersonates evidence, a document identity never becomes confused with a deployment, and a provider failure never looks like an empty answer. The system becomes federated only after the single-document contract is trustworthy.
The present implementation shows that the principal paths work in development. It also shows that functionality is not the finish line. For field use, the next decisive engineering problem is latency: return verified evidence in under five seconds, finish the answer in under ten, and let the user open the exact source whenever synthesis would only get in the way.

Sources and verification notes
Platform descriptions were verified against first-party documentation on September 6, 2026, and pricing figures were re-verified on September 22, 2026: Cloudflare Agents, Durable Objects, Vectorize, R2, D1, Workers AI, MCP on Cloudflare, and Cloudflare Access service tokens.
Implementation details, observed test data, engineering decisions, current status, and unfinished work come from the canonical implementation repository. All current pricing and platform-limit claims were refreshed immediately before publication.
notes
Follow the work
More field notes on retrieval systems, evidence, and supervised AI engineering.