メインコンテンツまでスキップ

check と validate の違い

koyu は「正しさ」を二つに割っている。

構成の診断建築の判定
コマンドkoyu checkkoyu validate
返す型Diagnostic { code, severity }Finding { rule, level }
識別子BND04 SUF01 — 3 字 + 2 桁envelope.gap access.unreachable — 章.規則
重さerror / warningviolation / caution
65 コード15 規則
凍る凍らない。増える
言うこと書かれたものがデータとして矛盾していない建築として妥当である (らしい)

綴りが違うのは事故を防ぐためである。ENV01envelope.gap を取り違える読み手はいない。

型からして別である

--json を付けると、二つが同じ形をしていないことがそのまま見える。

npx tsx src/cli.ts check b1.muro --json
[
{
"code": "BND04",
"severity": "error",
"message": "The spaces do not touch, so no boundary can be derived: /L1/a | /L1/b",
"line": 6,
"file": "b1.muro",
"path": [
"/L1/a",
"/L1/b"
]
}
]
npx tsx src/cli.ts validate gap.muro --json
[
{
"rule": "envelope.gap",
"level": "caution",
"message": "Perimeter not faced by any envelope: /L1/b — S 3600mm / E 4000mm / N 3600mm (11200mm over 3 run(s)). Write a boundary to the exterior",
"line": 6,
"file": "gap.muro",
"path": [
"/L1/b"
]
}
]

混ぜられないことがこの型の仕事である。下流の道具が二つを同じ配列に流し込むには、まず型を潰す必要がある。潰したことは、その時点で見える。

分ける理由 — 求められる品質が違う

判定は、何が正しいかがまだ定まっていない領域である。採光の有効係数をどう扱うか、階段の窮屈さをどこで切るか、避難の経路をどう数えるか — どれも管轄と時代と建物用途で変わる。定まらないうちに凍結すれば、誤りを凍結することになる。

一方、構成の診断は定まっている。パスが一意か。参照先が存在するか。二つの領域が重なっていないか。これらは「読解の一部」であって、意見の余地が無い。

だから扱いを変える。

構成の診断建築の判定
足すときの値段高い — 解析・合成・機械形式・仕様・文書を同時に触る安い — 台帳に一行と、頁に一節
間違えたときの値段極めて高い — 凍った面に誤りが残る安い — 書き直せる
精度完全でなければならない粗くてよい
捨てられるか捨てられない捨ててよい

汚くてよい条件は一つ。判定の結果が、原本の保証と混同されないこと。その条件を、綴りと型と出力の文言が三重に守っている。

Validation — 2 violations / 0 cautions
✔ Nothing caught by validation (this is a judgement, not a guarantee about the composition)

判定が緑でも、それは判定が緑なだけである。

判定が粗くてよいことの実例

envelope.gap は外皮の穴を報告する規則である。判定の母集団は外部への境界を一本でも書いたレベルだけである。

外皮をまだ模型にしていない階を「穴が開いている」とは言わない。「書き始めたなら閉じきる」という整合の要求であって、完全性の要求ではない。

これは正確な規則ではない。基本計画の途中で外皮を一階分だけ書いた模型は、他の階について何も言われない。それでよい — 粗さを直す値段が安いからこの粗さで出せる。core にこの規則があったら、この粗さでは出せなかった。

数を返すのは core、線を引くのは判定

集計とグラフの問いは core が持つ。ただし合否を言わない。

問いcore が返すもの判定が言うこと
採光床面積と有効窓面積1/7 を満たすか (daylight.ratio)
敷地敷地面積・接道長・建築面積・延べ面積とその商2m の接道 (site.frontage)・はみ出し (site.escape)
縦動線段数・蹴上・踏面・勾配窮屈さ (stair.proportion)・勾配 (run.slope)
外皮何にも面していない外周の線分それが穴か (envelope.gap)
動線最少扉数の経路と通行可能性外部へ出られるか (access.unreachable ほか)
柱と開口通り芯から立つ柱と線分上の開口重なっているか (column.blocksdoor)

閾値は建築の側にある。1/7 も 2m も 240mm も、原本の構成が満たすべき不変量ではない。数を返すところまでが core で、数に線を引くのが判定である。

この線引きがあるので、別の管轄の判定を足すことは core を一行も触らずにできる。規則を台帳に足し、頁を一つ書けば終わりで、言語の版は動かない。

判定は増える面である

15 規則は完成形ではない。防火区画、日影、斜線、動線の距離、バリアフリー、設備の成立 — 判定として書けることは山ほど残っている。

それらは全部この面に足される。足しても .muro の意味は変わらず、既存のファイルは読めたまま、正準 JSON は同じバイト列を出す。

言語に足すことは高く、判定に足すことは安い。この非対称を作るためにこそ、二つを分けてある。

この先