Skip to content

fix(ci): close HTTP error response bodies - #1879

Open
seonghobae wants to merge 3 commits into
mainfrom
codex/close-http-error-responses
Open

fix(ci): close HTTP error response bodies#1879
seonghobae wants to merge 3 commits into
mainfrom
codex/close-http-error-responses

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Summary

  • close HTTPError response bodies after bounded telemetry and policy reads
  • preserve existing sanitized error behavior
  • add focused regression coverage for all four paths

Verification

  • git diff --check
  • pytest -q tests/test_noema_review_gate.py tests/test_pingora_edge_policy.py tests/test_repository_metadata_live_verification.py tests/test_sandboxed_web_e2e.py — 261 passed

Replaces the only substantive runtime fixes from #1871 without its unrelated 928-line coverage/docstring expansion.

Signed-off-by: Seongho Bae <me@seonghobae.me>
@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 49 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: a0ca0c4e-a8ae-4d75-8a69-eb2a763e575a

📥 Commits

Reviewing files that changed from the base of the PR and between 8272e4f and 0723a0c.

📒 Files selected for processing (8)
  • scripts/ci/noema_review_gate.py
  • scripts/ci/pingora_edge_policy.py
  • scripts/ci/reconcile_repository_metadata.py
  • scripts/ci/sandboxed_web_e2e.py
  • tests/test_noema_review_gate.py
  • tests/test_pingora_edge_policy.py
  • tests/test_repository_metadata_live_verification.py
  • tests/test_sandboxed_web_e2e.py

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.

@seonghobae
seonghobae enabled auto-merge (squash) September 5, 2026 02:27
@opencode-agent
opencode-agent Bot disabled auto-merge September 5, 2026 05:56
seonghobae added a commit that referenced this pull request Sep 5, 2026
#1883)

