Skip to content

Trust maintainer-signed PR heads - #243

Merged
kixelated merged 14 commits into
mainfrom
quest/m0/kix/sandbox/trust
Oct 28, 2026
Merged

kixelated merged 14 commits into
mainfrom
quest/m0/kix/sandbox/trust

Conversation

@kixelated

@kixelated kixelated commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

PR iteration and merge jobs currently treat every head as untrusted, so even maintainers wait for a Linux VM runner. This trusts a PR head only when every commit beyond the repository's default branch has a valid GitHub signature from a current maintain/admin collaborator. Trust is checked when the job is created and rechecked before assignment and redelivery; unsigned, contributor, kix-pushed, moved, incomplete, and unverifiable heads fail closed. Untrusted jobs keep Linux VM routing and the existing runner refusal until VM support ships.

The check compares the default branch against the exact PR head, independently of the PR's chosen base, so retargeting the base cannot hide an unsigned ancestor. It checks the default branch's name/tip, comparison endpoints, live PR head, complete commit count, and pagination cursors on every page. Non-default-base PRs remain supported when their full ancestry beyond the default branch is signed.

Completes the trusted PR heads quest (quest/m0/kix/sandbox/trust.md deleted, links removed). No D1 migration.

Decisions

From the maintainer's 2026-10-28 /quest-plan trust audit, which supersedes the quest's "kix job pushed it" rule:

  • ✅ Maintainer signature only. The kix publication ledger is dropped (job_commits, migration 0020, the writes in store.ts, the pending-publication recovery in jobs/trust.ts): a compromised runner can publish any flake.nix, so publication is no execution trust. A head kix pushed to stays VM-only, as every PR head is on main today. Resolves the Codex Security P1 thread.
  • Explicit "approve this exact SHA" for host trust is a separate follow-up quest (quest/m0/kix/sandbox/head-approval.md), planned in its own PR and not built here.
  • The maintainer will enable SSH commit signing; until then this PR's own commits, and every unsigned head, stay untrusted.

Choices made while iterating

  • Assignment verifies the job's recorded head as-is, with no publication recovery. A publish whose response was lost leaves a stale recorded head, which fails the live-head check and stays untrusted; the existing publish.ts adoption still reconciles it once the job runs on a VM runner. store.dispatch takes a boolean Verify, and publish.ts is back to main's shape.
  • The dispatch fences (head IS ?, trusted=?) on claim and redelivery are kept, so a head or trust change between the check and the claim cannot slip through.
  • merge wait webhook wakeups (from main) now uses a Linux VM runner and stubs GitHub, since the hub rechecks its merge job's trust and the test has no signatures.
  • The root README tells maintainers to sign their commits (e.g. SSH signing) for iterate/merge jobs to run off-VM.

Validation

just check and just test pass on 8a3bce2 (588 CLI tests, 2 skipped; 411 Worker tests). Regression coverage: maintainer-signed heads routing to macOS, signed merges with an unsigned parent, retargeted bases hiding unsigned ancestors, valid non-default-base PRs, default-inherited revisions, unsigned/forged/invalid signatures, role revocation at creation and redelivery, queued head changes, comparison pagination and drift, and a kix-published head after a lost response routing only to a Linux VM runner.

Follow-ups

  • Approving an exact SHA for host trust: being planned in its own PR (head-approval.md).
  • The Worker tests print TLS errors from unmocked real GitHub fetches. They persist with the trust check stubbed out, so they come from elsewhere; no test fails, but those tests should stub the network.

(written by GPT-6; revised by Claude Opus 5.5)

@kixelated kixelated changed the title Run maintainers' PR heads on any runner Trust authenticated maintainer and kix PR commits Oct 28, 2026
@kixelated
kixelated marked this pull request as ready for review October 28, 2026 04:37
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 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-10-28T18:40:09.307565Z 08feed7 New commits
🔒 Security Review ✅ Completed 2026-10-28T18:42:35.653384Z 08feed7 New commits

Security findings

Advisory findings (2)

ℹ️ 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.

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 59b86a2

No actionable bugs found in the changed areas and relevant surrounding code.

Direction: authenticating signatures against current maintainer IDs/roles, rather than author email, is the right boundary. The repository-scoped publication ledger and transactional recording are justified: an initial job head or an unconfirmed push must not confer trust. Complete commit pagination and fail-closed assignment/redelivery checks preserve that policy without weakening untrusted-runner routing.

