Skip to content

feat(automations): native Automations page with web parity - #1893

Merged
bkudiess merged 64 commits into
mainfrom
bkudiess-reactor-automations-page
Nov 11, 2026
Merged

bkudiess merged 64 commits into
mainfrom
bkudiess-reactor-automations-page

Conversation

@bkudiess

@bkudiess bkudiess commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

What Problem This Solves

Users need a complete automation inventory and reliable everyday controls without reproducing the entire Gateway web editor.

User Impact

User impact: browse all accessible agents and paused or advanced jobs, run or pause jobs, edit ordinary schedules, inspect recent results, and open chat or web management for deeper work. Owner delivery and unsupported timing writes/copies remain web-managed; basic edits omit unchanged unsupported fields and preserve hidden saved settings.

Removal is not atomic: the client checks the loaded revision with cron.get, then sends the released Gateway's id-only cron.remove. A concurrent edit between those calls is not detected. Reported conflicts are surfaced without an unguarded removal retry.

Why This Change Was Made

The native page prioritizes discovery, status, timezone-aware presets, delivery visibility and daily actions. Permission checks, confirmations, draft lifetime and stale-response fencing remain explicit instead of silently converting advanced jobs. Landed Usage and Dashboard owners are preserved.

A reproduced queued-chat ordering defect is also repaired: delayed acceptance no longer reopens a completed turn or places its prompt after the response. Unrelated/newer runs and queued follow-ups remain isolated. The combined fixture inventory uses a measured 1500-second aggregate allowance within the unchanged 30-minute outer step; individual deadlines, assertions and cleanup gates are unchanged.

The final reader repair relinquishes bottom anchoring for an actual keyboard-directed destination outside the follow range. Matching native completion and existing tail-navigation owners retain follow/restoration responsibilities; no extra scrolling or forced layout is introduced.

Evidence

Current-head CI passed on attempt 1, including the required CI Gate. Head 35715c5900e0368f3d43d13bd0dd20e367f70a67 was tested as merge b6288e913dec3aa111c36b205961b9852f73569d (main a6ff6a16 plus this head), whose tree 9582ba29a84a747f2c6b369e60c2a7c3d8420005 exactly matches the local candidate.

The requested simplification removed 373 net lines of temporary diagnostics across three test files, with no production, test-case, assertion, action, wait-budget or CI-selection changes. The reduced candidate passed all 122 Debug fixture cases, both Debug/Release reader widths, two Release queued-chat cases, native UI 1243 cases with nine policy skips, and full unfiltered hosted Tray 6276/6276.

Previous intermittent failures are preserved. The reader counterfactual demonstrated that changing anchoring released the already-pending requests; it did not identify the source of the nine-DIP measurement oscillation. The original reader assertions passed through the production repair in Debug and Release. Temporary reader, reconnect and notification diagnostics are now retired without removing their regression tests; their removal is not a reconnect or notification root-cause fix. Fixture evidence does not establish live Gateway timing or installer/Store upgrade behavior.

Review scope and resolved findings

Independent Opus 5.5 and GPT-6 Astra code-review contexts covered implementation/proof-plan scope at 03f45691 against 045d13ac, 128 paths per reviewer. The rubber-duck role was unavailable. Ten retained findings were repaired in cab3b592 and subsequent lifetime, rendering and proof corrections. Supplemental coverage followed narrative exposure, so this was not wholly blind; reviewers did not execute runtime proof.

Separate bounded P0-P3 reviews covered integration conflicts, CI capacity, queued-turn repair, diagnostic safety, reader-anchor ownership, editor geometry and the Systems/Usage proof-readiness corrections. Accepted agent-delta correlation and Release-build prerequisite findings were repaired and rechecked. The simplification mapped 206 authored repair hunks to 193 retained and 13 removed; its independent review found no significant issues, and AST checks preserved cases, assertions, actions and waits. This is not a fresh whole-head dual-model review; subsequent reviewer model identities are unverified.

The older durable review was reconciled against source and executed regressions: Main normalizes to systemEvent/text; accepted invocation/run IDs govern completion, with conservative ID-less handling; unreachable full-history UI was removed while recent full results remain; hidden-field preservation and strict protocol tests protect existing jobs. Released portable-profile preservation is not installer/Store or live Gateway cron-storage migration proof.

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Docs or instructions
  • Tests or validation
  • Security hardening
  • Chore or infrastructure

Scope

  • Tray or WinUI UX
  • Windows node capability
  • Local MCP or winnode
  • Gateway, connection, or pairing
  • Setup or onboarding
  • Permissions, privacy, or security
  • Tests, CI, or docs

Required proof pools

  • windows-winui-interactive: native editing, navigation, focus, accessibility, responsive layout and visible result/hero rendering. Declaration is not complete-pool acceptance.

Validation

