Skip to content

Refactor PR 1: architecture ledger + shared test fixtures - #3

Closed
bkudiess wants to merge 102 commits into
mainfrom
bkudiess-refactor-architecture-plan
Closed

bkudiess wants to merge 102 commits into
mainfrom
bkudiess-refactor-architecture-plan

Conversation

@bkudiess

Copy link
Copy Markdown
Owner

Summary

First PR of the god-object refactor. It establishes the anti-regression foundation the rest of the plan depends on: a living architecture ledger plus a shared test-support library. This is deliberately the safest PR to go first because it makes zero production changes.

  • docs/ARCHITECTURE.md — living ownership ledger (machine-readable table): ownership rules, god-object map, "when you touch X → extract toward Y", and single-source owners. AGENTS.md now points at it as required reading and forbids re-adding closed responsibilities.
  • ArchitectureLedgerConsistencyTests — validates the ledger schema, guard_test Type.Method format, and that named guard tests actually exist in source (renaming/deleting a guard without updating the ledger fails CI).
  • tests/OpenClaw.TestSupport (Shared-only) — TempDirectory, EnvironmentScope, CliHarness, FakeMcpServer, SettingsDataBuilder.
  • GatewayRecordBuilder lives in OpenClaw.Connection.Tests so the shared lib stays Connection-free (no transitive Connection dep leaks onto the CLI tests).
  • Migrations proving the fixtures: GatewayRegistryTestsTempDirectory; the WinNode FakeMcpServer internal copy de-duplicated to the shared one.

Scope / behavior guarantee

No src/ (production) files changed or added — every change is under tests/, docs/, or the solution file. The shipped app's runtime behavior cannot change because none of its code changed. The one intentional non-additive change is test-only: FakeMcpServer now retries the port bind (strictly more robust).

Validation

.\build.ps1                                                         # all 5 src projects built ✅
dotnet test tests/OpenClaw.Shared.Tests      -> Passed 2760, Skipped 31, Failed 0 ✅
dotnet test tests/OpenClaw.Tray.Tests        -> Passed 1705, Failed 0 ✅
dotnet test tests/OpenClaw.Connection.Tests  -> Passed  429, Failed 0 ✅
dotnet test tests/OpenClaw.WinNode.Cli.Tests -> Passed  126, Failed 0 ✅

Anti-regression guard, proven by negative test (temporarily broke the ledger, confirmed CI fails, then restored):

  • Duplicate ledger id → Ledger_ids_are_unique FAILS: Duplicate ledger ids: test-temp-dir.
  • Guard test renamed to a nonexistent method → Named_guard_tests_exist_in_test_sources FAILS: no method 'NoSuchGuardMethod' was found in a type 'TestSupportFixtureTests'.

Real behavior proof

Ran this PR's build in no isolation (owned the Release single-instance), enabled Local MCP Server, then exercised the live server. Runtime unaffected by the change (as expected — no src/ diff), and the MCP contract this PR actually touches (the FakeMcpServer dedup) works end-to-end.

Live app / connection (app.status):

{ "connectionStatus": "Connected", "overallState": "Ready", "operatorState": "Connected",
  "nodeState": "Connected", "nodeConnected": true, "nodePaired": true,
  "gatewayVersion": "2026.6.11", "sessionCount": 1, "nodeCount": 1 }

MCP discovery — winnode --list-tools: 52 tools returned (system., app., canvas., device., screen., stt., tts.*).

