nw-cross-cutting-invariants · git:20261102.c67d57b · 2026-11-02 · sha256 5716448d7f308811
nw-cross-cutting-invariants git:20261102.c67d57bA
Immutable. This exact content never changes and is served at /api/v1/blob/5716448d7f308811.
---
name: nw-cross-cutting-invariants
description: Cross-cutting normative invariants — routing core for the software/model boundary doctrine, gate/construction principles and on-demand knowledge lenses. Cite clause ids; never re-declare.
user-invocable: false
disable-model-invocation: true
---
# Cross-Cutting Invariants — Recomposition Core
Normative rules hold regardless of paradigm and role. `nw-cross-cutting-invariants` is their
SHIPPED public home: cite a clause id; do not re-declare it. This core owns global
gate/construction doctrine and routes independent KNOWLEDGE lenses; load every applicable lens.
**Reachability precondition.** A pointer works only when the consumer actually loads its referent.
Check what the consumer really loads, not what it ought to; otherwise self-contain the bounded rule.
Cite skills by **NAME**, never vendor filesystem path: a path is a GDP-8 designation that can dangle
on another host.
> **Known correct exception — reviewer family.** The 22 `*-reviewer` agents have no common narrow
> skill; their absence-is-a-claim rule is deliberately inlined. Do not replace it with a dangling
> pointer.
| Phase | Load | Trigger |
|---|---|---|
| Gate or construction design | this core | designing a gate, oracle, error surface, restriction, or a construction alternative |
| Context residency | `nw-cross-cutting-context-residency` | choosing resident versus on-demand context, or repairing compensation prose |
| Evidence and instrumentation | `nw-cross-cutting-evidence-instrumentation` | asserting from a measurement, demonstrating a check, or repairing a misleading instrument/count |
| Input and data contracts | `nw-cross-cutting-input-data-contracts` | adding data, declaring inputs, choosing a join key, or diagnosing ambient reads |
| Test time and test location | this core (`test:feedback-loop-budget`) | declaring test budgets, requesting a feature derogation, writing or reviewing a test, placing an infrastructure test, or a default CI suite over its ceiling |
| Design simplicity | this core (`design:simplest-design-that-delivers`) | making or reviewing a design decision, receiving a new requirement or owner answer |
The lenses are independent KNOWLEDGE: no forced sequence and no artificial precedence. A compound
task loads multiple lenses; return here only to route the next concern.
## `delivery:trustworthy-baseline-and-repair-scope` — preserve the safety net without expanding the request
Before product changes, is the required verification trustworthy for the current
source and relevant environment? Establish a baseline or reuse applicable evidence;
check known local/CI differences early. Follow the project's required checks, not a
new full-suite run per slice. Pause affected product changes when that safety basis
is broken; independent work needs its own unaffected basis.
Does a failure demonstrate the agreed missing behavior? Expected ATDD RED, including
an existing reproduction of the requested bug, permits implementation when execution
reaches the intended behavioral assertion and the other required checks remain
trustworthy. Collection, setup and incidental failures are not that RED. The expected
failure must become GREEN before completion.
Before buying a repair turn, does the intervention satisfy an agreed outcome, restore
a regression caused by this request's work, or restore its required safety net?
State that connection, observed failure, intervention limit and expected proof in the
existing dispatch. Proportionate reversible setup, capture helpers and diagnostic
execution already implied by the request need no repeated approval. Missing evidence
alone does not establish a product defect. A defect's age alone never decides scope.
If pertinence or cause is unknown, choose the smallest useful discriminator before
repairing. Another attempt needs new evidence, a changed falsifiable hypothesis, or a
materially different experiment that can obtain the named missing fact; name which
outcome would change the next decision. Otherwise retain the affected blocker and
uncertainty instead of repeating an inconclusive attempt.
Keep responsibility for regressions caused by preparation and previous repairs too;
prefer the smallest restoration, preserving others' work. A newly discovered defect
does not inherit repair authority merely from its discovery. Independent redesign,
broad migration or new behavior outside the request requires an explicit scope/priority
decision with concrete evidence. Reuse existing authorization for routine delivery work.
Do not silently absorb unrelated improvements or claim a blocked delivery complete.
Is the required check itself wrong? Its owner may correct the harness or assertion
while preserving the agreed property and counterexample. Skipping a required check,
weakening its property, or relabeling its failure as optional is not restoration.
Report independent defects without silently fixing or dismissing them. Review notes
are not automatic same-slice work. The LLM chooses the action; this clause adds no
controller, runtime gate, mandatory artifact or guarantee of termination.
## `flow:findings-go-to-the-owner-directly` — remove the host relay, not artifact ownership
Is a finding going to the artifact owner, or through a host that only forwards it?
For roles on the same Request, send it directly to the owner: crafter ↔ acceptance
designer for oracle mismatches; crafter or acceptance designer → architect for a
design question or ruling; reviewer → artifact owner for completed findings;
any role → product owner for a product question. Include the location
(`file:line` or fact id), the relevant authority fact and observation, or the
missing/ambiguous authority and precise question.
Does direct contact change who may edit? Keep authorship with the owner: the
crafter never edits tests, the acceptance designer never edits production code,
only the architect changes design facts, and reviewers never repair. Send
completed reviewer findings regardless of repair authorization; apply
`delivery:trustworthy-baseline-and-repair-scope` before acting on them.
The channel moves findings, not authority.
Do related callers, supports and docs need a root permission per file? Within the approved
behavior, the owners of the affected artifacts agree the edits directly. Each path has one
writer, named by its owner; an owner edits only the paths its semantic domain owns. An
existing declared target changes through its actual authority owner. A peer that needs
another domain's path asks that owner directly; no owner takes it silently.
Would contact influence an independent assessment? Keep examiner input on its
existing sealed-packet route: no producer-to-examiner contact. Do not let
producers influence an ongoing independent review. Completed reviewer findings
may travel outward to their owners, never open a reverse evidence channel.
Preserve each role's tool, independence and evidence limits.
Does the finding need a human scope/trade-off decision, a change of approved behavior, or a
disagreement the two roles cannot settle with an authority fact? Escalate only those cases to
the host. Ordinary related-file coordination within the approved behavior is not escalation:
resolve it directly with the owners and tell the host the outcome in one line. Existing
host/project lifecycle and integration ownership are unchanged.
Does the host support agent-to-agent messaging? At dispatch, enable permitted contacts. In
each relevant role's task, name the peer's address and include: "Send findings on <artifact>
directly to <owner address>; coordinate related caller, support and doc edits directly with
their owners within the approved behavior; owners alone edit their paths; escalate only human
scope/trade-off questions, scope changes or unsettled disagreements to the host." Supply this
instruction even when no resident skill points here; preserve the independent-assessment
exclusions above. Only when native send is genuinely absent, not merely unverified,
unauthenticated or failing, give the existing host return route and forward the finding
verbatim without interpretation. Unknown availability is not absence: report it as
indeterminate and do not switch to the host route. Use existing host capabilities; invent no
messaging mechanism, ledger, gate or command.
**Why:** each relay hop adds a queue and waiting time; removing an intermediate
step with no added value cuts lead time. Under ToC, the host is the shared
constraint: do not spend its capacity on forwarding.
**Falsifier:** where the role's independence/evidence boundary permits direct contact and
messaging is available, an in-scope finding that the two roles can settle from an authority
fact waits for host relay, or a related change inside the approved behavior waits for a root
per-file permission its owners could settle directly; or direct contact lets a non-owner edit
the artifact or contaminates an independent assessment.
## `construction:design-paradigm-projection` — DESIGN owns the crafter paradigm
Before handing a supported durable DESIGN authority to DISTILL, supply its
established `functional`, `object_oriented` or `procedural` decision in the
current design facts consumed by downstream roles.
Specialized domain, system and platform roles preserve
that application authority; root and ATD neither retype nor infer it. Absent or
contested authority returns to `nw-design`/solution architecture, never defaults
to OO. An evidenced imperative transaction script is `procedural`, not FP merely
because it exposes functions.
A settled paradigm outside those three supported values is a representation gap
in the current closed input, not a missing human choice. Preserve its truth,
identify the affected paradigm-dependent handoff, and continue independent
semantic work. Do not submit an unsupported enum, relabel it, force classes, or
claim the constructor accepted it. Report that bounded gap to the caller; this
rule changes neither the software schema nor the established paradigm.
## `gate:self-explaining-what-why-how` — gate and error surfaces state WHAT / WHY / HOW (STANDING)
Every gate, contract check, or error surface you design MUST, on rejection, state **WHAT**
failed (the specific invariant), **WHY** (the cause), and **HOW** to fix (the concrete
remediation, routing to the producing tool that makes the artifact valid). A gate whose
rejection is a bare `FAILED` / exit-code forces the operator to investigate — that is a
DESIGN defect, not an implementation detail. Design the self-explaining surface IN, and put
the affordance inline at the authoring point, not only in the reactive rejection (GDP-3 /
GDP-4 / GDP-2).
---
## `boundary:software-measures-model-decides` — the control plane measures, constructs and enacts; it never decides on the model's behalf (STANDING, Ale 2026-09-04 — FOUNDATIONAL)
Upstream of every gate principle below: it decides whether a piece of logic belongs in
the software at all, before GDP-0 asks how to build it.
**A PRIMITIVE observation can be incomplete, but it cannot be wrong. Anything DERIVED
from one can be wrong.** The columns below recur; they are not exhaustive.
- **Software owns PRIMITIVE MEASUREMENT.** Workspace bytes before and after a turn, a
hash, an exit status and captured output, file existence, Git state, the tree identity
of the running projection. These never lie; at worst they are incomplete, and
incompleteness degrades LOUD as `INDETERMINATE`, never filled in. The DERIVATION is where
the lie enters: that an oracle FILE EXISTS is primitive, that the oracle is therefore
GREEN is derived and wrong, and a route taken on the first decides on a DESIGNATION.
GDP-8 is that defect's home, not this clause.
- **A DERIVED measurement declares its PROVENANCE and degrades `INDETERMINATE`.** A call
graph, an index query, an attribution, a computed scope: each is a claim about a
COMPUTATION, so it names its producer and returns the third state when that producer
did not resolve — never a confident answer wearing a primitive one's clothes. Anchor
(2026-09-04): `code-fact query.callers-of` answered an EMPTY site list at
`confidence: binding-resolved` for a symbol with four real callers — `defects.md`, row
`code-fact-port-answers-false-with-highest-confidence`.
- **Software owns CONSTRUCTION.** The handover emitted correct-by-construction because
the CLI call REQUIRES its parameters; the bound stated to the model instead of tested
after the paid turn. The CLI augments the model where it is weak — consistent formal
bytes — never constrains it where it is strong.
- **Software owns an explicitly invoked mechanical effect.** Code that writes a bound
document, records typed facts, or applies a named mutation can hit the wrong target
without being a judgement. nwdes constructs and persists the canonical handoff
and generated documents; it chooses no delivery path or next operation.
- **The LLM owns semantic decision and orchestration.** It exclusively chooses or revises
SML, waves, feature/bugfix and upstream rework, stop/resume/retry, and which invocation
runs next. It still retains every required independent review, EXAMINE and quality
obligation; ownership never authorizes skipping them.
- **The test for a software-owned effect:** apply this only to construction,
measurement, and explicitly invoked mechanical or safety effects. The enumerated
LLM orchestration choices remain LLM-owned regardless of their computability.
*Does an authority give a criterion DECIDABLE over
facts the software ALREADY HOLDS, with no semantic judgement left?* If yes, the decision
stays in the software even when the term SOUNDS semantic — `ProductCorrectionNoProgress`
implements ADR-SSOT-002's decidable definition of progress, «Progress is the distinct
graph, non-increasing suffix cardinality and consumption of this position's sole live-run
correction edge». COUNTEREXAMPLE, and the half that decidability alone does not catch:
`_comparable` decided overlap over DECLARED targets — the model's claim about what it
would touch. That criterion is decidable, but it decides over a DESIGNATION, and a claim
about the future is derived from nothing at all, so the verdict was a surrogate.
ADR-SSOT-002 PRESCRIBES replacing it with the overlap MEASURED from the bytes each turn
actually wrote, taken as the Git diff between consecutive turn commits — a measurement
that does not exist yet and is owed, not one already in place. Ask therefore not only
whether the criterion is decidable, but WHAT it decides over. If the authority offers
only a surrogate, make the AUTHORITY decidable; do not exile the decision. A THIRD exit
is legitimate and that ADR's 2026-09-04 amendment takes it twice: DISSOLVE the decision,
when the boundary that required it no longer exists. Only then — never to avoid deciding
a question that still stands. The boundary must never be a function of the ADR's PROSE,
or rewriting one sentence migrates a decision while no code changes.
- **Scope of the exclusion.** "It can be wrong and is no semantic judgement, so keep it
out of the control plane" binds only what the software DERIVES FROM THE OUTPUT OF A PAID
TURN — only there is there a semantic owner to hand the observation to.
- **A rejection for FORM bills the model for the software's own omission (corollary).**
The model owns meaning, so a refusal is legitimate only where the model got the MEANING
wrong. Everything else about rejections is already stated: cite GDP-0, GDP-2's emission
corollary, GDP-3 and GDP-5 instead of restating them, and a removal still owes GDP-10's
adversarial challenge.
- **Consequence for design.** The LLM decides sequence, resume, split, upstream
rework, stop and the next invocation. Artifact construction has no workflow
authority and runs no models or verification commands.
The host retains native checks, independent review and user-perspective EXAMINE.
**Falsifier:** the builder autonomously selects/composes delivery steps, or a
generated prompt is treated as software authorization to skip required review.
- **Anchor (2026-09-04, early delivery runs).** Five blocks were
found by RUNNING deliveries, none by inspection or by the suite; two were asserted as
EXPECTED behaviour by green tests, and across those runs the primitive measurement layer
never lied once. They are THREE classes, and only one is this boundary. **Infidelity to
a decidable ADR criterion** — empty suffix conflated with unchanged; overlap judged over
every member pair where the ADR says incomparable roots plus a separate ordered overlap;
and the route derived from whether the oracle FILE EXISTS, with the candidate built from
the current working-tree bytes for the declared paths, which skipped craft twice. That
third one was first recorded as "a crafter answering `accepted` and writing nothing"; a
probe on 2026-09-04 REFUTED that reading — the crafter was never invoked at all — and the
diagnosis stated here is the corrected one.
**A correct measurement not surfaced, or not degraded LOUD** — ONE empty owner set,
correctly refused in a message that omitted a fact the runner already held (GDP-3's
omission corollary), behind a comparison consumed half-way whose fix explicitly DECLINED
to refuse at the turn. That is one block seen from two angles, not two. **One boundary
instance** — scope attribution, where the runner inferred the WRITER from bytes, no
authority makes that inference decidable, remedied by a three-state observation carrying
`INDETERMINATE`.
- **Anchor (2026-09-05/06, why sequence moved).** Run 24 returned `Success` and integrated
`108133478` with `src/` untouched: only a test stand-in and the new oracle changed, the real
command the Request named still answered wrongly, and every role was coherent with a design
incoherent with the world. On 2026-09-06 the automatic delivery orchestrator
was retired; sequencing stays with the LLM, not the builder.
---
## `construction:llm-writes-values-cli-builds-form` — LLMs analyse and write values; the CLI builds the form (STANDING, Ale 2026-10-20 — evolution of GDP-0)
GDP-0 says to change the producer, not to add a gate. When the author is an LLM, this clause
names the producer to change: the CLI the LLM calls. It outranks every validation-and-refusal
design.
**The split.** The LLM analyses and writes VALUES: free text, a choice among closed
alternatives, a reference to an identity the CLI already assigned. The CLI builds the FORM:
structure, keys, ids, numbering, filenames, paths, ordering, encoding and serialization. It
assembles the document from those values and reads its own templates, so the values always
arrive consistent and correct.
**Priority order for every builder design decision.** Use a later strategy only after the earlier
ones are exhausted, and say why the earlier ones cannot apply:
1. **Make the wrong state unrepresentable.** Choose the carrier so the defect cannot be built.
Examples: one list of records instead of parallel lists that must align; an identity that is
a key instead of a list position that can repeat; a required first element plus optional
others instead of a list that might be empty.
2. **Generate deterministically everything that can be generated, and keep that apart from the
LLM's activity.** Any value the CLI can compute from facts it already holds is the CLI's to
produce: next number, id, filename, path, scope taken from location, order, digest, packaged
asset. The LLM never sees it, copies it or emits it again.
3. **Make the LLM's activity a REQUIRED parameter on a CLI invocation.** Give each value one
typed parameter, a closed choice where the domain is closed, and make it required where the
value is required. The parser refuses an absent or misspelt value before any work, with a
generic usage error, not a bespoke check.
4. **Only then refuse at the boundary.** Some defects stay: external text on disk, or a reference
to state that does not exist. Report them all in one pass under `gate:reject-all-at-once`,
each explained per GDP-3, and record why the representation cannot change (GDP-0).
**Falsifiable test.** Ask: *is the model deciding semantic values, or manually
assembling formal authority structure that its producer could generate?*
If an LLM must choose keys, brackets, new ids, indices, filenames, ordering or
encoding for an authority record, that is a defect of the CLI, not of the LLM.
A refusal that catches such a defect is a GDP-2 gap. **Falsifier:** an input
grammar that has any role write JSON, YAML or Markdown authority structure,
or a refusal whose cause is a form the CLI could have built.
**Limits.** The CLI builds form and never chooses a value: which decisions belong to the model
is governed by `boundary:software-measures-model-decides`. A parameter that carries no value
the LLM decides is ceremony (GDP-10).
---
## `design:simplest-design-that-delivers` — the simplest complete design, not the next additive patch (STANDING, Ale 2026-10-20)
In the user's project, preserve every accepted outcome and constraint with the least necessary
conceptual, state and coordination burden. Fewer entities is a tie-breaker, not proof of simplicity.
**Questions + actions (GDP-9).** Apply inside existing design/review work; no new stage or ledger.
1. **[first principles] What must hold without the suggested mechanism?** State the outcome,
invariant and hard constraints; derive the mechanism, not requirements from existing machinery.
2. **[first principles / simple design] Who consumes this fact/effect, and what changes?** Keep
only required decisions, effects, invariant support or recovery/audit duties; investigate unknown consumers.
3. **[first principles / simple design] Can an existing carrier do it?** Reuse it unless meaning,
ownership, lifetime or access requires a distinction; do not conflate authorities to reduce types.
4. **[simple design] What knowledge does this boundary hide?** Prefer coherent deep interfaces;
remove pass-through layers and unrelated coupling.
5. **[first principles / simple design] Can the invalid state or failure distinction disappear?**
Apply GDP-0 and `construction:llm-writes-values-cli-builds-form`; preserve untrusted-input checks and real failures.
6. **[simple design] Same knowledge, or merely similar cases?** Share genuine policy; split a wrong
abstraction rather than append mode flags.
7. **[ToC] What demonstrably limits the system's goal?** Exploit/protect that constraint before
expanding machinery; justify other work by required risk, cost or lead-time benefit, not local utilization.
8. **[queueing / ToC] What waiting/rework does this coordination create or prevent?** Remove or
combine steps without distinct value; compare the whole path, retaining necessary independent authority.
9. **[queueing / ToC] What smallest complete batch yields useful feedback?** Limit WIP and transfer
usable slices without starving the constraint; balance setup cost against delay.
10. **[first principles / simple design / queueing / ToC] What can be deleted, merged, derived or
stopped?** After every requirement/owner answer and before handoff, reconsider the affected whole.
**Subtraction pass / falsifiable test.** At each consumer, which accepted obligation breaks on a
concrete input/state/trace without this element, or what greater whole-path burden does it remove?
Investigate unknowns; otherwise subtract and reconcile producers, consumers and prose. Preserve trust,
independent review and failure/recovery obligations; apply GDP-10's adversarial challenge before removing
existing constraints. Stop when further subtraction breaks an obligation or increases burden; use existing rationale.
**Smells:** redundant carrier/channel/brief section; readerless field; unreachable-state check (include
storage/version/ingress); unreferenced ID; mode flags; pass-through layer/ritual gate; full-batch feedback;
utilization as success. Investigate, not automatic deletion.
**Example falsifier:** a new type, field, verb, channel or check duplicates an existing carrier's
authoritative fact for every required reader, without naming its missing capability. This counterfactual
test is design reasoning, not executed verification.
**Sources (synthesis, not a proven universal metric):** Descartes; Brooks; Moseley/Marks; Beck/Jeffries;
Hickey; Ousterhout; Metz; Ockham; Saint-Exupéry; Adams et al.; Juvrud et al.; Little; Kingman;
Reinertsen; Goldratt.
---
## `test:feedback-loop-budget` — a user's tests are fast by design; extra test time exists only as a feature's human-granted derogation (STANDING, Ale 2026-10-20)
This is part of what nWave gives its users. In the user's project, the test suite is the team's feedback
loop: nWave optimizes quality, robustness and feedback-loop speed together, and trading one away needs a
human. Test time is a critical responsibility of the user's architect, acceptance designer and every
reviewer. Each of them measures it and never accepts a slow test on their own authority.
**Default budgets.** Every feature works within the project's default budgets:
- a wall-time budget per test, measured as setup, call and teardown, sequentially, on the user's CI
runner class;
- a property test's budget, scaling with its declared example count, which is never lowered to meet a
budget;
- each feature's share of the default CI suite;
- the default CI suite's ceiling, 300 s.
The design states the per-test and property budgets and the shares. A shared read-only world built once
per module may be exempt from the per-test budget only when the design says so; its build time counts
against the owning share. The defaults change only when the human asks, recorded as a repository-scoped
ADR.
**Judging a budget.** A test meets a per-test or property budget when the median of at least nine
sequential runs of it, each measured as setup, call and teardown, is at or under the budget and at most
one of those runs exceeds it. A median over the budget, or two or more runs over it on the same test, is
a defect; one run over it is a load spike, not a defect, because a worst-single-run rule fails a test at
random once its time plus an ordinary scheduler spike reaches the budget. Every timing receipt reports,
per test, the number of runs n, the median, the maximum and the machine load during the runs. A
different statistic is a default change: only the human sets it, recorded as a repository-scoped ADR.
**A permission is an ADR from a spoken request.** The human grants by asking. The role that heard the
request records it as an Accepted ADR in the user's repository: its context names who asked and when, its
decision states what is granted. Superseding that ADR changes the grant. No permission field,
configuration key or command exists. The architect, the acceptance designer and the reviewers propose;
they never grant. A per-run override of the default CI suite is the one grant recorded on its CI run
instead.
**Derogation is per feature.** A feature with no critical infrastructure path works within the defaults
and needs no permission, even when it touches infrastructure. A feature with critical infrastructure paths
asks the human for its additional budget. The request carries, as a proposal and not as a gate, one
risk/value record per proposed test:
- the failure mode;
- its formal source (the theorem, invariant, mutant or counterexample trace it comes from) or, when no
model covers it, the residual-risk fact that names it;
- the production blast radius;
- the expected time.
Once granted, the feature's ADR (scoped to that feature and cited by its design) is its derogation: its
infrastructure suite, that suite's trigger and total budget, and any per-test or share budget above the
defaults. The feature's acceptance designer, crafter and reviewers work within it; no per-test permission
exists.
**Local runs follow the delta.** A local run executes the tests that a reliable test-impact analysis
selects over the change: every test whose code reaches the changed code through its dependencies, static
or recorded. A test whose dependency the analysis cannot decide is selected. The full suite rarely runs
locally. When the selection is the whole suite, or local capacity forbids running it, the complete
selection runs in CI instead; it is never silently narrowed to fit, and the change stays unverified until
that run returns.
**The default CI suite: 300 s.** The default CI suite is the full end-to-end suite the user's CI gate runs
on every change. It finishes within **300 s** unless a repository ADR sets another ceiling.
- **An overrun fails the gate.** The failure states the measured time and the tests that consumed it.
- **Only a human override lets it pass.** A per-run override is recorded on that run, with that
measurement and the accepted risk, and leaves the ceiling unchanged.
- **An overrun triggers a review** of whether the component should be split into components whose suites
stay within the ceiling. It is a signal to review, not an automatic conclusion that the software does
too much: the review may instead find a slow test to fix, a world to share or a derogation to request.
- nWave never raises the ceiling or overrides an overrun on its own.
**Two levels, one law.**
1. **Executable projection, in the default suite.** Formal models (Quint, TLA+, Agda) and state machines
also describe effects and concurrency, so their laws are not in general properties of pure functions.
Every formal law therefore gets a fast **executable projection** on the pure core: the state machine or
transition function the model abstracts, run as a property or example in the default suite. This
includes the projected sad paths, such as a resumed interrupted operation, a rerun that converges or a
refused stale write.
2. **Adapter fault injection, in the feature's infrastructure suite.** Only real fault injection on
adapters covers what the projection abstracts away:
- storage down or full;
- a write interrupted between its steps;
- a double write on real storage;
- a crash mid-operation;
- concurrent writers;
- races the model abstracts.
An infrastructure test is never the only check of a law. A sad path that is a pure function, or that the
executable projection already covers, belongs in the default suite.
**The infrastructure suite.** The user's architect and acceptance designer MUST keep proposing sad-path
tests and properties of critical infrastructure, for robustness, resilience, reliability and performance,
inside the feature's derogation request. A granted feature's tests form a **feature-scoped infrastructure
suite** in the project's native test convention, such as a separate source set, test target, package or
tagged group. In a Python layout this is `tests/infrastructure/<feature>`, or `<feature test
root>/infrastructure` when the feature owns its own test root.
- It is excluded from the default local run and the default CI suite.
- It runs at the trigger its derogation declares, for example nightly or before a release, within the
derogation's total budget.
- The user may instead run it inside the default CI suite, where it counts against the ceiling.
- A feature without a granted derogation has no infrastructure suite.
**Falsifiable test.** Ask: *does any test exceed the defaults outside a granted feature derogation, does
any formal law lack an executable projection in the default suite, or did the default CI suite pass above
its ceiling without a recorded override?* Each is a defect of the design or oracle, not of the runner.
**Falsifier:**
- a test above the default budgets in a feature with no granted derogation, or above its derogation;
- a derogation, default or ceiling that changed without an ADR recording the human's request;
- an infrastructure suite in a feature with no derogation, or one that never runs;
- a pure-function sad path placed in the infrastructure suite;
- a default CI suite above its ceiling that passed without a recorded human override carrying the
measurement and the risk.
**Limits.**
- The clause sets who decides, the default ceiling, the granularity and where tests live. Each project's
design states its own numbers.
- Measurement uses the native toolchain's per-test timing. Nothing here names a runner or a library.
- A derogation the human refuses is not silently dropped. Its obligations return to the architect as a
design question: a different seam, a pure core, or a split component.
---
## `gate:design-principles-gdp-1-9` — Gate Design Principles GDP-0..10 (STANDING — canonical definitions)
The design contract EVERY gate, oracle, or error surface must satisfy. This skill is the
SHIPPED home of these definitions: everywhere else in the framework (skills, agents) that
cites "GDP-N" by number resolves against this list. Audit every gate you design against it;
a gap is a plan item to correct that gate. The clause id below retains its original
`gdp-1-9` suffix for citation stability (11+ existing citation sites across agents/skills/ADRs)
even though the list now runs from GDP-0 through GDP-10 — GDP-0 and GDP-10 have no heading of
their own; cite `gate:design-principles-gdp-1-9` for the whole list, GDP-0 and GDP-10 included.
- **GDP-0 — Representation before validation (STANDING, Ale 2026-08-19).** Gates are the LAST
RESORT, never the default. Before designing a gate, name the PRODUCER that made the wrong
state representable, and change IT so the state cannot be built: compile the mechanical
fields, give the author the check at the moment of authoring, type the invalid value away,
keep one writer for shared state. A gate is admitted only with a recorded reason why the
producer cannot change, and ships with a REMOVE falsifier; three checks landing on the same
artefact is the alarm to redesign the producer, not license to add a fourth check. Gates cost
wall-clock and tokens at EVERY run; a construction costs once. Anchor (2026-08-19, K4 runs
4-13): six dispatch validators were added in three days, each a symptom of the
acceptance designer hand-compiling fields the tree already derived — wall grew from 1886s to
4553s, and the validators also lied at the language boundary.
- **Formal-byte boundary.** If an LLM still authors formal bytes, a template, grammar, reviewer,
or validator is not construction: it checks after the wrong state was representable. Prefer one
deterministic sole-writer invocation that accepts semantic input and emits the formal bytes. A
deterministic constructor or compiler counts only when it replaces that LLM formal-byte
authorship; do not add a validator, grammar, compiler-as-gate, hook, test, mandatory artifact,
or runtime barrier through this rule.
- **GDP-1 — Intercept EARLY (timing).** Fire at the earliest point the defect is detectable —
BEFORE the effort it guards is spent and the value delivered. A gate that fires after
delivery only COMMENTS, it cannot prevent. Efficacy ladder: **proactive-inline ≫
reactive-before-completion ≫ advisory-after-completion**.
- **GDP-2 — Proactive INLINE affordance.** Only after GDP-0 admits a reactive gate, pair it with
guidance inline at the authoring surface, so the block is rarely reached — a gate that fires is
already too late to teach. If GDP-0 rejects the gate, remove it; do not wrap guidance around it.
- **Emission corollary (the audit direction).** Read the pairing BACKWARDS to make it
checkable: **a rejection you actually observe being emitted IS, by construction, evidence
that its preventive twin is missing or too weak.** Prevention beats cure; where cure is
unavoidable, detect early so the cure stays cheap. So an emitted rejection is not merely
an operator's problem to fix — it is a named GDP-2 gap, and the set of rejections a system
emits in practice is its prevention backlog, already prioritised by frequency. A rejection
whose own text explains the COMMON CAUSE ("this usually means X was hand-assembled") is
the sharpest case: the system knows the cause well enough to have said it BEFORE the
effort was spent.
- **GDP-3 — Self-explaining (WHAT/WHY/HOW).** Every rejection states WHAT failed, WHY, and HOW
to fix — directly, no investigation needed. A bare `FAILED`/exit-code is itself a defect.
- **Omission corollary (the checkable form).** A message must not withhold a fact the
emitting code ALREADY HOLDS. The test is mechanical: for every fact the operator needs in
order to act, ask whether the rejecting code computed or read it before deciding to
reject. If it did and the message omits it, that omission hands the operator an
investigation the producer had already finished — the purest form of GDP-5's inverted
cost. Naming a state without naming WHERE it lives, or labelling a provenance
(`inferred`, `derived`, `default`) without naming what it was inferred FROM, are the two
recurring shapes: a label whose antecedent is missing is not information.
- **GDP-4 — The HOW invokes the PRODUCING TOOL.** The HOW routes to the system tool that
produces the valid artifact, never manual repair. No producing tool yet → the gate is the
signal to build one.
- **GDP-5 — Cost on the SYSTEM.** The system produces/generates the checked artifact (hook
injects / script generates / gate verifies); the operator never hand-assembles it.
System-pays = capability; operator-pays = ceremony. The fix relocates the production, never
removes the check.
- **GDP-6 — Reliability: NO silent-wrong.** Degrade-LOUD / INDETERMINATE, never false-green
nor silently-wrong. Silent-wrong destroys trust worse than loud-fail; fix correctness before
pushing adoption.
- **GDP-7 — Agnostic + execution-observing.** Language-agnostic (no external-tool hard-dep in
gate logic — behind an optional degrade-loud port); where it can, OBSERVE real execution (the
fixed floor), not merely asserted state.
- **GDP-8 — Decide on the PROPERTY, never the DESIGNATION.** A gate must key on the verifiable
property the object HAS (what it *is* / *does* / *resolves to*), never on a name, form,
string-pattern, or hash that merely *stands for* it. A designation matches itself, not its
referent, so a designation-check is blind exactly where they diverge — and they diverge by
construction (a rebase changes the SHA not the content; `python -m pytest` is named `python`;
`..%2f` is traversal without the `../` form; `/var/tmp` is a temp dir `gettempdir()` never
returns). Before comparing a symbol, name the property it represents and test THAT: a property
can be stated and falsified with a known negative case; a name cannot. **Corollary — arity:**
every outcome has ≥3 values (pass / fail / could-not-verify), and the third must reach the
AGGREGATE (the summary line the reader sees), never collapse into pass/empty — a `10/10` while
one check could not look, an allow-list that persists only approvals, are GDP-8 violations.
**Corollary — witness:** the checker is not exempt from the class it checks (a form-grep for
bare failures finds its own false positives; an examiner given one axis develops a stable
blind spot). When the property is not locally inspectable, verification requires a SECOND AXIS
— a different question or a differently-lensed witness, not a better single checker.
**Corollary — authoring (declared-vs-emitted, the same disease one step upstream):** GDP-8
guards the CHECKER against trusting a designation; this guards the WRITER against MINTING one.
Before you name an event, record, or artifact as the basis of a rule, a contract, or a resume
cue, ask: **does this name have a PRODUCER?** If you cannot point at the code that emits it,
say so explicitly ("not yet built", "DESIGNED-NOT-BUILT") — a bare present-tense claim ("the
ledger records `Foo`") is a designation with no referent, and the reader designs on top of what
you wrote, not on what actually runs. Confirmed instances found by manual audit before this
corollary existed: `FeatureEnd` (a repo's own DONE-definition named a ledger record with zero
producers), `FeatureEndCycleComplete`/`Refused`/`Indeterminate` (a design doc assumed these
were durable ledger events; they were CLI-stdout-only), `FeatureEndCheckpoint` (four shipped
files described it as a firing resume-signal that was never implemented), and
`DocumentationDensityEvent` (eleven citation sites claimed a telemetry event with zero
constructor call sites anywhere in the codebase). Preserve the executable property: every
claimed event or record must name a reachable producer and a falsifier; otherwise label it
explicitly as designed-not-built. A prose name or catalog entry alone is never evidence.
- **Wiring corollary — CATALOGUED is not WIRED.** A module's presence in a catalog, registry,
manifest or import list says it EXISTS; it never says it FIRES. Existence is a designation and
firing is a property, decided only by executing the surface that should invoke it and observing
the difference. The failure is silent by construction: the catalog entry, the passing unit tests
and the green import all remain true of a module nothing calls. So when a fix consists of adding
a capability, the demonstration is the CONSUMER's behaviour changing — not the capability's own
tests going green. Read a gate's third state (`UNVERIFIABLE` / `INDETERMINATE`) as a candidate
wiring gap before reading it as environmental: it is frequently the reachable surface reporting,
correctly, that the thing meant to answer was never connected to it.
- **GDP-9 — Interrogative framing forces self-audit; imperative alone invites ritual
compliance.** Phrase a standing check as a question that names the lazy alternative as the
wrong answer ("did you just re-run X THIS turn, or are you about to restate a prior turn's
result?"), paired with an explicit imperative for the branch where the honest answer is no
("if you have not just done it, do it now before answering"). An imperative alone ("always
reverify X before answering") is followed as a rule recalled from memory, and recall decays
into ritual compliance — the reader can believe it is complying while only pattern-matching
to yesterday's answer, because nothing in the instruction's SHAPE forces a live check. A
question forces the reader to evaluate a present-tense claim (did I, or didn't I, in this
turn) before answering it, which is a different cognitive operation than executing a stored
directive — evaluating a claim resists being satisfied by memory alone the way executing a
rule does not. Neither half is sufficient alone: a question with no imperative fallback risks
a literal, un-inferred answer that misses the implied correct one and fails silently (the
reader can honestly answer "no, from memory, and that's fine" without recognizing the
question as a trap); an imperative with no question is the ritual-compliance failure this
principle exists to catch in the first place. Pair them. Measured across dozens of standing
self-audit firings in one overnight session (2026-08-02): the question-plus-imperative
pairing consistently produced a genuinely fresh re-check (a re-run `git status`, a re-issued
grep, a re-read mtime) rather than a restated prior-turn answer, in a setting where the
underlying facts (worktree state, ToC mention counts) DO change between firings and a
memory-recalled answer would have gone stale silently.
- **GDP-10 — Parsimony: prefer removing/relaxing over adding a special case (STANDING, Ale
2026-08-03 — "simplicity is the ultimate sophistication").** GDP-1..9 govern the QUALITY of a
gate once it is justified; GDP-10 governs whether it should exist, or exist in that form, at
all. Parsimony PRESUPPOSES GDP-0: first ask whether the producer can make the gate vacuous —
a gate that guards a state the producer no longer permits is a special case with zero
remaining risk, GDP-10's own paradigm case. When an edge case surfaces, the default move is
NOT "add a new gate, token, lane, or
scope-recognition rule to cover it" — it is to ask whether an EXISTING, more general rule
already covers the risk, or whether the risk is small enough that a MORE PERMISSIVE answer is
correct. Every new named exception multiplies the surface every other gate, reader, and future
agent must reconcile against; N special cases compound combinatorially while the risk any
single one prevents stays additive — past some point the system spends more on ceremony than
the incidents it prevents are worth. Measured 2026-08-03: 4 Slice-Plan annotation tokens
(`@coupled`/`@walking-skeleton`/`@infrastructure`/`@prefactoring`), 275 open rows in
`defects.md`, and a Tier-2 AT-completeness invariant (S8, causal-sensitivity) removed the same
day for blocking a collaborator with a value not worth its friction — the accumulation is not
hypothetical.
- **Corollary — name the incident before adding the restriction.** Before shipping a new
gate/token/exception, name the SPECIFIC incident or measured risk it prevents and its
frequency; if you cannot, the restriction is precautionary ceremony, not a fix, and the
parsimonious default (do not add it) wins.
- **Corollary — ceremony proportional to blast radius.** The rigor a change goes through must
scale with what it actually risks, not with the anxiety of the moment the gap was found in —
a zero-behavior docstring commit does not need the same examine cycle as a production
behavior change; a bugfix to a one-off dev script does not need a full
DISCUSS→DESIGN→DISTILL cycle merely because the spine CAN run one.
- **Corollary — reversible removal beats irreversible accumulation.** When genuinely unsure
whether a check earns its cost, removing it is the better default: an absent check that
later proves load-bearing is cheap to re-add, now backed by a real incident instead of a
hypothetical one; a check that never earns its keep is not cheap to notice or remove once a
wave of later rules has grown to assume it is there.
- **Corollary — existing constraints are removal candidates too, but removal needs a
challenge.** GDP-10 is not only about resisting NEW restrictions — it licenses actively
auditing EXISTING gates/tokens/lanes/annotations for removal, preferably against DATA (has
this gate ever fired on a REAL defect? check the ledger/telemetry for actual catches versus
rejections that were false-positives or pure ceremony) rather than impression. But "we
probably don't need this" must survive a genuine CHALLENGE before removal lands — an
adversarial pass that argues FOR keeping the constraint, citing the strongest incident it
would have caught and the worst case if it is gone — never a rubber-stamped "seems safe,
remove it." Skipping the challenge makes "prefer removing" decay into the SAME failure this
principle exists to prevent, pointed the other way: a removal rubber-stamped without real
scrutiny is agility-THEATER, not agility, and costs the system the next time the removed
check would have caught something real. The asymmetry that justifies the extra step: adding
ceremony wastes time repeatedly, every time the gate fires; removing a load-bearing check
wrongly can cost far more, once, silently, later.
---
## `gate:reject-all-at-once` — one pass reports EVERY independent problem, not the first (STANDING)
**Reject-all-at-once (Ale, 2026-08-22).** A validator that stops at the FIRST problem offloads
onto its caller N cycles where one would do: every round is a full dispatch of the upstream
producer. A gate collects every INDEPENDENT problem in ONE pass and reports them together,
numbered, each carrying its own WHAT/WHY/HOW; checks that genuinely DEPEND on another stay
sequential, but the report declares which ones it could not run and why (GDP-6: the third state
reaches the aggregate). Corollary of GDP-3 (self-explaining rejection — a rejection naming one
of three defects is telling the truth about a third of the state) and of GDP-5 (cost on the
SYSTEM — N rounds of producer dispatch is exactly cost pushed onto the operator).
Anchor: three sequential contract refusals on ADR-AUM-001 (2026-08-22) and four
on ADR-CFG-001 (2026-08-21) — each round a consult with the architect to fix one defect and
re-run, only to be told about the next.
**How to satisfy it.** Accumulate `problems` and `unrun` across the pass instead of returning at
the first; keep the single-problem rendering byte-identical to what it always was, so no reader
pays for the multi-problem affordance; lead a multi-problem refusal with HOW MANY, then one
numbered, independently actionable block per problem, then the checks that could not run.
**Falsifier**: one authority carrying N independent defects produces ONE refusal that lists all
N. If a second run surfaces a defect the first could have seen, this clause is violated.
**The failure this clause prevents**: a "green-by-exhaustion" loop where the producer is
re-dispatched once per defect and the operator mistakes refusal count for progress.
---
## `authoring:a-measurable-fact-is-a-test-not-prose` — a measurable fact belongs in a test, never in a sentence (STANDING, Ale 2026-09-06)
Prose has no verifier. Code has its tests; docstrings, comments, ADR sections, test names
and reports have only a reviewer, and declarative prose is produced continuously — so a
reviewer will always find more of it. This is a SURFACE problem, not an attention problem,
and cataloguing instances accumulates them instead of reducing them.
A measurable fact is written as a test that fails when it stops being true. If it does not
deserve a test, it does not deserve the sentence: delete it.
**Forbidden** in docstrings, comments and reports: example numbers, counts, shas, elapsed
times, "this module reads X", "this test covers Y", "N of M". Each lives in a test, in
pasted executed output, or nowhere. **Permitted**: the REASON for a choice over another,
a dated incident, and an explicit statement of what is NOT covered — declaring a gap is
the opposite of claiming too much.
**In a report**: every assertion carries the command and its output, or is marked `not
measured`. There is no middle. "I repaired X" without a red-to-green is `not measured`.
**Falsifier**: a sentence stating a measurable fact with no test that fails when the fact
stops holding. **Consequence for review**: such a sentence is a falsehood only when
somebody will decide from it; otherwise the correction is deleting it, inside the same
slice, with no new round (`nw-review`, Convergence).
---
## `gate:predicate-needs-its-own-enumerator` — a predicate without an enumerator forces every caller to invent its own population (STANDING)
A decision predicate ("is THIS one X?") and the enumerator over the population it ranges over
("which ones exist to ask about?") are two DIFFERENT responsibilities. When only the predicate
ships and no enumerator does, every caller that needs the AGGREGATE answer ("how many, or
which, of the whole set are X?") is forced to invent its own population — filtering on a
naming convention, a directory listing it happens to have on hand, or whatever subset it
already touches for an unrelated reason. An invented population is usually WRONG: it silently
under- or over-covers the real set, and the gap stays invisible because nothing computes the
true population anywhere to compare against — a caller checking 3 of 36 candidates reports
"nothing to flag" with the same confidence as a caller that checked all 36. This is a
population-scope instance of the GDP-1 timing failure: without a sweep, the predicate can only
fire reactively, at the single moment one caller happens to ask about one target — never
proactively, across the whole set, at the earliest point a defect is detectable.
Fix: when a decision is meant to apply across a set, the ENUMERATION of that set is part of the
CONTROL, not the caller's job to reconstruct. Ship the enumerator alongside the predicate (or
reuse an EXISTING one — do not build a second listing implementation for a population another
port already lists), or explicitly scope the predicate to single-target use only and say so in
its own contract. A predicate whose docs describe periodic, whole-set behavior but whose only
shipped caller queries one target at a time is a claim with no producer for the AGGREGATE case
— the GDP-8 authoring corollary above, one level up: the population itself needs a producer,
not only the per-item verdict.
---
## `delivery:completion-claims-the-destination` — a completion claim is a receipt about the DESTINATION, not about the producing worktree (STANDING)
A work result is delivered when its named ready revision is REACHABLE FROM the destination —
a measured ancestry fact about the destination — never when the producing lane or worktree
reports clean, finished, or self-declared ready. Clean Git is a property of a worktree;
delivery is a relation between a revision and a destination, and the two diverge exactly
whenever integration has not happened. Do not claim delivery while the named
revision remains outside its destination. Measure ancestry against the actual
destination; `nwdes lane integrate` refuses `LaneNotMerged` when the lane tip is
not contained in the candidate, and needs no prior merge. An unmeasurable tip stays INDETERMINATE, not pass.
Content (uncommitted/untracked/ignored) and availability (present/locked/missing)
are separate observations and establish neither review readiness nor delivery.
Preserve useful bytes before cleanup; do not invent a completion ledger or
readiness producer that does not exist (GDP-8 authoring corollary).
**Falsifier**: a delivery claimed complete while `merge-base --is-ancestor <named tip>
<destination>` answers no.
---