← Skills

SIP Interface Rules

Native Read-only

Static connection rules between SIP components: roof-to-wall, wall-to-foundation, wall-to-wall corners, and opening-to-wall. Injected alongside domain skills.

/skills/sip_interfaces.md

Estimated tokens
2104
Characters
8414
Source
Native

Markdown

# SIP Interface Rules Skill

This skill describes the **static connection rules** between SIP component types. Every agent that interfaces with another component receives this skill. Use it to know which side of a connection you are responsible for, and what dimensions to use.

Dimensional values are declared in the `connection_details` catalog injected into this stage. Reference catalog entries by key rather than hardcoding values.

> **Note on dynamic dimensions:** This skill covers interface *rules* (who cuts what, where). The *actual dimensions* of adjacent components (e.g. the exact thickness of the roof panel chosen for this project) are resolved at manifest time and passed via the agent's `domain_knowledge` and `interfaces_provided` fields. Use those values when available; fall back to catalog defaults when not.

---

## Roof-to-Wall Interface

**Rule:** The wall agent is responsible for the connection geometry at its top edge. The roof agent bears on the wall top plate and does not modify the wall.

**Wall agent responsibilities:**
- The double top plate (2× 45×90mm timber) provides the bearing surface for the roof panel.
- For pitched roofs: the top plate must be cut at the pitch angle so the roof panel bears flat. Model this as an angled-cut top plate or use a separate angled bearer.
- For flat roofs: the top plate is horizontal; the roof panel bears flat on it with no cuts needed.
- The wall top plate depth is `CORE_THICKNESS` (not `TOTAL_THICKNESS`) — it slots into the foam groove.

**Roof agent responsibilities:**
- The roof panel eave end bears on the wall top plate.
- For pitched roofs: cut the eave bevel (`eave_bevel_y = TOTAL_THICKNESS / tan(PITCH_RAD)`) so the panel bears cleanly.
- For flat roofs: the panel bottom face sits directly on the top plate — no cuts needed.

**Shared dimension:**
- `PANEL_THICKNESS` (wall SIP total thickness) defines the inset for roof panel positioning:
  - Mono-pitch: `Placement(Vector(0, PANEL_THICKNESS, EAVE_HEIGHT), rot)`
  - Duo-pitch south: `Placement(Vector(0, PANEL_THICKNESS, EAVE_HEIGHT), rot)`
  - Duo-pitch north: `Placement(Vector(0, BUILDING_DEPTH - PANEL_THICKNESS, EAVE_HEIGHT), rot)`

---

## Wall-to-Foundation Interface

**Rule:** The wall agent is responsible for the sole plate (bottom plate) at Z=0. The foundation agent is responsible for the slab surface and DPC layer.

**Wall agent responsibilities:**
- Create a 45×90mm PT timber bottom plate at Z=0 as the first solid.
- Plate depth = `CORE_THICKNESS` (not `TOTAL_THICKNESS`) — it slots into the foam groove.
- Y-offset = `FACE_THICKNESS` so OSB skins overhang on both faces.
- SIP panels start at Z=90 (top of bottom plate).

**Foundation agent responsibilities:**
- The slab top surface is at Z=0.
- A DPC (damp proof course) layer sits between slab and bottom plate — model as a 3mm high-density polyethylene layer if required, or omit for clarity.
- The slab extends `SLAB_OVERHANG` (minimum 200mm) beyond the wall footprint on all sides.

**Connection detail:** `sole_plate_to_slab` in the `connection_details` catalog.

---

## Wall-to-Wall Corner Interface

**Rule:** For L-corners, one wall runs full length to the outer face; the perpendicular wall butts against it. A double block spline fills the internal corner pocket.

**Responsibility split:**
- The "full-length" wall includes the corner panel at its end — no special treatment needed.
- The "butting" wall's end panel butts against the exterior OSB face of the full-length wall. Its bottom plate runs to the face of the full-length wall. A double block spline (2× 45×90mm) fills the corner pocket on the butting wall's end.

**Corner spline geometry:**
```python
# Double block spline at L-corner (butting wall end)
# Both splines sit in the foam channel, side by side
spline_a = Part.makeBox(45, 90, PANEL_HEIGHT,
                        Vector(x_corner, (TOTAL_THICKNESS - 90) / 2, BOTTOM_PLATE_H))
spline_b = Part.makeBox(45, 90, PANEL_HEIGHT,
                        Vector(x_corner + 45, (TOTAL_THICKNESS - 90) / 2, BOTTOM_PLATE_H))
```

