# Tenon Tips & Coped Rails

*Mitred tenon tips, round-tenon wedges, and coped stile-and-rail joints*

**Names:** `tip` `wedge` `stile_and_rail`

Three gaps in the tenon family, closed by ADR-0026. Source of truth for the language is
`docs/KDL_AUTHORING.md` §8 (the joinery section); this page is the agent's quick card.

## When to use

- **`tip mitre=#true`** — two rails tenon into the *same* post from different faces (a
  desk's apron and side apron into one leg; a chair's seat rail and side rail). Their
  tenons would cross inside the leg; mitring the tips lets each be long. Without it the
  `tenons-meet` rule refuses the pair.
- **`wedge` on a `round_tenon`** — a round tenon driven through its mortised part and
  wedged in a kerf (a stool leg through its seat, a chair stretcher through a leg). The
  rectangular `mortise_and_tenon` has had `wedge` since M15; this is the round one.
- **`profile "ogee"` (or any moulding) on `stile_and_rail`** — a cope-and-stick door or
  frame: the inside edges are stuck with a moulding, and each rail end is coped to it.
  `profile "square"` (the default) is still the flat frame.

## Syntax

Mitred tips — one line in the body of **both** joints that meet:

```text
joinery mortise_and_tenon name=Apron_to_Leg {
    tenon_thickness 10.0
    tenon_length 48.0
    clearance 0.2
    tip mitre=#true
}
```

Round-tenon wedge — the tenon must be through (`through #true`, or `length` reaching the
far face); the kerf is sawn across the grain of the mortised part:

```text
joinery round_tenon name=Leg_to_Seat {
    diameter 22.0
    length 40.0
    through #true
    wedge kerf=3.0 depth=18.0 flare=2.0 flare_depth=10.0
}
```

Stuck profile — `profile` is a moulding name, `profile_size` its projection in mm, and
`profile_face` the way the frame's show face looks **in the assembly's axes**, written as
a CEL string (`"'neg_y'"`):

```text
profile "ogee"            // ovolo cove ogee thumbnail half_round cockbead; "square" is flat
profile_size 5.0
profile_face "'neg_y'"    // pos_x neg_x pos_y neg_y pos_z neg_z
```

## Example

A single door, stiles and rails 20 mm thick, the front (`neg_y`) stuck with a 5 mm ogee.
The right stile is the left turned half round and the bottom rail is turned over; the
sticking still lands on the front of all four members, because `profile_face` is a world
direction.

```kdl
project name="stuck_door" units=mm schema_version=1 {
    materials {
        material Softwood type=softwood
    }

    component DoorStile {
        stock Softwood 60.0 20.0 500.0
        groove target=panel face=pos_x width=8.0 depth=10.0 offset=6.0
        mark RailSeat_Top x=60.0 y=10.0 z=-30.0 normal=pos_x
        mark RailSeat_Bot x=60.0 y=10.0 z=-470.0 normal=pos_x
    }

    component DoorRail {
        stock Softwood 280.0 20.0 60.0
        groove target=panel face=neg_z width=8.0 depth=10.0 offset=6.0
        mark Stile_Left x=0.0 y=10.0 z=-30.0 normal=neg_x
        mark Stile_Right x=280.0 y=10.0 z=-30.0 normal=pos_x
    }

    joinery stile_and_rail name=DoorFrameJoint {
        groove_width 8.0
        groove_depth 10.0
        stub_tenon_length 12.0
        profile "ogee"
        profile_size 5.0
        profile_face "'neg_y'"
    }

    assembly Root {
        part DoorStile_L instance=DoorStile {
            pos x=0.0 y=0.0 z=0.0
        }
        part DoorStile_R instance=DoorStile {
            pos x=400.0 y=20.0 z=0.0
            rot z=180.0
        }
        part DoorRail_Top instance=DoorRail {
            pos x=60.0 y=0.0 z=0.0
        }
        part DoorRail_Bot instance=DoorRail {
            pos x=60.0 y=20.0 z=-500.0
            rot x=180.0
        }

        join joint=DoorFrameJoint male=DoorRail_Top@Stile_Left female=DoorStile_L@RailSeat_Top
        join joint=DoorFrameJoint male=DoorRail_Top@Stile_Right female=DoorStile_R@RailSeat_Top
        join joint=DoorFrameJoint male=DoorRail_Bot@Stile_Left female=DoorStile_L@RailSeat_Bot
        join joint=DoorFrameJoint male=DoorRail_Bot@Stile_Right female=DoorStile_R@RailSeat_Bot

        part DoorPanel role=panel {
            stock Softwood 296.0 8.0 396.0
            pos x=52.0 y=6.0 z=-52.0
        }
    }
}
```

