<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pearl/scripts/README.org, branch main</title>
<subtitle>Pearl Edits and Reflects Linear — manage Linear.app issues as org-mode in Emacs
</subtitle>
<id>https://git.cjennings.net/pearl/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/pearl/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/'/>
<updated>2026-06-07T05:46:29+00:00</updated>
<entry>
<title>fix(scripts): seed column types for board order, healing type drift</title>
<updated>2026-06-07T05:46:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-07T05:46:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=eef4b44b461a21fb99eedc4a70cb3f25fc536ba9'/>
<id>urn:sha1:eef4b44b461a21fb99eedc4a70cb3f25fc536ba9</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat(scripts): import an org backlog into the Pearl workspace</title>
<updated>2026-06-07T04:53:52+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-07T04:53:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=fef03a1f4f19c45a31928989aecb4ff8a47cea4a'/>
<id>urn:sha1:fef03a1f4f19c45a31928989aecb4ff8a47cea4a</id>
<content type='text'>
I had 44 open tasks in the org backlog and no way to get them into Linear short of typing each one in by hand. This adds a script that reads the level-2 TODO/DOING headings under the "Pearl Open Work" section and creates one issue per task.

The priority cookie maps to Linear priority, a [#D] "someday" task lands in Icebox and the rest in Backlog, tags become labels (missing ones created), and the heading body becomes the description. The discuss/next/cleanup/pearl workflow tags are dropped rather than turned into labels. It skips a task whose title already exists, so a re-run only fills in what's missing, and the two umbrella headings plus the Resolved section are left out.

Same shape as the seed script: a pure parser and mapper with no I/O, behind a thin GraphQL client that's the only network boundary, so a fake transport routing on the operation name covers the import end to end. 8 tests across parse, mapping, and the import flow.
</content>
</entry>
<entry>
<title>fix(scripts): make Triage the intake column and the default new-issue state</title>
<updated>2026-06-06T23:27:47+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-06T23:27:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=7bd9f49ed7cb8482226d70ffaaa3d83fde194710'/>
<id>urn:sha1:7bd9f49ed7cb8482226d70ffaaa3d83fde194710</id>
<content type='text'>
Two problems showed up dogfooding the seeded board. New issues landed in Backlog, because Linear's teamCreate sets the team's default new-issue state to its own Backlog default and the seed never changed it. And the intake column read "Triage Queue" when "Triage" is the name we want.

The script now points the team's defaultIssueStateId at the intake column after the columns reconcile, so a fresh issue opens in Triage instead of Backlog. It skips the update when the default is already correct, so a re-run stays a no-op. The intake column is renamed Triage throughout: the target state, the Pearl Inbox view filter, and INTAKE_STATE. find_team reads defaultIssueState so the idempotence check has something to compare.

Both mutations were schema-introspected first: TeamUpdateInput.defaultIssueStateId and CustomViewUpdateInput.filterData. The live board was fixed the same way (rename, default-state, Inbox filter) and the dry-run against it comes back all-update, no-create. 13 tests cover the rename, the default-state set on a fresh seed, and the skip when it's already Triage.
</content>
</entry>
<entry>
<title>docs(scripts): add a scripts README</title>
<updated>2026-06-06T22:40:23+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-06T22:40:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=4250bbb39ab1f01a09567ea8f202c2109a2dad30'/>
<id>urn:sha1:4250bbb39ab1f01a09567ea8f202c2109a2dad30</id>
<content type='text'>
scripts/README.org is the single home for documentation about the helpers under scripts/. A Purpose section says what the file is for, then one heading per script with its purpose, usage, and notes. It documents seed_pearl_workspace.py (including the Linear constraints that shaped its reconcile model) and coverage-summary.el, and asks that new scripts add a heading here too.
</content>
</entry>
</feed>