The admission-controller feature burst (#1859-#1869) shipped
review_admission_controller.py, pr_review_merge_scheduler_core.py's
SchedulerAdmissionGate, and (separately, pre-existing) a coverage gap
in audit_codeql_default_setup_rollout.py without full test coverage
or docstrings, breaking the required 100% coverage/docstring gate for
every PR in this repository regardless of that PR's own diff.

The original fix for this landed on .github#1871, which was later
closed in favor of narrower successors (#1877 for the stale schedule
oracles, #1879 for HTTP error response bodies) -- but the coverage and
docstring portion of #1871's delta was dropped in that narrowing and
never reached main. This PR recovers exactly that portion from
#1871's still-present branch (fix/hourly-review-repair-callers-cron-
format-drift) and completes it:

- review_admission_controller.py: 85% -> 100% coverage (new
  tests/test_review_admission_controller.py), 14 missing docstrings
  added across its WorkerBoundary/AdmissionRequest/RequestRecord/
  DispatchLease/ControllerState/DispatchPlan dataclasses and methods.
- audit_codeql_default_setup_rollout.py: 79% -> 100% coverage (new
  tests/test_codeql_default_setup_rollout.py), 2 missing docstrings
  added (parse_args, main).
- pr_review_merge_scheduler_core.py's SchedulerAdmissionGate: 3
  missing docstrings added (__init__ and its two nested closures,
  lease/reconcile_state).

Additionally closed pr_review_merge_scheduler_core.py's own separate,
longer-standing coverage gap (98% -> 100%, unrelated to the
admission-controller work) discovered while verifying this fix would
actually bring main to a green gate rather than a differently-shaped
99%: the durable admission gate's own bounded-budget/stale-head
branches across every dispatch call site (9 "admission_deferred"
checks across post_update_branch_followup/dispatch_draft_review_only/
inspect_pr, plus dispatch_strix_evidence's own two "admission_deferred"/
"stale_head" pairs), reconcile()'s live-head-moved and still-running
branches, rotating_pr_window's/dispatch_draft_review_only's/the
workflow-run classifier's/the empty-PR-close path's/main()'s own
--admission-state-path wiring's remaining gaps, and two untestable
package-import fallback lines marked `# pragma: no cover - package
import path` matching this file's established convention for that
exact pattern.

Full local triad: 2875 passed, 1 skipped; coverage 100%; interrogate
100%.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
seonghobae added a commit that referenced this pull request Sep 5, 2026
…pline (#1909)

Two rules from mistakes this session actually made and corrected, per the
per-session lane split agreed with the other concurrent sessions (peer 3
took verification discipline in #1907; peer 2 has gate/merge mechanics;
host 1 has close-time diff comparison and noema concurrency; host 2 has
CI failure diagnosis).

- Narrowing a PR does not carry its delta. #1871 was closed in favor of
  #1877 plus #1879; both successors were green, but neither carried the
  coverage/docstring delta, leaving main's required 100% gate broken
  until #1883 recovered it. "Each piece works" and "the pieces together
  cover the original's scope" are different questions.
- Compare content, not ancestry. main mixes squash and merge commits
  (last 200: 153 single-parent, 47 two-parent, counted directly), so
  `git merge-base --is-ancestor` gives false negatives for squashed
  deltas and false positives for reverted merge-commit deltas.
- Never endorse a timeout or retry constant on a model-invocation path
  without reading docs/product-goal-directive.md section 8, which accepts
  more than two hours per model and states speed is not a core
  consideration. #1889/#1890/#1892 each capped a model step at 900s on
  real multi-hour-hang evidence and were all reverted (#1891, #1895).

Every PR number, the section-8 quotes, the parent-count distribution, and
the 100% gate values were verified against the repository directly. An
earlier draft of the timeout bullet cited a section number that does not
exist and attributed a sentence to that file which appears only in
#1891's PR body; both were caught by grepping rather than trusting the
summary that introduced them, and that failure is recorded in the text.

Full suite: 2883 passed, 1 skipped.

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

@cwl-noema-review cwl-noema-review Bot 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.

Noema LLM review

The PR correctly and safely closes HTTP error response bodies across four scripts using HTTPError.close(), which is idempotent and prevents resource leaks (file descriptors, connections). Each code change is accompanied by a regression test asserting the response body is closed. The changes are narrowly scoped, preserve existing behavior for non-HTTP errors, and introduce no correctness, security, or maintainability regressions. The only minor gap is that test_repository_metadata_live_verification.py does not cover the plain URLError (non-HTTP) branch, but that branch is unchanged by this PR, so it is non-blocking.

Reviewed changed lines

  • scripts/ci/noema_review_gate.py:1639 (RIGHT): The finally block guarantees exc.close() is called even if _extract_http_error_telemetry raises. CPython's HTTPError.close() is idempotent and closes the underlying fp. The new test test_call_llm_reports_only_safe_model_from_bounded_http_error asserts response_body.closed, confirming the resource is released. The exception handling path is otherwise unchanged.
  • scripts/ci/pingora_edge_policy.py:307 (RIGHT): The isinstance(exc, HTTPError) check and exc.close() before re-raising PolicyError match CPython semantics. The test test_github_open_json_raises_policy_error_for_transport_errors asserts exc.fp.closed. Non-HTTP URLError and TimeoutError paths are unaffected.
  • scripts/ci/reconcile_repository_metadata.py:251 (RIGHT): HTTPError is a subclass of URLError, so the isinstance guard correctly catches redirected 302 cases from _NoPagesRedirects. The exc.close() call is idempotent; the new test test_pages_transport_error_closes_response_body verifies body.closed. Non-HTTP URLError/timeout/OSError branches are untouched.
  • scripts/ci/sandboxed_web_e2e.py:587 (RIGHT): The except (urllib.error.URLError, TimeoutError) as exc block now checks isinstance(exc, urllib.error.HTTPError) and calls exc.close() before sleeping. This matches CPython's HTTPError.close() semantics. The new test test_wait_for_url_closes_http_error_response asserts body.closed. Retry and sleep logic are unchanged for other error types.
  • tests/test_repository_metadata_live_verification.py:67 (RIGHT): The test constructs an HTTPError with a BytesIO body and verifies body.closed after _pages_publication_ready raises a RuntimeError. It exercises the HTTPError branch of the new exc.close() logic. The non-HTTP URLError branch is not covered here, but that branch was not modified by this PR.

Adversarial validation

  • scripts/ci/noema_review_gate.py:1639 (RIGHT) falsified: Calling exc.close() in a finally block could cause a double-close or an exception if _extract_http_error_telemetry already closed the body. — CPython source (urllib/error.py L94-96) and the added test test_call_llm_reports_only_safe_model_from_bounded_http_error which asserts response_body.closed after the call.
  • scripts/ci/sandboxed_web_e2e.py:587 (RIGHT) falsified: Closing the HTTP error body in the polling loop could break the retry logic or cause a sleep to be skipped. — The test asserts body.closed and that wait_for_url returns False after the timeout period, proving the sleep path is unaffected.
  • Residual risk: Low. The only untested scenario is a plain (non-HTTP) URLError in reconcile_repository_metadata.py, but that code path is unchanged and existing tests cover transport errors broadly. The risk of a resource leak is mitigated by the idempotent close() and the confirmed tests for all HTTPError paths.

Findings

  • No blocking findings.
  • Result: APPROVE
  • Head SHA: 0723a0c7d9d4da82e64f884cff8babf1f0e0c81a
  • Reviewer credential: noema-review-github-app-refresh
  • Actor: cwl-noema-review[bot]

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