Skip to content

Workspaces: add version history and exact restore#101900

Open
100yenadmin wants to merge 4 commits into
openclaw:mainfrom
100yenadmin:feat/dashboard-time-travel
Open

Workspaces: add version history and exact restore#101900
100yenadmin wants to merge 4 commits into
openclaw:mainfrom
100yenadmin:feat/dashboard-time-travel

Conversation

@100yenadmin

@100yenadmin 100yenadmin commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Workspace operators had undo but no inspectable version history: they could not preview an older snapshot, understand structural changes, or restore the exact version they reviewed. The original #101900 implementation was built on the superseded Dashboard stack and retained race, corruption, attribution, and sparse-history correctness issues.

Why This Change Was Made

This rebuild adds SQLite-backed history list/get/restore methods to the current Workspaces store and a history panel in the Workspaces UI. Restore is bound to the exact snapshot version the operator confirmed and executes inside the synchronous write transaction; the pre-restore workspace remains undoable and the resulting workspace version remains monotonic.

Corrupt rows are isolated instead of blocking valid older history. Change summaries use accurate creator/provenance terminology, distinguish move from resize, and report first-seen evidence as exact, bounded, or unknown when coverage is sparse. The UI documents the structural diff surface rather than claiming exhaustive content diffs.

The recovery also moves extension-owned synchronous SQLite queries through typed Kysely helpers exposed on the focused plugin-state SDK subpath.

User Impact

  • Operators can browse stored workspace versions and preview structural changes.
  • Restore always targets the exact confirmed snapshot, even if another writer changes the workspace after preview.
  • Damaged history rows do not hide or redirect valid restore choices.
  • Restore failures keep the panel open and do not falsely present success.
  • Current approval decisions remain protected from historical rollback.

Evidence

  • Rebased onto upstream main at 7da28f370476ef53c025f37339c1b128f6ed3933, captured 2026-07-13T09:16:13Z; conflicts preserve current main's private store-helper types and reconcile the SDK/API baselines to the feature's exact three intentional callable exports. A stale moving-main budget-only commit was dropped.
  • Final-head focused Vitest: 7 files / 96 tests passed across store, gateway, history model, widget cell, plugin page, and workspace view.
  • Plugin SDK API-baseline verification and the complete surface report passed: 10,648 public exports, 5,361 callable exports, 3,282 deprecated exports, and 210 wildcard exports.
  • Scoped type-aware oxlint, formatting, docs formatting, and git diff --check passed on the feature bundle.
  • Repository-wide validation remains GitHub Actions' responsibility.
  • Repository autoreview: clean, no accepted/actionable findings.
  • No GitNexus refresh or reset was performed.

Closes #101822.

@100yenadmin
100yenadmin requested a review from a team as a code owner July 7, 2026 22:49
@100yenadmin

Copy link
Copy Markdown
Contributor Author

