Project Management Workflow¶
This document describes the GitHub-native project management approach for gepa-adk, using labels, native issue dependencies, and GitHub Projects views.
Philosophy¶
- Labels as metadata - Priority, fit, size and track labels drive all views
- Native dependencies - Use GitHub's
blocked byrelationships between issues; theblockedlabel is only for blockers that are not issues - Views as filters - Project views slice existing data, no manual board management
- Release-driven - Work P1 and P2 until empty, then release and re-prioritize
- Zero ceremony - No sprints, no timeboxes, just continuous flow
Label Schema¶
Priority Labels (Required for "Groomed" Status)¶
Priority measures impact, not urgency. The scale is shared with judgevet.
| Label | Description |
|---|---|
P1 | Wrong output, a leaked secret, or a claim the repo cannot support |
P2 | An output a session or the maintainer reads and acts on is wrong |
P3 | The record, the process, a gate, or a capability |
P4 | Drift and nits |
No P label = Ungroomed - Appears in Needs Grooming view.
The former priority:high, priority:medium and priority:low labels were retired on 2026-09-25. They remain on closed issues for history and must not be applied to new ones.
Fit and Size Labels (Required for "Groomed" Status)¶
Fit says who does the work. Size says whether it can be dispatched whole. Size is defined once, by behaviour, in Delegate a bounded change; the rows below only summarize it.
| Label | Description |
|---|---|
pi-fit | Mechanical and machine-checkable: delegate to any worker harness |
judgment | Needs the orchestrating model: design, verdicts, done-ness |
size-S | One behaviour with an obvious proof; one dispatch |
size-M | One behaviour across a few files behind one acceptance check; one dispatch |
size-L | Too big to delegate whole. Split before assigning |
Workflow Labels¶
| Label | Description |
|---|---|
needs-triage | Filed, not yet read by the maintainer |
ready | An accepted definition of ready and done sits in an issue comment |
blocked | Waits on a named commit, key, release or date; the body names it |
ready is the definition of ready. An issue earns it when a comment records the decision, the necessary evidence, the allowed repairs and the stopping condition, under 150 words, as the repository's bounded-execution rule in CLAUDE.md requires. The specifier agent writes that comment when the brief authorizes posting. A P label alone does not make an issue ready.
blocked is a label because GitHub's native is:blocked filter only sees issue-to-issue dependencies. Use both: the label for a dependency on a release, a credential or a date, and the native relationship for another issue.
Track Labels (Context/Category)¶
| Label | Description |
|---|---|
core | Core evolution engine functionality |
adk | Google ADK integration |
track:tech-debt | Code quality / architectural debt |
track:docs | Documentation or examples |
track:nice-to-have | Non-blocking enhancement |
track:gepa-alignment | Parity with upstream GEPA |
track:adk-extension | ADK-specific extension |
Type Labels (Auto-applied by templates)¶
| Label | Template |
|---|---|
bug | Bug Report |
enhancement | Feature Request |
idea, needs-spec | Feature Idea (Spec-Kit Ready) |
tech-debt | Tech Debt |
adr-violation | Tech Debt (ADR type) |
Status (Inferred, Not Labeled)¶
| Status | How It's Determined |
|---|---|
| Ungroomed | No P label, or needs-triage |
| Triaged | Has P, fit and size labels, no ready comment yet |
| Ready | Has ready + not assigned + not blocked |
| In Progress | Assigned to someone |
| Blocked | Has blocked label or a GitHub dependency (is:blocked) |
| Done | Issue closed |
GitHub Project Views¶
| View | Filter | Purpose |
|---|---|---|
| Ready | is:open label:ready -label:blocked -is:blocked no:assignee | Dispatchable now |
| P1 / P2 | is:open label:P1,P2 -label:blocked -is:blocked | Wrong outputs and wrong records, specify next |
| Delegable | is:open label:pi-fit -label:size-L -label:blocked -is:blocked | Work a worker harness can take whole |
| Needs Split | is:open label:size-L | Split before assigning |
| Blocked | is:open label:blocked,is:blocked | Waiting on a named blocker |
| Needs Grooming | is:open -label:P1 -label:P2 -label:P3 -label:P4 | Untriaged issues |
| Icebox | is:open label:P4 | Drift and nits |
| Done | is:closed | Completed work |
From the CLI:
# what is ready to be worked
gh issue list --search "is:open label:ready -label:blocked -is:blocked no:assignee"
# wrong records a worker can fix now
gh issue list --search "is:open label:P2 label:pi-fit -label:blocked -is:blocked"
# what needs splitting (inventory, so blocked issues stay in)
gh issue list -l size-L
-l alone cannot see GitHub-native dependencies, so every actionable query goes through --search with -is:blocked.
Optional Views¶
| View | Filter | Purpose |
|---|---|---|
| Bugs | is:open label:bug -is:blocked | All open bugs |
| Tech Debt | is:open label:track:tech-debt | Cleanup work |
| Docs | is:open label:track:docs | Documentation tasks |
Workflow¶
Daily Work¶
- Look at the Ready view (or the P1 / P2 view when choosing what to specify next)
- Pick an unassigned issue
- Assign yourself (now "In Progress")
- Work on it
- Close when done (moves to "Done")
- Repeat
Grooming¶
- Open Needs Grooming view
- For each issue:
- Read and understand
- Add one
Plabel by impact, one fit label and one size label - Add track labels (core, adk, etc.)
- Add
blockedand name the blocker in the body, or add a GitHub dependency - Issue automatically moves to appropriate view
- To make a triaged issue Ready, post the definition of ready and done as a comment, then add
ready
Release Cycle¶
- Work until P1 / P2 is empty (except epics)
- Release
- Re-read the open P3 issues:
- Promote any whose impact grew to
P2 - Demote any that turned into drift to
P4 - Check Needs Grooming for anything missed
- Repeat
Dependencies¶
GitHub supports native issue dependencies (GA August 2025).
Adding a Dependency¶
Via UI: 1. Open the issue that is blocked 2. In right sidebar, find Relationships 3. Click "Mark as blocked by" 4. Select the blocking issue(s)
Via CLI (GraphQL):
# Get issue node IDs first
gh api graphql -f query='{
repository(owner: "Alberto-Codes", name: "gepa-adk") {
issue(number: ISSUE_NUMBER) { id title }
}
}'
# Add dependency
gh api graphql -f query='
mutation {
addBlockedBy(input: {
issueId: "BLOCKED_ISSUE_NODE_ID"
blockingIssueId: "BLOCKING_ISSUE_NODE_ID"
}) { issue { number } }
}'
Filtering Blocked Issues¶
is:blocked- All blocked issues-is:blocked- All unblocked issues- Use
-is:blockedin the Ready, P1 / P2 and Delegable views to show only actionable work
Issue Templates¶
| Template | Use When | Auto Labels |
|---|---|---|
| Bug Report | Something is broken | bug |
| Tech Debt / Maintenance | Code cleanup, ADR violations, refactoring | tech-debt |
| Feature Idea (Spec-Kit Ready) | Parking an idea that needs a specification before work; the template name is residue tracked in #518 | idea, needs-spec |
| Feature Request | New capability needed, ready to implement | enhancement |
| Story | A story under the optional story workflow | story |
| Retro Action | An action item from a retrospective | retro-action |
| TEA Audit Tracker | A test-maturity audit | tea:test-maturity, tea:audit |
| TEA Action Item | One action from a test-maturity audit | tea:test-maturity, tea:action |
All templates include invisible maintainer/AI guidance comments with: - Priority, fit and size label guidance - Track label hints - Dependency setup instructions via GraphQL
Maintenance¶
Regular Tasks¶
| Task | Frequency |
|---|---|
| Groom new issues | As needed |
| Review blocked issues | Weekly |
| Archive old Done items | Monthly |
| Re-prioritize after release | Per release |
Health Checks¶
- Needs Grooming not empty too long - Schedule grooming
- Ready empty while P1 / P2 is not - Run a specification pass
- P1 / P2 empty - Time for release or re-prioritize
- Blocked growing - Check if blockers are being worked