Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2ba23ba
test(theme): guard color flower first paint
Aug 28, 2026
721d1c0
fix(composer): keep animated ring out of body fill
Aug 28, 2026
8782861
test(qa): use app semantic names for visual hooks
Aug 28, 2026
249f2bb
test(theme): reveal first-paint region deterministically
Aug 28, 2026
9cad448
fix(qa): use localized surface labels
Aug 28, 2026
0371b56
qa: guard native UI interaction outcomes
Aug 28, 2026
f65dba7
ci: require ps-qa 0.4.14
Aug 29, 2026
90a01dc
fix(ui): restore settings visuals and language outcomes
Aug 29, 2026
e6e0c36
qa: guard native controls visuals and memory
Aug 29, 2026
53982f7
fix(qa): point dropdown contract at restore check
Aug 29, 2026
2a3adc6
fix(qa): require driven dropdown restore outcome
Aug 29, 2026
3e823f5
ci: install current ps-qa release
Aug 29, 2026
f60c4f7
fix(ui): restore behavior and comprehensive native QA
Aug 29, 2026
8c16ab0
style(build): satisfy rustfmt
Aug 29, 2026
51c57fd
build: resolve one current runtime graph
Aug 29, 2026
f346121
ci: require the complete rendered QA manifest
Aug 29, 2026
284e4f2
perf(gui): finish reactive workspace and QA integration
Aug 29, 2026
7e5f917
fix(theme): make zero native glass tint explicit
Aug 29, 2026
a41e356
fix(ui): satisfy component and formatting contracts
Aug 29, 2026
0836ca9
test(select): assert persistent trigger output
Aug 29, 2026
b8cf517
test(qa): address stable rendered controls
Aug 29, 2026
5d98fd9
fix(ui): keep retained workspace responsive
Aug 30, 2026
2635d12
test(qa): guard native UI outcomes
Aug 30, 2026
e87d5f1
test(qa): close Settings outcome gaps
Aug 30, 2026
d8ba43f
test(qa): prove zero opacity clears native tint
Aug 30, 2026
500a5af
perf(ui): register app events concurrently
Aug 30, 2026
b426902
fix(ui): preserve scaled control outcomes
Aug 30, 2026
834353d
fix(settings): guard opacity and workspace layout
Aug 30, 2026
60ad9c0
fix(settings): standardize language and model selectors
Aug 30, 2026
f818d8e
fix(composer): keep disabled send icon solid
Aug 30, 2026
68d814f
test(qa): declare application expand controls
Aug 30, 2026
10a52c4
style(test): satisfy selector audit formatting
Aug 30, 2026
eed115e
chore(runtime): adopt published observability stack
Aug 30, 2026
47054a6
fix(qa): make native UI outcomes deterministic
Aug 30, 2026
89c8828
fix(items): persist optimistic rows without artificial delay
Aug 31, 2026
58dde9c
test(qa): target language selector by stable id
Aug 31, 2026
a01e816
fix(gui): flush queued work when run slot releases
Aug 31, 2026
7af018b
perf(gui): await lifecycle completion events
Aug 31, 2026
28e71bc
perf(gui): replace restart timing with handshakes
Aug 31, 2026
4bed226
build: use portable shell scripts and compatible Blitz ranges
Aug 31, 2026
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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Check portable shell scripts
run: /bin/sh tests/shell-scripts.sh

# The Tauri stack needs a webview toolchain to compile at all.
- name: Install Tauri system dependencies
run: |
Expand Down
78 changes: 50 additions & 28 deletions .github/workflows/qa-panel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ name: QA panel
# frontend and QA changes while making a UI dependency bump prove the exact
# package it resolves before that pull request can merge.
#
# Pull requests run the input-component contract groups and tree integrity.
# Manual runs can execute every declared outcome and optionally reconcile every
# control instance, keeping historical whole-application debt separate from a
# focused component regression gate.
# Pull requests run every declared outcome plus tree integrity. Manual runs can
# still select a focused group while authoring, or add inventory reconciliation
# and lifecycle checks for the exhaustive release audit.
on:
pull_request:
paths:
Expand All @@ -21,6 +20,7 @@ on:
- 'apps/gui/frontend/src/**'
- 'ps-qa.ron'
- 'scripts/qa-profile-restore.sh'
- 'scripts/qa-memory-navigation.sh'
- 'scripts/qa-run-groups.sh'
- 'tests/ps-qa/**'
workflow_dispatch:
Expand Down Expand Up @@ -53,6 +53,9 @@ jobs:
# for a cold release build and cleanup, but never leave a stale QA process
# occupying a runner for an hour.
timeout-minutes: 30
defaults:
run:
shell: zsh {0}
steps:
- uses: actions/checkout@v4

