Skip to content

feat(sessions): surface blocked and stale session run statuses#92697

Closed
Hidetsugu55 wants to merge 2 commits into
openclaw:mainfrom
Hidetsugu55:hide/feat/session-status-stale-blocked
Closed

feat(sessions): surface blocked and stale session run statuses#92697
Hidetsugu55 wants to merge 2 commits into
openclaw:mainfrom
Hidetsugu55:hide/feat/session-status-stale-blocked

Conversation

@Hidetsugu55

Copy link
Copy Markdown
Contributor

Summary

Adds two session run statuses so stuck and orphaned sessions are recognizable in sessions.list and the Control UI:

  • blocked — the blocked-liveness watchdog now maps to a distinct terminal status instead of being folded into failed. A run that stalled waiting on something is no longer indistinguishable from a genuine failure.
  • stale — a display-only projection computed at sessions.list time for a row that still claims running but has no live-run evidence in this gateway (no Control UI-tracked run, no in-process embedded run for its sessionId/key, no live sub-agent run, not an ACP session, and not updated within a grace window). This is the signature of a run orphaned by a crash or restart. It is never written back to the session store.

Behavior

  • blocked is persisted by the gateway lifecycle mapping (AgentRunTerminalReason "blocked""blocked"). Every place that previously treated blocked-as-failed for behavior keeps that behavior, so this is a surfacing change, not a control-flow change:
    • session rotation reuse (resolveTerminalMainSessionTranscriptRegistryCheck)
    • sub-agent store reconciliation (resolveCompletionFromSessionEntry → error outcome)
    • terminal-status guards (isTerminalSessionStatus in both config and gateway)
    • sub-agent historical vs interrupted run-state derivation
  • stale is derived by projectSessionRowRunStatus, invoked from the existing sessions.list active-run-flags pass. Only the runningstale transition changes a value; every other status passes through untouched. Grace window is 5 minutes, sized so a brief lull between turns never flips a healthy run.
  • Run-status unions widened in lockstep across the gateway (GatewaySessionRow), the session tools (SessionRunStatus), and the Control UI. stale is excluded from the persisted SessionEntry["status"] type so it cannot be written to a store; the lifecycle derivation is typed to only ever yield persistable statuses.
  • Control UI renders blocked with the failed tone and stale with the idle tone (a soft warning, not an alarm). New statusBlocked / statusStale i18n keys added to the English source bundle and propagated to all locales (English fallback, tracked in the locale metadata).

Not in this PR (follow-ups)

  • Localized (non-English) translations of statusBlocked / statusStale — currently English fallback across the 18 non-English locales, which is the standard tracked-fallback state.
  • A Control UI filter facet for the new statuses (rows render and search correctly today; a dedicated filter chip is a natural follow-up).

Tests

  • src/gateway/server-methods/session-active-runs.test.ts (new): projectSessionRowRunStatus — stale projection, every live-run keep-alive signal (tracked run, embedded run by id/key, live sub-agent, ACP), grace window, missing updatedAt, and terminal pass-through.
  • src/agents/subagent-session-reconciliation.test.ts (new): blocked persisted status → error completion, freshness gating, running non-resolution.
  • src/gateway/session-lifecycle-state.test.ts: blocked-liveness lifecycle error → blocked status.
  • src/gateway/session-utils.subagent.test.ts: a blocked registry-only sub-agent run reads as historical (parity with the prior failed-folding).
  • src/agents/tools/sessions-list-tool.test.ts: stale / blocked pass through sessions_list; unknown status values are dropped.
  • ui/src/ui/views/sessions.test.ts: Control UI badge label/tone/aria for stale and blocked.
  • pnpm check --include-test-types green; pnpm check:docs green (broken_links=0); pnpm ui:i18n:check clean for all locales.

Real behavior proof

Behavior or issue addressed: A session row that still claims running but has no live run in this gateway (an orphan from a crash/restart) must be surfaced as stale by sessions.list without being persisted, while a freshly-updated running row and terminal rows are untouched; and a run ended by the blocked-liveness watchdog must persist as blocked rather than failed.

