diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-07 00:46:29 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-07 00:46:29 -0500 |
| commit | eef4b44b461a21fb99eedc4a70cb3f25fc536ba9 (patch) | |
| tree | 4197b2dcbbdc7febd50580745f9af4ae25549cf8 /scripts/README.org | |
| parent | fef03a1f4f19c45a31928989aecb4ff8a47cea4a (diff) | |
| download | pearl-eef4b44b461a21fb99eedc4a70cb3f25fc536ba9.tar.gz pearl-eef4b44b461a21fb99eedc4a70cb3f25fc536ba9.zip | |
fix(scripts): seed column types for board order, healing type drift
The seed put Triage on the unstarted type and Backlog on the backlog type. Linear's board orders columns by type category first (backlog before unstarted) and only then by position, so it grouped Icebox and Backlog together and pushed Triage to the right of Backlog. Position couldn't fix it: a state's type is immutable (workflowStateUpdate takes name, color, description, and position only), so the columns had to be retyped at the source.
To make the board read Icebox, Triage, Backlog, two of the three pre-work columns have to be the backlog type and the third the unstarted one Linear renders last. So Icebox and Triage are now backlog and Backlog is the team's unstarted state, which also satisfies Linear's rule that a team keep one.
Since type can't change in place, the reconcile gained a recreate path: a column found with the wrong type gets a fresh state of the right type, its issues moved over, and the old one archived. The phases are ordered so a new unstarted state exists before the old one is archived, and so a name is freed before another column reuses it. That lets a re-run heal a workspace seeded under the old layout, which is how I fixed the live one (Triage and Backlog recreated, 32 issues moved). Matching now prefers a type-correct state and only recreates when there's none, so the same targets build a fresh team and heal an existing one.
pearl's own grouped view needed no change — it already orders sections the way Linear's board does, by type rank then position, so the migrated types sort it correctly.
Diffstat (limited to 'scripts/README.org')
| -rw-r--r-- | scripts/README.org | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/scripts/README.org b/scripts/README.org index 5d5ab6d..0f180c5 100644 --- a/scripts/README.org +++ b/scripts/README.org @@ -53,31 +53,41 @@ the repo. A convenient way to pass it: ** Notes +- *Column types are chosen for board order.* Linear's board orders columns by + type category first (backlog before unstarted), then by position within a + category, so position alone can't move a column across a type boundary. To get + Icebox, Triage, Backlog all left of In Progress in that order, Icebox and + Triage are the backlog type and Backlog is the unstarted state (rendered last + in the pre-work group). Backlog being the unstarted state also satisfies + Linear's rule that a team keep one. + - *Reconcile, not create-from-scratch.* Linear's =teamCreate= seeds its own default columns, and Linear dedups state names case-insensitively, so a naive - "create all six" run collides with the defaults. The script instead renames - the defaults into the six Agile columns (keeping Backlog, In Progress, Done, - Canceled, and repurposing the unstarted Todo as Triage) and creates - only the genuinely-new Icebox. - -- *It never archives.* A Linear team must keep at least one unstarted state, and - the Duplicate state is reserved, so neither can be removed by API. The script - leaves any column it doesn't claim (Duplicate, which Linear hides in the board - UI) and reports it rather than failing. - -- *Positions are set in a second pass with distinct nonzero values.* Linear + "create all six" run collides with the defaults. The script reconciles by + name: it reuses a same-named (or default-aliased) state of the right type, and + creates only what's genuinely missing. On a fresh team Icebox takes over the + default backlog "Backlog" and Backlog takes over the unstarted "Todo". + +- *Wrong-type columns are recreated.* A state's type is immutable + (=workflowStateUpdate= takes name/color/description/position only), so a column + found with the wrong type can't be fixed in place. The script creates a fresh + state with the right type, moves the old state's issues onto it, and archives + the old one. The phases are ordered so a new unstarted state exists before the + old unstarted one is archived, and so a name is freed before another column + reuses it. This is what lets a re-run heal a workspace seeded under the older + type layout. + +- *The Duplicate state is left alone.* It's reserved and Linear hides it in the + board UI; the script reports it as a leftover rather than touching it. + +- *Positions are set in a final pass with distinct nonzero values.* Linear ignores a 0.0 position and appends a freshly-created state at a high one, so - the script updates positions after the states exist. + the script sets positions after the states exist. - *Grouping isn't set at view-create time.* Linear's =CustomViewCreateInput= has no grouping field, so Pearl Open Issues is created with its filter only. Group it by category in pearl with =pearl-set-grouping=, or in the Linear UI. -- *Triage is the unstarted type* (it took over the default Todo). pearl's - grouped view orders sections by state type and then position, so Triage - lists after the backlog columns in pearl even though the Linear board keeps - your column order. - - *New issues default to Triage, not Backlog.* The script points the team's default new-issue state at Triage (the intake column) after the columns reconcile, so a fresh issue lands there. |
