Project management
Work tracking, prioritization, and completion workflow. Linear-centric project management.
Project management
Purpose: Defines how Framework tracks, prioritizes, and completes work using Linear as the central issue tracker, covering issue types, priorities, triage rituals, branch naming, and GitHub integration.
How Framework tracks, prioritizes, and completes work.
Tool: Linear
All issue tracking and project management lives in Linear. GitHub handles code, PRs, and CI.
Issue types
| Label | When to use |
|---|---|
type: feature |
New functionality |
type: bug |
Something broken |
type: debt |
Technical debt, refactors |
type: idea |
Future possibility |
type: discovery |
Gap we didn't account for |
Priority
| Priority | Meaning | Action |
|---|---|---|
| Urgent | Production down, security issue | Drop everything |
| High | Blocks current work | This week |
| Medium | Important but not urgent | 2-4 weeks |
| Low | Nice to have | Backlog |
| No priority | Not yet triaged | Triage on Monday |
Workflow states
See standards/core/linear-lifecycle.md for statuses and transitions.
Rule: When in doubt, create a Linear issue in Triage.
Weekly triage ritual (15 min, Mondays)
For each item in Triage:
- Promote — Worth doing -> Set priority, move to Backlog
- Kill — Not worth it -> Cancel with note
- Clarify — Need more info -> Add questions, keep in Triage
Branch naming
Use Linear's "Copy git branch name" shortcut (Cmd+Shift+.) to generate branch names with the issue ID.
This ensures auto-linking works and eliminates typos.
Format:
feat/PROJ-42-add-door-unlock
fix/PROJ-51-login-timeout
chore/PROJ-60-update-deps
docs/PROJ-15-api-documentation
refactor/PROJ-33-auth-middleware
Commit messages
Conventional commits required:
feat: add door unlock endpoint
fix: resolve login timeout on slow connections
chore: update prisma to v6
docs: add API documentation
refactor: extract auth middleware
test: add unit tests for door service
Spec artifacts
Detailed specs live in the repo, not in Linear:
docs/specs/
PROJ-42-brief.md
PROJ-42-prototype.md # UI only
PROJ-42-tech.md
Linear issues link to specs. Specs link back to Linear.
Automation
Two GitHub -> Linear status automations are enabled. Issue linking is always active.
| Automation | Status | Notes |
|---|---|---|
| Issue linking (branch names, PR titles, commits with issue IDs) | Active | Always on — auto-links PRs to Linear issues |
| PR opened -> In Review | Enabled | Auto-transitions issue when PR is created |
| PR merged -> Preview Testing | Enabled | Maps to Preview Testing, NOT Done — preserves verification gate |
| Branch created -> In Process | Disabled | Conflicts with In Design -> In Process manual approval gate |
The orchestrator still manages design gates (In Design -> In Process) and the done gate (Preview Testing -> Done).
See standards/core/linear-lifecycle.md for full transition rules.
Linear issue description formatting
Structure
[One-line summary]
## Steps
1. First step
2. Second step
## TDD Verification
1. Test scenario -> expected outcome
## Acceptance Criteria
- Criterion one
- Criterion two
Rules
- Numbered lists for enumerations — Steps, fields, credentials, functions. Prevents missed items.
- Bullets for unordered sets — Acceptance criteria, notes.
- No inline
\ncharacters — Always real line breaks. Never escaped newlines in code. - Section headers —
##for top-level,###for subsections. - Code references — Backticks for file paths, function names, env vars:
`lib/env.ts`. - Sub-steps as nested numbered lists — Never jam multiple items into one comma-separated line.
Credential/config issues
Must include:
- 1Password Environment section — Name the target environment
- Numbered list of every value — Everything goes in one 1Password Environment
- Verification step — How to confirm setup works
See standards/reference/environments.md § "Secrets Management" for the 1Password architecture.
Description vs comment
Issue findings, media processing results, and structured data — Belong in the issue description (updated via npx tsx tools/scripts/linear-api.ts update-issue <ID> --description "...").
Comments are for conversation — Status updates, questions, review summaries, and checkpoint communications.
Never post structured findings (video analysis, root cause, steps to recreate) as a comment — update the description so the information is permanently visible at the top of the issue.
Programmatic creation
Pass description as a plain string with real newline characters.
Do NOT double-escape (\\n).
Test one issue visually before batch-creating.
Image assets in Linear
Design mockups, screenshots, and other images referenced in Linear issues should be hosted in Supabase Storage for reliable, permanent URLs.
Centralized storage (rajababa-assets)
All projects share a single Supabase project (rajababa-assets) dedicated to storage. No per-project Supabase instances for assets.
Two buckets:
| Bucket | Visibility | Purpose | Path convention |
|---|---|---|---|
assets |
Private (default) | Linear attachments, internal diagrams, issue screenshots | Vendor-rooted: linear/{ISSUE-ID}/name.ext, obsidian/{path}/name.ext |
public |
Public | Internet-facing content (site images, presentations) | Content-type-rooted: sites/, presentations/, assets/ |
Private by default. Only use the public bucket when the asset genuinely needs unauthenticated internet access.
Path convention (private assets bucket)
Vendor-rooted paths group files by the system that owns them:
linear/ORC-227/appearance-tab-proposal.png
linear/RAJ-212/login-flow-error-state.png
linear/ORC-123/frame-001.jpg
obsidian/people/indy-dev-dan/avatar.jpg
No subfolders beyond the vendor prefix and identifier. Use meaningful, descriptive filenames.
Upload via CLI
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/assets/linear/${ISSUE_ID}/<filename>" \
-H "Authorization: Bearer ${SUPABASE_ANON_KEY}" \
-H "Content-Type: image/png" \
-H "x-upsert: true" \
--data-binary @<local-file-path>
Accessing private assets (signed URLs)
Private bucket assets require a signed URL. Generate one with a 1-hour expiry:
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/sign/assets/linear/${ISSUE_ID}/<filename>" \
-H "Authorization: Bearer ${SUPABASE_ANON_KEY}" \
-H "Content-Type: application/json" \
-d '{"expiresIn": 3600}'
Linear integration: Embed the signed URL in markdown (). Linear auto-proxies external images to uploads.linear.app, making the image permanently embedded regardless of signed URL expiry.
Obsidian integration: Download the file to the local vault via signed URL, then reference as a local file path.
Security model
- RLS policies on both buckets: INSERT, UPDATE, DELETE require a valid anon key
- Path regex —
^[a-z][a-z0-9-]*/.+$(any valid vendor prefix) - Anon key — Safe to embed in agent code and CLI scripts. It only allows RLS-gated operations; it cannot bypass row-level security
- SVG uploads — Allowed. XSS is mitigated by Supabase domain isolation (SVGs are served from a separate domain, not the application domain)
Configuration
Credentials live in ~/.claude/supabase-assets.json, symlinked into each repo's .claude/ directory:
{
"supabaseUrl": "https://<project-ref>.supabase.co",
"supabaseAnonKey": "eyJ..."
}
Notes
- Use
x-upsert: true— To overwrite when re-uploading a revised image - Prefer PNG for UI mockups — Sharp text; JPEG for photos or large screenshots
- Legacy
issue-attachmentsbucket — The old per-projectissue-attachmentsbucket still exists but is not used for new uploads. All new assets go torajababa-assets
Linear + GitHub integration
- Connect Linear to GitHub repo — In Linear settings
- Branch detection — Linear detects branches containing issue IDs
- PR linking — PRs referencing issue IDs auto-link
- Auto-close — Disabled. Status transitions are managed by the orchestrator.
Plan document formatting
Milestone plans and roadmap trackers use strikethrough + dimming for completed items so active work visually dominates.
Pattern
Wrap completed text in <span style="opacity:0.4"> with strikethrough:
<!-- Table rows -->
| <span style="opacity:0.4">~~M1~~</span> | <span style="opacity:0.4">~~Plugin Hardening~~</span> | <span style="opacity:0.4">~~Done~~</span> |
| M2 | Active Milestone | In Progress |
<!-- List items -->
- <span style="opacity:0.4">~~**M10** — PDF generation & email~~</span>
- **M12** — E2E & regression testing
How it renders
| Renderer | Effect |
|---|---|
| Cursor / VS Code | Opacity + strikethrough — done items fade, active items pop |
PDF (/pdf skill) |
Typst template dims strikethrough to light gray automatically |
| GitHub | Strikethrough only — no dimming, still readable |
The pattern degrades gracefully. Worst case (GitHub) still shows strikethrough.
When to apply
- Dim entire row — In milestone tables when Done
- Dim completed bullets — In execution order lists
- Label completed nodes with
(done)— In dependency graphs
Do not apply to changelogs, commit messages, or Linear issues (Linear has its own done styling).
Last updated: March 2026