Skip to main content

Anti-pattern catalog — overview

The Architectural Type System for Verum maintains a canonical catalog of architectural defects, each registered as a refinement-level predicate the compiler checks. This page indexes the catalog and explains its structure. Each anti-pattern has its deep entry in one of the four band-specific pages.

The catalog itself — the closed enumeration of canonical anti-patterns — is the canonical source. The website mirrors the catalog exactly; adding a new pattern is the only way to extend the surface, and the docs follow the catalog, never the other way round.

The catalog is enumerableverum audit --arch-discharges prints every entry with its current verdict for the project at hand. The catalog is also append-only: a future Verum version may add patterns; existing patterns are never renumbered or removed.

1. The four bands

The forty patterns split into four bands by what kind of architectural concern they address. The bands are documentary categories — they all share the same diagnostic infrastructure, the same RFC code format (ATS-V-AP-NNN), and the same audit pipeline.

BandRangeConcernPage
Capability / composition coreAP-001 .. AP-010Capability discipline, composition algebra, lifecycle ordering, foundation drift, register mixing, transaction / resource straddling, CVE-closure completenessclassical
Boundary / lifecycle / capability ontologyAP-011 .. AP-026Stratum admissibility, boundary invariants, wire encoding, authentication, deterministic-test discipline, linear / affine / relevant capability flavours, persistence and time-bound contracts, transitive lifecycle, declaration vs body drift, foundation-content alignmentontology
Modal-temporal architectural calculusAP-027 .. AP-032Temporal stability, counterfactual brittleness, refactoring adjunctions, universal-property uniqueness, evolution-trigger satisfiability, Yoneda observer-functor invariancemtac
CVE articulation-hygieneAP-033 .. AP-040Operationalises CVE-architecture primitives: retracted-citation use, hypothesis without maturation plan, interpretation in mature corpus, observer impersonation, boundless audit, implicit substrate, anchoring overextension, self-reference without operator+fixed-pointcve-ah

The classical and ontology bands together cover what the ATS-V specification calls static-architecture defects — violations the compiler can decide without simulating time or counterfactuals. The MTAC band handles the modal-temporal surface (per spec §20–§23): time as a non-linear lattice, counterfactuals as paired decision swaps, refactorings as adjunctions, observers as Yoneda functors. The CVE-AH band operationalises the cve-architecture spec's load-bearing concepts that the canonical 32-pattern release omitted: the three senses of E (§2.3.0), declared purpose for audit termination (§14.6), cognitive substrate disclosure (§1.5), formal anchoring boundary (§4.5), and the CVE-violator discipline of [I] / [H] / [✗] (§3.5).

2. The catalog at a glance