---

## Volume-to-Volume Interface (multi-volume compositions)

**Rule:** Where two volumes touch, the touching walls are **one wall, built
once** — never two panels back to back. SIP panels join edge-to-edge through
splines; a face-to-face pair has no structural connection between the leaves,
only two independent racking planes with a sealed cavity that cannot be
inspected or dried. Dimensions come from the `wall_abutment` and
`shared_wall_ownership` entries in the `junctions` catalog.

**Responsibility split:**
- The **taller volume is the host** and builds the shared wall (ties break by
  longer span, then volume id). It needs no special treatment — it is an
  ordinary through wall.
- The **guest** builds nothing on that edge where the host covers it: the wall
  is marked `suppressed_by_adjacency`. The design entity survives on the
  footprint edge — a declared non-materialisation, never a hole — but **no
  component is generated**. If you are a guest wall agent on a suppressed edge,
  you have no geometry to build.
- The guest's **abutting side walls** butt into the host wall's face through an
  abutment post, and own that post the same way a butting wall owns its corner
  spline.

**Abutment post geometry:** 90mm wide × **full guest-wall thickness deep**
(`POST_D = TOTAL_THICKNESS`, the same rule as king studs — a 90mm-deep post
centred in the foam leaves the guest panel's OSB faces bearing on nothing).
Fixed with structural screws at 300mm centres, 75mm end offset, through the
guest panel into the post and through the post into the host panel. Panel
adhesive at the interface and joint tape on **both** faces: the abutment is an
airtightness and weather line, not only a structural joint.

```python
# Abutment post at the guest wall's end where it meets the host face
post = Part.makeBox(90, TOTAL_THICKNESS, PANEL_HEIGHT,
                    Vector(x_abut, 0, BOTTOM_PLATE_H))
n_screws = int((PANEL_HEIGHT - 2 * 75) // 300) + 1
```

**Different heights — the step case:** coverage is **2D**. A connection covers a
rectangle of the interface wall: horizontal span AND vertical band. Where the
volumes differ in height the guest's wall is `partial_infill`, and the guest
**must build real panel** in the uncovered band named by `infill_spans` /
`infill_band`. Above the shorter volume's roof line the shared wall becomes
**external**, so external finish and the weather line start at the guest roof
top, not at the wall base, and the step is closed by the `flat_guest_upstand`
flashing.

**Non-negotiable:** never generate a second wall on an edge the host already
builds — a doubled pair is a 284mm uninspectable dead cavity, not a wall. And
never treat a wall as fully suppressed on plan overlap alone: a stepped wing
suppressed horizontally is built with a hole beneath the host's floor, open to
the ground.

---

## Opening-to-Wall Interface

**Rule:** Openings (windows, doors) are framed within the wall component. The wall agent is responsible for stopping SIP panels at the king stud face and building the full-depth timber buck. If a window or door is described in the wall brief, the wall component includes all framing — there is no separate framing agent.

**King stud depth:** `KING_D = TOTAL_THICKNESS` (full wall thickness, not 90mm).

**Opening agent (if separate):** A separate opening agent adds only the glazed unit or door leaf — it does NOT build framing. Its X position, width, and height come from the wall agent's `interfaces_provided`.

---

## Quick Interface Checklist

Before generating any component that touches another, confirm:

| Check | Wall | Roof | Foundation | Opening |
|---|---|---|---|---|
| Sole plate at Z=0 with CORE_THICKNESS depth | ✅ my responsibility | — | — | — |
| Top plate angled for pitched roof | ✅ my responsibility | — | — | — |
| Eave bevel cut | — | ✅ my responsibility | — | — |
| Slab extends SLAB_OVERHANG beyond walls | — | — | ✅ my responsibility | — |
| King studs are TOTAL_THICKNESS deep | ✅ (if I have openings) | — | — | ✅ |
| Corner spline on butting wall end | ✅ (butting wall only) | — | — | — |
| No component on a `suppressed_by_adjacency` edge | ✅ my responsibility | — | — | — |
| Panel built in every `partial_infill` band | ✅ my responsibility | — | — | — |
| Abutment post is TOTAL_THICKNESS deep | ✅ (guest abutting wall) | — | — | — |
v0.0.985