ADR-022: Issue Lifecycle Tracking Pattern
Status
Accepted - 2025-10-01
Context
The three-branch cascade (ADR-001) and the human-centric cascade pattern (ADR-019) need a single place that shows where an upstream changeset is in the pipeline, whether it is blocked, and what a human should do next. Without it, that state is spread across workflow logs and several PRs, and a failure is easy to miss.
Requirements:
- One issue tracks the whole cascade lifecycle for one upstream changeset
- State is machine-readable through labels and human-readable through comments
- Conflicts and failures are visible on the issue, not only in logs
Decision
Create one tracking issue per upstream sync and keep it current through the cascade:
- Issue creation:
sync.ymlcreates the issue titled📥 Upstream Sync Ready for Review - <date>with labelsupstream-sync,human-required, subject to the duplicate prevention in ADR-024. The body carries the sync PR, upstream version, commit count, next steps, and a hidden<!-- upstream-sha: ... -->marker. - State transitions:
cascade.ymltakes the tracking issue number as itsissue_numberworkflow input and moves labels as the cascade progresses. - Progress comments: each transition adds a timestamped comment with a link to the workflow run.
- Safety net:
cascade-monitor.ymlcomments on the issue when it auto-triggers a missed cascade or a retry.
Issue State Machine
stateDiagram-v2
[*] --> created: sync.yml detects changes
created --> human_required: Issue created with upstream-sync label
human_required --> cascade_active: Human triggers cascade
human_required --> cascade_active: Monitor auto-triggers (safety net)
cascade_active --> cascade_blocked: Conflicts detected
cascade_active --> cascade_failed: Integration failed
cascade_active --> validated: Integration successful
cascade_blocked --> cascade_active: Conflicts resolved
cascade_failed --> cascade_active: Human resolves + monitor retries
validated --> [*]: Production PR merged, issue closed Label Strategy
| Label | Meaning | Human Action | Next State |
|---|---|---|---|
upstream-sync, human-required | Upstream sync complete, awaiting manual cascade trigger | Review sync PR, merge, trigger cascade | cascade-active |
upstream-sync, cascade-active | Cascade integration in progress | Monitor progress, wait for completion | validated, cascade-blocked, or cascade-failed |
upstream-sync, cascade-blocked | Conflicts detected, manual resolution needed (48-hour SLA, escalated by the monitor) | Resolve conflicts, commit fixes | cascade-active |
upstream-sync, cascade-failed, human-required | Integration failed, human intervention required | Review failure issue, fix problems, remove human-required label | cascade-active (automatic retry) |
upstream-sync, validated | Production PR created, ready for final review | Review and merge production PR | Issue closed |
The transitions are implemented inline in .github/template-workflows/cascade.yml: human-required to cascade-active when the cascade starts, cascade-active to cascade-blocked on merge conflicts or validation failure, cascade-active to cascade-failed,human-required on an unrecoverable error, and every cascade label removed in favour of validated when the production PR is created. The production-ready label exists in labels.json but no workflow applies it.
Alternatives Considered
- Workflow-only tracking: no extra resources, but state is spread over many runs and invisible without opening logs. Rejected.
- One issue per stage: precise, but proliferates issues and loses the overall story. Rejected.
- External tracking system: more capable, but adds infrastructure and is not integrated with GitHub. Rejected.
- PR-based tracking only: the sync PR closes at merge, before the cascade finishes, so its lifecycle does not match. Rejected.
- Project board: needs manual card movement, less automatable than labels. Rejected.
Consequences
Every sync creates an issue, so an abandoned cascade leaves an open issue behind; the monitor's stale-conflict escalation covers the cascade-blocked case but nothing closes an issue whose production PR was never merged. Label semantics are shared across sync.yml, cascade.yml, and cascade-monitor.yml (ADR-020), so a label change touches all three.
Related ADRs
- ADR-001: Three-Branch Fork Management Strategy - Defines cascade process being tracked
- ADR-019: Cascade Monitor Pattern - Human-centric cascade approach that this supports
- ADR-020: Human-Required Label Strategy - Label management strategy used for state tracking
- ADR-005: Automated Conflict Management Strategy - Conflict handling that this tracks
- ADR-024: Sync Workflow Duplicate Prevention - Issue creation and the
upstream-shamarker