HERMES-GIELIE/api
Arsh Kumar Singh d385db69d5
fix(clarify): require stable clarify_id and wait for backend ack so stale responses are rejected
The WebUI clarification popup had a response-delivery failure: users
submitted answers in the popup, but the agent still fell through to the
timeout fallback message.  Three bugs conspired:

1. No stable clarify_id — _ClarifyEntry had no unique identifier, so
   the frontend could not reference a specific pending prompt.  The
   backend used FIFO resolution which silently failed for stale/late
   responses.

2. Frontend hid the card before confirmation — respondClarify() called
   hideClarifyCard(true, 'sent') BEFORE the API call completed.  If the
   backend rejected the response, the card was already gone and the
   user's draft was discarded.

3. Backend lied about success — _resolve_clarify_legacy() returned
   bool(resolved) or not bool(clarify_id).  Since the frontend never
   sent clarify_id, the backend always reported ok:true even when
   nothing was resolved.

Changes:

api/clarify.py:
- _ClarifyEntry now auto-generates a stable clarify_id (uuid4.hex[:12])
- submit_pending() injects clarify_id into the data dict visible to the
  frontend via SSE and polling
- New resolve_clarify_by_id() for O(1) lookup by id instead of FIFO pop

api/routes.py:
- _resolve_clarify_legacy() uses resolve_clarify_by_id when clarify_id
  is provided; returns actual bool result (no more unconditional True)
- _handle_clarify_respond() returns HTTP 409 + {ok:false, stale:true}
  when resolution fails

static/messages.js:
- respondClarify() now sends clarify_id in the POST body
- Waits for a positive backend acknowledgement before hiding the card
- Saves a draft copy before POST and restores it on failure
- On 409/network error: re-enables controls, shows error toast
- Guards against parallel-SSE race where clearing the cache after a
  successful response could erase a newly queued next prompt (codex P1)

tests:
- Updated test_sprint30.py for new ack-before-hide behaviour
- Updated test_clarify_unblock.py for 409 on stale responses

Closes #2639.
2026-05-20 16:35:15 +00:00
..
__init__.py
agent_health.py fix(agent-health): treat stale running gateway as unknown 2026-05-11 23:13:09 +00:00
agent_sessions.py fix: label email gateway sessions 2026-05-17 02:49:25 -07:00
auth.py Add session-bound CSRF token checks 2026-05-18 07:14:26 +08:00
background.py feat(commands): /background, /btw slash commands + undo button + reasoning chip 2026-04-24 01:24:51 +00:00
clarify.py fix(clarify): require stable clarify_id and wait for backend ack so stale responses are rejected 2026-05-20 16:35:15 +00:00
commands.py fix(security): drop unsafe-eval + add jsdelivr to CSP, sanitize plugin error 2026-05-11 17:53:02 +00:00
compression_anchor.py feat(webui): render indexed context metadata 2026-05-19 18:52:50 +00:00
config.py Stage 388: PR #2524 2026-05-20 00:17:48 +00:00
dashboard_probe.py fix(system): allow browser-only dashboard links 2026-05-19 22:47:55 +00:00
extensions.py Opus pre-release follow-ups for PR #1445 2026-05-02 03:49:40 +00:00
gateway_watcher.py release: v0.50.241 (#1293) 2026-04-29 19:54:07 -07:00
goals.py fix(i18n): localize /goal runtime status strings 2026-05-10 15:21:24 +08:00
helpers.py stage-348: apply Opus SHOULD-FIX-pre-merge — add '://' to _SENSITIVE_LOWER_MARKERS 2026-05-13 16:54:36 +00:00
kanban_bridge.py stage-315 absorb: document handle_kanban_* three-valued return contract 2026-05-07 18:52:01 +00:00
metering.py fix: show TPS in assistant message headers 2026-05-04 21:26:43 +00:00
models.py Stage 387: PR #2600 2026-05-19 22:10:20 +00:00
oauth.py fix(oauth): serialize Anthropic env fallback reads 2026-05-07 02:47:19 +00:00
onboarding.py Classify onboarding DNS probe failures consistently 2026-05-15 08:51:30 +08:00
profiles.py fix: route background worker credentials through profile env 2026-05-16 01:02:19 -07:00
providers.py fix: add Grok OAuth provider catalog support 2026-05-18 19:51:01 -07:00
request_diagnostics.py fix: add request wedge diagnostics 2026-05-08 15:37:08 +00:00
rollback.py v0.50.255: Opus follow-ups (4 fixes) + CHANGELOG 2026-05-01 17:19:53 +00:00
routes.py fix(clarify): require stable clarify_id and wait for backend ack so stale responses are rejected 2026-05-20 16:35:15 +00:00
run_journal.py Address run journal replay review 2026-05-16 02:58:34 +00:00
runtime_adapter.py feat(runtime): add runner adapter facade 2026-05-19 12:06:57 -07:00
session_lifecycle.py fix: align WebUI memory commits with CLI boundaries 2026-05-17 05:04:57 -06:00
session_ops.py Show profile home in /status command (refs #463) (#1380) 2026-05-01 04:46:37 +00:00
session_recovery.py fix: audit turn journal terminal collisions 2026-05-12 05:20:06 -07:00
startup.py fix: P0 hotfixes — API regression, code block parser, chmod override 2026-05-01 12:10:48 +00:00
state_sync.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00
streaming.py Stage 388: PR #2598 2026-05-20 00:17:47 +00:00
system_health.py feat: add VPS resource health panel 2026-05-05 17:30:56 +00:00
terminal.py fix: reap terminal shells on shutdown 2026-05-19 04:57:51 -07:00
turn_journal.py fix: lock turn journal appends 2026-05-15 16:39:45 -07:00
updates.py Stage 378: PR #2146 2026-05-17 19:55:09 +00:00
upload.py fix(upload): scope archive extraction to per-session attachment dir 2026-05-18 21:22:02 +03:00
usage.py fix: display canonical cache hit percentage 2026-05-19 02:27:12 -06:00
workspace.py refactor: reduce stale workspace recovery fix 2026-05-12 06:28:35 -06:00
worktrees.py Harden worktree removal safeguards 2026-05-13 09:49:15 +08:00