test(proxy): harden transcript-proxy guard against two silent bypasses (hardens #1129) - #1131
test(proxy): harden transcript-proxy guard against two silent bypasses (hardens #1129)#1131groupthinking wants to merge 3 commits into
Conversation
youtube-transcript-api >=1.0 only honours a proxy when a ``proxy_config`` is passed to the constructor. Six call sites across four modules built a bare ``YouTubeTranscriptApi()``, so they egressed from the host's own IP and bypassed WEBSHARE_PROXY_URL entirely — including ``_extract_transcript_with_rotation``, whose name implies the opposite. - src/integration/youtube_api.py:99 - src/agents/process_video_with_mcp.py:222,233 - src/agents/interactive_metadata_extractor.py:87 - src/mcp/mcp_video_processor.py:694,718 Each now resolves its config from the canonical ``youtube_extension.utils.proxy.get_transcript_proxy_config`` helper, guarded by the import fallback this repo already uses in gemini_video_master_agent.py so modules stay importable outside the package. The helper returns None when no proxy is configured, so direct connections keep working unchanged. Adds tests/unit/test_transcript_proxy_coverage.py: an AST walk over src/ and shared/ that fails if any construction omits proxy_config, plus a canary that fails if the scan ever matches nothing (the vacuity mode that has bitten this repo repeatedly). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…roxy Review on #1129 found the guarded-import fallback introduced by this branch was itself a silent bypass: when a module is executed by path (the documented CLI entry point) youtube_extension is not importable, so the stub returned None and proxy_config=get_transcript_proxy_config() egressed directly from the host IP -- the exact failure this issue exists to prevent. Replace the stub in all four standalone-executable modules with a sys.path bootstrap to the repository's src directory, falling back to a hard ImportError. The proxy is now either honoured or the module refuses to load; it is never silently skipped. Harden the guard suite against three ways it could pass while protecting less than it claims: - a missing configured source root was skipped silently - SOURCE_ROOTS could be narrowed by hand with every other test still green; the required roots are now rediscovered from the tree - referencing the helper was satisfied by the call site alone, so a broken import passed; every import from the proxy module must now bind the helper All 9 mutations kill their tests, including one that revealed a newly added test was itself vacuous (it asserted parents[1] from a test-side constant rather than the index the source actually uses). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes the two residual holes the automated review flagged on the guard added by #1129 — both were ways a construction could pass the guard while still egressing outside the centralized proxy: 1. `**kwargs`-only calls were treated as compliant. `YouTubeTranscriptApi( **opts)` reads as opaque but egresses directly whenever `opts` omits `proxy_config` — the exact silent bypass this guard exists to catch. `_has_required_keyword` now requires an explicit `proxy_config=` keyword. No real call site uses `**kwargs`, so this adds zero false positives. 2. `test_module_resolves_proxy_config_from_the_canonical_helper` only checked that the helper name appeared in the source and was imported; a call passing `proxy_config=<foreign config>` or `proxy_config=object()` still passed. It now inspects each construction's `proxy_config` AST value and requires it to be a call to `get_transcript_proxy_config()`, subsuming the old literal-None check. Both tightenings are mutation-verified: a `**kwargs` bypass and a `proxy_config=object()` construction each now fail the guard where they previously passed. All 21 tests green against the real (14/14 compliant) call sites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NaRe39Fsrq2tv8vpn2aRdp
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🔍 PR Validation |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. Scanned FilesNone |
Agent Completion Truth Gate: BLOCKEDReasons: Machine-readable verdict{
"details": {
"collection_errors": [
"incomplete_linked_issue_contract",
"linked_issue_not_agent_task",
"missing_intent_snapshot",
"missing_agent_run_id",
"missing_agent_login"
],
"invalid_fields": [
"policy.agent_login",
"policy.run_id"
]
},
"reasons": [
"invalid_payload"
],
"verdict": "blocked"
} |
Blocker: Agent Completion Truth Gate — and why I'm not forcing past it
The change itself is sound and test-onlyTwo hardenings to the regression guard from #1129, closing the two residual holes the Copilot review flagged (commit
Both are mutation-verified (a Recommended human actionThis branch is a strict superset of #1129 (its HEAD
Merging to protected Generated by Claude Code |
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
|
Contained as a duplicate of canonical #1129. The exact two-part test-only hardening from |
Canonical issue
Closes #1087 (via the same fix as #1129 — see Agent handoff below).
Outcome
Strengthens the AST regression guard introduced by #1129 so it can no longer
pass a
YouTubeTranscriptApi(...)construction that would still egress outsidethe centralized outbound proxy. This branch is
fix/centralized-transcript-proxy-1087'sHEAD (
5659f2b) plus one test-only commit; the production fix is unchanged.Scope
tests/unit/test_transcript_proxy_coverage.py:_has_required_keywordno longer treats**kwargs-only calls as compliant —YouTubeTranscriptApi(**opts)reads as opaque but egresses directly wheneveroptsomitsproxy_config. It now requires an explicitproxy_config=keyword.test_module_resolves_proxy_config_from_the_canonical_helpernow inspects eachconstruction's
proxy_configAST value and requires it to be a call toget_transcript_proxy_config(). Previously a substring/import check letproxy_config=<foreign config>orproxy_config=object()pass.Risk
live constructions in
src/passproxy_config=get_transcript_proxy_config()explicitly.1ba9cd4.Verification
All at head
1ba9cd4666c1339c7c3001cafba21f8180639fb4.pytest tests/unit/test_transcript_proxy_coverage.py→ 21 passed.YouTubeTranscriptApi(**opts)bypass now failstest_every_transcript_client_passes_proxy_config(previously passed);proxy_config=object()construction now failstest_module_resolves_proxy_config_from_the_canonical_helper(previously passed).ruff checkclean;black --checkclean on the changed file.Production evidence
Not applicable — test-only change. The production behaviour and its evidence are
carried by #1129 (Vercel green, CodeRabbit approved).
Agent handoff
strict superset of fix: route every transcript client through the centralized proxy (#1087) #1129 (its HEAD + one test hardening). They must not both merge.
Recommended: merge this one and close fix: route every transcript client through the centralized proxy (#1087) #1129, or cherry-pick commit
1ba9cd4ontofix: route every transcript client through the centralized proxy (#1087) #1129 and close this. Human's call.
main)Generated by Claude Code