Boundary rule catalog¶
Boundary rules are opt‑in, declarative constraints that operate at the shape level, after individual fields have been scanned, normalized, parsed, and validated.
They answer a different question than validators: Given all accepted fields, does the overall shape make sense? Boundary rules enforce structural, relational, and cross‑field constraints that cannot be expressed at the field level.
Boundary rules:
- Never run automatically.
- Never mutate values.
- Never validate individual fields.
- Never parse or normalize.
- Emit boundary‑level events.
- Run after all field decisions are known.
- Operate on the final values of fields.
- Can produce multiple issues in a single pass.
Boundary rules are the final gate before a boundary is accepted.
How Boundary Rules Work¶
- Field‑level work completes first: Scanning, normalization, parsing, and validation all run before boundary rules. Each field now has a final value and a decision (
accept,reject, and so on). - Boundary rules receive the full field map: Each rule is passed
{ fields }, where each entry contains: - The final value.
- The decision.
- The events emitted so far.
- Rules inspect relationships between fields:
- Presence or absence.
- Mutual exclusivity.
- Conditional requirements.
- Chronological ordering.
- Structural constraints.
- Unknown keys.
- Rules emit boundary‑level events: These events describe shape‑level issues, not field‑level ones.
- Policy interprets boundary events. Policy decides whether boundary issues:
- Reject the boundary
- Downgrade to warnings
- Trigger review
Boundary rules never decide acceptance on their own.
Boundary Rule Categories¶
Boundary rules are grouped by the type of structural constraint they enforce.
Each section includes:
- A description of the rule category.
- The rules in that category.
- Cross‑links to related validators and parsers.
This helps developers understand how boundary rules fit into the full pipeline.
Presence Rules¶
Presence rules ensure that required fields appear — or that optional fields appear only under certain conditions.
- All listed fields must be present and accepted.
- Missing or rejected fields each produce an error.
- At least one of the listed fields must be accepted.
- Emits a single error if none are present.
- When a controlling field matches a specific value, additional fields become required.
- Emits one error per missing field.
Exclusivity Rules¶
Exclusivity rules ensure that certain fields cannot appear together.
- Fields
aandbcannot both be accepted. - Emits a single conflict error.
- No more than one of the listed fields may be accepted.
- Emits one error if multiple appear.
Structural Rules¶
Structural rules enforce shape‑level constraints that go beyond simple presence or exclusivity.
- Any field not listed is treated as unknown.
- Emits one error per unknown key.
- Ensures
startDateoccurs beforeendDate. - Emits a single chronological‑ordering error.
Example: Mutually Exclusive Rule¶
export function mutuallyExclusive(a: string, b: string): BoundaryRule {
return ({ fields }) => {
const ra = fields[a];
const rb = fields[b];
if (ra?.decision?.code === "accept" &&
rb?.decision?.code === "accept") {
const ev: JaneEvent = {
phase: "decide",
kind: "error",
code: "boundary.does.mutual-exclusion",
message: `Fields "${a}" and "${b}" cannot both be present`,
path: rootPath(),
};
return { events: [ev], issues: [ev] };
}
return { events: [], issues: [] };
};
}
This illustrates the boundary‑rule contract:
- Inspect final field decisions.
- Evaluate cross‑field relationships.
- Emit structured boundary events.
- Never mutate values.
- Never override field‑level decisions.
Summary¶
Boundary rules are the final structural enforcement stage of the Jane pipeline. They ensure that the shape of the data — not just individual fields — is valid.
Boundary rules are:
- Opt‑in: Nothing runs unless you call
.boundary(). - Declarative: You describe relationships, not mechanics.
- Pure: No mutation, no coercion.
- Event‑emitting: Every issue is recorded.
- Policy‑interpreted: Boundary rules never reject on their own.
Boundary rules are where the full shape becomes meaningful — explicitly, predictably, and transparently.