Skip to content

feat: require Python 3.10 and automate version reviews - #3537

Merged
jbeckwith-oai merged 12 commits into
mainfrom
codex/python-3-10-version-policy
Jul 24, 2026
Merged

jbeckwith-oai merged 12 commits into
mainfrom
codex/python-3-10-version-policy

Conversation

@jbeckwith-oai

Copy link
Copy Markdown
Contributor

Summary

  • raise the minimum supported runtime from Python 3.9 to Python 3.10
  • codify the SDK's Python-version and SemVer policy
  • test the minimum/current runtimes on normal CI and the full supported matrix on a schedule
  • add a monthly, least-privilege Codex assessment that opens or refreshes an advisory issue when lifecycle, usage, or repository drift needs maintainer action
  • validate built metadata and prove that pip on Python 3.9 rejects the new wheel

Why

Python 3.9 reached upstream end of life, while Python 3.10 remains supported through October 2026. Internal usage analysis estimates Python 3.9 at 2.09% of identifiable SDK downloads over 30 days and 2.44% over 90 days. The support policy, decision rationale, and rollout analysis are documented in the Python SDK version support PRD.

The automation follows the existing openai-go design: lifecycle and public usage inputs are snapshotted before Codex runs; the pinned agent runs as an unprivileged user with no command network access or repository writes; and a separate job without the OpenAI credential may publish an advisory issue. It never changes Requires-Python automatically.

User impact

Python 3.9 users remain on openai==2.48.0, the final compatible release. Installing the next minor release on Python 3.9 is rejected by standard package metadata rather than producing an import-time failure. Python 3.10 through 3.14 remain supported, with Python 3.15 tested as allowed-failure prerelease coverage.

A runtime-floor increase is treated as an SDK minor release rather than a patch or major release when documented APIs remain compatible on supported runtimes and Requires-Python protects unsupported installers.

Validation

  • rye build
  • ./scripts/lint
  • ./scripts/test: 7,079 passed, 29 skipped
  • Pydantic v1 session: 7,065 passed, 43 skipped
  • wheel and sdist Requires-Python validation
  • pip rejection using an actual Python 3.9 interpreter
  • Bedrock and HTTPX2 dependency/resolver validation
  • deterministic policy, lockfile, workflow YAML, and diff checks

Release note

The OpenAI Python SDK now requires Python 3.10 or later. openai==2.48.0 is the final release installable on Python 3.9. Previously published versions remain available, but unsupported runtimes and older SDK releases do not receive guaranteed fixes or security backports.

Copilot AI review requested due to automatic review settings July 23, 2026 21:39

Copilot AI 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.

Pull request overview

This PR raises the SDK’s minimum supported Python runtime to 3.10 and adds policy + automation to keep Python-version support, metadata, documentation, and CI coverage synchronized over time.

Changes:

  • Bump Requires-Python/classifiers/tooling targets to Python 3.10+ and remove now-redundant Python-version dependency markers.
  • Add deterministic policy checks and wheel/SDist metadata validation (including verifying Python 3.9 rejects the new wheel).
  • Expand CI to test min/current runtimes per PR, run a scheduled full-matrix smoke suite, and add a monthly least-privilege Codex-based version review workflow.

Reviewed changes

Copilot reviewed 17 out of 20 changed files in this pull request and generated no comments.

