import { CELL_SECTION_ICON, GAP_SECTION_ICON, GRID_SECTION_ICON, PREDICATE_SECTION_ICON, } from "#configuration/icons/architecture.icons"; import { CELL_SECTION_ID, GAP_SECTION_ID, GRID_SECTION_ID, PREDICATE_SECTION_ID } from "#core/ids/architecture.ids"; import { DIMENSION_SECTION_ID, LENS_SECTION_ID, REASONING_TAB, SURFACE_SECTION_ID, UNCOVERED_SECTION_ID, } from "#core/ids/ontology.ids"; import { ALGO_FACE } from "@govlab/constants"; 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"; import { tabLink } from "#assets/link.assets"; const SURFACE_SHAPE = 'export const DIMENSIONS = ["identity", "composition", "structure", "relation", "space", "time", "state", "change", "behaviour", "function", "cause", "meaning", "scale", "probability", "novelty"] as const;\nexport const LENSES = ["structural", "temporal", "spatial", "statistical", "frequency", "sequential", "relational", "behavioural", "functional", "semantic", "causal", "predictive", "anomaly", "evolutionary", "fractal", "transformational", "invariant", "optimisation", "complexity"] as const;\n\nexport type Dimension = (typeof DIMENSIONS)[number];\nexport type Lens = (typeof LENSES)[number];\n\nexport type Cell =\n | { readonly kind: "watched"; readonly invariant: string; readonly predicate: GateId }\n | { readonly kind: "unwatched"; readonly invariant: string; readonly because: string }\n | { readonly kind: "undecided"; readonly question: string };\n\nexport type CellKey = readonly [Dimension, Lens];\nexport type RuleSurface = ReadonlyMap;\n\nexport const emptyCells = (surface: RuleSurface): readonly CellKey[] =>\n [...surface.entries()].flatMap(([cell, held]) => (held === null ? [cell] : []));'; const RULE_SHAPE = 'export interface Rule {\n readonly cell: CellKey;\n readonly detect: (tree: Tree) => readonly Shape[];\n readonly report: (found: Shape) => { readonly invariant: string; readonly remediation: string };\n}\n\nexport interface Declared {\n readonly predicate: string;\n readonly status: "runs" | "absent";\n readonly because: string | null;\n}'; const PREDICATE_DIAGRAM = 'flowchart TB\n intent["An architectural intent · a sentence about how the system should be"]\n question["A question · what can drift, seen through how it drifts"]\n type["A mathematical type · a set, an ordering, a graph, a number"]\n predicate["A predicate · computable over the tree"]\n selects["Selects what to examine next"]\n closes["Marks when the concern is closed"]\n habit["A habit · held by whoever remembers"]\n intent --> question --> type --> predicate\n predicate --> selects\n predicate --> closes\n intent -. without the walk .-> habit'; const REAL_DIAGRAM = 'flowchart TB\n design["A design"]\n intentions["Its intentions · what the author meant"]\n predicates["Its predicate set · what a check can decide"]\n author{"Who writes the code?"}\n person["A person · intentions survive by attention, for a while"]\n model["A model · every intention with no predicate is absent"]\n real["The architecture that is real · the predicate set"]\n design --> intentions\n design --> predicates\n intentions --> author\n author -- person --> person\n author -- model --> model\n predicates --> real\n model -. only this survives .-> real'; const GRID_DIAGRAM = 'flowchart LR\n subgraph dimensions["What can drift"]\n identity["identity"]\n relation["relation"]\n change["change"]\n meaning["meaning"]\n end\n subgraph lenses["How it drifts"]\n structural["structurally"]\n relational["relationally"]\n sequential["sequentially"]\n semantic["semantically"]\n end\n cell["A cell · one invariant, watched, unwatched with a reason, or undecided"]\n identity --> cell\n relation --> cell\n change --> cell\n meaning --> cell\n structural --> cell\n relational --> cell\n sequential --> cell\n semantic --> cell'; const HEATMAP_DIAGRAM = 'block-beta\n columns 5\n corner[" "] structural["structural"] relational["relational"] sequential["sequential"] semantic["semantic"]\n identity["identity"] i1["watched"] i2["unwatched · declared"] i3["undecided"] i4["watched"]\n relation["relation"] r1["watched"] r2["watched"] r3["undecided"] r4["unwatched · declared"]\n change["change"] c1["undecided"] c2["watched"] c3["watched"] c4["undecided"]\n meaning["meaning"] m1["unwatched · declared"] m2["undecided"] m3["watched"] m4["watched"]'; const CELL_DIAGRAM = 'flowchart TB\n enumerate["Enumerate the checks that exist"]\n map["Map each to its cell · dimension by lens"]\n walk["Walk the grid"]\n empty{"Empty cell?"}\n name["Name the invariant that should hold there"]\n decide{"Can the invariant be stated?"}\n author["Author the predicate, or record the cell as deliberately unwatched"]\n undecided["An undecided intent · the finding is the design, never the rule"]\n enumerate --> map --> walk --> empty\n empty -- yes --> name --> decide\n decide -- yes --> author\n decide -- no --> undecided'; const GAP_DIAGRAM = 'flowchart TB\n called["A predicate the method calls for"]\n exists{"Does the tree run it?"}\n runs["Declared present · it runs in the chain"]\n absent["Declared absent · named in the one document that binds method to tree"]\n assumed["Assumed · the document describes an upgrade the tree never made"]\n called --> exists\n exists -- yes --> runs\n exists -- no --> absent\n exists -. neither written down .-> assumed'; const PREDICATE_SECTION: Section = { icon: PREDICATE_SECTION_ICON, id: PREDICATE_SECTION_ID, intro: "An intent that never became a predicate is a habit, and a habit is held by whoever remembers it, for as long as they do. The reasoning axis of the ontology is what turns a question into a type and a type into a predicate, the walk intent to predicate draws, and resolving a message on the methodology page walks the same axis on a request. How much of a design is real depends on who writes the code, as what is real draws.", subsections: [ { blocks: [ { application: "State every architectural intent as a question about what can drift, seen through how it drifts. Resolve the question to a type: what exists is a set, how parts are arranged is an ordering, what connects is a graph, how sure you are is a number. Derive the predicate from the type and run it over the tree as a check.", boundary: "Determinism lives in the predicate and never in the judgement that authored it. Which cells are worth watching is a decision; whether a cell's predicate holds is a computation. Keep the decision in the person and the computation in the check, and never let a predicate encode taste.", cause: "An intention has no objector, so its first violation is silent, and a system whose rules are silent is governed by attention rather than by structure.", decision: "Count the architecture by what the gate refuses rather than by what the document states.", failureMode: "A design document states twelve principles, the codebase honours four, and nobody can say which four without reading everything, because the other eight were never anything a check could evaluate.", kind: "lesson", principle: "An architecture is its predicate set, and a predicate selects what to examine and marks when the concern is closed.", problem: "Architecture is usually a set of intentions, and an intention cannot be evaluated, so nobody can say how much of the architecture is real.", validation: "List the architectural claims your system makes. Beside each, name the predicate that decides it and where that predicate runs. A claim with no predicate beside it is a sentence in a document, and the document is the only place it holds.", }, { caption: "intent to predicate", kind: "mermaid", text: PREDICATE_DIAGRAM }, ], title: "Question, type, predicate", }, { blocks: [ { kind: "text", text: "The double duty is what makes derivation possible. The predicate that says an export is unreachable is the same predicate that says reachability is covered: one tells you where to work, the other tells you the dimension is watched. A project that has the first without the second accumulates checks by incident, and one that has both can derive its checks from its invariants.", }, { kind: "text", text: "Policy as code is the canon's name for the whole move, and fitness functions are the same predicates run against an architecture rather than a request. Static analysis is where most predicates live, because a shape in a tree can be decided without running anything, and design by contract is the same idea one level down: preconditions, postconditions and invariants that a check can evaluate rather than a comment can promise.", }, { caption: "what is real", kind: "mermaid", text: REAL_DIAGRAM }, ], title: "A predicate does two jobs", }, { blocks: [ { kind: "text", text: "The coverage question is then answered from the grid what can drift, seen through how it drifts builds, rather than from a count of rules. Security theater is what a count produces: the presence of controls standing in for the coverage of them. A predicate set answers the other question, which cells have something that can disagree with them, and that is the only sense in which an architecture is enforced.", }, ], title: "Coverage from the grid, never from a count", }, ], title: "An architecture is its predicate set", }; const GRID_SECTION: Section = { icon: GRID_SECTION_ICON, id: GRID_SECTION_ID, intro: `The grid has two closed axes. The dimensions are what can drift and the lenses are how it drifts, and a cell is one invariant that must hold, watched by a predicate or declared unwatched with its reason, as two axes, one cell draws, a corner shows and a rule surface types. Two closed axes are what make coverage a derivation: the cells are enumerable, so the ones nothing watches are enumerable too, and a rule set is measured against the grid rather than against the incidents that happened to produce it.`, subsections: [ { blocks: [ { application: "Name the dimensions along which your system can drift and the lenses through which each drift is seen, and close both lists. Place every existing check in the cell it watches, one invariant per cell, and read an empty cell as a drift class nothing watches.", boundary: "The grid enumerates where drift can be watched and says nothing about which cells deserve a rule. A full grid is not the goal; a grid whose every cell is either watched, unwatched with a stated reason, or marked undecided is, and the third state is the one that carries the design decisions still to make.", cause: "Without closed axes a rule set has no denominator, so coverage is reported as a count that grows with every incident and never says what is missing.", decision: "Close the axes before counting anything, so the count has a denominator.", failureMode: "A suite reports hundreds of passing tests, the surface that fails in production was one none of them reached, and the green run was evidence over the wrong set.", kind: "lesson", principle: "Coverage is a grid of what can drift against how it drifts, and an unmeasured cell is unknown rather than clean.", problem: "A rule set with no denominator reports how many checks exist, which says nothing about how many drift classes have none.", validation: "Take the checks you have and place each in its cell. Then count the empty cells. If you cannot place a check, its invariant was never stated; if you cannot count the empties, the axes were never closed.", }, { caption: "two axes, one cell", kind: "mermaid", text: GRID_DIAGRAM }, ], title: "Two closed axes", }, { blocks: [ { kind: "text", text: "A module reaching across a boundary is relation seen relationally, and a circular dependency is relation seen structurally. Two files claiming one role is identity seen structurally. A manifest entry rotting is composition seen through evolution. A discriminated union gaining a case nothing handles is change seen sequentially. A registry written and never read is function seen functionally. Intent living in a comment is meaning seen semantically. The same defect at every scale is scale seen fractally, and a convention followed everywhere except here is novelty seen as anomaly.", }, { caption: "a corner", kind: "mermaid", text: HEATMAP_DIAGRAM }, { code: SURFACE_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a rule surface" }, ], title: "The axes, and a cell read off them", }, { blocks: [ { kind: "text", text: `The same grid projected onto correctness is the test-surface catalogue. Every surface a unit can fail in names its failure modes, its technique, its predicate and its evidence source, and its verdict domain carries unknown as a value distinct from pass. Property-based testing and specification-based testing are techniques a surface names, and chaos engineering is the technique for the surfaces only a running system can fail in.`, }, { kind: "text", text: `An unmeasured surface is unknown rather than clean, as unknown is not pass states and ${faceLink(ALGO_FACE, "evidence-verdict", "the evidence verdict")} records. Test pyramid inversion and the mock mirage are the two ways a green run stops being evidence, and ${faceLink(ALGO_FACE, "coverage-completion", "completion")} is the absence of required surfaces still unknown, never a percentage, because a percentage averages the surfaces that matter with the ones that cannot fail.`, }, ], title: "Projected onto correctness", }, ], title: "What can drift, seen through how it drifts", }; const CELL_SECTION: Section = { icon: CELL_SECTION_ICON, id: CELL_SECTION_ID, intro: "Coverage is planned by walking the grid, as the walk draws, and the step that pays is the one where a cell resists: an invariant that cannot be stated is not a missing rule, it is an architectural intent nobody has decided, and that is the finding.", subsections: [ { blocks: [ { application: "Walk the grid with the checks you have, and treat every empty cell as a question rather than a gap. Where the invariant states itself, author the predicate. Record the unwatched cells with their reasons, so the unassessed set stays countable and a later reader can tell a decision from an oversight.", boundary: "A cell whose predicate nothing could ever disagree with is not authored; it is held with the forgone property written down, for the reason the check comes first gives on the methodology page.", cause: "A rule set built by incident has a shape decided by which incidents happened, and the drift classes that never produced an incident are exactly the ones with nothing watching them.", decision: "Stop authoring when a cell resists, and decide the design before the check, because the cell is saying the convention it would enforce was never chosen.", failureMode: "A team adds a check after every outage, the check count grows, and the failure that ships next lives in a cell the outages never happened to touch.", kind: "lesson", principle: "A cell that resists an invariant is an undecided intent rather than a missing rule.", problem: "Checks accumulate by incident, so the covered cells are the ones that already failed and the uncovered ones are the ones that will.", validation: "Find an empty cell and try to state its invariant in one sentence that could be false. If the sentence comes, you were missing a check. If it does not, you are missing a decision, and no check can be written until it is made.", }, { caption: "the walk", kind: "mermaid", text: CELL_DIAGRAM }, ], title: "Walk the grid", }, { blocks: [ { kind: "text", text: "Two invariants keep this a method rather than a rule pile. No rule without a consuming failure mode: a rule earns its place only if a real drift class fires it, because a rule nothing can violate is ceremony, and ceremony costs the same review attention as a real rule, which is how a rule set stops being read.", }, { kind: "text", text: "And the rule set is derived while the judgement that authored it is not. Which cells need watching is a deterministic function of the architecture's declared invariants, whether an invariant was worth declaring is a decision, and the determinism stays in the predicate rather than in the deciding.", }, ], title: "Two invariants of the walk", }, { blocks: [ { kind: "text", text: `The ${faceLink(ALGO_FACE, "surface-grid-walk", "walk itself")} and the ${faceLink(ALGO_FACE, "uncovered-gap-derivation", "gap it derives")} are records in the canon, and the cells the canon has not yet covered are listed rather than assumed away.`, }, { kind: "text", text: "Gap analysis is the activity, and a resisting cell is its most useful output. A cell whose invariant states itself was a missing rule. A cell whose invariant will not state itself is an architecture review waiting to happen, and an architecture decision record is where its answer lands, so the next walk finds a decision rather than the same empty cell.", }, ], title: "The walk in the canon", }, ], title: "A cell that resists an invariant", }; const GAP_SECTION: Section = { icon: GAP_SECTION_ICON, id: GAP_SECTION_ID, intro: "Every cell that earns a rule renders two ways from one entry, a detect half and a report half, the shape a rule entry types. Every predicate the method calls for is either running in the tree or declared absent in the one document that binds the method to the tree, the three states running or absent draws. The second half is the honesty of the first: a method that cannot say which of its own predicates are missing has not measured itself, and a document that describes an upgrade the tree never made is the stale description the model section names.", subsections: [ { blocks: [ { application: "Author each rule as one entry with a detect half and a report half, discovered by shape and consumed whole by the gate. Then keep one document that names every predicate the method calls for and states, for each, whether the tree runs it or not, and never let an absence be assumed.", boundary: "A declared gap is not a licence. Naming a predicate as absent keeps the document honest and leaves the drift class unwatched, so an absent predicate is still a cell to decide, and the declaration only says that the decision has not been made yet.", cause: "A rule that only blocks teaches nothing, so the same violation returns from the next author, and a document that only describes the ideal cannot be checked against the tree, so its gaps are found by failure rather than by reading.", decision: "Write the report half beside the detect half rather than a blocking message alone, and name an absence in the binding document rather than leave it to be assumed.", failureMode: "A check refuses a change with a message that names a rule id, the author works around the id, and the document that describes the method lists a predicate that has never run anywhere.", kind: "lesson", principle: "A rule detects and reports from one entry, and a predicate the tree does not run is declared absent, never assumed.", problem: "Checks that only block teach nothing, and methods that only describe cannot say which of their own predicates exist.", validation: "Take any finding your gate prints and ask whether it names the invariant and the remediation. Then take the document that describes your method and ask, for each predicate it calls for, whether the tree runs it. A finding that names only a rule, or a predicate nobody can locate, is the gap.", }, { caption: "running or absent", kind: "mermaid", text: GAP_DIAGRAM }, ], title: "Detect, report, declare", }, { blocks: [ { kind: "text", text: "The detect half is the predicate that fires on the violating shape. The report half is the message that names the invariant and the remediation, so the failure teaches the convention rather than only blocking. Auto-remediation follows where the remediation has one correct answer, and where it does not the report still carries the handle a reasoning agent needs.", }, { kind: "text", text: "That is the registry pattern applied to enforcement: one entry per rule, discovered by shape through auto-discovery, consumed by the gate, with the whole set failing the build on drift. Where a project already has a registry primitive for code, enforcement reuses it rather than inventing a second one.", }, { code: RULE_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a rule entry" }, ], title: "One entry, two halves", }, { blocks: [ { kind: "text", text: "The walk is also how the gaps are named. A predicate the method calls for and the tree does not have is declared absent, in the one document that binds the method to the tree, rather than assumed. It is normal for the epistemic and structural predicates to exist and run: whether something is reachable, consumed, grounded, drifting or covered.", }, { kind: "text", text: "The conative ones are the usual gap: a computed worth over branches, a detector for a run that stops making progress, a calibrated confidence rather than a threshold. The methodology page keeps its own list under the same title, the honest gaps, and the two are one declaration read from two sides.", }, ], title: "Declared absent, never assumed", }, ], title: "The honest gaps", }; export const DRIFT_SECTIONS: readonly Section[] = [PREDICATE_SECTION, GRID_SECTION, CELL_SECTION, GAP_SECTION];