# configuration/strings/rule.strings.ts

> 246 lines of code and 14 definitions.

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

## Definitions

- `RULE_RECORD_SHAPE` (lexical_declaration, line 11)
- `RULE_LINES` (lexical_declaration, line 14)
- `ROLE_TEMPLATE` (lexical_declaration, line 17)
- `MECHANISM_DIAGRAM` (lexical_declaration, line 20)
- `CORRECTION_DIAGRAM` (lexical_declaration, line 23)
- `MECHANISM_SECTION` (lexical_declaration, line 26)
- `RULE_SECTION` (lexical_declaration, line 67)
- `CONTRACT_SECTION` (lexical_declaration, line 117)
- `POLICY_SKELETON` (lexical_declaration, line 155)
- `COMPOSITION_DIAGRAM` (lexical_declaration, line 158)
- `PORTABILITY_DIAGRAM` (lexical_declaration, line 161)
- `DELIVERY_DIAGRAM` (lexical_declaration, line 164)
- `POLICY_SECTION` (lexical_declaration, line 167)
- `RULE_SECTIONS` (lexical_declaration, line 260, exported)

## Source

```typescript
import {
    CONTRACT_SECTION_ICON,
    MECHANISM_SECTION_ICON,
    POLICY_SECTION_ICON,
    RULE_SECTION_ICON,
} from "#configuration/icons/rule.icons";
import { CONTRACT_SECTION_ID, MECHANISM_SECTION_ID, POLICY_SECTION_ID, RULE_SECTION_ID } from "#core/ids/rule.ids";
import { MARKDOWN_LANGUAGE, TYPESCRIPT_LANGUAGE } from "#configuration/constants/code.constants";
import type { Section } from "#types/document.types";

const RULE_RECORD_SHAPE =
    'export type Tier = "always" | "situational" | "exception";\nexport type Gate = { readonly kind: "check"; readonly id: GateId } | { readonly kind: "conduct" };\n\nexport interface RuleRecord {\n    readonly slug: string;\n    readonly directive: string;\n    readonly tier: Tier;\n    readonly gate: Gate;\n    readonly locked: boolean;\n    readonly source: DocumentId;\n}\n\nexport interface Digest {\n    readonly slug: RuleRecord["slug"];\n    readonly why: string;\n    readonly how: string;\n    readonly measured?: { readonly shape: string; readonly presents: string };\n}';

const RULE_LINES =
    "## <rules that bite every turn>\n\n- `read_before_claim`: a claim about a file is a lie until the file is read in this session · gate: conduct\n- `finding_not_principle`: the model is directed with a location and a mismatch, never with a principle · gate: conduct\n- `one_run_is_the_answer`: a check runs once per state and its first output is read whole · gate: conduct\n\n## <rules that fire on a matching task>\n\n- `rename_by_hand`: a move is done by hand, every reference enumerated before and verified after · gate: reference\n- `ask_at_the_uncertainty`: a question is raised where it appears, with a recommendation, before the dependent work · gate: conduct";

const ROLE_TEMPLATE =
    "# Reviewer\n\n## <identity>\nThe seat's identity, bound in the index before its first write.\n\n## <what it owns>\nThe list of findings, and nothing else.\n\n## <what finished means>\nA change ships only once the list is empty.\n\n## <how it works>\nOne finding per line: file, line, expected, found. No style comments, no rewrites.\n\n## <the shapes it gets wrong>\nAffirming a change that reads well. Reviewing the description instead of the diff.\n\n## <what decides its calls>\nA finding without a location is an opinion. Approval is what remains when the list is empty.";

const MECHANISM_DIAGRAM =
    'flowchart TB\n    rule["A rule"]\n    conversation["Held in the conversation"]\n    restated["Restated every session"]\n    fades["Fades as the context fills"]\n    defaults["The model is back to its defaults"]\n    tree["Held in the tree"]\n    policy["A policy file given to the model every session"]\n    check["A check that runs on every change"]\n    holds["Held by the tree, not by memory"]\n    rule --> conversation --> restated --> fades --> defaults\n    rule --> tree --> policy --> holds\n    tree --> check --> holds';

const CORRECTION_DIAGRAM =
    'flowchart TB\n    correction["A correction arrives"]\n    classify["Classified to one encoding"]\n    rule["One line · slug, directive, gate"]\n    reason["Its reason · why it exists"]\n    application["Its application · how it applies"]\n    memory["A memory file · the fact, its why, its how"]\n    search["Verified by search, never by recollection"]\n    correction --> classify --> rule --> reason --> application --> memory --> search\n    rule -. the class, never the instance .-> rule';

const MECHANISM_SECTION: Section = {
    icon: MECHANISM_SECTION_ICON,
    id: MECHANISM_SECTION_ID,
    intro: "A rule can live in one of two places, and <cite>two homes</cite> shows where each one leads. It can live in the conversation, where the developer has to restate it and hope it is followed, or it can live in the tree, where the model is given the policy file at the start of every session and a check refuses any change that breaks the rule. Everything in this method lives in the tree: as policy as code where a check can enforce it, and as a line in the policy where only the model's conduct can. An instruction that has to be restated is a mechanism that has not been built yet, and the ontology calls the state it leaves behind manual-only governance.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, each instruction you keep repeating moves into a file the model is given at the start of every session, and each check you keep performing by hand moves into a command the pipeline runs. Once the mechanism holds, the old habit is dropped, because a habit kept alongside its mechanism is a second home for the same rule.",
                    boundary:
                        "A conversation is the right place for a rule only when the model has no access to your files; as soon as it does, the tree is the right place.",
                    cause: "A rule held only by discipline is decided again every time it applies, and every new decision is a chance to decide differently.",
                    decision:
                        "Discipline is turned into mechanism as soon as a rule has been stated twice, rather than stated a third time.",
                    failureMode:
                        "The session starts well, the instructions fade as the context fills up, and by the end the model is back to its default behaviour.",
                    kind: "lesson",
                    principle:
                        "For this reason I hold rules in the tree rather than in the conversation, because a rule in the conversation decays and a check in the tree does not.",
                    problem:
                        "Rules that live in a chat have to be restated every session, and each restatement is a chance for them to drift.",
                    validation:
                        "To check this, delete your custom instructions for one session. What still holds is mechanism, and what breaks was discipline.",
                },
                {
                    kind: "text",
                    text: "The test that tells the two apart is whether anything would object if the rule stopped holding, the same objector test that the section stating an invariant applies to a whole topology. A rule in a conversation has no objector: once it is forgotten, nothing notices. A rule in the tree has one of two. Either a check refuses the change that breaks it, or a policy line states it in the same words at the start of every session. The second is weaker than the first, because the model can still fail to follow a line it has been given, but it is still stronger than a memory, because a policy is delivered to every session and a memory reaches only the party who remembers to look it up.",
                },
                {
                    kind: "text",
                    text: "Friction between several parties working on one tree is the same question at a larger scale, and coordination is software answers it. When two parties lose a write, leave a stale item behind or miss a message, the first question is what the shared surface is missing, never who should have been more careful. A rule added without a mechanism behind it only asks for more care, and it decays at the same rate the care did.",
                },
                { caption: "two homes", kind: "mermaid", text: MECHANISM_DIAGRAM },
            ],
            title: "Discipline decays, mechanism holds",
        },
    ],
    title: "Where a rule lives",
};

const RULE_SECTION: Section = {
    icon: RULE_SECTION_ICON,
    id: RULE_SECTION_ID,
    intro: "Every behavioural rule is written as one line with three parts: a stable name, a directive, and either the name of the check that enforces it or a statement that no check can. <cite>a policy file</cite> shows such lines, and <cite>a rule record</cite> shows the shape they are read into. The name is what a correction attaches to and what a citation points to. When I correct the model, the correction is written down in the same turn as a named rule and a memory, so that the rule is there for the next session instead of the correction having to be given again, as shown in <cite>a correction hardens</cite>.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, each rule is one line: a short stable name, a directive in the present tense, and the gate that enforces it. The name is cited wherever the rule applies. When a correction arrives, it is assigned to one home, the rule is written first, then its reason and how it applies, a memory is stored beside it, and every place it was written to is confirmed by searching rather than by recollection. What is captured is the kind of mistake the correction belongs to, never the single case that triggered it.",
                    boundary:
                        "A rule may mention the measured failure that led to it, in the past tense and only inside that rule, because that clause is part of what the rule depends on. It describes the shape of the failure and how it showed up, never who caused it, when, or in what order.",
                    cause: "A correction with nowhere to attach is remembered by the developer and forgotten by the model, so it has to be given again the following week.",
                    decision:
                        "Each rule gets a name that a correction can attach to, rather than a paragraph that corrections are appended to.",
                    failureMode:
                        "The same correction is made in three sessions, each time as a new paragraph, and the three paragraphs end up contradicting each other.",
                    kind: "lesson",
                    principle:
                        "For this reason I keep behaviour as a set of named rules, so that a correction becomes permanent rather than being repeated.",
                    problem: "Instructions written as prose have no fixed place for a correction to attach to.",
                    validation:
                        "To check this, take the last correction you gave the model and look for its name among the rules. If it has no name, you will have to give it again.",
                },
                {
                    kind: "text",
                    text: "The shape of the line is the whole design. A name is a stable identity, so a rule can be cited from a digest, a memory, a finding or another party's message without quoting its text, and the citation survives any rewording; the names are the ubiquitous language the developer, the model and the tooling share. A directive that fits on one line cannot hide a second instruction, so it reads as a single step. The gate field is the honest part: it names the check that enforces the rule, or it says that no artifact can show whether the rule held, and a rule that says neither has never been assessed. That field is written in exactly one place per rule, because a single source of truth allows no second place to declare it. A rule without its reason gets argued over again, and a rule without its application gets admired and ignored, so the digest that expands a rule carries both; a digest is an architecture decision record for one line of conduct.",
                },
                {
                    kind: "text",
                    text: "The reason and the application are written in the developer's own sharpest words wherever there are any, because a paraphrase loses the distinction that made the correction necessary. For example, one wrong path becomes a rule about checking paths, and one missed reference becomes a rule about places that find files by pattern.",
                },
                {
                    kind: "text",
                    text: "The rules are grouped into the ones that apply every turn and the ones that apply when a particular kind of task comes up, plus a small set of declared exceptions. That grouping helps the reader and means nothing to the checks. A check reads the gate field and never the heading, which is why a rule can move between groups without any mechanism noticing, and why a new rule is one added line rather than a new section.",
                },
                {
                    kind: "text",
                    text: "Once parsed, a rule is a record, and that record is what the inventory, the coverage walk and the leak check all read; coverage is derived from that inventory rather than counted. The gate field has two allowed forms, a check or conduct, rather than being optional, so a rule that declares neither cannot be written down at all; the unassessed state is impossible rather than merely discouraged.",
                },
                { code: RULE_LINES, kind: "code", language: MARKDOWN_LANGUAGE, title: "a policy file" },
                { code: RULE_RECORD_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a rule record" },
                { caption: "a correction hardens", kind: "mermaid", text: CORRECTION_DIAGRAM },
            ],
            title: "A correction lands on a name",
        },
    ],
    title: "Rules with names",
};

const CONTRACT_SECTION: Section = {
    icon: CONTRACT_SECTION_ICON,
    id: CONTRACT_SECTION_ID,
    intro: "A seat is a party's role in a collaboration, and it is defined by a contract, never by a character. A seat applies design by contract to a party: the contract is a role document with the same sections for every seat, as shown in <cite>a role document</cite>. It names what the seat owns, what it refuses, how it works, the principles that decide its calls and the mistakes it tends to make.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, a role is a short document with the same sections every time, and it names the mistakes that seat is known to make beside what it owns. The seat's output is checked against the contract, never against its tone. The seat's identity stays out of the filename, so that handing a role over changes a field rather than a path.",
                    boundary:
                        "A measured mistake is evidence and is kept in one place: it leaves a role document only by being moved to the one home history has. A mistake that is only expected never replaces one that was measured.",
                    cause: "A character is judged by how it sounds, and sounding right comes easily to a model even when the work underneath is wrong.",
                    decision: "A seat is defined by its contract rather than by its character.",
                    failureMode:
                        "The persona keeps its voice through the whole session and still drifts as much as a session with no persona at all.",
                    kind: "lesson",
                    principle: "For this reason I get consistency from checks rather than from roleplay.",
                    problem: "A persona gives a model a voice, and a voice is not a behaviour.",
                    validation:
                        "To check this, strip the voice from a session's output and check what remains against the contract. Whatever the voice was hiding becomes visible.",
                },
                {
                    kind: "text",
                    text: "A uniform shape is what makes a set of seats comparable. A reader looking for what a seat refuses finds it in the same place in every document; otherwise the documents are just prose filed together. The set of sections is the contract, and the declared fields are what a tool reads: the identity, the concern the seat holds, and the one line another seat uses to route work to it. The seat's identity is allocated and recorded before its first write, for the reasons coordination is software gives.",
                },
                {
                    kind: "text",
                    text: "The section that matters most is the one about what the seat gets wrong. A reviewer that approves a change because it reads well, a builder that reviews the description instead of the diff, and a coordinator that routes work a single edit would have closed are all measured mistakes. A seat is given its own document before its first edit so that it can avoid repeating them. A contract without that section is a job description, and a job description does not constrain the seat at all.",
                },
                { code: ROLE_TEMPLATE, kind: "code", language: MARKDOWN_LANGUAGE, title: "a role document" },
            ],
            title: "Contract over character",
        },
    ],
    title: "A seat is a contract",
};

const POLICY_SKELETON =
    "# <the stance and the hard prohibitions>\n\nA claim about the tree is unverified until the tree is read. Review is adversarial by default. Every manual step is a failure of automation. A document states what is true now.\n\n# <what governs what, and the precedence>\n\nThe behaviour policy governs the agent. The codebase contract governs the code. A digest expands one rule and declares nothing. The tree outranks all of them, and a document that disagrees with the tree is corrected the same turn.\n\n# <what is read first>\n\nA blocker outranks everything and is read first. Then the board, whole. Then the seat's own role. Then the document whose domain the task enters.\n\n# <rules that bite every turn>\n\n- `read_before_claim`: a claim about a file is a lie until the file is read in this session · gate: conduct\n\n# <rules that fire on a matching task>\n\n- `rename_by_hand`: a move is done by hand, every reference enumerated before and verified after · gate: reference\n\n# <declared exceptions>\n\n- `question_is_blocked`: a pending question is a blocked state, never a third verdict\n\n# <how the work is verified>\n\nOne command runs every stage in order. It runs once per state, and its first output is read whole.\n\n# <the layers>\n\n<layer>: what it holds and what authority it carries, one line each.";

const COMPOSITION_DIAGRAM =
    'flowchart TB\n    subgraph resident["Resident · in force before the task is known"]\n        axiom["The axiom · the stance, the readings, the hard prohibitions"]\n        set["The document set · what governs what, and the precedence"]\n        startup["Startup · what is read first, and in which order"]\n        always["Rules that bite every turn"]\n    end\n    subgraph referenced["Referenced · presupposes a known task"]\n        situational["Rules that fire on a matching task"]\n        exceptions["Declared exceptions"]\n        verify["How the work is verified · one chain"]\n        tooling["How the tree is looked at"]\n        notes["What the tree is"]\n        digests["Digests · one concern each, expanding a rule"]\n    end\n    test{"Does it tell you how to find out what you are doing?"}\n    test -- yes --> resident\n    test -- no --> referenced\n    axiom --> set --> startup --> always\n    situational --> exceptions --> verify --> tooling --> notes\n    resident -- delivery order --> referenced\n    situational -. needs room .-> digests';

const PORTABILITY_DIAGRAM =
    'flowchart TB\n    policy["The behaviour document"]\n    operations["Semantic operations · discover, read, search, analyse, execute, persist, report"]\n    slots["Slots · the gate, the rule host, the test root, the depth cap"]\n    binding["One binding per harness"]\n    toolsA["Harness A · its tools, its file name"]\n    toolsB["Harness B · its tools, its file name"]\n    model["The model · an absent slot by construction"]\n    policy --> operations --> binding\n    policy --> slots --> binding\n    binding --> toolsA\n    binding --> toolsB\n    policy -. names nothing about .-> model';

const DELIVERY_DIAGRAM =
    'flowchart TB\n    doc["The behaviour document · delivered once, at startup"]\n    seat["A seat"]\n    bounded["A bounded invocation"]\n    board["The board · delivered whole every round"]\n    line["One projection line · the only board it ever sees"]\n    invert["Turn-owning rules invert · returning is its contract"]\n    routed["A change to the document is routed to the running parties"]\n    doc --> seat --> board\n    doc --> bounded --> line\n    bounded --> invert\n    doc -. an edit mid-session does not reach running parties .-> routed';

const POLICY_SECTION: Section = {
    icon: POLICY_SECTION_ICON,
    id: POLICY_SECTION_ID,
    intro: "The behaviour policy is the system prompt of the collaboration, whatever file name the harness uses for it. It is the one document delivered to every session at startup, so it carries what has to be in force before the model knows what task it is on, and it points to everything else. The order of its parts is shown in <cite>a behaviour document</cite> and <cite>delivery order</cite>. It is written the same way for any harness and any model, because nothing in it names a tool: it names operations and slots, and a single binding says which tool performs each one, which applies platform independence to a prompt, as shown in <cite>one binding per harness</cite>. What each kind of reader receives is shown in <cite>reader classes</cite>. The document is the behavioural form among the three encodings, and document structure on the grammar page applies the same rule to a single document: declare first, then instruct.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, it opens with the stance and the hard prohibitions, because those apply before the task is known. Next comes what to read first and in which order, then the rules that apply every turn, then the ones that apply to particular tasks, then the declared exceptions. How the work is verified, how the tree is inspected and what the tree contains come after the rules, because each of them assumes a task. Anything that needs more room is moved into a digest the document points to. No tool is named anywhere: the document names the operation, and the binding decides which tool performs it.",
                    boundary:
                        "The document is delivered once to each reader, so a change to it does not reach a session that is already running. A rule edited mid-session reaches only the parties that start afterwards, which is why a governing change is also sent as a message to the parties already running, since messages reach them every round and the file does not.",
                    cause: "A document delivered in one piece has no structure that marks what must be in force from the start and what can be looked up later, so every line competes for the same attention and the order is simply the order it was written in.",
                    decision:
                        "The document is arranged by precedence and kept free of anything specific to one harness, rather than grown in the order rules happened to arrive.",
                    failureMode:
                        "The document grows by appending, every session opens on a wall of prose, the first rules get attention and the last ones barely any, and the same correction is added a fourth time at the bottom.",
                    kind: "lesson",
                    principle:
                        "For this reason I give the behaviour document a deliberate composition: what must be in force from the start comes first, the delivery order follows the order of precedence, and anything that only matters once the task is known is referred to rather than included.",
                    problem:
                        "A prompt written as one long instruction document is delivered once at startup to a model that will lose track of most of it, and nothing in its shape says which parts matter most.",
                    validation:
                        "To check this, rename the file to what another harness expects and give it to a different model. Where it breaks, a tool name or a path has leaked into a place that should hold a slot; where it holds, the composition has transferred.",
                },
                { code: POLICY_SKELETON, kind: "code", language: MARKDOWN_LANGUAGE, title: "a behaviour document" },
            ],
            title: "A system prompt with a composition",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: "One question decides where a part of the document goes. If it tells the model how to find out what it is doing, it belongs at the top, in the order it applies. If it tells the model what to do once it knows, it goes further down or into a digest the top points to. How often a rule applies is a poor guide: a rule that applies every hour but assumes a known task can safely be referred to, while a rule that applies once a month but decides which document to open belongs at the top.",
                },
                { caption: "delivery order", kind: "mermaid", text: COMPOSITION_DIAGRAM },
            ],
            title: "Resident, then referenced",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: "The document is a claim like any other, and the stance applies to it: the model is asked to re-read it whenever it enters the context, because a version held in memory is only a memory, and it gives way to the tree in the order three encodings sets out.",
                },
                {
                    kind: "text",
                    text: "It states what is true now and never what used to be, as derived state requires of every document. Copying a sentence from one document into another is how a dead reference spreads, so each fact has a single source of truth and the other documents point to it, which documentation is code turns into a check. The whole set of documents is validated, each kind against its declared shape, and a document that does not match its shape fails before it is delivered.",
                },
            ],
            title: "The document is a claim",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: "Portability follows from what the document is allowed to say. It states what to do as semantic operations, such as discovering resources, reading a resource, searching content, analysing, running a tool, saving an artifact and reporting a result, the same rule stated under semantic operations on the grammar page. It states where things are as slots, such as the gate, the rule host, the test root and the depth cap. One binding per harness maps each operation to that harness's tool and each slot to that tree's value, which is configuration externalization applied to a prompt. Moving the document to a harness that expects a different file name therefore takes a rename and one binding, and the rules do not change. The model is deliberately left as an empty slot, because choosing the model belongs to the harness, and a value written into that slot would have no source.",
                },
                {
                    kind: "text",
                    text: "A set of rules meant for use in other projects is written as a block that a host project copies into its own document, rather than merging it. Where the host's rule and the block's rule collide on the same thing, the host's rule wins, and the collision is treated as a finding rather than a negotiation. Every path in the block is relative to one value the adopting project sets, and the only literal path that remains is the import a runtime resolves, because a runtime reading a path has no binding to consult.",
                },
                { caption: "one binding per harness", kind: "mermaid", text: PORTABILITY_DIAGRAM },
            ],
            title: "Operations and slots",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: "Who receives the document decides which of its rules apply, and the document states which kind of reader each rule applies to, rather than leaving the reader to decide; coordination is software explains where the two kinds of reader come from. The single line a bounded reader receives is updated in the same change as the fact it carries and kept under a size limit, because a summary that keeps growing under an update rule with no stated limit turns into the document's own clutter.",
                },
                { caption: "reader classes", kind: "mermaid", text: DELIVERY_DIAGRAM },
            ],
            title: "Who receives it",
        },
        {
            blocks: [
                {
                    kind: "text",
                    text: "The document grows only in the shape rules with names describes, and when a rule has had to be stated twice for the same kind of problem, it becomes a check that the line points to.",
                },
                {
                    kind: "text",
                    text: "The document repeats nothing the codebase contract owns, and the contract repeats nothing the document owns; a reader who finds the same fact in both has found a copy that neither the developer nor the model maintains.",
                },
            ],
            title: "How it grows",
        },
    ],
    title: "The behaviour document",
};

export const RULE_SECTIONS: readonly Section[] = [MECHANISM_SECTION, RULE_SECTION, CONTRACT_SECTION, POLICY_SECTION];
```
