Implement ValidationPlan (ADR-012 §3, plan phase 7)

The compiled value-domain validation form: replaces the interpretive
BastDoc walk in validate_bytes with a compile-once-walk-many
constraint tree built at engine-compile time. This was the design
session + implementation ADR-012 §3 delegated; the shape decisions
are recorded in new ADR-012 §3a.

- New src/validation_plan.rs: ValidationPlan + ValidNode/ValidField/
  ValidVariant (Debug+Clone+PartialEq+Eq+Hash+Send+Sync),
  compile(&BastDoc) with eager $ref resolution, and a per-buffer walk
  with deferred error-path rendering (zero happy-path allocation,
  byte-identical error messages vs the 0.2.0 walker).
  fingerprint() via DefaultHasher, same as the phase-6 pattern.
- Compile-time graph safety: definition-level cycle set + depth cap
  (128) reject cyclic $ref graphs with AlkTypeError::Schema. The
  interpretive walker resolved refs lazily with no guard (stack-
  overflow hazard); diamond (shared) refs still compile.
- bast_validation.rs: interpretive walker retired (deleted);
  validate_value survives as a one-shot wrapper (compile + validate)
  for callers holding a doc without an engine.
- engine: Arc<ValidationPlan> built at compile in BOTH modes; the
  plan compile runs before the layout build and doubles as the
  engine's cyclic-ref gate (LayoutBuilder/OffsetMap struct recursion
  has no cycle guard; a cyclic doc previously overflowed there).
  validate_bytes walks the plan; new accessor validation_plan().
  validate_bytes signature unchanged.
- lib.rs: pub mod validation_plan + re-exports (ValidationPlan,
  ValidNode, ValidField, ValidVariant).

Verification: cargo test --release (355 pass, incl. parity suite,
fingerprint contract, cycle/depth rejection, Send+Sync + thread-share
assertions); clippy --all-targets -D warnings clean; cargo doc
zero warnings; wasm32-unknown-unknown release build green.

Co-authored-by: opencode <noreply@alk.dev>
This commit is contained in:
glm-5.3-flashandopencode committed 2026-08-31 17:45:46 +00:00
1 parent e461f01c97
commit e4636e6a44
10 files changed
+1568 -429

No files matched your search

+13 -7
View File
@@ -19,13 +19,17 @@
//! offsets, zero-copy for fixed-size types.
//! - **TUnion dispatch** ([`tunion`]): Byte-offset and field-name
//! discriminator dispatch over `BastUnion`.
//! - **Validation** ([`validation`], [`bast_validation`]): two
//! validators for two paths. `bast_validation` is the BAST-native
//! validator for `validate_bytes` — a recursive walker over the BAST
//! type tree (D-BAST-006). `validation` builds a standard
//! `jsonschema::Validator` from a consumer-provided JSON Schema for
//! `validate_json` / `is_valid_json` (D-BAST-007) — no custom keywords,
//! no BAST involvement.
//! - **Validation** ([`validation`], [`bast_validation`],
//! [`validation_plan`]): two validators for two paths.
//! `validation_plan` is the compiled `ValidationPlan` — a
//! compile-once-walk-many constraint tree over the BAST document's
//! value-domain constraints, walked by `validate_bytes` per buffer
//! without re-touching the document (ADR-012 §3). `bast_validation`
//! hosts the one-shot `validate_value` wrapper over the plan.
//! `validation` builds a standard `jsonschema::Validator` from a
//! consumer-provided JSON Schema for `validate_json` /
//! `is_valid_json` (D-BAST-007) — no custom keywords, no BAST
//! involvement.
//! - **Builder** ([`builder`]): Fluent Rust API for constructing BAST
//! documents (binary layout) and standard JSON Schemas (JSON
//! validation) at runtime, producing `serde_json::Value` (ADR-009,
@@ -52,6 +56,7 @@ pub mod schema;
pub mod sequential_reader;
pub mod tunion;
pub mod validation;
pub mod validation_plan;
pub use bast_meta::BAST_META_SCHEMA;
pub use bast::{
@@ -67,3 +72,4 @@ pub use schema::{Endian, AlkTypeKind, VariableEncoding};
pub use sequential_reader::{FieldValue, SequentialReader};
pub use tunion::UnionDispatch;
pub use validation::build_validator;
pub use validation_plan::{ValidField, ValidNode, ValidVariant, ValidationPlan};