CodeNameBandTriggered by
AP-001CapabilityEscalationcorebody uses capability not declared in requires
AP-002CapabilityLeakcorelinear / affine capability passed beyond its declared scope
AP-003DependencyCyclecorecomposes_with graph contains a cycle
AP-004TierMixingcoretier-N cog calls into tier-M without a bridge
AP-005FoundationDriftcorecomposing cogs with incompatible foundations and no bridge
AP-006RegisterMixingcoreproof / discharge mixes incompatible MSFS registers
AP-007TxStraddlingcoretransaction lives across an await boundary without scope
AP-008ResourceStraddlingcorelinear resource (file handle, db connection) outlives its scope
AP-009LifecycleRegressioncorecitation chain regresses to a strictly-lower lifecycle rank
AP-010CveIncompletecorestrict-mode cog with at least one missing CVE-closure axis
AP-011AbsoluteBoundaryAttemptontologycog declares MsfsStratum::LAbs (AFN-T α violation)
AP-012InvariantViolationontologydeclared BoundaryInvariant is not preserved by the boundary's traffic
AP-013DanglingMessageTypeontologymessage type declared without a wire encoding
AP-014UnauthenticatedCrossingontologyNetwork boundary without BoundaryInvariant::AuthenticatedFirst
AP-015DeterministicViolationontologyDST / replay test depends on non-deterministic primitives
AP-016CapabilityDuplicationontologyLinear capability used twice (multiplicity violation)
AP-017OrphanCapabilityontologyRelevant capability declared but never exercised
AP-018MissingHandoffontologycomposition capability not listed in composes_with
AP-019FoundationDowngradeontologystrong foundation passed through a weaker one without bridge
AP-020TimeBoundLeakageontologyTimeBound capability outlives its declared TTL
AP-021PersistenceMismatchontologyPersist capability for an operation that is not actually durable
AP-022CapabilityLaunderingontologymulti-hop privilege escalation through unmarked boundary
AP-023FoundationForgeryontologydeclared foundation contradicts the cited axiom corpus
AP-024TransitiveLifecycleRegressionontologytransitive [T] → … → [H] citation chain
AP-025DeclarationDriftontologydeclared @arch_module(...) shape diverges from inferred shape
AP-026FoundationContentMismatchontologycode body uses constructs from a foreign foundation
AP-027TemporalInconsistencymtacinvariant fails to hold across two sampled time-points
AP-028CounterfactualBrittlenessmtacverdict is fragile under counterfactual decision swap
AP-029MissedAdjointmtacrefactoring claimed without its inverse adjoint pair
AP-030UniversalPropertyViolationmtacuniversal-property uniqueness claim with no witness
AP-031PhantomEvolutionmtacdeclared evolution path passes through an unsatisfiable trigger
AP-032YonedaInequivalentRefactormtacrefactor changes the observer-functor (Yoneda inequivalent)
AP-033RetractedCitationUsecve-ahciting a [✗] Retracted artefact (cve-architecture spec §3.5)
AP-034HypothesisWithoutMaturationPlancve-ah[H] Hypothesis without @plan(...) (cve-architecture spec §3.5)
AP-035InterpretationInMatureCorpuscve-ah[I] Interpretation in strict-mode / mature corpus (cve-architecture spec §3.4)
AP-036ObserverImpersonationcve-ahobserver role mismatches assertion register (cve-architecture spec §6.7 L6)
AP-037BoundlessAuditcve-ahstrict-mode audit against Shape with no declared Purpose (cve-architecture spec §14.6)
AP-038ImplicitSubstratecve-ahstrict [T] cog without declared CognitiveSubstrate (cve-architecture spec §1.5)
AP-039AnchoringOverextensioncve-ah[T] cog under non-CHL foundation without declared FormalAnchoring (cve-architecture spec §4.5)
AP-040SelfReferenceWithoutOperatorcve-ahself-referential Shape pattern (self ∈ composes_with / capability target) without declared SelfReferenceWitness (cve-architecture spec §16; closes architectural-revision invariant R4)

3. The anatomy of an anti-pattern

Each entry in the catalog is structured identically. The catalog is a refinement-type-level specification — every pattern is a predicate, every diagnostic is a counterexample.

┌─ AP-NNN — name ──────────────────────────────────────────────┐
│ │
│ Severity: error / warning / hint │
│ Band: core | ontology | mtac │
│ Phase: arch-check | post-arch | bundle │
│ Stable: yes (RFC-locked) │
│ │
│ Predicate: forall Shape s, DiagnosticContext ctx. │
│ P(s, ctx) → defect │
│ │
│ Diagnostic: [error template with span pointers] │
│ │
│ Remediation: [canonical fix recipe] │
│ │
│ Pin test: smallest synthetic Shape that reproduces │
│ │
└───────────────────────────────────────────────────────────────┘

Three properties are load-bearing:

  1. The RFC code is stable. AP-001 always means CapabilityEscalation, even if the prose explanation is rewritten. Tooling that consumes audit reports can rely on the code as a permanent identifier.
  2. The predicate is published. Every anti-pattern's predicate is part of the catalog's externally observable surface. There are no hidden patterns that fire without an entry in this table. The catalog's predicate is the canonical reference; the docs paraphrase it.
  3. The pin test exists. Every catalog entry has a regression-pin synthetic example. The audit gate would surface a false negative if the pattern stopped triggering on its pin — the pin protects the catalog against silent degradation.

4. Severity levels

Patterns trigger at one of three severity levels:

  • Error — the build fails. Most core and ontology patterns are errors when the cog is in strict mode. The compiler refuses to emit code.
  • Warning — the build proceeds but verum audit reports the pattern. Used for patterns that may have legitimate workarounds in soft mode (e.g., AP-001 CapabilityEscalation is a warning when strict = false, error in strict mode).
  • Hint — informational only; the pattern is a candidate, pending confirmation by additional context. Used for inference hints (e.g., "consider declaring this capability explicitly").

Severity is per-pattern × per-cog: many patterns escalate to error in strict: true and remain warnings in soft mode. The escalation is encoded in each check_* function's Severity selection. verum.toml allows project overrides via [ats_v.severity]:

[ats_v.severity]
ap_005_foundation_drift = "warning" # ← demote from error
ap_019_foundation_downgrade = "error" # ← always error

Some patterns cannot be demoted below "warning" — those that would compromise soundness if silenced (most ontology patterns that touch the trusted base, all MTAC patterns).

5. Phases

Patterns trigger in three phases of the build:

  • arch-check — during the architectural type-checking phase, cog-by-cog. Most core patterns fire here.
  • post-arch — after every cog has been arch-checked, walking the cross-cog graph. Transitive patterns (AP-024 TransitiveLifecycleRegression, AP-022 CapabilityLaundering) and corpus-level invariants fire here.
  • bundle — at audit time, when verum audit --bundle walks the entire project. MTAC patterns fire here, because they require the full project graph plus the temporal / counterfactual / observer samples as input (see DiagnosticContext::temporal_samples / counterfactual_pairs / yoneda_observer_diff).

A pattern's phase is fixed; the audit pipeline runs phases in order and aggregates verdicts.

6. Suppressions and exceptions

ATS-V provides a single, audit-visible suppression mechanism:

@arch_module(
requires: [...],
@suppress(AP_005_foundation_drift, "explicitly bridged via core.proof.bridges")
)
module my_app.cross_foundation_proof;

The @suppress attribute:

  • Names the specific RFC code (no wildcards).
  • Carries a mandatory rationale string. The rationale is preserved in the audit chronicle.
  • Does not hide the pattern from verum audit; the audit report shows suppressed patterns separately, with their rationale.

There is no global suppression flag. There is no #[allow(...)]. Architectural defects are always observable.

7. Catalog growth

The catalog is append-only:

  • New patterns may be added in any release. They take the next unused RFC code.
  • Existing patterns may have their prose rewritten or their diagnostic improved.
  • Existing patterns may be split into two more-precise patterns (the original code is preserved as a deprecated alias).
  • Existing patterns may be demoted in severity but never removed.
  • Existing patterns may be promoted from warning to error only in major releases, and only with a deprecation cycle.

This discipline gives downstream codebases a stable target. A build that passes verum audit --arch-discharges today will continue to pass under future versions, modulo strict opt-in patterns.

8. The audit gate

verum audit --arch-discharges runs the catalog and emits a structured JSON report:

{
"schema_version": 2,
"verum_version": "0.x.y",
"patterns": [
{
"code": "ATS-V-AP-001",
"name": "CapabilityEscalation",
"severity": "error",
"verdict": "ok",
"occurrences": []
},
{
"code": "ATS-V-AP-009",
"name": "LifecycleRegression",
"severity": "error",
"verdict": "violations",
"occurrences": [
{
"citing": "my_app.checkout",
"cited": "my_app.experimental.zk_proof",
"citing_lifecycle": "Theorem(\"v1.0\")",
"cited_lifecycle": "Hypothesis(Medium)",
"rank_diff": 4
}
]
}
],
"summary": {
"total_patterns": 32,
"ok": 31,
"violations": 1,
"suppressed": 0
}
}

The report is suitable for archival in audit chronicles. Schema version 2 is the current schema; older schema versions are preserved as adapters.

9. Default severity at a glance

A common question: "how many of the forty are errors by default?" The default is encoded in each check_* function; many patterns escalate when Shape.strict == true. The summary below is the strict-mode picture:

SeverityCountPatterns
Error24AP-001..AP-009 (core), AP-011, AP-012, AP-014, AP-015, AP-016, AP-018, AP-019, AP-022, AP-023, AP-024, AP-025, AP-027, AP-028, AP-029, AP-031
Warning6AP-010 (CveIncomplete in soft mode), AP-013, AP-017, AP-020, AP-021, AP-026
Hint2AP-030 (UniversalPropertyViolation candidate), AP-032 (YonedaInequivalentRefactor candidate)

A clean default-mode build emits zero warnings; a clean strict-mode build also has zero hints. Many codebases adopt strict mode incrementally per cog (via @arch_module(strict: true)).

10. Verum-side surface

The 40-pattern catalog is exposed on the Verum side as a first-class enum in core.architecture.anti_patterns:

public type AntiPatternCode is
| CapabilityEscalation // AP-001
| CapabilityLeak // AP-002
// ... 30 more variants
| YonedaInequivalentRefactor; // AP-032

public fn anti_pattern_code_str(c: AntiPatternCode) -> Text // "ATS-V-AP-NNN"
public fn anti_pattern_name(c: AntiPatternCode) -> Text // "PascalCase"
public fn anti_pattern_full_roster() -> List<AntiPatternCode> // all 32
public fn anti_pattern_roster_size_invariant() -> Bool // pin: == 32

Verum cogs may iterate anti_pattern_full_roster() to build runtime walks (e.g. an in-process audit cog that records which patterns its codebase has cleared). The roster size is pinned by the cross-side test in crates/verum_kernel/tests/k_arch_v_alignment.rs — adding a 33rd code requires updating both the kernel-side AntiPatternCode::full_list() and the Verum-side roster in the same change-set.

Companion types:

public type Severity is | Error | Warning | Hint;
public fn severity_tag(s: Severity) -> Text;

public type AntiPatternViolation is {
code: AntiPatternCode,
severity: Severity,
summary: Text,
human_message: Text,
auto_fix_suggestion: Maybe<Text>,
};

public type DiagnosticContext is {
cog_name: Text,
parent_module: Maybe<Text>,
};

AntiPatternViolation carries the dual-audience payload — both human-readable text and machine-readable RFC code — surfaced by the ATS-V phase as a structured compiler diagnostic.

11. Implementation status

Every code in the canonical 40-pattern roster has a corresponding check_* function on the kernel side. The mapping is:

AP codeCheck functionLives in
AP-001check_capability_escalationarch_anti_pattern.rs
AP-002check_capability_leakarch_anti_pattern.rs
AP-003check_dependency_cyclearch_anti_pattern.rs
AP-004check_tier_mixingarch_anti_pattern.rs
AP-005check_foundation_driftarch_anti_pattern.rs
AP-006check_register_mixingarch_anti_pattern.rs
AP-007check_tx_straddlingarch_anti_pattern.rs
AP-008check_resource_straddlingarch_anti_pattern.rs
AP-009check_lifecycle_regressionarch_anti_pattern.rs
AP-010check_cve_incompletearch_anti_pattern.rs
AP-011check_stratum_admissiblearch_anti_pattern.rs
AP-012check_invariant_violationarch_anti_pattern.rs
AP-013check_dangling_message_typearch_anti_pattern.rs
AP-014check_unauthenticated_crossingarch_anti_pattern.rs
AP-015check_deterministic_violationarch_anti_pattern.rs
AP-016check_capability_duplicationarch_anti_pattern.rs
AP-017check_orphan_capabilityarch_anti_pattern.rs
AP-018check_missing_handoffarch_anti_pattern.rs
AP-019check_foundation_downgradearch_anti_pattern.rs
AP-020check_time_bound_leakagearch_anti_pattern.rs
AP-021check_persistence_mismatcharch_anti_pattern.rs
AP-022check_capability_launderingarch_anti_pattern.rs
AP-023check_foundation_forgeryarch_anti_pattern.rs
AP-024check_transitive_lifecycle_regressionarch_anti_pattern.rs
AP-025check_declaration_driftarch_anti_pattern.rs
AP-026check_foundation_content_mismatcharch_anti_pattern.rs
AP-027check_temporal_inconsistencyarch_anti_pattern.rs
AP-028check_counterfactual_brittlenessarch_anti_pattern.rs
AP-029check_missed_adjointarch_anti_pattern.rs
AP-030check_universal_property_violationarch_anti_pattern.rs
AP-031check_phantom_evolutionarch_anti_pattern.rs
AP-032check_yoneda_inequivalent_refactorarch_anti_pattern.rs

All 32 functions return Option<AntiPatternViolation>None means the predicate holds (no violation), Some(v) carries the structured diagnostic. check_all_anti_patterns walks every function and aggregates violations. The cross-side pin test in crates/verum_kernel/tests/k_arch_v_alignment.rs::pin_all_thirty_two_codes_have_check_function asserts every entry in this table has a matching pub fn check_* in the source — adding a 33rd code requires updating both the enum and the table in lockstep.

12. Adversarial-closure axioms

Beyond the 32 declarative patterns, the Verum-side cog core.architecture.anti_patterns declares four kernel-discharge axioms that close known attack vectors against the declarative surface:

  • kernel_arch_capability_ontology_check (closes AT-1) — registry validation for Capability.Custom { tag, schema }.
  • kernel_arch_theorem_cve_required (closes AT-2) — Lifecycle.Theorem(...) requires CVE-closure regardless of strict.
  • kernel_arch_yoneda_canonical_roster_complete (closes AT-3) — Yoneda verdicts demand the full canonical 5-roster.
  • kernel_arch_consumes_format_check (closes AT-5) — consumes field format enforcement.

See adversarial threat modelling for full attack-vector analysis.

13. Cross-references