MCP invocation — winnode --command:

  • device.info"appVersion": "0.6.13-bkudiess-refactor-architecture-plan.1" (confirms the live server is this branch's build).
  • system.which {"bins":["cmd","git"]} → resolved both paths.

Raw MCP JSON-RPC over http://127.0.0.1:8765/:

  • tools/listjsonrpc 2.0, 52 tools.
  • tools/call device.statusisError=false, real system snapshot returned.

Runtime log (%LOCALAPPDATA%\OpenClawTray\openclaw-tray.log, tokens redacted):

[INFO] Capabilities registered: system, canvas, screen, tts, stt, device (6 caps)
[INFO] [MCP] HTTP server listening on http://<host>:8765/
[INFO] [NodeService] AttachClient DONE: Capabilities=6, Commands=25
[INFO] Node status changed: Connected
[DEBUG] [MCP] tools/call system.which
[DEBUG] [MCP] tools/call device.info
[DEBUG] [MCP] tools/call device.status
[DEBUG] [MCP] tools/call app.navigate
[DEBUG] [MCP] tools/call app.status

Computer-use UI proof (captured the Permissions page — non-personal — via app.navigate permissions). Copied UI diagnostics from the live window:

Header: Permissions — THE-HIVE
Node mode: on
Node active — "Providing 6 capabilities: canvas, device, screen, stt, system, tts"
Capabilities: System tools = on, Browser control = off, Camera = off
Connection pill: Connected

Rubber-duck review

Dual-model adversarial review (GPT-5.5 + Claude Opus 4.8) on the diff. All consensus findings fixed before this PR:

  • SettingsDataBuilder aliasing (returned a shared instance) → now replays overrides onto a fresh instance per Build(); independence test added.
  • Ledger over-claimed protection → added Type.Method format + source-existence enforcement.
  • FakeMcpServer port TOCTOU race → retry on bind failure.
  • TestSupportConnection layering leak → made TestSupport Shared-only; builder moved to Connection.Tests.
  • Plus review-only/separator-row validation hardening in the ledger test.

Not verified / blocked

  • Gateway-mediated nodes invoke path not separately exercised; node connection to the live gateway (Connected, nodePaired: true) is shown in app.status, and MCP discovery/invocation covers the command contract this PR touches.
  • UI screenshot captured during validation as computer-use image; embedded here as copied UI diagnostics (text) rather than a hosted image.

Cleanup

The no-isolation proof run used the real profile: Local MCP Server was toggled on for the proof and restored to its prior value (off) afterward, and the temporary tray instances were stopped. The other worktree's tray instance was stopped to free the single-instance lock and was not relaunched.

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

bkudiess and others added 30 commits June 24, 2026 12:41
Adds app-managed WSL gateway recovery actions to the setup wizard, moves shared WSL gateway helpers into OpenClaw.Connection, and documents the recovery behavior.
Fixes the Settings hotkey to open the Settings page and refreshes the MXC helper restore so stale helper binaries are not reused while keeping npm restore incremental.
Ports the MXC probe/SDK 0.7.0 work and inbound pairing approval dialog from the mistaken master branch target onto main.

Maintainer repair included:
- Preserving non-actionable handling for ambiguous legacy pairing fallback IDs in the new approval queue.
- Adding regression coverage for device and node fallback ambiguity.
- Version-stamping MXC SDK restore so stale node_modules cannot satisfy the 0.7.0 port.

Validation:
- Local .\build.ps1 passed.
- Local Shared tests passed: 2411 passed / 29 skipped.
- Local Tray tests passed: 1127 passed.
- Local Connection tests passed: 373 passed.
- GitHub CI passed on repaired head 7be0688: test, E2E setup-connect, E2E revocation-recovery, E2E network-recovery, build win-x64, build win-arm64, repo-hygiene.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Routes local system.run approval prompts into native chat when an interactive chat surface is available, while preserving the native approval dialog fallback.

Maintainer updates:
- Rebased onto current main after the MXC/pairing port landed.
- Kept the deleted Chat Explorations fake provider removed during rebase.
- Removed a duplicate ChatWindow.Show() call introduced during the branch hardening pass.

Validation:
- Local .\build.ps1 passed.
- Local Shared tests passed: 2417 passed / 29 skipped.
- Local Tray tests passed: 1154 passed.
- Independent code review found only the duplicate Show() issue, now fixed.
- Independent security review found no concrete security vulnerabilities.
- GitHub CI passed on repaired head ae301c0: repo-hygiene, test, E2E setup-connect, E2E revocation-recovery, E2E network-recovery, build win-x64, build win-arm64, Socket Security.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merged after daily triage: focused scope, green CI, and low-risk validation evidence.
Merged after daily triage: focused scope, green CI, and low-risk validation evidence.
Merged after daily triage: focused scope, green CI, and low-risk validation evidence.
Merged after rerunning the failed setup-connect shard successfully; follow-on win-x64 and win-arm64 builds also passed.
Adds a static gateway protocol snapshot guard covering sessions, files, commands, and compaction, with maintainer repair so no-parameter used request methods are also checked for payload drift.
Improves Cron History so users can inspect full sanitized run responses, preserves expanded/running state while refreshing, adds response-aware cron.run feedback, and includes compatibility coverage for legacy cron.run payload fallback.
Route selected background issues into the in-app Notifications page, including connection, sandbox, channel, pairing, and cron failures. Partially addresses openclaw#820; it does not close the broader notification-routing issue.
* Make A2UI dataModelUpdate.valueArray first-class

The v0.8 `dataModelUpdate.valueArray` typed value was silently dropped by the
WinUI parser: `DataModelEntry` had no `ValueArray` field and `ToJsonNode()`
returned null for it. Only `valueString/Number/Boolean/valueMap` were handled.
This broke seeding an array into a surface's data model (e.g. a multi-select
`MultipleChoice` bound to a path), even though `valueArray` is part of the v0.8
protocol (docs/a2ui/protocol.md §2.2 and data-and-actions.md).

