Skip to content

Add durable resumable PR publication and recovery - #119

Open
Protonmatter wants to merge 3 commits into
masterfrom
docs/durable-pr-publication-20260925
Open

Protonmatter wants to merge 3 commits into
masterfrom
docs/durable-pr-publication-20260925

Conversation

@Protonmatter

@Protonmatter Protonmatter commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

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.

  • Current integration head: 3e6c79e5e8726ea614df205a1735aaed10cce99c
  • Implementation source: 0759f8dd1fe24e2ff8cfb166f9f61a6684573f09
  • Original design commit: 7d843fadcb22de6e23237c12f5661eccb26499d2
  • Target: master

Entry point: tools/publish_pr_candidate.py with inspect, prepare, execute, and resume. 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

  • Approved design: docs/superpowers/specs/2026-09-25-durable-pr-publication-design.md
  • Approved plan: docs/superpowers/plans/2026-09-25-durable-pr-publication.md
  • Acceptance scope: PUB-01 through PUB-12 in that design; transport/platform qualification limits remain explicit.
  • Operator guide: docs/PR_PUBLICATION.md; root AGENTS.md and PR-template publication-evidence fields included.
  • Daily-feed activation hold, generated-data allowlist, rendering code, textures, CI/Pages workflows, dependencies and branch protection are unchanged.
  • Non-goals: recreating missing Earth source, modifying Add optional Enhanced Earth oceans, raised clouds and shadows #116, accepting rendering appearance, creating credentials, or enabling unattended publication.

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 updateRefs with beforeOid; REST force=false is 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

  • Implementation suite: 98 publication tests passed; no failures/skips.
  • Fresh pre-merge rerun on the exact retained implementation source: 98 tests passed, 17.441 s, exit 0.
  • New-tool-only reported coverage: statements 862/868 (99.31%), branches 157/160 (98.125%). Not whole-repository coverage.
  • Binary recovery, stale leases, competing writers, lost API responses, corrupted packets, missing prerequisites, redirected remotes, hidden working changes, duplicate PR prevention and CI identity failures covered.
  • Implement durable resumable PR publication (stacked on #119) #120 hosted CI run 36154468542, Coverage 36154468193, and Docs 36154467819 completed successfully for source 0759f8dd1fe24e2ff8cfb166f9f61a6684573f09 and its recorded base. These are predecessor evidence, not the new Add durable resumable PR publication and recovery #119 gate.
  • Fresh combined-head Add durable resumable PR publication and recovery #119 CI/coverage/docs: must be verified for 3e6c79e5e8726ea614df205a1735aaed10cce99c before master merge.
  • Live native/GraphQL transport smoke qualification and physical platform durability: not established by local tests or this merge.
PYTHONPATH=tools python -m unittest discover -s tests/python -p 'test_pr_publication*.py' -v
98 tests; zero failures/skips; exit 0 (fresh pre-merge review).

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.

  • Design packet SHA-256: ab5662649c047377b96d7d233a4b095906fd87c2a6516223b746475a3d296bac
  • Implementation packet SHA-256: 436ed0a0ceff96a0acfe37313ccfaefd9322a9663cfd604bef11428238e99f59
  • Implementation tree: cc183af075df907196e2148aa2a5658b75373010
  • Implement durable resumable PR publication (stacked on #119) #120 merge commit into this branch: 3e6c79e5e8726ea614df205a1735aaed10cce99c

The 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.

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.
@Protonmatter Protonmatter changed the title Specify durable PR publication and Earth recovery Add durable resumable PR publication and recovery Sep 25, 2026
@Protonmatter
Protonmatter marked this pull request as ready for review September 25, 2026 16:54
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-25T17:01:32.257018Z 3e6c79e Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +81 to +82
value = client.find_pr(head.removeprefix('refs/heads/'), base.removeprefix('refs/heads/'), args.pr, owner)
number = value['number'] if value else None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +119 to +120
except PublicationError:
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +178 to +180
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/'))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +126 to +127
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')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

This branch has not been deployed

No deployments
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