# Style & Finish Rule

*A style rule keyed to the declared finish*

**Names:** `finish` `one_of`

## When to use

Use the `finish { one_of ... }` predicate when writing a style rule file (`styles/<id>.kdl`)
and the style guide names the surface treatments of its period: what the pieces were
painted, stained, oiled or shellacked with. It grades the `finish=` text a project already
declares (RFC-0122), so a design that says `finish="'milk paint, barn red'"` can be told it
is inside, or outside, the finishes the guide records.

It is advice, like every style rule. A part with no finish is not graded, and a project
where no part declares one reports "not applicable", never a pass.

## Syntax

In a rule file:

```text
rule recorded-finishes level=may cite=36 {
    finish {
        one_of paint painted stain stained varnish oil
    }
}
```

- `one_of` lists one or more words; at least one is required.
- Each part that declares a finish (its own `finish=`, else its material's) is split into
  lower-cased alphanumeric words. The part passes when any `one_of` word equals one of
  them as a **whole word**: `paint` matches "milk paint, barn red" and does not match
  "repainted". List the inflections you mean (`stain stained`, `fumed fuming`).
- Generated parts (dowels, loose tenons) are skipped.
- `cite=` is a line of the guide that records the finish; `level=` is `may` unless the
  guide forbids the others. The two shipped rules are `recorded-finishes` in
  `styles/traditional-shaker.kdl` (guide line 36) and `fumed-shellac-wax` in
  `a style file under styles/` (guide line 28).

## Example

A project the Shaker rule grades. The part inherits "milk paint" from its material and
passes; the second part overrides it with a finish the guide does not record and is
reported by name.

```kdl
project name="Finished Pair" units=mm schema_version=1 {
    params {
        top_w 500.0 min=300.0 max=900.0 step=10.0 label="Top Width" category="Envelope"
    }

    materials {
        material Poplar type=hardwood finish="'milk paint, barn red'"
    }

    assembly Root {
        part Painted material=Poplar role=top {
            stock Poplar top_w 400.0 20.0
            by top_sw
            pos x=0.0 y=0.0 z=0.0
        }
        part Plasticised material=Poplar role=shelf finish="'catalysed lacquer'" {
            stock Poplar top_w 300.0 20.0
            by top_sw
            pos x=0.0 y=0.0 z=100.0
        }
    }
}
```

Run it with `ww style finished-pair.kdl --style shaker`: `recorded-finishes` scores 1 of 2
and reports `Root/Plasticised` is finished "catalysed lacquer", not one of the listed words.

## Pitfalls and diagnostics

- **A passing `finish` rule is weak evidence by itself.** It proves the words, not the
  work: a part can say "oil" and be unfinished. Pair it with rules about shape and joinery.
- **Cite the guide, do not infer.** Take the words from the cited lines. Mission's rule
  omits `oil` because the guide never names it for that style; adding it would be inventing
  history. When a guide records no finish, write no rule.
- **A bare word in `finish=` is a CEL identifier.** Write `finish="'milk paint'"` with the
  inner quotes (ADR-0004), as in the example.
- **Not applicable is not a pass.** An example with no `finish=` anywhere reports "no part
  declares a `finish=`" and contributes nothing to the score; an example whose only finish
  is outside the set can score 0/100 (`welsh_dresser` against Mission).
- `kdl-check` does not read rule files. A rule file error (an empty `one_of`) shows when
  you run `ww style <file> --style <id>`, which exits 2.

## See also

- `docs/adr/0029-style-finish-rule.md`
- `docs/rfc/0122-finish-attribute.md` (the `finish=` attribute this rule reads)
- `styles/README.md` (the predicates), `docs/styles/traditional-shaker.md`,
  `a style guide under docs/styles/`
- `docs/agent-reference/features/grain-axis.md`

## Names

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

### `finish`

property; property in 78 of 116 examples (147 uses).

Shortest real use, from `farmhouse_harvest_table.kdl`:

```kdl
material Pine type=softwood finish="'none'"
```

### `one_of`

not used by any example yet.

