Data Validation Pipeline Pattern
> ℹ️ TWO SYNTAX STYLES: This document shows two AINL syntax styles: > 1. Compact syntax (works now) — Python-like, recommended for new code. > See examples/compact/ and AGENTS.md for the full reference. > 2. Graph blo
Data Validation Pipeline Pattern
ℹ️ TWO SYNTAX STYLES: This document shows two AINL syntax styles:
- Compact syntax (works now) — Python-like, recommended for new code. See
examples/compact/andAGENTS.mdfor the full reference.- Graph block syntax (
graph { node ... }) — DESIGN PREVIEW, does NOT compile. These blocks are labeled "Design Preview" below.Use compact syntax for real projects:
ainl validatefile--strict
Multi-stage data validation with LLM + deterministic checks.
Use Case
Ingesting data from external sources that may contain:
- Missing fields
- Wrong types
- Business logic violations
- Format errors
Need validation before processing.
Implementation
Real AINL Syntax (v1.3.3 — this compiles)
# validation_pipeline.ainl — Multi-stage data validation
# ainl validate validation_pipeline.ainl --strict
S app core noop
L_start:
R core.GET ctx "data" ->data
R core.GET ctx "source" ->source
# Stage 1: Check required fields
R core.GET data "id" ->id
R core.GET data "email" ->email
R core.GET data "amount" ->amount
If (core.eq id null) ->L_reject_schema ->L_check_email
L_check_email:
If (core.eq email null) ->L_reject_schema ->L_check_amount
L_check_amount:
If (core.lt amount 0) ->L_reject_business ->L_accept
L_reject_schema:
Set result {"valid": false, "errors": ["missing required field"]}
J result
L_reject_business:
Set result {"valid": false, "errors": ["amount must be >= 0"]}
J result
L_accept:
Set result {"valid": true, "errors": [], "data": data}
J result
Design Preview Syntax (AINL 2.0 — does NOT compile yet)
graph ValidationPipeline {
input: Record = { data: object, source: string }
node validate_schema: ValidateSchema("schema-check") {
schema: {
type: object
required: ["id", "email", "amount"]
properties: {
id: { type: "string" }
email: { type: "string", format: "email" }
amount: { type: "number", minimum: 0 }
}
}
data: input.data
}
node validate_business: Transform("rules") {
errors: []
if input.data.amount < 0:
errors.append("Amount must be >= 0")
result: { valid: len(errors)==0, errors: errors }
}
node aggregate: Transform("combine") {
is_valid: validate_business.valid
errors: validate_business.errors
result: { valid: is_valid, errors: errors, data: input.data if is_valid else null }
}
node route: switch(aggregate.result.valid) {
case true -> accept
case false -> reject
}
node accept: WriteFile("accepted") {
path: "./data/accepted.jsonl"
content: serialize_json(aggregate.result.data)
mode: append
}
node reject: WriteFile("rejected") {
path: "./data/rejected.jsonl"
content: serialize_json({
source: input.source,
data: input.data,
errors: aggregate.result.errors,
ts: now()
})
mode: append
}
output: aggregate.result
}
