Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Validation

Status: Current Last updated: 2026-06-21 23:23 EDT

CHAT validation runs at multiple points in the processing pipeline. All validation logic is in Rust: talkbank-model::validation owns CHAT-core validation, and talkbank_transform::validate (crates/talkbank-transform/src/validate.rs) owns the Batchalign-side pre/post validation gate functions (validate_to_level, validate_output). This page covers validity levels, pre/post validation gates, severity posture, the verification-gate set (G0-G14), and how validation failures interact with caches and bug reports.

For the CHAT-core error-code infrastructure (codes, sinks, severities, layers), now owned by chatter, see chat-core-errors. For the diagnostic UX standard, see error-diagnostics-ux.

Validity Levels

The ValidityLevel enum defines three cumulative validation levels. Each level includes all checks from lower levels.

LevelNameChecks
L0ParseableNo parse errors (clean tree-sitter CST)
L1StructurallyComplete@Participants and @Languages present, all speaker codes declared, every utterance has a terminator
L2MainTierValidWell-formed words, valid timing bullets if present

Pre-validation gates

Each command requires input to meet a minimum level before processing:

CommandRequired level
morphotagMainTierValid
utsegStructurallyComplete
translateStructurallyComplete
corefStructurallyComplete
alignParseable (lenient, must handle messy real-world files)

validate_to_level() checks the file against the required level and returns all failures found. Invalid files are rejected early with diagnostics, before any compute is spent on inference.

Post-Serialization Validation

After an orchestrator injects results and serializes CHAT output, the server runs validate_output():

  1. Alignment validation: checks that %mor/%gra/%wor tier word counts match the main tier. ParseHealth-aware: utterances flagged as unparseable during lenient parsing are excluded.
  2. Semantic validation: full CHAT validation:
    • E362: non-monotonic timestamps (utterance bullets must increase).
    • E701 / E704: temporal constraints (overlap rules, same-speaker timing).
    • Header correctness, required headers present and well-formed.
    • Cross-utterance patterns, speaker code consistency.

Only blocks on severity="error", not warnings.

Severity Posture

Validation intentionally distinguishes errors from warnings:

  • Errors block output. The server will not write CHAT with error-level validation failures.
  • Warnings are reported but do not block. Legacy corpora contain widespread minor violations that must remain processable.

This distinction matters especially for %gra:

  • Existing broken %gra in old corpora may be accepted with warnings so files remain processable.
  • Newly generated %gra from batchalign3 is validated more strictly before writeback.

Bug Reports and Cache Purges

When post-serialization validation fails:

  1. A structured bug report is written to ~/.batchalign3/bug-reports/.
  2. Cache entries that produced the invalid output are purged (self-correcting cache).

This prevents broken results from being served on future runs.

Verification Gates (make verify)

The mandatory pre-merge / pre-push gate. All gates must pass before any code or doc change ships:

GateWhat it checks
G0Parser signature guardrail
G1Rust workspace compile check
G2Spec tools compile check
G3Spec runtime tools compile check
G4CHAT manual anchor links
G5Generated parser corpus equivalence suite
G6Golden fragment validity (words + tiers)
G7Bare-timestamp regression gate
G8Reference corpus semantic equivalence
G9%wor tier parsing and alignment
G10Golden tier roundtrip (%mor, %gra, %pho, %wor)
G11Reference corpus node coverage
G12Generated artifacts match committed sources
G13Fuzz workspace isolation
G14Imported Batchalign Rust/PyO3 gate

The reference corpus at corpus/reference/ is the sacred semantic target, every file must be valid CHAT, and make verify runs each gate against it.

The pre-push hook (make install-hooks) runs the fast subset (fmt, affected compile, parser guardrail, generated-check, fuzz-check) locally before push. CI runs the full set.

Validation at the PyO3 Boundary

There is no public Python validation API. The ParsedChat handle that previously exposed validate() / validate_structured() / validate_chat_structured() was retired in the 2026-03-21 PyO3 slimdown to worker-runtime-only. Validation now runs entirely on the Rust side; when a worker invocation detects a failure it constructs BatchalignBoundaryError::ChatValidation { entries, … } which the PyO3 boundary lowers into a CHATValidationException carrying a populated errors: list[ValidationErrorEntry] on the Python side.

Python callers that need structured validation results invoke batchalign3 via subprocess and catch the exception:

from batchalign_core import CHATValidationException

try:
    batchalign_core.execute_v2(request)
except CHATValidationException as exc:
    for entry in exc.errors:
        print(entry.code, entry.line, entry.message)

See Errors, Batchalign Runtime and Python ↔ Rust errors for the full boundary contract.

Known limitations

  • Validation rules are intentionally permissive on legacy data. Some checks emit warnings rather than errors so legacy corpora remain processable while still surfacing the issue. Examples: pre-existing malformed %gra (warned, not blocked, so files that already shipped with bad %gra round-trip cleanly); some bullet-format minor variants. Newly generated tiers from batchalign are validated more strictly before writeback.
  • %wor word counts are not validated against the main tier. %wor is a timing-annotation tier with no downstream positional indexing; legacy files may have xxx, fragments, or nonwords in %wor without producing alignment errors.
  • Cross-utterance quotation validation is gated off by default (enable_quotation_validation flag), the cross-utterance walker exists but is not yet wired into the standard validation gate.
  • Some error-spec / validator pairs are not yet implemented. Tracked in spec/errors/ files marked Status: not_implemented; these generate #[ignore] tests via make test-gen rather than failing CI. Run grep -rl "Status.*not_implemented" spec/errors/ to enumerate.

This page last changed: 2026-06-21 (commit 1de757d7). The whole book last changed: 2026-09-16 (commit 34d249d8).