# Debt and leverage

> This section covers the consequence on each side of an inversion, which lets the rule survive the moment it is inconvenient.

Page: Architecture · Decay
Canonical: https://banes-lab.com/software-architecture/decay#debt-and-leverage

This section is stop 67 of 102 in the learning route. Previous: [03 - Never and always](https://banes-lab.com/software-architecture/decay/never-and-always.md). Next: [01 - From intent to predicate](https://banes-lab.com/software-architecture/coverage/an-architecture-is-its-predicate-set.md). It builds on [03 - Never and always](https://banes-lab.com/software-architecture/decay/never-and-always.md).

This section covers the consequence on each side of an inversion, which lets the rule survive the moment it is inconvenient. The consequences are derived by the two questions shown in [D1·a lender and replacement](https://banes-lab.com/software-architecture/decay#debt-and-leverage-panel-a), and they turn the pair into a finding a check can print, in the record typed in [D1·b an inversion record](https://banes-lab.com/software-architecture/decay#debt-and-leverage-panel-b).

### A lender and a purchase

Rules are justified with adjectives, and an adjective is re-argued every time the rule is inconvenient. A rule is defended as good practice, the defence convinces no reviewer under deadline, and the construct it refused is written because no reviewer could say who would pay for it. A rule whose reason is an adjective is re-argued because an adjective cannot be pointed at, while a rule whose reason names a lender ends the argument by naming who pays.

For this reason a consequence is a named lender or a named purchase, and a pair with both is already a finding. A rule is justified by who pays rather than by an adjective. In practice, the refused consequence is derived by asking whom the construct borrows from, whether the next reader, the developer who meets the failure later, or every future change that has to keep two paths alive. The required consequence is derived by asking what holds without attention once the replacement is in place. Both are named, so the rule can be pointed at when it is questioned, and the same two names become the message a check prints and the remediation it proposes.

To check this, take any rule you hold and name who pays when it is broken and what is bought when it is kept. A rule where either answer is an adjective has no consequence yet, and it will lose the next argument it is in. A consequence names a lender or a purchase and never a severity. How strictly a rule binds is a separate fact held beside it, so two rules with the same consequence can bind differently, and a consequence never argues for its own rule's rank.

### The lender

The same question derives the refused consequence every time, which is whom the construct borrows from. A shortcut borrows from the next reader. A [fallback pattern](https://banes-lab.com/records/algo/no-fallback.md) borrows from the developer, because it converts a loud failure into a quiet wrong answer that surfaces later and elsewhere. A [deprecation](https://banes-lab.com/records/algo/no-deprecation.md) borrows from every future change, because it keeps two paths alive so the choice can be put off.

A [second path](https://banes-lab.com/records/algo/no-dual-path.md) borrows from every reader, who now has to decide which one is real. Deferring borrows from the developer who will not remember. [Shared mutable state](https://banes-lab.com/records/algo/no-shared-ownership.md) borrows from the developer who has to find out which writer won, and [silent data corruption](https://banes-lab.com/records/arch/silent-data-corruption.md) from the developer who meets the failure it hid.

### The purchase

The required consequence names what the replacement buys, and the purchase is what makes the rule worth keeping. A [constraint](https://banes-lab.com/records/algo/no-shortcuts.md) is leverage because it holds without attention. [Fail fast](https://banes-lab.com/records/arch/fail-fast.md) is clarity, because the failure lands where its cause is. Explicit removal is coherence, because a removed path cannot be taken.

A single path is [determinism](https://banes-lab.com/records/arch/determinism.md). A single owner is [auditability](https://banes-lab.com/records/arch/auditability.md). A bounded lifetime is deterministic release. [An emitted event](https://banes-lab.com/records/algo/no-callbacks.md) is [loose coupling](https://banes-lab.com/records/arch/low-coupling.md), and [policy as code](https://banes-lab.com/records/algo/no-convention-enforcement.md) is an automated gate. Because each consequence is named this way, the same record serves the developer reading the rule and the check enforcing it, and the two never drift apart.

D1·a lender and replacement

```mermaid
flowchart TB
construct["A construct under review"]
lender{"Whom does it borrow from?"}
reader["the next reader"]
operator["the developer, later and elsewhere"]
change["every future change"]
nobody["no lender · it is not a debt"]
replacement["What stands in its place, and what does that buy?"]
rule["A rule · two constructs, two consequences"]
construct --> lender
lender --> reader --> replacement
lender --> operator --> replacement
lender --> change --> replacement
lender --> nobody
replacement --> rule
```

D1·b an inversion record

```typescript
export interface Inversion {
readonly refused: { readonly construct: Construct; readonly borrowsAgainst: Consequence };
readonly required: { readonly construct: Construct; readonly buys: Consequence };
}

export const inversionOf = (refused: Construct, required: Construct, debt: Consequence, leverage: Consequence): Inversion => ({
refused: { borrowsAgainst: debt, construct: refused },
required: { buys: leverage, construct: required },
});

export const asFinding = (rule: Inversion, at: Location): Finding => ({
at,
reported: rule.refused.construct,
remediation: rule.required.construct,
reason: rule.refused.borrowsAgainst,
});
```

## Links to

- [Fail-Fast Over Fallback](https://banes-lab.com/records/algo/no-fallback.md)
- [Explicit Removal Over Deprecation](https://banes-lab.com/records/algo/no-deprecation.md)
- [Single-Path Determinism Over Dual-Path](https://banes-lab.com/records/algo/no-dual-path.md)
- [Single Owner Over Shared Ownership](https://banes-lab.com/records/algo/no-shared-ownership.md)
- [Silent Data Corruption](https://banes-lab.com/records/arch/silent-data-corruption.md)
- [Constraints Over Shortcuts](https://banes-lab.com/records/algo/no-shortcuts.md)
- [Fail Fast](https://banes-lab.com/records/arch/fail-fast.md)
- [Determinism](https://banes-lab.com/records/arch/determinism.md)
- [Auditability](https://banes-lab.com/records/arch/auditability.md)
- [Event Emission Over Parent Callbacks](https://banes-lab.com/records/algo/no-callbacks.md)
- [Low Coupling](https://banes-lab.com/records/arch/low-coupling.md)
- [Rule As Code Over Convention](https://banes-lab.com/records/algo/no-convention-enforcement.md)

## Linked from

- [Fail at the boundary](https://banes-lab.com/disciplined-methodology/build/fail-at-the-boundary.md)
