Re-scoped 2026-07-25
The Success Metrics below describe a scratch-repo exercise. That is no longer the plan, and
the metrics that mention a scratch repo, the full chain, or a 30-minute reproduction are stale.
What changed. The epic's real question — does range derivation pick the right base against
real GitHub — needs a real merged PR, not a disposable one. This repo has a dozen. Measuring
against them read-only cost minutes, required no delete_repo scope, and returned 6/6 PASS with
zero divergences, including post-branch-delete pull/<N>/head reachability on four PRs whose
branches are actually gone. Recorded as
Run 2026-07-25.
Standing metrics, revised:
Why #134 and #136 were closed. Review publishing is unreachable on a single account, so the
analyze exercise would only have measured the comment fallback the next real epic exercises for
free; and close/distill failures are loud and recoverable, unlike a silently-wrong range. Neither
justified granting repo-delete to the maintainer's credential. Full rationale in each issue.
The nxs-pr-acceptance harness (#133) is retained as the controlled reproduction if something
misbehaves for real — it is no longer a gate.
Epic: Live Acceptance Dry-Run of the PR Post-Merge Flow
Description
The --pr post-merge flow — analyze --pr on the open PR, merge, then close --pr and
distill in one shared worktree — is the flow that decides which diff the distiller reads weeks
later. Its riskiest mechanics (merge-strategy-safe range derivation, the worktree lifecycle, the
analyze receipt that close reads back) live in libs/pr-worktree and are covered by unit tests
that inject a fake command runner. Those tests prove the logic given the git and gh output we
believe real GitHub produces. Nothing in the build environment has ever run the flow against an
actual pull request.
That gap matters most where the code already knows it is guessing. Range derivation cannot tell a
squash from a rebase by topology alone and disambiguates by comparing changed-file sets against a
fetched PR head; it deliberately refuses rather than stamps an ambiguous range. Whether real
GitHub merges produce the parent counts, SHAs, and post-branch-delete reachability those branches
assume is an empirical question, and a wrong answer is silent — it surfaces as the wrong concept
pages being rewritten long after the PR is forgotten.
This epic buys that evidence once and makes it cheap to re-buy. It builds a throwaway scratch
repo harness, drives the whole chain against it under each of the three merge strategies, and
leaves behind a runbook plus an acceptance record. It does not fix what it finds: divergences
between live behavior and the injected-runner assumptions are captured as filed issues or backlog
stubs, so the fix is a separately-sized decision rather than unbounded work smuggled into an
acceptance check.
Success Metrics
- All three merge strategies (squash, merge commit, rebase) are exercised against a real hosted
PR and each either yields a range verified against the authoritative PR file set or exits with a
named diagnostic — zero silently-wrong ranges.
- The full
analyze --pr → merge → close --pr → distill chain completes on the scratch repo with
no manual git or gh intervention beyond the harness's own commands.
- A maintainer can reproduce the entire exercise from the runbook on a clean checkout in under
30 minutes.
- Every divergence between live behavior and the injected-runner unit tests is captured as a filed
issue or backlog stub; the count is reported (and may legitimately be zero).
- Teardown leaves zero residue — no scratch repo, no stray git worktrees, no branches in the host
checkout.
Personas
Per docs/product/context.md. This epic is exercised by the maintainer/delivery lead persona
only; it adds no end-user-facing surface.
Assumptions
- The scratch repo is created under the same GitHub owner as this repo, is treated as disposable,
and is deleted at teardown; a keep-alive flag is available for debugging a failed run.
- This is a maintainer-invoked, on-demand exercise, not a CI job —
docs/system/stack.md
records that no CI is configured for this repo yet.
gh is authenticated with sufficient scope to create, merge into, and delete a repository.
- The exercise makes real GitHub API calls; no attempt is made to mock, record, or replay them.
- Where live behavior contradicts an injected-runner unit test, the live behavior is treated
as authoritative and the test is the thing recorded as suspect.
Out of Scope
- Hub / multi-repo workspace live runs — the stub scopes this to a single scratch repo; member-repo
--pr support remains the separate member-pr-post-merge-flow backlog stub.
- Fork-originated PR heads (the
pull/<N>/head fetch path) — proving it needs a second GitHub
account, which is a larger setup than this check justifies.
- Member-repo rejection of
--pr, which is a pure role-gate check already covered by unit tests.
- Wiring the acceptance run into CI.
- Fixing whatever the dry-run finds. Divergences are recorded and filed; each fix is sized and
scheduled separately.
Open Questions
None.
Epic: Live Acceptance Dry-Run of the PR Post-Merge Flow
Description
The
--prpost-merge flow —analyze --pron the open PR, merge, thenclose --pranddistillin one shared worktree — is the flow that decides which diff the distiller reads weekslater. Its riskiest mechanics (merge-strategy-safe range derivation, the worktree lifecycle, the
analyze receipt that close reads back) live in
libs/pr-worktreeand are covered by unit teststhat inject a fake command runner. Those tests prove the logic given the
gitandghoutput webelieve real GitHub produces. Nothing in the build environment has ever run the flow against an
actual pull request.
That gap matters most where the code already knows it is guessing. Range derivation cannot tell a
squash from a rebase by topology alone and disambiguates by comparing changed-file sets against a
fetched PR head; it deliberately refuses rather than stamps an ambiguous range. Whether real
GitHub merges produce the parent counts, SHAs, and post-branch-delete reachability those branches
assume is an empirical question, and a wrong answer is silent — it surfaces as the wrong concept
pages being rewritten long after the PR is forgotten.
This epic buys that evidence once and makes it cheap to re-buy. It builds a throwaway scratch
repo harness, drives the whole chain against it under each of the three merge strategies, and
leaves behind a runbook plus an acceptance record. It does not fix what it finds: divergences
between live behavior and the injected-runner assumptions are captured as filed issues or backlog
stubs, so the fix is a separately-sized decision rather than unbounded work smuggled into an
acceptance check.
Success Metrics
PR and each either yields a range verified against the authoritative PR file set or exits with a
named diagnostic — zero silently-wrong ranges.
analyze --pr → merge → close --pr → distillchain completes on the scratch repo withno manual
gitorghintervention beyond the harness's own commands.30 minutes.
issue or backlog stub; the count is reported (and may legitimately be zero).
checkout.
Personas
Per
docs/product/context.md. This epic is exercised by the maintainer/delivery lead personaonly; it adds no end-user-facing surface.
Assumptions
and is deleted at teardown; a keep-alive flag is available for debugging a failed run.
docs/system/stack.mdrecords that no CI is configured for this repo yet.
ghis authenticated with sufficient scope to create, merge into, and delete a repository.as authoritative and the test is the thing recorded as suspect.
Out of Scope
--prsupport remains the separatemember-pr-post-merge-flowbacklog stub.pull/<N>/headfetch path) — proving it needs a second GitHubaccount, which is a larger setup than this check justifies.
--pr, which is a pure role-gate check already covered by unit tests.scheduled separately.
Open Questions
None.