Show a summary per file
File Description
uv.lock Updates lock resolution and markers for the new minimum Python (3.10+).
tests/lib/test_bedrock_auth_conformance.py Uses zip(..., strict=True) now that Python 3.10+ is required.
scripts/utils/validate-python-version-wheel.py New script to validate Requires-Python in built artifacts and prove Python 3.9 rejects the wheel.
scripts/utils/validate-httpx2-wheel.py Updates metadata assertions and runtime behaviors now that Python 3.10+ is the floor.
scripts/utils/validate-bedrock-wheel.py Updates Bedrock extra validation for the unified supported Botocore requirement.
scripts/check-python-version-policy.py New deterministic check ensuring docs/metadata/CI/tooling agree on Python support policy.
requirements.lock Regenerated Rye lock output for the updated dependency surface.
requirements-dev.lock Regenerated dev lock output for the updated dependency surface.
README.md Updates stated minimum Python version and documents SemVer treatment for floor raises.
PYTHON_VERSION_POLICY.md New policy doc describing support windows, testing expectations, and release treatment.
pyproject.toml Raises requires-python, removes 3.9 classifier, and removes redundant Python markers on extras.
examples/realtime/push_to_talk_app.py Updates inline script metadata to require Python 3.10+.
CONTRIBUTING.md Links to the new Python version policy and documents floor-change requirements.
AGENTS.md Adds repository guidance and a consolidated checklist for Python floor changes.
.python-version Pins the contributor toolchain to Python 3.10.x.
.github/workflows/python-version-review.yml New monthly workflow that snapshots lifecycle/usage data and runs a least-privilege Codex assessment.
.github/workflows/ci.yml Adds per-PR min/current testing, scheduled compatibility smoke matrix, and metadata/rejection validations.
.github/codex/python-version-review-config.toml New least-privilege Codex permission profile for the scheduled review.
.github/codex/prompts/python-version-review.md New Codex prompt defining policy criteria and required output format.
.github/CODEOWNERS Requires SDK team review for Python floor/policy and related automation files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings July 23, 2026 21:44

Copilot AI 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.

Pull request overview

Copilot reviewed 17 out of 20 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/ci.yml
Copilot AI review requested due to automatic review settings July 23, 2026 21:50

Copilot AI 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.

Pull request overview

Copilot reviewed 17 out of 20 changed files in this pull request and generated 3 comments.

Comment thread scripts/utils/validate-python-version-wheel.py
Comment thread scripts/utils/validate-python-version-wheel.py
Comment thread PYTHON_VERSION_POLICY.md Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 22:00

Copilot AI 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.

Pull request overview

Copilot reviewed 17 out of 20 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/python-version-review.yml Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 22:11

Copilot AI 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.

Pull request overview

Copilot reviewed 17 out of 20 changed files in this pull request and generated 1 comment.

Comment thread scripts/utils/validate-httpx2-wheel.py
Copilot AI review requested due to automatic review settings July 23, 2026 22:26

Copilot AI 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.

Pull request overview

Copilot reviewed 17 out of 20 changed files in this pull request and generated 1 comment.

Comment thread pyproject.toml
@jbeckwith-oai
jbeckwith-oai marked this pull request as ready for review July 24, 2026 01:46
@jbeckwith-oai
jbeckwith-oai requested a review from a team as a code owner July 24, 2026 01:46
@openai-sdks

openai-sdks Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

OkTest Summary

