# configuration/strings/release.strings.ts

> 144 lines of code and 9 definitions.

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

## Definitions

- `STAGE_SHAPE` (lexical_declaration, line 7)
- `CHAIN_DIAGRAM` (lexical_declaration, line 10)
- `NARROWING_DIAGRAM` (lexical_declaration, line 13)
- `SCALE_DIAGRAM` (lexical_declaration, line 16)
- `DEPLOY_DIAGRAM` (lexical_declaration, line 19)
- `CHAIN_SECTION` (lexical_declaration, line 22)
- `SCALE_SECTION` (lexical_declaration, line 72)
- `DEPLOY_SECTION` (lexical_declaration, line 112)
- `RELEASE_SECTIONS` (lexical_declaration, line 147, exported)

## Source

```typescript
import { CHAIN_SECTION_ICON, DEPLOY_SECTION_ICON, SCALE_SECTION_ICON } from "#configuration/icons/release.icons";
import { CHAIN_SECTION_ID, DEPLOY_SECTION_ID, SCALE_SECTION_ID } from "#core/ids/release.ids";
import { GAP_SECTION, RETIRED_SECTION } from "#configuration/strings/release.fragment.strings";
import type { Section } from "#types/document.types";
import { TYPESCRIPT_LANGUAGE } from "#configuration/constants/code.constants";

const STAGE_SHAPE =
    'export const STAGE_SLUGS = ["<stage>", "<stage>", "<stage>"] as const;\nexport type StageSlug = (typeof STAGE_SLUGS)[number];\n\nexport interface Member {\n    readonly id: string;\n    readonly dir: string;\n    readonly gated: boolean;\n    readonly tests: string | null;\n}\n\nexport interface Step {\n    readonly label: string;\n    readonly command: readonly string[];\n    readonly scope: "wide" | "perMember" | "appOnly";\n    readonly tags: readonly ("generate" | "validate" | "build")[];\n    readonly produces?: string;\n    readonly consumes?: string;\n}\n\nexport interface Stage {\n    readonly slug: StageSlug;\n    readonly bypassedByDefault: boolean;\n    readonly parallel: boolean;\n    readonly steps: readonly Step[];\n}\n\nexport declare function stagesFor(scope: { readonly members: readonly Member[]; readonly only?: string; readonly bypass?: readonly StageSlug[] }): readonly Stage[];';

const CHAIN_DIAGRAM =
    'flowchart TB\n    command["one command"]\n    rederive["the rule index is re-derived from disk before any stage"]\n    prepare["dependency integrity, one typecheck per member"]\n    unused["dead code, dead exports, dead dependencies"]\n    fixers["strip comments, rebuild the graph, run the rewriters"]\n    format["the formatter, fix on"]\n    lint["every linter, per member, fix on, reading the graph the fixers wrote"]\n    test["every suite, then the passing-test floor"]\n    build["the site, the diagrams, the chapters, every generator, every derivation"]\n    validate["discovery, leaks, graphs, configs, documents"]\n    report["the one aggregate · written on every exit"]\n    command --> rederive --> prepare --> unused --> fixers --> format --> lint --> test --> build --> validate --> report\n    prepare -. fail fast .-> report\n    lint -. fail fast .-> report\n    test -. fail fast .-> report';

const NARROWING_DIAGRAM =
    'flowchart TB\n    whole["No arguments · every stage, whole scope, healing on"]\n    member["A member · that member\'s steps, repo-wide steps reported as skipped"]\n    step["A step · only that step"]\n    bypass["A bypass · one stage skipped, local iteration only"]\n    claim["A completion claim"]\n    whole --> claim\n    member -. never satisfies .-> claim\n    step -. never satisfies .-> claim\n    bypass -. never satisfies .-> claim';

const SCALE_DIAGRAM =
    'flowchart TB\n    work["A body of work"]\n    partition["Partition it into concerns that must be able to contradict each other"]\n    floor["Floor · the number of concerns"]\n    fanin["Measure the fan-in on each shared surface"]\n    ceiling["Ceiling · the worst fan-in before claims stop surviving"]\n    count["The count · a choice inside the range, with the partition written down"]\n    work --> partition --> floor\n    partition --> fanin --> ceiling\n    floor --> count\n    ceiling --> count';

const DEPLOY_DIAGRAM =
    'flowchart TB\n    routes["The served routes"]\n    follow["Follow every path a text artefact names"]\n    reached["What a page can reach"]\n    prune["Delete everything else"]\n    backup["Back up what is live"]\n    upload["Upload the whole of what is left"]\n    check{"Healthy?"}\n    done["Live"]\n    restore["Restore the backup"]\n    routes --> follow --> reached --> prune --> backup --> upload --> check\n    check -- yes --> done\n    check -- no --> restore';

const CHAIN_SECTION: Section = {
    icon: CHAIN_SECTION_ICON,
    id: CHAIN_SECTION_ID,
    intro: "One command runs every tool in this method as a single gate, in stages typed as shown in <cite>a stage array</cite>. The stages form a pipeline architecture ordered by causal dependency, as shown in <cite>the stages</cite>, and each stage runs the checks, fixers, generators and validators it owns. A check that runs only when you or the model remember its command is a convention rather than a check. Arguments can narrow the chain while you iterate, but only the whole run supports a claim that the work is done, as shown in <cite>narrowing</cite>. The chain is what turns a collection of tools into a verdict, and the rule it serves is described in the gate holds the line.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, the project has one entry point whose default is the whole pipeline, and arguments can narrow it but never widen it. Its stages are ordered by what each one needs from the one before, and a dependency is stated wherever a step produces an artifact that another stage consumes. Every check, fixer, generator and validator sits in a stage as a direct call, never as an alias the gate shells out to. The aggregate report is written on every exit path, and the gate governs its own tooling with the same rules it applies to the code.",
                    boundary:
                        "Narrowing is only for speed while iterating locally. A member, a step or a bypass answers a question faster, but a claim that the work is done needs one whole-scope run with nothing bypassed. A narrowed run never overwrites the one aggregate, because a report about a narrower subject under the aggregate's name would describe a different subject under the same name.",
                    cause: "A tool outside the chain depends on a developer's memory, and memory is the one component in the system with no check on it.",
                    decision:
                        "Every tool is routed through the one entry point, rather than kept as a command of its own.",
                    failureMode:
                        "There are three linters, two of which have not been run since spring, and a formatter that runs on some machines only because of an editor plugin.",
                    kind: "lesson",
                    principle:
                        "For this reason every tool runs through one chain, because a tool reached only by its own command enforces nothing.",
                    problem: "Tooling accumulates as separate commands, and the commands stop getting run.",
                    validation:
                        "To check this, list every check the project claims to have and run the one command. Each check should appear in its output; one that does not is not a check the project has.",
                },
                {
                    kind: "text",
                    text: "The stage order encodes real dependencies, event ordering in the ontology's sense, so it carries weight rather than being tidy. A cleaning step runs before anything measures a file, and a type check runs before any structural check reads a tree that may not compile. The fixer stage writes the closure graph that the graph-aware rules read when they load, so it comes before linting, and a graph-aware rule fails closed when the graph is missing rather than passing over nothing. Several stages change the working tree, which is why an investigation never runs the gate, as described in agents as executed contracts.",
                },
                {
                    kind: "text",
                    text: "A registry the run consumes at load is derived again before anything loads it, so deleting a member cannot break the run that would have removed its entry. Deleting a rule is then one step, just as adding one is one dropped file. The chain also checks its own registration contract and the shape of every finding.",
                },
                {
                    kind: "text",
                    text: "Where a host project already has a toolchain, the chain hands off rather than duplicating it. The host chooses which concerns to hand over, its tools stay its own, and there is one chain instead of two. A verification slot the host cannot fill, such as a build, a runtime probe or a size cap, resolves as absent. The step that reads it does not run, and the claim it would have settled is carried as observed by the developer rather than as verified.",
                },
                {
                    kind: "text",
                    text: "The chain is data before it is a run. A pure planner takes the resolved scope, meaning which members, which step and which bypasses, and returns the stage array, and the runner walks that array in order, with any order that carries weight stated on the step rather than remembered. A member with no tests declares null rather than an empty string, because the two are different claims. Everything a stage-control flag can do is a function over this data, and no flag can add a step that the array does not hold.",
                },
                { code: STAGE_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a stage array" },
                { caption: "the stages", kind: "mermaid", text: CHAIN_DIAGRAM },
                { caption: "narrowing", kind: "mermaid", text: NARROWING_DIAGRAM },
            ],
            title: "Everything through one chain",
        },
    ],
    title: "One chain",
};

const SCALE_SECTION: Section = {
    icon: SCALE_SECTION_ICON,
    id: SCALE_SECTION_ID,
    intro: "How many parties a body of work needs is not a matter of choice. The count follows from how the work divides into concerns that must be able to contradict each other. The floor is the number of those concerns, and the ceiling is set by the worst fan-in, the point at which claims resting on one surface stop surviving; <cite>floor, ceiling, count</cite> shows where each comes from. The architecture page derives the same range for a system, as described in a concern is a component and the ceiling moves by cost.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, the work is first divided into concerns, and counting them gives the floor. The fan-in on each shared surface is measured from the traffic the surface already records, which gives the ceiling. A count is then chosen inside that range, and the partition it came from is written down.",
                    boundary:
                        "Volume is the wrong input, as described in a concern is a component; the fan-in caps a small task and a large one alike.",
                    cause: "A count chosen independently of the partition either leaves a concern with no owner or gives one surface more claims than it can hold.",
                    decision: "The work is partitioned first and counted second.",
                    failureMode:
                        "Five agents work on a task that has two concerns, three of them wait, and the surface they all write to becomes the bottleneck.",
                    kind: "lesson",
                    principle:
                        "For this reason the number of parties follows from the structure of the work rather than from a preference.",
                    problem:
                        "The number of agents or people on a task comes from a preference, and a preferred number is wrong in one of two directions.",
                    validation:
                        "To check this, ask what partition the current count came from. A count with no partition behind it is a preference, and the fan-in will expose it.",
                },
                {
                    kind: "text",
                    text: "With fewer parties than the floor, one concern has no owner, so it is decided by whichever party happens to be nearest, which is the substitution every other chapter refuses. With more parties than the ceiling, the shared surface becomes the bottleneck: a claim is more often stale by the time it lands than it is read, and the parties spend their rounds re-deriving each other's reads.",
                },
                {
                    kind: "text",
                    text: "The argument is carried on the architecture page in scale follows determinism. A deterministic check returns the same verdict whoever runs it, so adding a party adds no enforcement cost, and that is why every coordination rule here is either a mechanism or a declared piece of conduct with its evidence written down.",
                },
                { caption: "floor, ceiling, count", kind: "mermaid", text: SCALE_DIAGRAM },
            ],
            title: "Floor and ceiling",
        },
    ],
    title: "Scale follows from structure",
};

const DEPLOY_SECTION: Section = {
    icon: DEPLOY_SECTION_ICON,
    id: DEPLOY_SECTION_ID,
    intro: "The deployable is derived from the routes the site serves, as shown in <cite>routes to site</cite>. The deploy is a file operation with a rollback, and it never touches a process it does not own, which is least privilege applied to a deploy. Secrets management keeps every secret outside the tree. Every served surface uses encryption in transit, including the local development server, because environment parity means development exercises the same transport as production; otherwise it exercises something else.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, the deploy starts from the served routes and follows every path a text artefact names. Every file that nothing reaches is deleted, and the whole of what is left is uploaded. One backup is kept of what is replaced, and it is restored on any failure. A command that touches a shared machine is handed to the developer who owns that machine rather than run, and every secret stays in the one artifact declared to hold it.",
                    boundary:
                        "On a machine that hosts other people's processes, nothing beyond your own files is touched. The deploy is a file operation because a file operation can be rolled back, while a process operation has a blast radius.",
                    cause: "Nothing between the build and the upload asks whether a file is reachable.",
                    decision:
                        "The deployable is pruned from the routes rather than taken from the build folder on trust, and a file operation is chosen over a process operation for its rollback.",
                    failureMode:
                        "A page fails to pre-render, and nothing reports it because the old file is still in the build folder, so the stale page ships.",
                    kind: "lesson",
                    principle: "For this reason the deployable is whatever a page can reach.",
                    problem: "A deploy that ships a build folder ships whatever happened to be in it.",
                    validation:
                        "To check this, list every file in the deployable and the route that reaches it. A file that no route reaches is one the discovery check should have refused.",
                },
                {
                    kind: "text",
                    text: "A discovery check derives, from the same registry the build reads, every route a page can serve and every file a route reaches. It fails the build on a route with no rendered file, a payload a machine cannot parse, or a file that nothing reaches, so the problem is found before a deploy rather than after.",
                },
                { caption: "routes to site", kind: "mermaid", text: DEPLOY_DIAGRAM },
            ],
            title: "Derived from the routes",
        },
    ],
    title: "The deploy is a file operation",
};

export const RELEASE_SECTIONS: readonly Section[] = [
    CHAIN_SECTION,
    SCALE_SECTION,
    DEPLOY_SECTION,
    RETIRED_SECTION,
    GAP_SECTION,
];
```