Current local source: head 35715c5900e0368f3d43d13bd0dd20e367f70a67, tree 9582ba29a84a747f2c6b369e60c2a7c3d8420005. Validation ran on the frozen source manifest whose exact tree became this commit. Its parent integrates pinned main a6ff6a16. $ownedResults denotes each invocation's separate task-owned output directory, with its private path redacted.

Recorded command Result
.\build.ps1 -NoTrustRepository All five targets passed
dotnet build .\tests\OpenClaw.Tray.UITests\OpenClaw.Tray.UITests.csproj -c Debug -r win-arm64 -p:DevBuild=false --disable-build-servers -nodeReuse:false Passed, zero warnings/errors; compilation only
dotnet build .\tests\OpenClaw.Tray.UITests\OpenClaw.Tray.UITests.csproj -c Release -r win-arm64 -p:DevBuild=false --disable-build-servers -nodeReuse:false -p:RequireSignedCleanupHost=false Passed, zero warnings/errors; unsigned non-Dev compilation only
dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --disable-build-servers --logger "trx;LogFileName=shared.trx" --results-directory $ownedResults 5760 passed, 28 ordinary opt-in skips, zero failed
dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --disable-build-servers --logger "trx;LogFileName=tray.trx" --results-directory $ownedResults --filter "FullyQualifiedName!=OpenClaw.Tray.Tests.SettingsManagerIsolationTests.OpenClawTrayDataDirRedirectsSettingsAwayFromRealAppData" 6275 passed, zero failed/skipped; partial local suite
dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --disable-build-servers --filter "FullyQualifiedName~ChatTimelinePresentationTests" --logger "trx;LogFileName=chat-focused.trx" --results-directory $ownedResults 103/103 passed, zero skips
git diff --check Passed

The one locally excluded Tray case reads OS-roaming settings outside isolation overrides. No repository/CI filter was changed. The exact case passed in both current hosted Tray variants; this does not retroactively make the local filtered run unfiltered.

Current-head hosted evidence Result
Native UI and production resources Standard UI 1243 passed, nine policy skips, zero failed; production-resource cases 31/31; reader 480/1100 and four editor geometry guards passed
Gateway fixture and Release proof Debug fixture 122/122, profile 55/55, released-profile 1/1; Release queued-chat 2/2 and reader 2/2; no selected skips
Unfiltered Tray 6276/6276 plus Dev 31/31; exact locally excluded privacy case passed in both

Earlier evidence stays attributed: the 621/621 provider-owner and 12/12 ordering/isolation runs belong to 575bd3d8; unchanged managed cases re-executed in current full Tray closeout. Documentation, skill, skill-validator and workflow-contract scripts passed at 3dec70a9; those inputs are unchanged by this three-test-file reduction. Actual-source reader characterization reproduced the missing handoff on the prior owner and passed on the repair; this does not substitute for native event/layout execution.

Real Behavior Proof

  • Environment tested: local isolated ARM64 managed/build validation; hosted Windows x64 Debug and targeted unsigned non-Dev Release fixtures.
  • PR head or commit tested: head 35715c59; hosted merge b6288e91, identical tree 9582ba29, as recorded above.
  • Exact steps or command run: recorded local commands above and hosted fixture invocations below.
  • Evidence after fix: weekly editor journeys passed in Light/Dark; both reader widths passed in Debug and Release without the counterfactual; queued-chat ordering passed both Release variants. Current Usage captures show the complete expanded header, cost/share and all facts through Errors, unobstructed in both themes.
  • Observed result: all required CI passed on the reduced candidate. The retained Release assembly identifies Release / OpenClawTray, and its SHA-256 906225BD5D23C040F4388F6EC105D13B95E1CB0573E41A5D58F9223E14A936C0 matches both running-app receipts.
  • Screenshot or artifact links verified? (Yes/No/N/A) Yes: current job artifacts were downloaded, raw TRX inspected and the Light/Dark expanded-detail images visually checked.
  • Not verified or blocked: local native input remains held after foreground refusal; full ARM64 Release/High Contrast/installed acceptance, live Gateway/provider timing, installer/Store upgrade and Gateway cron-storage migration are not established by the synthetic x64 fixtures.
.\scripts\test-gateway-fixture.ps1 -AppPath .\src\OpenClaw.Tray.WinUI\bin\Debug\net10.0-windows10.0.22621.0\win-x64\OpenClaw.Tray.WinUI.exe -ArtifactsDirectory .\TestResults\GatewayFixture -TestTimeoutSeconds 1500 -Screenshots -NativeInputProof -NoBuild
.\scripts\Invoke-CiTest.ps1 -Project tests\OpenClaw.Tray.UITests -Configuration Release -ResultsDirectory TestResults\GatewayFixtureRelease -TrxFileName GatewayFixtureRelease.trx -Runtime win-x64 -Filter "FullyQualifiedName~GatewayFixtureUiTests.CompletedRunLateSnapshotLeavesNativeComposerReadyAndQueueDraining" -ExpectedTestCount 2 -RequireAllTestsPassed -HangTimeoutSeconds 300 -CollectNativeFailureMetadata -CaptureHostExit
.\scripts\Invoke-CiTest.ps1 -Project tests\OpenClaw.Tray.UITests -Configuration Release -ResultsDirectory TestResults\ReaderRelease -TrxFileName ReaderRelease.trx -Runtime win-x64 -Filter "FullyQualifiedName~ReactorChatLayoutProofTests.ConversationFeedback_ThinkingToolReviewsAndHistoryRetainComposerWithoutSearch" -ExpectedTestCount 2 -RequireAllTestsPassed -HangTimeoutSeconds 120 -CollectNativeFailureMetadata -CaptureHostExit

