# One chain

> One command runs every tool in this method as a single gate, in stages typed as shown in a stage array].

Page: Methodology · Ship
Canonical: https://banes-lab.com/disciplined-methodology/ship#one-chain

This section is stop 92 of 102 in the learning route. Previous: [05 - Agent templates](https://banes-lab.com/pag/templates/templates-agents.md). Next: [44 - Scale follows from structure](https://banes-lab.com/disciplined-methodology/ship/scale-follows-from-structure.md). It builds on [18 - The gate holds the line](https://banes-lab.com/disciplined-methodology/build/the-gate-holds-the-line.md).

One command runs every tool in this method as a single gate, in stages typed as shown in [A1·a a stage array](https://banes-lab.com/disciplined-methodology/ship#one-chain-panel-a). The stages form a [pipeline architecture](https://banes-lab.com/records/arch/pipeline-architecture.md) ordered by [causal dependency](https://banes-lab.com/records/arch/causal-dependency.md), as shown in [A1·b the stages](https://banes-lab.com/disciplined-methodology/ship#one-chain-panel-b), 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 [A1·c narrowing](https://banes-lab.com/disciplined-methodology/ship#one-chain-panel-c). 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](https://banes-lab.com/disciplined-methodology/build/the-gate-holds-the-line.md).

### Everything through one chain

Tooling accumulates as separate commands, and the commands stop getting run. 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. 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.

For this reason every tool runs through one chain, because a tool reached only by its own command enforces nothing. Every tool is routed through the one entry point, rather than kept as a command of its own. 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.

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. 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.

The stage order encodes real dependencies, [event ordering](https://banes-lab.com/records/arch/event-ordering.md) 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](https://banes-lab.com/disciplined-methodology/collaborate/agents-as-executed-contracts.md).

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.

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](https://banes-lab.com/records/arch/verification.md) 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.

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.

A1·a a stage array

```typescript
export const STAGE_SLUGS = ["<stage>", "<stage>", "<stage>"] as const;
export type StageSlug = (typeof STAGE_SLUGS)[number];

export interface Member {
readonly id: string;
readonly dir: string;
readonly gated: boolean;
readonly tests: string | null;
}

export interface Step {
readonly label: string;
readonly command: readonly string[];
readonly scope: "wide" | "perMember" | "appOnly";
readonly tags: readonly ("generate" | "validate" | "build")[];
readonly produces?: string;
readonly consumes?: string;
}

export interface Stage {
readonly slug: StageSlug;
readonly bypassedByDefault: boolean;
readonly parallel: boolean;
readonly steps: readonly Step[];
}

export declare function stagesFor(scope: { readonly members: readonly Member[]; readonly only?: string; readonly bypass?: readonly StageSlug[] }): readonly Stage[];
```

A1·b the stages

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

A1·c narrowing

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

## Links to

- [Pipeline Architecture](https://banes-lab.com/records/arch/pipeline-architecture.md)
- [Causal Dependency](https://banes-lab.com/records/arch/causal-dependency.md)
- [The gate holds the line](https://banes-lab.com/disciplined-methodology/build/the-gate-holds-the-line.md)
- [Event Ordering](https://banes-lab.com/records/arch/event-ordering.md)
- [Agents as executed contracts](https://banes-lab.com/disciplined-methodology/collaborate/agents-as-executed-contracts.md)
- [Verification](https://banes-lab.com/records/arch/verification.md)

## Linked from

- [Three encodings](https://banes-lab.com/disciplined-methodology/start/three-encodings.md)
- [Tools live in the tree](https://banes-lab.com/disciplined-methodology/build/tools-live-in-the-tree.md)
