Add stop_reason field to plan_status (Proposal 114-I1)#244
Merged
Conversation
Agents can now distinguish user-initiated stops from actual failures: stop_reason is "user_requested" when plan_stop was called, null for real errors. Computed from existing stop_requested DB column — no migration needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The frontend now uses stop_reason to distinguish user-initiated stops from actual failures across all views: - /plan/meta endpoint includes stop_reason in response - Plan detail page shows "stopped" in status bar (initial + polled) - Plan list shows orange "stopped" chip instead of red "failed" - Dashboard recent tasks show "Stopped" label with orange dot Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document what was actually implemented vs proposed: minimal stop_reason vocabulary (user_requested vs null), no DB changes needed, frontend coverage beyond original MCP-only scope. Note I2 as prerequisite for richer stop_reason values. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a plan is stopped by the user, the status bar previously showed "stopped · 42% · Stop requested by user." — the progress message is redundant since "stopped" already communicates user intent. Now shows just "stopped · 42%". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The PlanItem admin list view now displays "stopped" (orange) instead of "failed" when stop_requested is true, matching the frontend behavior. The DB filter still operates on the raw state column. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace computed stop_reason/display_state_name logic with proper state semantics: plan_stop now transitions to PlanState.stopped instead of PlanState.failed, and the stop_reason field is removed from API responses. plan_retry and plan_resume accept both failed and stopped states. Includes DB migration to add 'stopped' to PostgreSQL planstate enum across all three startup paths (mcp_cloud, worker, frontend). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update cross-reference table, priority table, I2/I3/I8 descriptions to reflect Option A (PlanState.stopped) instead of the superseded Option B (stop_reason field). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The PostgreSQL enum type is named `taskstate` (from the original `TaskState` Python class), not `planstate` (the renamed class). The migration silently failed, so `'stopped'` was never added to the enum, causing Internal Server Error on plan stop. Try both type names to support existing and fresh databases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The worker's post-pipeline logic always set PlanState.failed for non-completed plans, even when the user requested the stop. Now checks stop_requested and uses PlanState.stopped for user stops. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The run_via_database.html progress poller only knew about pending, processing, completed, and failed. The new stopped state fell through to the unhandled-status error path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jinja indentation caused extra whitespace between "Status:" and the
state name. Use {%- whitespace control to produce clean single-space
output like "Status: stopped · 23%".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inline all Jinja tags on one line to avoid whitespace-stripping eating the space after "Status:". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
inline-flex collapses whitespace between text nodes. Wrap "Status:" in its own span and add gap: 0.3em to the flex container. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- planexe_mcp_interface.md: add stopped to state list, transitions, terminal states, caller contract, error codes, and recovery guidance - autonomous_agent_guide.md: add stopped to state monitoring section - proposal 87: update deferred stopped-state notes as implemented Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Note taskstate vs planstate enum type name issue - Note worker post-pipeline finalization fix - Add all affected files including docs and run_via_database.html - Update proposal 87 overlap reference Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update context: two sessions (12 plans total), not just one - Add I10: silent partial failures in completed plans - Enhance I2 with recoverable boolean suggestion - Add agent perception section (8.5/10 rating, strengths, trust gaps) - Add evolution table across sessions - Update cross-reference and priority tables Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New issue from v2 agent perception feedback: completed plans may have empty or stub-quality sections with no quality_summary signal. Also updated I2 description to mention the recoverable field. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
stop_reasonfield toplan_statusresponse so agents can distinguish user-initiated stops ("user_requested") from actual failures (null)stop_requestedDB column — no migration needed, non-breaking (new optional field)mcp_cloudandmcp_localto document the new fieldChanges
mcp_cloud/tool_models.pystop_reasonfield onPlanStatusSuccessandPlanStatusOutputmcp_cloud/handlers.pystop_reasonfromstate+stop_requestedmcp_cloud/schemas.pystop_reasonmcp_local/planexe_mcp_local.pymcp_cloud/tests/test_plan_status_tool.pyfrontend_multi_user/src/app.py/plan/metaincludesstop_reason; plan list + dashboard show "stopped"frontend_multi_user/templates/plan_iframe.htmlfrontend_multi_user/templates/plan_list.htmlfrontend_multi_user/templates/index.htmldocs/proposals/114-...mdTest plan
python -c "import ast; ast.parse(open('mcp_cloud/tests/test_plan_status_tool.py').read())"cd mcp_cloud && python -m pytest tests/test_plan_status_tool.py -vplan_statusreturnsstop_reason: "user_requested"afterplan_stopplan_statusreturnsstop_reason: nullfor actual failures and non-failed states🤖 Generated with Claude Code