Changes:
- Parser (A2UIProtocol.cs): add `DataModelEntry.ValueArray`; `ToJsonNode()`
  emits a `JsonArray`; new `ParseValueArray`/`ParseArrayElement` handle
  value-typed object elements, bare primitives (`["a",1,true]`), nested
  maps/arrays, and preserve JSON null as a stable index slot.
- DoS guard (DataModelStore.cs): the 32-deep depth bound now recurses
  `valueArray` as well as `valueMap`.
- Security (SecretRedactor.cs): the array branch now redacts registered/
  denylisted element paths instead of only recursing, so a secret seeded into
  an array (e.g. an obscured field bound to /codes/0) no longer leaks via
  canvas.a2ui.dump.
- Docs (SKILL.md): correct the stale "arrays are not first-class" note.

Tests: parser coverage for valueArray (strings, mixed scalars, maps, nested
arrays, bare primitives, empty, null slots) plus valueMap/scalar regressions;
secret-redaction regressions for secrets inside arrays; store-level base-path
landing and depth-guard rejection; and an end-to-end MultipleChoice surface
seeded via valueArray that asserts both the snapshot and the rendered
preselection.

Validation: build.ps1 (all projects), Shared.Tests, Tray.Tests, and A2UI
UITests all pass.

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

* Fix valueArray redaction and notifications

Reject non-canonical array pointer indices for data-model array access, notify descendant subscribers when container values are replaced, and redact registered secret descendants when action contexts or snapshots include parent paths.

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

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
* Fix canvas navigation URL handling

* Fix canvas navigate dispatcher timeout

Route canvas.navigate through the same dispatcher timeout guard used by canvas.eval and canvas.snapshot so stalled UI dispatch cannot hang MCP tool calls indefinitely.

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

---------

Co-authored-by: Scott Hanselman <scott@hanselman.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add TTS provider fallback and tts.status readiness command

When the requested/configured TTS provider isn't usable (no ElevenLabs key,
Piper voice not downloaded), gracefully fall back to Windows TTS instead of
throwing, and report the effective vs requested provider plus a fellBack flag.
A stale configured Windows voice now degrades to the system default voice so
the fallback always speaks.

Add a tts.status node command that reports per-provider readiness
(ready/needs-api-key/needs-voice/voice-not-downloaded/unavailable) plus the
configured/effective provider and willFallBack. PII-free. Wired across
DangerousCommands gating, MCP descriptions, skill.md, and the setup allowlist
export. Fix a stale pre-GA SHA-256 TODO docstring in PiperVoiceManager
(verification is already implemented and enforced by AssetHashPinningTests).

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

* Preserve configured TTS fallback for chat playback

Leave chat playback provider unset so TextToSpeechService can distinguish configured/default playback from explicit provider requests and apply the new Windows fallback when the configured provider is unavailable.

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

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
Validate screen.snapshot image formats before invoking the capture backend, normalize jpg to jpeg, and derive the response data URI MIME type from the validated format instead of the backend echo.

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…w#824)

* Wizard protocol resilience: progress/non-interactive steps, auth prompts, restart hardening

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

* Harden wizard progress polling budget

Allow a single long-running gateway progress step to use the full bounded progress budget instead of failing after the previous shorter per-step cap. Share the progress constants between the setup runner and UI and cover the intended budget in tests.

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

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
Measure the tray popup against its final client width and apply pixel-exact window sizing so wrapped content determines height deterministically.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Normalize the Sandbox page toggle off when MXC is definitively unavailable, reject turning it back on in the host-fallback mode, and preserve strict fallback blocking so users who opted into command denial remain protected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Squashed from PR openclaw#800 after maintainer review and local fixes.\n\nLocal validation:\n- .\\build.ps1\n- dotnet test .\\tests\\OpenClaw.Shared.Tests\\OpenClaw.Shared.Tests.csproj --no-restore\n- dotnet test .\\tests\\OpenClaw.Tray.Tests\\OpenClaw.Tray.Tests.csproj --no-restore\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* test: add Gateway MXC runtime E2E proof

