Skip to content

fix: publish Castiron checks for external-fork pull requests - #2464

Merged
HAYDEN-OAI merged 1 commit into
mainfrom
codex/castiron-external-fork-statuses-20260825
Aug 25, 2026
Merged

fix: publish Castiron checks for external-fork pull requests#2464
HAYDEN-OAI merged 1 commit into
mainfrom
codex/castiron-external-fork-statuses-20260825

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor

Summary

GitHub omits workflow_run.pull_requests for external-fork runs, and querying the upstream repository's commit-association endpoint returns no pull requests for those fork commits. That leaves the required Castiron / budget-only change and Castiron / custom-code budget contexts permanently expected even when the candidate workflow succeeds.

  • Centralize trusted Python pull-request association in custom_code_report.py and reuse it from trusted report generation, comment publication, and budget evaluation.
  • Resolve missing associations from the authenticated source run's head_repository, including legitimately renamed forks, then independently re-fetch every candidate PR from openai/openai-node.
  • Apply equivalent validation in both privileged JavaScript publishers: required commit statuses and failure-report comments.
  • Refresh the candidate workflow's pinned reporter SHA-256 after the trusted reporter change.

Security model

Fork-side associations and PR numbers are discovery hints, never authorization. The trusted paths:

  1. Re-fetch the workflow run from the upstream Actions API and verify its repository, immutable candidate SHA, workflow path, completion, and run attempt as applicable.
  2. Strictly validate the source repository's owner/name syntax and consistency with authenticated head_repository metadata; reject traversal-like components and spoofed identities.
  3. Re-fetch each hinted PR from the upstream repository and require an open PR with the exact candidate SHA, the exact source head repository, the intended upstream repository and main base ref, and exactly one valid current association.
  4. Require the current main base SHA wherever budget evaluation or status publication needs freshness; preserve existing stale-run behavior and merge-group validation.

The existing trusted workflow_run/main-checkout boundary, bare Git object store, candidate-artifact isolation, least-privilege job permissions, merge-queue protections, and exact required status names remain unchanged. No candidate workflow definition, mutable ref, contributor artifact, or fork-supplied PR number is trusted.

Affected contributor PRs

Verification

  • env PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s scripts/castiron -p 'test_custom_code*.py' — 60 tests pass, with one pre-existing skip.
  • go run github.com/rhysd/actionlint/cmd/actionlint@latest .github/workflows/castiron-custom-code.yml .github/workflows/castiron-custom-code-comment.yml — both workflows pass actionlint v1.7.12.
  • ruff format --check scripts/castiron/custom_code_report.py scripts/castiron/custom_code_budget.py scripts/castiron/test_custom_code_report.py scripts/castiron/test_custom_code_budget.py.
  • Ruff lint passes when ignoring only the same pre-existing baseline rule findings; git diff --check passes.
  • Executable publisher and Python regression coverage includes external forks with empty run associations, fork-side lookup, same-repository and renamed-fork PRs, malformed/spoofed repositories, unrelated source heads, ambiguous/duplicate/invalid associations, stale heads/bases/run attempts, exact required contexts, and merge groups.

@HAYDEN-OAI
HAYDEN-OAI requested a review from a team as a code owner August 25, 2026 17:36
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 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-08-25T17:38:15.600893Z ee9ee16 PR opened
🔒 Security Review Completed 2026-08-25T17:39:08.032374Z ee9ee16 PR opened
ℹ️ 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.

@openai-sdks

