# Architectural Rules

> Every algorithm contract in this domain is listed with its position on the derivation loop, its intent and invariant, the flow it walks, its productions as a…

Page: Ontology · Algorithms
Canonical: https://banes-lab.com/ontology/algorithms#algo-domain-architectural-rules

Every algorithm contract in this domain is listed with its position on the derivation loop, its intent and invariant, the flow it walks, its productions as a grammar, what it composes and is composed by, which forces and principles it answers to, what grounds it and what it grounds, and an exemplar where the record carries one. The diagram shows what composes what inside the domain.

Relations diagram

What composes what inside this domain.

```mermaid
flowchart LR
n_no_shortcuts["Constraints Over Shortcuts"]
n_no_backward_compat["Forward Compatibility Over Backward Compatibility"]
n_no_fallback["Fail-Fast Over Fallback"]
n_no_deprecation["Explicit Removal Over Deprecation"]
n_no_legacy["Greenfield Over Legacy"]
n_no_dual_path["Single-Path Determinism Over Dual-Path"]
n_no_deferring["Immediacy Over Deferring"]
n_no_optional["Mandatory Over Optional"]
n_no_for_now["Now Over For-Now"]
n_no_unobserved["Observed Execution Over Unobserved"]
n_no_uncompressed["Compression Over Repetition"]
n_no_unapproved["Approved Evolution Over Unapproved"]
n_no_ignored_feedback["Enforced Feedback Over Ignored"]
n_no_shared_ownership["Single Owner Over Shared Ownership"]
n_no_unbounded["Bounded Lifetime Over Unbounded"]
n_no_asymmetric["Enforced Symmetry Over Asymmetric Lifecycle"]
n_no_implicit_retention["Explicit Retention Over Implicit"]
n_no_discipline_release["Structural Release Over Discipline"]
n_no_mutable["Immutable Data Over Mutable State"]
n_no_silent["Errors As Language Over Silent Errors"]
n_no_hidden_invalidity["Explicit Invalidity Over Hidden"]
n_no_callbacks["Event Emission Over Parent Callbacks"]
n_no_retraction["Monotonic Growth Over Retraction"]
n_no_location["Semantic Addressing Over Location Addressing"]
n_no_timestamps["Ordinal Time Over Timestamps"]
n_no_separation["Homoiconicity Over Separation"]
n_no_unlimited["Bounded Complexity Over Unlimited"]
n_no_metrics["Computed Health Over Metric Health"]
n_no_hardcoded_secrets["Secret Store Over Hardcoded Secrets"]
n_no_unvalidated_input["Boundary Validation Over Unvalidated Input"]
n_no_broad_privilege["Least Privilege Over Broad Privilege"]
n_no_env_fallback["Config Externalization Over Env Fallback"]
n_no_unmeasured_optimization["Profile-First Over Unmeasured Optimization"]
n_no_convention_enforcement["Rule As Code Over Convention"]
n_no_implicit_contract["Design By Contract Over Implicit Contract"]
n_no_breaking_change["Versioned Evolution Over Breaking Change"]
n_no_untyped_boundary["Schema-Validated Boundary Over Untyped"]
n_no_partial_commit["Atomic Boundary Over Partial Commit"]
n_no_distributed_2pc["Saga Compensation Over Distributed 2PC"]
n_no_sync_cross_boundary["Async Events Over Synchronous Cross-Boundary"]
n_no_opaque_runtime["Observable Signals Over Opaque Runtime"]
n_no_hidden_dependency["Injected Dependency Over Hidden"]
n_no_hardcoded_wiring["Convention Discovery Over Hardcoded Wiring"]
n_no_imperative_config["Declarative Config Over Imperative"]
n_no_leaky_context["Anti-Corruption Layer Over Cross-Context Leak"]
n_no_hidden_nondeterminism["Injected Nondeterminism Over Hidden"]
n_no_speculative_pattern["Pattern By Fit Over Speculative Pattern"]
```

### Constraints Over Shortcuts

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a debt-incurring shortcut with an encoded constraint that makes the invalid state unrepresentable, so the rule holds without relying on discipline.

Invariant
A value that could be constructed invalidly is instead constructed only through a validating boundary.

Flow

```text
ShortcutTaken → IdentifyInvariant → EncodeConstraint → RouteThroughBoundary → LeverageGained
```

Productions

```bnf
NoShortcuts ::= <ShortcutTaken> "->" <IdentifyInvariant> "->" <EncodeConstraint> "->" <RouteThroughBoundary> "->" <LeverageGained>
```

Composes
[Structural Core](https://banes-lab.com/records/algo/structural-core.md), [Coupling Control](https://banes-lab.com/records/algo/coupling-control.md)

Forces
shortcuts (debt)

Grounds
none

Before

```typescript
type FooId = string;

function loadFoo(raw: string) {
return fooStore.get(raw as FooId);
}
```

After

```typescript
type FooId = string & { readonly __brand: "FooId" };

function fooId(raw: string): FooId {
if (!raw.startsWith("foo_") || raw.length <= 4) throw new Error(`invalid FooId: ${raw}`);
return raw as FooId;
}

function loadFoo(id: FooId) {
return fooStore.get(id);
}
```

### Forward Compatibility Over Backward Compatibility

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace accreted legacy input shapes with one forward-compatible envelope that carries extensions, so evolution compounds instead of branching.

Invariant
One canonical shape with an open extension slot subsumes every prior variant; no shape-discriminating branch remains.

Flow

```text
ManyVariants → DefineEnvelope → MapToCanonical → OpenExtensionSlot → RemoveVariantBranches
```

Productions

```bnf
NoBackwardCompat ::= <ManyVariants> "->" <DefineEnvelope> "->" <MapToCanonical> "->" <OpenExtensionSlot> "->" <RemoveVariantBranches>
```

Composes
[Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
backward_compatibility (debt)

Grounds
none

Before

```typescript
type FooInput = string | { name: string } | { label: string; flags?: string[] };

function readFoo(input: FooInput) {
if (typeof input === "string") return { label: input, flags: [] };
if ("name" in input) return { label: input.name, flags: [] };
return { label: input.label, flags: input.flags ?? [] };
}
```

After

```typescript
type FooEnvelope = {
kind: "foo";
label: string;
extensions: Readonly<Record<string, unknown>>;
};

function readFoo(input: FooEnvelope) {
return { label: input.label, extensions: input.extensions };

}
```

### Fail-Fast Over Fallback

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a silent fallback default with a required input that halts loudly when absent, so missing configuration surfaces at the boundary.

Invariant
Every required input is present and validated before use; absence throws rather than defaulting.

Flow

```text
OptionalInput → MarkRequired → ValidateAtBoundary → HaltOnAbsence → ClarityGained
```

Productions

```bnf
NoFallback ::= <OptionalInput> "->" <MarkRequired> "->" <ValidateAtBoundary> "->" <HaltOnAbsence> "->" <ClarityGained>
```

Composes
[Resource Core](https://banes-lab.com/records/algo/resource-core.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
fallback (debt)

Grounds
none

Before

```typescript
function makeFoo(config: { mode?: "foo" | "bar" }) {
const mode = config.mode ?? "foo";
return mode === "foo" ? new Foo() : new Bar();
}
```

After

```typescript
type FooConfig = { mode: "foo" | "bar" };

function makeFoo(config: FooConfig) {
if (!config.mode) throw new Error("FooConfig.mode is required");
return config.mode === "foo" ? new Foo() : new Bar();
}
```

### Explicit Removal Over Deprecation

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a deprecated alias kept for compatibility with outright removal, so the single current name is the only path.

Invariant
No symbol exists solely to forward to another; every callsite targets the canonical name.

Flow

```text
DeprecatedAlias → MigrateCallsites → DeleteAlias → SinglePathRemains
```

Productions

```bnf
NoDeprecation ::= <DeprecatedAlias> "->" <MigrateCallsites> "->" <DeleteAlias> "->" <SinglePathRemains>
```

Composes
[Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
deprecation (debt)

Grounds
none

Before

```typescript
class FooService {
makeFoo() { return this.createFoo(); }
createFoo() { return new Foo(); }
}
```

After

```typescript
class FooService {
createFoo() { return new Foo(); }
}
```

### Greenfield Over Legacy

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a legacy-mode branch with one current algorithm, deleting the old path rather than gating it behind a flag.

Invariant
A single implementation serves the concern; no legacy-mode conditional selects behavior.

Flow

```text
LegacyBranch → ExtractCurrentPath → DeleteLegacyPath → RemoveFlag
```

Productions

```bnf
NoLegacy ::= <LegacyBranch> "->" <ExtractCurrentPath> "->" <DeleteLegacyPath> "->" <RemoveFlag>
```

Composes
[Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
legacy (debt)

Grounds
none

Before

```typescript
function calculateFoo(input: FooInput, legacyMode: boolean) {
if (legacyMode) return oldFooAlgorithm(input);
return newFooAlgorithm(input);
}
```

After

```typescript
function calculateFoo(input: FooInput) {
return fooAlgorithm(input);
}
```

### Single-Path Determinism Over Dual-Path

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Collapse a flag-selected dual path into one deterministic path, removing the branch and the flag that caused ambiguity.

Invariant
Exactly one code path handles the operation; no runtime flag chooses between equivalent implementations.

Flow

```text
DualPath → ChooseCanonical → MigrateConsumers → DeleteAlternate → DeterminismGained
```

Productions

```bnf
NoDualPath ::= <DualPath> "->" <ChooseCanonical> "->" <MigrateConsumers> "->" <DeleteAlternate> "->" <DeterminismGained>
```

Composes
[Structural Core](https://banes-lab.com/records/algo/structural-core.md), [Execution Core](https://banes-lab.com/records/algo/execution-core.md)

Forces
dual-path (confusion)

Grounds
none

Before

```typescript
function saveFoo(foo: Foo, flags: { useNewStore: boolean }) {
return flags.useNewStore
? newFooStore.save(foo)
: oldFooStore.save(foo);
}
```

After

```typescript
function saveFoo(foo: Foo) {
return fooStore.save(foo);
}
```

### Immediacy Over Deferring

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a deferred follow-up with an atomic action that completes every coupled effect now, so nothing is forgotten.

Invariant
Coupled effects commit together within one boundary; no effect is left as an implicit later step.

Flow

```text
PartialAction → IdentifyCoupledEffects → WrapInTransaction → CommitTogether
```

Productions

```bnf
NoDeferring ::= <PartialAction> "->" <IdentifyCoupledEffects> "->" <WrapInTransaction> "->" <CommitTogether>
```

Composes
[Execution Core](https://banes-lab.com/records/algo/execution-core.md), [Atomic Boundary](https://banes-lab.com/records/algo/atomic-boundary.md)

Forces
deferring (forgetting)

Grounds
none

Before

```typescript
async function renameFoo(id: FooId, name: string) {
await fooStore.rename(id, name);

}
```

After

```typescript
async function renameFoo(id: FooId, name: string) {
await transaction(async tx => {
await tx.foos.rename(id, name);
await tx.search.reindex(id, name);
});
}
```

### Mandatory Over Optional

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace an optional dependency with a mandatory one, removing the null-guarded branch so behavior is system-defined not caller-defined.

Invariant
A dependency the behavior relies on is always supplied; no optional-chaining guards its use.

Flow

```text
OptionalDependency → MakeRequired → InjectAlways → RemoveGuards
```

Productions

```bnf
NoOptional ::= <OptionalDependency> "->" <MakeRequired> "->" <InjectAlways> "->" <RemoveGuards>
```

Composes
[Human Factors](https://banes-lab.com/records/algo/human-factors.md), [Resource Core](https://banes-lab.com/records/algo/resource-core.md)

Forces
optional (user-orientation)

Grounds
none

Before

```typescript
class FooService {
constructor(private readonly audit?: AuditSink) {}

create(foo: Foo) {
this.audit?.write({ type: "foo.created", foo });
return fooStore.save(foo);
}
}
```

After

```typescript
class FooService {
constructor(private readonly audit: AuditSink) {}

create(foo: Foo) {
this.audit.write({ type: "foo.created", foo });
return fooStore.save(foo);
}
}
```

### Now Over For-Now

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a temporary in-memory placeholder with the real durable implementation immediately, so the stopgap never ossifies.

Invariant
State that must survive restarts is persisted through the real store, not a transient map.

Flow

```text
TemporaryStub → IdentifyDurabilityNeed → WireRealStore → DeleteStub
```

Productions

```bnf
NoForNow ::= <TemporaryStub> "->" <IdentifyDurabilityNeed> "->" <WireRealStore> "->" <DeleteStub>
```

Composes
[Resource Core](https://banes-lab.com/records/algo/resource-core.md), [Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md)

Forces
for_now (deferring)

Grounds
none

Before

```typescript
class FooRepository {
private readonly data = new Map<string, Foo>();
save(foo: Foo) { this.data.set(foo.id, foo); }
}
```

After

```typescript
class FooRepository {
constructor(private readonly db: Database) {}

save(foo: Foo) {
return this.db.execute("insert into foos(id, value) values (?, ?)", foo.id, foo);
}
}
```

### Observed Execution Over Unobserved

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Wrap an unobserved effect in structured telemetry so every execution emits a learnable signal on success and failure.

Invariant
Every significant effect opens and closes a span carrying its outcome; no path executes blind.

Flow

```text
BlindEffect → OpenSpan → ExecuteWithinSpan → RecordOutcome
```

Productions

```bnf
NoUnobserved ::= <BlindEffect> "->" <OpenSpan> "->" <ExecuteWithinSpan> "->" <RecordOutcome>
```

Composes
[Observability](https://banes-lab.com/records/algo/observability.md), [Execution Core](https://banes-lab.com/records/algo/execution-core.md)

Forces
unobserved-execution (missed-learning)

Grounds
none

Before

```typescript
function publishFoo(foo: Foo) {
sendFoo(foo);
}
```

After

```typescript
async function publishFoo(foo: Foo, telemetry: Telemetry) {
const span = telemetry.startSpan("foo.publish", { fooId: foo.id });
try {
await sendFoo(foo);
span.end({ status: "ok" });
} catch (error) {
span.end({ status: "error", error });
throw error;
}
}
```

### Compression Over Repetition

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Extract a repeated pattern into one parameterized form, so the behavior lives once and duplication cannot drift.

Invariant
A behavior expressed more than once is factored to a single definition parameterized over its variation.

Flow

```text
DuplicatedPattern → IdentifyVariation → ExtractParameterized → RedirectCallsites
```

Productions

```bnf
NoUncompressed ::= <DuplicatedPattern> "->" <IdentifyVariation> "->" <ExtractParameterized> "->" <RedirectCallsites>
```

Composes
[Structural Core](https://banes-lab.com/records/algo/structural-core.md), [Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md)

Forces
pattern-without-compression (inefficiency)

Grounds
none

Before

```typescript
function validateFoo(foo: Foo) {
if (!foo.name) throw new Error("foo.name required");
if (foo.name.length > 40) throw new Error("foo.name too long");
}
function validateBar(bar: Bar) {
if (!bar.name) throw new Error("bar.name required");
if (bar.name.length > 40) throw new Error("bar.name too long");
}
```

After

```typescript
function requiredName(value: { name: string }, kind: string) {
if (!value.name) throw new Error(`${kind}.name required`);
if (value.name.length > 40) throw new Error(`${kind}.name too long`);
}

const validateFoo = (foo: Foo) => requiredName(foo, "foo");
const validateBar = (bar: Bar) => requiredName(bar, "bar");
```

### Approved Evolution Over Unapproved

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Gate a structural dependency behind a recorded architecture decision, so evolution proceeds only through approved boundaries.

Invariant
Every cross-boundary dependency traces to an approved decision record naming the allowed gateway.

Flow

```text
UnapprovedDependency → RaiseDecision → RecordApproval → WireApprovedGateway
```

Productions

```bnf
NoUnapproved ::= <UnapprovedDependency> "->" <RaiseDecision> "->" <RecordApproval> "->" <WireApprovedGateway>
```

Composes
[Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md), [Human Factors](https://banes-lab.com/records/algo/human-factors.md)

Forces
evolution-without-approval (architectural-drift)

Grounds
none

Before

```typescript
class FooService {

private readonly barDb = connectDirectlyToBarDatabase();
}
```

After

```typescript
type ArchitectureDecision = {
id: "ADR-0042";
status: "approved";
owner: "foo-platform";
allowedDependency: "BarGateway";
};

const decision: ArchitectureDecision = approvedDecision("ADR-0042");
class FooService {
constructor(private readonly bars: BarGateway, readonly adr = decision.id) {}
}
```

### Enforced Feedback Over Ignored

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Turn a logged-and-ignored warning into an enforced result, so negative feedback changes control flow instead of scrolling past.

Invariant
A detected invalid condition returns a typed failure; it is never merely logged and continued.

Flow

```text
WarnAndContinue → ModelFailureResult → ReturnTypedError → HaltHappyPath
```

Productions

```bnf
NoIgnoredFeedback ::= <WarnAndContinue> "->" <ModelFailureResult> "->" <ReturnTypedError> "->" <HaltHappyPath>
```

Composes
[Human Factors](https://banes-lab.com/records/algo/human-factors.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
feedback-ignored (stagnation)

Grounds
none

Before

```typescript
function ingestFoo(foo: Foo) {
if (foo.score < 0) console.warn("bad foo score", foo.score);
return fooStore.save(foo);
}
```

After

```typescript
function ingestFoo(foo: Foo) {
if (foo.score < 0) {
return { ok: false, error: { code: "INVALID_SCORE", value: foo.score } } as const;
}
fooStore.save(foo);
return { ok: true } as const;
}
```

### Single Owner Over Shared Ownership

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Give one service authority over a piece of state and propagate to others by event, removing multi-writer ambiguity.

Invariant
Exactly one service mutates a given entity; peers react to its events rather than co-writing it.

Flow

```text
MultiWriter → AssignOwner → EmitEvent → ProjectDownstream
```

Productions

```bnf
NoSharedOwnership ::= <MultiWriter> "->" <AssignOwner> "->" <EmitEvent> "->" <ProjectDownstream>
```

Composes
[Resource Core](https://banes-lab.com/records/algo/resource-core.md), [Execution Core](https://banes-lab.com/records/algo/execution-core.md)

Forces
shared-ownership (ambiguity)

Grounds
none

Before

```typescript
async function renameFoo(id: FooId, name: string) {
await fooService.rename(id, name);
await barService.patchFooName(id, name);
}
```

After

```typescript
async function renameFoo(id: FooId, name: string) {
await fooService.rename(id, name);
}

fooEvents.on("FooRenamed", event => {
barProjection.apply(event);
});
```

### Bounded Lifetime Over Unbounded

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace an unbounded cache with a capacity-bounded structure that evicts and clears, so memory release is deterministic.

Invariant
Every retained collection has an explicit bound and an eviction policy; growth cannot be unlimited.

Flow

```text
UnboundedStore → SetCapacity → AddEviction → ExposeClear
```

Productions

```bnf
NoUnbounded ::= <UnboundedStore> "->" <SetCapacity> "->" <AddEviction> "->" <ExposeClear>
```

Composes
[Resource Core](https://banes-lab.com/records/algo/resource-core.md)

Forces
unbounded-lifetime (leaks)

Grounds
none

Before

```typescript
const fooCache = new Map<string, Foo>();

function rememberFoo(foo: Foo) {
fooCache.set(foo.id, foo);
}
```

After

```typescript
class FooCache {
constructor(private readonly maxEntries: number) {}
private readonly values = new Map<string, Foo>();

set(foo: Foo) {
if (this.values.size >= this.maxEntries) {
const oldest = this.values.keys().next().value;
if (oldest !== undefined) this.values.delete(oldest);
}
this.values.set(foo.id, foo);
}

clear() { this.values.clear(); }
}
```

### Enforced Symmetry Over Asymmetric Lifecycle

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Pair every acquire with a guaranteed release via try/finally, so a fault mid-use cannot leak the resource.

Invariant
Acquisition and release are structurally symmetric; release runs on every exit path.

Flow

```text
UnbalancedAcquire → WrapTryFinally → ReleaseInFinally → GuaranteedCleanup
```

Productions

```bnf
NoAsymmetric ::= <UnbalancedAcquire> "->" <WrapTryFinally> "->" <ReleaseInFinally> "->" <GuaranteedCleanup>
```

Composes
[Resource Core](https://banes-lab.com/records/algo/resource-core.md)

Forces
asymmetric-lifecycle (resource-leaks)

Grounds
none

Before

```typescript
async function readFoo() {
const handle = await openFoo();
const foo = await handle.read();
await handle.close();
return foo;
}
```

After

```typescript
async function readFoo() {
const handle = await openFoo();
try {
return await handle.read();
} finally {
await handle.close();
}
}
```

### Explicit Retention Over Implicit

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace an anonymous listener push with an explicit retention token that names its owner and exposes release.

Invariant
Every retained reference is held through an ownership token that can be observed and released.

Flow

```text
AnonymousRetention → MintToken → NameOwner → ExposeRelease
```

Productions

```bnf
NoImplicitRetention ::= <AnonymousRetention> "->" <MintToken> "->" <NameOwner> "->" <ExposeRelease>
```

Composes
[Resource Core](https://banes-lab.com/records/algo/resource-core.md)

Forces
implicit-retention (hidden-leaks)

Grounds
none

Before

```typescript
const listeners: Array<() => void> = [];

function watchFoo(foo: Foo) {
listeners.push(() => console.log(foo.id));
}
```

After

```typescript
type Retention = { owner: string; release(): void };

function retainFoo(foo: Foo, owner: string): Retention {
const token = fooRetentions.add({ foo, owner });
return {
owner,
release: () => fooRetentions.delete(token),
};
}
```

### Structural Release Over Discipline

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace manual release calls with a language disposal scope, so cleanup is enforced structurally, not by the developer's memory.

Invariant
Resource cleanup is bound to scope exit by the language, not to a manually written release call.

Flow

```text
ManualRelease → ImplementDisposable → UseScopedBinding → AutomaticCleanup
```

Productions

```bnf
NoDisciplineRelease ::= <ManualRelease> "->" <ImplementDisposable> "->" <UseScopedBinding> "->" <AutomaticCleanup>
```

Composes
[Resource Core](https://banes-lab.com/records/algo/resource-core.md), [Enforcement Core](https://banes-lab.com/records/algo/enforcement-core.md)

Forces
discipline-release (human-error)

Grounds
none

Before

```typescript
async function useFoo() {
const foo = await acquireFoo();
await processFoo(foo);
await foo.release();
}
```

After

```typescript
class FooLease implements Disposable {
[Symbol.dispose]() { releaseFoo(this); }
}

function useFoo() {
using foo = acquireFooLease();
processFoo(foo);
}
```

### Immutable Data Over Mutable State

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace in-place mutation with a pure transform returning new data, so state transitions are reproducible.

Invariant
Data is readonly; a change produces a new value rather than mutating the existing one.

Flow

```text
InPlaceMutation → MarkReadonly → ReturnNewValue → ReproducibilityGained
```

Productions

```bnf
NoMutable ::= <InPlaceMutation> "->" <MarkReadonly> "->" <ReturnNewValue> "->" <ReproducibilityGained>
```

Composes
[Computation Core](https://banes-lab.com/records/algo/computation-core.md)

Forces
mutable-state (unpredictability)

Grounds
none

Before

```typescript
type Foo = { name: string; tags: string[] };

function addTag(foo: Foo, tag: string) {
foo.tags.push(tag);
return foo;
}
```

After

```typescript
type Foo = Readonly<{ name: string; tags: readonly string[] }>;

function addTag(foo: Foo, tag: string): Foo {
return { ...foo, tags: [...foo.tags, tag] };
}
```

### Errors As Language Over Silent Errors

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a null-on-failure return with a typed result union, so failure is machine-processable rather than swallowed.

Invariant
A fallible operation returns a discriminated ok/error result; failure carries a typed code.

Flow

```text
NullOnFailure → DefineResultUnion → ReturnTypedError → ForceHandling
```

Productions

```bnf
NoSilent ::= <NullOnFailure> "->" <DefineResultUnion> "->" <ReturnTypedError> "->" <ForceHandling>
```

Composes
[Computation Core](https://banes-lab.com/records/algo/computation-core.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
silent-errors (unknown-failure)

Grounds
none

Before

```typescript
function parseFoo(raw: string): Foo | null {
try {
return JSON.parse(raw) as Foo;
} catch {
return null;
}
}
```

After

```typescript
type ParseFooResult =
| { ok: true; value: Foo }
| { ok: false; error: { code: "INVALID_JSON" | "INVALID_FOO"; detail: string } };

function parseFoo(raw: string): ParseFooResult {
try {
const value = JSON.parse(raw);
return isFoo(value)
? { ok: true, value }
: { ok: false, error: { code: "INVALID_FOO", detail: "schema mismatch" } };
} catch (error) {
return { ok: false, error: { code: "INVALID_JSON", detail: String(error) } };
}
}
```

### Explicit Invalidity Over Hidden

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Model invalid state as an explicit variant rather than coercing to a plausible default that hides uncertainty.

Invariant
Validity is a represented state; invalid inputs map to an invalid variant, never a silent valid default.

Flow

```text
CoercedDefault → AddInvalidVariant → MapInvalidInputs → HonestUncertainty
```

Productions

```bnf
NoHiddenInvalidity ::= <CoercedDefault> "->" <AddInvalidVariant> "->" <MapInvalidInputs> "->" <HonestUncertainty>
```

Composes
[Computation Core](https://banes-lab.com/records/algo/computation-core.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
hidden-invalidity (false-consistency)

Grounds
none

Before

```typescript
type FooState = { count: number };

function readFooCount(raw: unknown): FooState {
return { count: typeof raw === "number" ? raw : 0 };

}
```

After

```typescript
type FooState =
| { status: "valid"; count: number }
| { status: "invalid"; reason: "NOT_A_NUMBER" };

function readFooCount(raw: unknown): FooState {
return typeof raw === "number"
? { status: "valid", count: raw }
: { status: "invalid", reason: "NOT_A_NUMBER" };
}
```

### Event Emission Over Parent Callbacks

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a parent-supplied callback with an emitted event, decoupling the producer from its consumers.

Invariant
A component announces facts via events; it holds no reference to who reacts.

Flow

```text
ParentCallback → DefineEvent → EmitFact → SubscribeExternally
```

Productions

```bnf
NoCallbacks ::= <ParentCallback> "->" <DefineEvent> "->" <EmitFact> "->" <SubscribeExternally>
```

Composes
[Execution Core](https://banes-lab.com/records/algo/execution-core.md), [Coupling Control](https://banes-lab.com/records/algo/coupling-control.md)

Forces
parent-callbacks (tight-coupling)

Grounds
none

Before

```typescript
class FooEditor {
constructor(private readonly onSaved: (foo: Foo) => void) {}

save(foo: Foo) {
fooStore.save(foo);
this.onSaved(foo);
}
}
```

After

```typescript
class FooEditor {
constructor(private readonly events: EventSink) {}

save(foo: Foo) {
fooStore.save(foo);
this.events.emit({ type: "FooSaved", fooId: foo.id });
}
}

fooEvents.on("FooSaved", event => refreshFooView(event.fooId));
```

### Monotonic Growth Over Retraction

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace destructive deletion with an append-only removal event, so history is monotonic and projectable.

Invariant
State changes append events; nothing is deleted in place, and current state is a projection.

Flow

```text
DestructiveDelete → DefineEventLog → AppendRemoval → ProjectCurrent
```

Productions

```bnf
NoRetraction ::= <DestructiveDelete> "->" <DefineEventLog> "->" <AppendRemoval> "->" <ProjectCurrent>
```

Composes
[Execution Core](https://banes-lab.com/records/algo/execution-core.md), [Causality Core](https://banes-lab.com/records/algo/causality-core.md)

Forces
retraction (complexity)

Grounds
none

Before

```typescript
type FooIndex = Map<FooId, Foo>;

function deleteFoo(index: FooIndex, id: FooId) {
index.delete(id);
}
```

After

```typescript
type FooEvent =
| { seq: number; type: "FooAdded"; foo: Foo }
| { seq: number; type: "FooRemoved"; fooId: FooId };

function removeFoo(log: FooEvent[], id: FooId) {
log.push({ seq: log.length + 1, type: "FooRemoved", fooId: id });
}

const currentFoos = projectFoos(log);
```

### Semantic Addressing Over Location Addressing

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace positional path addressing with a semantic identity reference, so references survive structural change.

Invariant
An entity is referenced by stable identity, never by its position within a container.

Flow

```text
PositionalRef → AssignIdentity → ReferenceById → ResolveByLookup
```

Productions

```bnf
NoLocation ::= <PositionalRef> "->" <AssignIdentity> "->" <ReferenceById> "->" <ResolveByLookup>
```

Composes
[Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
location-addressing (brittleness)

Grounds
none

Before

```typescript
const foo = document.sections[2].items[4];
const reference = "sections[2].items[4]";
```

After

```typescript
type FooRef = { kind: "foo"; id: FooId };

const reference: FooRef = { kind: "foo", id: fooId("foo_primary") };
const foo = document.foosById.get(reference.id);
```

### Ordinal Time Over Timestamps

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace wall-clock ordering with an ordinal sequence, so event order is logical and clock-independent.

Invariant
Ordering derives from a monotonic ordinal, not a physical timestamp subject to skew.

Flow

```text
WallClockOrder → AssignOrdinal → AppendWithOrdinal → SortByOrdinal
```

Productions

```bnf
NoTimestamps ::= <WallClockOrder> "->" <AssignOrdinal> "->" <AppendWithOrdinal> "->" <SortByOrdinal>
```

Composes
[Causality Core](https://banes-lab.com/records/algo/causality-core.md), [Execution Core](https://banes-lab.com/records/algo/execution-core.md)

Forces
timestamp-ordering (wall-clock-dependency)

Grounds
none

Before

```typescript
type FooEvent = { at: number; value: string };

const events = received.map(value => ({ at: Date.now(), value }));
events.sort((a, b) => a.at - b.at);
```

After

```typescript
type FooEvent = { ordinal: bigint; value: string };

function appendFoo(value: string): FooEvent {
return fooLog.append(nextOrdinal(), value);
}

const events = fooLog.read().sort((a, b) => Number(a.ordinal - b.ordinal));
```

### Homoiconicity Over Separation

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Fuse behavior and its separate metadata into one homoiconic data structure that is both the rule and its description.

Invariant
A rule is represented as data that is directly evaluated; no parallel metadata can drift from it.

Flow

```text
CodeAndMetadata → DefineExprData → EvaluateData → SingleSource
```

Productions

```bnf
NoSeparation ::= <CodeAndMetadata> "->" <DefineExprData> "->" <EvaluateData> "->" <SingleSource>
```

Composes
[Structural Core](https://banes-lab.com/records/algo/structural-core.md), [Declarative Core](https://banes-lab.com/records/algo/declarative-core.md)

Forces
separation (duplication)

Grounds
none

Before

```typescript
function calculateFoo(foo: Foo) {
return foo.value * 2;
}

const fooRuleMetadata = {
operation: "multiply",
operand: 2,
};
```

After

```typescript
type Expr =
| { op: "value"; key: keyof Foo }
| { op: "const"; value: number }
| { op: "multiply"; left: Expr; right: Expr };

const fooRule: Expr = {
op: "multiply",
left: { op: "value", key: "value" },
right: { op: "const", value: 2 },
};

const result = evaluate(fooRule, foo);
```

### Bounded Complexity Over Unlimited

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Constrain an open-ended rule surface to a bounded grammar with depth and fan-out limits, capping cognitive load.

Invariant
A rule structure has enforced maximum depth and breadth; unbounded nesting is rejected.

Flow

```text
OpenEndedRule → DefineBoundedGrammar → ValidateDepth → ValidateFanOut
```

Productions

```bnf
NoUnlimited ::= <OpenEndedRule> "->" <DefineBoundedGrammar> "->" <ValidateDepth> "->" <ValidateFanOut>
```

Composes
[Human Factors](https://banes-lab.com/records/algo/human-factors.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
unlimited-complexity (cognitive-overload)

Grounds
none

Before

```typescript
type FooRule = {
run(context: unknown): unknown;
};

function execute(rule: FooRule) {
return rule.run(globalThis);
}
```

After

```typescript
type FooRule =
| { op: "equals"; field: "name" | "kind"; value: string }
| { op: "all"; rules: readonly FooRule[] };

function validateRule(rule: FooRule, depth = 0): void {
if (depth > 5) throw new Error("FooRule depth exceeds 5");
if (rule.op === "all") {
if (rule.rules.length > 10) throw new Error("FooRule fan-out exceeds 10");
rule.rules.forEach(child => validateRule(child, depth + 1));
}
}
```

### Computed Health Over Metric Health

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace threshold-on-metrics health with a symbolic diagnosis that names the causes of an unready state.

Invariant
Health is a computed state naming concrete blocking causes, not a boolean over numeric thresholds.

Flow

```text
MetricThreshold → EnumerateCauses → ComputeState → NameBlockers
```

Productions

```bnf
NoMetrics ::= <MetricThreshold> "->" <EnumerateCauses> "->" <ComputeState> "->" <NameBlockers>
```

Composes
[Observability](https://banes-lab.com/records/algo/observability.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
metric-health (symptom-tracking)

Grounds
none

Before

```typescript
function fooHealth(metrics: { errorRate: number; latencyMs: number }) {
return metrics.errorRate < 0.01 && metrics.latencyMs < 200 ? "healthy" : "unhealthy";
}
```

After

```typescript
type FooHealth =
| { state: "ready" }
| { state: "blocked"; causes: readonly ("STORE_UNREACHABLE" | "SCHEMA_MISMATCH")[] };

function fooHealth(status: { storeReachable: boolean; schemaCompatible: boolean }): FooHealth {
const causes = [
...(!status.storeReachable ? ["STORE_UNREACHABLE" as const] : []),
...(!status.schemaCompatible ? ["SCHEMA_MISMATCH" as const] : []),
];
return causes.length ? { state: "blocked", causes } : { state: "ready" };
}
```

### Secret Store Over Hardcoded Secrets

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace an inline secret with a resolved read from a secret store that fails fast when the secret is absent.

Invariant
No secret literal appears in source; secrets are read at runtime from a store and validated present.

Flow

```text
InlineSecret → MoveToStore → ResolveAtRuntime → FailIfMissing
```

Productions

```bnf
NoHardcodedSecrets ::= <InlineSecret> "->" <MoveToStore> "->" <ResolveAtRuntime> "->" <FailIfMissing>
```

Composes
[Security Core](https://banes-lab.com/records/algo/security-core.md)

Forces
hardcoded-secrets (exposure)

Principle
[Secrets Management](https://banes-lab.com/records/arch/secrets-management.md)

Grounds
none

Before

```typescript
const fooClient = new FooClient({
apiKey: "foo_live_abc123",
});
```

After

```typescript
async function makeFooClient(secrets: SecretStore) {
const apiKey = await secrets.read("services/foo/api-key");
if (!apiKey) throw new Error("missing services/foo/api-key");
return new FooClient({ apiKey });
}
```

### Boundary Validation Over Unvalidated Input

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Parse and validate untrusted input at the boundary into a typed shape, failing fast on malformed data.

Invariant
Input crosses the boundary only after schema validation; no raw external value reaches the core.

Flow

```text
RawInput → ParseAtBoundary → ValidateSchema → PassTypedValue
```

Productions

```bnf
NoUnvalidatedInput ::= <RawInput> "->" <ParseAtBoundary> "->" <ValidateSchema> "->" <PassTypedValue>
```

Composes
[Security Core](https://banes-lab.com/records/algo/security-core.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
unvalidated-input (injection)

Principle
[Input Validation](https://banes-lab.com/records/arch/input-validation.md)

Grounds
none

Before

```typescript
async function createFoo(request: Request) {
const body = await request.json() as any;
return fooDb.query(`insert into foo(name) values ('${body.name}')`);
}
```

After

```typescript
type CreateFoo = { name: string };

function parseCreateFoo(value: unknown): CreateFoo {
if (!value || typeof value !== "object") throw new Error("body must be an object");
const name = (value as Record<string, unknown>).name;
if (typeof name !== "string" || name.length < 1 || name.length > 40) {
throw new Error("name must be 1..40 characters");
}
return { name };
}

async function createFoo(request: Request) {
const input = parseCreateFoo(await request.json());
return fooDb.query("insert into foo(name) values (?)", input.name);
}
```

### Least Privilege Over Broad Privilege

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Narrow a broad capability to the minimal typed interface a task needs, shrinking the blast radius.

Invariant
A component receives only the narrow capability its task requires, never an ambient broad authority.

Flow

```text
BroadCapability → DefineNarrowInterface → InjectMinimal → DenyRest
```

Productions

```bnf
NoBroadPrivilege ::= <BroadCapability> "->" <DefineNarrowInterface> "->" <InjectMinimal> "->" <DenyRest>
```

Composes
[Security Core](https://banes-lab.com/records/algo/security-core.md), [Coupling Control](https://banes-lab.com/records/algo/coupling-control.md)

Forces
broad-privilege (blast-radius)

Principle
[Least Privilege](https://banes-lab.com/records/arch/least-privilege.md)

Grounds
none

Before

```typescript
class FooJob {
constructor(private readonly admin: AdminDatabase) {}

run(foo: Foo) {
return this.admin.execute(`delete from bar; insert into foo values (?)`, foo);
}
}
```

After

```typescript
interface FooWriter {
insert(foo: Foo): Promise<void>;
}

class FooJob {
constructor(private readonly foos: FooWriter) {}

run(foo: Foo) {
return this.foos.insert(foo);
}
}
```

### Config Externalization Over Env Fallback

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace env-var-or-default reads with a validated config loaded at boot that fails fast on missing values.

Invariant
Configuration is parsed and validated once at startup; a missing required var halts boot.

Flow

```text
EnvOrDefault → DefineConfigSchema → LoadAtBoot → FailIfIncomplete
```

Productions

```bnf
NoEnvFallback ::= <EnvOrDefault> "->" <DefineConfigSchema> "->" <LoadAtBoot> "->" <FailIfIncomplete>
```

Composes
[Security Core](https://banes-lab.com/records/algo/security-core.md), [Resource Core](https://banes-lab.com/records/algo/resource-core.md)

Forces
env-fallback-default (silent-misconfig)

Grounds
none

Before

```typescript
const fooUrl = process.env.FOO_URL || "http://localhost:3000";
const retryCount = Number(process.env.FOO_RETRIES || "3");
```

After

```typescript
type AppConfig = Readonly<{ fooUrl: URL; retryCount: number }>;

function loadConfig(env: NodeJS.ProcessEnv): AppConfig {
if (!env.FOO_URL) throw new Error("FOO_URL is required");
if (!env.FOO_RETRIES) throw new Error("FOO_RETRIES is required");
const retryCount = Number(env.FOO_RETRIES);
if (!Number.isInteger(retryCount) || retryCount < 0) throw new Error("invalid FOO_RETRIES");
return Object.freeze({ fooUrl: new URL(env.FOO_URL), retryCount });
}

const config = loadConfig(process.env);
```

### Profile-First Over Unmeasured Optimization

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Gate any optimization behind a measured profile, so effort is evidence-driven rather than speculative.

Invariant
A performance change is justified by a before/after measurement of the actual bottleneck.

Flow

```text
SuspectedHotspot → Profile → IdentifyBottleneck → OptimizeMeasured → Verify
```

Productions

```bnf
NoUnmeasuredOptimization ::= <SuspectedHotspot> "->" <Profile> "->" <IdentifyBottleneck> "->" <OptimizeMeasured> "->" <Verify>
```

Composes
[Performance Core](https://banes-lab.com/records/algo/performance-core.md)

Forces
unmeasured-optimization (guesswork)

Grounds
none

Before

```typescript
const fooCache = new Map<string, Foo>();

function getFoo(id: string) {
if (!fooCache.has(id)) fooCache.set(id, expensiveLookup(id));
return fooCache.get(id)!;
}
```

After

```typescript
const profile = profiler.measure("foo.batch", () => {
for (const id of fooIds) expensiveLookup(id);
});

if (profile.hotspot === "repeated-foo-lookup") {
const foos = fooStore.getMany(fooIds);
consume(foos);
}
```

### Rule As Code Over Convention

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a written convention with an automated gate, so the invariant is enforced by code not by memory.

Invariant
Every stated invariant has an executable check that fails the build on violation.

Flow

```text
WrittenConvention → EncodeCheck → WireGate → FailOnViolation
```

Productions

```bnf
NoConventionEnforcement ::= <WrittenConvention> "->" <EncodeCheck> "->" <WireGate> "->" <FailOnViolation>
```

Composes
[Enforcement Core](https://banes-lab.com/records/algo/enforcement-core.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
convention-only-enforcement (drift)

Grounds
none

Before

```typescript
import { sql } from "../infrastructure/database";

export function makeFoo() {
return sql("select * from foo");
}
```

After

```typescript
const architectureRule = forbidImports({
from: "src/domain/**",
to: "src/infrastructure/**",
});

for (const violation of architectureRule.scan(projectGraph)) {
throw new Error(`forbidden dependency: ${violation.from} → ${violation.to}`);
}
```

### Design By Contract Over Implicit Contract

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
State pre-conditions, post-conditions, and invariants explicitly, so a boundary's contract is checkable not assumed.

Invariant
A boundary declares and enforces its pre/post/invariant conditions; callers are not left to guess.

Flow

```text
ImplicitAssumption → StatePreconditions → StatePostconditions → EnforceInvariants
```

Productions

```bnf
NoImplicitContract ::= <ImplicitAssumption> "->" <StatePreconditions> "->" <StatePostconditions> "->" <EnforceInvariants>
```

Composes
[Contracts Core](https://banes-lab.com/records/algo/contracts-core.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
implicit-contract (silent-breakage)

Grounds
none

Before

```typescript
function divideFoo(total: number, count: number) {
return total / count;
}
```

After

```typescript
function divideFoo(total: number, count: number): number {
if (!Number.isFinite(total)) throw new Error("pre: total must be finite");
if (!Number.isInteger(count) || count <= 0) throw new Error("pre: count must be positive");

const result = total / count;

if (!Number.isFinite(result)) throw new Error("post: result must be finite");
return result;
}
```

### Versioned Evolution Over Breaking Change

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Introduce change behind a version so existing consumers keep a stable contract while new ones adopt the new shape.

Invariant
A contract change is additive or versioned; no in-place change breaks an existing consumer silently.

Flow

```text
InPlaceChange → IntroduceVersion → RunBothContracts → MigrateConsumers
```

Productions

```bnf
NoBreakingChange ::= <InPlaceChange> "->" <IntroduceVersion> "->" <RunBothContracts> "->" <MigrateConsumers>
```

Composes
[Contracts Core](https://banes-lab.com/records/algo/contracts-core.md), [Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md)

Forces
unversioned-breaking-change (consumer-breakage)

Principle
[Versioning](https://banes-lab.com/records/arch/versioning.md)

Grounds
none

Before

```typescript
app.get("/foo", () => ({ label: "Foo", tags: [] }));
```

After

```typescript
app.get("/v1/foo", () => ({ name: "Foo" }));
app.get("/v2/foo", () => ({ label: "Foo", tags: [] }));
```

### Schema-Validated Boundary Over Untyped

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Type and schema-validate every boundary crossing, so invalid state cannot enter the typed core.

Invariant
Data entering the system is validated against a schema; untyped values never propagate inward.

Flow

```text
UntypedBoundary → DefineSchema → ValidateOnEntry → PropagateTyped
```

Productions

```bnf
NoUntypedBoundary ::= <UntypedBoundary> "->" <DefineSchema> "->" <ValidateOnEntry> "->" <PropagateTyped>
```

Composes
[Contracts Core](https://banes-lab.com/records/algo/contracts-core.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
untyped-boundary (invalid-state)

Grounds
none

Before

```typescript
async function loadFoo(response: Response): Promise<Foo> {
return await response.json() as Foo;
}
```

After

```typescript
type Foo = Readonly<{ id: string; count: number }>;

function decodeFoo(value: unknown): Foo {
if (!value || typeof value !== "object") throw new Error("Foo must be an object");
const record = value as Record<string, unknown>;
if (typeof record.id !== "string") throw new Error("Foo.id must be a string");
if (!Number.isInteger(record.count)) throw new Error("Foo.count must be an integer");
return { id: record.id, count: record.count as number };
}

async function loadFoo(response: Response): Promise<Foo> {
return decodeFoo(await response.json());
}
```

### Atomic Boundary Over Partial Commit

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Wrap coupled writes in an all-or-nothing boundary, so a fault cannot leave state half-applied.

Invariant
Coupled state changes either all commit or all roll back; no partial application persists.

Flow

```text
CoupledWrites → OpenTransaction → ApplyAll → CommitOrRollback
```

Productions

```bnf
NoPartialCommit ::= <CoupledWrites> "->" <OpenTransaction> "->" <ApplyAll> "->" <CommitOrRollback>
```

Composes
[Atomic Boundary](https://banes-lab.com/records/algo/atomic-boundary.md), [Resource Core](https://banes-lab.com/records/algo/resource-core.md)

Forces
partial-commit (corruption)

Grounds
none

Before

```typescript
async function moveFoo(id: FooId, from: BarId, to: BarId) {
await barStore.removeFoo(from, id);
await barStore.addFoo(to, id);
}
```

After

```typescript
async function moveFoo(id: FooId, from: BarId, to: BarId) {
await database.transaction(async tx => {
const removed = await tx.bars.removeFoo(from, id);
if (!removed) throw new Error("Foo is not owned by source Bar");
await tx.bars.addFoo(to, id);
});
}
```

### Saga Compensation Over Distributed 2PC

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a cross-service two-phase commit with a saga of compensable steps, preserving service autonomy.

Invariant
Cross-service consistency is achieved by compensating actions, not a distributed lock across services.

Flow

```text
CrossServiceLock → DefineSteps → DefineCompensations → RunSaga
```

Productions

```bnf
NoDistributed2pc ::= <CrossServiceLock> "->" <DefineSteps> "->" <DefineCompensations> "->" <RunSaga>
```

Composes
[Execution Core](https://banes-lab.com/records/algo/execution-core.md), [Coupling Control](https://banes-lab.com/records/algo/coupling-control.md)

Forces
cross-service-2PC (coupling)

Grounds
none

Before

```typescript
async function createFooAndBar(foo: Foo, bar: Bar) {
const tx = await coordinator.begin();
await fooService.prepare(tx.id, foo);
await barService.prepare(tx.id, bar);
await coordinator.commit(tx.id);
}
```

After

```typescript
async function createFooAndBar(foo: Foo, bar: Bar) {
const fooId = await fooService.create(foo);
try {
await barService.create({ ...bar, fooId });
} catch (error) {
await fooService.cancel(fooId);
throw error;
}
}
```

### Async Events Over Synchronous Cross-Boundary

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace a synchronous call across an autonomy boundary with an asynchronous event, decoupling in time.

Invariant
Calls across autonomy boundaries are asynchronous; no boundary blocks on another's synchronous response.

Flow

```text
SyncCrossCall → DefineEvent → EmitAsync → ConsumeIndependently
```

Productions

```bnf
NoSyncCrossBoundary ::= <SyncCrossCall> "->" <DefineEvent> "->" <EmitAsync> "->" <ConsumeIndependently>
```

Composes
[Execution Core](https://banes-lab.com/records/algo/execution-core.md), [Coupling Control](https://banes-lab.com/records/algo/coupling-control.md)

Forces
synchronous-cross-autonomy-boundary (fragility)

Grounds
none

Before

```typescript
async function createFoo(foo: Foo) {
const bar = await barServiceHttp.get(foo.barId);
await bazServiceHttp.validate(foo, bar);
return fooStore.save(foo);
}
```

After

```typescript
async function createFoo(foo: Foo) {
await fooStore.transaction(async tx => {
await tx.foos.save(foo);
await tx.outbox.append({ type: "FooCreated", fooId: foo.id, barId: foo.barId });
});
}

fooEvents.on("FooCreated", event => bazProjection.process(event));
```

### Observable Signals Over Opaque Runtime

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Emit structured signals around runtime behavior, so operation is observable rather than blind.

Invariant
Runtime paths emit structured telemetry sufficient to reconstruct what happened.

Flow

```text
OpaqueRuntime → InstrumentSignals → EmitStructured → EnableReconstruction
```

Productions

```bnf
NoOpaqueRuntime ::= <OpaqueRuntime> "->" <InstrumentSignals> "->" <EmitStructured> "->" <EnableReconstruction>
```

Composes
[Observability](https://banes-lab.com/records/algo/observability.md), [Execution Core](https://banes-lab.com/records/algo/execution-core.md)

Forces
opaque-runtime (blind-operation)

Grounds
none

Before

```typescript
async function processFoo(foo: Foo) {
console.log("starting foo");
await fooStore.save(foo);
console.log("done");
}
```

After

```typescript
async function processFoo(foo: Foo, telemetry: Telemetry) {
return telemetry.trace("foo.process", { fooId: foo.id }, async span => {
const started = performance.now();
try {
await fooStore.save(foo);
telemetry.count("foo.processed", 1, { result: "ok" });
span.event("foo.saved", { durationMs: performance.now() - started });
} catch (error) {
telemetry.count("foo.processed", 1, { result: "error" });
span.fail(error);
throw error;
}
});
}
```

### Injected Dependency Over Hidden

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Surface a concealed dependency as a constructor parameter, inverting control and revealing coupling.

Invariant
Every dependency is injected and visible in the signature; none is reached for ambiently.

Flow

```text
HiddenDependency → LiftToParameter → InjectAtComposition → RevealCoupling
```

Productions

```bnf
NoHiddenDependency ::= <HiddenDependency> "->" <LiftToParameter> "->" <InjectAtComposition> "->" <RevealCoupling>
```

Composes
[Coupling Control](https://banes-lab.com/records/algo/coupling-control.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
hidden-dependency (concealed-coupling)

Grounds
none

Before

```typescript
import { globalFooStore } from "./globals";

class FooService {
save(foo: Foo) {
return globalFooStore.save(foo);
}
}
```

After

```typescript
interface FooStore {
save(foo: Foo): Promise<void>;
}

class FooService {
constructor(private readonly store: FooStore) {}

save(foo: Foo) {
return this.store.save(foo);
}
}
```

### Convention Discovery Over Hardcoded Wiring

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace enumerated wiring with convention-based discovery, so new components register without editing a central list.

Invariant
Components are discovered by convention at runtime; no central switch enumerates each one.

Flow

```text
HardcodedList → DefineConvention → DiscoverAtRuntime → SelfRegister
```

Productions

```bnf
NoHardcodedWiring ::= <HardcodedList> "->" <DefineConvention> "->" <DiscoverAtRuntime> "->" <SelfRegister>
```

Composes
[Extensibility Core](https://banes-lab.com/records/algo/extensibility-core.md), [Structural Core](https://banes-lab.com/records/algo/structural-core.md)

Forces
hardcoded-wiring (rigidity)

Grounds
none

Before

```typescript
import { FooHandler } from "./foo-handler";
import { BarHandler } from "./bar-handler";
import { BazHandler } from "./baz-handler";

const handlers = [new FooHandler(), new BarHandler(), new BazHandler()];
```

After

```typescript
interface HandlerModule {
kind: string;
create(): Handler;
}

const modules = await discover<HandlerModule>("./handlers/*.handler.js");
const handlers = new Map(modules.map(module => [module.kind, module.create()]));
```

### Declarative Config Over Imperative

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Replace imperative setup steps with declarative configuration describing the desired state.

Invariant
Configuration declares the target state; it is not a sequence of mutation calls.

Flow

```text
ImperativeSetup → DescribeDesiredState → ApplyDeclaratively → ConvergeToState
```

Productions

```bnf
NoImperativeConfig ::= <ImperativeSetup> "->" <DescribeDesiredState> "->" <ApplyDeclaratively> "->" <ConvergeToState>
```

Composes
[Declarative Core](https://banes-lab.com/records/algo/declarative-core.md), [Extensibility Core](https://banes-lab.com/records/algo/extensibility-core.md)

Forces
imperative-config (drift)

Grounds
none

Before

```typescript
const app = new FooApp();
app.enableCache();
app.setRetries(3);
if (process.env.DEBUG) app.enableDebug();
app.register(new BarPlugin());
```

After

```typescript
type FooConfig = Readonly<{
cache: { enabled: boolean };
retries: number;
debug: boolean;
plugins: readonly ["bar"];
}>;

const config: FooConfig = {
cache: { enabled: true },
retries: 3,
debug: false,
plugins: ["bar"],
};

const app = FooApp.fromConfig(validateFooConfig(config));
```

### Anti-Corruption Layer Over Cross-Context Leak

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Insert an anti-corruption layer at a context boundary, so a foreign model cannot corrupt the local one.

Invariant
A foreign model is translated at the boundary; its shape never leaks into the local bounded context.

Flow

```text
ForeignModelLeak → DefineTranslation → TranslateAtBoundary → ProtectLocalModel
```

Productions

```bnf
NoLeakyContext ::= <ForeignModelLeak> "->" <DefineTranslation> "->" <TranslateAtBoundary> "->" <ProtectLocalModel>
```

Composes
[Domain Modeling](https://banes-lab.com/records/algo/domain-modeling.md), [Coupling Control](https://banes-lab.com/records/algo/coupling-control.md)

Forces
cross-context-leak (model-corruption)

Principle
[Anti-Corruption Layer](https://banes-lab.com/records/arch/anti-corruption-layer.md)

Grounds
none

Before

```typescript
function priceBar(foo: FooDatabaseRow) {
return foo.status === "A" ? 10 : 0;
}
```

After

```typescript
type FooDatabaseRow = { id: string; status: "A" | "D" };
type BarEligibility = { fooId: string; eligible: boolean };

function toBarEligibility(row: FooDatabaseRow): BarEligibility {
return { fooId: row.id, eligible: row.status === "A" };
}

function priceBar(input: BarEligibility) {
return input.eligible ? 10 : 0;
}
```

### Injected Nondeterminism Over Hidden

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Inject clocks, randomness, and IO so the core is deterministic and testable, isolating nondeterminism at the edge.

Invariant
Sources of nondeterminism are injected; the core computes deterministically given its inputs.

Flow

```text
HiddenClockOrRandom → DefinePort → InjectSource → DeterministicCore
```

Productions

```bnf
NoHiddenNondeterminism ::= <HiddenClockOrRandom> "->" <DefinePort> "->" <InjectSource> "->" <DeterministicCore>
```

Composes
[Computation Core](https://banes-lab.com/records/algo/computation-core.md), [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)

Forces
hidden-nondeterminism (unreproducible)

Grounds
none

Before

```typescript
function makeFoo(name: string): Foo {
return {
id: crypto.randomUUID(),
name,
createdAt: new Date(),
};
}
```

After

```typescript
interface Clock { now(): Date; }
interface IdSource { nextFooId(): string; }

function makeFoo(name: string, clock: Clock, ids: IdSource): Foo {
return {
id: ids.nextFooId(),
name,
createdAt: clock.now(),
};
}
```

### Pattern By Fit Over Speculative Pattern

- Math type: [logic](https://banes-lab.com/records/reason/math-type-logic.md)
- Yields: boolean

Details

Intent
Introduce a pattern only when a present force demands it, avoiding accidental complexity from anticipated needs.

Invariant
Every abstraction traces to a current force; none exists solely for a hypothesized future.

Flow

```text
SpeculativeAbstraction → IdentifyPresentForces → MatchPatternToForce → RemoveUnforced
```

Productions

```bnf
NoSpeculativePattern ::= <SpeculativeAbstraction> "->" <IdentifyPresentForces> "->" <MatchPatternToForce> "->" <RemoveUnforced>
```

Composes
[Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md), [Design Patterns Core](https://banes-lab.com/records/algo/design-patterns-core.md)

Forces
speculative-pattern (accidental-complexity)

Grounds
none

Before

```typescript
interface FooFactoryStrategy {
create(builder: FooAbstractBuilder, provider: FooProvider): Foo;
}

class DefaultFooFactoryStrategy implements FooFactoryStrategy {
create(builder: FooAbstractBuilder, provider: FooProvider) {
return builder.withName(provider.getName()).build();
}
}
```

After

```typescript
function makeFoo(name: string): Foo {
return { name };
}
```

## Links to

- [Logic](https://banes-lab.com/records/reason/math-type-logic.md)
- [Structural Core](https://banes-lab.com/records/algo/structural-core.md)
- [Coupling Control](https://banes-lab.com/records/algo/coupling-control.md)
- [Evolution Principles](https://banes-lab.com/records/algo/evolution-principles.md)
- [Resource Core](https://banes-lab.com/records/algo/resource-core.md)
- [Execution Core](https://banes-lab.com/records/algo/execution-core.md)
- [Atomic Boundary](https://banes-lab.com/records/algo/atomic-boundary.md)
- [Human Factors](https://banes-lab.com/records/algo/human-factors.md)
- [Observability](https://banes-lab.com/records/algo/observability.md)
- [Correctness Core](https://banes-lab.com/records/algo/correctness-core.md)
- [Enforcement Core](https://banes-lab.com/records/algo/enforcement-core.md)
- [Computation Core](https://banes-lab.com/records/algo/computation-core.md)
- [Causality Core](https://banes-lab.com/records/algo/causality-core.md)
- [Declarative Core](https://banes-lab.com/records/algo/declarative-core.md)
- [Security Core](https://banes-lab.com/records/algo/security-core.md)
- [Secrets Management](https://banes-lab.com/records/arch/secrets-management.md)
- [Input Validation](https://banes-lab.com/records/arch/input-validation.md)
- [Least Privilege](https://banes-lab.com/records/arch/least-privilege.md)
- [Performance Core](https://banes-lab.com/records/algo/performance-core.md)
- [Contracts Core](https://banes-lab.com/records/algo/contracts-core.md)
- [Versioning](https://banes-lab.com/records/arch/versioning.md)
- [Extensibility Core](https://banes-lab.com/records/algo/extensibility-core.md)
- [Domain Modeling](https://banes-lab.com/records/algo/domain-modeling.md)
- [Anti-Corruption Layer](https://banes-lab.com/records/arch/anti-corruption-layer.md)
- [Design Patterns Core](https://banes-lab.com/records/algo/design-patterns-core.md)

## Linked from

- [Never and always](https://banes-lab.com/software-architecture/decay/never-and-always.md)
