4 Commits

Author SHA1 Message Date
LZH-YS1998 a24cbea4d8 fix: never let a parked approval prompt implicitly consume plain chat
A task_user_input checkpoint created by an approval escalation (payload
runtime_v2.permission_requests non-empty) used to capture the next plain chat
message in the session as its answer. With deferred approval cards now staying
pending indefinitely (c9018000), that implicit capture would swallow every
later conversation message into the approval reply.

Permission prompts are decided through their approval card, whose reply always
carries an explicit response_to_checkpoint_id; a plain message now falls
through to normal turn processing and the card stays pending and clickable.
Waits without a permission request (agent asked the user a question) keep
accepting typed answers unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:38:33 +08:00
LZH-YS1998 8e048f0d5b Reapply "fix: enforce task-wait checkpoint lifecycle and stop UI probe from rescanning tasks table"
This reverts the revert e1c28c38, re-landing d502d66c.

Forensics on the project 000 incident show the original revert was a
misattribution: the failures observed at 19:00-19:21 ran on a server started
before the fix was committed (19:59), and the 20:27 failure was the separate
company_work_item_plan schema collision (fixed in the previous commit), which
this change never claimed to cover.

Re-landing is also now required by c9018000: the deferred approval-card click
path rewrites the reply to target the parked AWAITING_HUMAN checkpoint and
resumes through _resume_task_checkpoint — without this change that resume hits
the empty-task-list + MULTI_AGENT value-alias bug and returns an empty reply
on company tasks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:34:23 +08:00
LZH-YS1998 e1c28c3889 Revert "fix: enforce task-wait checkpoint lifecycle and stop UI probe from rescanning tasks table"
This reverts commit d502d66c60.
2026-07-07 20:30:17 +08:00
LZH-YS1998 d502d66c60 fix: enforce task-wait checkpoint lifecycle and stop UI probe from rescanning tasks table
A company-mode review left a pending task_user_input checkpoint behind: the
runtime carried the paused work item forward via approval-card grants and a
fresh review attempt without ever replying through the engine checkpoint. The
orphan row then captured the user's next chat message and resumed through the
deprecated multi-agent path with an empty task list, returning an empty reply.

Invariants added:
- write side: when a task settles (done/failed/cancelled) its pending
  task_user_input/task_peer_wait checkpoints are superseded
- read side: checkpoint matching lazily resolves rows whose task settled or
  whose linked work item reached a terminal phase (heals existing dirty DBs)
- resume: the primary task is always part of the resumed set; the
  MULTI_AGENT/COMPANY_MODE value-alias no longer routes company checkpoints
  into _execute_multi_agent (which silently returned "" on empty task lists)

Perf: get_latest_pending_checkpoint_for_session is called per task on every
UI sync tick, and its parent-session resolution loaded and JSON-parsed the
entire tasks table each time (24MB with inline artifact blobs) — a full core
pegged at 100% and the event loop starved so replies never surfaced. Now a
no-live-checkpoints fast path returns immediately, and the resolution uses a
targeted session_id query backed by a new tasks(session_id) index.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 19:59:26 +08:00