Skip to content

docs(triage): PR remediation run 2026-07-29 + refreshed CWE-209 (#831) canonical - #1077

Closed
groupthinking wants to merge 15 commits into
mainfrom
claude/determined-maxwell-82cm3w
Closed

docs(triage): PR remediation run 2026-07-29 + refreshed CWE-209 (#831) canonical#1077
groupthinking wants to merge 15 commits into
mainfrom
claude/determined-maxwell-82cm3w

Conversation

@groupthinking

Copy link
Copy Markdown
Owner

Canonical issue

Relates to the recurring PR-remediation runbook (prior records: #1044, #1059). The
security commits on this branch are the refreshed canonical CWE-209 work also tracked by
#831 — this branch rebases that work onto verified main; it is not a competing
re-implementation.

Outcome

Two things land on this branch:

  1. docs/triage/pr-remediation-2026-07-29.md — the audit record for the 2026-07-29
    remediation run. Oldest-first scan of all 36 open PRs. Result: 0 autonomously
    mergeable
    (the correct, safe outcome). 36 DEFERRED(draft), 0 HALTED, 0 MERGED.
    Every open PR is a draft; fix(auth): restore Google OAuth configuration in Vercel production #903 (the single human-gated PR on 07-28) has been returned
    to draft, so nothing is HALTED today.
  2. Refreshed canonical CWE-209 response-sanitization (fix(security): restore CWE-209 response protections #831) — 13 commits, ~1000
    insertions across cloud_api_endpoints.py, real_api_endpoints.py,
    cloud_ai_routes.py, official_api.py, code_generator.py, and their tests. Guards
    against internal exception / error-tree leakage in non-500 and cloud response bodies.
    Rebased onto verified main (0 commits behind).

Scope

  • Included:
  • Explicitly excluded:
    • any merge to protected main (publish gate is human-by-default; no PR carries
      automerge)
    • any push to app-owned bot (jules-*) branches
    • any dependency / CI-config change

Risk

  • Risk level: low (docs) / medium (the security guards touch API response paths)
  • Failure mode: over-sanitization could blank a legitimate error field; covered by the
    added tests asserting exact sanitized shapes
  • Rollback: revert this PR or restore the prior response-construction paths

Verification

  • Focused tests: test_500_info_disclosure.py, test_cloud_routes.py,
    test_code_generator_agent.py119 passed locally
    (test_real_api_endpoints.py requires the pinned pydantic-v1 / DB stack the local
    sandbox couldn't reconstruct; it is exercised by required CI on the head SHA)
  • Required CI on the current head
  • Review threads resolved: none opened by this run

Production evidence

Not applicable to the triage doc (documentation only). The CWE-209 guards change API
response construction but no production deploy is performed by this PR — production
remains on verified main.

Agent handoff

Agent provenance

Agent-authored triage + refreshed security branch. Scope and terminal states are
authoritative in the committed docs/triage/pr-remediation-2026-07-29.md.


Generated by Claude Code

claude and others added 14 commits July 21, 2026 08:11
…E-209)

Refreshed onto current main (was 73 commits behind). main already sanitizes the
500 HTTPException/JSONResponse details, the 503 CloudAIError, and the cloud-AI
exception ordering, but still returns the caught exception under an "error" key
in several handlers that *return* (not raise) a dict body — a 200
"degraded"/"failed" payload that discloses internal state just like a 500 detail
would.

- cloud_api_endpoints.py: /api/v3/queue/stats and /api/v3/cloud-status (three
  per-service checks + outer handler) now return a static status string and log
  the exception server-side with exc_info=True.
- real_api_endpoints.py: cost-dashboard, usage-analytics, optimization, and
  service-status handlers likewise return "Internal server error" / "Service
  unavailable" and log with exc_info=True.
- tests/unit/test_500_info_disclosure.py: extend main's AST guard with a
  response-body scanner that flags {"error": <exception>} bodies. It derives the
  caught identifier from the enclosing ast.ExceptHandler.name (per Copilot), so a
  renamed variable (e.g. `except Exception as failure`) cannot bypass it; scoped
  to the two handlers hardened here.

Existing endpoint tests assert status/degraded/key-presence, not the exception
string, so behavior is preserved. Guard suite: 5 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01He4GxmJcWW8XdwxYQQh8Sa
Copilot review: the response-body scanner lost the exception taint after an
intermediate assignment, e.g. `except Exception as failure: message =
str(failure); return {"error": message}` — a common refactor of the sanitized
sites — produced no finding.

Propagate taint from the handler-bound name to any variable assigned from an
expression that references an already-tainted name (fixpoint, monotonic), so an
alias cannot launder the leak past the guard. Added positive controls for the
str()/f-string alias forms and a negative control for a static alias.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01He4GxmJcWW8XdwxYQQh8Sa
Sanitize legacy persisted error text at every cloud endpoint read boundary, make rate-limit details static, extend the AST invariant to all 5xx statuses, and add focused regressions.
…E-209)

Closes two current-head Copilot findings on #831 (both CWE-209 information
disclosure through pass-through response sinks the boundary sanitizer missed):

- real_api_endpoints.py:_sanitize_response_errors only rewrote the singular
  "error" key, so the plural "errors" collection — which real_ai_processor
  .analyze_video_content() fills with scalar strings like
  f"{step}: {str(result)}" — passed exception text through unchanged in batch,
  cached, list, and status responses. Add _sanitize_error_list to replace scalar
  string entries with the public message while preserving/recursing structured
  batch error records (keeps test_batch_failure_records_are_sanitized_recursively
  green).

- /api/v2/process-video returned ai_analysis=result.get('ai_analysis') raw while
  every other endpoint wraps its payload; real_video_processor sets
  ai_analysis['error'] = f"AI analysis failed: {e}" on failure. Wrap it in
  _sanitize_response_errors so the nested error/errors are scrubbed too.

Adds focused regression tests for both shapes. No behavior change beyond
replacing leaked exception text with "Video processing failed"; server-side
diagnostics and logs are untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwvL8n17iZJqaj83ARzWrQ
The recursive `errors` sanitizer in real_api_endpoints and
cloud_api_endpoints replaced only `str` leaves and returned any other
scalar unchanged. FastAPI can serialize non-string leaves (bytes, ints,
bools), so a legacy/provider diagnostic value that is not a string could
bypass the scalar sanitization invariant and reach clients.

Replace every non-null leaf with the public message after handling
list/tuple/dict containers; only None (absence of an error) is preserved.
Adds a positive-control test covering int/bool/None leaves.

Addresses the current-head automated review finding on PR #831.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015A4gdsfGkyZdRYQwm4o99e
…eption leaks (CWE-209)

Resolves two Copilot review findings against the current head:

* Live leak: official_api.validate_video_url returned
  f"Invalid URL format: {e}" / f"Video validation failed: {e}" as its
  message element, which /api/v2/validate-video echoes verbatim to clients
  under "message" with HTTP 200. The adapter swallowed the exception and
  handed it back as data, so the endpoint's own 500 handler never saw it.
  Return static messages and log the exception server-side instead.

* Regression guard gaps in test_500_info_disclosure.py:
  - Scan the plural "errors" key so {"errors": [str(e)]} is flagged like a
    scalar "error" field; accept _sanitize_error_list as a boundary
    sanitizer; add positive/negative controls.
  - Add _iter_returned_exception_leaks: flag any return inside an
    except ... as <name> handler that carries the caught exception (or an
    alias) in official_api.py / real_api_endpoints.py / cloud_api_endpoints.py.
    This models the returned-value disclosure path neither prior scan caught.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01He4GxmJcWW8XdwxYQQh8Sa
Preserve exactly the nine declared CWE-209 implementation/test files while synchronizing the existing canonical branch with main@995fa268. No force push.
Records oldest-first triage of all 36 open PRs. Every open PR is a draft
(scope-gated -> DEFERRED(draft)); 0 autonomously mergeable, 0 HALTED. #903
(previously the single human-gated PR) has been returned to draft. Matches
the 2026-07-27 (#1044) and 2026-07-28 (#1059) conclusions: the backlog is
human-gated by design and the remediation loop should idle until a draft
flips to ready or a PR gains the automerge label.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQDL89d1xNEm4hijHZMaSf
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v0-uvai Canceled Canceled Aug 1, 2026 7:59pm

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • [‘architecture-gap’, ‘bug’, ‘ci-cd’, ‘ci/cd’, ‘copilot-rabbit’, ‘documentation’, ‘duplicate’, ‘enhancement’, ‘frontend’, ‘github_actions’, ‘good first issue’, ‘help wanted’, ‘high-priority’, ‘invalid’, ‘javascript’, ‘ml-model’, ‘needs-triage’, ‘pipeline-critical’, ‘placeholder-code’, ‘priority:high’, ‘python’, ‘python:uv’, ‘question’, ‘styling’, ‘tests’, ‘v0’]

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1961d651-30c3-4ce6-b110-c28866e11180

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actions github-actions Bot added documentation Improvements or additions to documentation python labels Jul 29, 2026
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA ea43337.
Ensure 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 Files

None

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

🔍 PR Validation

⚠️ Large PR detected (1261 lines changed)

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

Agent Completion Truth Gate: BLOCKED

Reasons: invalid_payload

Machine-readable verdict
{
  "details": {
    "invalid_fields": [
      "issue.number",
      "policy.agent_login",
      "policy.run_id"
    ]
  },
  "reasons": [
    "invalid_payload"
  ],
  "verdict": "blocked"
}

Workflow evidence

@groupthinking groupthinking added duplicate This issue or pull request already exists security labels Jul 29, 2026 — with ChatGPT Codex Connector

Copy link
Copy Markdown
Owner Author

Contained as draft duplicate evidence.

Do not transfer or merge this mixed payload as a competing implementation. Keep #1077 draft while the existing canonical unit remains #912/#831. No branch was deleted and no work was discarded.

@groupthinking groupthinking added tests and removed duplicate This issue or pull request already exists labels Jul 29, 2026 — with Claude

Copy link
Copy Markdown
Owner Author

Acknowledged — and verified directly against the repo, not just this thread.

#1077 is a duplicate and I am keeping it draft. It will not be marked ready, merged, or transferred.

What I confirmed by reading the canonical units:

On the red checks (none are code defects, none are autonomously fixable here):

  • agent-completion/truth-gate/pr-1077invalid_payload / missing_trusted_publication. This is the repo's by-design governance gate (draft_pr + a trusted agent-lock publication). I will not fabricate an agent_login / run_id to force a trust gate green.
  • Vercel — "Canceled from the Vercel Dashboard", not a build failure; no deployable change here.
  • CodeRabbit — skipped by design (.coderabbit.yaml auto_review.drafts: false); left for on-demand review once/if a human marks ready.

Focused tests on the security payload pass locally (119 passed across test_500_info_disclosure.py, test_cloud_routes.py, test_code_generator_agent.py; test_real_api_endpoints.py needs the pinned pydantic-v1/DB stack — covered by required CI). No branch deleted, no work discarded — canonical work remains #1076 and #831/#912. Terminal state: HALTED(duplicate — retained as draft evidence per repo convention); final keep-vs-close disposition is the owner's.


Generated by Claude Code

Copilot AI review requested due to automatic review settings August 1, 2026 19:43

Copy link
Copy Markdown
Owner Author

Noted that this PR was marked ready for review (actor: groupthinking). Flagging the status honestly rather than driving it to green, because doing so would be the wrong action for a duplicate:

#1077 is still a verified duplicate — triage record → canonical #1076; CWE-209 payload → canonical #831 / #912 at head 1a0ce65. Un-drafting it has surfaced the repo's full canonical-delivery contract, and it now fails exactly where a duplicate should:

I am not merging this to protected main (human publish gate; also blocked by every gate above) and not gaming the governance contract to make a duplicate look canonical.

This appears to contradict the earlier instruction on this PR ("keep #1077 draft ... do not merge as a competing implementation"). Since I can't reconcile that with the un-draft autonomously, I'm holding for an explicit owner decision:

Holding here. Further identical governance re-fires on this head are already accounted for.


Generated by Claude Code

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

Pull request overview

Adds the July 29 PR-remediation audit and hardens API responses against CWE-209 information disclosure.

Changes:

  • Records triage results for 36 draft PRs.
  • Sanitizes exception details across cloud and real API responses.
  • Expands regression tests and generated FastAPI error handling.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/triage/pr-remediation-2026-07-29.md Records remediation outcomes.
src/agents/specialized/code_generator.py Generates sanitized 500 responses.
src/youtube_extension/backend/cloud_ai_routes.py Sanitizes rate-limit details.
src/youtube_extension/backend/cloud_api_endpoints.py Sanitizes cloud response trees.
src/youtube_extension/backend/real_api_endpoints.py Sanitizes real API responses.
src/youtube_extension/backend/services/youtube/adapters/official_api.py Removes exception text from validation responses.
tests/unit/test_500_info_disclosure.py Expands static disclosure guards.
tests/unit/test_cloud_routes.py Tests cloud-response sanitization.
tests/unit/test_code_generator_agent.py Tests generated endpoint safety.
tests/unit/test_real_api_endpoints.py Tests recursive response sanitization.

Comment thread tests/unit/test_500_info_disclosure.py Outdated
Comment on lines +393 to +399
def _uses_public_error_sanitizer(node: ast.AST) -> bool:
return isinstance(node, ast.Call) and _call_name(node) in {
"_client_safe_error",
"_sanitize_public_error",
"_sanitize_response_errors",
"_sanitize_error_list",
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Verified — valid false negative. The Pass-3 allowlist in _uses_public_error_sanitizer accepts _sanitize_response_errors and _sanitize_error_list as sufficient for a scalar error= sink, but those are whole-tree sanitizers that return non-container inputs unchanged. So VideoAnalysisResponse(error=_sanitize_response_errors(result["error"])) satisfies the guard while still forwarding the raw diagnostic (Pydantic then coerces it to a string).

Fix: for scalar response-model error fields, require a scalar-replacing helper (_client_safe_error / _sanitize_public_error); keep the tree sanitizers allowlisted only for whole dict/list processor results, which are checked separately.


Generated by Claude Code

Comment thread tests/unit/test_500_info_disclosure.py Outdated
Comment on lines +109 to +124
def _status_symbol_table(tree: ast.Module) -> dict[str, int]:
"""Resolve module constants that alias literal or standard status values."""
symbols: dict[str, int] = {}
changed = True
while changed:
changed = False
for node in tree.body:
targets: list[ast.AST] = []
value: ast.AST | None = None
if isinstance(node, ast.Assign):
targets, value = node.targets, node.value
elif isinstance(node, ast.AnnAssign) and node.value is not None:
targets, value = [node.target], node.value
if value is None:
continue
status = _status_code_value(value, symbols)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Verified against the code — this is a real false negative. _status_symbol_table only walks tree.body, so a status aliased inside a function (e.g. server_failure = status.HTTP_503_SERVICE_UNAVAILABLE followed by HTTPException(status_code=server_failure, detail=str(exc))) never enters symbols. _status_code_value then falls through to _named_status_code('server_failure')None, and _status_is_server_error skips the call entirely.

Fix: resolve assignments in the enclosing lexical scope of each response call (walk FunctionDef/AsyncFunctionDef bodies, not just module scope) and add a local-alias control case so the guard stays honest.

Recording this as verified rather than force-landing a patch here: this PR is currently red on the agent-completion gate (a known misfire being fixed separately) and awaits a human protected-main publish decision, and its branch differs from this session's mandated working branch — so these two guard fixes should land on this branch (or fold into the #831 canonical work) via an authorized push, not a competing duplicate PR.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Automated shepherd note — PR marked ready-for-review. I diagnosed the red CI and am recording why it is not auto-fixed.

Code checks pass: validate ✅ and dependency-review ✅. copilot-pull-request-reviewer is still running. No open review threads.

Every red check is a repo agentic-governance gate, in two distinct causes:

  1. Canonical issue and evidence — legitimate policy rejection, needs a human. The check fails with exactly one closing reference is required: Closes #<issue>. This branch intentionally bundles two deliverables — the docs/triage/pr-remediation-2026-07-29.md record and the rebased CWE-209 security guards (the fix(security): restore CWE-209 response protections #831 canonical work) — and the PR body explicitly reserves for a human the decision of whether to fold fix(security): restore CWE-209 response protections #831 into this branch or keep them separate. Inserting a Closes #<issue> line would make that reserved call unilaterally (and could trip the check's competing-PR sub-rule if fix(security): restore CWE-209 response protections #831 is tracked elsewhere), so I am not adding one autonomously. PR Governance and Agent completion enforcement fail downstream of this same contract.

  2. agent-completion/truth-gate — systemic gate bug, not this diff. The gate's github-script step is erroring and self-publishing invalid_payload / "gate publication failed" — identically on unrelated PRs 🛡️ Sentinel: [MEDIUM] Fix internal error message leakage in API routes #1145 and fix: scope agent gate applicability to real dispatch evidence #1154 at the same minute. Dedicated PRs (fix(ci): report Agent Lock gate as neutral when trust policy is unprovisioned #1151, fix: scope agent gate applicability to real dispatch evidence #1154) already target this machinery. (The red Vercel status is a dashboard-canceled deploy, also not a code failure.)

Merge is a protected-main human publish gate (no automerge label).

Terminal state: HALTED — awaiting human decision on (a) the canonical-issue / #831 fold-or-split call and (b) the protected-main merge. No autonomous fix is safe here, so I am not pushing commits or merging.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Re: Copilot's two review comments on tests/unit/test_500_info_disclosure.py — I verified both against the source; both are valid CWE-209 static-guard false-negatives:

  1. Local status aliases (line ~124). _status_symbol_table only iterates tree.body, so a 5xx code bound to a local inside a function (e.g. server_failure = status.HTTP_503_SERVICE_UNAVAILABLEHTTPException(status_code=server_failure, detail=str(exc))) resolves to None in _status_code_value and is skipped by _status_is_server_error. Confirmed false-negative; a local-alias control case would fail today.
  2. Scalar pass-through sanitizer (line ~399). _sanitize_response_errors returns non-container inputs unchanged (cloud_api_endpoints.py:80; the real_api_endpoints.py twin's docstring even notes a plain recursion "would pass through unchanged"). Because line 439 whitelists it as a suppressor, error=_sanitize_response_errors(result["error"]) on a scalar error both evades the guard and forwards the raw diagnostic at runtime. Confirmed false-negative — a scalar error= sink should require a value-replacing helper (_client_safe_error / _sanitize_public_error), not the tree walker.

Disposition: I am not pushing these fixes here. #1077 is a duplicate held for a close-vs-canonical decision, and the identical code is canonical in #831 / #912 at the same head 1a0ce65 — so both gaps exist there too and should be fixed on whichever PR you designate canonical (today that's #831), not on this duplicate. Pushing to #1077 would only invalidate this Copilot review and re-fire the governance gates. Flagging on #831 so the finding isn't lost with this PR.


Generated by Claude Code

Both gaps were found by Copilot on #1077 and verified against the source;
the fix is landed on this branch per the owner's direction (not a new PR).

1. Local status aliases: _status_symbol_table only walked module scope, so a
   5xx code aliased inside a function body (server_failure = HTTP_503; then
   HTTPException(status_code=server_failure, ...)) resolved to None and the
   call was skipped. Resolve each response call against its module scope plus
   every enclosing FunctionDef/AsyncFunctionDef scope. Adds local-alias
   positive (5xx) and negative (4xx) control cases.

2. Scalar pass-through sanitizer: the keyword-sink allowlist accepted the
   whole-tree walkers (_sanitize_response_errors/_sanitize_error_list), which
   return non-container inputs unchanged, so error=_sanitize_response_errors(
   scalar) evaded the guard while forwarding the raw diagnostic. Scalar
   error/error_message sinks now require a value-replacing helper
   (_client_safe_error/_sanitize_public_error); errors (list) keeps
   _sanitize_error_list; the tree walkers remain valid only for whole
   processor results, checked separately. Adds matching controls.

Refs #831 #912 (canonical CWE-209 work); Copilot review on #1077.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQDL89d1xNEm4hijHZMaSf

Copy link
Copy Markdown
Owner Author

Both verified guard false-negatives are now fixed and pushed to this branch (head ea43337), per your direction to land them here via authorized push rather than a competing PR.

1. Local status aliases. _status_symbol_table now resolves per lexical scope: each response call is resolved against module scope plus every enclosing FunctionDef/AsyncFunctionDef body (base= seeds inherited symbols; nested scopes don't leak upward). Added controls — a function-scoped server_failure = status.HTTP_503_...HTTPException(status_code=server_failure, detail=str(exc)) is now flagged, and a function-scoped HTTP_400 alias is correctly not over-flagged.

2. Scalar pass-through sanitizer. The keyword-sink allowlist is now field-aware and value-replacing: scalar error/error_message sinks require _client_safe_error / _sanitize_public_error; errors (list) keeps _sanitize_error_list; the whole-tree walker _sanitize_response_errors is no longer accepted as a scalar-sink sanitizer (it stays valid for whole processor results, checked by the separate pass). Added controls — error=_sanitize_response_errors(result["error"]) is now flagged, and errors=_sanitize_error_list(...) remains allowed.

Verification: tests/unit/test_500_info_disclosure.py7 passed (real-code scan still clean, i.e. no false positives on the guarded endpoints); ruff + black clean.

Note on canonical sync: the identical gaps exist in #831/#912 (same code at 1a0ce65). Since these fixes now live on this branch, they'll need to be folded into #831 (or #1077's disposition resolved) so the canonical unit carries them. The duplicate/close-vs-canonical decision for #1077 remains yours; this push only lands the two guard fixes you authorized.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Quick note on the checks after the ea43337 push:

  • gitleaks (working tree) — pre-existing false-positive, not from this diff. The single finding is uv.lock:5129 (a package sha256: hash matched against the square-access-token rule). This commit only touches tests/unit/test_500_info_disclosure.py; uv.lock is inherited from base, so this reproduces independently of my change. If you want it silenced, the fix is an allowlist entry for uv.lock package hashes in .gitleaks.toml — out of scope for this PR.
  • agent-completion/truth-gate, PR Governance, Canonical issue and evidence, Vercel — unchanged from before: the by-design duplicate-contract governance gates + the Vercel dashboard cancellation, already diagnosed above. Not code defects, not fixed by gaming them.

The two CWE-209 guard fixes you authorized are in and green (test_500_info_disclosure.py: 7 passed). I'll stop echoing the repeating governance re-fires on this head. #1077's close-vs-canonical disposition remains yours.


Generated by Claude Code

@groupthinking

Copy link
Copy Markdown
Owner Author

Independent verification of PR #1077 (CWE-209) — no substantive findings

I picked up #912 as apparently-unclaimed work (canonical PR #831 is closed unmerged), independently re-derived the fix from the acceptance criteria, and only then found PR #1077. Rather than open a competing PR, I converted the work into the independent verification this issue is blocked on. My branch was deleted; no competing PR was opened.

Verified against ea4333797 (PR #1077 head) in a clean worktree.

1. Convergent-implementation evidence

I built my version from #912's text alone, without reading #1077. It converged on the same core fix, including the identical constructor-signature insight:

Capability My independent impl PR #1077
5xx range (500–599), not just == 500
Constructor-aware positional status_code index ✅ — same logic, same rationale
Positional JSONResponse body inspection
src/uvai/ml in scan roots ✅ (_ML_SERVE)
Named status constants (status.HTTP_503_…) _status_symbol_table
Lexically-aliased status resolution
Response error-field taint tracking _iter_response_error_leaks
Returned-exception guard _iter_returned_exception_leaks

Two independent derivations landing on the same constructor-index fix is decent evidence it's the right one. #1077 is a strict superset of what I built — it has four capabilities I lacked and none of mine are missing from it. My work is redundant and I'm dropping it.

2. Test execution

tests/unit/test_500_info_disclosure.py
tests/unit/test_cloud_routes.py
tests/unit/test_code_generator_agent.py
tests/unit/test_real_api_endpoints.py
=> 206 passed, 0 failed, 0 errors

(Needed aiohttp, sqlalchemy, python-dotenv, pydantic-settings installed — these are pre-existing env gaps, unrelated to this PR.)

3. Non-vacuity — the part that actually matters

A green guard proves nothing until you prove it can go red. I injected four regressions, one per claimed capability:

# Injected regression Expected Result
NC-1 detail=str(e) restored in the generated 500 template fail 2 failed
NC-2 HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail=str(e)) fail 1 failed
NC-3 JSONResponse({"error": str(e)}, 500) (positional) fail 2 failed
NC-4 status aliased to a local, then leaked fail 1 failed
all reverted pass 7 passed

Every claimed capability is independently exercised. No vacuous assertions found.

NC-2 and NC-4 are worth calling out: both are invisible to a scanner that only reads integer literals, and both are realistic regression shapes. The symbol-table + enclosing-scope resolution is doing real work.

4. Correctness of the code_generator.py fix

except Exception:
    logger.exception("Generated endpoint failed")
    raise HTTPException(status_code=500, detail="Internal server error")

Correct on all three axes: drops the as e binding so the exception can't be reached, keeps full server-side diagnostics via logger.exception, returns a static client body. Satisfies both "generated FastAPI endpoints" and "retain full server-side exception logging".

5. One observation, not a blocker

_guarded_python_files() scans (_BACKEND, _ML_SERVE); src/agents is not a scan root. I initially flagged this as a coverage gap, then disproved it: code_generator.py's only CWE-209 surface is inside a string template, which AST-scanning the module can't see anyway. #1077 correctly guards it via tests/unit/test_code_generator_agent.py instead — the right tool for the job. Not a finding; recorded so the next reviewer doesn't re-litigate it.

6. Current-state check

Scanning all of src/ with the widened rules finds 0 offenders. Production code is already clean — this PR is closing guard blind spots so the fix can't silently regress, not patching a live leak. Worth stating plainly so severity isn't overstated.


Verdict: no unresolved substantive findings. Guard is comprehensive, non-vacuous, and strictly stronger than main's. I have no changes to request.

Sole caveat: I'm an independent verifier, not a maintainer — this doesn't discharge the human review or provenance-boundary criteria, which remain yours. Flagging one thing for that review: this branch is stale (last updated 2026-08-01) and mergeable is UNKNOWN, so it likely needs a rebase onto current main before merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation python security tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants