Gap
PR #1545 currently protects the scheduled organization coordinator's OIDC → short-lived OpenCode App token exchange with static workflow-source assertions. Those checks detect missing permissions, endpoint, timeout, masking, and fallback strings, but cannot execute malformed-response and shell-control-flow branches without a real GitHub job OIDC identity.
Required implementation
Extract the exchange from inline workflow shell into a trusted default-branch helper owned by .github, while keeping the workflow as the sole caller and preserving the current trust boundary.
The helper must:
- accept the job-provided OIDC request URL/token, fixed audience, and fixed OpenCode exchange base URL through explicit inputs;
- append
audience= using ? or & correctly when the GitHub request URL already has a query;
- use bounded connect and total timeouts for both requests;
- require a non-empty JSON string at
.value and .token respectively;
- emit the maintainer token only through a masked GitHub output/environment channel;
- never accept repository
GITHUB_TOKEN, reviewer credentials, model-provider keys, or COPILOT_GITHUB_TOKEN as fallback;
- redact response bodies, authorization values, URLs with sensitive query values, and tokens from errors;
- fail nonzero for missing environment, transport failure, HTTP error, malformed JSON, empty/wrong-typed fields, and truncated responses;
- remain callable only from the protected-default-branch scheduled coordinator contract.
Tests
Use a local fake HTTP server or injected transport to prove:
- OIDC request URL with no query;
- OIDC request URL with an existing query;
- connection failure and timeout on both calls;
- non-2xx responses;
- malformed, empty, wrong-typed, and oversized/truncated JSON;
- exact mask/output ordering;
- no secret value appears in stdout, stderr, exceptions, or pytest output;
- no repository-token fallback;
- workflow-to-helper argument and permission contract;
- current scheduled default-branch acceptance after merge.
Production statement and branch coverage, public docstrings, warning-free Python 3.14 execution, compileall, security scanning, and exact-head independent review remain mandatory.
Scope
This is a focused testability refactor, not a new authentication model. Preserve #1545's PR_REVIEW_MERGE_TOKEN preference, OIDC/App fallback, egress allowlist, and fail-closed runtime behavior. Update docs/doctoring/organization-commercial-readiness-loop.md, docs/product-technical-gap-baseline.md, and CHANGELOG.md.
Gap
PR #1545 currently protects the scheduled organization coordinator's OIDC → short-lived OpenCode App token exchange with static workflow-source assertions. Those checks detect missing permissions, endpoint, timeout, masking, and fallback strings, but cannot execute malformed-response and shell-control-flow branches without a real GitHub job OIDC identity.
Required implementation
Extract the exchange from inline workflow shell into a trusted default-branch helper owned by
.github, while keeping the workflow as the sole caller and preserving the current trust boundary.The helper must:
audience=using?or&correctly when the GitHub request URL already has a query;.valueand.tokenrespectively;GITHUB_TOKEN, reviewer credentials, model-provider keys, orCOPILOT_GITHUB_TOKENas fallback;Tests
Use a local fake HTTP server or injected transport to prove:
Production statement and branch coverage, public docstrings, warning-free Python 3.14 execution,
compileall, security scanning, and exact-head independent review remain mandatory.Scope
This is a focused testability refactor, not a new authentication model. Preserve #1545's
PR_REVIEW_MERGE_TOKENpreference, OIDC/App fallback, egress allowlist, and fail-closed runtime behavior. Updatedocs/doctoring/organization-commercial-readiness-loop.md,docs/product-technical-gap-baseline.md, andCHANGELOG.md.