# configuration/strings/canon.strings.ts

> 221 lines of code and 11 definitions.

Tree: Site tree
Language: typescript
Layer: product
Canonical: https://banes-lab.com/anatomy/tree#file-configuration-strings-canon-strings-ts
Source text: https://banes-lab.com/assets/sources/source.053d10b433a4891c9022500e099c7e9c6698b0d6d2832e232681f55ee34428a3.generated.txt

## Definitions

- `PRINCIPLE_SHAPE` (lexical_declaration, line 18)
- `KIND_SHAPE` (lexical_declaration, line 21)
- `CANON_DIAGRAM` (lexical_declaration, line 24)
- `RECORD_DIAGRAM` (lexical_declaration, line 27)
- `KIND_MINDMAP` (lexical_declaration, line 30)
- `KIND_DIAGRAM` (lexical_declaration, line 33)
- `LAYER_DIAGRAM` (lexical_declaration, line 36)
- `CANON_SECTION` (lexical_declaration, line 39)
- `KIND_SECTION` (lexical_declaration, line 116)
- `GROUPING_SECTION` (lexical_declaration, line 173)
- `CANON_SECTIONS` (lexical_declaration, line 232, exported)

## Source

```typescript
import { ALGO_FACE, KIND_FACE, LAYER_FACE } from "@govlab/constants";
import { CANON_SECTION_ICON, GROUPING_SECTION_ICON, KIND_SECTION_ICON } from "#configuration/icons/architecture.icons";
import { CANON_SECTION_ID, GROUPING_SECTION_ID, RECORD_KIND_SECTION_ID } from "#core/ids/architecture.ids";
import {
    KIND_SECTION_ID,
    LEXICON_TAB,
    MEMBERSHIP_SECTION_ID,
    RANGE_SECTION_ID,
    SCHEMA_TAB,
    TOPOLOGY_SECTION_ID,
} from "#core/ids/ontology.ids";
import { pagePath, tabLink } from "#assets/link.assets";
import { ONTOLOGY_PAGE } from "#core/ids/page.ids";
import type { Section } from "#types/document.types";
import { TYPESCRIPT_LANGUAGE } from "#configuration/constants/code.constants";
import { faceLink } from "#domain/converters/ontology.converter";

const PRINCIPLE_SHAPE =
    'export type Kind =\n    | "anti-pattern" | "metric" | "quality-attribute" | "principle" | "constraint"\n    | "capability" | "activity" | "pattern" | "mechanism" | "technique"\n    | "approach" | "model" | "artifact" | "style";\n\nexport interface Principle {\n    readonly id: string;\n    readonly name: string;\n    readonly type: Kind;\n    readonly category: string;\n    readonly scope: readonly string[];\n    readonly requires: readonly string[];\n    readonly reinforces: readonly string[];\n    readonly enables: readonly string[];\n    readonly conflictsWith: readonly string[];\n    readonly tensionsWith: readonly string[];\n    readonly violatedBy: string;\n    readonly detectedBy: string;\n    readonly measuredBy: string;\n    readonly refactoredBy: string;\n    readonly enforcedBy: string;\n    readonly severity: string;\n    readonly exemplar?: { readonly before: string; readonly after: string; readonly lang: string };\n}\n\nexport interface Issues {\n    readonly danglingEdges: readonly { from: string; relation: string; target: string }[];\n    readonly duplicateIds: readonly string[];\n}\n\nexport const validate = (canon: readonly Principle[], resolveId: (name: string) => string | null): Issues => {\n    const ids = new Set(canon.map((principle) => principle.id));\n    const edges = ["requires", "reinforces", "enables", "conflictsWith", "tensionsWith"] as const;\n    return {\n        danglingEdges: canon.flatMap((principle) =>\n            edges.flatMap((relation) =>\n                principle[relation]\n                    .filter((target) => resolveId(target) === null && !ids.has(target))\n                    .map((target) => ({ from: principle.id, relation, target })),\n            ),\n        ),\n        duplicateIds: canon.map((principle) => principle.id).filter((id, index, all) => all.indexOf(id) !== index),\n    };\n};';

const KIND_SHAPE =
    "export interface KindRecord {\n    readonly kind: Kind;\n    readonly discriminator: string;\n    readonly distinguishesFrom: string;\n    readonly definitionSignatures: readonly string[];\n}\n\nexport const kindAgrees = (term: { readonly kind: Kind; readonly definition: string }, taxonomy: readonly KindRecord[]): boolean => {\n    const record = taxonomy.find((entry) => entry.kind === term.kind);\n    return record !== undefined && record.definitionSignatures.some((signature) => term.definition.includes(signature));\n};";

const CANON_DIAGRAM =
    'flowchart TB\n    principle["A principle · one canonical id, one kind, one category, a severity"]\n    requires["requires · cannot hold without"]\n    reinforces["reinforces · holds more easily beside"]\n    enables["enables · makes possible"]\n    tensions["in tension with · a record it pulls against, resolved by mechanism"]\n    conflicts["conflicts with · the anti-patterns that negate it"]\n    violated["violated by · what a violation looks like"]\n    detected["detected by · the signals that see it"]\n    measured["measured by · the numbers that size it"]\n    refactored["refactored by · the repairs that reverse it"]\n    enforced["enforced by · the gates that hold it"]\n    principle --> requires\n    principle --> reinforces\n    principle --> enables\n    principle --> tensions\n    principle --> conflicts\n    principle --> violated\n    principle --> detected\n    principle --> measured\n    principle --> refactored\n    principle --> enforced\n    gate["A resolution gate · every edge resolves to a record or a defined term, every kind is in range, or the gate refuses"]\n    requires -.-> gate\n    tensions -.-> gate\n    conflicts -.-> gate';

const RECORD_DIAGRAM =
    "classDiagram\n    class Principle {\n        id\n        name\n        kind\n        category\n        severity\n        violatedBy\n        detectedBy\n        measuredBy\n        refactoredBy\n        enforcedBy\n    }\n    class Term {\n        id\n        name\n        kind\n        definition\n    }\n    class AntiPattern {\n        id\n        absentControl\n    }\n    class Layer {\n        id\n        observes\n        feeds\n    }\n    Principle --> Principle : requires\n    Principle --> Principle : reinforces\n    Principle --> Principle : enables\n    Principle --> Term : tensions with\n    Principle --> AntiPattern : conflicts with\n    Principle --> Layer : member of";

const KIND_MINDMAP =
    'flowchart TB\n    kind(("kind"))\n    rule["a rule"]\n    measure["a measure"]\n    doing["a doing"]\n    shape["a shape"]\n    avoid["a condition to avoid"]\n    kind --> rule & measure & doing & shape & avoid\n    rule --> principle["principle · prescribes"] & constraint["constraint · must hold"]\n    measure --> metric["metric · a number"] & quality["quality attribute · a degree"]\n    doing --> capability["capability · what can be done"] & mechanism["mechanism · the facility"] & technique["technique · the method"] & approach["approach · the strategy"]\n    shape --> pattern["pattern · an arrangement"] & model["model · a representation"] & convention["style · a convention"] & artifact["artifact · a produced thing"]\n    avoid --> anti["anti-pattern"]';

const KIND_DIAGRAM =
    'flowchart TB\n    record["A record"]\n    question{"What does the definition say it is?"}\n    property["a property held to a degree · quality attribute"]\n    number["a measurement · metric"]\n    rule["a rule that prescribes · principle"]\n    bound["a rule that must hold · constraint"]\n    facility["a facility that does it · mechanism"]\n    method["a method a developer applies · technique"]\n    arrangement["a design-level arrangement · pattern"]\n    avoided["a condition to avoid · anti-pattern"]\n    record --> question\n    question --> property\n    question --> number\n    question --> rule\n    question --> bound\n    question --> facility\n    question --> method\n    question --> arrangement\n    question --> avoided\n    polarity["The polarity law · only conflicts-with may point at an anti-pattern"]\n    avoided -.-> polarity';

const LAYER_DIAGRAM =
    'flowchart TB\n    subgraph core["The four core layers"]\n        computation["computation · stateless"]\n        resource["resource · stateful"]\n        execution["execution · control flow and events"]\n        structural["structural · applies to all, observes itself"]\n    end\n    human["human factors · what a developer can hold"]\n    evolution["evolution · how the whole changes"]\n    subgraph crosscut["Cross-cutting layers · each cuts across the structural core"]\n        correctness["correctness"]\n        security["security"]\n        performance["performance"]\n        contracts["contracts"]\n        causality["causality"]\n        declarative["declarative"]\n        extensibility["extensibility"]\n        observability["observability"]\n        enforcement["enforcement"]\n        atomic["atomic boundary"]\n        domain["domain modeling"]\n        patterns["design patterns"]\n    end\n    resource -- observe --> computation\n    computation --> execution\n    resource --> execution\n    execution --> structural\n    structural -- feedback --> execution\n    structural --> human\n    structural --> evolution\n    evolution --> human\n    crosscut -. cross-cuts .-> structural';

const CANON_SECTION: Section = {
    icon: CANON_SECTION_ICON,
    id: CANON_SECTION_ID,
    intro: `This section covers how a principle is held as a typed record rather than a slogan. The record is typed in <cite>a principle record</cite>, its slots are shown in <cite>ten slots</cite>, and its edges are traced in <cite>the five edges</cite>. The whole canon resolves by identity join, so a list of principles becomes something a check can consult, and <a href="${pagePath(ONTOLOGY_PAGE)}">every record</a> this page names can be opened and walked on the ontology page.`,
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, every principle has one identity that nothing else carries, a kind from a closed taxonomy and a category from the data that holds it. Its relations to the other records are recorded as names that resolve to identities, never as free prose, together with what violates it, what detects and measures a violation, the repairs that reverse it and the gates that enforce it. An exemplar with a before and an after is attached, and the gate proves the whole before anything consults it.",
                    boundary:
                        "A canon is a vocabulary for reasoning, and it is the wrong home for a threshold or a path. A principle says that complexity is bounded. The number lives in the gate's config and the check reads it there. A canon that carries numbers is a second config, and a canon that carries paths is bound to one tree.",
                    cause: "Prose principles cannot be joined, so nothing can compute which principle a finding violates, which repair follows, or which two principles a design has set against each other.",
                    decision: "The canon is held as data a gate resolves rather than as a document a reviewer cites.",
                    failureMode:
                        "A review cites a principle by name, a second review cites its opposite by another name, both are in the document, and neither review can show that the two were ever meant to conflict or how the conflict resolves.",
                    kind: "lesson",
                    principle:
                        "For this reason principles are typed and related, and a canon that does not resolve by identity is refused by its gate.",
                    problem:
                        "Architecture principles are usually a reading list, and a reading list cannot tell you which of its entries a given change just broke.",
                    validation:
                        "To check this, take a finding from any check and resolve its canonical id. It must reach the principle, the principle's severity, its repairs and its relation graph in one lookup. A finding that reaches only a message has no canon behind it.",
                },
                { caption: "ten slots", kind: "mermaid", text: CANON_DIAGRAM },
            ],
            title: "Ten slots, one gate",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: `Requires says a principle cannot hold without another, so a design that adopts modularity has adopted its ${faceLink(ALGO_FACE, "dependency-closure", "whole closure")} whether it meant to or not. Reinforces says two principles hold more easily together, which is how an improvement ${faceLink(ALGO_FACE, "reinforcement-propagation", "propagates")} past the record it was made to. Enables says one makes another possible.`,
                },
                {
                    kind: "text",
                    text: `In tension with says two records pull against each other on one construct, and every such pair carries a resolution whose mechanism follows from what the two records are. Conflicts with is the one negative edge, pointing from a principle to the ${faceLink(KIND_FACE, "anti-pattern", "anti-patterns")} that negate it, and the polarity law says it may <a href="${tabLink(ONTOLOGY_PAGE, SCHEMA_TAB, RANGE_SECTION_ID)}">point nowhere else</a>.`,
                },
                { caption: "the five edges", kind: "mermaid", text: RECORD_DIAGRAM },
            ],
            title: "The five edges",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: `The descriptors are prose a developer reads. Violated-by describes the violation, detected-by the ${faceLink(ALGO_FACE, "violation-detection", "signals that see it")}, measured-by the numbers that size it, refactored-by the ${faceLink(ALGO_FACE, "refactor-selection", "repairs that reverse it")}, and enforced-by the ${faceLink(ALGO_FACE, "enforcement-gate", "gates that hold the line")}.`,
                },
                {
                    kind: "text",
                    text: `${faceLink(ALGO_FACE, "severity-policy", "Severity")} says how strictly the principle binds and, where the record states one, the condition under which it binds that strictly. It is a routing field that decides which handler a failure reaches, whether a refusal, a review note or an information line, and it never ranks one principle above another. A check still answers pass or fail, and severity says what happens to the answer.`,
                },
                { code: PRINCIPLE_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a principle record" },
            ],
            title: "The five descriptors",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: "Modularity is a mandatory principle in the structural core. It requires high cohesion, low coupling and explicit boundaries, because a module whose insides do not belong together, or whose edges were never drawn, is not one you can replace. It reinforces separation of concerns and composability, and it enables replaceability and plugin architecture.",
                },
                {
                    kind: "text",
                    text: "It is in tension with cross-cutting concerns, and that pair carries a recorded resolution. It conflicts with the big ball of mud, the one anti-pattern that is its outright negation. A reading list can tell you modularity is good. The record can tell you what you have already committed to by choosing it, what you will get for free, and what it refuses.",
                },
                {
                    kind: "text",
                    text: "Its descriptors meet the tree. It is violated by cyclic dependencies, shared mutable state and boundary leakage. It is detected by dependency cycles and an unstable module graph, measured by a modularity score, graph density and instability, and refactored by splitting the module, introducing a boundary or inverting the dependency. It is enforced by module rules, package ownership and fitness functions. The last slot is what separates a canon from a book, because a principle with an empty enforced-by is held by nothing.",
                },
            ],
            title: "One record, walked",
        },
    ],
    title: "Principles are typed",
};

const KIND_SECTION: Section = {
    icon: KIND_SECTION_ICON,
    id: RECORD_KIND_SECTION_ID,
    intro: `This section covers the kind every record carries, drawn from a <a href="${tabLink(ONTOLOGY_PAGE, SCHEMA_TAB, KIND_SECTION_ID)}">closed taxonomy</a>. How a kind is read from a definition is shown in <cite>kind from definition</cite>, the kinds are grouped in <cite>the fourteen kinds</cite>, and a kind record is typed in <cite>a kind record</cite>. The kind decides what may point at a record, how a tension with it resolves and whether a check can measure it, so a wrong kind is a wrong answer to every one of those questions at once.`,
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, the definition is read and asked what it describes, whether a degree a system exhibits, a number, a rule that prescribes, a rule that must hold, a facility, a method, an arrangement, a representation, a produced thing, a convention of expression, or a condition to avoid. The kind is assigned from that reading and never from the name.",
                    boundary:
                        "A kind classifies what a record is, never how important it is. Two records of the same kind can differ in severity, and a quality that a whole system depends on is still a quality rather than a rule, because the taxonomy answers one question and severity answers another.",
                    cause: "Names are chosen for recognition and definitions are written for precision, so the name of a record tends to overclaim its kind, and the overclaim is only visible once the definition is read against the taxonomy.",
                    decision:
                        "Each kind's discriminator is held as data the gate reads, rather than as a reviewer's judgement, so a record whose definition disagrees with its kind is refused rather than shipped.",
                    failureMode:
                        "A quality that a system exhibits to a degree is filed as a principle, a check is written to enforce it as a rule, and the check has nothing to return because a degree has no violation to report.",
                    kind: "lesson",
                    principle:
                        "For this reason a record's kind follows from its definition, and the taxonomy of kinds is closed.",
                    problem:
                        "Everything on a reading list is called a principle, so a quality, a mechanism and a technique are argued as though they were rules.",
                    validation:
                        "To check this, take any record and cover its name. Read the definition and name the kind from the definition alone. If it differs from the kind the record carries, the record is mis-filed, and every edge that points at it has been reasoning about the wrong thing.",
                },
                { caption: "kind from definition", kind: "mermaid", text: KIND_DIAGRAM },
            ],
            title: "Read the definition, not the name",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: `Each kind answers one question, whether about a rule, a measure, a doing, a shape or a condition to avoid. The pairs most often confused sit closest together. A metric is the measurement and a quality attribute is the property measured, a principle prescribes and a constraint binds, and a mechanism is the facility while a technique is the method a developer applies. The gate checks that every kind is in range, and for a <a href="${tabLink(ONTOLOGY_PAGE, LEXICON_TAB)}">defined term</a> it checks that the kind agrees with the definition, so a term cannot call itself a principle while defining a metric.`,
                },
                { caption: "the fourteen kinds", kind: "mermaid", text: KIND_MINDMAP },
                { code: KIND_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a kind record" },
            ],
            title: "The fourteen kinds",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: "Reading a kind off a name is the mistake the taxonomy exists to catch. Homoiconicity is a quality attribute, a degree a system exhibits, whatever a reading list calls it. Orchestration and choreography are mechanisms, facilities that do a thing. Pure functions are a technique a developer applies. Event sourcing and CQRS are patterns, arrangements a design takes. Fail fast is a principle and idempotency is a principle, because each prescribes.",
                },
                {
                    kind: "text",
                    text: "A check can enforce a principle and measure a metric, but it cannot enforce a quality attribute. A tension between two principles can separate by scope, while a tension between a principle and a quality attribute can only be traded, as derived in separate, trade, or mitigate.",
                },
            ],
            title: "What a name overclaims",
        },
    ],
    title: "Every record has a kind",
};

const GROUPING_SECTION: Section = {
    icon: GROUPING_SECTION_ICON,
    id: GROUPING_SECTION_ID,
    intro: `This section covers the two groupings of the canon and the different questions they answer. The records are held in topical categories, so a reader looking for least privilege finds it beside the other security records and backpressure beside the other resilience records. Each category is then <a href="${tabLink(ONTOLOGY_PAGE, SCHEMA_TAB, MEMBERSHIP_SECTION_ID)}">a member of one layer</a>, in the topology shown in <cite>the layers</cite>, and the layers are where tensions resolve, because a layer is a scope a principle can hold whole in.`,
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, records are grouped by topic for the reader looking for one, and every topical group maps to exactly one layer for the check that has to decide a scope. The two groupings are held as data with one derivation between them, so a record's layer is read from its category and never stated twice. Which layer observes, feeds or cuts across which is recorded too, because that topology is what a scope-separation between two principles is decided against.",
                    boundary:
                        "A grouping is a lookup structure and never a claim about a record. A principle in the security category is not more important than one in the structural category, and a layer is not a rank. The layer says only which scope a principle holds whole in.",
                    cause: "One grouping cannot serve both a reader and a check, because a reader looks by topic and a check decides by scope, and a canon that picks one leaves the other question answered by guesswork.",
                    decision:
                        "Both groupings are kept rather than one being picked, at the cost of one derivation between them.",
                    failureMode:
                        "Two principles pull against each other, the reviewer looks for the domain each belongs to, and finds two topical categories that say nothing about scope, so the tension is settled by the reviewer who argues longer.",
                    kind: "lesson",
                    principle:
                        "For this reason a canon is grouped by topic for people and by layer for checks, and the layer is derived from the topic rather than stated beside it.",
                    problem:
                        "A canon organised one way answers one question, and the other question is answered from memory.",
                    validation:
                        "To check this, take any principle and name its layer without opening the record, from its category alone. If the category does not decide it, the grouping is a reading order and not a scope, and no tension that names this principle can be resolved by data.",
                },
                { caption: "the layers", kind: "mermaid", text: LAYER_DIAGRAM },
            ],
            title: "By topic for people, by layer for checks",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: `Four layers form the core. ${faceLink(LAYER_FACE, "computation-core", "Computation")} is stateless and its outputs are frozen. ${faceLink(LAYER_FACE, "resource-core", "Resource")} is stateful, and every handle has one owner and a bounded lifetime. ${faceLink(LAYER_FACE, "execution-core", "Execution")} is control flow and events. ${faceLink(LAYER_FACE, "structural-core", "Structural")} applies to everything and observes itself.`,
                },
                {
                    kind: "text",
                    text: `Beneath the core sit ${faceLink(LAYER_FACE, "human-factors", "human factors")}, which bound the whole by what a developer can hold, and ${faceLink(LAYER_FACE, "evolution-principles", "evolution")}, which says how the whole changes over time. Around the core sit the twelve layers that cut across it, which are ${faceLink(LAYER_FACE, "correctness-core", "correctness")}, ${faceLink(LAYER_FACE, "security-core", "security")}, ${faceLink(LAYER_FACE, "performance-core", "performance")}, ${faceLink(LAYER_FACE, "contracts-core", "contracts")}, ${faceLink(LAYER_FACE, "causality-core", "causality")}, ${faceLink(LAYER_FACE, "declarative-core", "declarative design")}, ${faceLink(LAYER_FACE, "extensibility-core", "extensibility")}, ${faceLink(LAYER_FACE, "observability", "observability")}, ${faceLink(LAYER_FACE, "enforcement-core", "enforcement")}, the ${faceLink(LAYER_FACE, "atomic-boundary", "atomic boundary")}, ${faceLink(LAYER_FACE, "domain-modeling", "domain modeling")} and ${faceLink(LAYER_FACE, "design-patterns-core", "design patterns")}.`,
                },
                {
                    kind: "text",
                    text: `The <a href="${tabLink(ONTOLOGY_PAGE, SCHEMA_TAB, TOPOLOGY_SECTION_ID)}">topology</a> records which layer observes, feeds or cuts across which. A principle stated in one layer reaches the others by relation, never by being restated there.`,
                },
            ],
            title: "The layers",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: `The derivation is single source of truth applied to the grouping, and the same reasoning shapes how a record names its relations. Identity is the one thing written literally, and everything that points at a record does so by a name that resolves to that identity, so a leaf record depends on nothing beside it and a display name can be corrected without breaking an edge. Held that way the canon is a graph rather than a list, the ${faceLink(ALGO_FACE, "architecture-knowledge-graph", "whole of it is traversable")}, and each ${faceLink(ALGO_FACE, "architectural-relationship-record", "principle record")} reconciles to one vocabulary rather than the vocabulary bending to the records.`,
                },
            ],
            title: "One derivation, never two facts",
        },
    ],
    title: "The canon is grouped twice",
};

export const CANON_SECTIONS: readonly Section[] = [CANON_SECTION, KIND_SECTION, GROUPING_SECTION];
```
