Scope — what a green check means
For mode spatial, see spatial models: unwritten boundaries stay unresolved, heights and slabs may be omitted, and architectural assessment is not evaluated.
npx tsx src/cli.ts check examples/two-rooms.muro
✔ Consistent — 3 spaces / 3 boundaries
Structural consistency only — architectural validity is what koyu validate says, separately
What that one line promises, and what it does not. That is this page.
The definition of green
For the structural tier and the interpreted tier, the declared invariants hold. About the carried tier it says nothing. About architectural validity it says nothing.
This is not a judgement but part of reading — the same layer at which a JSON parser rejects broken JSON.
Three domains
koyu is made of three domains. They are kept apart because the quality demanded of each is different.
| Domain | What it holds | Size | Quality | Version |
|---|---|---|---|---|
| core | the language, its semantics, composition, identity, derivation, structural diagnostics, questions, canonical JSON | small | must be clean | freezes |
| validation | architectural judgement — under a profile you name | grows | may be messy | does not freeze |
| presentation and build | SVG generation and outside viewers | grows | may be messy | does not freeze |
The dependency runs one way. Validation and presentation depend on core; core depends on neither. Core runs complete on its own. That one-wayness is enforced by a test, not by prose.
Not separating them makes two things happen at once — mess seeps into core and freezes there, and core's caution stops validation and presentation from growing. The separation itself is what makes it acceptable for the other two to be messy. Mess in a domain that does not freeze can be rewritten at any time, so it is cheap. Mess in a domain that freezes is permanent.
Even the types are separate. Core returns Diagnostic { code, severity }; validation returns an AssessmentReport whose findings carry { rule, level } around outcomes carrying { status }. Adding a judgement never moves the language version.
What is guaranteed
| Guarantee | Diagnostics |
|---|---|
| Uniqueness of paths and identity | UID01–04 / ZON02 / duplicate-path errors during composition |
| Existence of referents | REF01 / undefined asset / the zone a polygon belongs to (SIT04) |
| Levels are defined | LVL01 / VRT02 |
| Overlapping regions (in plan) | GEO01 / GEO02 |
| Overlapping regions (in section) | HGT01 / HGT02 |
| Composition resolves | composition errors |
| Sufficiency of what shape needs | SUF01–04 |
| Soundness of relations | BND01–06 / VRT01–06 |
Uniqueness of derivation (openings, segs, lines, columns, run shapes) | OPN01–08 / SEG01–08 / LIN01–03 / COL01–02 / RUN01–03 / RUN05 |
| Value domains of interpreted attributes | ATT01–03 / DAY01 |
| Soundness of the givens | SIT01 / SIT02 |
Overlap in section belongs to core because it is the sectional case of overlap in plan. A ceiling below and a floor above occupying the same z is the same kind of contradiction as two space regions overlapping, and no single shape can be made from it. Architectural judgements about height — storey height, eaves height, setback envelopes — are not guaranteed; those are the validation face.
What is not guaranteed
Daylight, area ratios, floor area ratio, envelope continuity, whether a stair is climbable, whether a door can physically be installed, means of escape, street frontage — and every other question of architectural validity. Plus the meaning of carried-tier attributes.
None of these are absent. They are on another face — koyu validate holds them.
npx tsx src/cli.ts validate examples/two-rooms.muro --profile koyu.profile.schematic-screen --as-of 2026-08-03
✔ Nothing caught by validation (this is a judgement, not a guarantee about the composition)
The output says so itself.
Do not claim "it works" because it is green
Green does not mean the building is usable.
Touching spaces default to a wall, and so does a face onto the outside, so a two-storey building that declares not one door stays green and is completely sealed. What a forgotten boundary to the outside costs is not the wall but the name of what it faces, and check says so as BND08.
Circulation is answered by koyu doors; judgement by koyu validate.
Questions do not say pass or fail
Core holds the questions of quantity and graph. It just never says pass or fail.
| Question | What core returns | What validation says |
|---|---|---|
| Daylight | floor area and effective window area | whether it meets 1/7 (koyu.schematic.daylight.ratio) |
| Site | site area, frontage length, building area, total floor area and their ratios | 2m of frontage (koyu.schematic.site.frontage), escape beyond the line (koyu.schematic.site.escape) |
| Vertical runs | riser count, riser, going, slope | whether it is cramped (koyu.schematic.stair.proportion), whether the slope is acceptable (koyu.schematic.ramp.declared-slope / koyu.schematic.escalator.usual-slope) |
| Envelope | outline runs no declared boundary reaches, and the default wall on them | whether the building should be open there instead |
| Circulation | the minimum-door route and passability | whether you can reach the outside (access.*) |
| Columns and openings | columns standing on grid intersections, openings on a segment | whether they collide (koyu.schematic.column.blocksdoor) |
Thresholds belong to architecture. Neither 1/7 nor 2m nor 240mm is an invariant a composition must satisfy. Core returns numbers; validation draws lines through them.
The three attribute tiers
| Tier | Examples | How core treats it |
|---|---|---|
| Structural | path, region, level, the other end of a relation, kind | always read. If it is broken, nothing is read |
| Interpreted | h ceiling daylight road site style … | the ledger defines the value domain, and core reads it |
| Carried | acme.sensor bems.temp survey.measured … | not read. Open, with a namespace |
The carried tier carries a namespace (dot-separated). An unknown key without one is an error (ATT03) — so that a one-letter slip like heigh:2400 cannot silently do nothing. That is the only shape in which "not looked at" and "looked at and fine" can be told apart.
Without the declaration, they cannot be told apart, and "nothing wrong" in that state means nothing. Being able to carry something without judging it is a legitimate state, and saying so explicitly is the condition of that freedom.
Not read is not the same as unreachable. A caller may name a carried key and get the values back grouped — koyu stats --by lease.category totals floor area by that key's effective value. Core forms no opinion even then: it checks no value, derives nothing from one, and groups by equality of the string alone, so it answers the same way for a key it has never seen. What the key means is the caller's, which is why it stays on the list of what is not guaranteed.
Neighbouring pages
- Stability — what is promised not to break
- Identity — how far a uid guarantees anything
- What koyu does not hold — the resolution of this description
- koyu check — using the gatekeeper
- koyu validate — the judgement face
- Diagnostics
- Judgements