* test: probe MXC E2E gate with discovered wxc-exec

* test: extend Gateway MXC E2E timeout budgets

* test: avoid blocked redirection in Gateway MXC deny proof

* test: prove MXC denied copy reaches destination

* test: document serialized MXC E2E collection gate

* test: raise MXC E2E sandbox timeout cap

* test: approve MXC denied-write copy proof step

* test: sync MXC approval proof diagnostics

* test: narrow MXC exec approval proof policy

* ci: extend setup-connect E2E timeout

Give only the setup-connect E2E shard extra time for the combined setup and MXC runtime proof fixtures while leaving the other E2E shards on the existing budget.

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

* fix: omit unsupported MXC denied paths

Windows wxc-exec rejects filesystem.deniedPaths before launching the sandboxed command. Keep denied paths as the local allow-list filter, but omit the unsupported backend field so AppContainer default-deny can run the command while still stripping parent/exact grants over sensitive paths.

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

---------

Co-authored-by: Vitor Cepeda Lopes <7040636+TheAngryPit@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
)

* Improve remote gateway setup and connection error recovery

Add RemoteGatewayClassifier + GatewayErrorClassifier in OpenClaw.Shared and
wire ConnectionPage remote setup advice, scope/token-drift/TLS recovery, and
localized strings.

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

* Clear stale SSH fields for setup-code flow

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
* Node mode UI: surface MCP-only/connecting states and repair gateway-node gating

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

* Fix MCP-only node status visibility

Surface the local MCP-only node card even when no gateway/operator session exists, and make the reconnect-backoff test wait for server-side accept publication.

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

* Keep MCP-only mode from joining gateways

Gate the post-operator local NodeService auto-connect on EnableNodeMode so local MCP-only serving does not create gateway node pairing requests.

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

* Request node reconnect in shared-token setup E2E

The shared-token setup path can now remain MCP-only after operator approval, so the E2E needs to request node reconnect explicitly before waiting for a node credential.

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

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
)

A connection/auth failure rendered two error bars: the global top-window
InfoBar plus an in-page "Connection Error" InfoBar on the Connection page.
The auth pipeline also published two global notifications for one failure,
which forced the banner action to degrade to "Show more".

Remove the in-page AuthErrorBar and consolidate to one top banner that:
- carries the gateway/node error states the in-page bar covered
- always routes the user to the Connection page via an "Open Connection"
  action (connection notifications are prioritized as the visible banner,
  preferring an actionable one over an action-less transient)
- renders as a single thin line: bold headline + " - detail", with the
  action as a right-aligned hyperlink (Windows-aligned InfoBar)

Other changes:
- Stop publishing the duplicate connection:authentication-failed banner;
  the snapshot-driven connection:issue notification is the single source.
- Re-home transient errors: WSL host-action failures use the inline card
  status (or a top notification when the card is hidden); connect/switch
  failures publish via ShowTransientConnectionError on the same banner id.
- Remove now-dead resw strings (ConnectionPage_AuthGuidance*,
  ConnectionPage_ConnectFailed) across all five locales.

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add tray live dashboard glance

Add a compact status summary to the tray flyout that surfaces gateway health, refresh freshness, session and usage metrics, and the current session preview before the existing action rows.

Wire a Diagnostics action into the tray menu and keep the summary computation in a testable, render-free builder shared by existing usage/session rows.

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

* Remove message previews from tray glance

Keep the tray dashboard focused on health, freshness, session metadata, and usage while avoiding conversation message text in the top-level flyout.

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

* Avoid activity snippets in tray dashboard glance

Keep the top-level tray dashboard limited to stable metadata so command, query, path, or URL activity text stays out of the glance.

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

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
Move notifications from the footer rail into a title-bar bell flyout and replace the compact connection status dots with a status pill plus detail flyout. Keep the status presentation aligned with the Connection page by deriving node state from shared presenter logic and the node-mode/capability settings.

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Port PR openclaw#562 onto current main and harden diagnostics redaction so JSONL remains parseable while sensitive values, metadata keys, paths, emails, headers, and compound JSON values are sanitized before export.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
shanselman and others added 28 commits July 6, 2026 16:04
Keep release identity as the default and require explicit opt-in for side-by-side dev builds.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fix LocalizationHelper so runtime callers passing XAML property resource keys like ConnectionPage_Connect2.Content resolve through MRT path segments like ConnectionPage_Connect2/Content instead of displaying raw keys.