Verification: static inspection of the classifier, publication/recovery paths, dispatch fencing, migration, and regression tests. I did not run tests, apply the migration, or exercise live GitHub signature responses or runner execution.

@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 Security Review · Automatically triggered

Here are some automated security review suggestions for this pull request.

Reviewed commit: 59b86a2bcf

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread cloudflare/src/github/service.ts Resolved
@kixelated

Copy link
Copy Markdown
Collaborator Author

Design change: authenticate commits from a comparison of the repository's trusted default branch to the exact PR head, rather than the PR's commit list. A PR author can retarget its base and hide an unsigned ancestor from that list. The comparison remains independent of the PR base and checks the default branch's name/tip, comparison endpoints, PR head, complete count, and pagination cursors. Non-default-base PRs remain supported when every commit beyond the trusted default branch is authenticated.

(written by GPT-6)

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 4a61f5a
Compared with my previous review at 59b86a2; the base is unchanged.

Fixed: the independently reported retargeted-base trust bypass, which my earlier review missed. cloudflare/src/github/service.ts:787–828 now compares the exact head against the repository default branch, so changing the PR base cannot exclude an unsigned ancestor. The new retargeting and pagination-drift regressions cover the intended boundary.

No new actionable bugs found in this delta. Direction: this comparison is preferable to rejecting all non-default-base PRs; endpoint/name/tip checks and complete pagination are justified security safeguards.

Verification: static inspection of the changed classifier, fixtures, and tests. I did not run tests or independently exercise the live GitHub comparison API.

@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: 4a61f5ae34

ℹ️ 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 thread cloudflare/src/jobs/hub.ts Resolved

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 495c782
Compared with 4a61f5a; base unchanged.

Fixed: the independent pending-publication reassignment finding. Assignment now recovers a confirmed reserved commit through the shared publication-head check before classifying the effective head, and dispatch fences its claim against that head. The landed/unconfirmed/unrelated-head regression cases exercise the relevant distinctions. The previous default-branch trust fix remains intact.

No new actionable bugs found in this delta. Direction: reusing publication recovery is simpler and safer than a second provenance mechanism; the small verifier module and head-bearing result are justified.

Verification: static inspection of the delta and surrounding authorization, adoption, and assignment paths. I did not run tests or reproduce a lost GitHub response against a live runner.

@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 Security Review · Automatically triggered

Here are some automated security review suggestions for this pull request.

Reviewed commit: 495c782b69

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread cloudflare/src/github/service.ts Resolved
@kixelated
kixelated marked this pull request as draft October 28, 2026 05:12
@kixelated
kixelated marked this pull request as ready for review October 28, 2026 05:15
@kixelated
kixelated marked this pull request as draft October 28, 2026 16:41
@kixelated

Copy link
Copy Markdown
Collaborator Author

Maintainer decision (2026-10-28, via /quest-complete): hold this PR. The question of what counts as a trusted head (maintainer signatures, kix-published commits, or explicit approval of a SHA) is folded into a /quest-plan lifecycle and trust-boundary audit, together with #246. Don't iterate or merge until that audit settles it.

(written by Claude Opus 5.5)

Drop the kix publication ledger (job_commits, migration 0020, its writes
on settle/adopt, and pending-publication recovery before assignment). A
compromised runner can publish any flake.nix, so a confirmed publication
is no execution trust. A head is trusted only when every commit beyond
the default branch has a valid signature from a current maintain/admin
collaborator, rechecked at creation and assignment; heads kix pushed to
stay VM-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

Design change: host trust comes from maintainer signatures only. Per the maintainer's 2026-10-28 trust audit, the kix publication ledger is dropped (job_commits, migration 0020, the writes in store.ts, and the pending-publication recovery in jobs/trust.ts), because a compromised runner can publish any flake.nix. A PR head is trusted only when every commit beyond the repository's default branch has a valid signature from a current maintain/admin collaborator, rechecked at creation and assignment. Unsigned heads and heads kix pushed to stay VM-only, as every PR head is on main today. Assignment now verifies the recorded head as-is; a lost publish response leaves a stale head that fails the live-head check and stays untrusted, so no recovery is needed before routing. Approving an exact SHA for host trust is a separate follow-up quest, not built here. The PR no longer needs a D1 migration.

(written by Claude Opus 5.5)

