Executor
The execution port: run a plan into blocks, embeddings, and a trace.
Port: encode(request: EncodeRequest) -> EncodeResult, reached as indx.encode().
A stage rather than an extension point, so no Executor protocol is declared:
DocumentExecutor is the one implementation and nothing outside this workspace
provides another.
Executor is the boundary for turning a route plan into processed document
data. It accepts a source, output and embedding preferences, constraints, and an
optional plan. It returns the plan used, an addressable block tree, embedding
space descriptions, an execution trace, and aggregate usage.
Execution invokes the capability selected for each scope and may proceed through only the ordered fallbacks declared in the plan. It records what actually ran and distinguishes completed, failed, and unreadable outcomes.
The executor keeps expensive and failure-prone work separate from planning. The planner can remain deterministic and inspectable, while execution can report real latency, cost, quality, resource use, validation results, and fallback behavior.
Treating the plan as an execution boundary also protects caller intent. A supplied plan is either compatible with the source and snapshot or rejected; it is never silently replaced with a newly chosen route.
Contract
Section titled “Contract”The input is
EncodeRequest,
which carries a request ID, source, constraints, requested granularities,
embedding-space IDs, signature-detection flag, optional RoutePlan, and
metadata — the caller’s own labels, carried onto the document block and
enforced nowhere. That field is on EncodeRequest and deliberately not on
PlanRequest: plan_id hashes every field of the plan it is decided into, so a
tenant label would give two identical documents two plans for a value that
routes nothing. It refuses the keys languages and classification, which the
executor writes from an installed language detector
and from the classifiers the
request enabled under classification – IDs in the order they are asked, named
per unit. It refuses entities the same way, which the executor writes from the
entity extractors a request enabled
under extraction. Nothing bounds how much of the document an annotation is
shown: each is handed the full text of its unit and applies its own bound if it
needs one.
Annotations are refused before the source is fetched, never mid-run: an ID
nothing installed declares is a 422 enumerating the ones that are; an
implementation whose device is external under a data_residency constraint
is a 422 rather than a silent omission; and naming a chunk-targeted classifier
or extractor without asking for CHUNK granularity is a 422 too, because
there would be no chunks to annotate and an empty answer is indistinguishable
from no opinion. The last is the same refusal
REGION
already gets, for the same reason.
The output is
EncodeResult,
which carries:
- The request and document IDs and the exact plan used.
- Addressable document, page, region, and chunk blocks.
- Text, metadata, provenance, status, and embeddings on those blocks. The document block’s provenance names the media type and the source URI or filename beside the plan it came from; its metadata carries the caller’s labels, where a detector is installed the languages it was read in, where the request enabled a classifier the facets it was labelled with, and where it enabled an entity extractor the spans it found, keyed by the block each was found in, with document-level counts beside them.
- The complete embedding-space descriptors needed to interpret vectors.
- A scoped execution trace identifying planned and actual capabilities.
- Aggregate bytes, pages, cost, latency, quality, and resource use.
Responsibilities and guarantees
Section titled “Responsibilities and guarantees”- Obtain a plan before capability execution when the request does not supply one, through the composed encoding workflow.
- Validate a supplied plan against the source digest, media type and capability snapshot.
- Execute only selected capabilities or fallbacks explicitly declared by the plan.
- Preserve scope and parent relationships in the returned block tree.
- Identify every vector by embedding-space and embedder ID and honor the declared vector dimension.
- Record actual capability, device, fallback index, validation, latency, cost, and quality for each trace event.
- Report unreadable scopes and terminal failures explicitly rather than silently omitting content.
An unsatisfied plan is reported, not raised. Nothing conflicts and the request was valid: the caller’s constraints simply cannot be met by what is installed. That outcome is a failed document block carrying the reason and a failed trace saying the same, which keeps the constraints visible instead of flattening them into an error string.
Validation of what a capability produced is first-party and not a declared port,
and it asks three questions of every page a rung was given. Did anything come
back for it? Did the capability declare the page failed? And did it report a
confidence below the floor this deployment set in
INDX_VALIDATION_MIN_CONFIDENCE, which is 0.0 – off – unless an operator has
measured one against their own output? Any of the three sends that page, and only
that page, to the next rung, and the refused output is discarded rather than
carried alongside its replacement. An unreadable status is deliberately not one
of the three: it is a verdict about the content rather than the attempt.
A route whose every capability failed is a 503. The routing ladder ends in
manual review by construction, so exhausting one means an installation that
stripped the terminal fallback out – a deployment fault the caller should hear
about, rather than a document quietly returned with pages missing.
The protocol does not prescribe adapter internals or how the composed service obtains a missing plan. Those choices remain behind the boundary.
Place in the system
Section titled “Place in the system”The public indx.encode() facade and POST /v1/encode operation expose the
encoding workflow. The executor consumes planning decisions and capability
implementations but returns only public indx-interfaces contracts.