✅ 237/237 SDK tests passed in 9.435s for Python SDK PR #3537.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 122ms
tests/chat-completions-create.test.ts ✅ Passed 226ms
tests/chat-completions-stream.test.ts ✅ Passed 100ms
tests/files-content-binary.test.ts ✅ Passed 123ms
tests/files-create-multipart.test.ts ✅ Passed 280ms
tests/files-list-pagination.test.ts ✅ Passed 114ms
tests/initialize-config.test.ts ✅ Passed 125ms
tests/instance-isolation.test.ts ✅ Passed 146ms
tests/models-list.test.ts ✅ Passed 264ms
tests/responses-background-lifecycle.test.ts ✅ Passed 229ms
tests/responses-body-method-errors.test.ts ✅ Passed 288ms
tests/responses-cancel-timeout.test.ts ✅ Passed 217ms
tests/responses-cancel.test.ts ✅ Passed 241ms
tests/responses-compact-retries.test.ts ✅ Passed 246ms
tests/responses-compact.test.ts ✅ Passed 192ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 110ms
tests/responses-create-advanced.test.ts ✅ Passed 151ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.3s
tests/responses-create-errors.test.ts ✅ Passed 247ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 163ms
tests/responses-create-retries.test.ts ✅ Passed 313ms
tests/responses-create-stream-failures.test.ts ✅ Passed 114ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 182ms
tests/responses-create-stream-wire.test.ts ✅ Passed 2.763s
tests/responses-create-stream.test.ts ✅ Passed 112ms
tests/responses-create-terminal-states.test.ts ✅ Passed 215ms
tests/responses-create-timeout.test.ts ✅ Passed 238ms
tests/responses-create.test.ts ✅ Passed 201ms
tests/responses-delete.test.ts ✅ Passed 187ms
tests/responses-input-items-errors.test.ts ✅ Passed 259ms
tests/responses-input-items-list.test.ts ✅ Passed 267ms
tests/responses-input-items-options.test.ts ✅ Passed 250ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 205ms
tests/responses-input-tokens-count.test.ts ✅ Passed 158ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.003s
tests/responses-not-found-errors.test.ts ✅ Passed 252ms
tests/responses-parse.test.ts ✅ Passed 322ms
tests/responses-retrieve-retries.test.ts ✅ Passed 244ms
tests/responses-retrieve.test.ts ✅ Passed 194ms
tests/responses-stored-method-errors.test.ts ✅ Passed 784ms
tests/retry-behavior.test.ts ✅ Passed 3.076s
tests/sdk-error-shape.test.ts ✅ Passed 300ms

View OkTest run #30125296618

SDK merge (b48e1304c403) · head (26090d3e4b3d) · base (8a6adcb3b88d) · OkTest (91635c6a2723)

@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: 59fe6ea218

ℹ️ 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 .github/workflows/python-version-review.yml Outdated
Comment thread scripts/check-python-version-policy.py Outdated
@apcha-oai

Copy link
Copy Markdown
Contributor

Can we remove workflow_dispatch from the Codex workflow and make it cron-only? Scheduled workflows already run exclusively on the default branch (main). Otherwise LGMT

Copy link
Copy Markdown
Contributor Author

@apcha-oai Fixed in 6922777: I removed workflow_dispatch from the monthly Codex workflow, so it is cron-only on the default branch, and updated the repository automation map to match. Thanks!

@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: 69227778fc

ℹ️ 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 .github/codex/prompts/python-version-review.md Outdated

@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: 06fe88d81d

ℹ️ 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 scripts/check-python-version-policy.py
Comment thread requirements.lock

@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: 8406132629

ℹ️ 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 scripts/check-python-version-policy.py

@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: 41ac9de0ce

ℹ️ 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 scripts/check-python-version-policy.py

@HAYDEN-OAI HAYDEN-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 26090d3 with a thermonuclear maintainability pass. I inspected the complete diff, repository policy and packaging surfaces, monthly automation trust boundary, prior review threads, and current CI. The latest head closes the lockfile synchronization gap; I found no remaining substantive correctness, security, compatibility, or structural-maintainability issues. CI is green for lint, build plus wheel/sdist metadata and Python 3.9 rejection, Bedrock/HTTPX2 validators, Python 3.10/3.14 tests, HTTPX2, examples, CodeQL, breaking-change detection, and Agents SDK integration.

@jbeckwith-oai
jbeckwith-oai merged commit d4c151d into main Jul 24, 2026
20 checks passed
@jbeckwith-oai
jbeckwith-oai deleted the codex/python-3-10-version-policy branch July 24, 2026 21:02
@stainless-app stainless-app Bot mentioned this pull request Jul 24, 2026
jbeckwith-oai pushed a commit that referenced this pull request Jul 27, 2026
Automated Release PR
---


## 2.49.0 (2026-07-27)

Full Changelog:
[v2.48.0...v2.49.0](v2.48.0...v2.49.0)

### Features

