Roadmaps & Initiatives
Long-range planning via initiatives — hierarchical groupings with their own four-status lifecycle, linked directly to issues across projects and teams.
Initiatives are the long-range planning primitive. They sit above projects and sprints, group issues across teams and timelines, and nest into each other for layered planning (parent ↔ child). The roadmap view renders them on a timeline. Source: type Initiative struct in models.go.
Initiatives
| Field | Type | Notes |
|---|---|---|
name, description | strings | |
status | enum | Four values, see below — distinct from Project status |
progress | int (0–100) | Manually set or computed from linked issues + child initiatives |
startDate, targetDate | nullable dates | |
ownerId | nullable | Designated user; can be empty |
teamId | nullable | Optional anchoring to a team — initiatives can also span teams |
color | nullable | UI hint for the timeline bar |
children | recursive | An initiative can have nested child initiatives |
linkedIssues, linkedIssueCount | computed | Issues with initiativeId set to this initiative |
Status
Five values from InitiativeStatus, distinct from Project’s six:
| Status | When |
|---|---|
not_started | Future work; no issues in_progress yet |
in_progress | Active — at least one linked issue or child is in flight |
at_risk | Won’t hit targetDate without intervention |
blocked | Stalled on an external dependency or unresolved decision |
completed | Done — all linked issues done or cancelled |
Status is set explicitly (or by automation). It’s not auto-derived from issue progress, so you can mark at_risk even if every linked issue is technically still on schedule.
How initiatives link to other entities
Initiative ────────► Initiative (parent ↔ children, recursive)
│
├──► Issue.initiativeId (issues link directly)
│
╳ Project does NOT link to Initiative
— projects and initiatives both exist but they don't reference
each other in the schema. Use issue-level linkage instead.
This is the most common point of confusion: there’s no project.initiativeId field. Projects organize day-to-day work; initiatives organize cross-project arcs. Issues are the connective tissue — an issue can sit in a project and an initiative simultaneously.
Creating an initiative
From the UI
Plan → Roadmaps → New Initiative. Name, optional description, target date, and (optionally) a parent initiative for nesting.
From the CLI
pfai initiative create "Q2 OIDC GA" \
--owner alice --target-date 2026-06-30 --color "#3B82F6"
pfai initiative add-child <parent-id> <child-id>
pfai initiative link-issues <initiative-id> BACK-42 BACK-43 ... Initiative progress
Two ways to drive progress:
- Manual —
pfai initiative update <id> --progress 60. Useful when you want a strategic narrative independent of issue counts. - Computed — UI averages child-initiative progress + linked-issue completion, weighted by count. Re-computes on issue/child changes.
Pick one approach per initiative; mixing is confusing.
The roadmap view
The roadmap is a horizontal timeline of initiatives (and optionally projects + milestones).
- Horizontal axis: time, zoomable from week to year
- Rows: initiatives — child initiatives indent under their parents
- Bar color: initiative status (
not_started,in_progress,at_risk,completed) — also configurable per initiative viacolor - Filters: by team, owner, status, target quarter
Summary table
Below the timeline, the dashboard table:
| Column | Source |
|---|---|
| Initiative | name |
| Owner | owner |
| Status | status (with color) |
| Progress | progress |
| Linked issues | linkedIssueCount |
| Target date | targetDate |
Filter by team, status, or date range to focus a planning session.
Permissions
- Anyone with team-write access can create initiatives anchored to that team
- Org-level initiatives (no
teamId) are admin-only by default - The owner has implicit edit rights regardless of team membership
- Org admins can edit any initiative
REST endpoints
| Method · Path | Purpose |
|---|---|
GET /api/v1/initiatives?team=&status=&owner=... | List |
POST /api/v1/initiatives | Create — pass parentId for nesting |
GET /api/v1/initiatives/{id} | Read with embedded children[] and linkedIssues[] |
PATCH /api/v1/initiatives/{id} | Update — name, status, progress, dates, owner, parent, color |
DELETE /api/v1/initiatives/{id} | Soft-delete |
POST /api/v1/initiatives/{id}/issues | Bulk-link issues |
DELETE /api/v1/initiatives/{id}/issues/{issueId} | Unlink an issue |
See also
Project status + health are separate dimensions, independent of initiative membership.
Issues link directly to initiatives via initiativeId — projects don't.
Short-term cadence; initiatives are the long-range overlay.
CLI surface — list, view, create, update, link-issues, add-child.