Real environment tested: macOS (Apple Silicon) checkout of this branch, Node v25.9.0, isolated OPENCLAW_STATE_DIR=/tmp/oc-prC-proof. The production functions ran in-process with no test doubles: listSessionsFromStore (gateway row assembly), projectSessionRowRunStatus (the exact per-row projection the sessions.list handler runs, fed by the real listActiveEmbeddedRunSessionIds/Keys), and derivePersistedSessionLifecyclePatch (gateway lifecycle → persisted status).

Exact steps or command run after this patch:

cd ~/repos/oc-worktrees/impl-prC   # this branch
mkdir -p /tmp/oc-prC-proof
OPENCLAW_STATE_DIR=/tmp/oc-prC-proof pnpm exec tsx proof-session-status.harness.ts

The harness builds a real session store with three rows — a running row last updated 6 min ago (past the 5 min grace), a running row updated 30 s ago, and a done row — then runs the sessions.list projection over them with no live runs registered, and separately derives the persisted status for a blocked-liveness lifecycle event and an aborted control event.

Evidence after fix:

## stale projection over real session store (live embedded runs: ids=0 keys=0)
[sessions.list] {"key":"agent:main:fresh","persistedStatus":"running","projectedStatus":"running"}
[sessions.list] {"key":"agent:main:orphaned","persistedStatus":"running","projectedStatus":"stale"}
[sessions.list] {"key":"agent:main:finished","persistedStatus":"done","projectedStatus":"done"}

## gateway lifecycle → persisted status
[lifecycle blocked-liveness] {"status":"blocked"}
[lifecycle aborted control] {"status":"killed"}

Observed result after fix: The orphaned running row (no live evidence, past the grace window) projected to stale, while the freshly-updated running row stayed running and the terminal done row was untouched — so the projection changes exactly the orphaned row and nothing else. The blocked-liveness lifecycle event persisted as blocked; the aborted control event persisted as killed, confirming the new mapping is specific to blocked liveness and not a blanket change.

What was not tested: A full live gateway driving an end-to-end model turn that crashes mid-run and then renders the stale badge in a real browser (the projection and the badge rendering are covered separately by the harness above and the Control UI unit tests); Windows runtime behavior.

Add two run statuses to make stuck and orphaned sessions recognizable in
sessions.list and the Control UI:

- blocked: the blocked-liveness watchdog now maps to a distinct terminal
  status instead of being folded into "failed". Everywhere that treated
  blocked as failed for behavior (session rotation reuse, subagent
  reconciliation, terminal-status guards, subagent historical state) keeps
  the same behavior; only the surfaced status changes.
- stale: a display-only projection computed by sessions.list for rows that
  still claim "running" but have no live run evidence in this gateway (no
  tracked run, no in-process embedded run, no live subagent run, no ACP
  session, and not updated within a grace window). Never persisted.

Wired the projection into the sessions.list active-run-flags pass, widened
the session run status unions (gateway, session tools, Control UI), added
statusBlocked/statusStale i18n keys (English fallback across locales), and
documented both statuses in docs/concepts/session-tool.md.

Tests: new projectSessionRowRunStatus suite, blocked subagent
reconciliation + historical-state parity, blocked liveness lifecycle
mapping, sessions_list status passthrough, and Control UI badge rendering.
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: web-ui App: web-ui gateway Gateway runtime agents Agent runtime and tooling size: L proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 13, 2026
@clawsweeper

clawsweeper Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 30, 2026, 8:23 PM ET / 00:23 UTC.

Summary
The PR adds blocked and display-only stale session run statuses across gateway session listing, persisted lifecycle mapping, session tools, Control UI badges, i18n, docs, and tests.

PR surface: Source +197, Tests +235, Docs +13. Total +445 across 59 files.

Reproducibility: yes. for the review finding at source level: the PR implementation excludes ACP rows from stale projection, while the added session-tool docs do not mention that exception. The feature itself is proof-based rather than a failing current-main bug report.

