PR #874 follow-ups: gt-route downstack depth, merged-parent diagnosis, set_body/pr_patch nf-yo4 ← Beads

open priority 2 task unassigned

Twinned from https://github.com/cfsh/ninefold/issues/877 by tools/beads/import_github.py's reconcile pass.

Suggestions from ninefold-reviewer's review of #874. Unclaimed, all advisory — #874 is CONVERGED and none of these blocked it.

1. The downstack guard is one branch deep; the hazard is the whole downstack. plan_pr refuses when the gt parent has no open PR (tools/nflib/devcli.py, the gt_parent is not None and base != TRUNK and parent is None arm), but gt submit --no-stack keeps the entire downstack in scope. On main ← A ← B ← C where B has an open PR and A's was closed, a run from C passes the guard and the submit still creates a gateless, ledgerless PR for A. The immediate-parent check is a proxy for "every branch below has a PR", and it holds only while every PR in the stack was opened by this tool and none has since closed. Walk the downstack, or say in the refusal's neighbourhood that it sees only one level.

2. The same refusal misdiagnoses the most common way it will fire. When the parent's PR merged — the normal end of a stack, and the state this very branch was in an hour ago — parent is None for a reason the message does not cover, and it prints "<base> has no open PR yet … gt checkout <base> — open its PR first". The right move there is a restack (gt sync, or gt move --onto main). One extra pr_list(state="merged", head=base) separates the two cases (DEV_PRINCIPLES D2).

3. Gh.set_body is now a strict subset of Gh.pr_patch. Same endpoint, same --input - construction, the same #657 reasoning in both docstrings; set_body(n, b) is exactly pr_patch(n, body=b). One caller each (_link_parent, entitle). Collapse to one (B12, B10).

**4. The composed "⚠ Stacked on #N — this PR's base is X, not main" line goes stale on a restack, and nothing rewrites it.** compose_body writes it once at creation; merge_pr.py retargets a child PR's base when its parent merges, and the sentence in the body then says the opposite of what the PR is. #874 is the specimen — it still claims a base of feat/graphite-token-gotcha after #870 merged and the base moved to main. Either have the retarget rewrite the line, or have it name the parent PR without asserting a base branch.

Dependencies

None.

Comments

No comments.

Add a comment