# Plans & Interfaces

*Placing several designs in a room, and the component interface that makes one placeable*

**Names:** `plan` `site` `room` `run` `place` `fill` `interface` `wall` `edge` `opening` `feature` `obstacle` `footprint` `mount` `attach` `abut` `needs` `stretch` `expose` `design` `swing` `hinge` `against` `at` `left_of` `right_of` `centre_on` `align` `gap` `facing` `elevation` `pin`

## When to use

A `plan` lays out several parametric designs (a bed, a wardrobe, a run of kitchen
cabinets) in a room and compiles them as one project. A design becomes placeable by
adding an `interface` block to its root `assembly`; nothing else about the design
changes, and it still builds alone. This is Stream 1 of ADR-0060 (#463): the grammar and
the static checks (`ww::plan::*`) are implemented and type-check; the positioning verbs
(`against`, `centre_on`, `fill`, ...) parse and have their references checked, but have
**no geometric effect yet** — nothing is placed into world space, so `status: partial`.
Lowering a `Plan` into a built, pooled scene is ADR-0061 (a later stream).

## Syntax

```text
project ... {
    plan <Name> { ... }          // or `site <Name>`, an exact alias for outdoor work
}
```

Inside a `plan`/`site`:

```text
room <Name> [height=<expr>] [floor=<expr>] {
    start x=<expr> y=<expr>
    wall <Name> x=<expr> y=<expr>     // or `edge` (bounds the room, is not a wall)
    opening <Name> wall=<Name> at=<expr> width=<expr> height=<expr> [sill=<expr>]
        kind=door|window|opening [swing=in|out] [hinge=left|right]
    feature <Name> wall=<Name> at=<expr> kind=<word> [z=<expr>]
    obstacle <Name> x=<expr> y=<expr> w=<expr> d=<expr> [h=<expr>]
}

run <Name> wall=<Name> [from=left|right] [offset=<expr>] [elevation=<expr>] {
    place <Id> <Design> [overrides...] [label=] [finish=] [mirror=] [role=reference] { <verbs> }
    fill <Design> [<Id>]
}

place <Id> <Design> ... { <verbs> }     // also legal directly inside a plan
clearance <RefA> <RefB> min=<expr> [label=]   // plan-level, check-only
```

Positioning verbs inside a `place` body (ADR-0060 §4.5; parsed and reference-checked, no
geometric effect in this stream): `against <Ref>`, `at <len>`, `left_of <Ref> [gap=]`,
`right_of <Ref> [gap=]`, `centre_on <Ref> [with=]`, `align <face> with=<Ref>`,
`gap <Ref> <len>`, `facing <word>`, `elevation <len>`, `pin x= y= [rot=]`,
`clearance <Ref> min=<len>`.

Inside a top-level `assembly`, the `interface` that makes it placeable:

```text
assembly <Name> export=<Name> {
    interface [kind=<word>] [front=pos_x|neg_x|pos_y|neg_y|pos_z|neg_z] {
        expose <param>... [{ standard <len>... }]
        footprint [x=] [y=] [z=] w=<expr> d=<expr> h=<expr>
        mount floor|free|wall [z=<expr>]
        attach <face>...          // default: back
        abut <face>...            // default: none (not abuttable)
        clearance <face> depth=<expr> [width=] [kind=walk|use|swing] [hinge=left|right] [label=]
        needs <role> design=<Name> at=exposed_end|wall_end [min=<expr>]
        stretch <param>...
        mark <Name> [x=] [y=] [z=] [normal=pos_x|neg_x|pos_y|neg_y|pos_z|neg_z]
    }
    ...
}
```

Face words (`attach`/`abut`/`clearance <face>`/`align <face>`, and what a `mark` may not
be named): `front back left right top bottom`. `expose` names either a param of this
assembly or a project param of this file (ADR-0060 Q4) — most catalogue designs keep their
envelope dimensions (`width`, `bench_length`, ...) at project scope, not assembly scope.

## Example

```kdl fragment=project
materials {
    material Oak type=hardwood
}
assembly Board export=Board {
    params {
        w 100.0 min=50.0 max=200.0 label="Width"
    }
    interface kind=panel {
        expose w
        footprint w=w d=10.0 h=10.0
        mount floor
        attach back
        abut left right
        clearance front depth=600.0 kind=walk label="Walkway"
    }
    part Panel {
        stock Oak w 10.0 10.0
        by top_sw
        pos x=0.0 y=0.0 z=0.0
    }
}
plan Room {
    room Main height=2400.0 {
        start x=0.0 y=0.0
        wall S x=4000.0 y=0.0
        wall E x=4000.0 y=3000.0
        wall N x=0.0    y=3000.0
        wall W x=0.0    y=0.0
    }
    place B1 Board w=120.0 label="Board" {
        against S
        centre_on S
    }
}
```

## Pitfalls and diagnostics

- **`ww::plan::duplicate_plan`** — at most one `plan`/`site` per project (ADR-0060 Q2).
- **`ww::plan::plan_in_import`** — plans are not importable (Q15); an imported file
  declaring one is refused at the `import` line.
- **`ww::plan::no_footprint`** / **`duplicate_interface`** — an `interface` needs exactly
  one `footprint`.
- **`ww::plan::reserved_param`** — `expose` may not name `label`, `finish`, `mirror` or
  `role`: those are reserved `place` overrides.
- **`ww::plan::mark_shadows_face`** — an interface `mark` may not be named `front`,
  `back`, `left`, `right`, `top` or `bottom`.
- **`ww::plan::room_not_closed`** / **`room_self_intersecting`** / **`opening_off_wall`**
  — pure 2D geometry over literal room coordinates; a room whose walls depend on an
  unresolved CEL expression is checked at Stage 2 instead (not yet implemented).
- **`ww::plan::unknown_design`** / **`no_interface`** — `place`/`fill`/`needs design=`
  names a top-level assembly of this file or an import, and that design has an
  `interface`.
- **`ww::plan::not_exposed`** — a `place` override must name a param the design's
  `interface` exposes.
- **`ww::plan::standard_out_of_range`** — an `expose ... { standard ... }` size must lie
  inside the param's own `min..max`.
- **`ww::plan::fill_without_stretch`** — `fill <Design>` needs a design with a `stretch`
  param.
- **`ww::plan::not_abuttable`** — a design with no `abut` faces (and no `needs`, which the
  compiler would otherwise add fillers/end panels for) cannot sit mid-run.
- **`ww::plan::duplicate_name`** / **`unknown_ref`** / **`ambiguous_ref`** — walls,
  openings, features, obstacles, runs and places share one namespace per plan.
- **`ww::plan::mount_needs_wall`** — a `mount wall` design placed outside a `run` needs an
  explicit `against <Wall>`.
- A `place`'s overrides are evaluated like a `--set` on the design's own file (ADR-0060
  §5.3): this stream checks the override resolves and lies in range, but does not yet
  build a specialised instance — that is ADR-0061's lowering.

## See also

`parts-and-assemblies` (an assembly's own params and `part`/`instance=`),
`reuse-and-collections` (`import`/`export=`, the mechanism `place`'s design names resolve
through), `project-and-params` (`expose`'s project-scope half, ADR-0060 Q4).

## Names

Every name this page declares, how the example library uses it, and the shortest real use.

### `plan`

project-level node; not used by any example yet.

### `site`

project-level node; not used by any example yet.

### `room`

word-valued property; not used by any example yet.

### `run`

node in 2 of 116 examples (2 uses).

Shortest real use, from `postmodern_broken_pediment_cabinet.kdl`:

```kdl
run          "w / 2.0 - gap_w / 2.0"
```

### `place`

not used by any example yet.

### `fill`

property; property in 10 of 116 examples (10 uses).

Shortest real use, from `deco_side_chair.kdl`:

```kdl
material Stuffing type=fabric weave=velvet color="#1f4d3c" fill="'webbing, springs and horsehair under a velvet cover (one solid stands for all of it)'"
```

### `interface`

not used by any example yet.

### `wall`

word-valued property; not used by any example yet.

### `edge`

property; property in 23 of 116 examples (45 uses).

Shortest real use, from `tall_white_cutout_cabinet.kdl`:

```kdl
rabbet face=pos_x edge=pos_y width=back_th depth=rd
```

### `opening`

word-valued property; not used by any example yet.

### `feature`

not used by any example yet.

### `obstacle`

not used by any example yet.

### `footprint`

not used by any example yet.

### `mount`

not used by any example yet.

### `attach`

not used by any example yet.

### `abut`

not used by any example yet.

### `needs`

not used by any example yet.

### `stretch`

not used by any example yet.

### `expose`

not used by any example yet.

### `design`

word-valued property; not used by any example yet.

### `swing`

word-valued property; not used by any example yet.

### `hinge`

word-valued property; value in 1 of 116 examples (2 uses).

Shortest real use, from `ebonised_incised_cabinet.kdl`:

```kdl
component StrapR role=hinge {
    stock Brass hinge_len 3.0 22.0
    cut_path depth=0.0 face=neg_y keep="inside" {
        polyline {
            point x=hinge_len y=0.0
            point x=18.0 y=0.0
            point x=0.0 y=11.0
            point x=18.0 y=22.0
            point x=hinge_len y=22.0
        }
    }
}
```

### `against`

not used by any example yet.

### `at`

property; node in 47 of 116 examples (1024 uses); property in 10 of 116 examples (18 uses).

Shortest real use, from `windsor_round_stool.kdl`:

```kdl
at z=-4.0 { circle r=rf }
```

### `left_of`

not used by any example yet.

### `right_of`

not used by any example yet.

### `centre_on`

not used by any example yet.

### `align`

not used by any example yet.

### `gap`

node in 1 of 116 examples (1 uses).

Shortest real use, from `drawer_stack.kdl`:

```kdl
gap     10.0 min=4.0   max=30.0  step=1.0  label="Gap between drawers"
```

### `facing`

not used by any example yet.

### `elevation`

not used by any example yet.

### `pin`

node in 19 of 116 examples (35 uses).

Shortest real use, from `appalachian_ladder_back_side_chair.kdl`:

```kdl
pin shape=round size=3.0
```

## Related terms

- [Gilt-bronze mount](/almanac/techniques#gilt-bronze-mount)
- [Hardware mount](/almanac/techniques#hardware-mount)
- [Hinge](/almanac/techniques#hinge)
- [Peg](/almanac/techniques#peg)
- [Shadow gap](/almanac/techniques#shadow-gap)