Review metrics: 1 noteworthy metric.

  • Run-status contract: 1 persisted added, 1 display-only added. The added blocked and stale values are the compatibility-sensitive API and stored-state change maintainers should notice before merge.

Stored data model
Persistent data-model change detected: serialized state: src/agents/tools/sessions-list-tool.test.ts, serialized state: src/gateway/server-methods/session-active-runs.test.ts, serialized state: src/gateway/server-methods/session-active-runs.ts, serialized state: src/gateway/server-methods/sessions.ts, serialized state: src/gateway/session-lifecycle-state.test.ts, serialized state: src/gateway/session-lifecycle-state.ts, and 8 more. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: partial_overlap
Canonical: #39127
Summary: This PR adds coarse blocked/stale status surfacing that partially overlaps the broader gateway session activity and attention-state contract; it does not supersede the canonical design issue or the separate broader implementation candidate.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add real browser or visual artifact proof showing Stale and Blocked badges with private details redacted.
  • Document the ACP stale-status exception in the session-tool docs.
  • Resolve the current merge conflicts and refresh the diff.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body includes useful terminal proof for backend projection/lifecycle behavior, but it does not show the user-visible Control UI Stale and Blocked badges in a real browser or equivalent visible setup. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A real Control UI visual proof would materially verify the new session status badges beyond unit tests. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify sessions.list stale and blocked rows render as Stale and Blocked badges in the Control UI.

Risk before merge

  • [P1] Merging expands the sessions run-status contract with one persisted value and one display/API value; existing clients that exhaustively handle the old set may need compatibility and release-note treatment.
  • [P1] The supplied real behavior proof exercises backend projection/lifecycle mapping in a terminal harness, but it does not show the new Control UI Stale and Blocked badges in a real browser session.
  • [P1] GitHub currently reports the branch as dirty/conflicting, so maintainers need a refreshed mergeable diff before final review.

Maintainer options:

  1. Fix docs, proof, and conflicts before merge (recommended)
    Update the session-tool docs for ACP rows, add real browser proof or an explicit proof override for the badges, resolve the merge conflicts, and then have maintainers accept the new status contract.
  2. Accept the expanded status contract
    Maintainers can intentionally accept the persisted/display status expansion after confirming downstream client compatibility and release-note expectations.
  3. Pause behind the activity-state API
    If maintainers do not want more coarse status values before the broader session activity contract is settled, pause this PR and route the direction through the canonical activity issue.

Next step before merge

  • [P1] Manual review is needed because the branch is conflict-marked, contributor-visible proof is incomplete, and maintainers must explicitly accept the expanded session status contract.

Security
Cleared: No concrete security or supply-chain regression was found; the diff does not change workflows, dependencies, lockfiles, permissions, secrets handling, or downloaded code execution paths.

Review findings

  • [P3] Document the ACP stale-status exception — docs/concepts/session-tool.md:66-70
Review details

Best possible solution:

Land only after the ACP docs exception is fixed, visible UI proof or an explicit proof override covers the badges, conflicts are resolved, and maintainers accept the additive status contract while keeping the broader activity-state API tracked separately.

Do we have a high-confidence way to reproduce the issue?

Yes for the review finding at source level: the PR implementation excludes ACP rows from stale projection, while the added session-tool docs do not mention that exception. The feature itself is proof-based rather than a failing current-main bug report.

Is this the best way to solve the issue?

Mostly yes: deriving stale in sessions.list and keeping it out of persisted state is the right owner boundary, and blocked follows the existing terminal-outcome normalization path. The PR still needs the docs edge case, visible UI proof, conflict resolution, and maintainer acceptance of the additive contract before it is the best mergeable solution.

Full review comments:

  • [P3] Document the ACP stale-status exception — docs/concepts/session-tool.md:66-70
    The implementation keeps ACP session keys running because those runs can live out of process, but the new stale docs list the projection conditions without that exception. Add the ACP exception so API and tool consumers do not expect old ACP rows to become stale.
    Confidence: 0.86