Validation: GitHub Build and Test, CodeQL gate, Socket checks all passed.
Refine the gateway setup wizard UX, improve accessibility names, make wizard text selectable, and fix the expanded-provider step id handling.

Follow-up included in this merge: remove the stale 'More' overflow button when resetting wizard steps so it cannot leak onto later steps.

Validation: local build.ps1, Shared tests, Tray tests; GitHub Build and Test, CodeQL gate, Socket checks all passed.
Remove the footer/sidebar Notifications navigation item so Notifications remains available through the title-bar bell only.

Validation: GitHub Build and Test, CodeQL, Socket checks all passed; UIA proof confirmed the bell remains and no sidebar/footer Notifications row is present.
Add a shared red-bot BrandMark control and replace lobster/generic robot brand marks across Hub, onboarding, dialogs, and Agent Events surfaces while keeping native Windows accent colors unchanged.

Validation: GitHub Build and Test, CodeQL gate, Socket checks all passed; current-head visual/UI proof included in PR.
Fix queued chat message parity by assigning stable queued send run IDs/idempotency keys, reconciling duplicate prompts by queue/run identity, handling deferred in_flight admission with bounded retries, adding per-entry queue cancel/remove controls, and exposing local MCP queue list/cancel commands.

Follow-up review blocker resolved: local echo suppressors are deduped and removed by queued message ID, with regression coverage for in_flight retry followed by a later same-text remote user message.

Validation: GitHub Build and Test, CodeQL gate, Socket checks all passed; PR includes local build/test counts plus winnode MCP list/cancel proof.
Align tray app display identity across runtime AppUserModelID, executable metadata, installer shortcut AUMIDs, manifest identity, and approval/permission popup titles so Windows surfaces show OpenClaw Companion instead of OpenClaw.Tray.WinUI.

Validation: local build.ps1, Shared tests, Tray tests; GitHub Build and Test, CodeQL, Socket checks all passed. Local proof confirmed built FileDescription/ProductName, installer AUMID declarations, manifest identity, and live OpenClaw Companion app/window identity.
Move STT/TTS capability toggles to Permissions while keeping speech provider/model/voice setup in Voice & Audio. Disabled voice input now routes users to Permissions; missing speech model setup routes users to Voice & Audio.

Validation: local build; GitHub Build and Test, CodeQL, Socket checks all passed. Live UX proof confirmed disabled STT opens Permissions, missing model opens Voice & Audio, and Voice & Audio setup controls remain available.
Persist the user-selected native chat session, prefer it on remount while it still exists, keep it pending until sessions.list proves otherwise, and prevent stale debounced default-state writes from overwriting explicit selections.

Validation: focused local OpenClawChatDataProvider test run (223 tests) passed; GitHub Build and Test, CodeQL gate, Socket checks all passed.
…nclaw#945)

Mirror connection status onto tray and HubWindow icons using the updated badge policy: neutral/error attention states are badged, connected/connecting uses the plain lobster.

Validation: local build; GitHub Build and Test, CodeQL, Socket checks all passed. Live proof: current head launched against the maintainer normal profile and tray/taskbar icon behavior was visually confirmed.
Share session-title formatting between native Chat and the Sessions page, adding deterministic disambiguation when display names collide while preserving original session keys for navigation and actions.

This is the openclaw#955 app/test change set without the optional workflow proof-summary plumbing.

Validation: focused local OpenClawChatDataProvider/SessionTitleFormatter test run passed (234 tests); GitHub Build and Test, CodeQL, E2E, win-x64/win-arm64 builds all passed. Maintainer live-tested against a real profile containing duplicate session titles.

Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Make active gateway switching persisted, observable, rollback-safe, and stale-event resistant; add detailed credential resolution states and UI/diagnostic projection; harden credential mutation paths.

Policy accepted: unreadable/corrupt identity may use visible same-gateway shared/bootstrap fallback; readable device tokens always take precedence and credentials never cross gateway records.

Validation: PR CI green; gateway-mediated openclaw nodes invoke proof; existing-profile proof; current-main local merge validation passed build, Shared 2724/31 skipped, Tray 1662, and Connection 422 tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Expose read-only local MCP diagnostics for connection state and saved gateways. Add snapshot-derived projection, command docs, and regression coverage for credential-safe URL display and degenerate gateway records.

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix: authorize exact commands inside gateway wrappers

* fix: preserve wrapper prompt semantics

* fix: make Windows MXC defaults executable

* fix: report Windows node command success
* Add OpenTelemetry endpoint probe

Add Diagnostics UI for configuring an OpenTelemetry connection with explicit OTLP/gRPC or OTLP/HTTP protocol selection. Persist the endpoint and protocol settings, create a probe-only tray connector, and send a single minimal OpenTelemetry probe when a saved endpoint is configured.

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

* Add OpenTelemetry helper API

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

* Refine OpenTelemetry helper API

Split shared telemetry names from span-local attributes, keep span names at point of use, and make helper outcome tagging consistent across success, failure, and cancellation.

Validation:

.\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

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

* Add OpenTelemetry metrics helpers

Add shared System.Diagnostics.Metrics helpers and emit a probe counter alongside the existing OTLP trace probe. Register and flush both trace and metric providers from the tray-owned exporter path.

Validation:

.\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

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

* Add OpenTelemetry log export probe

Wire the tray-owned OpenTelemetry sink to emit a safe structured log probe alongside trace and metric probes. Add an allowlisted log export policy, include log flushing in probe lifecycle checks, and cover the policy in tray tests.

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

* Harden OpenTelemetry endpoint handling

Reject credential-bearing or parameterized endpoint URLs, reset protocol defaults on clear, and make probe sink disposal best-effort during reconfiguration and shutdown.

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

* Fix OTLP HTTP signal endpoints

Derive trace, metric, and log HTTP/protobuf exporter URLs from the configured collector base while preserving gRPC endpoint behavior. Normalize version-only and signal-specific HTTP paths before appending signal suffixes, and add focused coverage for base paths, /v1 paths, signal-specific inputs, mixed-case suffixes, and gRPC pass-through.

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

* Document OpenTelemetry diagnostics boundary

Add telemetry documentation covering opt-in behavior, current probe-only exports, future instrumentation boundaries, endpoint handling, and plain HTTP guidance.

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

* Add telemetry guardrails for agents

Point agents at the durable telemetry conventions and summarize the operational rules for safe OpenTelemetry changes.

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

* Address telemetry review follow-ups

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

* Allow retrying telemetry probes

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

Copilot-Session: 4f0e93ff-d320-454d-b00a-865dac727d0c

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Scott Hanselman <scott@hanselman.com>
* chore: align pull request template

* chore: preserve Windows validation in PR template
openclaw#975)

Bumps [github/gh-aw-actions/setup-cli](https://github.com/github/gh-aw-actions) from 0.82.2 to 0.82.8.
- [Release notes](https://github.com/github/gh-aw-actions/releases)
- [Changelog](https://github.com/github/gh-aw-actions/blob/main/CHANGELOG.md)
- [Commits](github/gh-aw-actions@3fac1cf...99d9d88)

---
updated-dependencies:
- dependency-name: github/gh-aw-actions/setup-cli
  dependency-version: 0.82.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
updated-dependencies:
- dependency-name: GitVersion.MsBuild
  dependency-version: 6.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
updated-dependencies:
- dependency-name: gitversion.tool
  dependency-version: 6.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
updated-dependencies:
- dependency-name: Microsoft.ML.OnnxRuntime
  dependency-version: 1.27.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Foundation for the god-object refactor's anti-regression mechanism.

- docs/ARCHITECTURE.md: living ownership ledger (schema + rows) and AGENTS.md pointer
- ArchitectureLedgerConsistencyTests: validates ledger schema, guard-test Type.Method
  format, and that named guard tests actually exist in the tests source
- tests/OpenClaw.TestSupport (Shared-only): TempDirectory, EnvironmentScope, CliHarness,
  FakeMcpServer, SettingsDataBuilder
- GatewayRecordBuilder lives in OpenClaw.Connection.Tests so the shared lib stays
  Connection-free (no transitive Connection dep on CLI tests)
- Migrated GatewayRegistryTests to TempDirectory; de-duplicated the WinNode FakeMcpServer

No production (src/) changes: tests and docs only.

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

Copy link
Copy Markdown
Owner Author

Superseded — reopened against the main repo openclaw/openclaw-windows-node (openclaw#990).

@bkudiess bkudiess closed this Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.