Add durable resumable PR publication and recovery - #119
Protonmatter wants to merge 3 commits into
Conversation
Integrate the reviewed publisher implementation into the specification branch. Preserve original ancestry for the #120 -> #119 stack. Current-head CI, Coverage and Docs passed; 98 publisher tests passed again during pre-merge review. Live transport/platform qualification remains documented separately. No rendering changes or Earth recovery included. Master promotion remains gated on fresh #119 validation.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3e6c79e5e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| value = client.find_pr(head.removeprefix('refs/heads/'), base.removeprefix('refs/heads/'), args.pr, owner) | ||
| number = value['number'] if value else None |
There was a problem hiding this comment.
Require --pr before adopting an existing pull request
When --pr is omitted but an exact open head/base match already exists, these lines silently assign its number and proceed with publication. An operator intending a new PR can therefore update the branch backing an existing PR without explicitly approving that PR's scope; reject the match and require its number to be supplied before proceeding.
AGENTS.md reference: AGENTS.md:L13-L15
Useful? React with 👍 / 👎.
| except PublicationError: | ||
| pass |
There was a problem hiding this comment.
Preserve definitive PR-creation failures after reconciliation
When create_pr fails definitively with code 4, such as an HTTP 403 or 422, this catch discards the classification; if the subsequent read confirms no PR was created, line 124 replaces it with code 5. The receipt now labels a known rejection as uncertain, so resume calls create_pr again instead of remaining blocked; retain the original failure after readback when the PR is still absent.
AGENTS.md reference: AGENTS.md:L17-L20
Useful? React with 👍 / 👎.
| client = client_factory(args.repository, args.checkout, runner=runner) | ||
| head, base = full_ref(args.head), full_ref(args.base) | ||
| info = client.preflight(head.removeprefix('refs/heads/')) |
There was a problem hiding this comment.
Validate the selected transport during inspect
The inspect path never reads args.transport: it only performs GitHub API metadata checks and then returns success. Consequently, inspect --transport native can report state: inspected even when Git is unavailable, native credentials cannot push, or URL rewriting would later reject the endpoint, so the required authenticated publication path is not established until after implementation and packet preparation; probe and report the selected transport's actual capabilities here.
AGENTS.md reference: AGENTS.md:L3-L5
Useful? React with 👍 / 👎.
| paths = sorted(p for p in before.keys() | after.keys() if before.get(p) != after.get(p)) | ||
| require(paths and paths == sorted(allowed), 'changed-path-allowlist-mismatch') |
There was a problem hiding this comment.
Audit all published history against the allowlist
The allowlist is derived only from the anchor and candidate trees, so a multi-commit candidate can add a credential or out-of-scope file in an intermediate commit and remove it before the final tree while still passing this check. The recovery bundle and native push nevertheless include that intermediate commit and blob, exposing data that was absent from the approved final diff; either require a direct-parent candidate or validate every commit and object that the bundle will publish.
AGENTS.md reference: AGENTS.md:L27-L30
Useful? React with 👍 / 👎.
Outcome
Combined specification, implementation, regression tests, and operator guidance for durable PR publication. This PR originally contained design documents only; the owner approved the implementation and the #120 -> #119 -> master integration sequence. #120 has now been merged into this branch with a merge commit, preserving the original implementation commit and ancestry.
3e6c79e5e8726ea614df205a1735aaed10cce99c0759f8dd1fe24e2ff8cfb166f9f61a6684573f097d843fadcb22de6e23237c12f5661eccb26499d2masterEntry point:
tools/publish_pr_candidate.pywithinspect,prepare,execute, andresume. The tool preserves a binary-safe candidate and immutable checkpoints, protects head updates with explicit preconditions, and verifies remote branch/PR identity before reporting source publication. It reports CI separately and never merges or deploys on its own.Specification and traceability
docs/superpowers/specs/2026-09-25-durable-pr-publication-design.mddocs/superpowers/plans/2026-09-25-durable-pr-publication.mddocs/PR_PUBLICATION.md; rootAGENTS.mdand PR-template publication-evidence fields included.Correctness and risk
Six Python production modules separate immutable intent/reconciliation, recovery packets/journals, native Git, API staging, concrete authenticated GitHub CLI access, and the operator CLI. Exact committed bytes, allowed paths, Git OIDs, SHA-256, tree and ordered parents are validated.
Native publication requires an explicit expected-head lease plus ancestry checks. Existing-head API publication requires GraphQL
updateRefswithbeforeOid; RESTforce=falseis not treated as compare-and-swap. A bridge lacking the stronger primitive cannot silently downgrade an existing-ref update. Timed-out writes are reconciled by fresh reads; duplicate PR creation is not blindly retried.Source publication, CI observation, CI success, merge, and deployment remain separate. Current-source/current-base identities are required for CI evidence. Failure output uses unknown publication state rather than falsely asserting that no remote side effect occurred.
Limitations retained from #120: concrete CLI storage is an operator-declared persistent filesystem; a ChatGPT Library bridge must be integrated explicitly. API parent commits must already exist remotely; native Git transfers otherwise unpublished history. API mode rejects unsupported signed/encoding headers. Live native/GraphQL qualification and physical Windows/network-filesystem durability remain open. The helper must actually be used by the authoring runtime.
Deferred minor: subprocess output is bounded after capture rather than streamed, so an unusually noisy hook can temporarily consume additional memory. Author-side review only; no independent approval is fabricated.
Rollback: revert the combined change with the normal reviewed workflow. No application/data migration or renderer change is included.
UI and UX
No application UI change. Operator output distinguishes prepared, persisted, object/commit verified, branch verified, PR verified and CI states. PowerShell examples and same-operation resume avoid manual SHA transcription.
Validation evidence
0759f8dd1fe24e2ff8cfb166f9f61a6684573f09and its recorded base. These are predecessor evidence, not the new Add durable resumable PR publication and recovery #119 gate.3e6c79e5e8726ea614df205a1735aaed10cce99cbefore master merge.The local review checkout was recovered from the exact saved implementation overlay because direct GitHub clone still failed DNS resolution in the execution container. It is not represented as a full local SOL checkout. Hosted full-repository results are assessed separately.
Publication identity and recovery
The original design packet and implementation packet were saved outside their execution environments before publication and read back with checksum verification. Immutable tree/commit/ref checkpoints remain in the owner's Library.
ab5662649c047377b96d7d233a4b095906fd87c2a6516223b746475a3d296bac436ed0a0ceff96a0acfe37313ccfaefd9322a9663cfd604bef11428238e99f59cc183af075df907196e2148aa2a5658b753730103e6c79e5e8726ea614df205a1735aaed10cce99cThe original newer Earth candidate remains missing; #116 is unchanged and held. Duplicate #117/#118 were closed without deleting branches or merging their rendering changes. Sun/planet visual release holds remain intact.
Master integration gate
Use a merge commit and an expected source-head SHA. Require fresh combined-head validation and respect all server-enforced protection. After master merge, verify the resulting master CI/artifact/deployment separately; never infer served release success from PR merge success.