# 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.