CI explicitly selects the Release app, enables isolated fixtures/screenshots, and retains its DLL for configuration, identity and runtime-hash verification. Unsigned fixture builds do not change production signing defaults.

Security Impact

  • New permissions or capabilities? (Yes/No) No.
  • Secrets or tokens handling changed? (Yes/No) No.
  • New or changed network calls? (Yes/No) Yes.
  • Command or tool execution surface changed? (Yes/No) No.
  • Data access scope changed? (Yes/No) Yes.
  • If any answer is Yes, explain the risk and mitigation: native discovery reads all jobs accessible to the connected operator. Existing authenticated Gateway authorization governs reads and mutations. Explicit filters, capability checks and generation fencing reject stale results and unsupported writes. Web handoff retains existing credential policy; run-result rendering stays inert.

Compatibility and Migration

  • Backward compatible? (Yes/No) Yes, with explicit web-management fallback for unsupported edits or Gateway revisions.
  • Config or environment changes? (Yes/No) Yes: ordinary hosted fixture allowance is 1500 seconds; runner default remains 900 and accepted range remains 1 through 1800.
  • Migration needed? (Yes/No) No.
  • If yes, list the exact upgrade steps: N/A. Cron definitions remain Gateway-owned. Basic update patches preserve inherited fields rather than migrating or replacing them; the non-atomic removal caveat above remains.

Review Conversations

  • I replied to or resolved every bot review conversation addressed by this PR.
  • I left unresolved only conversations that still need maintainer judgment.

The final review-thread check found zero inline threads. No formal approval or bot reply is implied; the old-head durable findings are reconciled above and final required CI is green.

Rebuild the Windows Automations page with Reactor on a UI-agnostic
OpenClaw.Shared.Cron layer so operators can see and manage an agent's
automations with the same information and actions as the web page.
Fix agent scoping: every cron.list now sends agentId.

Upgrade Microsoft.UI.Reactor to 0.1.0-preview.16 and retire the
preview.12 pin and Markdown ListItem workaround.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@clawsweeper

clawsweeper Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. 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. labels Oct 27, 2026
@clawsweeper

clawsweeper Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex review: blocked before merge.

What this changes

This PR replaces the Cron page with agent-scoped native Automations management and upgrades Reactor.

Example: Browse the ops agent’s daily automations.

  • Before: The legacy Cron page requests an unscoped inventory.
  • After: Automations requests agentId=ops and offers an explicit All agents view.

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) Useful authorized direction with substantial supporting tests, but current runtime evidence is insufficient and source review identifies actionable defects.
Proof confidence 🧂 unranked krab (1/6) Real behavior proof is not required for maintainer- or bot-authored pull requests.
Patch quality 🦐 gold shrimp (3/6) 3 actionable review findings remain.

Product

Kind: Feature · Worth it: Yes · Fix scope: Complete
User problem: Operators need native agent-scoped scheduling without losing advanced saved settings or sending requests released Gateways reject.
Reason: The collaborator-authored direction provides a coherent daily workflow and explicitly leaves advanced authoring in the web app; no additional product approval is required.

Merge readiness

⛔ Blocked before merge - 5 items remain

Keep this maintainer-authored draft open: it delivers distinct native scheduling work, but two behavior defects and unreachable production UI remain.

Priority: P2
Reviewed head: f7ae188fe3ae6805a1e66e41075778f4ee6b7b20

Before merge

  • Convert the payload when selecting the Main session (P2) - Create a new automation with the default assistant task, enter a name and prompt, then select Main. This handler changes only SessionTarget; Normalize leaves AgentTurn unchanged and validation accepts it. Save therefore sends sessionTarget="main" with payload.kind="agentTurn", which the released Gateway rejects in assertSupportedJobSpec. The old editor generated systemEvent/text for Main. Restore that mapping in the existing form normalization and cover the serialized request.
  • Match run completion to the accepted invocation (P2) - If run A completes while the cached job still reports an earlier LastRunAtMs, starting run B captures that stale baseline. B's watcher then accepts A's history entry because its timestamp exceeds the baseline, clearing B's running indicator before B finishes and enabling actions prematurely. The acknowledgement's RunId is currently used only for a notice. Retain it with the run owner and require matching completion, including in list reconciliation; timestamp-only completion must not settle an ID-less acknowledgement. The same distinction is documented in fix: keep older Run Now attempts from clearing newer runs #2082.
  • Remove the unreachable full-history component (P2) - The narrowed page never instantiates AutomationRuns: its only production use is the static RenderRun helper from AutomationDetail, which renders three recent results and sends All runs to the web. The component still adds its own search, filters, paging, score projection, and store view machinery for an unreachable surface. Keep the shared recent-result renderer and remove the unreferenced component and exclusively dependent state rather than carrying the superseded UI alongside the daily workflow.
  • Add data-model compatibility proof - The review found that existing stored data may not work after upgrade. Show that existing data still loads and works with this change.
  • Explain or restore the original intent of Session-target payload selection - 61fcd39: The earlier Cron editor selected systemEvent/text for Main and agentTurn/message otherwise, matching the Gateway contract.

Findings

  • [P2] Convert the payload when selecting the Main session — src/OpenClaw.Tray.WinUI/Automations/AutomationEditor.cs:550-552
  • [P2] Match run completion to the accepted invocation — src/OpenClaw.Shared/Cron/AutomationsStore.cs:901-903
  • [P2] Remove the unreachable full-history component — src/OpenClaw.Tray.WinUI/Automations/AutomationRuns.cs:22-29

Provenance

  • Session-target payload selection changes intended behavior without addressing why it exists (61fcd39: The earlier Cron editor selected systemEvent/text for Main and agentTurn/message otherwise, matching the Gateway contract.)

Tests

  • Missing end-to-end proof: Current-head native scheduling, Main-session creation, successive-run completion, and stable-release upgrade preservation remain unverified; historical screenshots and unrun regressions do not establish them.
Agent review details

How this fits together

The WinUI page sends authenticated scheduling requests through the shared Automations store and Gateway client, then renders jobs, recent results, and mutation feedback.

flowchart LR
  User[Operator] --> Page[Native Automations page]
  Page --> Store[Automations store]
  Store --> Client[Operator Gateway client]
  Client --> Gateway[Gateway scheduler]
  Gateway --> Overview[Overview and Inbox facts]
  Overview --> Page
Loading

Technical review

Best possible solution:

Land the daily-workflow replacement with valid session payloads, invocation-bound run tracking, and only reachable UI.

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

Source establishes the Main-session failure against the released Gateway validator and the stale-history completion path; neither was executed during this read-only review.

Is this the best way to solve the issue?

The shared store and retained daily editor are appropriate, but session normalization and run identity need correction, and the superseded full-history component should be removed.

Full review comments:

  • [P2] Convert the payload when selecting the Main session — src/OpenClaw.Tray.WinUI/Automations/AutomationEditor.cs:550-552
    Create a new automation with the default assistant task, enter a name and prompt, then select Main. This handler changes only SessionTarget; Normalize leaves AgentTurn unchanged and validation accepts it. Save therefore sends sessionTarget="main" with payload.kind="agentTurn", which the released Gateway rejects in assertSupportedJobSpec. The old editor generated systemEvent/text for Main. Restore that mapping in the existing form normalization and cover the serialized request.
    Confidence: 0.99
  • [P2] Match run completion to the accepted invocation — src/OpenClaw.Shared/Cron/AutomationsStore.cs:901-903
    If run A completes while the cached job still reports an earlier LastRunAtMs, starting run B captures that stale baseline. B's watcher then accepts A's history entry because its timestamp exceeds the baseline, clearing B's running indicator before B finishes and enabling actions prematurely. The acknowledgement's RunId is currently used only for a notice. Retain it with the run owner and require matching completion, including in list reconciliation; timestamp-only completion must not settle an ID-less acknowledgement. The same distinction is documented in fix: keep older Run Now attempts from clearing newer runs #2082.
    Confidence: 0.96
  • [P2] Remove the unreachable full-history component — src/OpenClaw.Tray.WinUI/Automations/AutomationRuns.cs:22-29
    The narrowed page never instantiates AutomationRuns: its only production use is the static RenderRun helper from AutomationDetail, which renders three recent results and sends All runs to the web. The component still adds its own search, filters, paging, score projection, and store view machinery for an unreachable surface. Keep the shared recent-result renderer and remove the unreferenced component and exclusively dependent state rather than carrying the superseded UI alongside the daily workflow.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.95

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 1c223f14f6b6.

Provenance checked

  • Full run-response presentation keeps the original intent (638386e: Improve Cron run history UX #814 made complete sanitized responses available without leaving Cron history.)
  • Legacy snapshot ownership changes intended behavior with a stated reason (ece8758: The previous AppState extraction centralized observable snapshots; this PR explicitly transfers scheduling ownership to the typed store and removes the old forwarding path.)
  • Reactor dependency upgrade changes intended behavior with a stated reason (a4dd026: The preview.16 pin adopted the native session-switch workaround; this PR moves to official preview.17 packages for subsequent control fixes while retaining chat regression requirements.)

Testing

Proof path: none.

Security

None.

Evidence

Acceptance criteria:

  • ./build.ps1
  • dotnet test ./tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj --no-restore
  • dotnet test ./tests/OpenClaw.Tray.Tests/OpenClaw.Tray.Tests.csproj --no-restore
  • dotnet test ./tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj --no-restore --filter 'FullyQualifiedNameCron|FullyQualifiedNameAutomations'

What I checked:

  • Pinned change and main behavior: The introduced diff replaces the legacy Cron implementation; current main still contains the old page. The feature is not already implemented on main. (src/OpenClaw.Tray.WinUI/Pages/CronPage.xaml.cs:65, f7ae188fe3ae)
  • Previous findings reconciled: History requests omit view; removal performs a revision preflight followed by id-only removal; native validation blocks unsupported timing and Owner changes; expanded successful results use safe Markdown. The maintainer-authored description explicitly records the non-atomic removal tradeoff. (src/OpenClaw.Shared/Cron/CronGatewayRequests.cs:56, f7ae188fe3ae)
  • Main-session regression: The new session selector changes SessionTarget without converting AgentTurn to SystemEvent. Main previously selected both the payload kind and text field from the session target. (src/OpenClaw.Tray.WinUI/Automations/AutomationEditor.cs:552, f7ae188fe3ae)
  • Released Gateway contract: The PR executes this repository’s cron protocol. At stable v2026.11.2, assertSupportedJobSpec rejects agentTurn with sessionTarget=main; the closed request schemas also confirm the earlier view, removal, and delivery.target compatibility repairs. (src/cron/service/jobs-validation.ts:60, b556fdf457b0)
  • Run completion identity: Polling accepts any history timestamp newer than the cached job baseline, although the run acknowledgement supplies a RunId. The related repair describes the same timestamp-versus-invocation distinction: fix: keep older Run Now attempts from clearing newer runs #2082. (src/OpenClaw.Shared/Cron/AutomationsStore.cs:902, f7ae188fe3ae)
  • Proof and current checks: The four prepared screenshots were inspected and show the superseded split-pane UI. The full PR description explicitly leaves current native and stable-Gateway upgrade proof unverified. Exact-head fast-validation has passed; other required suites remain in progress. No target code, builds, or tests were run during this review. (f7ae188fe3ae)

Likely related people:

  • Régis Brid: Raw commit 638386e adds src/OpenClaw.Shared/OpenClawGatewayClient.cs:785 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 638386ed73ae; files: src/OpenClaw.Shared/OpenClawGatewayClient.cs)

Preflight source

Source unknown. Source comparison at the observed PR snapshot only. Completion is self-reported; body, policy, tests, execution, and report bytes are not verified.

Review metrics

Metric Value Why it matters
Source and test delta src +11,901/-4,579; tests +9,174/-813 The replacement includes substantial localization and native coverage; the unreachable full-history component is avoidable production growth.

Labels

Label changes:

No label changes.

Label justifications:

  • P2: Native scheduling is a useful improvement, with bounded editor and running-state defects.
  • merge-risk: 🚨 compatibility: The replacement changes released-Gateway request shapes and persisted-job updates; selecting Main currently constructs a rejected job definition.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

History

Review history (1 earlier review cycle)
  • reviewed 2026-10-27T19:13:43.567Z sha 97bbae6 :: blocked before merge. :: [P1] Keep history requests compatible with the released Gateway | [P1] Preserve removal on Gateways without revisioned deletion | [P2] Check Gateway support before offering new scheduling fields | [P2] Retain Markdown rendering for successful full responses

Reviewed November 9, 2026, 6:13 PM ET / 23:13 UTC (Revision 2).

bkudiess and others added 5 commits October 27, 2026 17:11
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep Automations mounted during reconnect attempts so its recovery UI remains available. Exercise the populated page in Light and Dark with per-process Axe scans.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retain all populated theme scans and offline UI assertions. Disconnected CronPage Axe coverage stays in the existing stable accessibility lane, avoiding live element invalidation during reconnect.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Pin Light and Dark for the disconnected Axe path without Gateway reconnect events. Keep populated fixture scans and offline screenshots independent.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@bkudiess

Copy link
Copy Markdown
Collaborator Author

Native Automations proof

Windows 11 ARM64, isolated synthetic Gateway. No production jobs or provider calls. The app source is unchanged since 776f8df3; the later commits change only the proof tests. Current-head source correspondence and executable/library SHA-256 hashes were recorded locally.

Debug proof: Light and Dark populated states, independent Light/Dark disconnected Axe scans, and the actual final message in 240-message chat histories at both window widths: 5 passed, 0 failed, 0 skipped.

Details in Light

Automations details in Light

Details in Dark

Automations details in Dark

Other main states, editor and confirmation

List

Agent-scoped Automations list

Run history and transcript

Run history with a synthetic run transcript

All runs

Agent-wide run history

Editor in Light

Schedule editor in Light

Editor in Dark

Schedule editor in Dark

Pause confirmation

Pause confirmation before a fixture-only change

Empty agent

Starter automations for an empty agent

Disconnected recovery

Open Connection recovery retained during reconnect

Wait for the independent recent-run summary and completed fixture reads, rather than scan controls while asynchronous replies replace their native elements.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@bkudiess

Copy link
Copy Markdown
Collaborator Author

Real Windows High Contrast (Night sky), production-shaped Release ARM64, fixture Gateway only. The test recorded Windows high contrast: True and passed all main states plus populated Axe checks (1 passed, 0 failed, 0 skipped). Both stable disconnected Axe cases also passed in the preceding High Contrast run. The original None contrast setting was restored and verified. An earlier duplicate Light case completed its UI checks but failed on temporary-profile cleanup; that failed attempt remains recorded locally.

Actual High Contrast details

Actual High Contrast editor

Actual High Contrast empty state

@bkudiess

Copy link
Copy Markdown
Collaborator Author

Automations parity checklist (web → native)

Reference: openclaw/openclaw@5089aa71 ui/src/pages/cron/, ui/src/lib/cron/.
Status: ☐ planned · ☑ done · ⏸ deferred (with reason).

# Web item Native equivalent Data source Status
1 Job list scoped to the selected agent Left list pane; agent:{id}:cron passes agentId cron.list { agentId } ☑
2 Search Search box (debounced) cron.list { query } ☑
3 All / Active / Paused SelectorBar cron.list { enabled, includeDisabled } ☑
4 Sort (next run, recently updated, name; asc/desc) Sort DropDownButton with radio items cron.list { sortBy, sortDir } ☑
5 Advanced filters (schedule kind, last status, condition) Filter flyout cron.list { scheduleKind, lastRunStatus, trigger } ☑
6 Paging / load more, shown of total "Load more" + count cron.list { limit, offset } → hasMore,nextOffset,total ☑
7 Scheduler status, next wake, totals, failing Status strip at top cron.status, scoped cron.list ☑
8 Job row: state, name, agent, schedule, next/last run, trigger List card CronJob ☑
9 Job details Detail pane, Overview tab cron.get ☑
10 Pause / resume (disable confirms) Native action buttons + confirmation for pause cron.update {enabled, expectedConfigRevision} ☑
11 Run now / run if due, running state, feedback Run split button, running badge cron.run {id, mode} ☑
12 Edit Editor pane cron.update ☑
13 Clone More menu → prefilled editor cron.add ☑
14 Remove (confirm) More menu → ContentDialog cron.remove ☑
15 Schedule: once, interval, cron, event; on-exit/stream read-only Schedule editor schedule object ☑
16 Time zone Cron time zone box schedule.tz ☑
17 Stagger window / exact timing Exact toggle + amount/unit schedule.staggerMs ☑
18 Active hours Toggle + start/end + tz activeHours ☑
19 Readable schedule summary Live summary under editor + list local ☑
20 Assistant task prompt / timeline message Action section payload ☑
21 Model, thinking, timeout Editable combos + number payload.model/thinking/timeoutSeconds ☑
22 Light context, include reasoning, skip empty scratch Advanced toggles payload flags ☑
23 Read-only command/script payloads Read-only block payload ☑
24 Session target, wake mode, idle only, delete after run Advanced job fields ☑
25 Condition trigger script Advanced trigger ☑
26 Delivery: mode none/announce/webhook Delivery section delivery.mode ☑
27 Target conversation (suggestions) Editable combo of conversations conversations.list ☑
28 Channel, account, owner DM, direct policy, best effort Delivery section delivery.* ☑
29 Webhook URL + validation Delivery section delivery.to ☑
30 Failure alerts inherit/disabled/custom Failure alerts section failureAlert ☑
31 Event-triggered jobs from MCP servers Event schedule: server, event, args JSON config.get (mcp.servers), mcp.events.list ☑ (live mcp-events.status subscription diagnostics ⏸ deferred: needs a long-lived event subscription the page host does not keep; definitions and configured servers are shown)
32 Per-job scratch Scratch tab (load, save, remove, size, conflict) cron.scratch.get/set ☑
33 Run history per job + all runs (Activity) Runs tab + Run history view cron.runs ☑
34 Run filters: search, status, delivery, sort, load more Filter bar cron.runs ☑
35 Run status, delivery outcome, suppression, error, model, tokens Run card CronRunLogEntry ☑
36 Run transcript Transcript panel with paging cron.history ☑
37 Condition activity (checks, last checked, last fired) Runs tab header job state ☑
38 Auto-disabled status Status pill + InfoBar state.autoDisabled ☑
39 Suggested schedules / starter automations Empty state cards local ☑
40 Non-admin limited actions Read-only banner, mutations hidden operator scopes ☑
41 Revision conflict handling Reload latest + InfoBar CRON_JOB_CHANGED ☑
42 Empty / loading / error / no-match states Native states — ☑
43 Disconnected + Open Connection InfoBar + empty state connection ☑
44 One-time job finished notification (Windows) InfoBar + app notification run-now watcher + cron.get not-found ☑

Screenshots: Light/Dark main-state gallery and actual Windows High Contrast.

This is the implementation inventory, not a claim that every control has separate live-provider proof. Runtime proof uses the isolated fixture Gateway.

@bkudiess
bkudiess marked this pull request as ready for review October 28, 2026 02:32
Keep editor form, revision and save feedback in the page-owned session. Fence delayed updates and close callbacks by editor nonce. Scope conversation directory results and selections to the active delivery route.

Add fixture response gates and three native regressions. Build passed; Shared: 4701 passed, 25 ordinary skips; Tray: 4583 passed, four known ARM64 prerequisite failures. All five selected native UI cases passed against an isolated app compiled with the local Reactor fix.

The directory regression still needs the unpublished Reactor empty-Suggestions binding fix. The NuGet dependency is unchanged, and no consumer workaround is added. Document that dependency explicitly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
bkudiess and others added 4 commits November 5, 2026 14:42
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…on requests

Reduce the native Automations page to the workflows people use every day,
keep advanced jobs readable and safe, and make the cron client work against
released Gateways.

Automations page
- Show the full inventory on the connected Gateway, including paused and
  auto-disabled jobs, with All agents discovery and explicit agent
  filtering. Keep search, All/Active/Paused, paging and counts, refresh and
  scoped scheduler health and failures.
- Keep Run now, pause and resume, safe ordinary edits and confirmed removal.
  Keep one-time, interval, daily, weekday and weekly presets with timezone
  clarity, and a simple delivery destination with visible existing
  destinations and delivery errors.
- Keep recent run history with result and error text, Open chat, and Open in
  web handoffs that only use routes the web app supports.
- Advanced jobs stay visible and readable. Basic edits preserve hidden
  settings, and unsupported edits route to web management instead of
  rewriting the job.
- Remove client-authored suggestions, event and cron-step authoring, scratch
  editing and the inline transcript explorer.
- Match the shared eyebrow row, anchor the page gradient to the viewport
  behind the scroll viewer, and separate stacked cards with the shared
  8 DIP inner gap.

Gateway cron requests
- cron.runs no longer sends the beta-only view parameter, which stable
  Gateways reject with "unexpected property 'view'".
- cron.remove sends only the job id after confirming the loaded revision with
  cron.get, matching the stable closed schema.
- The Gateway fixture now enforces the stable closed cron schemas so this
  cannot be hidden again.

Build and CI
- Move Microsoft.UI.Reactor and Microsoft.UI.Reactor.Advanced to
  0.1.0-preview.17 through a digest-pinned bootstrap of the official release
  assets into an ignored repository-local feed, and adapt the chat link
  builder to the new API.
- Run the steady-resource Automations UI tests in CI.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Merge origin/main (4ea07e8) into the Automations page. The only textual
conflict was CronPage.xaml.cs, where main still edited the retired XAML
page; the Reactor host is kept.

Main's shared navigation search (#2016) opens a found automation through
CronPage.RevealSearchJob, which the Reactor page did not have. Port it:

- AutomationsStore.RevealAsync looks the job up on the Gateway, selects it
  and reports Revealed, NotFound, Failed or Superseded. A missing job
  selects nothing instead of leaving a phantom selection, and a reveal
  that loses to a newer load changes nothing.
- A reveal can widen a specific-agent filter to All agents so a job owned
  by another agent is shown. Search and the post-save reveal widen; agenda
  and attention reveals stay in the current scope. New automations still
  belong to the route agent.
- A job that no longer exists shows the Hub search "unavailable" wording
  as a neutral, auto-dismissing in-page notice. It is not a global
  notification and adds no new localized strings.
- AutomationsRevealChannel carries the page request to the mounted root,
  holds one pending request until the root attaches, and supersedes it on
  dispose, so a search that lands before the first render is not lost.
- SettingsShellView and the search catalog from main are unchanged.

Docs: update the architecture ledger rows for the Automations page and add
the search reveal owner with its behavioral guard.

Tests: store reveal tests (found, missing, filtered, widened, saved for
another agent, disconnected, superseded), channel tests and source
contract tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve complete inventory and advanced job settings, integrate shared adaptive Settings and inset ownership, and add focused pinned native proof definitions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
roboclaw-bot and others added 2 commits November 8, 2026 06:43
Reconcile Settings navigation persistence and adaptive page allocation, retire removed Event Stream state, and preserve the native foreground activation gate after replacing the legacy Cron editor tests.

Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
@roboclaw-bot roboclaw-bot added the status: 🚢 actively landing A maintainer or agent is actively driving this item through implementation, validation, or merge. label Nov 8, 2026
roboclaw-bot and others added 2 commits November 8, 2026 06:56
Keep the viewport-layer ordering and single brush-owner assertions while matching the header height plus retained shell inset.

Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
Read the nonce-bound owner session when Save runs, rather than the render-captured form. Keep UIA proof on exposed controls and explicitly positioned viewports; preserve exact inert-link and destructive-copy checks and route keyboard-only proof through its existing opt-in lane.

Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
bkudiess and others added 11 commits November 9, 2026 23:33
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve daily workflows and distinct native regressions while removing unrelated baseline repairs, duplicate shared guards, unused history copy and reflection diagnostics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retain cached chat theme resources alongside the Automations production-profile guard and shared resource loader.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep text subscriptions bound to Reactor lifetime and isolate result rendering from chat navigation. Exercise modal input and native allocation contracts, and distinguish fixed pixel sampling apertures from aggregate UIA bounds.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Verify automatic automation reveal before scrolling to inspect details, retain the observed Settings search peer, and give the ordinary hosted fixture invocation 1200 seconds within its existing outer limit. Keep the 900-second default and strict owned-process and result admission guards.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retain the independently measured same-window sampling aperture for post-reveal detail inspection instead of resetting and traversing the entire expanded inventory. Keep automatic focus, capture, containment and deadline assertions unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use the existing dedicated-worker pattern without changing the identity lock deadline or security assertions. Add the approved bounded public reader-event observations only to failure diagnostics, preserving all actions, predicates and timeouts.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Expanding the agenda can scroll the header out of view. Return to the top and invoke the observed enabled New button once, retaining the expansion and draft-preservation assertions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve both host-owned Usage and Automations sources, protocol interfaces, fixtures and locale catalogs. Reconcile native fixture input type names without changing input behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Place pagination rows on one local reported date and expand the rendered date group rather than recomputing its key from a later clock sample. Preserve the collapsed budget, automatic reveal, detail capture and separate multi-group/calendar coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Integrate e59374c while preserving both page owners. Size the ordinary fixture aggregate budget from measured combined inventory and wait for committed history publication in the transient-retry fixture.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@roboclaw-bot

Copy link
Copy Markdown
Contributor

PR cleanup review

Reviewed head: d11898a373bece41ced81b6f476abb8f860adf20. Main comparison: e59374c064f43d68f5c72d070d4c89ef2d20ec3b.

Thanks for the work on this. I would keep #1893 (feat(automations): native Automations page with web parity) open as a draft, rather than close it as superseded: pinned main still has the legacy Cron page, and this branch has a distinct native daily-workflow implementation.

At d11898a, the latest CI run has completed, not remained pending: the production-resource lane passed 31/31, while the UI and Mock Gateway jobs failed on reader scrolling, a Usage title-bar peer and composer readiness. Those failures need attribution before rerunning; this read-only pass did not establish baseline flakes.

The next useful pass is focused lifecycle and proof work: bind the page store to its originating connection, cover omitted-owner cloning and multiple expanded rows across reconnect, and preserve visible results when persistent error toasts fill the queue. Please also keep capture observational and restore the native timezone-transition matrix. These are source-backed concerns, not an executed Windows reproduction.

Please refresh the body to the actual head and current daily-workflow scope, reconcile the older review against the repairs already present, and attach current-head native/compatibility evidence before moving out of draft. Historical screenshots and the old parity checklist are useful provenance, but not proof of this UI.

Action in this cleanup pass: leaving this PR open. No branch changes or runtime-proof waiver. The findings above come from source, discussion and recorded-CI review; Windows validation was not rerun in this pass.

bkudiess and others added 7 commits November 10, 2026 14:05
Preserve run-correlated transcript ordering and queued follow-ups across delayed acknowledgements. Keep fixture geometry readiness bounded, retain critical reader failure observations, and add exact-two-case unsigned non-Dev Release fixture proof without changing production signing defaults.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Observe the existing failed reader request under one restored anchoring counterfactual and always rethrow its original failure. Capture content-free single-write reconnect diagnostics only on failure; preserve all original actions, predicates and deadlines.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep the existing rendered readiness deadlines and all strict geometry, focus and consequence assertions; a popup entry alone does not establish that its dialog template is loaded.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use bounded overlapping viewport steps for the exact session header, preserve strict expansion assertions, and record content-free reopened-Inbox evidence only if its existing wait fails.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep automatic expansion evidence separate from explicit inspection. Freeze the client-clipped sampling aperture and require stable visible detail anchors through the final Errors row, with obstruction checks around capture.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Integrate exact a6ff6a1. Yield edge anchoring for an admitted keyboard reader bring while preserving initial, disclosure and tail navigation ownership. Guard editor reveal against nonfinite geometry and require the exact reader pair in Release proof.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retire reader event buffering, reconnect peer sampling and reopened-Inbox failure dumps. Preserve all test cases, native actions, readiness predicates, assertions and Debug/Release proof selections; production behavior is unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants