Skip to content

Release: gateway approval_id fallback (#6168) + update-check guard (#6180) + state-dir test isolation (#6305)#6332

Merged
nesquena-hermes merged 8 commits into
masterfrom
release/stage-6168
Jul 19, 2026
Merged

Release: gateway approval_id fallback (#6168) + update-check guard (#6180) + state-dir test isolation (#6305)#6332
nesquena-hermes merged 8 commits into
masterfrom
release/stage-6168

Conversation

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Release batch (experimental channel) — 3 no-intervention fixes

Batched low-risk backend/test-only fixes. Full gate clean (see below). Tags exp-v0.52.117.

Included PRs

PR Author Change Surface
#6168 @webtecnica Synthesize a non-empty uuid4().hex approval_id when a gateway approval.request omits both approval_id and legacy id (#6008) api/gateway_chat.py (+3) — already gate-certified at this exact head
#6180 @webtecnica Defensive guard: wrap check_for_updates() in POST /api/updates/check in try/except returning a clean 500 (does NOT claim to fix #6086) api/routes.py (+11/-1)
#6305 @pxxD1998 Test-infra: pin HOME/USERPROFILE/LOCALAPPDATA to fixture paths so import-only STATE_DIR probes can't reconcile pytest defaults into real user settings.json tests/test_issue4449_state_dir_contract.py (test-only)

Gate results

  • Full pytest suite (serial, -p no:xdist): 13443 passed, 10 skipped, 0 failed.
    • A single test_static_asset_resolver failure appeared in one earlier run and was root-caused as an operator-timing artifact (git HEAD moved mid-run because the CHANGELOG commit landed while the suite was executing; WEBUI_VERSION reload picked up the new sha). Disproved as a code regression by (a) clean-master detached full suite = 13442 passed / 0 failed, and (b) stage re-run with frozen HEAD = 13443 passed / 0 failed.
  • Codex regression gate: VERDICT: SAFE TO SHIP — "No regression risk found. Core flows intact." (enumerated the full diff, ran focused probes on gateway approval routing, update-check success path, and probe env inheritance).
  • ruff forward gate: clean (0 new violations on added/changed lines).
  • No served-page (static/*) change → browser-smoke gate not applicable.

Attribution

Credit preserved via --no-ff merge commits + Co-authored-by. Thanks @webtecnica and @pxxD1998.

@nesquena-hermes
nesquena-hermes enabled auto-merge (squash) July 19, 2026 17:37
@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This release batch applies three isolated fixes from the experimental channel. No shared state or cross-cutting changes are involved.

  • api/gateway_chat.py — when a gateway approval.request arrives with neither approval_id nor the legacy id field, uuid.uuid4().hex is now synthesized so the approval card is always respondable. Because the respond path resolves the routing by run_id independently, the synthetic id never causes a mismatch.
  • api/routes.pyPOST /api/updates/check now wraps check_for_updates() in a try/except that logs the full traceback via logger.exception and returns a clean 500 through bad(). The success path is unchanged.
  • tests/test_issue4449_state_dir_contract.py — subprocess probes now pin HOME/USERPROFILE/LOCALAPPDATA to fixture-owned paths and clear additional redirect vars, with a new mutation-guard test that confirms the probe cannot reconcile pytest workspace defaults into the real user settings.json.

Confidence Score: 5/5

All three changes are minimal and self-contained with no shared state between them.

The approval_id fallback is a 3-line addition that only runs when both id fields are absent, and the downstream routing is already independent of the id. The update-check guard is purely additive; it cannot change any existing success response. The test changes tighten isolation without touching production code. No issues found across any of the changed paths.

No files require special attention.

Important Files Changed

Filename Overview
api/gateway_chat.py Adds uuid import and a 3-line fallback that synthesizes a uuid4().hex approval_id when both approval_id and legacy id are absent from a gateway approval.request payload. Logic is correct; downstream respond path resolves by run_id independently so the synthetic id is harmless.
api/routes.py Wraps check_for_updates() in a try/except that logs with logger.exception and returns a clean 500 via bad(). Adds info-level logging before and after the call. Success path is unchanged; the guard is purely defensive.
tests/test_issue4449_state_dir_contract.py Pins HOME/USERPROFILE/LOCALAPPDATA to fixture-owned paths in every subprocess probe and clears additional redirect vars; adds a new mutation-guard test that verifies the probe cannot reconcile pytest defaults into the real user settings.json. Test-only change with solid isolation logic.
CHANGELOG.md Prepends three release entries for #6168, #6180, and #6305 to the Fixed section; documentation-only change authored as part of the release process.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant GW as Gateway
    participant WU as WebUI (gateway_chat.py)
    participant UI as Browser UI

    GW->>WU: approval.request event
    Note over WU: Extract approval_id or legacy id
    alt approval_id present
        WU->>WU: use provided id verbatim
    else both absent (new fallback)
        WU->>WU: "approval_id = uuid4().hex"
    end
    WU->>UI: approval card (with non-empty approval_id)
    UI->>WU: POST /api/gateway/approval/respond
    Note over WU: Resolves by run_id (independent of approval_id)
    WU->>GW: approval response routed
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant GW as Gateway
    participant WU as WebUI (gateway_chat.py)
    participant UI as Browser UI

    GW->>WU: approval.request event
    Note over WU: Extract approval_id or legacy id
    alt approval_id present
        WU->>WU: use provided id verbatim
    else both absent (new fallback)
        WU->>WU: "approval_id = uuid4().hex"
    end
    WU->>UI: approval card (with non-empty approval_id)
    UI->>WU: POST /api/gateway/approval/respond
    Note over WU: Resolves by run_id (independent of approval_id)
    WU->>GW: approval response routed
Loading

Reviews (1): Last reviewed commit: "docs(changelog): stamp #6168 approval_id..." | Re-trigger Greptile

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.

WebUI server silently exits on every /api/updates/check and on gateway restart when a stale gateway_state.json is present (fail-closed recovery)

3 participants