openai-sdks Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 12.046s for Node SDK PR #2464.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 184ms
tests/chat-completions-create.test.ts ✅ Passed 243ms
tests/chat-completions-stream.test.ts ✅ Passed 255ms
tests/files-content-binary.test.ts ✅ Passed 160ms
tests/files-create-multipart.test.ts ✅ Passed 185ms
tests/files-list-pagination.test.ts ✅ Passed 202ms
tests/initialize-config.test.ts ✅ Passed 189ms
tests/instance-isolation.test.ts ✅ Passed 131ms
tests/models-list.test.ts ✅ Passed 171ms
tests/responses-background-lifecycle.test.ts ✅ Passed 260ms
tests/responses-body-method-errors.test.ts ✅ Passed 510ms
tests/responses-cancel-timeout.test.ts ✅ Passed 267ms
tests/responses-cancel.test.ts ✅ Passed 214ms
tests/responses-compact-retries.test.ts ✅ Passed 309ms
tests/responses-compact.test.ts ✅ Passed 315ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 158ms
tests/responses-create-advanced.test.ts ✅ Passed 235ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.155s
tests/responses-create-errors.test.ts ✅ Passed 278ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 167ms
tests/responses-create-retries.test.ts ✅ Passed 276ms
tests/responses-create-stream-failures.test.ts ✅ Passed 329ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.2s
tests/responses-create-stream-wire.test.ts ✅ Passed 3.032s
tests/responses-create-stream.test.ts ✅ Passed 115ms
tests/responses-create-terminal-states.test.ts ✅ Passed 279ms
tests/responses-create-timeout.test.ts ✅ Passed 269ms
tests/responses-create.test.ts ✅ Passed 297ms
tests/responses-delete.test.ts ✅ Passed 258ms
tests/responses-input-items-errors.test.ts ✅ Passed 248ms
tests/responses-input-items-list.test.ts ✅ Passed 202ms
tests/responses-input-items-options.test.ts ✅ Passed 195ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 314ms
tests/responses-input-tokens-count.test.ts ✅ Passed 282ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.633s
tests/responses-not-found-errors.test.ts ✅ Passed 383ms
tests/responses-parse.test.ts ✅ Passed 252ms
tests/responses-retrieve-retries.test.ts ✅ Passed 379ms
tests/responses-retrieve.test.ts ✅ Passed 253ms
tests/responses-stored-method-errors.test.ts ✅ Passed 648ms
tests/retry-behavior.test.ts ✅ Passed 3.131s
tests/sdk-error-shape.test.ts ✅ Passed 378ms

View OkTest run #32878844426

SDK merge (8c497a860f71) · head (ee9ee16e1715) · base (c100c832962e) · OkTest (2b1bdfd25e98)

@github-actions

Copy link
Copy Markdown
Contributor

Castiron custom code

✅ No new custom-code files detected.

32 mixed files remain; 2 existing customizations changed.

Compared ddf99223c43fee9ee16e1715. Generated baselines verified.

File Result Current custom patch
scripts/castiron/custom_code_report.py Existing customization changed +183 / −31
scripts/castiron/test_custom_code_report.py Existing customization changed +518 / −42
30 existing customizations unchanged
  • api.md
  • scripts/castiron/README.md
  • src/client.ts
  • src/resources/audio/transcriptions.ts
  • src/resources/audio/translations.ts
  • src/resources/beta/assistants.ts
  • src/resources/beta/beta.ts
  • src/resources/beta/index.ts
  • src/resources/beta/responses/internal-base.ts
  • src/resources/beta/responses/responses.ts
  • src/resources/beta/threads/index.ts
  • src/resources/beta/threads/runs/index.ts
  • src/resources/beta/threads/runs/runs.ts
  • src/resources/beta/threads/threads.ts
  • src/resources/chat/completions/completions.ts
  • src/resources/chat/completions/index.ts
  • src/resources/conversations/index.ts
  • src/resources/embeddings.ts
  • src/resources/files.ts
  • src/resources/fine-tuning/checkpoints/permissions.ts
  • src/resources/images.ts
  • src/resources/responses/internal-base.ts
  • src/resources/responses/responses.ts
  • src/resources/skills/skills.ts
  • src/resources/skills/versions/versions.ts
  • src/resources/vector-stores/file-batches.ts
  • src/resources/vector-stores/files.ts
  • src/resources/webhooks/index.ts
  • src/resources/webhooks/webhooks.ts
  • tests/lib/data-residency.test.ts

A changed generated baseline means this report cannot reliably identify which handwritten lines changed.

Inspect the custom-code diff

Download the exact patch produced by this run (requires repository access):

gh run download 32879001656 --repo openai/openai-node \
  --name castiron-custom-code-32879001656-1 --dir /tmp/castiron-custom-code-32879001656-1
git apply --stat /tmp/castiron-custom-code-32879001656-1/custom-code.patch
cat /tmp/castiron-custom-code-32879001656-1/custom-code.patch

Or reproduce it from an SDK checkout containing the vendored reporter:

git fetch --no-tags origin c100c832962ec42e7777ba506bba9b34e3520d52 ee9ee16e1715f41436bfef6f5954d353f9e9a064
python3 scripts/castiron/custom_code_report.py report \
  --base c100c832962ec42e7777ba506bba9b34e3520d52 \
  --head ee9ee16e1715f41436bfef6f5954d353f9e9a064 --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-ee9ee16e1715
cat /tmp/castiron-custom-code-ee9ee16e1715/custom-code.patch

This is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR.