## Pitfalls and diagnostics

- `tenons-meet` — two tenons run into each other inside one part. Shorten them, or write
  `tip mitre=#true` on **both** joints. `tip-mitre` — the mitre needs tenons that meet at
  an angle (parallel axes have no bisector), and the bisector plane may not cut a tenon's
  own rail: use shorter tenons. The mortises are **not** clipped to the mitre (they stay the
  full rectangular pockets); only the male tips are.
- `wedge-kerf` — the wedge needs a *through* round tenon (`through #true`); `depth` must be
  at least `flare_depth` and at most three quarters of the tenon's run through the mortised
  part; a kerf may be no closer than 1.5× its width to the tenon's surface or another kerf.
  `wedge-grain` — the wedges spread the tenon along the mortised part's **grain** (spreading
  across it splits the part): declare `grain` on it, otherwise the longer of its two faces
  square to the tenon is taken; a tenon in end grain is refused. `wedge-flare`,
  `wedge-frame` — see `docs/KDL_AUTHORING.md`.
- `params` — a stuck `profile` needs both `profile_size` and `profile_face`; an unknown
  profile or face word is named. `profile_size`/`profile_face` with `profile "square"` is
  only a warning (they do nothing).
- `cope-profile` — the sticking would cut into the panel groove (`profile_size` larger than
  the wood between the show face and the groove: for a 20 mm member with an 8 mm groove,
  6 mm), is deeper than half the rail's width, `profile_face` names a narrow edge of the
  rail or a way no member's side face looks, or the shoulder is off square.
- `profile_face` is a **world** direction, never part-local: a door's right stile and
  bottom rail are usually the same component turned. Check the face against the *assembly*.
- The cope has no clearance: `clearance` belongs to the groove (D8, ADR-0012). The cope
  is the stile's sticking void exactly, to the chord of the 16-segment section.

## See also

- `docs/KDL_AUTHORING.md` §8 — "Mitred tips", the round `wedge`, and the `stile_and_rail`
  stuck-profile paragraph.
- `docs/adr/0026-tenon-tips-wedges-and-coped-rails.md` — the three decisions and their
  evidence; RFC-0041, RFC-0126, RFC-0127.
- `docs/agent-reference/nodes.md` — the node index.
- Examples: `examples/desk.kdl` and `examples/dining_chair.kdl` (`tip mitre=#true`);
  `docs/styles/models/stile-and-rail.kdl` (the glossary's frame joint).

## Names

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

### `tip`

node in 15 of 116 examples (22 uses).

Shortest real use, from `deco_console_table.kdl`:

```kdl
tip mitre=#true
```

### `wedge`

node in 6 of 116 examples (8 uses).

Shortest real use, from `wedged_post_and_rung_stool.kdl`:

```kdl
wedge kerf=3.0 depth=18.0 flare=2.0 flare_depth=10.0
```

### `stile_and_rail`

joinery kind; value in 9 of 116 examples (9 uses).

Shortest real use, from `ebonised_incised_cabinet.kdl`:

```kdl
joinery stile_and_rail name=PanelFrame {
    groove_width panel_th
    groove_depth groove_d
    stub_tenon_length stub_l
    profile "square"
}
```

## Related terms

- [Kusabi](/almanac/techniques#kusabi)
- [Rail](/almanac/techniques#rail)
- [Stile](/almanac/techniques#stile)
- [Stile-and-rail joint](/almanac/techniques#stile-and-rail)
- [Wedged tenon](/almanac/techniques#wedged-tenon)
