Commit Graph
6 Commits
Author SHA1 Message Date
zicochaosandnesquena-hermes a6b187fc84 refactor(routes): extract the 585-line GET /api/session handler to _handle_session_get (#7340)
* refactor(routes): extract the 585-line GET /api/session handler to _handle_session_get

Pure move out of handle_get's if/elif chain into a named module-level handler, matching the pattern the other ~200 routes already use. Body is verbatim (one-level dedent only); AST identity of the moved statements verified; no behavior change — the GET /api/session test slice passes identically before and after.

* test: repoint four source-window tests to _handle_session_get

The moved block's source-window extractors (chat_start synthesiser/read-only
pins, regressions runtime-streaming-state window, issue1436 load-path
markers, security-redaction inspect) now anchor on the extracted handler;
assertions unchanged.

* test: repoint messaging-session loader pin to _handle_session_get

---------

Co-authored-by: nesquena-hermes <nesquena+hermes@gmail.com>
2026-09-10 12:49:14 -07:00
nesquena-hermesandfranksong2702 cf7eb48e56 Release exp-v0.52.197: preserve api_content for agent replay (#6757, @franksong2702)
Ships PR #6757 with a maintainer hardening pass folded in (authorship preserved).

Preserves the exact provider-facing reply text (api_content) through the internal
session store for byte-accurate agent replay, while guaranteeing it never reaches
a browser: every client-facing surface strips it via the public projection.

Maintainer fixes (2 defects my adversarial re-gate reproduced):
- Selective session redaction restored: only transcript fields are scrubbed;
  operational fields (e.g. workspace path) pass through unchanged, so a path
  containing credential-shaped text is no longer masked into an invalid path.
- Runner-backed SSE relay now projects payloads before emit, closing an
  api_content leak through _stream_runner_run_events.
+5 regression tests. Codex adversarial re-gate: SAFE TO SHIP. Full suite clean.

Co-authored-by: franksong2702 <franksong2702@users.noreply.github.com>
2026-08-11 02:10:21 +00:00
Rod Boev 11eed2af54 fix(session): harden cron branch source gate (#5477) 2026-07-04 16:41:15 -04:00
Rod Boev cbc164de0c feat(#5477): fork read-only cron sessions 2026-07-04 16:38:27 -04:00
Rod Boev 9e13ec9e03 fix(#5498): prevent deleted WebUI sessions from resurrecting from state.db 2026-07-03 23:05:44 -04:00
nesquena-hermesandmerodahero 31a01e8adf fix(routes): claim CLI/TUI/Desktop sessions on POST, not just GET (salvage of #4153)
CLI/TUI/Desktop sessions were *recreated* on every POST to /api/chat/start
instead of *claimed*, because the claim/synthesis logic only ran on the GET
stub path. GET /api/session already synthesized a read-only stub from
state.db, but POST /api/chat/start unconditionally 404'd on any session_id
without a WebUI JSON sidecar — and the frontend 404 handler then ran its
empty-state self-heal, stripping the URL and silently discarding the user's
typed message.

This closes the GET/POST asymmetry by routing both endpoints through a new
shared helper, _claim_or_synthesize_cli_session, that materialises a
WebUI-owned Session on first write (via synth.save()).

Preserved guards:
- Denylist of foreign-owned sources via _is_claimable_cli_source:
  {claude_code, cron, external_agent, gateway, messaging, unknown}; cli/tui/
  desktop fall through to CLAIMABLE.
- The not_claimable arm returns 403 (NOT 404) and never reaches synth.save()
  (ownership guard). 403-vs-404 matters: the frontend 404 handler runs the
  empty-state self-heal that strips the URL, so a legitimately-listed
  read-only session must surface a refusal instead of vanishing.
- created_at mapping from state.db is load-bearing (Session.save() doesn't
  touch created_at), so claimed sidecars no longer sort as "Jan 1 1970".
- The 500 path uses _sanitize_error so a raw OSError can't leak the sidecar
  filesystem path.
- The #2782 deleted-WebUI-session 404 self-heal contract is preserved via
  _session_index_marks_was_webui.
- The GET path's _session_visible_to_active_profile gate is preserved.

Polish over the original PR:
- Test docstring rationale corrected re: updated_at — Session.save() defaults
  touch_updated_at=True so the claimed sidecar's updated_at is stamped to
  "now" regardless; only created_at is preserved. Assertions unchanged.
- touch_updated_at=True default kept (a claimed session jumps to "just now",
  which is the desired UX); no test pins persisted updated_at to the state.db
  value.
- Added a path-leak assertion to the 500-sanitisation test: the sanitized
  string must not contain a '/' segment from the session-store root.

Salvage of #4153.

Co-authored-by: merodahero <merodahero@users.noreply.github.com>
2026-06-28 07:43:46 +00:00