Board DSL — Groups
Groups band columns together. This page covers group blocks, the three-scope
groups: semantics, and depth bands. See the reference index for
the board header and the other constructs.
Group blocks (board-level groups:, lane groups:, sub-groups:)
A group block bands columns together. It carries a required name and any
of columns: / lanes: / groups: (the children, by kind), plus optional
agreements: / interactions: / tags: / status-category: metadata.
| Field | Values / shape | Default | Diagnostic on misuse |
|---|---|---|---|
name | string (required) | — | board.invalid-group (block skipped when missing/empty) |
columns | list of column entries (banded under this group) | (none) | per-entry board.invalid-column |
lanes | list of lane entries (a group hosting nested lanes) | (none) | per-entry board.invalid-lane |
groups | list of sub-group blocks | (none) | per-entry board.invalid-group |
agreements | string OR string list — group working agreements | (none) | tolerant |
interactions | string OR string list — group meeting / interaction pointers | (none) | tolerant |
tags | string list (descriptive category chips, rendered visibly) | (none) | tolerant |
status-category | single value, closed set to-do | in-progress | done | waiting | assess (group-band tint) | (none) | board.invalid-status-category |
A group path nested deeper than 3 levels emits board.nested-too-deep and
the deeper levels are ignored. (A lane is a container, not a group level — a
depth-3 group path inside a lane is not capped by the lane wrapper.)
The three-scope groups: semantics. The same word groups: means three
different things depending on where it appears — the parser dispatches on
scope, not on the key name:
Where groups: appears | Means | Parser behavior |
|---|---|---|
| Board level | a group sidecar | columns-only → flatten columns into ast.columns (carrying a group: path) + emit a metadata-only sidecar into ast.groups; lane-hosting → a first-class BoardGroup |
| Lane level | the lane’s children | merged into the lane children array (columns-then-groups); columns-only → flatten + sidecar; lane-hosting → first-class |
| Group level | sub-groups | recursive nested children, depth-capped at 3 |
Placing groups: at an unintended level is the construct most likely to produce
the wrong shape — match the scope to the meaning above.
Depth bands & layout. Groups render as depth bands .group-bar-l1 / -l2 /
-l3. A flat layout (all bands same depth) stacks the bands over one
columns row, each band spanning its columns; a nested layout (any depth ≥ 2)
nests .group-section containers so an L1 band visually contains its L2 bands
which contain their columns. Multiple parallel sibling L1 groups (N ≥ 2) render
as siblings, not nested. A group’s status-category: renders as a
.group-status-lozenge on the band (a lozenge, not a full band tint — this
preserves the L1/L2/L3 hierarchy color).
Pitfall — quote a name that is a YAML keyword. YAML auto-types bare scalars: a group or column named
1,true,yes,null, oronwould parse as a number / boolean / null, not a string. Quote any such name:- { name: "1", columns: [a, b] }. Likewise quote anagreements:string that contains a:or starts with a special character.
Example
A focused board with two parallel board-level groups (N ≥ 2 — they render as
sibling bands, not nested), each banding its own columns; one carries a
status-category: lozenge on its band:
title: Roadmap groups: - name: Discovery status-category: assess columns: - Ideas - Shaping - name: Delivery columns: - Build - Done
Like what you see? → Start — build your own org folder in ~2 min