Expand All @@ -71,8 +74,7 @@ jobs:
# spending minutes building or launching an app with an incompatible
# harness release.
- name: Install ps-qa
# Compatible 0.4 releases preserve the reviewed QA profile contract.
run: cargo install ps-qa --version '^0.4.4'
run: cargo install ps-qa

- name: Validate the QA profile and outcome manifest
run: ps-qa --app ps-qa.ron list --checks tests/ps-qa
Expand Down Expand Up @@ -120,6 +122,7 @@ jobs:
run: |
launch_app() {
HOME=/tmp/qa-home AZ_DATA_DIR=/tmp/qa-profile-db \
AZ_QA_WORKSPACE_ROOT=/tmp/qa-profile-db-workspace \
./target/release/az-gui --blitz-control > /tmp/az-qa.log 2>&1 &
echo $! > /tmp/az-qa.pid
}
Expand Down Expand Up @@ -169,7 +172,7 @@ jobs:

- name: Run the focused input checks
id: checks
if: ${{ github.event_name == 'pull_request' || inputs.group != '' || inputs.suite == 'focused' }}
if: ${{ github.event_name == 'workflow_dispatch' && (inputs.group != '' || inputs.suite == 'focused') }}
continue-on-error: true
timeout-minutes: 3
env:
Expand Down Expand Up @@ -198,7 +201,7 @@ jobs:
# a blank group, after the focused regression is green.
- name: Run the complete behavior audit
id: full
if: ${{ github.event_name == 'workflow_dispatch' && inputs.group == '' && inputs.suite != 'focused' }}
if: ${{ github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.group == '' && inputs.suite != 'focused') }}
continue-on-error: true
timeout-minutes: 3
env:
Expand All @@ -217,7 +220,7 @@ jobs:
timeout-minutes: 3
run: |
set -o pipefail
ps-qa inventory 2>&1 | tee /tmp/cover.txt
ps-qa inventory --require-outcomes 2>&1 | tee /tmp/cover.txt
components="$(awk '/^components:/ { print $2; exit }' /tmp/cover.txt)"
unverified="$(awk '/^unverified:/ { print $2; exit }' /tmp/cover.txt)"
isolated="$(awk '/^isolated:/ { print $2; exit }' /tmp/cover.txt)"
Expand All @@ -238,19 +241,19 @@ jobs:
ps-qa reconcile /tmp/cover.txt --checks tests/ps-qa \
2>&1 | tee /tmp/sweep.txt

- name: Verify native navigation memory plateaus
if: ${{ github.event_name == 'workflow_dispatch' && inputs.group == '' && inputs.suite == 'exhaustive' && steps.full.outcome == 'success' }}
timeout-minutes: 2
run: scripts/qa-memory-navigation.sh

- name: Verify the inspection toggle disconnects control
id: isolated
if: ${{ github.event_name == 'workflow_dispatch' && inputs.group == '' && inputs.suite == 'exhaustive' && steps.full.outcome == 'success' }}
if: ${{ (github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.group == '' && inputs.suite == 'exhaustive')) && steps.full.outcome == 'success' }}
continue-on-error: true
run: |
ps-qa click Settings
sleep 2
ps-qa click "Enable inspection and agent control" \
ps-qa click '#tabs-settings'
ps-qa click '#settings-inspection-control' \
> /tmp/isolated.txt 2>&1 || true
if ps-qa nodes > /tmp/isolated-probe.txt 2>&1; then
ps-qa click "Enable inspection and agent control" \
>> /tmp/isolated.txt 2>&1 || true
fi
disconnected=0
for _ in $(seq 1 20); do
if ! ps-qa nodes > /tmp/isolated-probe.txt 2>&1; then
Expand All @@ -268,22 +271,41 @@ jobs:
# stopped at the first failure and silently hid later lifecycle failures.
- name: Enforce complete QA outcome
if: always()
env:
EVENT_NAME: ${{ github.event_name }}
REQUESTED_GROUP: ${{ inputs.group }}
REQUESTED_SUITE: ${{ inputs.suite }}
INTEGRITY_OUTCOME: ${{ steps.integrity.outcome }}
FOCUSED_OUTCOME: ${{ steps.checks.outcome }}
FULL_OUTCOME: ${{ steps.full.outcome }}
INVENTORY_OUTCOME: ${{ steps.inventory.outcome }}
SWEEP_OUTCOME: ${{ steps.sweep.outcome }}
ISOLATED_OUTCOME: ${{ steps.isolated.outcome }}
run: |
failed=0
for gate in \
'tree integrity:${{ steps.integrity.outcome }}' \
'focused input checks:${{ steps.checks.outcome }}' \
'complete behavior audit:${{ steps.full.outcome }}' \
'reachability inventory:${{ steps.inventory.outcome }}' \
'semantic sweep:${{ steps.sweep.outcome }}' \
'inspection toggle:${{ steps.isolated.outcome }}'; do
name="${gate%%:*}"
outcome="${gate#*:}"
if [ "$outcome" = failure ]; then
require_gate() {
local name="$1"
local outcome="$2"
if [[ "$outcome" != success ]]; then
echo "$name failed" >&2
failed=1
fi
done
}

require_gate 'tree integrity' "$INTEGRITY_OUTCOME"
if [[ "$EVENT_NAME" == pull_request ]]; then
require_gate 'complete behavior audit' "$FULL_OUTCOME"
require_gate 'inspection toggle' "$ISOLATED_OUTCOME"
elif [[ -n "$REQUESTED_GROUP" || "$REQUESTED_SUITE" == focused ]]; then
require_gate 'focused input checks' "$FOCUSED_OUTCOME"
else
require_gate 'complete behavior audit' "$FULL_OUTCOME"
fi
if [[ "$EVENT_NAME" == workflow_dispatch && -z "$REQUESTED_GROUP" && "$REQUESTED_SUITE" == exhaustive ]]; then
require_gate 'reachability inventory' "$INVENTORY_OUTCOME"
require_gate 'semantic sweep' "$SWEEP_OUTCOME"
require_gate 'inspection toggle' "$ISOLATED_OUTCOME"
fi
exit "$failed"

- name: Summary
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-experimental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
# See the same step in release.yml: the crates.io build of the CLI the
# npm package shims, so the release path never needs Node.
- name: Install the Tauri CLI
run: cargo install tauri-cli --version "^2.11"
run: cargo install tauri-cli

- name: Build the AgencyProxy sidecar
run: scripts/stage-agency-proxy-sidecar.sh
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ jobs:
# package is a thin Node shim around this binary, so taking it from
# crates.io is what keeps Node out of the release path entirely.
- name: Install the Tauri CLI
run: cargo install tauri-cli --version "^2.11"
run: cargo install tauri-cli

- name: Build the AgencyProxy sidecar
run: scripts/stage-agency-proxy-sidecar.sh
Expand Down
42 changes: 39 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ members = [
]

[workspace.package]
version = "0.8.41"
version = "0.8.48"
edition = "2024"
publish = false

Expand All @@ -21,8 +21,12 @@ az-core = { path = "crates/core" }
# time rather than at build time. Both are declared here so the pair cannot
# drift: the crates inherit these, and sidecar staging asks cargo for the
# resolved version instead of re-parsing the manifest to check they match.
agency-proxy-client = "0.1.7"
agency-proxy-protocol = "0.1.7"
agency-proxy-client = "^0.1.8"
agency-proxy-protocol = "^0.1.8"
# The GUI and both storage tools compile the same schema against one resolved
# WorkTable package. A workspace dependency prevents their compatible ranges
# from drifting into separate copies without freezing the selected patch.
worktable = "1.0.0-beta.11"