Full report and patch

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the fork workflow-run association and privileged Castiron reporting paths, including independent upstream PR/head/source-repository/base validation, stale-run handling, artifact isolation, least-privilege status/comment publication, and the expanded security regression coverage. LGTM.

@apcha-oai apcha-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[sdk codex review] Approving ee9ee16e1715f41436bfef6f5954d353f9e9a064 after two independent full reviews of all six changed files and their reporting/publication contracts. No substantiated blocking issue found.

Fork-side associations remain discovery hints: the resolver and both privileged publishers re-fetch upstream PRs and validate source repository, exact head, open state, intended base and a single current association. Trusted computation/artifact boundaries, least-privilege permissions, stale-run handling and merge-group checks remain intact. The new regressions exercise the actual embedded publisher JavaScript; no duplicate review comments are needed.

Primary Castiron CI checked out this exact head, verified the reporter checksum, and ran 60 focused tests successfully with one skip. Node CI passed the Node 22/24/26 test matrix at the head, plus lint/type checks. OkTest passed 237 tests across 42 suites on merge 8c497a860f716e4e7111d64fcc711ca1b66b0a2f (head + base c100c832). Subsequent observed main changes affect only pnpm-lock.yaml, with no overlap with these workflow/Python paths; these results are not execution against that newer main.

Head, PR base, live base, author, open/non-draft status and mergeability rechecked before submission. Validation used source review, existing hosted logs and read-only GitHub API observations—not new scans, candidate execution or a deployed privileged fork-publisher test.

@HAYDEN-OAI
HAYDEN-OAI added this pull request to the merge queue Aug 25, 2026
Merged via the queue into main with commit a90581e Aug 25, 2026
35 checks passed
@HAYDEN-OAI
HAYDEN-OAI deleted the codex/castiron-external-fork-statuses-20260825 branch August 25, 2026 18:06
@openai-sdks openai-sdks Bot mentioned this pull request Aug 25, 2026
euntaek-hong pushed a commit to wrongbutworks/openai-node that referenced this pull request Aug 26, 2026
Automated Release PR
---


##
[7.6.0](openai/openai-node@v7.5.0...v7.6.0)
(2026-08-26)


### Features

* **api:** Add obfuscation field to ChatCompletionChunk
([openai#2423](openai#2423))
([39afa3a](openai@39afa3a))
* **api:** Add project residency and usage quantity_unit fields
([openai#2461](openai#2461))
([26d8158](openai@26d8158))
* **api:** support backend-mediated Realtime WebRTC calls
([openai#2469](openai#2469))
([0d12ca8](openai@0d12ca8))
* **auth:** add pinned X.509 workload token exchange
([openai#2470](openai#2470))
([9dd8648](openai@9dd8648))
* **auth:** attest cross-module X.509 transport capabilities
([openai#2471](openai#2471))
([c6769fa](openai@c6769fa))
* **auth:** harden X.509 token lifecycle and tenant isolation
([openai#2473](openai#2473))
([6992683](openai@6992683))
* **auth:** integrate attested X.509 workload identity into clients
([openai#2472](openai#2472))
([ee5229b](openai@ee5229b))
* support named data-residency endpoints
([openai#2393](openai#2393))
([62d98dd](openai@62d98dd))


### Bug Fixes

* [responses] Avoid quadratic comparisons when accumulating long text
([openai#2434](openai#2434))
([95628ce](openai@95628ce))
* **assistants:** reject run-step identity hijacking before tool
callbacks ([openai#2476](openai#2476))
([63b1c75](openai@63b1c75))
* **audio:** preserve recording outcomes during cancellation and cleanup
([openai#2482](openai#2482))
([dafcac4](openai@dafcac4))
* **auth:** honor an explicit zero GCP metadata timeout
([openai#2481](openai#2481))
([7a9dec8](openai@7a9dec8))
* **auth:** sanitize malformed Azure IMDS token responses
([openai#2427](openai#2427))
([bbfb792](openai@bbfb792))
* **auth:** sanitize malformed workload OAuth token responses
([openai#2468](openai#2468))
([cd5b2d8](openai@cd5b2d8))
* avoid double-counting logprobs in streamed chat completions
([openai#2444](openai#2444))
([ddf9922](openai@ddf9922))
* **bedrock:** honor cancellation during bearer credential resolution
([openai#2478](openai#2478))
([2dac2f4](openai@2dac2f4))
* drain tee stream queues in linear time
([openai#2379](openai#2379))
([1f3ce07](openai@1f3ce07))
* **polling:** honor cancellation during polling delays
([openai#2477](openai#2477))
([520d604](openai@520d604))
* preserve large streaming responses
([openai#2433](openai#2433))
([4e588c2](openai@4e588c2))
* preserve multipart upload array order
([openai#2380](openai#2380))
([f1a2b61](openai@f1a2b61))
* publish Castiron checks for behind-main pull requests
([openai#2486](openai#2486))
([662bb37](openai@662bb37))
* publish Castiron checks for external-fork pull requests
([openai#2464](openai#2464))
([a90581e](openai@a90581e))
* **security:** abort streaming examples when clients disconnect
([openai#2426](openai#2426))
([b32a25b](openai@b32a25b))
* **security:** authenticate Cloudflare tests and restrict streaming
proxies ([openai#2413](openai#2413))
([9286fdb](openai@9286fdb))
* **security:** authenticate Vercel ecosystem APIs and clean up uploaded
files ([openai#2412](openai#2412))
([d58608a](openai@d58608a))
* **security:** bound SDK event streams and validate streamed item
identities ([openai#2415](openai#2415))
([7df29a9](openai@7df29a9))
* **security:** bound SSE frames and NDJSON lines before buffering
([openai#2411](openai#2411))
([0e250a4](openai@0e250a4))
* **security:** close rejected Azure managed-identity response streams
([openai#2416](openai#2416))
([387bbc8](openai@387bbc8))
* **security:** harden Bedrock regions, query merges, and upload errors
([openai#2410](openai#2410))
([ce45d0d](openai@ce45d0d))
* **security:** harden Realtime WebSocket origins, worker guards, and
Azure credentials
([openai#2414](openai#2414))
([5533f73](openai@5533f73))
* **security:** preserve chat structured response-format integrity
([openai#2402](openai#2402))
([e69df93](openai@e69df93))
* **security:** prevent AssistantStream deltas leaking sensitive data
([openai#2392](openai#2392))
([17cf54c](openai@17cf54c))
* **security:** prevent streaming upload filename path disclosure
([openai#2386](openai#2386))
([c88a024](openai@c88a024))
* **security:** prevent structured-output format downgrade
([openai#2394](openai#2394))
([dd945e6](openai@dd945e6))
* **security:** redact built-in structured JSON parse errors
([openai#2418](openai#2418))
([a0d68cc](openai@a0d68cc))
* **security:** redact chat completion finalization snapshots
([openai#2400](openai#2400))
([fb5d8e7](openai@fb5d8e7))
* **security:** redact GCP metadata authentication error bodies
([openai#2399](openai#2399))
([322840c](openai@322840c))
* **security:** redact invalid Bedrock bearer credentials
([openai#2419](openai#2419))
([39c06d1](openai@39c06d1))
* **security:** redact invalid workload identity access tokens
([openai#2425](openai#2425))
([0d28da3](openai@0d28da3))
* **security:** redact malformed NDJSON stream diagnostics
([openai#2420](openai#2420))
([dcc705c](openai@dcc705c))
* **security:** redact malformed Realtime WebSocket error causes
([openai#2408](openai#2408))
([e7a1a44](openai@e7a1a44))
* **security:** redact malformed SSE diagnostic payloads
([openai#2403](openai#2403))
([272a2cc](openai@272a2cc))
* **security:** redact sensitive assistant delta diagnostics
([openai#2406](openai#2406))
([b130b83](openai@b130b83))
* **security:** redact unsupported Responses stream event payloads
([openai#2395](openai#2395))
([32b2953](openai@32b2953))
* **security:** reject malformed Realtime WebSocket event frames
([openai#2391](openai#2391))
([e6e11b0](openai@e6e11b0))
* **security:** require an exact SSE completion sentinel
([openai#2422](openai#2422))
([a905bfb](openai@a905bfb))
* **security:** require OIDC for npm publishing
([openai#2404](openai#2404))
([342764b](openai@342764b))
* **security:** respect configured logger for Assistants stream errors
([openai#2390](openai#2390))
([8ba3009](openai@8ba3009))
* **security:** restrict live CI credentials to protected main
([openai#2405](openai#2405))
([3554cdc](openai@3554cdc))
* **security:** scope Cloudflare ecosystem API key files
([openai#2398](openai#2398))
([4f4b45d](openai@4f4b45d))
* **security:** secure Next.js Edge streaming example requests
([openai#2424](openai#2424))
([861caed](openai@861caed))
* **security:** stop delayed and additional tool callbacks after
cancellation
([openai#2430](openai#2430))
([c168599](openai@c168599))
* **security:** stop retaining sensitive assistant stream events
([openai#2407](openai#2407))
([dfec129](openai@dfec129))
* settle concurrent stream event waiters in linear time
([openai#2387](openai#2387))
([a88c2ca](openai@a88c2ca))
* settle WebSocket event waiters in linear time
([openai#2389](openai#2389))
([489dc72](openai@489dc72))
* **standard-schema:** preserve validator bindings across helpers
([openai#2483](openai#2483))
([e4afdb7](openai@e4afdb7))
* **streaming:** reject named SSE provider error events
([openai#2409](openai#2409))
([b7a0bd6](openai@b7a0bd6))
* **tests:** make credential-lifecycle held-inode scenarios portable to
macOS ([openai#2480](openai#2480))
([60f5267](openai@60f5267))
* **uploads:** preserve Blob files and multipart media types
([openai#2467](openai#2467))
([d497fb3](openai@d497fb3))
* **webhooks:** bound signature verification work
([openai#2475](openai#2475))
([05cf7ab](openai@05cf7ab))
* **ws:** block custom credential headers on redirects
([openai#2429](openai#2429))
([d2ab6e7](openai@d2ab6e7))
* **zod:** support only provably JSON-native structured outputs
([openai#2396](openai#2396))
([c3d68e4](openai@c3d68e4))


### Chores

* **api:** clarify image transparency and audio delta docs
([openai#2439](openai#2439))
([f14e885](openai@f14e885))
* **api:** document supported image generation models
([openai#2432](openai#2432))
([0e00909](openai@0e00909))
* **api:** update SDK generation metadata
([openai#2448](openai#2448))
([d1410d1](openai@d1410d1))
* **deps-dev:** bump @cloudflare/workers-types from 5.20260809.1 to
5.20260816.1 in /ecosystem-tests/cloudflare-worker
([openai#2452](openai#2452))
([cf7e588](openai@cf7e588))
* **deps-dev:** bump @smithy/hash-node from 4.4.16 to 4.5.2
([openai#2455](openai#2455))
([342b0a3](openai@342b0a3))
* **deps-dev:** bump @smithy/signature-v4 from 5.6.12 to 5.7.2
([openai#2459](openai#2459))
([bf4386c](openai@bf4386c))
* **deps-dev:** bump publint from 0.3.22 to 0.3.23
([openai#2457](openai#2457))
([c100c83](openai@c100c83))
* **deps-dev:** bump puppeteer from 25.5.0 to 25.7.0 in
/ecosystem-tests/browser-direct-import
([openai#2451](openai#2451))
([c6c406b](openai@c6c406b))
* **deps-dev:** bump puppeteer from 25.5.0 to 25.7.0 in
/ecosystem-tests/ts-browser-webpack
([openai#2456](openai#2456))
([e1faab1](openai@e1faab1))
* **deps-dev:** bump ws from 8.21.1 to 8.21.3
([openai#2454](openai#2454))
([1f84889](openai@1f84889))
* **deps:** bump next from 15.5.21 to 15.5.23 in
/ecosystem-tests/vercel-edge
([openai#2458](openai#2458))
([cc532b3](openai@cc532b3))
* **deps:** bump next from 16.3.0 to 16.3.1
([openai#2460](openai#2460))
([a2d88c1](openai@a2d88c1))
* set a 3,000-line custom-code budget
([openai#2446](openai#2446))
([2035847](openai@2035847))


### Documentation

* encode recurring SDK review feedback in agent guidance
([openai#2378](openai#2378))
([e552523](openai@e552523))
* **security:** add secure contributor and agent guidance
([openai#2382](openai#2382))
([459d009](openai@459d009))


### Refactors

* move embedding encoding into an SDK-owned helper
([openai#2436](openai#2436))
([db9e930](openai@db9e930))
* move file processing wait into an SDK-owned helper
([openai#2438](openai#2438))
([3d39e64](openai@3d39e64))
* move vector store batch uploads into an SDK-owned helper
([openai#2441](openai#2441))
([0257e51](openai@0257e51))
* move vector store polling into an SDK-owned helper
([openai#2437](openai#2437))
([4317319](openai@4317319))
* move webhook signature checks into an SDK-owned helper
([openai#2442](openai#2442))
([283e12b](openai@283e12b))
* share SDK-owned assistant run polling
([openai#2440](openai#2440))
([4de295b](openai@4de295b))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: openai-sdks[bot] <284451331+openai-sdks[bot]@users.noreply.github.com>
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.

3 participants