Release sync — worker tags → Linear release waves
One wave = all <worker>/vX.Y.Z tags created on the same UTC day.
Each wave maps to one Linear document on team iii titled
Release YYYY-MM-DD — the combined release note, one ## <worker> vX.Y.Z
section per worker — plus a child label YYYY-MM-DD under the team label
group release, applied to every shipped issue. (This is the free-plan
model; Linear's native Releases feature requires Business+.)
Prerequisites
- Linear MCP tools (the claude.ai Linear connector).
- Team label group release on team iii (create once with
create_issue_label, isGroup: true, if missing).
1. Collect pending tags
git fetch --tags origin
git for-each-ref 'refs/tags/*/v*' --sort=creatordate \
--format='%(refname:short) %(creatordate:short)'
- Only consider tags that still exist on origin (
git ls-remote --tags origin on doubt) — rolled-back local tags don't count.
- With arguments: sync exactly those tags.
- Without arguments: a tag is already synced iff it appears in the
header tag list of an existing wave document (
list_documents,
query Release, team iii — each doc's first line lists its tags; that
list is the idempotency record). Pending = every worker tag not found.
- Skip
-dry-run. tags. Include prereleases (-rc.N, -beta.N) and label
them in the note.
2. Group into waves
Group pending tags by tag creation date (UTC day). If more than 3 waves
would be written (typical of a first backfill), show the plan
(date → tags) and get user confirmation before writing anything.
3. Gather changes per tag
- Previous tag of the same worker:
git tag -l '<worker>/v*' --sort=-v:refname → the entry after the
current one.
- Commits:
git log --format='%h %s%n%b' <prev>..<tag> -- <worker>/
(first release of a worker: git log <tag> -- <worker>/).
- Extract
MOT-\d+ from subjects and bodies. For PR references (#N)
with no MOT id, gh pr view N --json title,body and scan those too.
- Judgment attachments: if a change clearly implements a known issue that
was never referenced, find it via
list_issues (title terms, team iii)
and read the issue to verify it matches before labeling. Never invent
or guess identifiers; when unsure, leave it off and flag it in the
report.
4. Write to Linear (per wave)
- Label: child label
YYYY-MM-DD under group release (team iii,
create_issue_label with parent: release; skip if it exists).
- Label every verified issue: read the issue's current labels first and
pass the union to
save_issue — never drop existing labels.
- Worker labels: also apply flat
worker:<name> team labels
(worker:shell, worker:console, ...) matching the worker commit
ranges that referenced the issue — create missing ones lazily; same
union rule. Flat, NOT a label group: Linear group children are
mutually exclusive, and one issue often spans several workers.
- Document:
save_document on team iii titled Release YYYY-MM-DD
(update the existing one if present — look it up via list_documents).
First line: the full tag list (idempotency record — always complete)
and the wave label name. Body: a ## <worker> vX.Y.Z section per tag
(collapse multiple same-day tags of one worker into
## <worker> vA → vB), 2–5 bullets each — what shipped, why it
matters, breaking changes called out as Breaking:, shipped issues
linked by URL. Plain changelog register; no internal workflow chatter.
5. Report
Table: wave date → document URL → tags → labeled issues. Flag tags where
no issues were found and any judgment attachments made.
Rules
- Never change issue status, never create issues, never remove existing
labels from an issue.
- Re-runs must converge: a late same-day tag merges into the existing
wave document and the note is regenerated to include it.
1---2name: release-sync3description: Release sync — worker tags → Linear release waves4---56# Release sync — worker tags → Linear release waves78One **wave** = all `<worker>/vX.Y.Z` tags created on the same UTC day.9Each wave maps to one **Linear document** on team **iii** titled10`Release YYYY-MM-DD` — the combined release note, one `## <worker> vX.Y.Z`11section per worker — plus a child label `YYYY-MM-DD` under the team label12group **release**, applied to every shipped issue. (This is the free-plan13model; Linear's native Releases feature requires Business+.)1415## Prerequisites1617- Linear MCP tools (the claude.ai Linear connector).18- Team label group **release** on team iii (create once with19 `create_issue_label`, `isGroup: true`, if missing).2021## 1. Collect pending tags2223```bash24git fetch --tags origin25git for-each-ref 'refs/tags/*/v*' --sort=creatordate \26 --format='%(refname:short) %(creatordate:short)'27```2829- Only consider tags that still exist on origin (`git ls-remote --tags30 origin` on doubt) — rolled-back local tags don't count.31- With arguments: sync exactly those tags.32- Without arguments: a tag is already synced iff it appears in the33 **header tag list of an existing wave document** (`list_documents`,34 query `Release`, team iii — each doc's first line lists its tags; that35 list is the idempotency record). Pending = every worker tag not found.36- Skip `-dry-run.` tags. Include prereleases (`-rc.N`, `-beta.N`) and label37 them in the note.3839## 2. Group into waves4041Group pending tags by tag creation date (UTC day). If more than 3 waves42would be written (typical of a first backfill), show the plan43(date → tags) and get user confirmation before writing anything.4445## 3. Gather changes per tag4647- Previous tag of the same worker:48 `git tag -l '<worker>/v*' --sort=-v:refname` → the entry after the49 current one.50- Commits: `git log --format='%h %s%n%b' <prev>..<tag> -- <worker>/`51 (first release of a worker: `git log <tag> -- <worker>/`).52- Extract `MOT-\d+` from subjects and bodies. For PR references `(#N)`53 with no MOT id, `gh pr view N --json title,body` and scan those too.54- Judgment attachments: if a change clearly implements a known issue that55 was never referenced, find it via `list_issues` (title terms, team iii)56 and read the issue to verify it matches before labeling. Never invent57 or guess identifiers; when unsure, leave it off and flag it in the58 report.5960## 4. Write to Linear (per wave)61621. Label: child label `YYYY-MM-DD` under group **release** (team iii,63 `create_issue_label` with `parent: release`; skip if it exists).642. Label every verified issue: read the issue's current labels first and65 pass the union to `save_issue` — never drop existing labels.663. Worker labels: also apply flat `worker:<name>` team labels67 (`worker:shell`, `worker:console`, ...) matching the worker commit68 ranges that referenced the issue — create missing ones lazily; same69 union rule. Flat, NOT a label group: Linear group children are70 mutually exclusive, and one issue often spans several workers.714. Document: `save_document` on team iii titled `Release YYYY-MM-DD`72 (update the existing one if present — look it up via `list_documents`).73 First line: the full tag list (idempotency record — always complete)74 and the wave label name. Body: a `## <worker> vX.Y.Z` section per tag75 (collapse multiple same-day tags of one worker into76 `## <worker> vA → vB`), 2–5 bullets each — what shipped, why it77 matters, breaking changes called out as **Breaking:**, shipped issues78 linked by URL. Plain changelog register; no internal workflow chatter.7980## 5. Report8182Table: wave date → document URL → tags → labeled issues. Flag tags where83no issues were found and any judgment attachments made.8485## Rules8687- Never change issue status, never create issues, never remove existing88 labels from an issue.89- Re-runs must converge: a late same-day tag merges into the existing90 wave document and the note is regenerated to include it.