* require Python 3.10 and automate version reviews
([#3537](#3537))
([d4c151d](d4c151d))

---
This pull request is managed by Stainless's [GitHub
App](https://github.com/apps/stainless-app).

The [semver version
number](https://semver.org/#semantic-versioning-specification-semver) is
based on included [commit
messages](https://www.conventionalcommits.org/en/v1.0.0/).
Alternatively, you can manually set the version number in the title of
this pull request.

For a better experience, it is recommended to use either rebase-merge or
squash-merge when merging this pull request.

🔗 Stainless [website](https://www.stainlessapi.com)
📚 Read the [docs](https://app.stainlessapi.com/docs)
🙋 [Reach out](mailto:support@stainlessapi.com) for help or questions

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
yonasb added a commit to starslingdev/skills that referenced this pull request Oct 22, 2026
… (OPT89 to OPT91), and OPT21 stops flagging deliberate gate jobs (#140)

* ci-speedup: three catalog patterns for slow builds and slow PR checks (OPT89 to OPT91)

Adds three catalog-only entries, each quoting changes OpenAI engineers
made in their public repos (every figure re-read from the PR body):

- OPT89 The Slowest Platform Compiles Its Own Tests (data-driven, risk
  MEDIUM): build once on a fast runner, run natively per platform.
  openai/codex#20585, openai/codex#23358, openai/tiktoken 853da97.
- OPT90 Every Pull Request Pays for Coverage That Could Run After Merge
  (data-driven, risk MEDIUM). openai/codex#16072, openai/openai-python#3537
  (no timings), openai/codex#20585 (its saving comes from two changes the
  PR does not separate, so none is credited to this pattern).
- OPT91 The Compile Is the Long Pole and Nobody Profiled It (data-driven,
  risk MEDIUM). openai/codex#23710 (ThinLTO), openai/codex#16630
  (async_trait removal; no CI run linked).

All three are detector: manual, like OPT25 and OPT43, so they are never
emitted. Counts 86 -> 89 (78 hygiene + 11 structural) in SKILL.md,
ARCHITECTURE.md and evals.json; SKILL.md line count unchanged (515).

Red-first exemption: catalog and doc text only, no behavior to regress.
Scoped run: 249 passed.

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

* ci-speedup: OPT89 says how to tell build from test time when one step does both

Checked against openai/codex's real runs: on both cited PRs the slow leg
compiles and tests inside one step (bazel test, cargo nextest), so step
timings alone cannot confirm detection step 2. The step now names the
evidence that can (run log, a build-timing artifact, or a test-only run),
and the #20585 example says its baseline job is named "Local Bazel build".

Text only, red-first exempt.

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

* ci-speedup: OPT21 no longer flags a wait on a cheap check job

OPT21 flagged any job whose `needs:` read no outputs and downloaded no
artifact, and each hit was credited a flat 30s wall-clock saving. That
fired on deliberate cheap gates, where a test job waits on a lint,
pre-commit or lockfile-check job so the expensive jobs never start when
the cheap check fails (openai/whisper whisper-test needing pre-commit;
openai/openai-python lint, build, test and five more needing
dependency-locks).

The detector now skips a job when every job it needs is a check-only
gate: every step is recognised setup (checkout, setup-*, cache,
dependency install) or a recognised check (lint, format check,
pre-commit, type check, lockfile check, actionlint and similar, or a
step named Check/Verify/Validate/Lint/...), at least one step is a
check, nothing builds, tests, deploys or publishes, and the job has no
outputs, services, container, environment, reusable uses: or
continue-on-error. A waiting job with always()/failure()/cancelled() in
its if: is still flagged. Anything unclassifiable fails closed to the
old behaviour. The OPT21 catalog entry gains a "When a needs: edge is
the right call" paragraph.

Red run (new tests against the unfixed detector):

  E       AssertionError: assert ['whisper-test'] == []
  E       AssertionError: assert ['build', 'lint', 'test'] == []
  E       AssertionError: assert ['e2e'] == []
  FAILED test_scan_detectors.py::test_opt21_not_flagged_on_a_pre_commit_gate
  FAILED test_scan_detectors.py::test_opt21_not_flagged_on_a_lockfile_check_gate
  FAILED test_scan_detectors.py::test_opt21_not_flagged_on_a_lint_gate
  3 failed, 11 passed, 208 deselected

Green: 14 passed (OPT21 tests); 283 passed across test_scan_detectors,
test_offline_pipeline_e2e, test_evidence_claim_guards and
test_catalog_anchor_aliases.

Real files: whisper test.yml OPT21 hits 1 -> 0; openai-python ci.yml
OPT21 hits 8 -> 0.

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

* ci-speedup: changelog entry for the OPT21 cheap-gate fix

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

* ci-speedup: OPT90 and OPT91 detection steps match what OpenAI's real repos show

Checked each entry's detection steps against openai/codex and
openai/openai-python workflows and run history:

- OPT90: step 2 now says how to count leg-unique failures (codex's
  Windows test legs often failed when every other leg passed, which is
  the case the step keeps on the PR path). A PR path already running a
  subset is the recommended shape, not an instance. The subset can be
  empty for a check another PR workflow covers (codex #16072 kept no
  compile or test legs). openai-python #3537 is described as adopting
  the shape, not as a measured saving: its full matrix was new.
- OPT91: a clean-by-design release build satisfies step 2, and a
  timing report CI produces but nobody reads counts as unread (codex
  already ran cargo --timings in release CI). The #23710 example says
  only codex's Windows release builds still used fat LTO. Codex's stable
  Windows release builds fell from 64.8 to 72.4 minutes (v0.131 to
  v0.137) to 43.2 and 48.8 minutes (v0.138, v0.139), in line with the
  PR's figure.

Text only, red-first exempt.

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

* ci-speedup: OPT90's guardrail fits a scheduled run, and OPT91 profiles with the slow job's cache state

OPT90's guardrail required the moved run to start on every merge, which a
scheduled run cannot do although the fix recipe offers one. It now asks that
every merged commit is covered and that a release never ships a commit the
full matrix has not passed.

OPT91's first fix step profiled a clean build, which adds back dependency
compilation the slow job does not repeat. It now profiles with the slow job's
own cache state and keeps a clean build as a comparison only.

Text-only catalog edits, so no red-first test (doc-only exemption).

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

* ci-speedup: OPT21's gate check no longer lets a check-style step name vouch for a test run, and no longer counts gates that cannot fail

Review of the OPT21 cheap-gate carve-out found it silencing real findings:
a step named "Verify" or "Check" counted as a check whatever it ran unless a
short denylist caught it, so `mvn -B verify`, `make check`, `pnpm -r test`,
`nix flake check`, `bundle exec rspec`, `ctest`, `python -m unittest` and
`./ci/run_all_tests.sh` under such names all made a gate. A check that
cannot fail (`|| true`, `|| exit 0`), a check that runs only under an `if:`,
a gate with steps the walker could not read, and `npm run lint-and-build`
(read as `lint`) also made a gate.

- The name rule now fails closed: a check-named step counts only when every
  line is a recognised check or setup line, an inline interpreter script, a
  shell test, an assignment, a read-only git command, or
  `git show <file> | python -`.
- A check that cannot fail, a conditional check, and an unreadable step never
  make a gate; npm/make script names must match whole.
- Each wait left unflagged is logged at DEBUG.
- Doc fixes: the catalog paragraph names the rules, the docstrings match
  the code, and OPT89's changelog line says "after merge or on a schedule".

Red proof: against the unfixed scan.py, 15 new tests fail, e.g.
  FAILED test_opt21_still_flags_a_test_run_under_a_check_name[Verify-mvn -B verify]
  FAILED test_opt21_still_flags_a_test_run_under_a_check_name[Check-make check]
  FAILED test_opt21_still_flags_a_wait_on_a_gate_it_cannot_vouch_for[check-that-cannot-fail]
  FAILED test_opt21_still_flags_a_wait_on_a_gate_it_cannot_vouch_for[unreadable-step]
  FAILED test_opt21_gate_suppression_leaves_a_debug_trace
  15 failed, 28 passed
With the fix: 43 passed. 14 further controls pin the job-level
disqualifiers, result conditions, two-gate needs, and missing or empty
upstream jobs. The real openai/openai-python ci.yml and openai/whisper
test.yml still give no OPT21 finding (8 and 1 waits left unflagged).

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

* ci-speedup: OPT21's gate check closes the remaining silent drops and no longer backtracks for minutes on a long flag run

On top of the check-name tightening, a gate still silenced real waits when:
- a lint was piped or chained into other work (`eslint . | ./heavy.sh`,
  `pre-commit run || ./run-integration-tests.sh`) or used `--exit-zero`;
- a script only started with lint (`./scripts/lint-and-test.sh`);
- a step used a local composite action (`./setup-and-test`), a custom
  `shell:`, or the job set `defaults:`;
- the job had a `wait:`/`cancel:` control step the walker drops;
- the gate itself waited on a build (`e2e` needs `lint` needs `build`).
All now keep the finding. The runner-prefix flag pattern in the check-line
and inline-script regexes was ambiguous (`--f` read as `-` + `-f`), so a
16-flag `uv run` line took 28s (55s under a check name) to classify; flags
now start with one or two dashes then a word character, and a value never
starts with a dash, so matching is linear.

Red proof against the unfixed scan.py (test_scan_detectors.py -k opt21):
  FAILED ...work_dressed_as_a_check[lint-piped-into-other-work]
  FAILED ...work_dressed_as_a_check[lint-or-other-work]
  FAILED ...work_dressed_as_a_check[lint-and-test-script]
  FAILED ...work_dressed_as_a_check[lint-with-exit-zero]
  FAILED ...work_dressed_as_a_check[local-composite-action]
  FAILED ...work_dressed_as_a_check[custom-shell]
  FAILED ...gate_whose_steps_are_not_plain[control-step]
  FAILED ...gate_whose_steps_are_not_plain[job-default-shell]
  FAILED ...wait_through_a_gate_that_waits_on_a_build
  FAILED ...stays_fast_on_a_long_flag_run (x2: 27.8s and 55.8s, budget 5s)
  11 failed, 58 passed
With the fix: 279 passed (detector + anchor tests). openai/whisper test.yml
and openai/openai-python ci.yml still scan to 0 OPT21 findings.

Text-only corrections (doc-only exemption): OPT89 says the 28m12s and 9m16s
runs are not like for like and quotes the full job name; OPT90 names the
real second change in codex #20585 and the lint package tests #16072 kept;
OPT91 says only stable Windows builds used fat LTO and quotes #16630's
futures exactly; the three entries cite OPT86 and OPT88 (not OPT25 and
OPT43, which are emitted) as unemitted peers. The OPT21 paragraph and the
changelog name the added rules.

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

* ci-speedup: OPT86 and OPT88 stop naming OPT25 and OPT43 as patterns nothing detects

Both entries said "Like other `detector: manual` entries (for example OPT25
and OPT43), no pass emits ...", but collect_runs emits OPT25 and OPT43
findings. They now name each other, matching the OPT89 to OPT91 wording.
Headings and anchors unchanged.

Text-only catalog and changelog edit, so no red-first test (doc-only
exemption).

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

* ci-speedup: OPT21's gate paragraph reads as a short lead and four bullets

The "When a `needs:` edge is the right call" paragraph was one long sentence
of nested parentheses. It is now a lead sentence (the gate's own duration in
wall clock traded for runner minutes saved when it fails) and bullets for
what counts as a check-only gate, what disqualifies one, when the wait is
still flagged, and that cheap is judged by what the gate runs, not how long
it takes. Same facts as before; the OPT21 heading and anchor are unchanged.

Text-only catalog edit, so no red-first test (doc-only exemption).

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
ci — 26090d3e Deployed Jul 24, 2026 by jbeckwith-oai via examples #5217
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.

4 participants