Context
During the active review-liveness P0 on 2026-06-19, PR #13527 looked locally clean against its stacked base (agent/13498-who-is-online) and had its PR-body/review-body lint checks green. But its base PR, #13517, was still mergeStateStatus: DIRTY against dev. That means #13527 could not naturally retarget to dev, and the promised full-CI run on retarget could not happen until someone noticed and routed the base-PR rebase.
This is not covered by #13522. #13522 handles assigned review requests aging without visible reviewer action. This ticket handles a different lifecycle topology failure: a stacked PR can look clean on its feature base while the base PR is stale/dirty against dev, silently blocking the downstream PR's full-CI path.
Live latest-open sweep: checked latest 20 open issues at 2026-06-19T07:15:01Z; adjacent issues found (#13522, #13524, #13515, #13498, #13289), but no equivalent stacked-PR dependency / retarget-CI blocker ticket.
A2A in-flight claim sweep: checked latest 30 all-status messages at 2026-06-19T07:15:01Z; no competing [lane-claim] / [lane-intent] for stacked PR dependency liveness found.
Release classification: boardless P0 agent-runtime hardening. It can be pulled into the active Agent Harness board if the operator wants the whole #13498 / review-liveness chain board-tracked.
The Problem
Stacked PRs are useful for small, sequenced substrate work, but they introduce a second readiness dimension:
- The child PR can be
CLEAN against its feature-branch base.
- The base PR can be
DIRTY, UNSTABLE, or otherwise not mergeable against dev.
- The child PR's full CI can be deferred until retarget to
dev.
When those facts are not projected together, agents can overstate readiness. The child PR reads like "only waiting on retarget/full CI," but the retarget is blocked by a base PR that needs author action. This preserves the same operator-visible failure class as stale review requests: the lifecycle appears handled while no visible actor owns the next transition.
The Architectural Reality
The relevant substrate is the PR lifecycle workflow, not the GitHub API itself:
post-review-pickup already requires live PR-state freshness before naming merge/readiness state.
- #13523 adds an active-window review-request liveness gate so assigned review requests are not treated as coordination-complete.
- Stacked PRs add a dependency edge that is not currently audited by those gates:
baseRefName !== dev should trigger a lookup of the base PR that owns that branch and a readiness projection of that base PR.
This is a process-trust/lifecycle projection gap, not a hard ban on stacked PRs.
The Fix
Add a stacked-PR dependency liveness check to the agent lifecycle substrate:
- When a PR's
baseRefName is not dev (or the configured default branch), resolve whether that base branch belongs to an open PR.
- Project the base PR's
state, mergeStateStatus, reviewDecision, and relevant check state before declaring the child PR ready, CI-deferred, human-gated, or verified-empty.
- If the base PR is
DIRTY, UNSTABLE, missing required review, or otherwise blocking retarget, route a targeted A2A / PR comment to the base PR author or current owner.
- Preserve the allowed stacked-flow shape: child PR review may still verify the delta against the stacked base, but formal merge-readiness / final approval must name the base dependency and the full-CI retarget gate.
A minimal first implementation can be documentation/workflow substrate in post-review-pickup / pr-review / pull-request; a later mechanical helper can consume the same contract if recurrence justifies code.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
| Reviewer PR readiness wording |
This ticket, #13522, pr-review freshness gates |
Stacked child PR reviews must name base-PR readiness and retarget/full-CI status before approval or merge-readiness claims |
If base PR cannot be resolved, treat stack-readiness as unknown and route a blocker instead of approving readiness |
pr-review / related reference payload |
Review body on a stacked PR includes base PR state |
| Post-review pickup lane-state |
This ticket, post-review-pickup |
human-gate / verified-empty is invalid when a relevant stacked base PR is dirty/stale and the agent can route it |
If the base PR belongs to another author, send targeted A2A rather than stealing the branch |
post-review-pickup reference payload |
A dirty base PR produces a visible handoff |
| Author-side PR routing |
This ticket, pull-request workflow |
Authors opening stacked PRs must state merge order and full-CI deferral, and revisit the base PR when it blocks retarget |
Non-stacked PRs unaffected |
pull-request workflow pointer |
PR body/checklist covers stack dependency |
Decision Record impact
none. Aligned with the existing PR lifecycle freshness discipline and #13522's active-window review-request liveness gate.
Acceptance Criteria
Out of Scope
- Banning stacked PRs.
- Automatically rebasing another maintainer's PR branch.
- Building a dedicated stack graph service unless this workflow rule proves insufficient.
- Replacing #13522's review-request liveness gate.
Avoided Traps
- Treating child
CLEAN as merge-ready: rejected. Clean against a stacked base is not proof that the base can merge to dev.
- Treating deferred CI as green CI: rejected. Full CI may not exist until retarget; wording must preserve that distinction.
- Stealing author branches: rejected. The first fix is visibility and routing; author ownership remains intact unless a maintainer-polish path is explicitly invoked.
Related
Related: #13522, #13517, #13527, #13498, #13289
Origin Session ID: c3a6e312-b858-4be4-ad97-9bc55cbad5ae
Handoff Retrieval Hints
query_raw_memories("stacked PR dirty base retarget full CI review liveness mergeStateStatus")
query_raw_memories("#13527 stacked-PR full CI deferred to retarget #13517 DIRTY")
Context
During the active review-liveness P0 on 2026-06-19, PR #13527 looked locally clean against its stacked base (
agent/13498-who-is-online) and had its PR-body/review-body lint checks green. But its base PR, #13517, was stillmergeStateStatus: DIRTYagainstdev. That means #13527 could not naturally retarget todev, and the promised full-CI run on retarget could not happen until someone noticed and routed the base-PR rebase.This is not covered by #13522. #13522 handles assigned review requests aging without visible reviewer action. This ticket handles a different lifecycle topology failure: a stacked PR can look clean on its feature base while the base PR is stale/dirty against
dev, silently blocking the downstream PR's full-CI path.Live latest-open sweep: checked latest 20 open issues at 2026-06-19T07:15:01Z; adjacent issues found (#13522, #13524, #13515, #13498, #13289), but no equivalent stacked-PR dependency / retarget-CI blocker ticket.
A2A in-flight claim sweep: checked latest 30 all-status messages at 2026-06-19T07:15:01Z; no competing
[lane-claim]/[lane-intent]for stacked PR dependency liveness found.Release classification: boardless P0 agent-runtime hardening. It can be pulled into the active Agent Harness board if the operator wants the whole #13498 / review-liveness chain board-tracked.
The Problem
Stacked PRs are useful for small, sequenced substrate work, but they introduce a second readiness dimension:
CLEANagainst its feature-branch base.DIRTY,UNSTABLE, or otherwise not mergeable againstdev.dev.When those facts are not projected together, agents can overstate readiness. The child PR reads like "only waiting on retarget/full CI," but the retarget is blocked by a base PR that needs author action. This preserves the same operator-visible failure class as stale review requests: the lifecycle appears handled while no visible actor owns the next transition.
The Architectural Reality
The relevant substrate is the PR lifecycle workflow, not the GitHub API itself:
post-review-pickupalready requires live PR-state freshness before naming merge/readiness state.baseRefName !== devshould trigger a lookup of the base PR that owns that branch and a readiness projection of that base PR.This is a process-trust/lifecycle projection gap, not a hard ban on stacked PRs.
The Fix
Add a stacked-PR dependency liveness check to the agent lifecycle substrate:
baseRefNameis notdev(or the configured default branch), resolve whether that base branch belongs to an open PR.state,mergeStateStatus,reviewDecision, and relevant check state before declaring the child PR ready, CI-deferred, human-gated, or verified-empty.DIRTY,UNSTABLE, missing required review, or otherwise blocking retarget, route a targeted A2A / PR comment to the base PR author or current owner.A minimal first implementation can be documentation/workflow substrate in
post-review-pickup/pr-review/pull-request; a later mechanical helper can consume the same contract if recurrence justifies code.Contract Ledger Matrix
pr-reviewfreshness gatespr-review/ related reference payloadpost-review-pickuphuman-gate/verified-emptyis invalid when a relevant stacked base PR is dirty/stale and the agent can route itpost-review-pickupreference payloadpull-requestworkflow pointerDecision Record impact
none. Aligned with the existing PR lifecycle freshness discipline and #13522's active-window review-request liveness gate.
Acceptance Criteria
baseRefNamenotdev/ default branch) and requires resolving the base PR readiness before merge-readiness or final approval claims.human-gate/verified-emptywhen a dirty/stale stacked base PR is the next visible transition and the agent can route it.Out of Scope
Avoided Traps
CLEANas merge-ready: rejected. Clean against a stacked base is not proof that the base can merge todev.Related
Related: #13522, #13517, #13527, #13498, #13289
Origin Session ID: c3a6e312-b858-4be4-ad97-9bc55cbad5ae
Handoff Retrieval Hints
query_raw_memories("stacked PR dirty base retarget full CI review liveness mergeStateStatus")query_raw_memories("#13527 stacked-PR full CI deferred to retarget #13517 DIRTY")