Contracts¶
Every parser layer boundary in structure_parser is defined by a versioned Pydantic model. This design means any layer can be replaced or tested in isolation as long as it accepts the same input contract and returns the same output contract — the caller never needs to know which implementation is behind the interface.
Repository pipeline contracts are operational Pydantic models. They describe discovery, target paths, file statuses, run diagnostics, and aggregate statistics without redefining article, unit, component, or attribute semantics.
ParserConfig¶
ParserConfig is the configuration contract. It is a frozen Pydantic model constructed once per run and passed through to every layer that needs it. Its fields are:
| Field | Type | Default | Meaning |
|---|---|---|---|
schema_version |
str |
"1" |
Contract version |
source_format |
str |
"markdown" |
Format identifier used by AdapterRegistry |
enable_structured_markdown |
bool |
True |
Whether to run the Classification layer |
validation_mode |
str |
"advisory" |
"advisory" or "strict" |
resolve_local_references |
bool |
False |
Whether to run LocalFileResolver |
model_schema_dir |
str \| None |
None |
Override path for JSON schema directory |
emit_debug_logs |
bool |
False |
Whether to emit debug-level log lines |
max_diagnostic_count |
int |
200 |
Cap on diagnostics collected per document |
The validation_mode field controls the entire Validation layer's error-reporting behavior: "advisory" produces SP-030 warnings; "strict" produces SP-099 errors that set ParsedDocument.has_errors to True.
RawParseModel and RawNode¶
RawParseModel is the output contract of every adapter. It carries the source format identifier, the source path, a SHA-256 content hash of the raw bytes, the parsed front matter dict (or an empty dict if absent), the flat ordered list of RawNode objects, and any parse errors that the adapter could not recover from. Preserving source order is a hard requirement because the Classification and Enrichment layers depend on positional relationships between nodes.
Each RawNode carries:
| Field | Type | Meaning |
|---|---|---|
node_type |
str |
Broad category (heading, fence, inline, image, etc.) |
tag |
str |
Source tag or token type |
content |
str |
Text content of the node |
children |
list[RawNode] |
Inline children for block nodes |
attrs |
dict |
Element attributes (href, src, alt, etc.) |
start_line |
int \| None |
First source line (1-indexed) |
end_line |
int \| None |
Last source line (1-indexed) |
level |
int \| None |
Heading level (1–6) for heading nodes |
Line numbers are None when the adapter cannot determine them, which the provenance system records as partial or unavailable status.
ParsedDocument¶
ParsedDocument is the primary output contract of the parser flow. It is the object returned by single-file parser commands, API consumers, and parser test assertions. Its fields are:
| Field | Type | Meaning |
|---|---|---|
schema_version |
str |
Contract version |
source_path |
str |
Absolute path to the source file |
source_format |
str |
Format string from ParserConfig |
provenance |
DocumentProvenance |
Hash, timestamp, adapter version |
metadata |
dict |
Extracted front matter key-value pairs |
title |
str \| None |
H1 heading text, if present |
structure |
DocumentStructure |
Heading tree |
structured_content |
StructuredContent \| None |
Classification output; None if disabled |
references |
list[Reference] |
All links and images found |
diagnostics |
list[Diagnostic] |
All diagnostics emitted across all layers |
validation |
ModelValidationResult \| None |
Schema validation result |
readiness |
TransformReadiness \| None |
Per-target readiness assessment |
Three computed properties make common queries concise:
has_errors—Trueif anyDiagnosticindiagnosticshasseverity == "error"error_count— count of error-severity diagnosticswarning_count— count of warning-severity diagnostics
StructuredContent, Unit, Component, Attribute¶
These four contracts form the classification hierarchy. StructuredContent is the top-level container; it holds the inferred article type and an ordered list of Unit objects. Each Unit corresponds to one H2 section of the document and carries a unit_type, a heading title, a SourceSpan, and an ordered list of Component objects. Each Component maps to one block-level node and carries a component_type, its text content, a SourceSpan, and an optional list of Attribute objects. Each Attribute maps to one inline node and carries an attribute_type and its text content.
Unknown content at any level uses sentinel type values — artUnknown, unitUnknown, compUnknown, attUnknown — so that unclassified material is preserved in the output rather than discarded.
ParseRunResult and ParseStats¶
ParseRunResult is the contract returned by batch operations that process multiple files. It contains:
documents— the list ofParsedDocumentobjects, one per source filerun_diagnostics— diagnostics that apply to the run as a whole rather than any single file (for example, SP-002 when a directory contains no supported files)stats— aParseStatsobject
ParseStats summarizes the run with counts: total_files, success_count, error_count, warning_count, and elapsed_seconds. The computed property success on ParseRunResult is True only if no document in the run has has_errors == True and run_diagnostics contains no errors.
PipelineConfig and PipelineRunResult¶
PipelineConfig is the repository pipeline configuration contract. It contains file or folder inputs, an output directory, optional report and log paths, include and exclude patterns, strict-mode behavior, dry-run behavior, and the ParserConfig applied to each discovered source.
PipelineRunResult is the repository pipeline result contract. It contains a run_id, one PipelineFileResult per discovered file, run-level diagnostics, and PipelineRunStats.
PipelineFileResult is the bridge between repository operations and parser diagnostics. It records the discovered source, target path, status, parser diagnostic codes, pipeline error code, error count, warning count, and file-level duration.
DocumentProvenance and SourceSpan¶
These two contracts carry origin tracking information at different granularities. DocumentProvenance is attached to the ParsedDocument and records the SHA-256 content_hash of the source bytes, the parse_timestamp in ISO 8601 format, the adapter_version string, and the schema_version. SourceSpan is attached to individual Unit, Component, and Attribute objects and records the source_path, start_line, end_line, and a provenance_status value (available, partial, or unavailable).
Schema Versioning¶
All contracts carry schema_version = "1". The version field exists so that serialized contract instances (for example, cached JSON files) can be detected as stale if the schema changes between releases. Any change that removes a field, renames a field, or alters a field's type is a breaking change and requires incrementing schema_version. Additive changes — new optional fields with defaults — do not require a version bump but should be documented in the changelog.
Contract Class Hierarchy¶
classDiagram
class ParserConfig {
+schema_version: str
+source_format: str
+enable_structured_markdown: bool
+validation_mode: str
+resolve_local_references: bool
}
class RawParseModel {
+source_format: str
+source_path: str
+content_hash: str
+front_matter: dict
+nodes: list[RawNode]
+parse_errors: list
}
class RawNode {
+node_type: str
+tag: str
+content: str
+children: list[RawNode]
+attrs: dict
+start_line: int
+end_line: int
+level: int
}
class ParsedDocument {
+schema_version: str
+source_path: str
+source_format: str
+metadata: dict
+title: str
+has_errors: bool
+error_count: int
+warning_count: int
}
class StructuredContent {
+article_type: str
+units: list[Unit]
}
class Unit {
+unit_type: str
+title: str
+components: list[Component]
}
class Component {
+component_type: str
+content: str
+attributes: list[Attribute]
}
class Attribute {
+attribute_type: str
+content: str
}
class DocumentProvenance {
+content_hash: str
+parse_timestamp: str
+adapter_version: str
+schema_version: str
}
class DocumentStructure {
+headings: list
}
class Reference {
+ref_type: str
+href: str
+text: str
+state: str
+resolved_path: str
}
class Diagnostic {
+code: str
+severity: str
+category: str
+message: str
+remediation: str
}
class ModelValidationResult {
+schema_id: str
+valid: bool
+diagnostics: list[Diagnostic]
}
class TransformReadiness {
+targets: list[TargetReadiness]
}
class TargetReadiness {
+target: str
+status: str
+reasons: list[str]
+missing: list[str]
}
class ParseRunResult {
+documents: list[ParsedDocument]
+run_diagnostics: list[Diagnostic]
+stats: ParseStats
+success: bool
}
class ParseStats {
+total_files: int
+success_count: int
+error_count: int
+elapsed_seconds: float
}
RawParseModel "1" --> "0..*" RawNode : nodes
ParsedDocument "1" --> "1" DocumentProvenance : provenance
ParsedDocument "1" --> "1" DocumentStructure : structure
ParsedDocument "1" --> "0..1" StructuredContent : structured_content
ParsedDocument "1" --> "0..*" Reference : references
ParsedDocument "1" --> "0..*" Diagnostic : diagnostics
ParsedDocument "1" --> "0..1" ModelValidationResult : validation
ParsedDocument "1" --> "0..1" TransformReadiness : readiness
StructuredContent "1" --> "0..*" Unit : units
Unit "1" --> "0..*" Component : components
Component "1" --> "0..*" Attribute : attributes
TransformReadiness "1" --> "1..*" TargetReadiness : targets
ParseRunResult "1" --> "0..*" ParsedDocument : documents
ParseRunResult "1" --> "1" ParseStats : stats