| name | koyu-validate |
| description | Judge a building written in muro and repair what is wrong with it โ rooms nobody can reach, bedrooms with no daylight, missing exterior walls, stairs at impossible proportions, a building that escapes its site. Use this skill whenever someone asks whether a plan works, wants it reviewed or checked over, hands you koyu validate output or a `.muro` file to look at, or says something like "ใใฎ้ๅใๅคงไธๅคซ๏ผ", "review this plan", "ไฝใๅ้กใใ๏ผ", "fix the findings", "ใชใๅฑใใชใใฎ". Use it after koyu-author writes a plan and before anyone is shown it. Do NOT use it for writing a new building from a brief (that is koyu-author), for building-code compliance certification, or for structural, energy or cost analysis, none of which koyu performs. |
Judging a building, and repairing it
koyu check proves the description is consistent โ that one form derives from
it. It deliberately says nothing about whether the building works. A two-storey
building that declares not one door contradicts nothing and checks green while
being completely sealed.
koyu validate is the separate judgement. It returns findings, each with a rule
name, a level, and the line that caused it:
node dist/cli.js validate main.muro --profile koyu.profile.schematic-screen --as-of 2026-08-03
npx -p @kensnzk/koyu koyu validate main.muro --profile koyu.profile.schematic-screen --as-of 2026-08-03
The profile and the date are required. koyu never guesses which rules to
apply or what date to apply them on; a call without them stops at exit 2 before
judging anything. koyu ships one profile, koyu.profile.schematic-screen.
Violations block; cautions inform. Exit is 0 only when the whole set ran and
nothing was violated โ so a clean exit still leaves cautions worth reading, and
a rule that could not run exits 1 rather than passing quietly. Add --json for
the whole AssessmentReport when you are feeding another program.
An empty findings is not by itself a pass. Read summary.state: it is
complete only when nothing was left indeterminate and nothing errored.
This judgement is coarse and early, at the resolution of a scheme design.
It is not a compliance verdict, and passing it is not permission to build.
What this skill covers is the judgement and what it names. A finding says
what is wrong and which muro expression caused it. Which repair to choose when
several would clear it, and which cautions are worth acting on at all, are
architectural decisions โ validate does not make them and neither does this
skill.
Read the finding, then repair it
Findings name their own repair once you know the vocabulary. Violations are what
the exit code turns on, so clear those and re-run; a caution never blocks and
never has to be cleared.
| Rule | Level | What it means | The repair |
|---|
koyu.schematic.access.unreachable | violation | a space with a region cannot reach any outside:1 space along passable boundaries | declare the boundary to the circulation space and put a door on it |
koyu.schematic.access.voidonly | violation | its only way out is through a void or a shaft โ a door onto a floorless hole | give it a boundary to a space people can stand in |
koyu.schematic.access.parking | violation | a car cannot get out: a stair is a step to a car, and a door narrower than 2400 is a wall | a type:open boundary, a door โฅ 2400 wide, or a space carrying ramp: |
koyu.schematic.access.throughtenant | caution | escape from a stair reaches the outside only through rentable space โ if the tenant locks up, there is no way out | route it through common space, or accept it deliberately |
koyu.schematic.access.backofhouse | caution | a common stair or escalator is reachable from the common corridor only by passing through back-of-house, so visitors cannot use it | open a route from the corridor that avoids the back-of-house space |
koyu.schematic.daylight.ratio | violation | effective window area is under a seventh of the floor, on a space you marked daylight:1 | add a window on a boundary to /out, or drop daylight:1 if the room is not habitable |
koyu.schematic.daylight.unknown | caution | daylight:1 on a space whose openings cannot be evaluated | give the boundary a real opening, or say the room is out of scope |
koyu.schematic.stair.proportion | caution | riser and tread fall outside workable proportions | change the storey height, the run length, or the number of flights |
koyu.schematic.ramp.declared-slope / koyu.schematic.escalator.usual-slope |
Not every rule looks at every space. access.parking judges only the spaces
whose TYPE is parking or ramp. access.throughtenant judges only the spaces
typed stair, and the route it wants is one to the outside that never enters a
space whose lease.category is rentable. access.backofhouse judges only the
spaces carrying stair: or escalator: and lease.category:common, and the
route it wants starts at a corridor also carrying lease.category:common and
never enters a space typed backyard. Write neither the type nor the key and the
rule reports itself not applicable โ which is not a pass: it produces no finding
and is counted in summary.rules.notApplicable.
What passable means
Every access rule stands on what counts as passable, and misreading that is the
usual reason a repair does not take.
Passable by a person โ a type:open boundary, a type:stair boundary
joining two levels, and a wall carrying a door. A derived wall has no door,
so it is not passable, and neither is a window. type:shaft and type:void boundaries
are never passable, and you cannot walk through a void:1 space or a space
typed shaft to somewhere beyond it.
Passable by a car โ type:open, a door at least 2400 wide, or a vertical
link on a space carrying ramp:. A stair is, to a car, a step.
Note where the spelling is guarded and where it is not. void:1 is a ledger key,
so voi:1 is an error (ATT03). shaft sits in the type position, which is open
vocabulary โ write shaftt and this rule quietly stops applying. Core reads no
type word at all; the judging face does, and that face does not freeze.
lease.category is guarded no better: it is a carried namespaced key, and a
namespace is precisely the statement that koyu has not looked at the word, so
lease.categry:common is accepted in silence while the tenancy rules stop
applying to that space. When a finding you expected is missing, check the
spelling of the type and of the key before you look at the geometry โ koyu stats --by lease.category prints the buckets, and a misspelling lands in
(unspecified).
So the commonest violation in a new building is not a mistake in the drawing: it
is a boundary nobody wrote. koyu doors <file> <from> <to> shows the route it
did find, or nothing, which is faster than reading the plan.
Daylight, exactly
Only spaces you wrote daylight:1 on are in scope โ room does not imply
habitable, and the grain of the question (a whole dwelling, or each room) is
decided by where you write it. Effective area is w ร h ร factor summed over
the windows on that space's boundaries, against a threshold of floor รท 7:
| what the window faces | factor |
|---|
an outside:1 space | 1.0 |
| a semi-outdoor space open to the sky โ a garden, a top-floor balcony | 1.0 |
| a semi-outdoor space with something above it โ under an eave or a balcony | 0.7 |
| an indoor neighbour | 0 โ it does not count at all |
koyu light <file> returns the numbers without the threshold, which is what to
read when a finding looks wrong: it shows whether the window is small or simply
facing the wrong thing.
Two things bite while writing the repair itself: an opening on a boundary to
/out needs edge:N|E|S|W, because that boundary always has several segments;
and a name: value containing a space must be quoted (name:"West window") or
the parser reads the second word as a broken attribute.
The envelope is not a verdict โ it is a check warning
There used to be a rule here for perimeter that faced nothing. It is gone, because that
state cannot arise: every side of a space is a wall unless something says otherwise, the
outside included. A forgotten exterior boundary is no longer a missing wall.
What is left belongs to check, as BND08 (a warning): the wall is there, but nobody said
which outside it faces โ road, neighbour, garden. That decides frontage, daylight and
specification, so it is worth reporting. The message names the sides
(S 4000mm / N 4000mm), which tells you which edge: to write.
Read the set of them as an inventory of faces nobody has named yet. Naming is a decision
about the building, which no rule settles โ report them rather than writing boundaries
just to make them stop.
The loop
check first โ validate on a description that does not parse tells you
nothing.
validate, and read every violation with its line.
- Repair the violations in one edit, using the table above.
validate again. Stop when violations are zero.
- Tell the person what you fixed, and list the cautions you left standing.
Which of those to take up is theirs to decide, so hand them over rather than
deciding for them.
The reference for every rule, with a failing example each, is
docs/reference/validate in this
repository. Read the page for a rule when the table is not enough โ access.md
in particular, which explains why its access rules exist.