diff --git a/jira/AGENTS.md b/jira/AGENTS.md new file mode 100644 index 00000000..f84a8aa8 --- /dev/null +++ b/jira/AGENTS.md @@ -0,0 +1,119 @@ +# Jira Team Context + +## User + +Load your persona from `personas/` to tailor agent behaviour to your role: + +- **Director / Product Owner** → `personas/director.md` +- **Squad Lead** → `personas/squad-lead.md` +- **Developer / Individual Contributor** → `personas/developer.md` + +## Atlassian + +- **Site:** [warthogs](https://warthogs.atlassian.net) +- **Cloud ID:** `220bceb6-6b32-4813-90eb-68d67c9445db` + +## Projects + +| Project Key | Project Name | +|-------------|---------------------| +| UDENG | Desktop Roadmap | + +## Team + +The authoritative roster of all Desktop team members is maintained in +the GitHub team: +[IS Platform Services: Desktop](https://github.com/orgs/canonical/teams/is-platform-services-desktop) + +## Squads + +| Squad | Project | Jira Team Name (`customfield_10001`) | +|--------------------------|---------|---------------------------------------| +| GNOME Team | UDENG | Desktop \| GNOME | +| Integration Team | UDENG | Desktop \| Integration | +| Apps Team | UDENG | Desktop \| Apps | +| Enterprise Team | UDENG | Desktop \| Enterprise | +| Core Desktop Team | UDENG | Desktop \| Core | +| WSL Team | UDENG | Desktop \| WSL | +| Design Team | UDENG | Desktop \| Design | + +## Issue Hierarchy + +`Objectives > Epics > Stories / Tasks / Spikes` + +| Issue Type | Timebox | Sized by | Notes | +|------------|---------------|--------------|----------------------------------------------------| +| Objective | LTS Cycle | - | Owned/triaged by director or senior leads | +| Epic | Release Cycle | T-shirt size | Roadmap commitment; max XL per person per cycle | +| Story | Pulse | Story points | Delivers incremental value; fits in one pulse | +| Task | Pulse | Story points | Background/overhead work; may not have parent Epic | +| Spike | Pulse | Story points | Investigation/ideation to break down parent work | + +## Key Custom Fields + +| Field | Jira ID | Notes | +|--------------|---------------------|--------------------------------------------------| +| Team | `customfield_10001` | Squad name (see Squads table) | +| T-shirt size | `customfield_10040` | XS, S, M, L, XL — used on Epics | +| Roadmap Item | `customfield_10615` | Value `"Roadmap Item"` — marks Epic as committed | +| Story Points | `customfield_10016` | Used on Stories, Tasks, Spikes — **Note:** the API returns story points in `customfield_10024` (not `customfield_10016`) in issue responses; use `customfield_10016` in JQL but read `customfield_10024` from results | + +Note: in JQL, `customfield_NNNNN` is written as `cf[NNNNN]`. + +> **JQL limitation — Team field filtering:** Filtering by team (`cf[10001]` +> or `"Team[Team]"`) combined with a `sprint =` clause returns no results +> due to a Jira API limitation on this instance. **Workaround:** omit the +> team filter from JQL, fetch all sprint items, then filter locally by +> `customfield_10001.name` in the returned JSON. + +## Timeboxes + +| Timebox | Duration | Jira representation | +|---------------|-----------|-----------------------------------------------------| +| LTS Cycle | ~2 years | FixVersion e.g. `26.04 LTS` | +| Release Cycle | ~6 months | FixVersion e.g. `26.10` | +| Pulse | 2 weeks | Sprint, named `Pulse YYYY#nn` e.g. `Pulse 2025#01` | + +- Pulse is the internal name for a Jira sprint — all Canonical teams share + the same sprint numbering. `#nn` is the sequential sprint number for the + year. +- Roadmap Items are Epics with `customfield_10615 = "Roadmap Item"` plus a + release label (e.g. `26.10`). +- Uncompleted Roadmap Items are carried over: new label added, FixVersion + updated. + +## Issue States + +`Untriaged` → `Triaged` → `In Progress` → `In Review` → `Done` +(or `Blocked` / `Rejected`) + +- Parent chain must be marked Triaged before a child can be Triaged. +- Parent chain should be marked In Progress when a child moves to In Progress. +- Parent is Done only when all children are Done. + +## Metrics & Targets + +| Metric | Target | Current (approx.) | +|------------------------------------|--------|-------------------| +| Pulse velocity | ≥ 80% | ~60% | +| Untriaged issues in active timebox | 0% | significant debt | +| Issues without team/component | ~0 | - | +| Epics without t-shirt size | 0 | - | +| Epics without parent Objective | 0 | - | + +## Backlog Grooming Owners + +| Backlog | Who grooms | +|-----------------|-------------------------------------| +| Full backlog | Director + senior leads | +| Product (LTS) | Seniors, architects, SMEs | +| Release (Cycle) | Assigned objective lead, Epic owner | +| Pulse | Everyone / issue owners | + +## Practice References + +For full lifecycle rules, grooming checklists, and interrupt workflows: + +- Objectives → `practices/objectives.md` +- Epics → `practices/epics.md` +- Pulse items (Stories / Tasks / Spikes) → `practices/pulse.md` diff --git a/jira/README.md b/jira/README.md new file mode 100644 index 00000000..5edc7a07 --- /dev/null +++ b/jira/README.md @@ -0,0 +1,64 @@ +# Jira Agent Tooling + +This directory is the working root for AI-assisted Jira workflows on the +Dektop team. Open it as your project folder in OpenCode to get full +agent context, skills, and practices automatically loaded. + +## Prerequisites + +- [OpenCode](https://opencode.ai) installed +- Jira MCP configured for `warthogs.atlassian.net` + - Cloud ID: `220bceb6-6b32-4813-90eb-68d67c9445db` + - The MCP server must be listed in your OpenCode config + (`~/.config/opencode/config.json`) + +## Quick Start + +```bash +git clone https://github.com/canonical/desktop-engineering +cd desktop-engineering/jira +opencode +``` + +On first run, tell the agent your role so it loads the right persona: + +> "I am a squad lead" — loads `personas/squad-lead.md` +> "I am the director" — loads `personas/director.md` +> "I am a developer" — loads `personas/developer.md` + +The agent will automatically read `AGENT.md` for team context (Atlassian +config, custom fields, issue hierarchy, metrics targets). + +## Available Skills + +Skills are loaded automatically from `.opencode/skills/`. Each skill provides +the agent with a focused workflow for a specific task. + +| Skill | Trigger phrases | What it does | +|--------------|-----------------|-----------------------------------------------------| +| *(none yet)* | — | Skills are being developed — see Contributing below | + +## Practices + +Detailed lifecycle rules, grooming checklists, and interrupt workflows: + +| Document | Covers | +|---------------------------|--------------------------------------------------------------------------------------------------------| +| `practices/objectives.md` | Objective creation, grooming → Triaged, state transitions, carry-over, interrupts | +| `practices/epics.md` | Epic creation, grooming → Triaged, child items, state transitions, carry-over, interrupts | +| `practices/pulse.md` | Story / Task / Spike creation, sizing, sprint assignment, pulse planning, velocity | + +## Personas + +| File | For | +| -------------------------- | ------------------------------------------------------------------------------------------ | +| `personas/director.md` | Director / Product Owner — LTS Objectives, cross-squad prioritisation, interrupt triage | +| `personas/squad-lead.md` | Squad Leads — Release backlog, Epic ownership, pulse health per squad | +| `personas/developer.md` | Individual Contributors — pulse delivery, Epic ownership, velocity, blockers | + +## Contributing + +- Practice changes (grooming rules, checklists): edit `practices/*.md` and open a PR +- New skills: add a directory under `.opencode/skills/` with a `SKILL.md` and any supporting scripts +- Persona updates: edit `personas/*.md` — keep role-specific context current after each cycle +- Discuss on [`#dekstop-team-eng`](https://chat.canonical.com/canonical/channels/desktop-team-eng) diff --git a/jira/personas/developer.md b/jira/personas/developer.md new file mode 100644 index 00000000..8aba8f92 --- /dev/null +++ b/jira/personas/developer.md @@ -0,0 +1,140 @@ +# Persona: Developer / Individual Contributor + +Individual contributors own the delivery of pulse items and the quality of +their assigned Epics. This persona is for any Foundations team member who is +not acting as a squad lead or director. + +--- + +## Primary Responsibilities + +- **Pulse delivery**: complete assigned Stories, Tasks, and Spikes within the + Pulse; target ≥ 80% of your committed story points done each sprint +- **Own your Epic quality**: for any Epic you own, ensure it meets grooming + criteria before and during the cycle — description, t-shirt size, parent + Objective, team field, and a docs Story child +- **Proactive blocking**: flag blockers to your squad lead the moment they + appear — do not wait until the Pulse review +- **WIP discipline**: finish in-progress items before picking up new ones; + keep your active item count low +- **Triage hygiene**: keep your assigned items free of dangling Untriaged + work — everything in an active Pulse should be Triaged or beyond + +## Decision Authority + +| Decision | Authority | +| -------- | --------- | +| Create a Story / Task / Spike under your Epic | You | +| Estimate story points on your items | You (with squad lead input) | +| Move an item to In Progress / In Review / Done | You | +| Flag an item as Blocked | You — notify squad lead immediately | +| Carry over an item to the next Pulse | You + squad lead awareness | +| Create a new Epic | You + squad lead sign-off to triage it | + +--- + +## Typical Agent Prompts + +### My current pulse + +``` +Show all my active pulse items in the current sprint — flag any missing +story points, assignee, or parent +``` + +### My Epic health + +``` +Assess grooming quality for all Epics assigned to me — flag missing fields +or child items +``` + +### What should I pick up next? + +``` +Show all Triaged Stories and Tasks assigned to me that are not yet in a +sprint, ordered by parent Epic priority +``` + +### Carry-over check + +``` +Which of my items from the previous Pulse are still open? Should any be +re-estimated or closed? +``` + +### Create a new pulse item + +``` +I need to create a Story under Epic FR-XXXX to [description]. Help me write +a well-formed description with Why, Who, What, and How. +``` + +### Check my velocity + +``` +What is my pulse velocity for the last 3 sprints? How does it compare to +the 80% target? +``` + +### Blocker + +``` +UDENG-XXXX is blocked — [describe blocker]. Help me write a clear blocker +comment and identify who can unblock it. +``` + +--- + +## Pre-baked JQL Queries + +### My active pulse items + +``` +assignee = currentUser() AND issuetype in (Story, Task, Spike) +AND sprint in openSprints() AND statusCategory != Done +ORDER BY status ASC +``` + +### My untriaged items + +``` +assignee = currentUser() AND status = Untriaged +AND statusCategory != Done ORDER BY created ASC +``` + +### My Epics (owned) +``` +project in (UDENG) AND issuetype = Epic AND assignee = currentUser() +AND statusCategory != Done ORDER BY status ASC +``` + +### My Epics missing grooming fields + +``` +project in (UDENG) AND issuetype = Epic AND assignee = currentUser() +AND statusCategory != Done +AND (cf[10040] is EMPTY OR cf[10001] is EMPTY) +``` + +### Items I own that are blocked + +``` +assignee = currentUser() AND status = Blocked ORDER BY updated ASC +``` + +### Items assigned to me not yet in a sprint + +``` +assignee = currentUser() AND issuetype in (Story, Task, Spike) +AND sprint is EMPTY AND statusCategory != Done ORDER BY created ASC +``` + +--- + +## Practice References + +- Pulse items (your day-to-day): `practices/pulse.md` +- Epic lifecycle (if you own Epics): `practices/epics.md` +- Objective lifecycle (read-only): `practices/objectives.md` +- Team context, custom fields, timeboxes: `AGENT.md` diff --git a/jira/personas/director.md b/jira/personas/director.md new file mode 100644 index 00000000..34e9777d --- /dev/null +++ b/jira/personas/director.md @@ -0,0 +1,137 @@ +# Persona: Director / Product Owner + +**Role:** Director, Desktop Engineering — product owner for Themes and +Objectives grooming + +--- + +## Primary Responsibilities + +- **LTS Objectives backlog**: own the full product backlog of Objectives + across all squads for the current and next LTS cycle +- **Interrupt triage**: receive and assess ad-hoc requests; decide whether + they become new Objectives, absorb into existing ones, or are deferred +- **Cross-squad re-prioritisation**: when new commitments arrive, assess + impact on existing Objectives and communicate trade-offs to leads +- **Velocity oversight**: monitor team-wide pulse velocity (target ≥ 80%) + and squad-level triage debt +- **Grooming quality**: ensure all Objectives and Epics meet creation and + grooming criteria before commitment + +## Decision Authority + +| Decision | Authority | +| -------- | --------- | +| Commit / de-commit an Objective to an LTS cycle | Director | +| Commit / de-commit an Epic to a Release Cycle | Squad lead + Director sign-off | +| Re-prioritise Objectives within an LTS cycle | Director (communicate to leads) | +| Assign Objective owner | Director | +| Escalate staffing or structural concerns | Director → Engineering Manager | + +--- + +## Typical Agent Prompts + +### Objectives backlog review + +``` +Review all untriaged Objectives in the FR project for the 26.04 LTS cycle +``` + +### Interrupt assessment + +``` +A new request has come in: [description]. Should this be a new Objective, +absorbed into an existing one, or deferred? Check for duplicates first. +``` + +### Roadmap snapshot + +``` +Give me a roadmap snapshot for the 26.10 cycle — total Epics by squad, +status breakdown, and top triage concerns +``` + +### Triage debt overview + +``` +What is the untriaged Epic count per squad for the 26.10 cycle? Flag any +squad above 30% untriaged. +``` + +### Grooming quality check + +``` +Assess all active Objectives in the FR project against grooming criteria — +flag any missing Why, Who, What, or Docs sections +``` + +### Carry-over assessment + +``` +Which 26.10 Epics are at risk of not completing this cycle? List Roadmap +Items that are still Untriaged or have no In Progress children. +``` + +--- + +## Pre-baked JQL Queries + +### All untriaged Objectives (current LTS) + +``` +project = UDENG AND issuetype = Objective AND status = Untriaged +AND fixVersion = "26.04 LTS" ORDER BY created ASC +``` + +### All Roadmap Item Epics for 26.10 + +``` +project in (UDENG) AND issuetype = Epic AND labels = "26.10" +AND cf[10615] = "Roadmap Item" ORDER BY project ASC, status ASC +``` + +### Untriaged Epics by squad (replace team name as needed) + +``` +project in (UDENG) AND issuetype = Epic AND status = Untriaged +AND "Team[Team]" = "Desktop" ORDER BY created ASC +``` + +### Blocked items + +``` +project in (UDENG) AND status = Blocked AND statusCategory != Done +ORDER BY updated ASC +``` + +### Epics missing t-shirt size + +``` +project in (UDENG) AND issuetype = Epic AND cf[10040] is EMPTY +AND statusCategory != Done +``` + +### Epics missing parent Objective + +``` +project in (UDENG) AND issuetype = Epic +AND issueFunction in subtasksOf("issuetype = Objective") is EMPTY +AND statusCategory != Done +``` + +### Issues without team field + +``` +project in (UDENG) AND cf[10001] is EMPTY AND statusCategory != Done +AND issuetype != Objective +``` + +--- + +## Practice References + +- Objective lifecycle: `practices/objectives.md` +- Epic lifecycle: `practices/epics.md` +- Pulse items: `practices/pulse.md` +- Team context, custom fields, timeboxes: `AGENT.md` diff --git a/jira/personas/squad-lead.md b/jira/personas/squad-lead.md new file mode 100644 index 00000000..bd6085c6 --- /dev/null +++ b/jira/personas/squad-lead.md @@ -0,0 +1,146 @@ +# Persona: Squad Lead + +Squad leads own the release backlog and pulse health for their squad. This +persona is pre-populated for all current Foundations squad leads. + +--- + +## Squad Leads — Current Cycle + +| Squad | Lead | Scope | +| ----- | ---- | ----- | +| GNOME | Daniel Van Vugt | GNOME Shell ecosystem | +| Integration | Jean-Baptiste Lallement | Lower level desktop components such as multimedia, webbrowsers, printing, accessibility | +| Apps | Didier Roche Tolomelli | In-house applications such as installer, app center, security center, TPMFDE, permission prompting | +| Enterprise | Adrian Dombeck | Enterprise application such as GPO client (adsys), cloud authentication (authd) | +| WSL | Carlos Nihelton Santana De Oliveira | Everything WSL and container based | +| Design | Ana Sereijo | UX and Design for the Desktop | + +> Update this table at the start of each cycle. See `AGENT.md` for the full +> squad roster and Jira team names. + +--- + +## Primary Responsibilities + +- **Release backlog grooming**: ensure all Epics in your squad are triaged + before or during the SRR review process for the upcoming cycle +- **Epic quality**: verify all active Epics have Why/Who/What/Community/ + Innovation/How, t-shirt size, parent Objective, team field, and a docs + Story child +- **Pulse health**: monitor pulse velocity for your squad members; target + ≥ 80% +- **Child item grooming**: ensure Stories, Tasks, and Spikes have story + points, sprint assignment, and parent set before each Pulse +- **Blocker escalation**: surface blocked items to the Director immediately; + do not let blocked Epics sit + +## Decision Authority + +| Decision | Authority | +| -------- | --------- | +| Triage an Epic for the upcoming Release Cycle | Squad lead | +| Set t-shirt size on an Epic | Squad lead (with Epic owner) | +| Add/remove child Stories/Tasks/Spikes | Squad lead or Epic owner | +| Commit a new Epic to the current cycle | Squad lead + Director sign-off | +| De-commit / carry over an Epic | Squad lead + Director sign-off | +| Escalate a new Objective request | Squad lead → Director | + +--- + +## Typical Agent Prompts + +### Triage debt review for your squad + +``` +Show all untriaged Epics for the Apps team in the 26.10 cycle, +ordered by creation date +``` + +### Epic grooming quality check + +``` +Assess grooming quality for all active Epics in the GNOME team — +flag missing fields +``` + +### Pulse health overview + +``` +Show all active pulse items (Stories, Tasks, Spikes) for the WSL team +in the current sprint — flag those missing story points or sprint assignment +``` + +### Blocker check + +``` +List all blocked items in the Enterprise team and how long they +have been blocked +``` + +### Sprint planning prep + +``` +What Stories and Tasks in the Design team are Triaged but not yet +assigned to a sprint? +``` + +### Carry-over risk + +``` +Which Roadmap Item Epics in the Integration team are still Untriaged with +less than 3 months to cycle end? +``` + +--- + +## Pre-baked JQL Queries + +### Untriaged Epics for your squad (replace team name) + +``` +project in (UDENG) AND issuetype = Epic AND status = Untriaged +AND "Team[Team]" = "Desktop | Integration" AND fixVersion = "26.10" +ORDER BY created ASC +``` + +### Active pulse items for your squad + +``` +project in (UDENG) AND issuetype in (Story, Task, Spike) +AND "Team[Team]" = "Desktop | GNOME" AND statusCategory != Done +AND sprint in openSprints() ORDER BY assignee ASC +``` + +### Epics missing t-shirt size in your squad + +``` +project in (UDENG) AND issuetype = Epic AND cf[10040] is EMPTY +AND "Team[Team]" = "Desktop | Enterprise" AND statusCategory != Done +``` + +### Items without story points in your squad + +``` +project in (UDENG) AND issuetype in (Story, Task, Spike) +AND cf[10016] is EMPTY +AND "Team[Team]" = "Desktop | WSL" +AND statusCategory != Done +``` + +### Blocked items in your squad + +``` +project in (UDENG) AND status = Blocked +AND "Team[Team]" = "Desktop | GNOME" +AND statusCategory != Done +``` + +--- + +## Practice References + +- Epic lifecycle: `practices/epics.md` +- Pulse item lifecycle: `practices/pulse.md` +- Objective lifecycle (read-only for leads): `practices/objectives.md` +- Team context, custom fields, timeboxes: `AGENT.md` diff --git a/jira/practices/epics.md b/jira/practices/epics.md new file mode 100644 index 00000000..db352672 --- /dev/null +++ b/jira/practices/epics.md @@ -0,0 +1,176 @@ +# Epics — Full Lifecycle & Best Practices + +Epics are the primary unit of Release Cycle planning and roadmap commitment. +They define a chunk of work deliverable within a single release cycle +(~6 months). Use this document when **creating, assessing, or grooming** an +Epic. + +--- + +## Description Structure (Creation Criteria) + +All three of Why, Who, and What must be **clearly articulated at creation +time** — stricter than Objectives. A vague Epic must not be created; write +it up properly first or create a Spike to investigate. + +**Why** — motivation +: Based on the parent Objective. Must be clear and specific before creating + the Epic. + +**Who** — beneficiary / stakeholder +: Clearly identified — not just broad at this stage. Name the personas or + teams who benefit. + +**What** — value / deliverable +: Clearly articulated scope and definition of done for this Epic. Specific + enough to know when the Epic is finished. + +**Community** +: Is this Epic suitable for community engagement (mailing list, Discourse, + blog post)? State yes/no and what kind. + +**Innovation** +: Does it give Ubuntu any unique advantages? What competitive or technical + differentiation does this create? + +**How** (broad ideas) +: Propose at a high level how the work will be done, preferably referencing + a draft specification. + +--- + +## Ownership & Parenting + +- Must have a **parent Objective**. +- Assign to a **team lead or team member** who understands the full scope or will primarily work on it. +- Created in `Untriaged` state. +- One person can carry at most **one XL Epic** per release cycle. Plan capacity accordingly. + +--- + +## Grooming → Triaged (Release Backlog Grooming) + +Performed during Release Backlog grooming (SRR review process for the +upcoming cycle). + +**Grooming checklist:** + +- [ ] Why, Who, and What are clear and confirmed +- [ ] Community and Innovation sections present +- [ ] Specification draft started (high-level How) +- [ ] Priority established relative to other triaged Epics in the Release Backlog +- [ ] T-shirt size recorded in `customfield_10040` (XS / S / M / L / XL) + - One person can carry at most one XL per cycle + - Workload balanced against team capacity +- [ ] Parent Objective is set and is `Triaged` +- [ ] Team field (`customfield_10001`) set to the correct squad +- [ ] FixVersion set to target Release Cycle (e.g. `26.10`) +- [ ] If roadmap committed: release label added (e.g. `26.10`) and `customfield_10615` set to `"Roadmap Item"` +- [ ] Broken down into child Spikes, Stories, and Tasks (initially Untriaged) +- [ ] A **docs Story** created as a child issue +- [ ] State set to `Triaged` + +--- + +## Child Work Items + +Every Epic must have at least one child issue. A **docs Story** is mandatory +for every Epic. + +| Type | Purpose | Creation Criteria | Sized by | +| ----- | ------- | ----------------- | -------- | +| Spike | Investigation / ideation to clarify How | Purpose clearly articulates what will be learned | Story points | +| Story | Incremental value; ideally fits in one Pulse | Why/Who/What clear, How specified, parent Epic spec approved | Story points | +| Task | Non-value work (tech debt, background, overhead) | What clearly articulated | Story points | +| Docs | Documentation Story — mandatory for every Epic | What / scope of docs clearly stated | Story points | + +--- + +## Child Item Grooming → Triaged (Pulse Backlog Grooming) + +Before a Story, Task, or Spike can be assigned to a Pulse: + +- [ ] Story points estimated (`customfield_10016`) +- [ ] Assigned to a specific Pulse (sprint) +- [ ] Detailed How specified (in the item or parent Epic spec) +- [ ] Parent Epic spec is approved (critical for Stories) +- [ ] Workload balanced across the Pulse +- [ ] Team field (`customfield_10001`) set +- [ ] State set to `Triaged` + +See `practices/pulse.md` for full pulse-level grooming rules. + +--- + +## Ongoing State Transitions + +| State | Trigger | +|-------------|-------------------------------------------------------------| +| Triaged | Grooming checklist complete; added to Release Backlog | +| In Progress | Work actually starts; parent Objective also set In Progress | +| In Review | Owner's work done; reviewer identified early | +| Blocked | External factor halts all progress | +| Done | All child items Done; delivery to product complete | +| Rejected | Work is no longer needed; explicitly closed | + +**State rules:** + +- Parent Objective must be `Triaged` before the Epic can be `Triaged`. +- An Epic moves to `In Progress` when any child starts; do not wait until + all children are active. +- An Epic is `Done` only when **all** child items are `Done`. +- Identify a reviewer early — do not wait until the Epic is done to start + In Review. + +--- + +## Missing Commitments (Carry-Over) + +If a Roadmap Item Epic is not completed by end of its Release Cycle: + +1. Add new release label (e.g. `27.04`) +2. Update `FixVersion` to the next cycle +3. Communicate carry-over to the Objective lead and Director +4. Re-assess t-shirt size — scope may have changed + +--- + +## Interrupts — Ad-hoc Epic or Child Item Requests + +| Urgency | Issue Type | Action | +| ------- | ---------- | ------ | +| NOW / ASAP | Story/Task/Bug | Add to current Pulse; communicate to leads — something may need dropping | +| NOW / ASAP | Epic | Create Epic; communicate to leads — this impacts the Release Backlog | +| Next Pulse | Story/Task/Spike | Treat as regular new work; apply pulse grooming criteria | +| Next Cycle | Epic | Treat as regular new work; apply release grooming criteria | + +**Steps:** + +1. **Check scope** — does an existing Epic already cover this? If so, add a + child item rather than a new Epic. +2. **Identify timebox** — NOW/ASAP requires immediate lead communication; + future timeboxes follow normal grooming. +3. **Choose issue type** — Epic (>1 pulse, <1 cycle), Story (incremental + value, 1 pulse), Task (non-value), Bug (defect). +4. **Assign owner** — Epic: objective lead + Epic owner; Story/Task/Spike: + team member. +5. **Apply grooming criteria** for the appropriate level. + +--- + +## Grooming Quality Checks (for Agent Assessment) + +| Check | Field / Rule | +| ----- | ------------ | +| `has_why` | Description contains a clear "Why" section | +| `has_who` | Description contains a clear "Who" section | +| `has_what` | Description contains a clear "What" section | +| `has_community` | Description contains a "Community" section | +| `has_innovation` | Description contains an "Innovation" section | +| `has_how` | Description contains a "How" section | +| `has_tshirt_size` | `customfield_10040` is not null | +| `has_fix_version` | `fixVersions` is not empty | +| `has_parent_objective` | Parent is set and is an Objective | +| `is_roadmap_item` | `customfield_10615 == "Roadmap Item"` (if committed) | +| `has_team` | `customfield_10001` is not null/empty | +| `has_owner` | `assignee` is set | diff --git a/jira/practices/objectives.md b/jira/practices/objectives.md new file mode 100644 index 00000000..faae06a4 --- /dev/null +++ b/jira/practices/objectives.md @@ -0,0 +1,134 @@ +# Objectives — Full Lifecycle & Best Practices + +Objectives are the primary unit of LTS-level planning. They define what the +Desktop team commits to deliver within an LTS cycle (~2 years). Use this +document when **creating, assessing, or grooming** an Objective. + +--- + +## Description Structure (Creation Criteria) + +Every Objective description must contain the following four sections. **Why +must be clear at creation time.** Who and What may be broad or imprecise +initially. + +**Why** — motivation +: Clearly articulate why this work is needed and how it aligns with + Desktop team's value propositions. This is the minimum requirement to create + an Objective. Without a clear Why, do not create the Objective. + +**Who** — beneficiary / stakeholder +: Identify who benefits. Can be broad (e.g. "Enterprise developers", "OEM + partners", "all users") at creation time. + +**What** — value / deliverable +: Describe the value or outcome at a high level. More specific than a Theme, + but does not need to be precise at creation time. + +**Docs** — documentation planning +: Every Objective must include a Docs section covering documentation planning + and scoping. Mandatory — even if the initial entry is "TBD, scoped with + Objective owner before triaging". + +--- + +## Ownership & Parenting + +- Assign to a **senior team member, architect, or SME** who will lead the + Objective. +- If a parent Theme exists, parent the Objective to it (Themes not currently + active but may be used in future). +- Created in `Untriaged` state in the Full Backlog. +- FixVersion set to target LTS cycle at creation (e.g. `26.04 LTS`). + +--- + +## Grooming → Triaged (Product Backlog / LTS Grooming) + +Performed before the first Product roadmap sprint of the upcoming LTS cycle, +or whenever a new Objective is committed to the current cycle. + +> Before committing a new Objective to the **current** LTS cycle, +> re-prioritisation of already committed Objectives must be considered and +> communicated to leads. + +**Grooming checklist:** + +- [ ] Why is clearly articulated and confirmed with relevant stakeholders +- [ ] Standard spec draft started to detail the What (may start as a + braindump) +- [ ] Creation criteria verified: Why clear, Who and What recorded +- [ ] Docs section present (at minimum a placeholder with scoping intent) +- [ ] Priority established relative to other triaged Objectives in the + Product Backlog +- [ ] FixVersion set to target LTS cycle (e.g. `26.04 LTS`) +- [ ] Broken down into child Epics (initially Untriaged) — or at least one + child Spike if investigation is needed first +- [ ] Child Spikes created if investigation is needed before Epics can be + defined +- [ ] State set to `Triaged` + +--- + +## Ongoing State Transitions + +| State | Trigger | +|-------------|------------------------------------------------------| +| Triaged | Grooming checklist complete; priority established | +| In Progress | First child Epic moves to In Progress | +| In Review | Child Epics are in review (if applicable) | +| Blocked | External factor halts progress on all child Epics | +| Done | All child Epics are Done | +| Rejected | Work is no longer needed; explicitly closed | + +**State rules:** + +- Parent chain (Objective) must be `Triaged` before a child Epic can be `Triaged`. +- Parent chain should move to `In Progress` when a child moves to`In Progress`. +- An Objective is `Done` only when **all** child Epics are `Done`. + +--- + +## Missing Commitments (Carry-Over) + +If an Objective is not completed by the end of its LTS cycle: + +1. Update `FixVersion` to the next LTS cycle + (e.g. `26.04 LTS` → `28.04 LTS`) +2. Re-prioritise against new and existing Objectives for the incoming cycle +3. Communicate carry-over to leads and document reason + +Do not silently carry over without re-prioritisation — carried Objectives +compete with new commitments. + +--- + +## Interrupts — Ad-hoc Objective Requests + +When a new urgent request arrives that may become an Objective: + +1. **Check for duplicates** — if an existing Objective already covers it, + update that one instead of creating a new one. +2. **Identify timebox** — typically the next LTS cycle. If the current cycle + is requested, re-prioritisation of committed Objectives is required; + communicate with Director and leads. +3. **Apply creation criteria** — Why (clear), Who, What, Docs section + (placeholder). +4. **Assign owner** — escalate to Director / seniors / architects for + grooming. +5. **Apply LTS grooming criteria** — prioritise against existing backlog; + communicate with leads if re-prioritisation is needed. + +--- + +## Grooming Quality Checks (for Agent Assessment) + +| Check | Field / Rule | +| --- | --- | +| `has_why` | Description contains a "Why" section with non-trivial content | +| `has_who` | Description contains a "Who" section | +| `has_what` | Description contains a "What" section | +| `has_docs` | Description contains a "Docs" section | +| `has_fix_version` | `fixVersions` is not empty | +| `has_owner` | `assignee` is set | +| `state_valid` | If children exist and are In Progress, Objective should be In Progress | diff --git a/jira/practices/pulse.md b/jira/practices/pulse.md new file mode 100644 index 00000000..360cb665 --- /dev/null +++ b/jira/practices/pulse.md @@ -0,0 +1,172 @@ +# Pulse Items — Full Lifecycle & Best Practices + +Pulse items are Stories, Tasks, and Spikes — the atomic units of work +assigned to a 2-week sprint (Pulse). Use this document when **creating, +sizing, assigning, or grooming** pulse-level work. + +--- + +## What is a Pulse? + +A Pulse is a 2-week sprint. All Canonical teams share the same sprint +numbering: `Pulse YYYY#nn` (e.g. `Pulse 2026#22`). Pulses are the primary +delivery cadence for the Foundations team. + +Pulse velocity target: **≥ 80%** of committed story points completed per +Pulse. The team currently averages ~60%. + +--- + +## Issue Types + +| Type | When to use | Parent required? | +| ----- | ----------- | --------------- | +| Story | Delivers incremental user/product value; fits in one Pulse | Yes — must have a parent Epic | +| Task | Background, overhead, tech debt, or maintenance work that does not deliver direct user value | No — Tasks may be parentless if they are cross-cutting or team overhead | +| Spike | Time-boxed investigation or ideation to clarify How for a parent Epic or Story | Yes — must have a parent Epic or Story | + +**If work spans more than one Pulse, it is an Epic — not a Story.** +Break it down. + +--- + +## Creation Criteria + +### Story + +All of the following must be clear before creating a Story: + +- **Why**: why does this story matter to the user/product? (derived from + parent Epic) +- **Who**: who benefits from this story being done? +- **What**: what is the specific deliverable or behaviour change? Include a + definition of done. +- **How**: how will this be implemented? The parent Epic's specification must + be approved before the Story is triaged. + +### Task + +- **What**: clearly articulate what needs to be done and why it is necessary + overhead. +- Tasks do not need a formal Why/Who/What structure, but must not be vague + (e.g. "misc work" is not acceptable). + +### Spike + +- **Purpose**: clearly state what question the spike will answer or what + decision it will enable. +- **Time-box**: spikes must have a story point estimate that fits within one + Pulse. If the investigation cannot be completed in one Pulse, break it into + multiple spikes. +- **Output**: define the expected output (e.g. "a decision on approach X vs + Y", "a draft specification", "a prototype"). + +--- + +## Sizing — Story Points + +Story points estimate effort relative to complexity, not time. Use the +following as a rough guide: + +| Points | Effort | +| ------ | ------ | +| 1 | Trivial — a few hours | +| 2 | Small — half a day to one day | +| 3 | Medium — two to three days | +| 5 | Large — most of a Pulse for one person | +| 8 | Very large — consider breaking down; may span multiple people | +| 13+ | Too large for a pulse item — must be broken down into smaller Stories/Tasks | + +A single person should carry at most **~15 story points per Pulse** across +all assigned items. Plan capacity accordingly. + +--- + +## Pulse Planning Checklist (Grooming → Triaged) + +Before a pulse item can be committed to a Pulse: + +- [ ] Story points estimated (`customfield_10016`) +- [ ] Assigned to a specific Pulse / sprint +- [ ] Assignee set (a real person — not unassigned) +- [ ] Parent set (mandatory for Stories and Spikes; optional for Tasks) +- [ ] Team field (`customfield_10001`) set to the correct squad +- [ ] For Stories: parent Epic specification approved +- [ ] Detailed How specified (in the item description or parent Epic spec) +- [ ] Workload balanced across the Pulse for the assignee +- [ ] State set to `Triaged` + +--- + +## During a Pulse + +- Move item to `In Progress` when work actually starts — not at Pulse + kickoff. +- If a blocker is encountered: set status to `Blocked`, add a comment + describing the blocker and who can unblock it, and notify the squad lead + immediately. +- Keep WIP low — completing in-progress items is higher priority than + starting new ones. +- If an item will not complete this Pulse: flag it to the squad lead + **before** the Pulse ends, not in the retro. + +--- + +## Pulse Review & Carry-Over + +At the end of each Pulse: + +- Items `Done` count toward velocity. Target: ≥ 80% of committed story + points done. +- Items not completed: + - If still valid: carry to next Pulse (reassign sprint); re-estimate if + scope changed. + - If no longer needed: close as `Rejected` with a comment. + - Do not silently leave items dangling across multiple Pulses without + comment. + +**Velocity formula:** + +`velocity % = (done story points) / (committed story points) × 100` + +If velocity is consistently below 80%, common causes: + +- Over-commitment at planning (reduce points planned next Pulse) +- Too many parallel items per person (reduce WIP) +- Unresolved blockers accumulating (escalate earlier) +- Items too large to complete in one Pulse (break down further) + +--- + +## State Transitions + +| State | Trigger | +| ----------- | ------- | +| Untriaged | Newly created; not yet groomed | +| Triaged | Grooming checklist complete; assigned to a Pulse | +| In Progress | Work actually starts | +| In Review | Owner's work done; reviewer working on it | +| Blocked | External factor prevents progress | +| Done | Work complete and accepted | +| Rejected | No longer needed; explicitly closed | + +**Rules:** + +- Parent Epic must be `Triaged` before a child can be `Triaged`. +- Parent Epic moves to `In Progress` when any child starts. +- A child Story/Task/Spike moves to `In Review` when the owner is done — + do not skip In Review for non-trivial items. + +--- + +## Grooming Quality Checks (for Agent Assessment) + +| Check | Field / Rule | +| ----- | ----------- | +| `has_story_points` | `customfield_10016` is set and > 0 | +| `has_sprint` | Sprint (Pulse) is assigned | +| `has_parent` | Parent is set (mandatory for Stories and Spikes) | +| `has_team` | `customfield_10001` is not null/empty | +| `has_assignee` | `assignee` is set | +| `status_valid` | Not `Untriaged` if sprint is active | +| `not_oversized` | Story points ≤ 8 (flag if 13+) |