Skip to main content
Reference

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

  1. Numbered lists for enumerations — Steps, fields, credentials, functions. Prevents missed items.
  2. Bullets for unordered sets — Acceptance criteria, notes.
  3. No inline \n characters — Always real line breaks. Never escaped newlines in code.
  4. Section headers## for top-level, ### for subsections.
  5. Code references — Backticks for file paths, function names, env vars: `lib/env.ts`.
  6. Sub-steps as nested numbered lists — Never jam multiple items into one comma-separated line.

Credential/config issues

Must include:

  1. 1Password Environment section — Name the target environment
  2. Numbered list of every value — Everything goes in one 1Password Environment
  3. 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 (![description](signed-url)). 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-attachments bucket — The old per-project issue-attachments bucket still exists but is not used for new uploads. All new assets go to rajababa-assets

Linear + GitHub integration

  1. Connect Linear to GitHub repo — In Linear settings
  2. Branch detection — Linear detects branches containing issue IDs
  3. PR linking — PRs referencing issue IDs auto-link
  4. Auto-closeDisabled. 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

Search Framework Explorer

Search agents, skills, and standards