StructX Roadmap¶
Last updated: 2026-07-11
This roadmap records future library work that should remain reproducible, portable, and safe across Python processes. It is ordered by dependency rather than calendar date.
Current Focus¶
The current priority is the stable extraction pipeline:
- portable
ExtractionRequestdefinitions - canonical type capabilities
- synchronous and native asynchronous extraction
- schema generation and refinement
- deterministic custom-model handling
- row-level outcomes and usage reporting
- consistent document preparation and cleanup
Future: Declarative Business Validation¶
Status: Not scheduled
Business validation should extend the portable model definition without storing
or executing arbitrary user code. Existing ModelField.validation constraints
already cover deterministic field semantics such as:
gt,ge,lt,le, andmultiple_ofmin_lengthandmax_length- string patterns
- strict field handling
- required, nullable, and default-value behavior
The next validation layer should support relationships between fields and
domain rules that cannot be represented by one Pydantic Field.
Design Principles¶
- Store declarative rule data, never Python source, pickles, lambdas, or arbitrary expressions.
- Compile deterministic rules from trusted StructX implementations.
- Keep extraction success separate from business-validation status.
- Preserve every rule and outcome so an extraction can be reproduced.
- Make semantic LLM validation an explicit, metered phase rather than a hidden side effect of Pydantic parsing.
- Track validation usage through the same operation-local usage system as schema generation and extraction.
- Never modify extracted values silently.
Portable Rule Contract¶
ExtractionRequest should eventually contain a versioned list of typed rule
definitions. Rules should use a discriminated union rather than a free-form
expression language.
Illustrative deterministic rule:
{
"id": "valid_contract_dates",
"kind": "field_comparison",
"left_field": "effective_date",
"operator": "le",
"right_field": "termination_date",
"severity": "error",
"message": "The effective date must not be after the termination date"
}
Initial deterministic rule types should be evaluated separately and added only when their semantics are unambiguous:
- compare a field with another field
- compare a field with a constant
- require a field conditionally
- require at least one field from a group
- require exactly one field from a group
- make fields mutually exclusive
- restrict values to an allowed set
- enforce date ordering
- enforce numeric totals or ranges
- enforce collection uniqueness where the type alone does not
Every rule should include:
- stable identifier
- rule kind and typed parameters
- referenced fields
- error or warning severity
- user-facing failure message
- schema version
The compiler must validate field references and rule compatibility when the
model is created. It must not use eval, execute user expressions, or import
user code.
Runtime Compilation¶
model_from_extraction_request() should compile supported deterministic rules
into Pydantic model validators generated by StructX. These runtime callables are
implementation details; the serialized rule definitions remain the source of
truth.
model_to_extraction_request() should continue rejecting arbitrary validators
from external Pydantic models. Models created by StructX can round-trip because
they retain their original portable definition, including its rule data.
The compiler should return clear construction-time errors for:
- missing field references
- incompatible operand types
- unsupported rule combinations
- rules that require executable Python behavior
- recursive or ambiguous dependencies between rules
Validation Outcomes¶
Validation should produce structured outcomes rather than only raising an exception:
{
"rule_id": "valid_contract_dates",
"status": "failed",
"severity": "error",
"fields": ["effective_date", "termination_date"],
"reason": "The effective date is after the termination date",
"suggested_value": null
}
Planned result semantics:
passed: rule was evaluated and satisfiedfailed: an error-severity rule was violatedwarning: a warning-severity rule was violatedskipped: required inputs were unavailable or nullerror: the validation engine could not evaluate the rule
Row extraction status and validation status must remain separate. A row may be successfully extracted while failing one or more business rules.
Future: Semantic LLM Validation¶
Status: Not scheduled; dependent on deterministic validation outcomes
Semantic rules should be portable natural-language statements with explicit scope and behavior:
{
"id": "deliverable_address",
"kind": "semantic",
"fields": ["address"],
"statement": "The address must be complete enough for postal delivery",
"severity": "warning",
"action": "flag"
}
Semantic validation should run after ordinary extraction and deterministic Pydantic validation:
Extraction
-> Pydantic field validation
-> deterministic business rules
-> batched semantic validation
-> structured validation outcomes
The semantic validation engine should:
- provide native sync and async APIs
- validate the complete object when a rule crosses field boundaries
- include relevant source evidence when available
- batch compatible rules to avoid one model request per field
- use a separately configurable validation model
- isolate validation usage under a dedicated extraction step
- preserve provider usage objects
- return reasons and optional suggested corrections
- default to flagging rather than mutating values
- make any automatic correction explicit, opt-in, and auditable
Relationship To Instructor llm_validator¶
Instructor's llm_validator demonstrates the usefulness of semantic
validation, but it should not be StructX's production execution model. The
callable captures a synchronous client and model, performs a model request
during Pydantic parsing, and does not report usage through StructX. Applying it
to many fields or list items could also create hidden request multiplication.
StructX may provide an adapter for local synchronous use in the future, but the core implementation should be an operation-level async validation phase with explicit usage and outcomes.
Configuration And Usage¶
Semantic validation will likely require:
- a
validationsection inExtractionConfig - an optional validation model distinct from planning and extraction models
- a new
ExtractionStep.SEMANTIC_VALIDATION - validation usage merged into
ExtractorUsage - per-row validation usage where evaluation occurs per row
No validation defaults should silently add model calls. Semantic validation must run only when the caller supplies semantic rules and enables evaluation.
Proposed Public API¶
Exact names remain open, but the API should make validation visible:
result = await extractor.extract_async(
data=input_data,
query=query,
model=model,
validate=True,
)
for row in result.rows:
print(row.status)
print(row.validation_status)
print(row.validation_outcomes)
A standalone API may also be useful for validating existing objects without re-running extraction:
validation = await extractor.validate_async(
data=existing_object,
model=model,
source=optional_source_evidence,
)
Implementation Phases¶
Phase 1: Rule Schema¶
- Define versioned deterministic rule models.
- Add rules to the portable extraction definition.
- Validate field references and operand compatibility.
- Document serialization and migration behavior.
Phase 2: Deterministic Compiler¶
- Compile supported rules into trusted Pydantic validators.
- Add structured validation outcomes.
- Preserve extraction and validation status separately.
- Add nested-model and collection coverage.
- Add serialization and reconstruction tests for every rule type.
Phase 3: Semantic Validation Engine¶
- Define the portable semantic rule schema.
- Add sync and native async evaluation.
- Add object and source-evidence context.
- Batch compatible rules.
- Add configurable validation models and parameters.
- Track operation-level and row-level usage.
- Add warnings, failures, reasons, and suggested corrections.
Phase 4: Corrections And Review¶
- Add explicit correction proposals.
- Preserve original and proposed values.
- Require opt-in before automatic correction.
- Record correction provenance and usage.
- Add revalidation after accepted corrections.
Testing Requirements¶
- deterministic rule serialization and reconstruction
- invalid field references and incompatible operand types
- nested models and collection rules
- null and missing-value behavior
- warning versus error semantics
- stable outcomes across sync and async paths
- semantic request batching and concurrency limits
- semantic usage attribution
- partial provider failures
- suggested corrections that never overwrite originals implicitly
- no model request when semantic validation is disabled
Open Decisions¶
- whether validation rules belong directly on
ExtractionRequestor in a versioned companion model - whether deterministic failures should raise during construction, extraction, or only appear as outcomes
- how source evidence is selected and limited for semantic validation
- whether one semantic request should validate one row or a bounded row batch
- which correction actions are permitted in the core library
- whether validation models should have independent retry and concurrency limits
- how semantic validation interacts with Instructor retries during extraction
Maintenance¶
Keep future work in this file until it is scheduled. Once implementation begins, move accepted contracts into user guides and API documentation, and move completed work into the changelog.