Skip to content

fix(projects): a status named Paused reads as paused everywhere - #73

Merged
muqsitnawaz merged 1 commit into
mainfrom
feat/paused-status
Oct 12, 2026
Merged

muqsitnawaz merged 1 commit into
mainfrom
feat/paused-status

Conversation

@muqsitnawaz

@muqsitnawaz muqsitnawaz commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

A project status named Paused now reads as paused everywhere linear-cli shows a project: projects, projects show, projects overview (text and JSON state), initiatives show, and the create guard from #72.

Why: Linear's settings UI can only add Paused under the Planned category, so the status's type is planned and the deprecated project.state says planned. The #72 guard therefore never fired for a paused project. project_state() derives the state from status { name type } and treats the name Paused as paused. list_team_projects and the other project reads normalize through it.

Also fixed: resolve_project_status_id matched type before name. With two planned-type statuses, --state planned could pick Paused, since Linear lists it first. Exact names now win.

Bumps to v0.31.0, including the install.sh pin and SHA.

Run evidence

Ran the branch build against live Linear from a directory bound to AGI, which is now set to the workspace's new Paused status. Output captured from that run:

$ linear projects | head -3
5 project(s):
  AGI                                       paused        Low       99%  1145 issue(s)  lead: Muqsit
  Muqsit                                    backlog       High       8%     3 issue(s)  lead: Muqsit

$ linear projects show AGI | head -2
AGI
  State:    paused

$ linear projects overview | grep ^AGI
AGI  [low · paused · target -]

$ linear projects overview --json  (state per project)
[('Rush', 'started'), ('Muqsit', 'backlog'), ('AGI', 'paused'), ('Atlas', 'completed'), ('Wispr', 'completed')]

$ linear create "probe: should be refused"
Refusing to create 'probe: should be refused': project 'AGI' is paused in Linear.
  A paused, completed or canceled project takes no new issues. Comment on or
  update an existing issue instead; --force files it anyway.
exit=1

python3 -m unittest test_linear → Ran 280 tests ... OK (skipped=4). New: ProjectStateTest and test_name_wins_over_a_paused_status_of_type_planned.

🤖 Generated with Claude Code

Linear's settings UI files a Paused status under the Planned category, so
its type is planned and the closed-project guard never fired. Project
state now derives from status (Linear deprecated state) in projects,
show, overview, initiatives show and create. Exact status names resolve
before types so --state planned no longer picks Paused. Release v0.31.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@muqsitnawaz

Copy link
Copy Markdown
Contributor Author

Verdict: APPROVE

Checked at 88ccd70:

  • Tests: PYTHONDONTWRITEBYTECODE=1 python3 -m unittest test_linear -> Ran 280, OK (skipped=4).
  • SHA: sha256sum linear = 0156f360...82eb3, matches install.sh EXPECTED_SHA256; __version__ and install.sh VERSION and README pins all v0.31.0.
  • Coverage: every project node that selects state also selects status { name type } and is normalized: _TEAM_PROJECTS_QUERY (linear:1081, normalized at 1098; this also feeds the create guard at 4307-4309, projects at 4745, and the callers at 1189/1253/1395/1446), _project_show (4777/4793), overview query + build_overview (4847, 5027; text at 5162 reads the built dict), _initiative_show (5596/5608), _project_update (5277 already selected status; 5295 now uses project_state). No other project-node state selection found.
  • JSON consumers: state keeps the same values (status type) as before except a status named Paused now yields paused instead of planned; real paused-type statuses already yielded paused. No key added or removed in projects show/initiatives show/overview JSON, though projects show --json and initiatives show --json now also carry the raw status object (additive).
  • Resolver (linear:1283-1293): name-first only changes the result when a status name equals the input and differs from the first same-type match. started, completed, backlog match no custom name unless one is literally named that, in which case the exact name is the more literal reading; otherwise they fall through to type as before.

Nits (non-blocking):

  • The PR body is on a public repo and cites a local scratchpad path (/tmp/claude-1000/-home-muqsit-src-github-com-muqsitnawaz-...) and workspace project names/counts ("AGI ... 1145 issue(s)"). Consider trimming the path from the body.
  • Docstring at linear:1276-1277 has an over-long line.

@muqsitnawaz
muqsitnawaz merged commit e340687 into main Oct 12, 2026
5 checks passed
@muqsitnawaz
muqsitnawaz deleted the feat/paused-status branch October 12, 2026 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant