Skip to main content

koyu validate

Runs the judgements that belong to architecture — daylight, reachability, envelope continuity, stair proportions, the site numbers. It says, under a different name and a different type, what koyu check does not guarantee.

Arguments

koyu validate <entry.muro> [--json]

Takes one entry path.

Flags

FlagEffect
--jsonWrites the findings to stdout as Finding[] JSON

Output

When nothing is caught, one line comes out.

npx tsx src/cli.ts validate examples/house/main.muro
✔ Nothing caught by validation (this is a judgement, not a guarantee about the composition)

Otherwise each finding gets a line and a count follows. is a violation, is a caution.

npx tsx src/cli.ts validate sealed.muro
✖ [daylight.ratio] <absolute path>/sealed.muro:line 7: Insufficient daylight: /L1/a — effective window 0.00 m2 < required 2.31 m2 (1/7 of the 16.20 m2 floor)
✖ [access.unreachable] <absolute path>/sealed.muro:line 7: Cannot reach the exterior: /L1/a (no passable boundary leads out — write a door)
✖ [access.unreachable] <absolute path>/sealed.muro:line 8: Cannot reach the exterior: /L1/b (no passable boundary leads out — write a door)
Validation — 3 violations / 0 cautions

That sealed.muro is a file koyu check returns green for. The two commands look at different things.

Inside the square brackets is the rule name; what follows, <resolved absolute path>:line <n>:, is the provenance. Findings without a position carry no prefix.

The shape of --json

npx tsx src/cli.ts validate caution.muro --json
[
 {
  "rule": "envelope.gap",
  "level": "caution",
  "message": "Perimeter not faced by any envelope: /L1/a — S 3600mm / N 3600mm / W 4500mm (11700mm over 3 run(s)). Write a boundary to the exterior",
  "line": 7,
  "file": "<absolute path>/caution.muro",
  "path": [
   "/L1/a"
  ]
 }
]

rule, level and message are always present; line, file and path appear only when the finding has them.

level is an invariant property of the rule. The same rule is never a violation one time and a caution another.

The 15 rules

RuleLevelWhat it says
envelope.gapcautionA hole in the envelope — perimeter that faces nothing
daylight.ratioviolationEffective window area is below one seventh of the floor
daylight.unknowncautionA window has no h, so the window area was not fully counted
stair.proportioncautionThe derived steps are cramped (tread under 240mm, or 2R+T outside 550–700)
run.slopecautionThe derived slope is steeper than declared, or outside normal use
run.disconnectedcautionA vertical run exists in form, but no vertical boundary joins the two levels
access.unreachableviolationA room with a region cannot reach the exterior
access.voidonlyviolationThe only doors open onto a void, where there is no floor
access.throughtenantcautionEscape from a stair core passes through a leased tenancy
access.parkingviolationA car cannot get out of the parking
access.backofhousecautionA vertical run is unreachable from the public corridor without crossing back-of-house
column.blocksdoorviolationA derived column overlaps a derived door
site.escapeviolationThe building leaves the site polygon
site.areacautionThe declared and derived site areas disagree
site.frontageviolationRoad frontage is under 2m

A rule name is a chapter (envelope / daylight / stair / run / access / column / site) plus a name inside it. The chapter is a subject, not a jurisdiction.

Findings come out in chapter order, and within a chapter in scan order.

Exit codes

Exit codeMeaning
0No violations — cautions alone still give 0
1One or more violations
2No file path was given (usage is printed)

A file that could not be read exits 1, with a single on stderr. --json does not produce valid JSON on that path — the SYN01 trick that check --json uses does not exist in validate.

Here is the cautions-only exit code for real.

npx tsx src/cli.ts validate caution.muro
⚠ [envelope.gap] <absolute path>/caution.muro:line 7: Perimeter not faced by any envelope: /L1/a — S 3600mm / N 3600mm / W 4500mm (11700mm over 3 run(s)). Write a boundary to the exterior
Validation — 0 violations / 1 caution

The exit code is 0. To fail CI on cautions too, read --json and count them yourself. There is no validate equivalent of check --strict.

How it differs from check

koyu checkkoyu validate
Returned typeDiagnosticFinding
Namecode (BND04 — four letters and two digits)rule (envelope.gap — chapter and name)
Weightseverity: error / warninglevel: violation / caution
Count65 codes15 rules
What it guaranteesThat what is written holds together as dataNothing — it is a judgement
Nature of the surfaceFrozen. Adding or removing moves the language versionNot frozen. May grow, may be discarded

The field names differ, so the two arrays cannot be confused; try to concatenate them and the types fail. Making it impossible to describe "check's green" and "validate's green" with the same words is the point of the split.

Adding a judgement does not move the language version. The validate surface is allowed to be coarse, to cover one jurisdiction only, and to be imprecise — it is cheap because it is not frozen.

See also