-
Check auth before live work when credentials are uncertain.
Completion criterion: auth status returns authenticated: true, or immediately start the OAuth flow below. Never ask the user to paste a token.
-
Use the zero-configuration OAuth login when unauthenticated.
Completion criterion: run linear-axi auth login on the user's machine. It opens the default browser. Ask the user to select the intended Linear workspace and click Authorize, keep the CLI process alive, then verify linear-axi auth status reports authenticated: true. The token is stored with private permissions in $XDG_CONFIG_HOME/linear-axi/credentials.env, or ~/.config/linear-axi/credentials.env when XDG_CONFIG_HOME is unset. If LINEAR_AXI_ENV_FILE is set in the process environment, that file is used instead. No OAuth app registration or token paste is required. Use --no-open only when the authorize URL should be opened manually.
-
Use the shared browser flow when the CLI runs remotely.
Completion criterion: start linear-axi auth login --notify in a persistent exec session, copy the exact authorize URL from stderr, use chrome-devtools-axi open <authorize-url>, and verify the snapshot shows axi-cli is requesting access. Hand the browser to the user so they can select the intended workspace and click Authorize. The live WebRTC URL mirrors the shared browser's current tab and does not navigate by itself.
-
Treat every mutating command as a live mutation.
Completion criterion: run issue create, assign, unassign, close, or description update; label create or apply; relation create; and comment create only after explicit user intent identifies the target and desired change. Auth status, team, issue, label, relation, and comment reads plus Wayfinder frontier remain read-only.
-
Interpret state filters and resolve ambiguity explicitly.
Completion criterion: treat completed, canceled, and duplicate as the three terminal workflow types. issues list --state open excludes all three, while --state closed includes all three. Treat missing, archived, and ambiguous identity errors as authoritative. Never pick the first team, issue, label, workflow state, or user candidate. Retry with the intended UUID. Assign only to an active, unarchived, assignable user. Issue summaries retain attached archived label names, so use labels list --issue <issue> --include-archived --fields id,name,archivedAt when label status matters.
-
Read TOON stdout directly.
Completion criterion: do not rerun only to confirm an empty state or error; structured output is authoritative unless the command exits non-zero.
-
Let usage errors self-correct.
Completion criterion: after exit 2, use the help field from stdout to repair the command in one step.
-
Do not leave stale OAuth listeners running.
Completion criterion: if a browser handoff times out, is interrupted, or the user lands on This site can't be reached, stop the old auth login process and restart with a fresh authorize URL. OAuth codes and state are one-use.
-
Handle remote-browser loopback callbacks.
Completion criterion: if the user approves Linear OAuth and the live browser lands on http://127.0.0.1:14582/oauth/callback?... with This site can't be reached, keep the still-running auth login process alive and paste that full callback URL into the CLI stdin. Then read the waiting CLI output and verify the configured credentials file was written. Do not paste the callback code or resulting tokens in the final answer.
-
Preserve directed relation semantics.
Completion criterion: prefer relations create --issue <blocked> --blocked-by <blocker> and relations list --issue <blocked> --blocked-by for blocking relationships. Create maps the blocker to the source and the blocked issue to the target, and names both in its output. List maps to incoming blocks, reports the query as top-level blockedIssue, and names each row's counterpart blockerIssue. Do not combine the shorthand with generic relation flags. For the generic relations create --type blocks form, pass the source blocker as --issue and the target blocked issue as --related-issue. Treat source, target, and type as the relation identity; a reverse relation is distinct. Never create a self-block, including through two references that resolve to the same issue.
-
Treat assignment as a non-atomic claim convention.
Completion criterion: claim only an unassigned issue, never pass --replace for a Wayfinder claim, and release with --if-assignee me. Read-after-write verification narrows but cannot eliminate concurrent claim races.
-
Replace descriptions only from the latest version.
Completion criterion: fetch the full issue, merge locally, then pass the exact canonical updatedAt emitted by the CLI to issues update --if-updated-at. On conflict, refetch and merge again. Linear has no atomic compare-and-swap, so keep resolution comments canonical and do not claim that the final read/write race is eliminated.
-
Reuse caller-retained mutation UUIDs safely.
Completion criterion: pass a UUID v4 with --id when issue, label, relation, or comment creation must be retryable. Reuse it only for the same intended content and scope. Rich-text comparisons tolerate normalized newlines and Linear's angle-bracket form for HTTP(S) Markdown links. Treat changed: false as a successful no-op and any UUID/content conflict as a stop condition.
-
Follow every list cursor exactly.
Completion criterion: for issue, label, relation, and comment lists, replay the same filters with the returned page.endCursor as --after. For Wayfinder frontier, use pageInfo.endCursor. Never construct or edit a cursor. Relation pages and issue-scoped exact-name label pages are current-state projections, so restart without --after when current membership matters.
-
Validate the Wayfinder projection before claiming.
Completion criterion: require exactly one active production wayfinder:map label, or for isolated verification one WF-VERIFY-<run>:map label whose type labels use the same prefix. Before candidate loading, require all four active, ordinary, non-group labels to resolve uniquely among workspace and map-team labels, even when the map has no candidates: <prefix>:research, <prefix>:prototype, <prefix>:grilling, and <prefix>:task. Then require exactly one of those labels on every direct open, unblocked, unassigned child. Treat any projection error as a metadata repair task, not as an empty frontier.
-
Treat frontier pages as current-state projections.
Completion criterion: restart without --after when current membership or ordering matters. Frontier pagination does not provide snapshot isolation.