Skip to main content

The three tiers of attribute

Attributes are written key:value. But the key is not free.

Which keys may be written is set by a ledger. A key that is not in the ledger and carries no namespace is the error ATT03.

/L1/a carries nmae:, which is not in the ledger (check the spelling, or add a namespace if
the value is only carried — e.g. acme.nmae:居室)

That line exists to keep "not looked at" distinguishable from "looked at and fine". With keys unguarded, heigh:2400 silences the height invariant, sit:1 silences the site check and stiar:N silences the vertical circulation — each of them while check stays green. koyu does not keep a state in which what you wrote does not take effect and the file is green.

How a line is spelled (where the : falls, how values are typed, what a repeat does) is in how a line is read. This page is about which keys go where, and what happens to the values.

The three tiers

TierExamplesHow core treats it
Structurethe path, the type, the region, the level, the other end of a relation, type t air edge w at hinge swing d x yAlways read. If it is broken the file is not read at all — it stops on the spot
Interpretedh use road daylight site area style ceiling uid name stair riserRead. The ledger defines the range of values, and a value outside it produces a diagnostic
Carriedspec fire sound floor sill, and any namespaced keyNot read. Carried, nothing more

Structure keys do not survive as attributes. type:, t:, air:, edge:, w:, at:, hinge:, swing:, d:, x: and y: are lifted into fields of the element as the file is read, and their values are checked right there. So they never appear as ATT01 or ATT02 — a non-numeric t: stops earlier, with t is written as a positive number.

Carried values cannot be looked at. spec:RC, fire:60 and sill:800 are carried and given no meaning. What a wall is made of is a value of the thing-name key (spec); it is not a reason to add a boundary type.

The ledger lists what may be written, not what core reads

Being in the ledger does not mean core reads the key. spec, fire, sound, floor and sill are carried-tier words that are in the ledger — they are listed so that a settled meaning does not get two spellings, and their values are not interpreted.

Conversely, a key that is not in the ledger may still be written if it carries a namespace.

space /L1/a room X1..X2 Y1..Y2 acme.sensor:23 bems.temp:22.5 survey.measured:2026-03-11

A namespace is spelled starting with a lowercase letter and containing at least one dot-separated segment ([a-z][a-z0-9_-]* followed by one or more .[a-z0-9_-]+).

WrittenResult
acme.sensor:23carried. core gives the content no meaning whatever
bems.temp:22.5the same
Acme.sensor:23ATT03 — a key starting with a capital is not read as a namespace
acme.Sensor:23ATT03 — segments take no capitals
sensor:23ATT03 — no dot
nmae:居室ATT03 — a misspelling of name. This is the case the rule exists for

core holds no rule about the inside of a namespace, not even how to split it. One dot anywhere makes it carried — that is the whole rule.

Being able to write anything with a namespace is not the same as it meaning something. acme.uid: can be written, but it is carried, and it does not give the space an identity.

The three shapes a value check takes

Interpreted values that do not match the type the ledger sets become diagnostics. A value that was written and not interpreted is never quietly dropped to a default.

CodeWhat it saysExample
ATT01a key requiring a positive number got a non-number, zero, or a negativeh on /L1/a is written as a positive number: h:0
ATT02a value outside a fixed vocabularyceiling on /L1/a is one of 0 / 1: ceiling:2
ATT03a key not in the ledger and not namespacedsee above

A few keys are guarded by their own diagnostics — daylight by DAY01, the direction of a vertical circulation by RUN02, form by RUN05.

daylight is either 1 (in scope for the daylight check) or 0 (out of scope): /L1/b carries daylight:yes
site on zone /L1 is one of 0 / 1: site:yes
style on door (/L1/a | /L1/b) is one of hinged / sliding / auto: style:swing
turn on /L1/b is one of R / L: turn:X

The ledger, element by element

The ledger is closed per element. uid may be written on space and zone and nowhere else — on a boundary it is ATT03.

space

KeyTierValueMeaning
levelstructurea level namestates the level explicitly. Defaults to the first path segment
wstructurea positive integer in mm, or restthe dimension of a band member. Cannot be written on a space outside a band
hinterpretedpositive number, mmceiling height. Defaults to the level's h
useinterpretedfreethe axis of aggregation. Inherited from a zone
roadinterpretedpositive number, mmthe width of an exterior — the mark of a road. Read when frontage is derived
daylightinterpreted0 / 1declares whether the daylight question applies
ceilinginterpreted0 / 10 means no ceiling is built
uidinterpretedan opaque tokenpersistent identity across renames. Not digits alone, no whitespace
nameinterpretedfreedisplay name
stair ramp escalatorinterpretedN / E / S / Wa vertical circulation. The value is the direction of travel going up
liftinterpreted1a lift. It has no direction
forminterpretedstraight / returnwhether the run turns back
turninterpretedR / Lwhich way it turns
entryinterpretedpositive number, mmdepth of the boarding floor
landinginterpretedpositive number, mmdepth of the intermediate landing
riserinterpretedpositive number, mmthe maximum riser
treadinterpretedpositive number, mmthe target tread
laneinterpretedpositive number, mmthe width of one unit or lane
slopeinterpretedpositive numberthe denominator of the permitted slope (slope:6 = up to 1/6)
floorcarriedfreefloor finish
speccarriedfreethe name of the thing

zone

KeyTierValueMeaning
nameinterpretedfreedisplay name
useinterpretedfreethe axis of aggregation, inherited by the spaces below
siteinterpreted0 / 1marks the site aggregation
areainterpretedpositive number, m²the declared (surveyed) site area, reconciled against the derived one
uidinterpretedan opaque tokensame rule as space

boundary

KeyTierValueMeaning
typestructurewall / open / stair / shaft / voidthe topology of the relation
tstructurepositive number, mmwall thickness, split about the centreline
airstructure0 / 11 = there is a thing, but it blocks neither air nor light (a railing, a fence)
edgestructureN / E / S / Wnarrows the segments to one face seen from the a side
hinterpretedpositive number, mmtop height of an air:1 boundary
nameinterpretedfreedisplay name
speccarriedfreethe name of the thing (RC, LGS, curtain wall, railing…)
firecarriedfreefire rating
soundcarriedfreeacoustic rating

door / window / asset

A door asset is read against the opening ledger. That is deliberate: there must be no attribute that an asset can carry and an opening cannot.

KeyTierValueMeaning
wstructurepositive number, mmwidth. Required (the asset may supply it)
hstructurepositive number, mmheight
atstructurea 0..1 ratio, or a grid referenceposition
edgestructureN / E / S / Wpicks a face when there are several segments
hingestructureN / E / S / Wthe jamb the hinge sits on
swingstructurea / bwhich side it opens toward
styleinterpretedhinged / sliding / autothe kind of leaf
nameinterpretedfreeunique within the boundary — the key to an opening's identity
sillcarriedfreesill height
spec firecarriedfree

area / seg / column

ElementStructureInterpretedCarried
area(the region is positional)namefloor spec
segw at edgenamespec fire sound
columnd x ynamespec

level holds no attribute dictionary

level takes exactly h, slab, pitch and underground; nothing else, not even with a namespace.

level carries undergound:, which is not in the ledger (level reads h / slab / pitch / underground)
level carries acme.x:, which is not in the ledger (level reads h / slab / pitch / underground)

Everything a level holds is a typed field, so there is no attribute dictionary to put a leftover key in. A leftover would vanish without a trace in the machine format — so unless it is refused here, undergound:1 quietly becomes an above-ground storey.

Inheritance and override

There are exactly three paths along which an attribute travels between elements.

use is inherited from zone to space

Only the axis of aggregation is genuinely inherited. The use of the deepest zone whose path is a prefix of the space's path is handed down, and a declaration on the space wins.

koyu 1.0
name 継承の例
grid X 0 4000 8000
grid Y 0 4000
level L1 0 h:2400 slab:150
zone /L1/A name:Aタイプ use:exclusive
space /L1/A/ldk  ldk  X1..X2 Y1..Y2 name:LDK
space /L1/A/hall hall X2..X3 Y1..Y2 name:玄関 use:common
By use: exclusive 16.00 m2 (50.0%) / common 16.00 m2 (50.0%)

/L1/A/ldk received exclusive from the zone without writing it; /L1/A/hall overrode it with its own common.

floor overrides space → area, and spec overrides boundary → seg, over an interval

area and seg are segmentations that are not counted. They carry a region or an interval, and the attributes that differ only there.

space /L1/ldk ldk X1..X2 Y1..Y2 floor:オーク
  area X1..X1+1800 Y1..Y1+1800 name:土間 floor:タイル

boundary /L1/ldk /L1/corridor spec:LGS
  seg w:1800 at:0.5 spec:受付ガラス

This is an override over an interval — not composition, not inheritance. The value of the segmentation is read for its region or its interval, and the parent's value is read outside it. Segmentations affect neither area nor room count nor the graph; only spaces and boundaries are counted.

Nothing else travels

The flow from an asset to an opening looks like an exception. An asset's attributes become the opening's defaults, and attributes written on the opening line override them. That is not inheritance but a reference — a way to keep a bundle of default values in one place. A name inherited from an asset is the name of a type, not a claim about that opening's identity: hanging the same product twice on one wall is ordinary design.

Nor is it inheritance when h falls back from a space to its level. That is a rule of derivation: read the space's h, and failing that the level's. With neither, no shape can be made, and it is SUF01 — see what happens when you write nothing.