# Well-formedness

> This section covers the static analysis that decides whether a document can be trusted; two routes to trust] contrasts it with trusting a document because it…

Page: PAG · Guide
Canonical: https://banes-lab.com/pag/guide#well-formedness

This section is stop 20 of 102 in the learning route. Previous: [05 - Writing constraints](https://banes-lab.com/pag/guide/writing-constraints.md). Next: [12 - Worth before work](https://banes-lab.com/disciplined-methodology/plan/worth-before-work.md). It builds on [05 - Writing constraints](https://banes-lab.com/pag/guide/writing-constraints.md).

This section covers the [static analysis](https://banes-lab.com/records/arch/static-analysis.md) that decides whether a document can be trusted; [F1·e two routes to trust](https://banes-lab.com/pag/guide#well-formedness-panel-e) contrasts it with trusting a document because it reads fluently, and [F1·d the scan](https://banes-lab.com/pag/guide#well-formedness-panel-d) shows the scan. Each defect is named for the shape it catches and has one fix, as paired in [F1·a defect set](https://banes-lab.com/pag/guide#well-formedness-panel-a) and reported in [F1·b scan result](https://banes-lab.com/pag/guide#well-formedness-panel-b). The syntactic defects are a missing declaration, a bare iteration, a lowercase [keyword](https://banes-lab.com/pag/keywords/keyword-ontology.md), a conditional with no colon, a malformed node tag, and a node declared twice. The epistemic defects are a node with no gate, a gate with fewer than three or more than five checks, a check that is a judgement, a check with no evidence, a gate with no population or an empty one, and an unknown left unrouted. The remaining defects are a write with no refusal, an artifact with no freshness, an input that names no source, an invariant missing its set, its parties or its objector, and a bare invariant block. The scan is the terminate stage applied to the document itself: it yields one boolean, and because it reads tokens rather than patterns, its verdict has [repeatability](https://banes-lab.com/records/arch/repeatability.md).

### The defect set and the scan

A document that reads well is walked as if it had been checked. A document reads well, but a bare iteration completes as a count, the node produces one result instead of many, and the gate that would have caught it was never written. Fluency is a property of prose, and the defects that break a document are properties of tokens the prose reader does not see.

For this reason a document is trusted after a deterministic scan, not because it reads well. The tokens are scanned rather than matched against a pattern or read for fluency, because only a token scan reports a location a reader can go to. In practice, a document is scanned for the defect set before it is walked and after every edit. Each defect is reported with its location, what was found, what was expected and the one fix, so a reader repairs the line rather than re-reading the whole document. A document is trusted only when the defect set is empty, and a fluent document that fails the scan counts as ill-formed, however well it reads.

To check this, plant one defect from the set in a passing document and scan it. A scan that stays green cannot catch that class of defect, and a scan that reports it at the wrong location is matching a pattern rather than reading tokens. Well-formedness is structure, not meaning. A document can pass every scan and still ask for the wrong thing, and that is what the gates, the review and the method exist to catch.

The defect set is the grammar's taxonomy of failures, and it is derived rather than collected. Each epistemic defect is one of the ways a representation escapes its check, which the methodology page names from the other side in [the honest gaps](https://banes-lab.com/disciplined-methodology/ship/the-honest-gaps.md) and [coverage is derived](https://banes-lab.com/disciplined-methodology/verify/coverage-is-derived.md). A check with no population is the gate that passed over nothing, and an unknown left unrouted is the verdict that folded a third value into pass. A write with no refusal is an irreversible act with nothing to stop it, an input that names no source is a dependency inferred from a name, and an invariant with no objector is a property nothing would disagree with. Each defect has one repair, which is what lets a scanner state it. The scan works on tokens and uses no pattern language; that is a fact about the scanner rather than the grammar, whose conditions may still carry a pattern literal.

Three defects that the scan does not catch show up as gate failures instead, as shown in [F1·c gate failures](https://banes-lab.com/pag/guide#well-formedness-panel-c), and all three are found by tracing a value from the node that yields it to the node that reads it. One of them, a contract whose input names a later node's output, is repaired in the decomposition rather than in the line, because the node is in the wrong place.

F1·a defect set

```pag
# no declaration · a document with no stated kind
%% META %%:
THIS WORKFLOW EXECUTES <what it is for>

# a bare iteration · reads as a count, completes as one
FOR <item> IN <collection>:
FOR EACH <item> IN <collection>:

# a lowercase keyword · a word, not a token
if <condition>
IF <condition>:

# a node with no gate · a unit nothing can prove closed
# NODE 2 — CONVERT   [epistemic · formalisation · computation · yields: procedure]
COMPOSE_ARTIFACT <shaped> FROM <row> USING <rules>
# NODE 2 — CONVERT   [epistemic · formalisation · computation · yields: procedure]
COMPOSE_ARTIFACT <shaped> FROM <row> USING <rules>
HANDOFF GATE:
[check] every <row> converted (evidence: one <shaped> per row) over: <rows> measured: <converted> / <rows>
[check] <shaped> holds one entry per <row> (evidence: the two counts match)
[check] every entry conforms to <rules> (evidence: VALIDATE_ARTIFACT passed on each)
result: pass → NODE 3 | mismatch → REPAIR (owner: NODE 2) | unknown → BLOCKED

# a vague check · a judgement in a gate
[check] data looks good
[check] <data>.<field> matches <pattern> (evidence: the match returned true)

# a check with no evidence · a claim the gate cannot settle
[check] <report> is complete
[check] <report> names every entry in <findings> (evidence: each finding's id present)

# a gate with no population · a verdict about nothing
[check] every <file> conforms (evidence: the validator's report)
[check] every <file> conforms (evidence: the validator's report) over: <files> measured: <conforming> / <files>

# an unknown left unrouted · the third verdict absorbed into pass
result: pass → NODE 3 | failure → REPAIR (owner: NODE 2)
result: pass → NODE 3 | failure → REPAIR (owner: NODE 2) | unknown → BLOCKED

# a write with no refusal · an irreversible act with no condition to stop it
PERSIST_ARTIFACT <shaped> TO <destination>
refuse: <destination> changed since it was read before PERSIST_ARTIFACT

# an invariant with no objector · a property nothing would disagree with
INVARIANT one-writer: a record has exactly one writer
INVARIANT one-writer: a record has exactly one writer over: every record binds: every party objector: [check] one open fence per record

# a bare invariant block · a bullet under a head, with no set, no parties, no objector
ALWAYS:
- VALIDATE at node boundaries
INVARIANT validate-at-boundary: every node validates its output over: every node binds: the reader objector: [check] the gate ran

# a prose directive · an instruction the model must interpret
Get the customer data and check it
READ_RESOURCE <records> INTO <held>
VALIDATE_ARTIFACT <held> AGAINST <schema>
```

F1·b scan result

```text
document: <name>
defect      for_without_each
locus       NODE 2, line 4
found       FOR <item> IN <collection>:
expected    FOR EACH <item> IN <collection>:
fix         insert EACH after FOR

defect      gate_without_population
locus       NODE 3, gate
found       three checks, none with a set
expected    at least one check measured over a declared set
fix         name the set and the count measured over it

defect      unknown_unrouted
locus       NODE 3, result line
found       pass and failure arms only
expected    an unknown arm routed to BLOCKED
fix         add the third arm

defect      invariant_without_objector
locus       cross-node invariants, one-writer
found       a property with no objector
expected    the check that would disagree, or none as declared debt
fix         name the objector

verdict: ill_formed
```

F1·c gate failures

```pag
# a value undefined in a later node
# cause · declared inside a branch, so it exists only there
IF <condition>:
DECLARE <result>: object

DECLARE <result>: object
IF <condition>:
SET <result>.<value> = <data>

# a gate that always fails
# cause · the check names a value the node never produced
APPEND <item> TO <processed-items>
HANDOFF GATE:
[check] <processed-list> populated (evidence: a count above zero)

APPEND <item> TO <processed-items>
HANDOFF GATE:
[check] <processed-items> populated (evidence: a count above zero)

# a contract that reads forward
# cause · the input names an output a later node yields
# NODE 2 — ANALYSIS
CONTRACT:
input: <report> from NODE 3

# NODE 2 — ANALYSIS
CONTRACT:
input: <files> from NODE 1
```

F1·d the scan

```mermaid
flowchart TB
doc["A document"]
scan["A deterministic scan · tokens, never patterns"]
defects["The defect set · each named for the shape it catches"]
well["well_formed"]
ill["ill_formed · each defect with its locus and its fix"]
doc --> scan --> defects
defects -- empty --> well
defects -- non-empty --> ill
```

F1·e two routes to trust

```mermaid
flowchart LR
fluent["Reads fluently"]
trusted1["Trusted · and wrong in the details that went unread"]
scanned["Passes the scan"]
trusted2["Trusted · because a mechanism said so"]
fluent -. the tempting path .-> trusted1
scanned --> trusted2
```

## Links to

- [Static Analysis](https://banes-lab.com/records/arch/static-analysis.md)
- [Keywords](https://banes-lab.com/pag/keywords/keyword-ontology.md)
- [Repeatability](https://banes-lab.com/records/arch/repeatability.md)
- [The honest gaps](https://banes-lab.com/disciplined-methodology/ship/the-honest-gaps.md)
- [Coverage is derived](https://banes-lab.com/disciplined-methodology/verify/coverage-is-derived.md)

## Linked from

- [BNF grammar](https://banes-lab.com/pag/grammar/bnf-grammar.md)