Overall correctness: patch is correct
Overall confidence: 0.82

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 5a73361ed2b3.

Label changes

Label justifications:

  • P2: This is a normal-priority session observability feature with bounded scope but real compatibility and proof gates.
  • merge-risk: 🚨 compatibility: The PR exposes new blocked and stale status values that existing sessions API consumers or stored-status readers may not handle.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes useful terminal proof for backend projection/lifecycle behavior, but it does not show the user-visible Control UI Stale and Blocked badges in a real browser or equivalent visible setup. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +197, Tests +235, Docs +13. Total +445 across 59 files.

View PR surface stats
Area Files Added Removed Net
Source 52 308 111 +197
Tests 6 235 0 +235
Docs 1 13 0 +13
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 59 556 111 +445

What I checked:

Likely related people:

  • clay-datacurve: Commit 7b61ca1 introduced the broad session management and dashboard API foundation that this status work extends. (role: feature introducer; confidence: high; commits: 7b61ca1b0615; files: src/gateway/server-methods/sessions.ts, src/gateway/session-lifecycle-state.ts, src/gateway/server-methods-list.ts)
  • vincentkoc: Live issue metadata assigns the broader session activity contract to this person, and recent history includes gateway/protocol-adjacent work. (role: canonical issue assignee and adjacent contributor; confidence: high; commits: 2b75806197ab; files: packages/gateway-protocol/src/schema/sessions.ts, src/gateway/server-chat.ts, docs/gateway/protocol.md)
  • Val Alexander: Commit 4935e24 added compact Control UI run-status cleanup that the new badges extend. (role: adjacent Control UI run-status contributor; confidence: medium; commits: 4935e24c7a7f; files: ui/src/ui/views/chat.ts, ui/src/ui/chat/status-indicators.ts, ui/src/ui/app-gateway.ts)
  • Fermin Quant: Commit 598aad4 changed the agent-facing sessions_list visibility/docs surface that now needs the widened status values to remain accurate. (role: recent session-tool contributor; confidence: medium; commits: 598aad4f666b; files: src/agents/tools/sessions-list-tool.ts, docs/concepts/session-tool.md)
  • cxbAsDev: Current checkout blame points central session status, lifecycle, docs, and UI badge lines at a recent grafted main snapshot; this is useful routing signal but not full origin proof. (role: recent current-main snapshot contributor; confidence: low; commits: f284ce3b4df7; files: src/gateway/session-lifecycle-state.ts, src/gateway/session-utils.types.ts, src/gateway/server-methods/session-active-runs.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

…tus-stale-blocked

# Conflicts:
#	ui/src/i18n/.i18n/ar.meta.json
#	ui/src/i18n/.i18n/de.meta.json
#	ui/src/i18n/.i18n/es.meta.json
#	ui/src/i18n/.i18n/fa.meta.json
#	ui/src/i18n/.i18n/fr.meta.json
#	ui/src/i18n/.i18n/id.meta.json
#	ui/src/i18n/.i18n/it.meta.json
#	ui/src/i18n/.i18n/ja-JP.meta.json
#	ui/src/i18n/.i18n/ko.meta.json
#	ui/src/i18n/.i18n/nl.meta.json
#	ui/src/i18n/.i18n/pl.meta.json
#	ui/src/i18n/.i18n/pt-BR.meta.json
#	ui/src/i18n/.i18n/th.meta.json
#	ui/src/i18n/.i18n/tr.meta.json
#	ui/src/i18n/.i18n/uk.meta.json
#	ui/src/i18n/.i18n/vi.meta.json
#	ui/src/i18n/.i18n/zh-CN.meta.json
#	ui/src/i18n/.i18n/zh-TW.meta.json
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 13, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 13, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jul 15, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #clawtributors on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui channel: slack Channel integration: slack docs Improvements or additions to documentation extensions: memory-wiki gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: L stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant