Skip to content

Fix Workboard card status persistence#88957

Closed
TurboTheTurtle wants to merge 3 commits into
openclaw:mainfrom
TurboTheTurtle:codex/workboard-persist-running
Closed

Fix Workboard card status persistence#88957
TurboTheTurtle wants to merge 3 commits into
openclaw:mainfrom
TurboTheTurtle:codex/workboard-persist-running

Conversation

@TurboTheTurtle

@TurboTheTurtle TurboTheTurtle commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #88592

Real behavior proof

Behavior or issue addressed: Workboard linked cards could bounce away from an explicit operator status change because stale linked-session lifecycle sync rewrote the card after drag/edit saves. The follow-up fix also preserves the documented contract that fresh linked session/task lifecycle updates still move active todo/running cards to review or blocked, including task payloads that do not provide a valid updatedAt timestamp.

Real environment tested: local OpenClaw checkout on macOS, branch codex/workboard-persist-running, Node 24.15.0, using the production Workboard UI controller functions from ui/src/ui/controllers/workboard.ts.

Exact steps or command run after this patch: ran direct pnpm exec tsx --eval commands that import getWorkboardState, moveWorkboardCard, and syncWorkboardLifecycle; they exercise production-controller scenarios for stale/fresh session lifecycle sync, stale/fresh task lifecycle sync, and the Copilot-reviewed missing-task-timestamp case.

Evidence after fix:

$ pnpm exec tsx --eval '<script importing getWorkboardState, moveWorkboardCard, syncWorkboardLifecycle from ./ui/src/ui/controllers/workboard.ts and exercising stale/fresh session + task lifecycle sync>'
{
  "staleCompletedSessionAfterReload": {
    "finalStatus": "running",
    "finalPosition": 2000,
    "requestMethods": [],
    "updateWasCalled": false
  },
  "freshCompletedSessionAfterMove": {
    "finalStatus": "review",
    "finalPosition": 2000,
    "requestMethods": [
      "workboard.cards.move",
      "workboard.cards.update"
    ],
    "updatePatch": {
      "status": "review"
    }
  },
  "staleCompletedTaskAfterNewerCardUpdate": {
    "finalStatus": "running",
    "requestMethods": [
      "tasks.list"
    ],
    "updateWasCalled": false
  },
  "freshFailedTaskAfterNewerTaskUpdate": {
    "finalStatus": "blocked",
    "requestMethods": [
      "tasks.list",
      "workboard.cards.update"
    ],
    "updatePatch": {
      "status": "blocked"
    }
  }
}
$ pnpm exec tsx --eval '<script importing getWorkboardState and syncWorkboardLifecycle from ./ui/src/ui/controllers/workboard.ts and exercising a completed task without updatedAt>'
{
  "missingTaskTimestampLifecycleSync": {
    "finalStatus": "review",
    "requestMethods": [
      "tasks.list",
      "workboard.cards.update"
    ],
    "updatePatch": {
      "status": "review"
    }
  }
}

Observed result after fix: stale lifecycle events older than the persisted card update no longer issue workboard.cards.update, so the explicit operator change survives reload/new-host state. Fresh completed/failed session and task lifecycle events still issue the expected workboard.cards.update patches. Task payloads without valid timestamps fall back to the previous sync behavior instead of being treated as stale.

What was not tested: no live browser recording was captured; the proof exercises the real local Workboard controller path and request methods directly.

Supplemental validation

  • Replaced the transient host-local manualStatusCardIds override with a timestamp-aware lifecycle guard based on persisted card update time and linked session/task update time.
  • Updated the task timestamp path so the staleness guard only applies to valid positive task timestamps; missing/unparseable task timestamps do not suppress task-driven lifecycle sync.
  • Added controller regressions for stale completed session after edit save, stale completed session after drag, fresh completed session after drag, reload/new-host stale sync, stale completed task, missing task timestamp sync, and fresh failed task lifecycle updates.
  • Preserved the view regression proving returned card state is reflected after save and still appears when the edit modal is reopened.
  • node scripts/run-vitest.mjs ui/src/ui/controllers/workboard.test.ts ui/src/ui/views/workboard.test.ts passed, 83 tests.
  • node scripts/run-vitest.mjs extensions/workboard/src/store.test.ts extensions/workboard/src/gateway.test.ts passed, 75 tests.
  • pnpm check:test-types passed.
  • pnpm lint passed.
  • pnpm run format:check -- ui/src/ui/controllers/workboard.ts ui/src/ui/controllers/workboard.test.ts passed.
  • git diff --check passed.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. size: S labels Jun 1, 2026
@clawsweeper

clawsweeper Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close as superseded: the open maintainer-owned Workboard persistence PR now covers this PR's useful UI/controller changes and adds the missing persisted store-side lifecycle provenance needed for the underlying bug.

Canonical path: Close this branch and continue review on #89600 as the canonical fix for #88592.

So I’m closing this here and keeping the remaining discussion on #89600 and #88592.

Review details

Best possible solution:

Close this branch and continue review on #89600 as the canonical fix for #88592.

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

Yes, source-reproducible: current main's lifecycle sync can emit a status update when linked session/task state changes, and the Workboard store currently accepts status patches without lifecycle provenance. The linked user report gives concrete Control UI edit and drag steps, but I did not run a live browser repro in this read-only review.

Is this the best way to solve the issue?

No. This PR is a useful partial mitigation, but the best fix is the persisted lifecycle provenance/store-side guard plus UI/view coverage represented by #89600.

Security review:

Security review cleared: The diff only touches Workboard UI/controller code and tests, with no dependency, workflow, credential, publishing, or code-execution surface change.

AGENTS.md: found and applied where relevant.

What I checked:

  • Current lifecycle sync path: On current main, syncWorkboardLifecycle builds a workboard.cards.update status patch whenever shouldSyncCardStatus accepts the lifecycle target, so the stale rewrite risk is in the Workboard lifecycle update path. (ui/src/ui/controllers/workboard.ts:1624, c2d7b4a486b1)
  • Persistent store boundary: Current main's WorkboardStore.updateCard accepts normalized status patches without any lifecycle-status provenance check, which is the persisted boundary this PR does not modify. (extensions/workboard/src/store.ts:2570, c2d7b4a486b1)
  • This PR's patch shape: The submitted diff adds sourceUpdatedAt and shouldSkipStaleLifecycleStatusSync in the UI controller plus selected-option rendering, but it has no Workboard store, SQLite schema, or browser E2E coverage. (ui/src/ui/controllers/workboard.ts, ab08180590c0)
  • Canonical superseding PR: Fix Workboard status persistence #89600 is open, maintainer-authored, explicitly says it supersedes this approach, and records/persists metadata.lifecycleStatusSourceUpdatedAt so stale Gateway writes are handled at the store boundary. (08182e24d89f)
  • Canonical diff covers the missing boundary: The superseding PR diff adds persisted lifecycle provenance fields, store-side stale lifecycle status guards, and a Workboard browser E2E test for status persistence. (08182e24d89f)
  • Related user report remains owned by the canonical PR: The underlying Workboard bug report is still open and describes card edits not persisting and drag-to-running bouncing in Control UI; the canonical PR closes that user report.

Likely related people:

  • BunsDev: BunsDev is assigned on this PR, authored the open canonical Workboard status-persistence PR, and authored the recently merged Workboard movement-control PR that touched the same view surface. (role: likely follow-up owner; confidence: high; commits: 08182e24d89f, be336cc1e489; files: ui/src/ui/views/workboard.ts, ui/src/ui/views/workboard.test.ts, extensions/workboard/src/store.ts)
  • Vincent Koc: Current-main blame and recent commits on the Workboard controller/store paths point to recent local maintenance of the affected lifecycle and store code. (role: recent area contributor; confidence: medium; commits: 7cbdebc4edee, f02c1209aa2d, 2a3421a0da2e; files: ui/src/ui/controllers/workboard.ts, ui/src/ui/views/workboard.ts, extensions/workboard/src/store.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against c2d7b4a486b1.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. 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: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jun 1, 2026
@TurboTheTurtle TurboTheTurtle force-pushed the codex/workboard-persist-running branch from 5116e7e to cbb0836 Compare June 1, 2026 06:44
@TurboTheTurtle

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 1, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 1, 2026
@TurboTheTurtle

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 1, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 1, 2026
@TurboTheTurtle

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 2, 2026
@BunsDev BunsDev self-assigned this Jun 2, 2026
@TurboTheTurtle

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

Re-review progress:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses Workboard cards “bouncing” back to lifecycle-driven statuses after an explicit operator change (drag/edit), by adding a timestamp-based guard to ignore stale lifecycle updates. It also fixes the edit modal so persisted card values (status/priority/agent/session) reliably render as selected when reopening the modal.

Changes:

  • Add sourceUpdatedAt to computed lifecycle data and skip status sync when lifecycle updates are older than the card’s persisted updatedAt.
  • Ensure edit-modal <select> fields reflect draft values on re-render/reopen by explicitly selecting the matching <option>.
  • Add regression tests covering stale vs fresh lifecycle sync behavior for both linked sessions and linked tasks.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
ui/src/ui/views/workboard.ts Ensures edit modal selects render the current draft value as selected.
ui/src/ui/views/workboard.test.ts Adds a regression asserting saved card values are shown when reopening the edit modal.
ui/src/ui/controllers/workboard.ts Introduces sourceUpdatedAt and a staleness guard to prevent outdated lifecycle sync from overwriting newer card updates.
ui/src/ui/controllers/workboard.test.ts Adds controller tests for stale/fresh lifecycle sync across edit saves, drags, reloads, and task updates.

Comment thread ui/src/ui/controllers/workboard.ts
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 2, 2026
@TurboTheTurtle

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. 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 3, 2026
@BunsDev

BunsDev commented Jun 4, 2026

Copy link
Copy Markdown
Member

Closing this as superseded by #89600 plus follow-up #90067.

#89600 landed the persisted lifecycle provenance/UI/store fix for #88592, and #90067 covered the final bulk-update safety finding: stale lifecycle suppression no longer mutates a shared bulk patch. This PR was a useful partial attempt, but it used generic update freshness and did not cover persisted/store-side stale writes or the shared bulk patch isolation path.

Thanks for the report/fix attempt.

@BunsDev BunsDev closed this Jun 4, 2026
@TurboTheTurtle TurboTheTurtle deleted the codex/workboard-persist-running branch June 4, 2026 05:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M 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.

bug(workboard): Control UI card settings don't persist + drag to running fails

3 participants