Skip to content

fix: repoint a merged PR's change backlink when the change is archived - #397

Merged
danielhanold merged 13 commits into
mainfrom
fix/repoint-a-merged-pr-s-change-backlink-when-the-change-is-arc
Oct 6, 2026
Merged

danielhanold merged 13 commits into
mainfrom
fix/repoint-a-merged-pr-s-change-backlink-when-the-change-is-arc

Conversation

@danielhanold

@danielhanold danielhanold commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

↩ Change 0529 — Repoint a merged PR's change backlink when the change is archived

Summary

Close-out now repoints a merged PR's docket backlink block at the archived change record (best effort; a failure is a pr-backlink-pending warning that cleanup and the full maintenance sweep retry). New docket repository repair --pr-backlinks previews and, with --yes, fixes merged PRs whose backlink names a stale active/ path. Routine repository repair, check, and prepare make no PR-body reads.

Heads-up before merge: the full maintenance sweep's retry also covers legacy PRs, so the first full sweep after merge will repoint about 168 existing PR descriptions without a preview. Run docket repository repair --pr-backlinks (preview only) first if you want to review the list. Details in the results file.

Other departures from the spec: finalize.closeout declares external-write; --pr-backlinks runs only the PR repair; full sweeps batch-read done PRs' bodies (~ceil(done/25) GraphQL calls).

Review

Whole-branch review: deep tier (standard build tier, bumped for a >1500-line diff).

# Severity Finding Disposition
1 blocker Full sweep silently bulk-repairs legacy PRs, contradicting the "human-confirmed" framing fixed 2e16a4435 (kept the spec §1 sweep rule, pinned with a test, docs corrected)
2 important Carried stacked descendant's pending repoint could never be retried by cleanup fixed c26c95de9
3 minor A refused GitHub edit was reported as a race (contended) fixed cb89d6e90
4 minor byPR map unused; duplicate-PR candidates planned twice fixed cb89d6e90 (sharers now skipped)
5 minor finalize skill put the GitHub edit inside the atomic transaction fixed cb89d6e90
6 minor convention said the PR-body backlink is written solely by artifact.backlink fixed cb89d6e90

command: go run ./cmd/docket development test
result: green
head_sha: df03be7
ran_at: 2026-10-06T01:51:39Z

Docket-Plan-Path: docs/superpowers/plans/2026-10-05-repoint-a-merged-pr-s-change-backlink-when-the-change-is-arc.md
…revision

Verification:

$ gh --version
gh version 2.101.0 (2026-09-15)
https://github.com/cli/cli/releases/tag/v2.101.0

$ gh api graphql \
  -f query='query($o:String!,$n:String!){repository(owner:$o,name:$n){pullRequest(number:250){number state viewerCanUpdate}}}' \
  -f o=danielhanold -f n=docket
{"data":{"repository":{"pullRequest":{"number":250,"state":"MERGED","viewerCanUpdate":true}}}}
(exit 0)

EditPullRequestBody is classified as a network WRITE site in
TestEveryNetworkSiteIsReadWriteClassified and the client_test.go enumeration.
…klinks; docs say so

The full maintenance sweep assesses every archived done record's merged PR
body and its cleanup repoints a backlink still naming the old active/ path,
with no prior close-out attempt; the implementation-scope sweep defers the
record untouched. Living docs and the docket-status skill now say the full
sweep makes this repair unpreviewed and that repository repair --pr-backlinks
is the previewed way to do it all at once.
…ore the destination refusal

A carried stacked descendant merges into its parent's branch, so cleanup's
merge-destination refusal returned before the PR-body repoint leg; a close-out
repoint that failed had no reachable retry while the sweep kept re-dispatching
cleanup. The non-destructive repoint now runs first and its finding rides the
refusal; the destructive legs stay gated as before.
- M3: EditPullRequestBody's verify probe now tells a refused or lost edit
  (the body still equals the pre-edit body) from a race (a third body). The
  former is `unknown` with a bounded, redacted stderr excerpt; only the latter
  is `contended`. applyPRBacklinkRepoint's unknown detail says the edit was not
  applied or could not be verified, so a 403/locked PR is no longer reported as
  "the body changed since it was read".
- M4: planPRRepairs uses byPR: a PR named by more than one done change is a
  `skipped` row for each sharer, never read or planned.
- M5: docket-finalize-change places the PR-backlink repoint after the
  lease-pushed archive transaction as a separate best-effort follow-up, for
  done-archived and for root-archived roots and descendants.
- M6: docket-convention names the PR-body backlink writers (pr.publish;
  finalize.closeout retried by finalize.cleanup and maintenance.sweep;
  repository.repair with --pr-backlinks) beside artifact.backlink, one shared
  renderer. Embedded assets regenerated; skill word budgets resized.
@danielhanold
danielhanold merged commit abdc6df into main Oct 6, 2026
1 check passed
@danielhanold
danielhanold deleted the fix/repoint-a-merged-pr-s-change-backlink-when-the-change-is-arc branch October 6, 2026 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant