# Validation Architecture Validation is split into three ownership layers. ```mermaid flowchart LR Server[server
stores simple settings
binds table fields
enforces writes] Core[validation-core
owns meaning
resolves sets
runs pure validation] Canvas[canvas
editor integration
masking while typing
UI feedback] Common[common/proto
wire format] Server --> Core Canvas --> Core Server --> Common Canvas --> Common ``` ## Rule `server` stores dumb, serializable settings. `validation-core` owns what those settings mean. `canvas` uses the resolved result for editing behavior. ```mermaid flowchart TD Settings[ValidationSettings
serializable data] Rule[ValidationRule
named reusable fragment] Set[ValidationSet
ordered rules] Config[ValidationConfig
resolved runtime config] Result[ValidationResult] Rule --> Settings Set --> Rule Set --> Settings Settings --> Config Config --> Result ``` ## Current Data Flow ```mermaid sequenceDiagram participant DB as server DB participant Server as server participant Core as validation-core participant Client as client/canvas DB->>Server: stored field validation settings Server->>Core: interpret shared validation primitives Server->>Client: gRPC validation config Client->>Core: resolve/use shared primitives Client->>Client: canvas editing, masks, errors ``` ## Set Flow ```mermaid flowchart LR RuleA[digits-only rule] RuleB[phone-length rule] RuleC[phone-mask rule] Set[phone set] Assignment[column assignment] Stored[server stored settings
set name + resolved config] Runtime[server/canvas runtime] RuleA --> Set RuleB --> Set RuleC --> Set Set --> Assignment Assignment --> Stored Stored --> Runtime ``` The server stores reusable rules and sets, and field application stores a resolved snapshot: ```text field customer_phone uses set phone resolved settings = {...} ``` That keeps backend enforcement stable even if the reusable set changes later.