@kixelated kixelated changed the title Trust authenticated maintainer and kix PR commits Trust maintainer-signed PR heads Oct 28, 2026
@kixelated
kixelated marked this pull request as ready for review October 28, 2026 17:14

@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: 8a3bce2b25

ℹ️ 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 thread cloudflare/src/github/service.ts Resolved

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 8a3bce2

No new actionable bugs found in the substantive update since 495c782, accounting for merged base changes. The independent runner-publication trust finding is addressed: publication no longer bypasses signature checks, and the ledger/migration are removed. The default-branch ancestry check and assignment/redelivery head fences remain intact.

Direction: maintainer signatures are a clearer and simpler execution-trust boundary than publication provenance. The earlier pending-publication recovery fix is intentionally superseded: a lost-response head now fails closed and routes VM-only rather than recovering host trust. That means such jobs cannot resume on ordinary runners while VM execution remains unavailable; the new regression verifies routing, not VM execution.

Verification limits: static inspection of the changed classifier, dispatch, publication/adoption paths, and regression tests. I did not run tests or verify live GitHub signature/comparison responses or runner execution.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary for 4931322:

  • Codex reviewed 8a3bce2 (the signatures-only head from the 2026-10-28 Design change:). Its one finding, that Ref.compare(headRef:) cannot take a commit SHA, is a false positive: the live API returns headTarget.oid equal to the exact SHA (reply). No code change.
  • Merged origin/main (d2aac13, conflict-free, only assets/skills/complete.md) into the branch, so the 8a3bce2 review still covers the code.
  • Required check passed on 4931322. The optional native Windows (windows-11-arm) job failed in a quest gate admissions concurrency test (admissions length 2, expected 4). This PR doesn't touch that code, and the same job passed on 8a3bce2, so it looks like a flake.
  • quest check --base origin/main --branch quest/m0/kix/sandbox/trust passes: the PR deletes trust.md and its links.
  • Head approval stays a separate planned quest (kixelated/quest#264), which is still open.

(written by Claude Opus 5.5)

kixelated and others added 3 commits October 28, 2026 10:38
Drop the finished trust quest's links from head-approval.md and the sandbox epic, which #264 added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@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: 005e225f97

ℹ️ 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 thread cloudflare/src/jobs/store.ts Resolved
kixelated and others added 2 commits October 28, 2026 11:19
A lost publication can settle between a claim and the assignment read, moving the head with no attempt fence. Key the claim's verification to its attempt and head, and verify any other head again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 107d2c5

Fixed: the independent cached-trust head/attempt race, which my earlier review missed. cloudflare/src/jobs/store.ts now caches the exact head and resulting attempt only after a successful claim, then rechecks a different assignment snapshot before delivery. The regression settles an untrusted publication between claim and assignment and asserts cancellation/requeue rather than macOS delivery.

No new actionable bugs found in this substantive delta, accounting for base merges. Binding the existing cache to its verified snapshot is a small, justified fix and simpler than another trust mechanism; the existing SQL head/attempt fences still protect the recheck.

Verification limits: static inspection of the dispatch change, surrounding claim/redelivery logic, and regression test. I did not run tests or reproduce the race against live D1/GitHub/runners.

@kixelated

Copy link
Copy Markdown
Collaborator Author

Landing summary for 08feed7:

  • Codex's Ref.compare finding on 8a3bce2 was a false positive, confirmed against the live API. No change.
  • Codex's cached-trust race finding on 005e225 was real. It's fixed in 4db733e: dispatch now keys a claim's verification to its attempt and head, and verifies again if a settled publication moved the head before delivery. A regression test in trust.test.ts fails without the fix. Codex 👍'd 107d2c5 and 08feed7, and the automated review found nothing new.
  • Main is merged up to e564fc5. When kixelated/quest#264 landed, I removed head-approval.md's Required link to trust.md and the sandbox epic's trust.md entry, and repointed head-approval's prose link at this PR.
  • All checks pass on 08feed7, and quest check --base origin/main passes. The optional Windows ARM job failed twice on earlier heads in gate.test.ts > concurrent processes never admit past the headroom, which this PR doesn't touch. That looks like a flake; I'm suggesting it as a follow-up.

(written by Claude Opus 5.5)

@kixelated
kixelated merged commit 50a4d02 into main Oct 28, 2026
4 checks passed
@kixelated
kixelated deleted the quest/m0/kix/sandbox/trust branch October 28, 2026 18:43
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