Linear ticket management best practices. Use when creating issues, updating status, or attaching evidence. Provides evidence templates for dev/staging/done phases.
Guide consistent Linear ticket management. Provides evidence templates for the mandatory dev/staging/UAT evidence policy.
Since Gemini CLI doesn't have native Linear integration, use the Linear web UI or CLI for these operations:
# Via Linear Web UI
# Navigate to: https://linear.app/team/{{PROJECT_TEAM_NAME}}/issue/{{TICKET_PREFIX}}-XXX
# Or use Linear CLI if installed
linear issue view {{TICKET_PREFIX}}-XXX
# Via Linear Web UI: Click "New Issue" or press C
# Or use Linear CLI:
linear issue create --title "feat(scope): description" --team {{PROJECT_TEAM_NAME}}
# Via Linear Web UI: Open issue and update status
# Or use Linear CLI:
linear issue update {{TICKET_PREFIX}}-XXX --state "Done"
# Via Linear Web UI: Open issue and add comment
# Or use Linear CLI:
linear issue comment {{TICKET_PREFIX}}-XXX "**Dev Evidence**\n\n..."
For work that spans many issues, Linear has objects above the issue. Use them; do not flatten a program into a flat list of tickets.
Initiative the program (one per program)
โโโ Project a Unit of Work โ one coherent outcome
โโโ Milestone an AI-DLC phase: Inception, Construction, Operations
โโโ Issue a Story
โโโ Sub-issue a Mob Elaboration task (created during Inception, not before)
Program build-out assumes these label namespaces are pre-created in the workspace. Create them before building the program, not during:
bolt:0 โฆ bolt:N โ which Bolt an issue belongs toagent:* โ the lead role (must match an actual agent role defined for the project)Labels are workspace-scoped in Linear โ do not create team-scoped duplicates.
Linear sub-initiatives require an Enterprise plan. If your workspace has it, model program streams as sub-initiatives under the initiative. If it does not, encode the stream as project priority instead โ highest-risk stream gets Urgent/High, follow-up stream gets Medium.
# Create the initiative
# Linear Web UI: Initiatives โ New initiative
# Add a project (Unit of Work) to the initiative
# Linear Web UI: Initiative โ Add project
# Add the three AI-DLC phase milestones to each project
# Linear Web UI: Project โ Milestones โ New milestone
# Wire dependencies between issues
# Linear Web UI: Issue โ Add relation โ "Blocks" / "Blocked by"
Use relatedTo ("Related") for soft links that inform but do not block.
Wire so the enforcement lands before the thing it enforces โ see the safe-ai-dlc skill for the
four dependency-wiring heuristics.
When a program absorbs tickets that already exist, update them into the project โ never recreate them. Duplicates break traceability and split the evidence trail.
Every issue requires evidence at each phase:
| Phase | Required? | Content |
|---|---|---|
| Dev | MUST | Implementation proof |
| Staging | MUST | UAT validation (or N/A) |
| Done | MUST | Final verification |
**Dev Evidence**
**PR**: https://github.com/{{ORG_NAME}}/{{REPO_NAME}}/pull/XXX
**Commit**: [short-hash]
**Branch**: {{TICKET_PREFIX}}-XXX-description
**Implementation:**
- [x] Feature implemented
- [x] Tests passing
- [x] Lint passing
**Verification:**
\`\`\`bash
yarn ci:validate
# Output: All checks passed
\`\`\`
**Staging Evidence**
**Environment**: Pop OS dev server
**URL**: http://pop-os:3000
**Validation Steps:**
1. Deployed to staging: [timestamp]
2. Smoke test passed: [yes/no]
3. Feature verified: [description]
**UAT Status:** [Passed/Pending/N/A]
If N/A, reason: [e.g., "Dev tooling only - no user-facing changes"]
**Done Evidence**
**PR Merged**: https://github.com/{{ORG_NAME}}/{{REPO_NAME}}/pull/XXX
**Merge Commit**: [hash]
**Final Checklist:**
- [x] All acceptance criteria met
- [x] Documentation updated (if applicable)
- [x] No regressions detected
When reading issue descriptions, extract ACs:
## Acceptance Criteria
- [ ] User can perform action X
- [ ] System responds with Y
- [ ] Error handling for Z
Convert to testable checklist:
const acceptanceCriteria = [
{ criterion: "User can perform action X", verified: false },
{ criterion: "System responds with Y", verified: false },
{ criterion: "Error handling for Z", verified: false },
];
Backlog -> Ready -> In Progress -> Testing -> Ready for Review -> Done
Tickets referenced in commit messages (e.g., [{{TICKET_PREFIX}}-123]) automatically move to Done when the PR merges. Child stories not referenced in any commit message must be manually closed after merge.
Best practice: Reference Feature-level tickets in commit messages. After merge, manually close orphaned child stories that weren't referenced.
| From | To | When |
|---|---|---|
| Backlog | Ready | Sprint planning |
| Ready | In Progress | Work starts |
| In Progress | Testing | PR created |
| Testing | Ready for Review | Tests pass, UAT complete |
| Ready for Review | Done | POPM approval or auto-sync via PR merge |
Linear uses UUIDs internally. When working with APIs:
// Issue identifiers (human-readable)
const issueId = "{{TICKET_PREFIX}}-459";
// UUIDs (API operations)
const uuid = "ef6a5fa0-2b46-417f-8266-dea2d187b10a";
// Get UUID from identifier via Linear web UI or API
// The issue URL contains the UUID
PRs are automatically linked when:
{{TICKET_PREFIX}}-XXX[{{TICKET_PREFIX}}-XXX]Use Linear web UI: Click "Add sub-issue" on parent issue
Use Linear web UI filters:
docs/sop/AGENT_WORKFLOW_SOP.md