# Heavy deps are declared per-crate on purpose: only apps/gui pulls in the
# Tauri stack, so agent/proxy builds never trigger a webview toolchain build.
Expand All @@ -45,6 +49,38 @@ agency-proxy-protocol = "0.1.7"
debug = 0
incremental = true

# The frontend is JavaScript interpreted by Boa. Leaving the interpreter at
# dev's default opt-level 0 made a small Solid reaction take ~300ms in the QA
# build while the renderer itself took single-digit milliseconds. Keep AZ's own
# crates quick to compile, but build the long-lived script runtime like runtime
# code rather than like code under source-level debugging.
[profile.dev.package.ps-boa-engine]
opt-level = 2

[profile.dev.package.ps-boa-gc]
opt-level = 2

[profile.dev.package.ps-boa-string]
opt-level = 2

[profile.dev.package.ps-blitz-script]
opt-level = 2

# Pixel QA uses the renderer's real CPU paint path. At opt-level 0 even a
# 32x32 crop spends seconds repainting the window, so the inspector times out
# before it can compare first paint with the post-hover frame.
[profile.dev.package.ps-blitz-paint]
opt-level = 2

[profile.dev.package.ps-anyrender-vello-cpu]
opt-level = 2

[profile.dev.package.ps-vello-cpu]
opt-level = 2

[profile.dev.package.ps-glifo]
opt-level = 2

[profile.test]
# Tests need assertions and line-bearing panic output, not debugger symbols.
debug = 0
Expand Down
14 changes: 8 additions & 6 deletions apps/blitz-preview/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ build = "build.rs"
# with it the only genuinely headless path, from building at all.
anyrender = { package = "ps-anyrender", version = "^0.13.0" }
anyrender_vello_cpu = { package = "ps-anyrender-vello-cpu", version = "^0.16.0", optional = true }
blitz-dom = { package = "ps-blitz-dom", version = "^0.3.0-beta.11", features = ["system-fonts"] }
blitz-paint = { package = "ps-blitz-paint", version = "^0.3.0-beta.11", features = ["scrollbars"] }
blitz-script = { package = "ps-blitz-script", version = "^0.3.0-beta.11", features = ["system-fonts"] }
blitz-traits = { package = "ps-blitz-traits", version = "^0.3.0-beta.11" }
blitz-dom = { package = "ps-blitz-dom", version = "^0.3", features = ["system-fonts"] }
blitz-paint = { package = "ps-blitz-paint", version = "^0.3", features = ["scrollbars"] }
blitz-script = { package = "ps-blitz-script", version = "^0.3", features = ["system-fonts"] }
blitz-traits = { package = "ps-blitz-traits", version = "^0.3" }
brotli = { version = "^8.0.4", default-features = false, features = ["std"] }
png = { version = "^0.18.1", optional = true }
tauri = { version = "^2.11.5", default-features = false, features = ["compression"] }
tauri-runtime-blitz = "^0.1.0"
tauri-runtime-blitz = "^0.3"
url = "^2.5.8"

# For `--offscreen`: the activation policy has to be set before any window
Expand All @@ -36,7 +36,9 @@ brotli = { version = "^8.0.4", default-features = false, features = ["std"] }
tauri-build = { version = "^2.6.3", features = [] }

[dev-dependencies]
usvg = "^0.46.0"
# Use the renderer's SVG fork so geometry assertions inspect the exact tree
# type produced by Blitz instead of compiling a second, incompatible `usvg`.
usvg = { package = "ps-usvg", version = "^0.48.1" }

[features]
capture = ["dep:anyrender_vello_cpu", "dep:png"]
Expand Down
3 changes: 0 additions & 3 deletions apps/blitz-preview/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ fn compress_asset(path: &Path, output: &Path, quality: u32) -> usize {
input.len()
}




/// Drop framework load commands that nothing in this binary references.
///
/// On macOS `tauri` and `tauri-runtime` depend on `objc2-web-kit`
Expand Down
Loading
Loading