Skip to content

fix(scheduler): canonicalize repository dispatch identity - #1984

Draft
seonghobae wants to merge 2 commits into
mainfrom
codex/canonicalize-repository-dispatch-identity
Draft

fix(scheduler): canonicalize repository dispatch identity#1984
seonghobae wants to merge 2 commits into
mainfrom
codex/canonicalize-repository-dispatch-identity

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

BLOCKED — fresh runtime evidence invalidates this PR's single-principal premise. Run 33998627665 proves the merge-scheduler's github-actions[bot] sender is legitimate and terminal-green, while App-token required-workflow dispatches arrive as opencode-agent[bot] and are rejected by the unchanged single-value setting. The P0 minimal repair is the already-supported exact two-principal allowlist, retaining actor=sender equality. This Draft must not merge unless a separate reviewed security requirement justifies retiring the proven scheduler principal after settings convergence.

Problem

The trusted OpenCode producer already creates central repository_dispatch events with the OIDC-exchanged OpenCode App token (opencode-agent[bot]), while the PR review scheduler creates the same OpenCode/Strix events with github.token (github-actions[bot]). Current receiver-side actor=sender enforcement is correct; the producer identity drift is not. Broadening the live allowlist to two principals would keep two mutable transport identities for one operation.

Refs #1927. This is separate from dependency-review #810 and workflow materialization #712.

Change

  • add a dedicated SCHEDULER_REPOSITORY_DISPATCH_TOKEN bound only to steps.scheduler_app_token.outputs.token;
  • send OpenCode and Strix repository-dispatch POSTs only through that credential;
  • fail closed when the OIDC/App exchange is unavailable, with no runner-token, ambient-token, PAT, or mutation-token fallback;
  • retain SCHEDULER_DISPATCH_TOKEN only for central Actions artifact reads/control;
  • preserve receiver actor=sender equality, target allowlisting, exact-head revalidation, admission budgets, and all merge/security gates;
  • update CHANGELOG, doctoring, and product-technical gap evidence.

TDD evidence

RED on protected main@49eb9e7035a6994fffb5b24bf943156be27a02fb:

  • 6 focused failures: missing workflow App-token wiring, missing fail-closed App boundary, App token not recognized for central dispatch, and both actual dispatch paths still wired to the runner-token function.

GREEN on exact head 0212917f3ee00deb9feacc64b9126590af242cfd, exact tree d7b92693bf9d7678d110313db57e01aed987acc0:

  • focused scheduler/queue contracts: 400 passed;

  • full Python suite: 2971 passed, 1 skipped, 21 subtests passed;

  • Python compile and git diff --check: PASS.

  • full Strix shell harness: test_strix_quick_gate: PASS.

The exact-tree full Strix shell harness also reports test_strix_quick_gate: PASS. Hosted checks/review are not yet complete, so this PR remains Draft.

Ownership / merge order

#1238 currently changes the same scheduler workflow for independent flag-coercion semantics. This branch was built from the same live main and does not alter that delta, but whichever PR lands second must ordinarily adopt the first without force-push or semantic loss. Do not merge this PR until that overlap and all exact-head gates are resolved.

Post-merge acceptance

Source merge alone does not close #1927. An authorized settings owner must set the live allowlist to the single canonical opencode-agent[bot] principal after protected-source convergence, then unchanged consumer exact heads must produce terminal central verdicts and callbacks. This PR does not mutate settings, secrets, consumer refs, or rulesets.

Use the OIDC-exchanged OpenCode App token exclusively for OpenCode and Strix repository_dispatch POSTs. Keep central Actions reads and PR mutation credentials separate, and fail closed without the scoped App credential.

Refs #1927.
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

Exact-head local execution receipt for 71bda03067ad94e90db53ad3274e43dc4b242eed / tree 7b81c66cb1a97f27fd89e894e238e015c867648c:

  • realistic RED: 6 focused failures on protected main@49eb9e7035a6994fffb5b24bf943156be27a02fb
  • focused scheduler/queue contracts: 399 passed
  • full suite under coverage: 2970 passed, 1 skipped, 21 subtests passed
  • coverage: 13205 statements / 5342 branches, 0 missed, 100%
  • full Strix shell harness: PASS
  • Python compile and git diff --check: PASS
  • remote compare: ahead 1, behind 0, merge-base exactly protected main

This is source-level GREEN only. Hosted checks are queued, exact-head approvals are 0, #1238 has an independent same-file delta, and live allowlist/settings convergence plus unchanged-consumer terminal callbacks remain required. Draft retained; no merge/rerun/settings/bypass action taken.

Copy link
Copy Markdown
Contributor Author

SOURCE WRITER RECLAIM — protected main advanced to 5c60b5d9e8fb8461480d6a30b0b5f149753afb12 via #1980 after this Draft was published. I am ordinarily adopting its 26-line tests/test_required_workflow_queue_contract.py cancel-value contract, preserving this PR's transport-identity delta, then rerunning exact-tree focused/full verification. No force-push or source-neutral commit.

Ordinarily adopt #1980's cancel-in-progress value contract without changing the canonical repository-dispatch identity repair.

Copy link
Copy Markdown
Contributor Author

P0 BLOCKER / PREMISE CORRECTION — fresh Actions evidence in #1927 shows opencode-review-dispatch run 33998627665 completed all four jobs successfully as actor=sender=github-actions[bot], while App-token required-workflow dispatches arrive as actor=sender=opencode-agent[bot] and fail only because the live setting still contains github-actions[bot]. This disproves this Draft's single-principal migration as the smallest P0 repair. The receiver already safely parses a comma-separated allowlist and keeps same-identity enforcement; the authorized settings owner should configure exactly the two intended principals. #1984 remains Draft/quarantined and must not merge on its current premise. Its current-head tests are source integrity evidence only, not acceptance of this design. No ref, setting, consumer, or gate was changed by this correction.

Copy link
Copy Markdown
Contributor Author

SOURCE WRITER RELEASE — current exact head 0212917f3ee00deb9feacc64b9126590af242cfd ordinarily adopts protected main@5c60b5d9e8fb8461480d6a30b0b5f149753afb12 with parents 71bda03067ad94e90db53ad3274e43dc4b242eed and 5c60b5d9e8fb8461480d6a30b0b5f149753afb12; exact tree d7b92693bf9d7678d110313db57e01aed987acc0. Exact-tree checks: scheduler/queue 400 passed; full Python 2971 passed, 1 skipped, 21 subtests; 100% coverage; full test_strix_quick_gate.sh PASS; diff clean.

Design status remains BLOCKED/Draft: direct run 33998627665 proves github-actions[bot] is a legitimate terminal-green scheduler principal, so the current single-App-principal premise is not the P0 minimum. The settings repair is the exact two-principal allowlist with actor=sender equality. These tests do not authorize merging #1984. No live variable, rule, consumer ref, or gate changed.

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.

vars.OPENCODE_REPOSITORY_DISPATCH_ACTOR is stale: every dispatch is rejected since 2026-08-31

1 participant