On dependency-guard: inherited from the unmerged Wave 1 base (#101098) — no new dependency. Read-only surface (history list/get + UI); restore reuses the existing undo. Verified by the submitting orchestrator's own gate: extensions/dashboard 83 tests, UI dashboard+plugin+cell 138 tests, ui:build + full type-aware oxlint clean.

@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Dependency graph guard cleared

This PR no longer has blocked dependency graph changes. A future dependency graph change requires a fresh /allow-dependencies-change comment after the guard blocks that new head SHA.

  • Current SHA: e9fc1b6513037bce23772c71b9359979dad30683

@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 13, 2026, 5:51 AM ET / 09:51 UTC.

Summary
Adds SQLite-backed workspace history list, snapshot preview, structural diffs, provenance details, and exact-version restore in the Workspaces UI, plus three synchronous Kysely helpers on the public plugin-state SDK subpath.

PR surface: Source +1140, Tests +649, Docs +17, Generated 0, Other -1. Total +1805 across 23 files.

Reproducibility: not applicable. This PR adds a new Workspaces capability rather than repairing an established failing behavior. Source and tests provide a clear validation model, but they are not a current-main bug reproduction.

Review metrics: 3 noteworthy metrics.

  • Public plugin SDK callables: 3 added. Each new callable becomes a compatibility-sensitive third-party plugin contract rather than an implementation-local helper.
  • Workspace gateway methods: 3 added. History list, get, and restore expand the operator-facing RPC surface and require authorization and upgrade review.
  • Persisted restore paths: 1 new exact-version path. The new mutation rewrites stored workspace state while preserving approvals and monotonic versioning, which warrants real upgrade and failure proof.

Stored data model
Persistent data-model change detected: database schema: ui/src/lib/workspace/history.test.ts, serialized state: ui/src/lib/workspace/history.test.ts, serialized state: ui/src/lib/workspace/history.ts, unknown-data-model-change: ui/src/lib/workspace/history.test.ts, unknown-data-model-change: ui/src/lib/workspace/history.ts, vector/embedding metadata: extensions/workspaces/src/store.test.ts, and 1 more. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #101822
Summary: This PR is the implementation candidate for the canonical workspace-history issue; the roadmap tracker is broader, while the Teams PR is adjacent work sharing an authorization integration seam.

Members:

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

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup 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 redacted current-head browser proof covering preview, exact restore, monotonic versioning, and a failed restore that leaves the panel open.
  • Obtain an explicit maintainer decision on the three public plugin SDK exports and narrow them if general-purpose exposure is not intended.
  • Resolve the current control-ui-i18n and checks-node-compact-small-2 failures, then refresh the review on the resulting head.

Proof guidance:

  • [P1] Needs real behavior proof before merge: Only automated tests and static checks are supplied; add a redacted browser recording showing history open, snapshot preview, exact restore, monotonic result, and visible restore failure, then update the PR body to trigger review or ask for @clawsweeper re-review.

Risk before merge

  • [P1] The three new plugin-state-runtime functions become supported third-party plugin API and may be difficult to narrow or remove after release; green API-baseline checks do not decide whether this is the intended permanent abstraction.
  • [P1] Restore rewrites persisted workspace state and approval-sensitive fields, so unit coverage alone does not prove fresh-install and realistic upgrade behavior or demonstrate recovery from a failed restore in the browser.
  • [P1] If the scoped Teams work lands, historical snapshot reads must use the same exact-resource projection as live reads or they could expose content omitted from the current authorized workspace view.
  • [P1] The current head still reports failures in control-ui-i18n and checks-node-compact-small-2; their causes must be resolved or shown to be unrelated before merge.

Maintainer options:

  1. Narrow and prove before merge (recommended)
    Approve the feature direction, narrow the public SDK seam if required, resolve current checks, and add real browser plus Teams-composition proof.
  2. Accept the API and state risk
    Merge the current contract only after maintainers explicitly accept the three public helpers and the restore/authorization upgrade obligations.
  3. Pause pending roadmap sponsorship
    Keep the PR open or close it later if maintainers do not want version history or another permanent plugin SDK expansion now.

Next step before merge

  • [P1] A maintainer should decide the permanent plugin SDK boundary and feature sponsorship; afterward the contributor must provide real browser proof and clear the current failing checks.

Maintainer decision needed

  • Question: Should Workspaces version history ship with these three general synchronous Kysely helpers as permanent public plugin SDK exports, or must the storage seam be narrowed before merge?
  • Rationale: The feature is new user-facing product surface and the implementation expands a compatibility-sensitive public SDK; tests cannot determine the intended long-term API boundary.
  • Likely owner: steipete — The unresolved choice concerns supported plugin SDK and product surface rather than a mechanical branch repair.
  • Options:
    • Approve a narrower SDK seam (recommended): Keep the Workspaces feature but replace the three general helpers with the smallest purpose-specific plugin-state contract that satisfies this store.
    • Accept the proposed exports: Treat the three synchronous Kysely helpers as supported third-party plugin API and retain the accompanying documentation and baseline changes.
    • Pause the feature: Leave version history unmerged until the broader Workspaces roadmap and storage API direction are explicitly sponsored.

Security
Cleared: No standalone security or supply-chain regression is established in this head; the documented Teams composition requires an authorization follow-through before both features ship together.

Review details

Best possible solution:

Keep exact-version restore transactional and approval-preserving, but land it only with redacted browser proof, an explicit authorization test for the Teams composition, and a maintainer-approved narrow SDK contract—keeping the Kysely helpers internal or purpose-specific if general public exports are not intended.

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

Not applicable: this PR adds a new Workspaces capability rather than repairing an established failing behavior. Source and tests provide a clear validation model, but they are not a current-main bug reproduction.

Is this the best way to solve the issue?

Unclear: transactional exact-version restore is a strong implementation shape, but the general public SDK expansion is not proven to be the narrowest maintainable owner boundary and still needs maintainer approval.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 9ea4b167fad2.

Label changes

Label changes:

  • add merge-risk: 🚨 session-state: Exact restore mutates persisted workspace history and must not restore stale approvals, target the wrong snapshot, or corrupt monotonic state.

Label justifications:

  • P2: This is a substantial but bounded Workspaces improvement with limited blast radius and no demonstrated emergency regression.
  • merge-risk: 🚨 compatibility: The PR adds three permanent public plugin SDK functions and new gateway behavior that shipped plugins or future upgrades may depend on.
  • merge-risk: 🚨 session-state: Exact restore mutates persisted workspace history and must not restore stale approvals, target the wrong snapshot, or corrupt monotonic state.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Only automated tests and static checks are supplied; add a redacted browser recording showing history open, snapshot preview, exact restore, monotonic result, and visible restore failure, then update the PR body to trigger review or ask for @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +1140, Tests +649, Docs +17, Generated 0, Other -1. Total +1805 across 23 files.

View PR surface stats
Area Files Added Removed Net
Source 10 1173 33 +1140
Tests 7 653 4 +649
Docs 3 18 1 +17
Config 0 0 0 0
Generated 1 2 2 0
Other 2 2 3 -1
Total 23 1848 43 +1805

What I checked:

  • Exact restore implementation: The branch adds history list/get/restore operations to the SQLite-backed Workspaces store, with restore performed against the selected version while retaining monotonic workspace versions and current approval state. (extensions/workspaces/src/store.ts:45, e9fc1b651303)
  • Gateway API surface: The branch registers three new Workspaces gateway methods: workspaces.history.list, workspaces.history.get, and workspaces.history.restore, with list/get read-scoped and restore write-scoped. (extensions/workspaces/src/gateway.ts:804, e9fc1b651303)
  • Public plugin SDK expansion: The existing plugin-state-runtime subpath gains three callable exports for synchronous Kysely compilation and execution, making the implementation choice a third-party plugin compatibility contract. (src/plugin-sdk/plugin-state-runtime.ts:4, e9fc1b651303)
  • User-visible history flow: The Control UI adds history loading, snapshot selection, structural comparisons, restore confirmation and failure handling, and provenance display for workspace widgets. (ui/src/pages/plugin/workspace-view.ts:123, e9fc1b651303)
  • Focused automated coverage: The branch adds or updates store, gateway, history-model, workspace-view, widget-cell, plugin-page, and workspace-state tests; the PR reports 96 focused tests passing on the current head. (extensions/workspaces/src/store.test.ts:64, e9fc1b651303)
  • Real behavior proof gap: The PR body supplies test, lint, type, SDK-surface, and autoreview results but no screenshot, recording, live browser output, or linked artifact showing the history panel and restore behavior after the fix. (ui/src/pages/plugin/workspace-view.ts:123, e9fc1b651303)

Likely related people:

  • 100yenadmin: The contributor also drove the merged Workspaces foundation and the related Workspaces roadmap, history, and Teams design, giving them substantial prior domain context beyond this proposal. (role: Workspaces feature owner; confidence: high; commits: cffebbb0f72e, 70a3ed14f4fd, fbffa878bb3a; files: extensions/workspaces/src/store.ts, extensions/workspaces/src/gateway.ts, ui/src/lib/workspace/history.ts)
  • steipete: Recent repository history and release ownership connect this maintainer to core/plugin contract decisions; the unresolved choice is whether these SDK exports and the feature belong in the supported surface. (role: likely API and product decision owner; confidence: medium; files: src/plugin-sdk/plugin-state-runtime.ts, scripts/plugin-sdk-surface-report.mjs)
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.
Review history (12 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-08T04:33:02.084Z sha 876d5a3 :: needs real behavior proof before merge. :: [P1] Move dashboard state out of JSON sidecars | [P1] Remove or approve the dependency graph change | [P2] Skip invalid snapshots when fetching history | [P3] Remove the local carve spec from the branch
  • reviewed 2026-07-09T21:01:17.476Z sha 4fc4e91 :: needs real behavior proof before merge. :: [P1] Move dashboard state out of JSON sidecars | [P1] Remove or approve the dependency graph change | [P2] Skip invalid snapshots when fetching history | [P3] Remove the local carve spec from the branch
  • reviewed 2026-07-09T21:10:33.195Z sha 4fc4e91 :: needs real behavior proof before merge. :: [P1] Move dashboard state out of JSON sidecars | [P1] Remove or approve the dependency graph change | [P2] Skip invalid snapshots when fetching history | [P3] Remove the local carve spec from the branch
  • reviewed 2026-07-09T23:19:22.101Z sha e78e38d :: needs real behavior proof before merge. :: [P1] Move dashboard state out of JSON sidecars | [P1] Remove or approve the dependency graph change | [P2] Skip invalid snapshots when fetching history | [P3] Remove the local carve spec from the branch
  • reviewed 2026-07-10T08:50:42.372Z sha 447b2c4 :: needs real behavior proof before merge. :: [P1] Move dashboard state out of JSON sidecars | [P1] Remove or approve the dependency graph change | [P2] Skip invalid snapshots when fetching history | [P3] Remove the local carve spec from the branch | [P1] Filter historical snapshots for the requesting operator
  • reviewed 2026-07-12T20:38:57.926Z sha b27f4fc :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-13T02:24:20.042Z sha 68dea4c :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-13T07:17:36.441Z sha f02040f :: needs real behavior proof before merge. :: none

@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: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 7, 2026
@100yenadmin

Copy link
Copy Markdown
Contributor Author

Security (cross-PR, surfaced by the downstream Boardstate extraction's audit — SPEC invariant I6): private-tab leak via workspace history, emergent when this PR and #101913 both land.

Neither branch has the hole in isolation (this one has no private tabs yet; that one has no history endpoint). But once both are on main, history.get returns snapshots unfiltered, so a non-owner can read another operator's private tab out of any older version — bypassing the live-read filter.

Fix at integration: route the history.get snapshot through the same filterWorkspaceForOperator(doc, operatorId) that respondDoc uses for live reads (the version field stays the real/unfiltered value so client change-dedup is unaffected). Reference: the extracted Boardstate applies exactly this in its dashboard.workspace.history.get handler.

Flagging on both PRs so it isn't lost at merge. (The other two audit findings — approval-elevation via workspace.replace, and CSP on widget-route 404s — were single-branch and are fixed directly in #101094 and #101098.)

@100yenadmin
100yenadmin force-pushed the feat/dashboard-time-travel branch from 447b2c4 to b27f4fc Compare July 12, 2026 20:29
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation scripts Repository scripts plugin: workspaces Agent-composable Workspaces plugin labels Jul 12, 2026
@100yenadmin 100yenadmin changed the title Dashboard: workspace time-travel + blame Workspaces: add version history and exact restore Jul 12, 2026
@github-actions github-actions Bot removed the dependencies-changed PR changes dependency-related files label Jul 12, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 12, 2026
@100yenadmin
100yenadmin force-pushed the feat/dashboard-time-travel branch 2 times, most recently from 68dea4c to f02040f Compare July 13, 2026 06:32
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 13, 2026
@100yenadmin
100yenadmin force-pushed the feat/dashboard-time-travel branch from f02040f to 53be35a Compare July 13, 2026 09:04
@100yenadmin
100yenadmin force-pushed the feat/dashboard-time-travel branch from 53be35a to e9fc1b6 Compare July 13, 2026 09:30
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. label Jul 13, 2026
@clawsweeper

clawsweeper Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

@100yenadmin thanks for the PR. ClawSweeper is still waiting on real behavior proof before this can move forward.

Useful proof can be a screenshot, short video, terminal output, copied live output, linked artifact, or redacted logs that show the changed behavior after the fix. Please redact private tokens, phone numbers, private endpoints, customer data, and anything else sensitive.

Once proof is added to the PR body or a comment, ClawSweeper or a maintainer can re-check it.

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 docs Improvements or additions to documentation 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. plugin: workspaces Agent-composable Workspaces plugin rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. scripts Repository scripts size: XL 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.

Dashboard: workspace time-travel — history scrub, version diff, and widget→logbook blame

1 participant