Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ jobs:
- name: Architecture names, release authentication and signed targets
run: node --test scripts/test-native-arch.mjs scripts/test-native-release-auth.mjs
- name: Debian package assembly, runtime repack and desktop metadata
run: node --test scripts/test-native-deb.mjs scripts/test-llama-runtime.mjs scripts/test-native-desktop-metadata.mjs scripts/test-native-app-run.mjs
run: node --test scripts/test-native-deb.mjs scripts/test-llama-runtime.mjs scripts/test-native-desktop-metadata.mjs scripts/test-native-app-run.mjs scripts/test-native-webkit-paths.mjs
- name: Packaging PATH and pinned sources
run: node --test scripts/test-native-packaging-env.mjs scripts/test-native-source-fetch.mjs
- name: Installer on this architecture
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
- name: Native window dependencies
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev librsvg2-dev libayatana-appindicator3-dev libasound2-dev patchelf webkit2gtk-driver xvfb appstream dbus-daemon dbus-bin lintian desktop-file-utils xdg-utils
- name: Test release staging and immutable retry behavior
run: node --test scripts/test-native-release.mjs scripts/test-native-release-verification.mjs scripts/test-publisher-auth.mjs scripts/test-native-release-signing.mjs scripts/test-native-test-session.mjs scripts/test-clean-host-mcp-receipt.mjs scripts/test-clean-host-container.mjs scripts/test-native-app-run.mjs scripts/test-llama-build-inputs.mjs scripts/test-native-arch.mjs && node scripts/test-native-process-ownership.mjs
run: node --test scripts/test-native-release.mjs scripts/test-native-release-verification.mjs scripts/test-publisher-auth.mjs scripts/test-native-release-signing.mjs scripts/test-native-test-session.mjs scripts/test-clean-host-mcp-receipt.mjs scripts/test-clean-host-container.mjs scripts/test-native-app-run.mjs scripts/test-native-webkit-paths.mjs scripts/test-llama-build-inputs.mjs scripts/test-native-arch.mjs && node scripts/test-native-process-ownership.mjs
- name: Verify publisher authentication and private release snapshots
run: node --test scripts/test-native-release-auth.mjs scripts/test-check-secrets.mjs
- name: Package version
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ jobs:
cache-dependency-path: ui/package-lock.json
- name: Native package dependencies
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev librsvg2-dev libayatana-appindicator3-dev libasound2-dev patchelf webkit2gtk-driver xvfb appstream dbus-daemon dbus-bin lintian desktop-file-utils
# Additional mandatory regression coverage keeps the independently approved
# signing receipt command set byte-identical. No existing gate is removed.
- name: Verify WebKit relocation before release qualification
run: node --test --test-reporter=tap scripts/test-native-webkit-paths.mjs
- name: Test release staging and immutable retry behavior
run: node scripts/native-release-verification.mjs run release-tests
- name: Verify publisher authentication and private release snapshots
Expand Down Expand Up @@ -174,6 +178,10 @@ jobs:
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev librsvg2-dev libayatana-appindicator3-dev libasound2-dev patchelf webkit2gtk-driver xvfb appstream dbus-daemon dbus-bin lintian desktop-file-utils xdg-utils cmake ninja-build libssl-dev libvulkan-dev glslc spirv-headers gcc-14 g++-14
- name: Install the pinned Rust toolchain
run: rustup toolchain install 1.95.0 --profile minimal --component rustfmt --component clippy
# Additional mandatory regression coverage keeps the independently approved
# signing receipt command set byte-identical. No existing gate is removed.
- name: Verify WebKit relocation before release qualification
run: node --test --test-reporter=tap scripts/test-native-webkit-paths.mjs
- name: Run every required release gate in order on aarch64
run: |
set -euo pipefail
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## Unreleased

## 2.3.2: Desktop reliability

- Relocate bundled WebKit helper paths so AppImages do not depend on the build host's Debian filesystem layout. Verify relocation against the shipped library bytes.
- On compatible non-Debian desktop layouts, select a complete host WebKit/GTK stack to avoid mixing newer Mesa drivers with the bundled Debian graphics stack. Both helper executables and all native dependencies are checked; the bundled fallback remains available. No sandbox is disabled.
- Closing the model picker no longer steals focus back from a composer the user has already focused. This fixes interrupted typing and accidental picker reopening.
- Vendor discovery no longer selects unknown or interactive ACP authentication methods such as Grok browser login. It checks an existing session and leaves interactive sign-in to Connect. Known existing-login methods remain supported.
- Sidebar shortcuts display Command on Apple keyboards and Control on Windows/Linux.
- Add installed-engine endurance qualification for Windows, macOS, and Linux, with platform-specific process measurements and explicit test-scope limits.
- Editor browser tests use the platform's document-navigation and editing shortcuts.


- About → Website now opens https://shadowcode.org (was shadowfetchlinux.org/shadowcode); the AppStream homepage URL matches.

## 2.3.1: Delegation prerequisites
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ exclude = ["vendor/glib-0.18.5"]
resolver = "2"

[workspace.package]
version = "2.3.1"
version = "2.3.2"
edition = "2021"
rust-version = "1.95"
license = "Apache-2.0"
Expand Down
96 changes: 96 additions & 0 deletions docs/PLATFORM_QUALIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Physical-machine platform qualification

## 2.3.2 candidate — November 1, 2026

This is a qualification record, not a claim that the candidate has been released.
Final package installation, hashes, screenshots, and website deployment receipts
will be added after the release builds. Prior evidence remains version-specific.

### Problems reproduced

- On Omarchy/Arch, the public 2.3.1 AppImage's engine CLI started, but its native
window failed when WebKit looked for `WebKitNetworkProcess` at the Debian build
host's absolute path. That path does not exist on Arch. Relocating the compiled
helper paths then exposed an EGL initialization failure with the bundled stack
and the host's newer Mesa drivers.
- The candidate relocates only the known, equal-length WebKit path strings,
checks both helper executables, retains a before/after hash receipt and the
relocation program in the package, and verifies the actual packaged library.
- The launcher can select a complete host WebKit/GTK stack when its helper layout
differs from Debian. It refuses missing native dependencies or helpers. It keeps
AppImage extraction ownership, does not disable the sandbox, and avoids probing
the graphics stack for ordinary CLI commands. `SHADOWCODE_APPIMAGE_STACK` can be
`auto` (default), `bundled`, or `host`; explicitly requesting an incomplete host
stack fails rather than silently selecting it.
- The isolated candidate AppDir on Omarchy reached the native first-window-loaded
marker after this change. This does not yet qualify a final signed 2.3.2 AppImage.
- The model picker could restore focus after model selection had already focused
the composer. Typing a space could then reopen the picker. A deterministic unit
regression failed before the fix. Close now respects focus moved outside the
picker, including focus moved synchronously by the selection callback.
- Editor browser scenarios sent Control shortcuts on macOS; they now use the
platform's Command editing and document-navigation shortcuts. Sidebar hints
follow the viewing keyboard, including remote browsers.

- Physical desktop testing also reproduced Grok's interactive `authenticate` flow
opening a browser during background discovery. The probe now authenticates only
through known existing-login methods; other advertised methods use `session/new`
to check an existing login and leave interactive authentication to explicit Connect.
A regression covers both an existing session and authentication-required responses.

### Physical Wayland packaging experiment

A focused native-window smoke ran on the actual Omarchy Hyprland compositor with
its existing tiling and scale. It passed 12 checks: onboarding, picker and refresh,
local test-model registration/selection, accessibility checks, approved file-write
and command execution, the completed task summary, and application/child shutdown.
The executable was the 2.3.1 baseline in an isolated AppDir with the candidate
launcher and library relocation. A scripted test server supplied model responses;
this is neither real inference nor final 2.3.2 package qualification.

The unmodified upstream desktop suite first rejected the compositor's tiled size
because it expected a floating window fitted to 90% of the screen. That failure
is retained. The focused smoke explicitly excludes floating-size policy, scripted
resizing, recovery and endurance. Grok was excluded from the successful baseline
smoke after its unsolicited login was reproduced; candidate Grok discovery has
separate regression coverage and still needs final physical-package verification.

### Installed-engine 2.3.1 baseline

The new `scripts/test-platform-runtime.mjs` was run on each physical machine's
installed native executable, with disposable profiles/projects and a loopback
scripted provider. Each passed 100 sequential tasks, 80 concurrent tasks, five
provider-stall cancellations, bounded resource growth, and retrieval of completed
and cancelled tasks after stopping and reopening the engine.

| Machine | Engine RSS, warm to final | Resource counts, warm to final | Result |
| --- | --- | --- | --- |
| Windows 11 x64 laptop | 23,964 → 32,856 KiB | 203 → 215 handles | Passed |
| Omarchy x64 laptop | 69,788 → 78,412 KiB | 18 → 18 file descriptors | Passed |
| Intel iMac, macOS 15 | 17,444 → 23,992 KiB | 15 → 15 file descriptors | Passed |

Raw versioned binary hashes and measurements are in
[`qa/platform-baseline-2.3.1/`](qa/platform-baseline-2.3.1/). Omarchy's native
executable was extracted from the publisher-authenticated installed AppImage.
The Windows installed runtime also passed the clean-PATH desktop, llama-server,
llama-cli, and isolated async CLI checks.

These engine results do not certify native rendering, inference-server memory,
real model quality/speed, GPU endurance, or cloud-provider accounts. Unix shutdown
uses SIGTERM; the Windows probe verifies persistence after forced termination and
does not claim graceful Windows shutdown. The original Linux stress suite keeps
its independent, stricter process-resource and SQLite-integrity coverage.

### Running the portable probe

Use Node 22 or newer. Set `SHADOW_STRESS_BINARY` to the installed native executable
(not an AppImage extraction wrapper or shell launcher), and optionally set
`SHADOW_STRESS_ARTIFACTS` to the output directory. Run:

```text
node scripts/test-platform-runtime.mjs
```

No API keys or downloaded model weights are required. This probe starts its own
loopback provider and engine and removes its temporary profile/project afterward.
It never runs tasks against the user's normal project or profile.
15 changes: 15 additions & 0 deletions docs/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# ShadowCode 2.3.2 — candidate

This source candidate addresses an AppImage desktop-startup failure reproduced on
Omarchy, a model-picker focus race, unsolicited interactive ACP login during vendor discovery, and misleading Mac keyboard hints. It is not
yet a qualified public release. Final package hashes, physical-machine results,
and publication receipts will be recorded after the release builds.

The new platform endurance probe exercises the installed native engine against
a loopback scripted provider. It measures 100 sequential tasks, 80 concurrent
tasks, five cancellations, process resource growth, and persisted state after
stopping/reopening. It does not certify desktop rendering, paid-provider
accounts, real-model quality, GPU inference, or inference-server memory.
Windows persistence is tested after forced process termination; graceful
Windows shutdown is not claimed by that probe.

# ShadowCode 2.3.1

Write-subagent guidance now names its Git-history prerequisite and directs
Expand Down
58 changes: 58 additions & 0 deletions docs/qa/platform-baseline-2.3.1/imac.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"passed": true,
"platform": "darwin",
"osRelease": "24.6.0",
"version": "ShadowCode 2.3.1",
"binarySha256": "0122cfbff84c62f113386db66998d521f64397ae5e62476559df1f374fc72c9a",
"sequentialCompleted": 100,
"concurrentCompleted": 80,
"cancelled": 5,
"requests": 367,
"measurements": [
{
"round": "warmup",
"rssKiB": 17444,
"threads": 6,
"resources": 15,
"resourceKind": "file descriptors"
},
{
"round": "sequential-25",
"rssKiB": 21148,
"threads": 6,
"resources": 15,
"resourceKind": "file descriptors"
},
{
"round": "sequential-50",
"rssKiB": 21704,
"threads": 6,
"resources": 15,
"resourceKind": "file descriptors"
},
{
"round": "sequential-75",
"rssKiB": 21768,
"threads": 6,
"resources": 15,
"resourceKind": "file descriptors"
},
{
"round": "sequential-100",
"rssKiB": 21840,
"threads": 7,
"resources": 15,
"resourceKind": "file descriptors"
},
{
"round": "completed",
"rssKiB": 23992,
"threads": 10,
"resources": 15,
"resourceKind": "file descriptors"
}
],
"persistenceAfterStop": true,
"shutdown": "SIGTERM graceful shutdown",
"scope": "Installed native engine with loopback scripted provider. Not desktop UI, paid providers, real model inference or inference-server memory."
}
58 changes: 58 additions & 0 deletions docs/qa/platform-baseline-2.3.1/omarchy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"passed": true,
"platform": "linux",
"osRelease": "7.2.8-9-omarchy",
"version": "ShadowCode 2.3.1",
"binarySha256": "86a0808c19ad48a5cac50a4df4805bba1f339c1b15b02d00a6d13e163fc64dce",
"sequentialCompleted": 100,
"concurrentCompleted": 80,
"cancelled": 5,
"requests": 367,
"measurements": [
{
"round": "warmup",
"rssKiB": 69788,
"threads": 6,
"resources": 18,
"resourceKind": "file descriptors"
},
{
"round": "sequential-25",
"rssKiB": 75312,
"threads": 6,
"resources": 18,
"resourceKind": "file descriptors"
},
{
"round": "sequential-50",
"rssKiB": 75968,
"threads": 6,
"resources": 18,
"resourceKind": "file descriptors"
},
{
"round": "sequential-75",
"rssKiB": 76360,
"threads": 7,
"resources": 18,
"resourceKind": "file descriptors"
},
{
"round": "sequential-100",
"rssKiB": 76376,
"threads": 7,
"resources": 18,
"resourceKind": "file descriptors"
},
{
"round": "completed",
"rssKiB": 78412,
"threads": 11,
"resources": 18,
"resourceKind": "file descriptors"
}
],
"persistenceAfterStop": true,
"shutdown": "SIGTERM graceful shutdown",
"scope": "Installed native engine with loopback scripted provider. Not desktop UI, paid providers, real model inference or inference-server memory."
}
58 changes: 58 additions & 0 deletions docs/qa/platform-baseline-2.3.1/windows.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"passed": true,
"platform": "win32",
"osRelease": "10.0.26200",
"version": "ShadowCode 2.3.1",
"binarySha256": "62c405b64b18c440eda1300d08f39056dab6d546d4b604eb8c0026095bfb55f2",
"sequentialCompleted": 100,
"concurrentCompleted": 80,
"cancelled": 5,
"requests": 367,
"measurements": [
{
"round": "warmup",
"rssKiB": 23964,
"threads": 14,
"resources": 203,
"resourceKind": "handles"
},
{
"round": "sequential-25",
"rssKiB": 27508,
"threads": 14,
"resources": 205,
"resourceKind": "handles"
},
{
"round": "sequential-50",
"rssKiB": 28144,
"threads": 14,
"resources": 205,
"resourceKind": "handles"
},
{
"round": "sequential-75",
"rssKiB": 28048,
"threads": 14,
"resources": 205,
"resourceKind": "handles"
},
{
"round": "sequential-100",
"rssKiB": 28216,
"threads": 14,
"resources": 205,
"resourceKind": "handles"
},
{
"round": "completed",
"rssKiB": 32856,
"threads": 16,
"resources": 215,
"resourceKind": "handles"
}
],
"persistenceAfterStop": true,
"shutdown": "forced termination; graceful shutdown not tested",
"scope": "Installed native engine with loopback scripted provider. Not desktop UI, paid providers, real model inference or inference-server memory."
}
Loading
Loading