import { COVERAGE_TAB, GAP_SECTION_ID } from "#core/ids/architecture.ids"; import { ARCHITECTURE_PAGE } from "#core/ids/page.ids"; import { ONBOARDING_SECTION_ICON } from "#configuration/icons/system.icons"; import { ONBOARDING_SECTION_ID } from "#core/ids/system.ids"; import type { Section } from "#types/document.types"; import { TYPESCRIPT_LANGUAGE } from "#configuration/constants/code.constants"; import { tabLink } from "#assets/link.assets"; const SLOT_SHAPE = 'export type SlotState = "RESOLVED" | "ABSENT" | "DEFERRED";\nexport type SlotValue = string | number | readonly string[] | null;\n\nexport interface Slot {\n readonly state: SlotState;\n readonly value: SlotValue;\n readonly note: string;\n}\n\nexport const resolved = (value: Exclude, note: string): Slot => ({ state: "RESOLVED", value, note });\nexport const absent = (note: string): Slot => ({ state: "ABSENT", value: null, note });\nexport const deferred = (note: string): Slot => ({ state: "DEFERRED", value: null, note });\n\nexport interface Binding {\n readonly project: Readonly>;\n readonly surface: Readonly>;\n readonly convention: Readonly>;\n readonly limits: Readonly>;\n readonly execution: Readonly>;\n}\n\nexport const binding: Binding = {\n project: {\n root: resolved("", "the host root relative to this package, the one value an adopter sets"),\n policy_projection: absent("the host has not adopted the package, so no projection is written into its document"),\n rollback_point: deferred("a reversible checkpoint will exist once the host is under version control"),\n },\n surface: { board: resolved("", "the coordination board") },\n convention: { nesting_cap: resolved("", "the placement depth cap from a governed root") },\n limits: { file_cap: absent("no per-file cap; a host that wants one holds it in its own linter") },\n execution: { compile: absent("nothing here compiles") },\n};'; const DROP_IN_DIAGRAM = 'flowchart TB\n subgraph governance["The governance folder · copied whole, never edited for a feature"]\n policy["The behaviour policy · named rules the AI reads first"]\n checks["The checks · one file per rule, each proven to fire"]\n cores["The cores · reasoning that names no project"]\n binding["The binding · the one file that names this tree"]\n end\n code["The code · shaped by the grammar the checks parse"]\n command["The one command · every check, fixer, generator and validator"]\n binding -. resolves every slot the cores name .-> cores\n checks -. parse .-> code\n command --> checks\n policy -. governs .-> code'; const SLOT_DIAGRAM = 'flowchart LR\n core["A core names a slot"]\n binding{"What does the binding say?"}\n resolved["Resolved · the branch runs against this tree\'s value"]\n absent["Absent · the branch does not run, and says so"]\n deferred["Deferred · the branch is blocked until the value exists"]\n faked["Nothing declared · the branch runs against a guess"]\n core --> binding\n binding -- a value --> resolved\n binding -- declared absent --> absent\n binding -- declared deferred --> deferred\n binding -. no declaration .-> faked'; const ONBOARDING_SECTION: Section = { icon: ONBOARDING_SECTION_ICON, id: ONBOARDING_SECTION_ID, intro: "Onboarding a project is a template applied to a binding, not a ritual performed in a chat. The whole governance set is a folder that names no project, plus one file that does, as a drop-in draws. Adopting it means copying the folder and writing that one file, a binding, in which every host fact is a slot in one of the three states slot states draws, and the gate is green on an empty tree before the first line of code exists. Everything about how that works follows from one separation: the thinking is kept apart from the tools, which is platform independence for a method and configuration externalization for its facts. The template families the grammar page publishes are what the folder is generated from.", subsections: [ { blocks: [ { application: "Keep the reasoning in cores that name no project. Keep the bindings in one adapter that resolves every slot the cores leave open. Name a slot that nothing fills as absent, in the adapter, rather than letting the core assume it, and let the branch that depends on it not run. Prove the set on an empty tree, because a gate that is red before any code exists is reporting a binding, and a gate that is green there is the baseline every later red is measured against.", boundary: "A catalogue inside a core, a list of principles or patterns or examples, may assume constructs this tree does not carry. The mechanism transfers unchanged and the catalogue is re-derived against what exists here. Substituting the mechanism is the violation and re-deriving the catalogue is the work.", cause: "A core that names a path is bound to the tree that has it, so the next tree has to edit the core.", decision: "Port by rewriting one adapter rather than by editing the cores.", failureMode: "Every new project starts with a long conversation reconstructing rules that already exist somewhere else, slightly wrong.", kind: "lesson", principle: "Cores are agnostic, one adapter binds them, and every absence carries a declaration rather than a patch.", problem: "A method that lives in one project's vocabulary does not transfer.", validation: "Apply the set to an empty project. A red gate there is a binding the adapter did not make; a green one proves the binding and nothing else, because a check over an empty tree measures nothing.", }, { caption: "a drop-in", kind: "mermaid", text: DROP_IN_DIAGRAM }, ], title: "A template applied to a binding", }, { blocks: [ { kind: "text", text: "A core is a document that states what to do as semantic operations and slots, the shape the behaviour document already has. It never says which tool discovers or which folder is the test root, because the moment it does it is bound to one tree and the next tree has to edit it. The adapter is the one file where those names live, and it is the only file rewritten when the set is ported.", }, { kind: "text", text: `A slot resolves to one of three states, and the third is the load-bearing one. Resolved means this tree has the thing and the value is here. Absent means this tree has no analogue, the branch that depends on it does not run, and that is declared rather than faked. Deferred means the thing will exist and does not yet, so the branch is blocked rather than skipped, which answers a different question in the right shape. An adapter that resolves everything is lying about something. The predicates this tree does not have, a computed worth, a non-progress detector, a calibrated confidence, are named as absent in the adapter so that nothing upstream assumes them; the honest gaps chapter lists them, and the architecture page reaches the same declared absences because an architecture is its predicate set.`, }, { caption: "slot states", kind: "mermaid", text: SLOT_DIAGRAM }, ], title: "Cores, one adapter, three slot states", }, { blocks: [ { kind: "text", text: "The template that generates the set retains mechanism and rewrites content. A fact that would be wrong in the next project is templatized into a slot. A statement true of one domain that is true of the class is generalized to the class. A mechanism that must carry no knowledge of what it governs is made agnostic. Then the generator substitutes the one binding, validates in both directions, that every slot the cores name is bound and that every binding names a slot, installs, runs the gate, and removes itself before the gate certifies the tree. A generated project is therefore green on arrival with no hand edit, which is what makes every manual step of onboarding a manual runbook dependency rather than a chore.", }, { kind: "text", text: "The checks derive their contracts from the same templates the surfaces are raised from, a single source of truth the check reads at run time. A check that transcribed a schema would hold a second copy with nothing keeping the two equal, and the drift would surface only when somebody raised a new surface and it failed on its first run, non-conformant at birth from a template that read as authoritative.", }, ], title: "The generator removes itself", }, { blocks: [ { kind: "text", text: "The binding is a typed module rather than a page, and the prose face of it is rendered from the module so the two cannot disagree, which is what self-describing architecture means for a binding. A slot is one record with a state from a closed union, a value that is null in every state but resolved, and a note stating why, so a reader meets the reason beside the value and a mechanism meets the state before the value. The three constructors are the only way to make a slot, which is what keeps a resolved slot from carrying no value and an absent one from carrying a stale one.", }, { kind: "text", text: "Slots are grouped by who supplies them: what the host supplies, what the package owns, the conventions, the limits and the execution commands. A census over the states is derived on render, so it cannot disagree with the table above it, and a binding whose census shows every slot resolved is the one to distrust.", }, { code: SLOT_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a binding" }, ], title: "The binding as a module", }, ], title: "The drop-in", }; export const SYSTEM_SECTIONS: readonly Section[] = [ONBOARDING_SECTION];