diff --git a/.github/workflows/msdk.yml b/.github/workflows/msdk.yml new file mode 100644 index 000000000..b73852f66 --- /dev/null +++ b/.github/workflows/msdk.yml @@ -0,0 +1,208 @@ +name: M-series SDK developer path + +on: + workflow_dispatch: + pull_request: + paths: + - "rust/msdk/**" + - "rust/msdk-gtk/**" + - "rust/claude-pantheon-rs/sdk/**" + - "rust/mseries-greeter/data/greeter.ui.json" + - "mseries/sdk-tests/**" + - "mseries/sdk-status-host/**" + - "mseries/dock-taskbar/TaskbarT3RPopover.vala" + - "mseries/codexbar-wingpanel/JsonBoundary.vala" + - "mseries/sdk-bench/**" + - ".github/workflows/msdk.yml" + push: + branches: [dev] + paths: + - "rust/msdk/**" + - "rust/msdk-gtk/**" + - "mseries/sdk-tests/**" + - "mseries/sdk-status-host/**" + - "mseries/dock-taskbar/TaskbarT3RPopover.vala" + - "mseries/codexbar-wingpanel/JsonBoundary.vala" + - "mseries/sdk-bench/**" + - ".github/workflows/msdk.yml" + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + qualify: + runs-on: ubuntu-26.04-arm + timeout-minutes: 25 + env: + CARGO_TARGET_DIR: ${{ github.workspace }}/work/sdk-target + steps: + - uses: actions/checkout@v7 + - name: Provision native SDK test environment + run: | + # The Azure mirror took >25 minutes for two Rust archives in run + # 40355512113. Use official Ubuntu ports with the existing signed trust. + sudo python3 - <<'PYTHON' + from pathlib import Path + import re + path = Path('/etc/apt/sources.list.d/ubuntu.sources') + text = path.read_text() + path.write_text(re.sub(r'(?m)^URIs:.*$', 'URIs: http://ports.ubuntu.com/ubuntu-ports', text)) + PYTHON + sudo apt-get -o Acquire::Retries=2 -o Acquire::http::Timeout=20 update + sudo apt-get -o Acquire::Retries=2 -o Acquire::http::Timeout=20 install -y --no-install-recommends cargo rustc rustfmt rust-clippy \ + build-essential pkg-config valac libgtk-4-dev libgranite-7-dev libjson-glib-dev libwayland-dev libwayland-bin \ + xvfb xauth dbus-x11 at-spi2-core dpkg-dev desktop-file-utils appstream python3-jsonschema python3-pyatspi python3-dbus xdotool x11-utils + - uses: actions/cache@v6 + with: + path: | + ~/.cargo/registry + work/sdk-target + key: msdk-native-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock') }} + restore-keys: msdk-native-${{ runner.arch }}- + - name: Prepare isolated SDK workspace + run: python3 mseries/sdk-tests/prepare.py "$RUNNER_TEMP/sdk" + - name: Core tests and strict lint + run: | + python3 -m unittest discover -s mseries/sdk-bench -p 'test_*.py' + cargo fmt --manifest-path "$RUNNER_TEMP/sdk/Cargo.toml" -p msdk --check + cargo test --manifest-path "$RUNNER_TEMP/sdk/Cargo.toml" -p msdk + cargo clippy --manifest-path "$RUNNER_TEMP/sdk/Cargo.toml" -p msdk --all-targets -- -D warnings + - name: Independent schema and checker agreement + run: python3 mseries/sdk-tests/check-schema.py --msdk "$CARGO_TARGET_DIR/debug/msdk" --rust-root "$RUNNER_TEMP/sdk" + - name: Build and test generated native application + run: | + mkdir -p "$RUNNER_TEMP/sdk-evidence" + "$CARGO_TARGET_DIR/debug/msdk" new settings "$RUNNER_TEMP/starter" --name 'SDK Settings' --id io.github.techmore.SdkSettings + "$CARGO_TARGET_DIR/debug/msdk" gen "$RUNNER_TEMP/starter/app.ui.json" "$RUNNER_TEMP/generated" --sdk-root "$RUNNER_TEMP/sdk" + cargo fmt --manifest-path "$RUNNER_TEMP/generated/Cargo.toml" + cargo test --manifest-path "$RUNNER_TEMP/generated/Cargo.toml" --all-targets + cargo clippy --manifest-path "$RUNNER_TEMP/generated/Cargo.toml" --all-targets -- -D warnings + for mode in light dark; do + theme=Adwaita + if [ "$mode" = dark ]; then theme=Adwaita:dark; fi + GTK_THEME="$theme" GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + "$CARGO_TARGET_DIR/debug/msdk-sdksettings" --screenshot "$RUNNER_TEMP/sdk-evidence/settings-$mode.png" + done + cp "$RUNNER_TEMP/sdk/Cargo.lock" "$RUNNER_TEMP/sdk-evidence/sdk-Cargo.lock" + cp "$RUNNER_TEMP/generated/Cargo.lock" "$RUNNER_TEMP/sdk-evidence/generated-Cargo.lock" + git rev-parse HEAD > "$RUNNER_TEMP/sdk-evidence/source.txt" + sha256sum "$CARGO_TARGET_DIR/debug/msdk-sdksettings" > "$RUNNER_TEMP/sdk-evidence/binary.sha256" + - name: Actual keyboard and accessibility controls + run: | + MSDK_PRIVATE_TEST_BUS=1 GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + python3 mseries/sdk-tests/controls.py --binary "$CARGO_TARGET_DIR/debug/msdk-sdksettings" --output "$RUNNER_TEMP/sdk-evidence/controls.json" + - name: Compact and larger-text render matrix + run: bash mseries/sdk-tests/render-matrix.sh "$CARGO_TARGET_DIR/debug/msdk-sdksettings" "$RUNNER_TEMP/sdk-evidence/matrix" + - name: Native host lifecycle + run: | + cargo clippy --manifest-path "$RUNNER_TEMP/sdk/Cargo.toml" -p msdk-gtk --all-targets -- -D warnings + MSDK_PRIVATE_TEST_BUS=1 XDG_DATA_HOME="$RUNNER_TEMP/sdk-state" GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + cargo test --manifest-path "$RUNNER_TEMP/sdk/Cargo.toml" -p msdk-gtk --test lifecycle --test runtime --test cli --test usage --test codexbar -- --test-threads=1 + - name: C host SDK usage boundary + run: | + cargo build --manifest-path "$RUNNER_TEMP/sdk/Cargo.toml" -p msdk-gtk --lib + cc -Wall -Wextra -Werror mseries/sdk-tests/usage-host-abi.c \ + -I "$RUNNER_TEMP/sdk/msdk-gtk/include" $(pkg-config --cflags --libs gtk4) \ + -L "$CARGO_TARGET_DIR/debug" -lmsdk_gtk -Wl,-rpath,"$CARGO_TARGET_DIR/debug" \ + -o "$RUNNER_TEMP/usage-host-abi" + printf '#!/bin/sh\nprintf x >> "%s"\necho "{}"\n' "$RUNNER_TEMP/usage-host-read" > "$RUNNER_TEMP/usage-host-fixture" + chmod 700 "$RUNNER_TEMP/usage-host-fixture" + GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + "$RUNNER_TEMP/usage-host-abi" "$RUNNER_TEMP/usage-host-fixture" "$RUNNER_TEMP/usage-host-read" + mkdir -p "$RUNNER_TEMP/vala-output" + valac --directory "$RUNNER_TEMP/vala-output" --pkg gtk4 --vapidir mseries/sdk-status-host --pkg msdk-usage \ + -X "-I$RUNNER_TEMP/sdk/msdk-gtk/include" -X "-L$CARGO_TARGET_DIR/debug" -X -lmsdk_gtk \ + -X "-Wl,-rpath,$CARGO_TARGET_DIR/debug" -o "$RUNNER_TEMP/usage-vala-host" mseries/sdk-status-host/UsagePage.vala mseries/sdk-tests/usage-vala-host.vala + rm -f "$RUNNER_TEMP/usage-host-read" + GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + "$RUNNER_TEMP/usage-vala-host" "$RUNNER_TEMP/usage-host-fixture" "$RUNNER_TEMP/usage-host-read" + - name: Shared desktop status menu with SDK usage + run: | + mkdir -p "$RUNNER_TEMP/status-home/.local/bin" "$RUNNER_TEMP/status-home/.config" "$RUNNER_TEMP/status-home/.cache" "$RUNNER_TEMP/vala-output" + cat > "$RUNNER_TEMP/status-home/.local/bin/codexbar-linux" <<'SCRIPT' + #!/bin/sh + printf x >> "$HOME/reads" + now=$(date -u +%Y-%m-%dT%H:%M:%SZ) + printf '{"schemaVersion":1,"entries":[{"provider":"codex","updatedAt":"%s","windows":[{"key":"week","label":"7 day","remaining":75,"resetsAt":""}]}]}\n' "$now" + SCRIPT + chmod 700 "$RUNNER_TEMP/status-home/.local/bin/codexbar-linux" + valac --directory "$RUNNER_TEMP/vala-output" --define MSDK_STATUS_HOST --pkg gtk4 --pkg granite-7 --pkg json-glib-1.0 --pkg gio-unix-2.0 \ + --vapidir mseries/sdk-status-host --pkg msdk-usage \ + -X "-I$RUNNER_TEMP/sdk/msdk-gtk/include" -X "-L$CARGO_TARGET_DIR/debug" -X -lmsdk_gtk -X "-Wl,-rpath,$CARGO_TARGET_DIR/debug" \ + -o "$RUNNER_TEMP/status-host-integration" mseries/sdk-status-host/UsagePage.vala \ + mseries/dock-taskbar/TaskbarT3RPopover.vala mseries/codexbar-wingpanel/JsonBoundary.vala \ + mseries/sdk-tests/status-host-stubs.vala mseries/sdk-tests/status-host-integration.vala + for mode in wingpanel dock; do + rm -f "$RUNNER_TEMP/status-home/reads" + HOME="$RUNNER_TEMP/status-home" XDG_CONFIG_HOME="$RUNNER_TEMP/status-home/.config" XDG_CACHE_HOME="$RUNNER_TEMP/status-home/.cache" \ + GSETTINGS_BACKEND=memory GTK_A11Y=none G_DEBUG=fatal-criticals GSK_RENDERER=cairo \ + xvfb-run -a dbus-run-session -- "$RUNNER_TEMP/status-host-integration" "$RUNNER_TEMP/status-home/reads" "$mode" + done + - name: Capture candidate usage rows for review + run: | + cargo build --manifest-path "$RUNNER_TEMP/sdk/Cargo.toml" -p msdk-gtk --examples + printf '#!/bin/sh\nprintf invalid-json\n' > "$RUNNER_TEMP/usage-fixture-failure" + chmod 700 "$RUNNER_TEMP/usage-fixture-failure" + icons="$RUNNER_TEMP/usage-data/icons/hicolor/scalable/apps" + mkdir -p "$icons" + for provider in openai claude grok opencode; do + install -m 644 "mseries/codexbar-wingpanel/icons/$provider.svg" "$icons/mseries-codexbar-$provider-symbolic.svg" + done + for mode in light dark; do + theme=Adwaita + if [ "$mode" = dark ]; then theme=Adwaita:dark; fi + for points in 10 15; do + config="$RUNNER_TEMP/usage-config-$mode-$points" + mkdir -p "$config/gtk-4.0" + printf '[Settings]\ngtk-font-name=Sans %s\n' "$points" > "$config/gtk-4.0/settings.ini" + XDG_DATA_HOME="$RUNNER_TEMP/usage-data" XDG_CONFIG_HOME="$config" GTK_THEME="$theme" GSK_RENDERER=cairo MSDK_MATRIX_POINTS="$points" \ + xvfb-run -a dbus-run-session -- bash -eu -c ' + python3 mseries/sdk-tests/font-profile.py + "$CARGO_TARGET_DIR/debug/examples/usage_preview" "$RUNNER_TEMP/sdk-evidence/usage-'"$mode"'-'"$points"'.png" + ' + XDG_DATA_HOME="$RUNNER_TEMP/usage-data" XDG_CONFIG_HOME="$config" GTK_THEME="$theme" GSK_RENDERER=cairo MSDK_USAGE_SCROLL_END=1 \ + xvfb-run -a dbus-run-session -- \ + "$CARGO_TARGET_DIR/debug/examples/usage_preview" "$RUNNER_TEMP/sdk-evidence/usage-$mode-$points-end.png" + XDG_DATA_HOME="$RUNNER_TEMP/usage-data" XDG_CONFIG_HOME="$config" GTK_THEME="$theme" GSK_RENDERER=cairo \ + xvfb-run -a dbus-run-session -- \ + "$CARGO_TARGET_DIR/debug/examples/usage_control_preview" "$RUNNER_TEMP/sdk-evidence/usage-error-$mode-$points.png" "$RUNNER_TEMP/usage-fixture-failure" + done + done + - name: Usage refresh keyboard and accessibility + run: | + MSDK_PRIVATE_TEST_BUS=1 GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + python3 mseries/sdk-tests/usage-controls.py \ + --binary "$CARGO_TARGET_DIR/debug/examples/usage_control_interactive" \ + --output "$RUNNER_TEMP/sdk-evidence/usage-controls.json" + - name: Candidate usage anchor interactions + run: | + MSDK_PRIVATE_TEST_BUS=1 GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + python3 mseries/sdk-tests/usage-anchor-controls.py \ + --binary "$CARGO_TARGET_DIR/debug/examples/usage_anchor_interactive" \ + --output "$RUNNER_TEMP/sdk-evidence/usage-anchor-controls.json" + - name: Package, install, reinstall and remove the generated app + run: | + "$CARGO_TARGET_DIR/debug/msdk" pack "$RUNNER_TEMP/generated" \ + --binary "$CARGO_TARGET_DIR/debug/msdk-sdksettings" \ + --output "$RUNNER_TEMP/sdk-evidence/settings.deb" + dpkg-deb --info "$RUNNER_TEMP/sdk-evidence/settings.deb" > "$RUNNER_TEMP/sdk-evidence/package-info.txt" + sudo dpkg --install "$RUNNER_TEMP/sdk-evidence/settings.deb" + sudo dpkg --install "$RUNNER_TEMP/sdk-evidence/settings.deb" + cmp "$CARGO_TARGET_DIR/debug/msdk-sdksettings" /usr/bin/io.github.techmore.SdkSettings + GTK_THEME=Adwaita GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + /usr/bin/io.github.techmore.SdkSettings --screenshot "$RUNNER_TEMP/sdk-evidence/installed.png" + sha256sum /usr/bin/io.github.techmore.SdkSettings > "$RUNNER_TEMP/sdk-evidence/installed.sha256" + sudo dpkg --remove msdk-io.github.techmore.sdksettings + test ! -e /usr/bin/io.github.techmore.SdkSettings + test ! -e /usr/share/applications/io.github.techmore.SdkSettings.desktop + test ! -e /usr/share/icons/hicolor/scalable/apps/io.github.techmore.SdkSettings.svg + - uses: actions/upload-artifact@v7 + if: always() + with: + name: msdk-native-${{ github.run_id }} + path: ${{ runner.temp }}/sdk-evidence/ + if-no-files-found: warn diff --git a/mseries/APP-BUILDING-GUIDE.md b/mseries/APP-BUILDING-GUIDE.md index a8d62558c..7d2e5a9df 100644 --- a/mseries/APP-BUILDING-GUIDE.md +++ b/mseries/APP-BUILDING-GUIDE.md @@ -8,6 +8,13 @@ The owner rejected the result. Both apps are incomplete and deferred. ## First establish what the person will experience +The owner clarified on 2026-10-26 that not every app needs a native experience. +Choose the UI architecture for the actual product journey: existing web UI, +wrapper, webview/hybrid or native controls as appropriate. SDK completion needs +reusable capabilities and representative integration proof, not native rewrites +of every app or full feature parity with every existing client. Do not promise +a WebView vocabulary component or other integration that has not been shipped. + Write a short outcome contract before implementation: - What opens, which window owns navigation, and what each primary action does. @@ -37,8 +44,9 @@ necessary. Do not add recurring notifications or timers just to enforce this rul ## Use the implemented SDK authoring path -Descriptions (`.msdk` or JSON), rules and declared services are the primary -authoring path. `msdk new` already generates a description, gates and README +For SDK-rendered native UI, descriptions (`.msdk` or JSON), rules and declared +services are the primary authoring path. This is not a requirement to replace +an appropriate existing frontend. `msdk new` generates a description, gates and README from six templates; it does not generate a complete Cargo project, backend, standalone executable or package. Use app-local Rust `Services`/`Logic` only where the supported vocabulary is insufficient; record each escape hatch and @@ -51,9 +59,13 @@ transport, account mappings and GitHub services remain app-specific adapters. Use `cargo run -p msdk -- templates` from `rust/` to discover actual starters, then the CLI's `describe`, `check` and `gate` commands. Consult -[RUST-PANTHEON-SDK.md](RUST-PANTHEON-SDK.md) for boundaries. Do not present -proposed `msdk gen`, `msdk pack`, `msdk parity` or live introspection commands -as available. Keep native chrome, scaling, accessibility, recoverable states, +[RUST-PANTHEON-SDK.md](RUST-PANTHEON-SDK.md) for boundaries. Use `msdk gen --sdk-root /rust` +when a standalone Cargo executable and typed models are needed. It preserves +rules and the GTK host; custom service backends are app-owned extension points. +Use `msdk pack --binary --output ` +on the matching Linux architecture after building the intended artifact; package +creation is separate from install/reinstall/remove and loaded-host qualification. +Do not present proposed `msdk parity` or live introspection commands as available. Keep native chrome, scaling, accessibility, recoverable states, diagnostics and install/remove behavior in the delivered outcome contract. ## Keep development builds fast diff --git a/mseries/OS9-HANDOFF.md b/mseries/OS9-HANDOFF.md index ed01210e4..5f80f1ff7 100644 --- a/mseries/OS9-HANDOFF.md +++ b/mseries/OS9-HANDOFF.md @@ -1,3 +1,843 @@ +## Candidate anchor hover failure — 2026-10-26 + +SDK desktop-host ARM workflow 40418084280 passed on attempt 2 at 64ca2db, including C/Vala host boundaries, shared T3 menu in hosted and dock modes with synthetic neighbors, and SDK/package checks. Attempt 1 passed host checks but its later private display failed to open; see `sdk-tests/receipts/2026-10-26-desktop-host-ci/`. Real desktop builds, installation, target GTK compatibility and owner acceptance remain open. + +SDK desktop-host work: an opt-in Plan usage page now shares the existing T3 menu source between Dock and Wingpanel, via a provisional C/Vala boundary. On a local ARM Ubuntu 26.04 VM with isolated synthetic data, the actual shared menu source passed hosted and dock-mode usage display, page switching and closed-read checks; neighboring indicators were stubs. Full Wingpanel/Dock build, installation, live desktop validation and GTK compatibility on the elementary target remain open. See `sdk-status-host/README.md`. + +ARM SDK run 40416161840 at 26a71f7 passed the candidate usage anchor interaction suite, including unpinned pointer exit, plus package lifecycle. The retained synthetic fixture receipt is `sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/`; actual status-host integration and target acceptance remain open. + +ARM run 40415797379 at 7fa281f passed the candidate usage anchor synthetic hover travel, pin, outside dismissal and keyboard interactions, and package lifecycle; see `sdk-tests/receipts/2026-10-26-usage-anchor-pass/`. This does not qualify an installed desktop host. An added explicit unpinned pointer-leave check is pending. + +ARM run 40412642984 at 98867b8 passed core, generated app, accessibility, lifecycle and usage-refresh steps. The candidate anchor opened and read once, but failed pointer travel; pinning and subsequent steps were not reached. See `sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/`. X11 surface diagnostics are being added; native interaction validation remains open. + +Candidate usage anchor: ARM run 40407270110 did not open on hover; diagnostics showed the test pointer on the X root and no synthetic read. The isolated fixture now exports GTK bounds for pointer placement. GTK documents that changing auto-hide hides a visible popover, so the candidate now closes and reopens on pinning without restarting its read; interaction validation remains pending. This is a reusable candidate, not an installed desktop host. See `sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/`. + +SDK run 40406733431 compiled 5c7dcbc but failed the synthetic hover interaction: +the Usage anchor was present while the popup was not observed. The failure is +retained under sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail; its cause +is unproven. The follow-up checks actual popup mapping and adds pointer/read +diagnostics. It needs source-matched native execution; no host acceptance is +claimed and no owner desktop was changed. + +## Candidate usage status anchor — native validation pending, 2026-10-26 + +An embeddable GTK UsageAnchor is modeled on the existing taskbar hover/pin +interaction and owns the UsageControl lifecycle without background polling. A +private synthetic X11/AT-SPI probe exercises hover focus, pointer travel, +hover-to-click pinning, outside dismissal, keyboard open/Escape and closed +no-read behavior. Native compilation and interaction tests are pending. This +widget is not installed in either real desktop profile; host adapters, real +provider coverage and owner acceptance remain open. No panel was restarted. + +## Usage control keyboard validation — 2026-10-26 + +Hosted ARM developer-path run 40405964283 passed on 477234a. A private synthetic +AT-SPI/keyboard probe found `Refresh usage` as a button, used Tab and Space to +exercise failure and retry, checked stale data and private-stderr exclusion, +and closed with Ctrl+Q. Four reviewed failure-state frames and the probe +receipt are in sdk-tests/receipts/2026-10-26-usage-keyboard-pass. Earlier +private-display and accessible-name failures remain retained. This does not +qualify keyboard scrolling, actual desktop status-host interactions, real +accounts or owner visual acceptance. + +## Usage accessibility name diagnosis — 2026-10-26 + +SDK run 40405291097 failed its synthetic keyboard probe on 9dac12e. The +retained AT-SPI tree shows a button named `Refresh` with role `button`, not the +expected `Refresh usage`. See sdk-tests/receipts/2026-10-26-usage-accessibility-tree. +The visible label has been changed to `Refresh usage` to match the intended +accessible name; GTK, keyboard and visual revalidation remain pending. The +previous X-display startup failure is separate and remains unexplained. + +## Usage keyboard probe failures — 2026-10-26 + +SDK run 40404146612 on 34a26fa failed twice: attempt 1 could not open the +private X display; attempt 2 opened the app but the expected accessible refresh +button was not found. Synthetic receipts are in +sdk-tests/receipts/2026-10-26-usage-keyboard-failures. Causes are unproven and +no keyboard acceptance is claimed. The follow-up records a bounded synthetic +accessibility tree on failure so the actual role/name can be diagnosed. + +## Usage keyboard and AT-SPI probe — validation pending, 2026-10-26 + +A private-session synthetic app and probe exercise the actual UsageControl via +Tab and Space, inspect the accessible name/role, provoke a failed refresh, retry +and close with Ctrl+Q. The probe records only synthetic data and checks private +stderr does not enter the accessible tree. Native execution is pending. This +standalone fixture does not prove keyboard behavior or focus in either actual +status host and does not touch real accounts or the owner desktop. + +## Usage refresh control validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40403452026 passed on e1c91a8. Native +synthetic tests cover open/busy/failure/retry and four failure-state light/dark +Sans 10/15 frames were reviewed and retained under +sdk-tests/receipts/2026-10-26-usage-control-final. Failure, stale data and the +Refresh button are visible in the fixture; the footer no longer repeats the +failure wording. Keyboard/AT-SPI, busy-state visual review, actual status hosts, +real collectors/accounts and owner approval remain open. + +## Usage control initial validation — 2026-10-26 + +Hosted ARM SDK run 40402684685 passed on a5b0ff2, including synthetic GTK +success/failure/retry and failure-state captures. Initial review found the +notice, stale data and refresh button readable, but the failure was repeated in +both the panel and footer. Four frames and limits are retained under +sdk-tests/receipts/2026-10-26-usage-control-first. The footer now says “Retry +when ready”; that follow-up still needs source-matched GTK and visual review. +Real collectors, keyboard/AT-SPI and actual desktop hosts remain open. + +## Usage refresh control — native validation pending, 2026-10-26 + +A candidate embeddable UsageControl exposes refresh, spinner and status around +the on-demand monitor. Explicit open starts one read; repeated open does not +start another, and close/unmap/drop cancel owned work. Native synthetic tests +exercise success, malformed-output failure and retry; the CI preview captures +failure state in light/dark at two text sizes. GTK execution and visual review +are pending. Actual status hosts, keyboard/AT-SPI interaction, real collector +and accounts remain unqualified; no panel or service was restarted. + +## On-demand usage refresh validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40401954793 passed on ee9cd5e after the +retained 58dd831 strict-lint failure. The native synthetic executable test +checks no reads while closed or merely opened, duplicate refresh coalescing, +source-age recheck at delivery, close/cancel, and a new refresh after reopening. +The fixture does not prove real collector/account behavior, visible refresh +controls, desktop-host integration or owner acceptance. No scheduled polling +or owner desktop service was started. + +## Refresh controller lint repair — 2026-10-26 + +SDK developer-path run 40401485674 failed at GTK strict clippy on 58dd831: +`needless_return` in the expired-reply match arm. The arm now uses unit. Native +controller tests did not run in that attempt and source-matched validation is +still required. The earlier failed run remains evidence, not a passing test. + +## On-demand usage refresh lifecycle — native validation pending, 2026-10-26 + +A candidate CodexBarMonitor explicitly opens/closes a UsagePanel, starts one +bounded read on request, coalesces duplicates, cancels/invalidate on close and +reports state to its host. It rechecks source age at final GTK delivery; no +polling is scheduled. Synthetic GTK tests cover closed/open no-read, duplicate +refresh, age, cancellation and reopen. The 107-test core suite and clippy pass +on macOS; source-matched GTK compilation and lifecycle execution are pending. +This does not connect either actual desktop status host or real provider data. + +## Scoped usage delivery validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40400566671 passed on 5a6a1e6. Its GTK +regression executes a synthetic snapshot program, applies a successful result, +rejects a queued result after a context switch, and checks that a later failure +shows a generic notice with last-known data marked stale and no private stderr. +The executable and data are synthetic; real collector/account integration, +actual desktop host interactions and visual review of the new failure state +remain open. No background polling or owner desktop service was started. + +## Scoped usage delivery — native validation pending, 2026-10-26 + +UsagePanel can consume the scoped CodexBar read on the GTK/state-owner thread: +old queued replies are ignored, and current failures retain last-known data as +stale with a generic notice. A synthetic executable-to-GTK regression covers +success, a context switch after queueing, failure and private-stderr exclusion. +Core usage tests and strict clippy pass on macOS; source-matched GTK execution +is pending. The caller still owns refresh, cancellation and host lifecycle. + +## Scoped CodexBar read validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40399879070 passed on 9e8fecc. Its five +CodexBar tests include an actual synthetic executable with a shell-sensitive +filename, literal `--snapshot` argument, malformed output and a context switch +that cancels the owned work and rejects the stale completion. The core test +also checks literal argv and preserved scope across transformation. These are +isolated synthetic executable tests, not a live collector or account read. +Real provider coverage, polling lifecycle and desktop status hosts remain open. + +## CodexBar bounded read adapter — native validation pending, 2026-10-26 + +A scoped direct-executable SDK process API runs literal argv without a shell. +The CodexBar adapter uses it for one five-second, two-MiB bounded `--snapshot` +read, retaining context until delivery and leaving polling/service management +to its caller. Synthetic executable tests cover arguments, malformed output and +context cancellation. The full 107-test core suite and strict clippy pass on +macOS; GTK adapter execution/source-matched Linux validation remain pending. +No live collector, account data, desktop service or daemon was touched. +## CodexBar snapshot decoder validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40398755850 passed on ee2eb68. Four decoder +regressions cover aggregate scope and partial coverage, null quota, source-time +freshness, future/expired values, malformed input, bounds and error redaction; +a native GTK widget test renders a synthetic v1 snapshot. This validates the +decoder against fixtures, not execution of a live collector, real accounts, +account-specific coverage or either actual desktop host. Those remain open. + +## CodexBar snapshot decoder — native validation pending, 2026-10-26 + +A bounded read-only decoder maps the existing CodexBar v1 provider snapshot to +candidate usage observations, retaining source timestamps and partial coverage. +It never claims account-specific usage from provider aggregates. Synthetic +regressions cover unknown, stale, future, expired and malformed data and a GTK +rendering path. No process, live backend or owner account is touched. GTK +compilation and source-matched native tests are pending; real collector reads, +account adapters and status-host integration remain open. + +## Usage viewport refresh validation — 2026-10-26 + +Hosted ARM developer-path run 40397942393 passed on cc2dace. Its native widget +regression rejects an invalid replacement, applies two valid updates and retains +a numeric scroll offset with unchanged-height synthetic content. Preview images +are retained in sdk-tests/receipts/2026-10-26-usage-viewport; reviewed frames +keep provider overview visible at the top. Semantic anchoring, shorter/changed +content behavior beyond clamping, keyboard/focus, real providers and both actual +status-area hosts remain open. No owner desktop or real accounts were touched. + +## Usage viewport refresh — validation pending, 2026-10-26 + +The candidate GTK UsagePanel provides a bounded read-only viewport and validates +replacement snapshots before display. It restores a prior numeric scroll offset +when refreshing and coalesces restoration after back-to-back updates. Native +tests exercise invalid replacement, multiple updates and scroll retention; the +synthetic preview now embeds this viewport. GTK compilation and execution on +this exact source remain pending. Semantic row anchoring, focus in interactive +children, provider refresh/teardown and actual status-host binding remain open. + +## Usage provider overview review — 2026-10-26 + +Hosted ARM SDK run 40397085739 passed on 0951bde, including the native widget +and scrolling regression. Eight synthetic light/dark Sans 10/15 top/end captures +are in sdk-tests/receipts/2026-10-26-usage-overview. All four fixture provider +names and partial coverage are visible on opening in both profiles; cards +remain separate and scrollable. Compact quota layout, long-label/translation, +keyboard interaction, real adapters, actual status hosts and owner acceptance +remain open. The overview is not proof of complete provider coverage. + +## Usage provider overview — validation pending, 2026-10-26 + +The candidate usage view now lists provider names and partial/unknown coverage +before the provider cards. Repeated sources for one provider remain separate +cards while the overview lists that provider once. The native regression checks +that the four-provider overview and partial coverage precede all account rows. +Source-matched GTK tests, top/end screenshots and visual review remain pending; +this is not an interactive status host or evidence of complete provider coverage. + +## Multi-provider usage fixture review — 2026-10-26 + +Hosted ARM SDK run 40396405090 passed on 2111eb1. Native synthetic checks cover +two Codex accounts, two Claude, Grok and OpenCode and a reachable programmatic +scroll end; eight reviewed top/end light/dark Sans 10/15 frames are retained in +sdk-tests/receipts/2026-10-26-usage-multiprovider. Existing CodexBar provider +marks were staged only in the isolated fixture. At large text only two providers +are visible on opening, so the provider-coverage presentation requirement is +still unmet. Keyboard scrolling, actual hosts, real adapters and owner visual +approval remain open. + +## Usage provider marks and scrolling fixture — validation pending, 2026-10-26 + +The candidate usage component can use existing CodexBar symbolic provider marks +when present and always retains a readable provider label when absent. The +synthetic preview now includes two Codex accounts, two Claude accounts, one +Grok and one OpenCode account in a bounded scroll viewport. The CI fixture +stages existing project icon assets in an isolated data directory and captures +top and bottom in light/dark Sans 10/15; a native regression checks multiple +accounts and scroll range. Source-matched GTK build/test, captures and visual +review remain pending. No provider adapter, real account or host is involved. + +## Usage card refinement review — 2026-10-26 + +Hosted ARM SDK run 40395621853 passed on dd96c00, including native widget +checks and four synthetic light/dark Sans 10/15 captures. Compared with the +previous preview, the card and account headings improve hierarchy and avoid +repeated stale text and awkward reset wrapping in the tested fixture. Evidence +is in sdk-tests/receipts/2026-10-26-usage-cards. Provider marks, compact quota +presentation, multi-provider/long-list review, host interactions, real adapters +and owner approval remain open; this is not full status-module acceptance. + +## Usage card hierarchy refinement — validation pending, 2026-10-26 + +The candidate usage rows now use a scoped, theme-derived card treatment based on +CodexBar's existing card styling. Account headings have stronger hierarchy; +stale is shown once per account, and reset text has a separate line for large +text. The widget regression also checks stale versus expired presentation. +This is not a provider mark, complete status control or visual acceptance. +Source-matched native GTK build, tests, new captures and independent review +are required before claiming an improvement. + +## Candidate usage preview review — 2026-10-26 + +Hosted ARM developer-path run 40395051297 passed on edf7a4e, including native +widget-tree regression and four synthetic usage screenshots. Review found the +candidate too flat versus the CodexBar reference: provider/account hierarchy is +weak, stale is repeated, and large-text wrapping is awkward. Images and scoped +findings are in sdk-tests/receipts/2026-10-26-usage-preview. The candidate is +not visually accepted; provider marks, compact hierarchy, interaction/scrolling, +hosts and real adapters remain open. The earlier d4bd990 compile failure is +retained above; the Rust orientation fix passed in this run. + +## Candidate usage GTK compile repair — 2026-10-26 + +Developer-path run 40394710018 failed compiling d4bd990 because the candidate +usage component used the Vala spelling `Orientation::VERTICAL` in Rust. The +three sites now use the Rust GTK spelling `Orientation::Vertical`. No native +widget test or screenshot ran in that attempt. Source-matched GTK validation +and visual review remain required; retain this failed attempt in the record. + +## Synthetic usage preview — validation pending, 2026-10-26 + +An isolated GTK example renders synthetic accounts and saves a window capture; +the SDK workflow builds it and captures light/dark at Sans 10 and 15 for review. +This is a candidate component preview, not a real status host or evidence of +visual acceptance. GTK compilation, all four captures and independent visual +review remain pending on the exact source. It must not read real account data. + +## Candidate usage GTK rows — validation pending, 2026-10-26 + +`msdk_gtk::usage::render` builds read-only provider/source and account rows from +validated snapshots with explicit unavailable, stale and expired states. A +native widget-tree test covers separate accounts, unknown/expired quota and +partial coverage. The data tests (4), complete macOS core suite (106) and strict +clippy pass. GTK compilation, native execution, light/dark/large-text visual +review and real status hosts remain open. This initial widget does not yet meet +the full CodexBar-derived status standard or implement refresh and actions. + +## Usage presentation inputs — 2026-10-26 + +The candidate usage snapshot now carries separate display labels and selected +state, and can group validated observations by provider and source while +preserving every account and separating aggregates. Four usage tests and all +106 core tests plus strict clippy pass on macOS. This prepares inputs for a +native control; it is not a widget, provider adapter or status host. The +source-matched Linux run for the prior commit is still in progress, and this +local change needs its own Linux, visual and interaction validation. + +## Usage observation snapshots — 2026-10-26 + +The candidate Rust usage data layer now supports explicit coverage and validates +snapshot identity, duplicate scopes/windows, source timestamps for fresh +observations and impossible token subsets. Distinct accounts and sources are +not merged; unknown values remain optional. Full macOS core tests (106) and +strict clippy pass. This is an in-memory API, not a wire protocol, collector, +presentation or status host. Source-matched Linux and the remaining status-area +integration and visual/interaction gates are still required. + +## Usage observation semantics — 2026-10-26 + +The candidate `msdk::usage` data API separates account/provider/source scope, +used and remaining quota, expired windows, unknown values and token subsets. +Debug omits scope identifiers. Three focused semantic tests and the complete +105-test core suite plus strict clippy pass on macOS. This is data groundwork; +collectors, cross-source deduplication, native presentation, both status hosts, +real interaction/visual review and source-matched Linux validation remain open. +The benchmark host is unreachable. See `SDK-USAGE-DATA.md` for the boundary. + +## SDK accessibility failure diagnosis — 2026-10-26 + +The synthetic failure artifact from developer-path run 40392328090 attempt 1 +shows GTK failed to open the display before accessibility registration. The +reason for the display failure remains unknown; attempt 2 passed. The original +receipt is retained in sdk-tests/receipts/2026-10-26-accessibility-failure. +The probe now reports a child exit immediately and preserves stderr, instead of +waiting for an accessibility-root timeout after the app has already exited. +Linux execution of this probe change remains to be verified. + +## Golden-path fixture validation — 2026-10-26 + +On dbf4eee, hosted ARM SDK/System Monitor run 40392327560 passed. SDK +Developer-path run 40392328090 attempt 1 failed because the generated app's +accessibility root was not observed within the probe timeout. Attempt 2 passed, +including that probe and the native runtime version-mismatch fixture/no-fallback +regression, then package lifecycle. The first failure is retained; its cause is +unknown and one retry does not establish that the probe is reliable. This tests +SDK extension negotiation, not an OS backend protocol or a timed novice trial. + +## Golden-path version injection — validation pending, 2026-10-26 + +Fixture files may specify an SDK extension `api_version` to exercise a visible +version mismatch without a real backend; invalid version values are rejected. +The golden-path guide describes the injection. A native regression checks the +error and verifies no built-in process fallback executes. GTK compilation and +source-matched native execution remain pending; this is not an OS backend +protocol compatibility result or a measured developer trial. + +## Context-bound feed validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40391629479 and SDK/System Monitor run +40391629511 passed on bb90bf7. The native GTK lifecycle test confirms a +current feed update reaches host state, an update from an advanced context is +ignored, rebinding is rejected, and the provider stops on close. This is an +explicitly bound test provider; legacy providers are unscoped, and cancelling +backend reads/subscriptions and displaying account identity remain provider +responsibilities. Physical Pantheon and model-trial gates remain open. + +## SDK context-bound feeds — validation pending, 2026-10-26 + +An opt-in typed feed endpoint carries an app-owned context to GTK delivery and +rejects stale updates. Legacy feeds remain compatible and unscoped; providers +must explicitly retire subscriptions and reads on context changes and close. +A native lifecycle regression covers delivery, context advance, rebinding +rejection and close. Source-matched Linux GTK compilation and execution are +required before this feature is claimed as validated; SER8 remains unreachable. + +## SDK source-matched ARM and native validation — 2026-10-26 + +Developer-path run 40391194892 passed for b7b3a99 on hosted ARM Linux: +core tests/lint, schema checks, generated native build, keyboard/accessibility, +render matrix, native host lifecycle (including the incompatible provider and +built-in feed regression), and package install/reinstall/removal. SDK/System +Monitor run 40391194847 also passed on that source. These are hosted CI checks, +not physical M-series Pantheon or owner visual acceptance. The model trial and +other release gates remain open. + +## SDK built-in feed compatibility — 2026-10-26 + +The local GTK host change keeps an incompatible optional service extension from +blocking the host-owned `windows.list` feed; lifecycle test now exercises that +combination and verifies the incompatible provider receives no external feed. +The generated test document and manifest pass the SDK checker with zero warnings. +This change has not been compiled or run on Linux GTK and is not +ready to claim as verified. SDK developer-path run 40390669721 passed on prior commit 4909d91, including +native lifecycle and package operations; SER8 is unreachable. Validate this +changed source and retain the result before claiming it passes. The current core-only macOS +suite, including the unread scoped-stream case, passes 102 tests and clippy. + +## SDK authoring scenario tool — 2026-10-26 + +The benchmark worker now accepts a confined scenario-file path for `gate`, so +model authors can run the same acceptance scenarios supplied by SDK starters. +Five boundary tests pass; a local worker-to-CLI smoke passed all seven settings +gates, including four named scenarios. This is not a model trial or isolated +Linux benchmark preflight; the changed worker/controller still need staging and +validation on SER8 before admission. Source-matched ARM runs remain pending. + +## SDK context-bound process streaming — 2026-10-26 + +The Rust SDK now offers `spawn_streaming_scoped`: context expiry cancels the +owned process, and chunks and completion carry their context to the final state +owner. The test switches context after receiving a real process chunk, verifies +the queued chunk and completion are rejected, and verifies a new stream works. +A further macOS regression verifies unread buffered bytes and a completed reply +are both rejected after the context closes, even after the process exits. +The complete SDK core suite and strict clippy passed in a macOS SDK-only copy. +This source change postdates the previous Linux/ARM and GTK qualification; +source-matched Linux, ARM and release-host validation remain outstanding. It +does not automatically scope GTK feeds or external backend subscriptions. + +## SDK benchmark packaging and quit checks — 2026-10-26 + +The SDK authoring harness now exposes packaging through its fixed SDK tool +surface and treats failure to quit on Ctrl+Q as a failed capture. An isolated +uid2000 smoke built a real .deb and launched the generated settings window; +a separate window that ignores Ctrl+Q produced the expected failure. Evidence +is in `sdk-bench/receipts/2026-10-26-pack-preflight`. This smoke did not install +or remove its package. Four boundary tests pass. The first model trial and +independent acceptance remain open; the latest attempt to check SER8 timed out, +so its current model residency is unknown. Native ports of every app are not a +completion requirement. + +## SDK authoring preflight retained; model admission deferred — 2026-10-26 + +The full offline uid2000 tool preflight succeeds through generation, build, +actual external capture and Ctrl+Q; the fixture screenshot has visible real +settings content without clipped primary controls. Four tool-boundary tests +and the three native suites pass. All 80 SDK source fingerprints match the +production snapshot. Sanitized configuration, seed/generated source and locks, +provisioning/prewarm logs and tool results are retained under +sdk-bench/receipts/2026-10-26-preflight. Benchmark helper boundary tests now run +in SDK CI; CI never launches the model controller. + +The s01 seed17 controller's admission attempt exited before inference because +qwen3.5:2b was already resident in the existing Ollama service. Residency does +not prove active inference; the conservative rule avoids replacing that worker. +No prompts were dispatched, generated model code was run, or model-quality +score claimed. No daemon or owner workload was stopped/switched. The synthetic +smoke project/state was archived and cleared; the sandbox is empty for a future +properly admitted cohort. Keep the admission receipt; do not count it as a +failed or completed model trial. Full-spec/baseline/repeated-model qualification +remains open. + +SDK ARM developer-path run 40378225258 succeeded on bd002fa, and matching +SDK/System Monitor run 40378225297 passed. This covers the current production +Rust context-binding code; newer changes here are benchmark tooling/docs only. +Native app ports/product feature parity remain outside SDK completion scope. + +## SDK model authoring discovery runner and offline preflight — 2026-10-26 + +Added a bounded SDK JSON-action authoring controller for the frozen benchmark +specs, plus a fixed project-only tool worker and external window/capture/quit +probe. Four boundary tests pass. It pins qwen3.5:4b digest + d8b0f5e9760cd1682034f292d7ef72ec46f432149be0df7574bf2d6e92e38c04, +packaged Apache-2.0 license, runtime/options and prompt/spec/source identities. +The model receives actual app frames; independent audit alone can establish the +rubric done bar. `done` is a candidate, not a pass. No baseline/repeated-model or +whole-SDK completion result is claimed by harness preparation. + +Prepared a separate ephemeral msdk-bench-20261026 clone with uid2000, zero +capabilities, loopback-only networking for execution, no owner-data mounts and +configured CPU/memory/process/disk bounds. Trusted GTK/SQLite/screenshot setup +and cache warming occurred before the trial timer. Initial provisioning failed +because networking was disabled too early; no model code/inference ran. Corrected +order is provision first, disable and verify before generated code. No host +model daemon was restarted, no second GPU worker launched, and no owner app, +desktop, accounts or service data changed. + +Offline unprivileged native CLI/lifecycle/runtime preflight passes. Fixed +settings new/gen/build/capture/Ctrl+Q succeeds through the actual tool bridge: +generation ~0.021s, cold cache-completion build 82.12s, window mapped ~0.283s and +capture ~0.927s. These are harness/provisioning facts, not model coding times or +a general performance comparison. Archive/clear that owned smoke project before +starting the unchanged s01 model cohort. Retain all failures/interventions and +inspect produced code/GUI/SQLite/shortcuts before scoring. See sdk-bench/RUNNER.md. + +## Owner SDK scope clarification: native is not mandatory for every app — 2026-10-26 + +The owner explicitly said we do not need a native experience for all apps. +SDK completion covers reusable SDK capabilities and a small set of representative +consumer/integration flows. Preserve suitable web interfaces, wrappers, webview/ +hybrid architectures and existing clients; do not create a project-wide native +porting or full app-parity prerequisite. Generic WebView hosting is not currently +a shipped vocabulary component, so do not imply that integration already exists. + +Updated SDK-COMPLETION.md, RUST-PANTHEON-SDK.md and APP-BUILDING-GUIDE.md to apply +this scope. Full T3/client parity and app-by-app native status ports are separate +app work. SDK host quality, declared API/lifecycle/authority contracts, selected +reference flows, distribution, developer usability and supported-host validation +remain SDK work. Signal/Messages deferral stays in force. No new consumer app +port or owner desktop/service/account changes were made for this clarification. + +## Typed GTK reply contexts and ARM foundation pass — 2026-10-26 + +ARM developer-path run 40375089386/job 121755848259 succeeded on pushed +7a5f4d27deeabf6334ba9c3d441e39eb0374ed3a, including core/schema, generated app, +keyboard/AT-SPI, text/theme captures, native CLI/lifecycle/runtime and package +lifecycle. SDK/System Monitor run 40375089841 also passed. Preserve these +completed runs; the newer scoped GTK reply work needs its own current CI. + +`ServiceReply::in_context(token)` now binds once before work, with binding and +first completion shared across clones. The Host checks tokens at final typed +GTK delivery. An error callback keeps its token through its additional queue; +a context switch between error receipt and callback cannot mutate the new page. +Synchronous invoke Err also uses the shared binding. Rebinding or binding after +completion is invalid input. A provider that binds then declines gets an owned +unavailable result; it cannot trigger a real unscoped built-in fallback. Replies/queues retain no GTK/Host ownership. + +Native regressions prove obsolete success/error rejection, synchronous denied +reply after binding, the second-queue callback race, current recovery, actual +visible GTK labels and Host release/stop. Core and existing lifecycle/CLI tests +and strict lint pass in the disposable SER8 environment. The change is explicit +opt-in: legacy raw events, feeds, built-ins/pre-invoke version failures, +streaming and T3/network adapters are not automatically scoped. Real backends +must retire reads/workers and preserve visible account identity separately. +SDK-RUNTIME-CONTRACT.md documents those boundaries. No owner desktop/accounts/ +services/kernel/panel changes. Continue full ledger and final current CI. + +## SDK current runtime/reference native qualification — 2026-10-26 + +Resolved the prior source-transfer approval block with direct owner-machine +context plus SSH/container identity evidence; automatic review accepted the +scoped SDK-only transfer. Existing ephemeral SER8 container remained running; +no owner desktop, accounts, panel, kernel or services changed. Current isolated +Ubuntu 26.04 x86_64 / Rust 1.93.1 / GTK 4.22.4 qualification passes 100 core +checks, three native suites (CLI failure exits, D-Bus lifecycle, typed runtime), +SDK strict Clippy and generated Home Storage model/build/strict Clippy. + +The actual generated app's keyboard/AT-SPI flow proves an absent synthetic HOME +causes a recoverable real command error, then a keyboard retry succeeds in the +SAME process after the harness creates that folder. Ctrl+Q passes separately. +Eight source/binary-matched light/dark, requested 480/900 widths and asserted +10/15-point captures pass keyboard recovery and visual inspection. Original raw +df table wrapped at larger text and was rejected; labeled figures now remain +readable, and unsupported report shapes fail instead of inventing usage. + +Actual package creation, install, reinstall, installed-binary equality, installed +launch and owned-file removal pass in the disposable container. Final executable +SHA256 74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464; +package d01aa58ba3a3b560c696806a788fd4772e206687ffd84241190bc19f0caf166e. +All 80 SDK source/fixture hashes match the qualified code. Retain receipts under +sdk-tests/receipts/2026-10-26-native-runtime-reference, including generated source, +locks, raw synthetic logs, screenshots and rejected layout evidence. + +The full SDK goal stays active. Next: current ARM CI, GTK context/streaming and +real backend adapters, shared CodexBar-derived status module/host conformance, +controlled exact-model/novice trials and performance, then physical Pantheon/ +M-series acceptance and release audit. Existing ARM foundation run 40363235712 +on ed9bc5b is completed prior evidence, not current-runtime ARM acceptance. + +## SDK request context ownership and stale reply delivery — 2026-10-26 + +Added core RequestContext/ContextToken/Scoped for app-owned account/page/ +selection generations. Advance invalidates old successes/errors, including +already queued replies; close is permanent and last-owner drop invalidates +without tokens retaining the owner. Freshness is checked at final delivery, +with switches and application serialized on the state-owner thread. Tokens +store no account data and Scoped Debug omits its value. Native UI must continue +to show the actual identity and cannot treat the token as authority. + +`process::spawn_scoped` checks the token before starting and during bounded task +work, cancels/reaps when its context expires and delivers a scoped completion. +Core tests exercise stale queued success/error, independent/returning contexts, +owner release/close, an already closed task that never executes, real sleeping +process cancellation/reaping and a successful replacement request. Runtime +discovery publishes the explicit core APIs and automatic-adapter limitations. + +GTK ServiceReply/streaming chunks/T3 network subscriptions are NOT automatically +scoped yet. Core freshness is a snapshot, not an arbitrary cross-thread state +transaction or rollback. These adapters and native final-source qualification +remain open in SDK-COMPLETION.md. SER8 source-transfer approval is still pending; +no transfer/retry/bypass or owner services/desktop/accounts/kernel/panel change. + +## SDK entry points stop on manifest and validation failures — 2026-10-26 + +Core CLI `check`, `render`, `gate`, `complete` and `agent-manifest` previously +printed service-manifest errors and continued with incomplete contracts. They +now stop on unreadable/invalid/conflicting manifests; check emits structured +service-manifest errors in JSON mode. Adjacent discovery is deterministic and +reports directory errors. Missing explicit paths/flag values fail. A check with +no descriptions no longer returns a false success. `gate --services PATH` no +longer mistakes the flag for a gates filename. Generation/package already +propagate loader errors; actual CLI tests verify generation creates no output +when an adjacent manifest is invalid. + +GTK preview now stops on invalid manifests and missing --services values, +reports discovery errors, and returns failure for rejected descriptions/surfaces +or failed screenshots rather than quitting with success. A private-session native +CLI test is added to the native workflow for those failure paths, but has NOT +been compiled/run here: Linux source-transfer authorization remains pending. +Core executable tests pass on macOS; final receipts distinguish that evidence +from unqualified GTK code. No remote retry or owner desktop/service/account/ +shipping action was performed. Continue final native qualification, GTK +streaming/context adapters and the full completion ledger. + +## Atomic versioned SDK manifests and compatibility boundaries — 2026-10-26 + +Manifest loading now validates its complete input and conflicting registered +service/feed shapes before publishing under one write lock. Invalid later +entries cannot leave earlier entries registered; concurrent conflicting loaders +have one winner, and the losing manifest publishes nothing. Identical reloads +are idempotent, independent of argument/field object order. Explicit +manifest_version 1 is supported; omitted version preserves legacy v1 manifests. +Unsupported versions and malformed/unknown fields fail explicitly. Rejected and +idempotent manifests no longer leak strings into the lifetime registry. + +SDK-COMPATIBILITY.md distinguishes package, app-description, manifest, extension, +diagnostic, GTK and shell protocol versions; publishes candidate ownership, +migration/deprecation rules and actual host evidence; and keeps real backend +protocols and physical supported-host release qualification open. Runtime +discovery derives package/app/manifest versions from actual constants. Version +errors guide migration rather than blindly relabeling an incompatible document. + +Eight manifest checks cover rollback, conflicts, idempotency, feed shape, +concurrency, malformed input/version and immutable document rejection. An initial +full core run exposed simultaneous generator-test scratch directories with the +same timestamp; an atomic serial and exclusive-create retry repair the collision. +That failure is retained with final local receipts. No remote source transfer, +owner desktop/service/account/kernel/panel mutation or whole-SDK completion claim. +Linux final-source validation remains pending the previously requested explicit +SER8 source-transfer authorization. Continue GTK streaming/context adapters and +remaining completion-ledger gates after qualifying the final sources. + +## Bounded Rust process streaming — 2026-10-26 + +`msdk::process::spawn_streaming` now supplies private raw stdout/stderr chunks +before completion. Its owned subscription and process handle cancel on drop, +including silent work. A 32 × 8192-byte queue uses nonblocking delivery; a slow +consumer terminates the task with output-limit failure rather than hanging the +worker. Already queued/consumed partial output survives cancellation and timeout; +stream closure precedes completion, which remains the terminal-status authority. +Raw bytes preserve invalid UTF-8; Chunk Debug omits payloads. Discovery records +the Rust API/limits separately from completed-output `process.run`. + +Five new real-process checks pass on macOS: early private stdout/stderr plus +cancel, raw byte fidelity, bounded slow-consumer failure, silent-task cancellation +on subscription drop, and partial output after timeout. Full core suite (82 +checks), strict Clippy and formatting pass. Linux current-source qualification +still awaits explicit source-transfer/destination approval; no remote retry was +made. GTK streaming/progress adapter, stale-context protection and the updater +reference consumer remain unfinished. See SDK-RUNTIME-CONTRACT.md for semantics. +No owner desktop, services, accounts, kernel or panel changed. + +## Typed SDK runtime and owned task commands — 2026-10-26 + +ARM developer-path run 40363235712 passed on ed9bc5b. Continue that evidence; no +replacement was needed for the completed foundation run. + +Added candidate `ServiceFailure`/FailureKind diagnostics, `msdk describe runtime` +and runtime-code explanations. Modern `Services::invoke(ServiceCall)` owns typed +async replies; registered result shapes are checked, first completion wins and +errors do not fall through to real system work. Extension interface version 1 is +checked before dispatch; real backend OS/network protocol negotiation remains +separate. Existing provider entry points remain compatible. Missing fixture +replies now fail explicitly, and fixture traces omit arguments. + +`msdk::process` owns a Linux/macOS process group, nonblocking pipes, monotonic +120-second/default 1-MiB combined output bounds and cancellation/reaping. Host +concurrency is four and accepted close cancels handles. Kernel PID identity is +held until group signals finish, with cancellation serialized. Private stderr +can reach app UI, while Debug/Display/diagnostics omit payloads. Streaming, +partial output, privileged/daemon job supervision and app-context races remain +open; no whole-SDK or backend stability claim. SDK-RUNTIME-CONTRACT.md records +actual identifiers, limits, compatibility and reproduction commands. + +Real process/diagnostic tests pass on macOS. Initial Linux core/native checks +pass, including blocked mismatch and recovery, unavailable/malformed/denied +async replies, duplicate rejection and real command termination on close. +Final fixture-no-fallback and updated discovery checks remain to qualify on the +final Linux source. Automatic approval review rejected the updated source transfer +to SER8 pending explicit destination/payload authorization; no transfer was made. +Local core/lint/format checks pass. Home Storage now supplies a read-only useful +reference flow, duplicate-submit suppression and actual command error/retry tests; +SDK-GOLDEN-PATH.md records reproduction and still-pending native UI/trial gates. +Next: authorize/resume isolated Linux qualification, retain source-matched receipts, +then shared status module, streaming and controlled model trials. +No owner desktop, accounts, services, kernel or panel changes. + +## Source-matched SDK developer-path receipts retained — 2026-10-26 + +The final isolated x86_64 pass covers exact SDK code `287886e3b4399c742bf286bbaf3905b36439467d`; +all 67 source/fixture fingerprints match the checkout. Receipts, generated Cargo +sources, dependency locks, raw synthetic test/install logs, eight reviewed PNGs +and retained failures are under `sdk-tests/receipts/2026-10-26/summary.json`. + +65 core tests pass; strict core/runtime and generated-app lint pass on Rust +1.93.1/GTK 4.22.4. Native private D-Bus lifecycle proves accepted/vetoed close, +stop/read behavior, late-event rejection and Host release. Live keyboard and +AT-SPI checks prove Switch/ComboBox/Button names/roles, saved values, reset and +Ctrl+Q. All eight light/dark, 480/900-wide, asserted Sans 10/15-point captures +were visually inspected without clipped actions/labels. This is isolated GTK +rendering, not owner visual or physical-scale/Wayland acceptance. + +Actual `.deb` metadata/dependencies, fresh install, reinstall, byte equality, +installed launch and all five owned artifact classes' removal pass. Final app +SHA256 is `e68aefa505ea9f16eeb8d475d6997f4340cd10e3cfe31b9d504ed92e78c91feb`; +package SHA256 is `ebc6015c44c2adc4ebe394ef3f0561edfab0ab5900b3230130e95a0feb69f317`. +Unmodified SDK/app lock files and generated sources are retained. No owner's +services, desktop or accounts were changed. The completion ledger retains all +remaining gates: versioned service/errors/process cancellation, shared status +module/T3 host semantics, model usability, performance and supported target +architecture/distro/owner qualification. The full SDK goal remains active. + +A final schema-probe interruption came from AppleDouble files in an early Mac +archive; preparation/filtering now ignore that metadata. Completed core/lint/ +lifecycle work was reused, and only unfinished phases resumed. ARM CI still +needs the official-ports provisioning correction qualified; source merge is +not a claim of complete SDK acceptance. Next: inspect that new CI handle, then +implement the service/error/cancellation contract and its useful golden-path app. + +## SDK native validation and authoring repairs — 2026-10-26 + +The SDK now has standalone typed Cargo generation and explicit ELF-to-Debian +packaging. In a new disposable SER8 Ubuntu 26.04 x86_64 container (Rust 1.93.1, +GTK 4.22.4), core tests, actual GTK lifecycle, generated-app keyboard/AT-SPI +controls, metadata validation, install/reinstall/installed launch/binary equality +and removal pass on the tested snapshots. Final source fingerprints/artifact +receipts are being retained separately; this is not whole-SDK or target desktop +acceptance. The owner's containers, desktop, panel, accounts and kernel remain +unchanged. The temporary msdk-validation-20261026 container is scoped to this +SDK goal; retain its build cache while work continues. + +Concrete repairs: weak Host dispatch/event ownership; cancelable/serialized +window polling with an owned handle; provider teardown hook and late-event +rejection; accepted-close disposal (a vetoed close stays usable). Independent +native D-Bus reads prove enabled/closed/disabled behavior and Host release. +Generated apps have standard Ctrl+Q and native window-control layout. Visual +review rejected oversized custom oval controls and a missing dropdown label; +those are repaired. Original GDK_DPI_SCALE screenshots did not change text and +are not larger-text evidence. The corrected private GTK 10/15-point profiles +assert the effective font setting before capture. Physical scale/theme/owner +acceptance remain open. + +The JSON schema previously omitted initial/persist/feeds/update/logic and could +not accept the shipped starters. It now describes those and all rule verbs; +an independent Draft 2020-12 validator accepts 11 real descriptions/metadata +cases and rejects seven malformed action shapes also refused by the checker. +Generated manifests register once; corrected package metadata passes actual +AppStream validation. A stale probe selected static labels rather than their +identically named controls; that failure is retained before its repaired live +Switch/ComboBox/Button checks. Rust 1.93 strict lint exposed older boolean +forms; equivalent rewrites retain lexer bounds ordering and pass native lint. + +Run 40355512113 reached its 25-minute limit during Azure package provisioning, +not SDK tests. Its log shows the two Rust archives stalled for minutes. The +workflow now selects official Ubuntu ports while preserving signed APT trust, +adds bounded download waits, independent schema checking, actual keyboard and +accessibility checks, native lifecycle and compact/larger-text rendering. +Next: retain final source-matched receipts and arm64 CI; then finish versioned +service/error/process cancellation contracts, reusable status module conformance, +model-authored app trials/performance and target-host qualification. All remain +open in SDK-COMPLETION.md. Signal/Messages remain deferred. + +## SDK native compilation reached; warning correction — 2026-10-26 + +Linux run 40354775593 passes the complete core suite and compiles/tests the +generated GTK application. Strict lint then rejects unused serde imports in the +empty generated records module (settings has no record types), so no screenshot +was reached. Generated derives now use qualified serde paths without redundant +imports; the all-starter generated-model fixture denies warnings to retain this +regression. Native rendering and package qualification remain pending. + +## SDK explicit binary packaging — 2026-10-26 + +Added `msdk pack --binary --output `: matching native +architecture required, shared-library dependencies resolved from the supplied +binary with dpkg-shlibdeps, metadata validated before archive publication, +owned executable/desktop/icon/metainfo/license files included. Existing outputs +are never replaced. No build, app execution, installation or background service +is performed by the command. Generated projects now include icon/license assets +and preserve declared-service manifests for packaging. App-specific attribution +and production metadata remain release review work. + +Core architecture/metadata-injection/XML checks and strict lint pass on macOS; +actual package/native runtime qualification is Linux-only and pending. The +workflow now exercises package creation, installation, reinstall, installed +binary equality/launch and removal on a disposable runner. Full target desktop, +service/lifecycle, benchmark and owner acceptance gates remain open in the SDK +completion ledger. No owner's desktop or running panel changes. + +## SDK Linux first-run dependency correction — 2026-10-26 + +Native workflow run 40354229616 failed before GTK build: the generated-model +integration test uses offline Cargo, but serde derive/proc-macro dependencies had +not been provisioned by core Cargo tests. Added the actual test dependency and +copied the parent lock into the generated fixture before offline compilation. +This preserves offline test execution and pinned versions; it does not weaken +or skip generated-code compilation. Native build/render checks remain pending. + +## SDK standalone app generation and core reconciliation — 2026-10-26 + +Added `msdk gen` for checked descriptions: independent Cargo project, inspectable +Rust records/State/Message/event bridges, embedded document/service manifests, +real GTK executable and initial-state test. No custom backend or Rust logic is +silently invented. All six generated models compile; keyword/collision cases +and >2^53 integers round-trip exactly. Starter escaping remains covered. +Reconciled two stale core tests with the current T3 SDK identity and Usage +start page while preserving permission/page-visibility assertions. + +Core tests and strict clippy pass in the isolated macOS core workspace. New +Linux native generation/build/launch screenshot CI is pending; target desktop, +package/install, lifecycle, model usability and owner acceptance remain open. +`SDK-COMPLETION.md` preserves the full requested completion contract and next +gates; mandatory SDK/authoring and CLI docs describe the new command accurately. +No desktop installation, live account reads, kernel or panel changes. + +## SDK starter literal-name repair — 2026-10-26 + +`msdk new` now JSON-escapes supplied identity/name strings and substitutes original +placeholders once. Quotes, backslashes, Unicode, newlines and names resembling +placeholder text no longer corrupt or recursively rename generated descriptions. +Five template tests pass; actual CLI settings generation in JSON and `.msdk` +formats passes `check` and `gate` with a quoted/backslashed Unicode name. + +Verification used an isolated copy of the unchanged msdk crate plus its external +fixture files, with cached Cargo dependencies on macOS. Workspace offline testing +cannot resolve the uncached pinned Smithay Git dependency. The full isolated core +suite has two failures: inspect expects the old T3 Chat default/usage heading, +and intents expects absent tool `claudepantheonrs_send`. These are outside template +rendering and remain open; no green whole-suite or GTK/runtime claim is made. + +Next SDK completion work: reconcile those T3 contract tests; provide a complete +standalone app/build/package path; qualify versioned service errors and optional +capability lifecycle; exercise native Dock conformance (#605), and retain actual +visual/accessibility/installation and controlled model-authoring evidence (#535). +Signal/Messages remain deferred. No desktop installation or panel restart. + ## Unified native T3 panel integration — 2026-10-26 Merged Fleet PR #607 at `04fe68e6`. Owner does not require particular remote diff --git a/mseries/ROADMAP.md b/mseries/ROADMAP.md index 24ab7645d..518c90408 100644 --- a/mseries/ROADMAP.md +++ b/mseries/ROADMAP.md @@ -1,3 +1,841 @@ +## Candidate anchor hover failure — 2026-10-26 + +SDK desktop-host ARM workflow 40418084280 passed on attempt 2 at 64ca2db, including C/Vala host boundaries, shared T3 menu in hosted and dock modes with synthetic neighbors, and SDK/package checks. Attempt 1 passed host checks but its later private display failed to open; see `sdk-tests/receipts/2026-10-26-desktop-host-ci/`. Real desktop builds, installation, target GTK compatibility and owner acceptance remain open. + +SDK desktop-host work: an opt-in Plan usage page now shares the existing T3 menu source between Dock and Wingpanel, via a provisional C/Vala boundary. On a local ARM Ubuntu 26.04 VM with isolated synthetic data, the actual shared menu source passed hosted and dock-mode usage display, page switching and closed-read checks; neighboring indicators were stubs. Full Wingpanel/Dock build, installation, live desktop validation and GTK compatibility on the elementary target remain open. See `sdk-status-host/README.md`. + +ARM SDK run 40416161840 at 26a71f7 passed the candidate usage anchor interaction suite, including unpinned pointer exit, plus package lifecycle. The retained synthetic fixture receipt is `sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/`; actual status-host integration and target acceptance remain open. + +ARM run 40415797379 at 7fa281f passed the candidate usage anchor synthetic hover travel, pin, outside dismissal and keyboard interactions, and package lifecycle; see `sdk-tests/receipts/2026-10-26-usage-anchor-pass/`. This does not qualify an installed desktop host. An added explicit unpinned pointer-leave check is pending. + +ARM run 40412642984 at 98867b8 passed core, generated app, accessibility, lifecycle and usage-refresh steps. The candidate anchor opened and read once, but failed pointer travel; pinning and subsequent steps were not reached. See `sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/`. X11 surface diagnostics are being added; native interaction validation remains open. + +Candidate usage anchor: ARM run 40407270110 did not open on hover; diagnostics showed the test pointer on the X root and no synthetic read. The isolated fixture now exports GTK bounds for pointer placement. GTK documents that changing auto-hide hides a visible popover, so the candidate now closes and reopens on pinning without restarting its read; interaction validation remains pending. This is a reusable candidate, not an installed desktop host. See `sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/`. + +SDK run 40406733431 compiled 5c7dcbc but failed the synthetic hover interaction: +the Usage anchor was present while the popup was not observed. The failure is +retained under sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail; its cause +is unproven. The follow-up checks actual popup mapping and adds pointer/read +diagnostics. It needs source-matched native execution; no host acceptance is +claimed and no owner desktop was changed. + +## Candidate usage status anchor — native validation pending, 2026-10-26 + +An embeddable GTK UsageAnchor is modeled on the existing taskbar hover/pin +interaction and owns the UsageControl lifecycle without background polling. A +private synthetic X11/AT-SPI probe exercises hover focus, pointer travel, +hover-to-click pinning, outside dismissal, keyboard open/Escape and closed +no-read behavior. Native compilation and interaction tests are pending. This +widget is not installed in either real desktop profile; host adapters, real +provider coverage and owner acceptance remain open. No panel was restarted. + +## Usage control keyboard validation — 2026-10-26 + +Hosted ARM developer-path run 40405964283 passed on 477234a. A private synthetic +AT-SPI/keyboard probe found `Refresh usage` as a button, used Tab and Space to +exercise failure and retry, checked stale data and private-stderr exclusion, +and closed with Ctrl+Q. Four reviewed failure-state frames and the probe +receipt are in sdk-tests/receipts/2026-10-26-usage-keyboard-pass. Earlier +private-display and accessible-name failures remain retained. This does not +qualify keyboard scrolling, actual desktop status-host interactions, real +accounts or owner visual acceptance. + +## Usage accessibility name diagnosis — 2026-10-26 + +SDK run 40405291097 failed its synthetic keyboard probe on 9dac12e. The +retained AT-SPI tree shows a button named `Refresh` with role `button`, not the +expected `Refresh usage`. See sdk-tests/receipts/2026-10-26-usage-accessibility-tree. +The visible label has been changed to `Refresh usage` to match the intended +accessible name; GTK, keyboard and visual revalidation remain pending. The +previous X-display startup failure is separate and remains unexplained. + +## Usage keyboard probe failures — 2026-10-26 + +SDK run 40404146612 on 34a26fa failed twice: attempt 1 could not open the +private X display; attempt 2 opened the app but the expected accessible refresh +button was not found. Synthetic receipts are in +sdk-tests/receipts/2026-10-26-usage-keyboard-failures. Causes are unproven and +no keyboard acceptance is claimed. The follow-up records a bounded synthetic +accessibility tree on failure so the actual role/name can be diagnosed. + +## Usage keyboard and AT-SPI probe — validation pending, 2026-10-26 + +A private-session synthetic app and probe exercise the actual UsageControl via +Tab and Space, inspect the accessible name/role, provoke a failed refresh, retry +and close with Ctrl+Q. The probe records only synthetic data and checks private +stderr does not enter the accessible tree. Native execution is pending. This +standalone fixture does not prove keyboard behavior or focus in either actual +status host and does not touch real accounts or the owner desktop. + +## Usage refresh control validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40403452026 passed on e1c91a8. Native +synthetic tests cover open/busy/failure/retry and four failure-state light/dark +Sans 10/15 frames were reviewed and retained under +sdk-tests/receipts/2026-10-26-usage-control-final. Failure, stale data and the +Refresh button are visible in the fixture; the footer no longer repeats the +failure wording. Keyboard/AT-SPI, busy-state visual review, actual status hosts, +real collectors/accounts and owner approval remain open. + +## Usage control initial validation — 2026-10-26 + +Hosted ARM SDK run 40402684685 passed on a5b0ff2, including synthetic GTK +success/failure/retry and failure-state captures. Initial review found the +notice, stale data and refresh button readable, but the failure was repeated in +both the panel and footer. Four frames and limits are retained under +sdk-tests/receipts/2026-10-26-usage-control-first. The footer now says “Retry +when ready”; that follow-up still needs source-matched GTK and visual review. +Real collectors, keyboard/AT-SPI and actual desktop hosts remain open. + +## Usage refresh control — native validation pending, 2026-10-26 + +A candidate embeddable UsageControl exposes refresh, spinner and status around +the on-demand monitor. Explicit open starts one read; repeated open does not +start another, and close/unmap/drop cancel owned work. Native synthetic tests +exercise success, malformed-output failure and retry; the CI preview captures +failure state in light/dark at two text sizes. GTK execution and visual review +are pending. Actual status hosts, keyboard/AT-SPI interaction, real collector +and accounts remain unqualified; no panel or service was restarted. + +## On-demand usage refresh validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40401954793 passed on ee9cd5e after the +retained 58dd831 strict-lint failure. The native synthetic executable test +checks no reads while closed or merely opened, duplicate refresh coalescing, +source-age recheck at delivery, close/cancel, and a new refresh after reopening. +The fixture does not prove real collector/account behavior, visible refresh +controls, desktop-host integration or owner acceptance. No scheduled polling +or owner desktop service was started. + +## Refresh controller lint repair — 2026-10-26 + +SDK developer-path run 40401485674 failed at GTK strict clippy on 58dd831: +`needless_return` in the expired-reply match arm. The arm now uses unit. Native +controller tests did not run in that attempt and source-matched validation is +still required. The earlier failed run remains evidence, not a passing test. + +## On-demand usage refresh lifecycle — native validation pending, 2026-10-26 + +A candidate CodexBarMonitor explicitly opens/closes a UsagePanel, starts one +bounded read on request, coalesces duplicates, cancels/invalidate on close and +reports state to its host. It rechecks source age at final GTK delivery; no +polling is scheduled. Synthetic GTK tests cover closed/open no-read, duplicate +refresh, age, cancellation and reopen. The 107-test core suite and clippy pass +on macOS; source-matched GTK compilation and lifecycle execution are pending. +This does not connect either actual desktop status host or real provider data. + +## Scoped usage delivery validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40400566671 passed on 5a6a1e6. Its GTK +regression executes a synthetic snapshot program, applies a successful result, +rejects a queued result after a context switch, and checks that a later failure +shows a generic notice with last-known data marked stale and no private stderr. +The executable and data are synthetic; real collector/account integration, +actual desktop host interactions and visual review of the new failure state +remain open. No background polling or owner desktop service was started. + +## Scoped usage delivery — native validation pending, 2026-10-26 + +UsagePanel can consume the scoped CodexBar read on the GTK/state-owner thread: +old queued replies are ignored, and current failures retain last-known data as +stale with a generic notice. A synthetic executable-to-GTK regression covers +success, a context switch after queueing, failure and private-stderr exclusion. +Core usage tests and strict clippy pass on macOS; source-matched GTK execution +is pending. The caller still owns refresh, cancellation and host lifecycle. + +## Scoped CodexBar read validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40399879070 passed on 9e8fecc. Its five +CodexBar tests include an actual synthetic executable with a shell-sensitive +filename, literal `--snapshot` argument, malformed output and a context switch +that cancels the owned work and rejects the stale completion. The core test +also checks literal argv and preserved scope across transformation. These are +isolated synthetic executable tests, not a live collector or account read. +Real provider coverage, polling lifecycle and desktop status hosts remain open. + +## CodexBar bounded read adapter — native validation pending, 2026-10-26 + +A scoped direct-executable SDK process API runs literal argv without a shell. +The CodexBar adapter uses it for one five-second, two-MiB bounded `--snapshot` +read, retaining context until delivery and leaving polling/service management +to its caller. Synthetic executable tests cover arguments, malformed output and +context cancellation. The full 107-test core suite and strict clippy pass on +macOS; GTK adapter execution/source-matched Linux validation remain pending. +No live collector, account data, desktop service or daemon was touched. +## CodexBar snapshot decoder validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40398755850 passed on ee2eb68. Four decoder +regressions cover aggregate scope and partial coverage, null quota, source-time +freshness, future/expired values, malformed input, bounds and error redaction; +a native GTK widget test renders a synthetic v1 snapshot. This validates the +decoder against fixtures, not execution of a live collector, real accounts, +account-specific coverage or either actual desktop host. Those remain open. + +## CodexBar snapshot decoder — native validation pending, 2026-10-26 + +A bounded read-only decoder maps the existing CodexBar v1 provider snapshot to +candidate usage observations, retaining source timestamps and partial coverage. +It never claims account-specific usage from provider aggregates. Synthetic +regressions cover unknown, stale, future, expired and malformed data and a GTK +rendering path. No process, live backend or owner account is touched. GTK +compilation and source-matched native tests are pending; real collector reads, +account adapters and status-host integration remain open. + +## Usage viewport refresh validation — 2026-10-26 + +Hosted ARM developer-path run 40397942393 passed on cc2dace. Its native widget +regression rejects an invalid replacement, applies two valid updates and retains +a numeric scroll offset with unchanged-height synthetic content. Preview images +are retained in sdk-tests/receipts/2026-10-26-usage-viewport; reviewed frames +keep provider overview visible at the top. Semantic anchoring, shorter/changed +content behavior beyond clamping, keyboard/focus, real providers and both actual +status-area hosts remain open. No owner desktop or real accounts were touched. + +## Usage viewport refresh — validation pending, 2026-10-26 + +The candidate GTK UsagePanel provides a bounded read-only viewport and validates +replacement snapshots before display. It restores a prior numeric scroll offset +when refreshing and coalesces restoration after back-to-back updates. Native +tests exercise invalid replacement, multiple updates and scroll retention; the +synthetic preview now embeds this viewport. GTK compilation and execution on +this exact source remain pending. Semantic row anchoring, focus in interactive +children, provider refresh/teardown and actual status-host binding remain open. + +## Usage provider overview review — 2026-10-26 + +Hosted ARM SDK run 40397085739 passed on 0951bde, including the native widget +and scrolling regression. Eight synthetic light/dark Sans 10/15 top/end captures +are in sdk-tests/receipts/2026-10-26-usage-overview. All four fixture provider +names and partial coverage are visible on opening in both profiles; cards +remain separate and scrollable. Compact quota layout, long-label/translation, +keyboard interaction, real adapters, actual status hosts and owner acceptance +remain open. The overview is not proof of complete provider coverage. + +## Usage provider overview — validation pending, 2026-10-26 + +The candidate usage view now lists provider names and partial/unknown coverage +before the provider cards. Repeated sources for one provider remain separate +cards while the overview lists that provider once. The native regression checks +that the four-provider overview and partial coverage precede all account rows. +Source-matched GTK tests, top/end screenshots and visual review remain pending; +this is not an interactive status host or evidence of complete provider coverage. + +## Multi-provider usage fixture review — 2026-10-26 + +Hosted ARM SDK run 40396405090 passed on 2111eb1. Native synthetic checks cover +two Codex accounts, two Claude, Grok and OpenCode and a reachable programmatic +scroll end; eight reviewed top/end light/dark Sans 10/15 frames are retained in +sdk-tests/receipts/2026-10-26-usage-multiprovider. Existing CodexBar provider +marks were staged only in the isolated fixture. At large text only two providers +are visible on opening, so the provider-coverage presentation requirement is +still unmet. Keyboard scrolling, actual hosts, real adapters and owner visual +approval remain open. + +## Usage provider marks and scrolling fixture — validation pending, 2026-10-26 + +The candidate usage component can use existing CodexBar symbolic provider marks +when present and always retains a readable provider label when absent. The +synthetic preview now includes two Codex accounts, two Claude accounts, one +Grok and one OpenCode account in a bounded scroll viewport. The CI fixture +stages existing project icon assets in an isolated data directory and captures +top and bottom in light/dark Sans 10/15; a native regression checks multiple +accounts and scroll range. Source-matched GTK build/test, captures and visual +review remain pending. No provider adapter, real account or host is involved. + +## Usage card refinement review — 2026-10-26 + +Hosted ARM SDK run 40395621853 passed on dd96c00, including native widget +checks and four synthetic light/dark Sans 10/15 captures. Compared with the +previous preview, the card and account headings improve hierarchy and avoid +repeated stale text and awkward reset wrapping in the tested fixture. Evidence +is in sdk-tests/receipts/2026-10-26-usage-cards. Provider marks, compact quota +presentation, multi-provider/long-list review, host interactions, real adapters +and owner approval remain open; this is not full status-module acceptance. + +## Usage card hierarchy refinement — validation pending, 2026-10-26 + +The candidate usage rows now use a scoped, theme-derived card treatment based on +CodexBar's existing card styling. Account headings have stronger hierarchy; +stale is shown once per account, and reset text has a separate line for large +text. The widget regression also checks stale versus expired presentation. +This is not a provider mark, complete status control or visual acceptance. +Source-matched native GTK build, tests, new captures and independent review +are required before claiming an improvement. + +## Candidate usage preview review — 2026-10-26 + +Hosted ARM developer-path run 40395051297 passed on edf7a4e, including native +widget-tree regression and four synthetic usage screenshots. Review found the +candidate too flat versus the CodexBar reference: provider/account hierarchy is +weak, stale is repeated, and large-text wrapping is awkward. Images and scoped +findings are in sdk-tests/receipts/2026-10-26-usage-preview. The candidate is +not visually accepted; provider marks, compact hierarchy, interaction/scrolling, +hosts and real adapters remain open. The earlier d4bd990 compile failure is +retained above; the Rust orientation fix passed in this run. + +## Candidate usage GTK compile repair — 2026-10-26 + +Developer-path run 40394710018 failed compiling d4bd990 because the candidate +usage component used the Vala spelling `Orientation::VERTICAL` in Rust. The +three sites now use the Rust GTK spelling `Orientation::Vertical`. No native +widget test or screenshot ran in that attempt. Source-matched GTK validation +and visual review remain required; retain this failed attempt in the record. + +## Synthetic usage preview — validation pending, 2026-10-26 + +An isolated GTK example renders synthetic accounts and saves a window capture; +the SDK workflow builds it and captures light/dark at Sans 10 and 15 for review. +This is a candidate component preview, not a real status host or evidence of +visual acceptance. GTK compilation, all four captures and independent visual +review remain pending on the exact source. It must not read real account data. + +## Candidate usage GTK rows — validation pending, 2026-10-26 + +`msdk_gtk::usage::render` builds read-only provider/source and account rows from +validated snapshots with explicit unavailable, stale and expired states. A +native widget-tree test covers separate accounts, unknown/expired quota and +partial coverage. The data tests (4), complete macOS core suite (106) and strict +clippy pass. GTK compilation, native execution, light/dark/large-text visual +review and real status hosts remain open. This initial widget does not yet meet +the full CodexBar-derived status standard or implement refresh and actions. + +## Usage presentation inputs — 2026-10-26 + +The candidate usage snapshot now carries separate display labels and selected +state, and can group validated observations by provider and source while +preserving every account and separating aggregates. Four usage tests and all +106 core tests plus strict clippy pass on macOS. This prepares inputs for a +native control; it is not a widget, provider adapter or status host. The +source-matched Linux run for the prior commit is still in progress, and this +local change needs its own Linux, visual and interaction validation. + +## Usage observation snapshots — 2026-10-26 + +The candidate Rust usage data layer now supports explicit coverage and validates +snapshot identity, duplicate scopes/windows, source timestamps for fresh +observations and impossible token subsets. Distinct accounts and sources are +not merged; unknown values remain optional. Full macOS core tests (106) and +strict clippy pass. This is an in-memory API, not a wire protocol, collector, +presentation or status host. Source-matched Linux and the remaining status-area +integration and visual/interaction gates are still required. + +## Usage observation semantics — 2026-10-26 + +The candidate `msdk::usage` data API separates account/provider/source scope, +used and remaining quota, expired windows, unknown values and token subsets. +Debug omits scope identifiers. Three focused semantic tests and the complete +105-test core suite plus strict clippy pass on macOS. This is data groundwork; +collectors, cross-source deduplication, native presentation, both status hosts, +real interaction/visual review and source-matched Linux validation remain open. +The benchmark host is unreachable. See `SDK-USAGE-DATA.md` for the boundary. + +## SDK accessibility failure diagnosis — 2026-10-26 + +The synthetic failure artifact from developer-path run 40392328090 attempt 1 +shows GTK failed to open the display before accessibility registration. The +reason for the display failure remains unknown; attempt 2 passed. The original +receipt is retained in sdk-tests/receipts/2026-10-26-accessibility-failure. +The probe now reports a child exit immediately and preserves stderr, instead of +waiting for an accessibility-root timeout after the app has already exited. +Linux execution of this probe change remains to be verified. + +## Golden-path fixture validation — 2026-10-26 + +On dbf4eee, hosted ARM SDK/System Monitor run 40392327560 passed. SDK +Developer-path run 40392328090 attempt 1 failed because the generated app's +accessibility root was not observed within the probe timeout. Attempt 2 passed, +including that probe and the native runtime version-mismatch fixture/no-fallback +regression, then package lifecycle. The first failure is retained; its cause is +unknown and one retry does not establish that the probe is reliable. This tests +SDK extension negotiation, not an OS backend protocol or a timed novice trial. + +## Golden-path version injection — validation pending, 2026-10-26 + +Fixture files may specify an SDK extension `api_version` to exercise a visible +version mismatch without a real backend; invalid version values are rejected. +The golden-path guide describes the injection. A native regression checks the +error and verifies no built-in process fallback executes. GTK compilation and +source-matched native execution remain pending; this is not an OS backend +protocol compatibility result or a measured developer trial. + +## Context-bound feed validation — 2026-10-26 + +Hosted ARM SDK developer-path run 40391629479 and SDK/System Monitor run +40391629511 passed on bb90bf7. The native GTK lifecycle test confirms a +current feed update reaches host state, an update from an advanced context is +ignored, rebinding is rejected, and the provider stops on close. This is an +explicitly bound test provider; legacy providers are unscoped, and cancelling +backend reads/subscriptions and displaying account identity remain provider +responsibilities. Physical Pantheon and model-trial gates remain open. + +## SDK context-bound feeds — validation pending, 2026-10-26 + +An opt-in typed feed endpoint carries an app-owned context to GTK delivery and +rejects stale updates. Legacy feeds remain compatible and unscoped; providers +must explicitly retire subscriptions and reads on context changes and close. +A native lifecycle regression covers delivery, context advance, rebinding +rejection and close. Source-matched Linux GTK compilation and execution are +required before this feature is claimed as validated; SER8 remains unreachable. + +## SDK source-matched ARM and native validation — 2026-10-26 + +Developer-path run 40391194892 passed for b7b3a99 on hosted ARM Linux: +core tests/lint, schema checks, generated native build, keyboard/accessibility, +render matrix, native host lifecycle (including the incompatible provider and +built-in feed regression), and package install/reinstall/removal. SDK/System +Monitor run 40391194847 also passed on that source. These are hosted CI checks, +not physical M-series Pantheon or owner visual acceptance. The model trial and +other release gates remain open. + +## SDK built-in feed compatibility — 2026-10-26 + +The local GTK host change keeps an incompatible optional service extension from +blocking the host-owned `windows.list` feed; lifecycle test now exercises that +combination and verifies the incompatible provider receives no external feed. +The generated test document and manifest pass the SDK checker with zero warnings. +This change has not been compiled or run on Linux GTK and is not +ready to claim as verified. SDK developer-path run 40390669721 passed on prior commit 4909d91, including +native lifecycle and package operations; SER8 is unreachable. Validate this +changed source and retain the result before claiming it passes. The current core-only macOS +suite, including the unread scoped-stream case, passes 102 tests and clippy. + +## SDK authoring scenario tool — 2026-10-26 + +The benchmark worker now accepts a confined scenario-file path for `gate`, so +model authors can run the same acceptance scenarios supplied by SDK starters. +Five boundary tests pass; a local worker-to-CLI smoke passed all seven settings +gates, including four named scenarios. This is not a model trial or isolated +Linux benchmark preflight; the changed worker/controller still need staging and +validation on SER8 before admission. Source-matched ARM runs remain pending. + +## SDK context-bound process streaming — 2026-10-26 + +The Rust SDK now offers `spawn_streaming_scoped`: context expiry cancels the +owned process, and chunks and completion carry their context to the final state +owner. The test switches context after receiving a real process chunk, verifies +the queued chunk and completion are rejected, and verifies a new stream works. +A further macOS regression verifies unread buffered bytes and a completed reply +are both rejected after the context closes, even after the process exits. +The complete SDK core suite and strict clippy passed in a macOS SDK-only copy. +This source change postdates the previous Linux/ARM and GTK qualification; +source-matched Linux, ARM and release-host validation remain outstanding. It +does not automatically scope GTK feeds or external backend subscriptions. + +## SDK benchmark packaging and quit checks — 2026-10-26 + +The SDK authoring harness now exposes packaging through its fixed SDK tool +surface and treats failure to quit on Ctrl+Q as a failed capture. An isolated +uid2000 smoke built a real .deb and launched the generated settings window; +a separate window that ignores Ctrl+Q produced the expected failure. Evidence +is in `sdk-bench/receipts/2026-10-26-pack-preflight`. This smoke did not install +or remove its package. Four boundary tests pass. The first model trial and +independent acceptance remain open; the latest attempt to check SER8 timed out, +so its current model residency is unknown. Native ports of every app are not a +completion requirement. + +## SDK authoring preflight retained; model admission deferred — 2026-10-26 + +The full offline uid2000 tool preflight succeeds through generation, build, +actual external capture and Ctrl+Q; the fixture screenshot has visible real +settings content without clipped primary controls. Four tool-boundary tests +and the three native suites pass. All 80 SDK source fingerprints match the +production snapshot. Sanitized configuration, seed/generated source and locks, +provisioning/prewarm logs and tool results are retained under +sdk-bench/receipts/2026-10-26-preflight. Benchmark helper boundary tests now run +in SDK CI; CI never launches the model controller. + +The s01 seed17 controller's admission attempt exited before inference because +qwen3.5:2b was already resident in the existing Ollama service. Residency does +not prove active inference; the conservative rule avoids replacing that worker. +No prompts were dispatched, generated model code was run, or model-quality +score claimed. No daemon or owner workload was stopped/switched. The synthetic +smoke project/state was archived and cleared; the sandbox is empty for a future +properly admitted cohort. Keep the admission receipt; do not count it as a +failed or completed model trial. Full-spec/baseline/repeated-model qualification +remains open. + +SDK ARM developer-path run 40378225258 succeeded on bd002fa, and matching +SDK/System Monitor run 40378225297 passed. This covers the current production +Rust context-binding code; newer changes here are benchmark tooling/docs only. +Native app ports/product feature parity remain outside SDK completion scope. + +## SDK model authoring discovery runner and offline preflight — 2026-10-26 + +Added a bounded SDK JSON-action authoring controller for the frozen benchmark +specs, plus a fixed project-only tool worker and external window/capture/quit +probe. Four boundary tests pass. It pins qwen3.5:4b digest + d8b0f5e9760cd1682034f292d7ef72ec46f432149be0df7574bf2d6e92e38c04, +packaged Apache-2.0 license, runtime/options and prompt/spec/source identities. +The model receives actual app frames; independent audit alone can establish the +rubric done bar. `done` is a candidate, not a pass. No baseline/repeated-model or +whole-SDK completion result is claimed by harness preparation. + +Prepared a separate ephemeral msdk-bench-20261026 clone with uid2000, zero +capabilities, loopback-only networking for execution, no owner-data mounts and +configured CPU/memory/process/disk bounds. Trusted GTK/SQLite/screenshot setup +and cache warming occurred before the trial timer. Initial provisioning failed +because networking was disabled too early; no model code/inference ran. Corrected +order is provision first, disable and verify before generated code. No host +model daemon was restarted, no second GPU worker launched, and no owner app, +desktop, accounts or service data changed. + +Offline unprivileged native CLI/lifecycle/runtime preflight passes. Fixed +settings new/gen/build/capture/Ctrl+Q succeeds through the actual tool bridge: +generation ~0.021s, cold cache-completion build 82.12s, window mapped ~0.283s and +capture ~0.927s. These are harness/provisioning facts, not model coding times or +a general performance comparison. Archive/clear that owned smoke project before +starting the unchanged s01 model cohort. Retain all failures/interventions and +inspect produced code/GUI/SQLite/shortcuts before scoring. See sdk-bench/RUNNER.md. + +## Owner SDK scope clarification: native is not mandatory for every app — 2026-10-26 + +The owner explicitly said we do not need a native experience for all apps. +SDK completion covers reusable SDK capabilities and a small set of representative +consumer/integration flows. Preserve suitable web interfaces, wrappers, webview/ +hybrid architectures and existing clients; do not create a project-wide native +porting or full app-parity prerequisite. Generic WebView hosting is not currently +a shipped vocabulary component, so do not imply that integration already exists. + +Updated SDK-COMPLETION.md, RUST-PANTHEON-SDK.md and APP-BUILDING-GUIDE.md to apply +this scope. Full T3/client parity and app-by-app native status ports are separate +app work. SDK host quality, declared API/lifecycle/authority contracts, selected +reference flows, distribution, developer usability and supported-host validation +remain SDK work. Signal/Messages deferral stays in force. No new consumer app +port or owner desktop/service/account changes were made for this clarification. + +## Typed GTK reply contexts and ARM foundation pass — 2026-10-26 + +ARM developer-path run 40375089386/job 121755848259 succeeded on pushed +7a5f4d27deeabf6334ba9c3d441e39eb0374ed3a, including core/schema, generated app, +keyboard/AT-SPI, text/theme captures, native CLI/lifecycle/runtime and package +lifecycle. SDK/System Monitor run 40375089841 also passed. Preserve these +completed runs; the newer scoped GTK reply work needs its own current CI. + +`ServiceReply::in_context(token)` now binds once before work, with binding and +first completion shared across clones. The Host checks tokens at final typed +GTK delivery. An error callback keeps its token through its additional queue; +a context switch between error receipt and callback cannot mutate the new page. +Synchronous invoke Err also uses the shared binding. Rebinding or binding after +completion is invalid input. A provider that binds then declines gets an owned +unavailable result; it cannot trigger a real unscoped built-in fallback. Replies/queues retain no GTK/Host ownership. + +Native regressions prove obsolete success/error rejection, synchronous denied +reply after binding, the second-queue callback race, current recovery, actual +visible GTK labels and Host release/stop. Core and existing lifecycle/CLI tests +and strict lint pass in the disposable SER8 environment. The change is explicit +opt-in: legacy raw events, feeds, built-ins/pre-invoke version failures, +streaming and T3/network adapters are not automatically scoped. Real backends +must retire reads/workers and preserve visible account identity separately. +SDK-RUNTIME-CONTRACT.md documents those boundaries. No owner desktop/accounts/ +services/kernel/panel changes. Continue full ledger and final current CI. + +## SDK current runtime/reference native qualification — 2026-10-26 + +Resolved the prior source-transfer approval block with direct owner-machine +context plus SSH/container identity evidence; automatic review accepted the +scoped SDK-only transfer. Existing ephemeral SER8 container remained running; +no owner desktop, accounts, panel, kernel or services changed. Current isolated +Ubuntu 26.04 x86_64 / Rust 1.93.1 / GTK 4.22.4 qualification passes 100 core +checks, three native suites (CLI failure exits, D-Bus lifecycle, typed runtime), +SDK strict Clippy and generated Home Storage model/build/strict Clippy. + +The actual generated app's keyboard/AT-SPI flow proves an absent synthetic HOME +causes a recoverable real command error, then a keyboard retry succeeds in the +SAME process after the harness creates that folder. Ctrl+Q passes separately. +Eight source/binary-matched light/dark, requested 480/900 widths and asserted +10/15-point captures pass keyboard recovery and visual inspection. Original raw +df table wrapped at larger text and was rejected; labeled figures now remain +readable, and unsupported report shapes fail instead of inventing usage. + +Actual package creation, install, reinstall, installed-binary equality, installed +launch and owned-file removal pass in the disposable container. Final executable +SHA256 74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464; +package d01aa58ba3a3b560c696806a788fd4772e206687ffd84241190bc19f0caf166e. +All 80 SDK source/fixture hashes match the qualified code. Retain receipts under +sdk-tests/receipts/2026-10-26-native-runtime-reference, including generated source, +locks, raw synthetic logs, screenshots and rejected layout evidence. + +The full SDK goal stays active. Next: current ARM CI, GTK context/streaming and +real backend adapters, shared CodexBar-derived status module/host conformance, +controlled exact-model/novice trials and performance, then physical Pantheon/ +M-series acceptance and release audit. Existing ARM foundation run 40363235712 +on ed9bc5b is completed prior evidence, not current-runtime ARM acceptance. + +## SDK request context ownership and stale reply delivery — 2026-10-26 + +Added core RequestContext/ContextToken/Scoped for app-owned account/page/ +selection generations. Advance invalidates old successes/errors, including +already queued replies; close is permanent and last-owner drop invalidates +without tokens retaining the owner. Freshness is checked at final delivery, +with switches and application serialized on the state-owner thread. Tokens +store no account data and Scoped Debug omits its value. Native UI must continue +to show the actual identity and cannot treat the token as authority. + +`process::spawn_scoped` checks the token before starting and during bounded task +work, cancels/reaps when its context expires and delivers a scoped completion. +Core tests exercise stale queued success/error, independent/returning contexts, +owner release/close, an already closed task that never executes, real sleeping +process cancellation/reaping and a successful replacement request. Runtime +discovery publishes the explicit core APIs and automatic-adapter limitations. + +GTK ServiceReply/streaming chunks/T3 network subscriptions are NOT automatically +scoped yet. Core freshness is a snapshot, not an arbitrary cross-thread state +transaction or rollback. These adapters and native final-source qualification +remain open in SDK-COMPLETION.md. SER8 source-transfer approval is still pending; +no transfer/retry/bypass or owner services/desktop/accounts/kernel/panel change. + +## SDK entry points stop on manifest and validation failures — 2026-10-26 + +Core CLI `check`, `render`, `gate`, `complete` and `agent-manifest` previously +printed service-manifest errors and continued with incomplete contracts. They +now stop on unreadable/invalid/conflicting manifests; check emits structured +service-manifest errors in JSON mode. Adjacent discovery is deterministic and +reports directory errors. Missing explicit paths/flag values fail. A check with +no descriptions no longer returns a false success. `gate --services PATH` no +longer mistakes the flag for a gates filename. Generation/package already +propagate loader errors; actual CLI tests verify generation creates no output +when an adjacent manifest is invalid. + +GTK preview now stops on invalid manifests and missing --services values, +reports discovery errors, and returns failure for rejected descriptions/surfaces +or failed screenshots rather than quitting with success. A private-session native +CLI test is added to the native workflow for those failure paths, but has NOT +been compiled/run here: Linux source-transfer authorization remains pending. +Core executable tests pass on macOS; final receipts distinguish that evidence +from unqualified GTK code. No remote retry or owner desktop/service/account/ +shipping action was performed. Continue final native qualification, GTK +streaming/context adapters and the full completion ledger. + +## Atomic versioned SDK manifests and compatibility boundaries — 2026-10-26 + +Manifest loading now validates its complete input and conflicting registered +service/feed shapes before publishing under one write lock. Invalid later +entries cannot leave earlier entries registered; concurrent conflicting loaders +have one winner, and the losing manifest publishes nothing. Identical reloads +are idempotent, independent of argument/field object order. Explicit +manifest_version 1 is supported; omitted version preserves legacy v1 manifests. +Unsupported versions and malformed/unknown fields fail explicitly. Rejected and +idempotent manifests no longer leak strings into the lifetime registry. + +SDK-COMPATIBILITY.md distinguishes package, app-description, manifest, extension, +diagnostic, GTK and shell protocol versions; publishes candidate ownership, +migration/deprecation rules and actual host evidence; and keeps real backend +protocols and physical supported-host release qualification open. Runtime +discovery derives package/app/manifest versions from actual constants. Version +errors guide migration rather than blindly relabeling an incompatible document. + +Eight manifest checks cover rollback, conflicts, idempotency, feed shape, +concurrency, malformed input/version and immutable document rejection. An initial +full core run exposed simultaneous generator-test scratch directories with the +same timestamp; an atomic serial and exclusive-create retry repair the collision. +That failure is retained with final local receipts. No remote source transfer, +owner desktop/service/account/kernel/panel mutation or whole-SDK completion claim. +Linux final-source validation remains pending the previously requested explicit +SER8 source-transfer authorization. Continue GTK streaming/context adapters and +remaining completion-ledger gates after qualifying the final sources. + +## Bounded Rust process streaming — 2026-10-26 + +`msdk::process::spawn_streaming` now supplies private raw stdout/stderr chunks +before completion. Its owned subscription and process handle cancel on drop, +including silent work. A 32 × 8192-byte queue uses nonblocking delivery; a slow +consumer terminates the task with output-limit failure rather than hanging the +worker. Already queued/consumed partial output survives cancellation and timeout; +stream closure precedes completion, which remains the terminal-status authority. +Raw bytes preserve invalid UTF-8; Chunk Debug omits payloads. Discovery records +the Rust API/limits separately from completed-output `process.run`. + +Five new real-process checks pass on macOS: early private stdout/stderr plus +cancel, raw byte fidelity, bounded slow-consumer failure, silent-task cancellation +on subscription drop, and partial output after timeout. Full core suite (82 +checks), strict Clippy and formatting pass. Linux current-source qualification +still awaits explicit source-transfer/destination approval; no remote retry was +made. GTK streaming/progress adapter, stale-context protection and the updater +reference consumer remain unfinished. See SDK-RUNTIME-CONTRACT.md for semantics. +No owner desktop, services, accounts, kernel or panel changed. + +## Typed SDK runtime and owned task commands — 2026-10-26 + +ARM developer-path run 40363235712 passed on ed9bc5b. Continue that evidence; no +replacement was needed for the completed foundation run. + +Added candidate `ServiceFailure`/FailureKind diagnostics, `msdk describe runtime` +and runtime-code explanations. Modern `Services::invoke(ServiceCall)` owns typed +async replies; registered result shapes are checked, first completion wins and +errors do not fall through to real system work. Extension interface version 1 is +checked before dispatch; real backend OS/network protocol negotiation remains +separate. Existing provider entry points remain compatible. Missing fixture +replies now fail explicitly, and fixture traces omit arguments. + +`msdk::process` owns a Linux/macOS process group, nonblocking pipes, monotonic +120-second/default 1-MiB combined output bounds and cancellation/reaping. Host +concurrency is four and accepted close cancels handles. Kernel PID identity is +held until group signals finish, with cancellation serialized. Private stderr +can reach app UI, while Debug/Display/diagnostics omit payloads. Streaming, +partial output, privileged/daemon job supervision and app-context races remain +open; no whole-SDK or backend stability claim. SDK-RUNTIME-CONTRACT.md records +actual identifiers, limits, compatibility and reproduction commands. + +Real process/diagnostic tests pass on macOS. Initial Linux core/native checks +pass, including blocked mismatch and recovery, unavailable/malformed/denied +async replies, duplicate rejection and real command termination on close. +Final fixture-no-fallback and updated discovery checks remain to qualify on the +final Linux source. Automatic approval review rejected the updated source transfer +to SER8 pending explicit destination/payload authorization; no transfer was made. +Local core/lint/format checks pass. Home Storage now supplies a read-only useful +reference flow, duplicate-submit suppression and actual command error/retry tests; +SDK-GOLDEN-PATH.md records reproduction and still-pending native UI/trial gates. +Next: authorize/resume isolated Linux qualification, retain source-matched receipts, +then shared status module, streaming and controlled model trials. +No owner desktop, accounts, services, kernel or panel changes. + +## Source-matched SDK developer-path receipts retained — 2026-10-26 + +The final isolated x86_64 pass covers exact SDK code `287886e3b4399c742bf286bbaf3905b36439467d`; +all 67 source/fixture fingerprints match the checkout. Receipts, generated Cargo +sources, dependency locks, raw synthetic test/install logs, eight reviewed PNGs +and retained failures are under `sdk-tests/receipts/2026-10-26/summary.json`. + +65 core tests pass; strict core/runtime and generated-app lint pass on Rust +1.93.1/GTK 4.22.4. Native private D-Bus lifecycle proves accepted/vetoed close, +stop/read behavior, late-event rejection and Host release. Live keyboard and +AT-SPI checks prove Switch/ComboBox/Button names/roles, saved values, reset and +Ctrl+Q. All eight light/dark, 480/900-wide, asserted Sans 10/15-point captures +were visually inspected without clipped actions/labels. This is isolated GTK +rendering, not owner visual or physical-scale/Wayland acceptance. + +Actual `.deb` metadata/dependencies, fresh install, reinstall, byte equality, +installed launch and all five owned artifact classes' removal pass. Final app +SHA256 is `e68aefa505ea9f16eeb8d475d6997f4340cd10e3cfe31b9d504ed92e78c91feb`; +package SHA256 is `ebc6015c44c2adc4ebe394ef3f0561edfab0ab5900b3230130e95a0feb69f317`. +Unmodified SDK/app lock files and generated sources are retained. No owner's +services, desktop or accounts were changed. The completion ledger retains all +remaining gates: versioned service/errors/process cancellation, shared status +module/T3 host semantics, model usability, performance and supported target +architecture/distro/owner qualification. The full SDK goal remains active. + +A final schema-probe interruption came from AppleDouble files in an early Mac +archive; preparation/filtering now ignore that metadata. Completed core/lint/ +lifecycle work was reused, and only unfinished phases resumed. ARM CI still +needs the official-ports provisioning correction qualified; source merge is +not a claim of complete SDK acceptance. Next: inspect that new CI handle, then +implement the service/error/cancellation contract and its useful golden-path app. + +## SDK native validation and authoring repairs — 2026-10-26 + +The SDK now has standalone typed Cargo generation and explicit ELF-to-Debian +packaging. In a new disposable SER8 Ubuntu 26.04 x86_64 container (Rust 1.93.1, +GTK 4.22.4), core tests, actual GTK lifecycle, generated-app keyboard/AT-SPI +controls, metadata validation, install/reinstall/installed launch/binary equality +and removal pass on the tested snapshots. Final source fingerprints/artifact +receipts are being retained separately; this is not whole-SDK or target desktop +acceptance. The owner's containers, desktop, panel, accounts and kernel remain +unchanged. The temporary msdk-validation-20261026 container is scoped to this +SDK goal; retain its build cache while work continues. + +Concrete repairs: weak Host dispatch/event ownership; cancelable/serialized +window polling with an owned handle; provider teardown hook and late-event +rejection; accepted-close disposal (a vetoed close stays usable). Independent +native D-Bus reads prove enabled/closed/disabled behavior and Host release. +Generated apps have standard Ctrl+Q and native window-control layout. Visual +review rejected oversized custom oval controls and a missing dropdown label; +those are repaired. Original GDK_DPI_SCALE screenshots did not change text and +are not larger-text evidence. The corrected private GTK 10/15-point profiles +assert the effective font setting before capture. Physical scale/theme/owner +acceptance remain open. + +The JSON schema previously omitted initial/persist/feeds/update/logic and could +not accept the shipped starters. It now describes those and all rule verbs; +an independent Draft 2020-12 validator accepts 11 real descriptions/metadata +cases and rejects seven malformed action shapes also refused by the checker. +Generated manifests register once; corrected package metadata passes actual +AppStream validation. A stale probe selected static labels rather than their +identically named controls; that failure is retained before its repaired live +Switch/ComboBox/Button checks. Rust 1.93 strict lint exposed older boolean +forms; equivalent rewrites retain lexer bounds ordering and pass native lint. + +Run 40355512113 reached its 25-minute limit during Azure package provisioning, +not SDK tests. Its log shows the two Rust archives stalled for minutes. The +workflow now selects official Ubuntu ports while preserving signed APT trust, +adds bounded download waits, independent schema checking, actual keyboard and +accessibility checks, native lifecycle and compact/larger-text rendering. +Next: retain final source-matched receipts and arm64 CI; then finish versioned +service/error/process cancellation contracts, reusable status module conformance, +model-authored app trials/performance and target-host qualification. All remain +open in SDK-COMPLETION.md. Signal/Messages remain deferred. + +## SDK native compilation reached — 2026-10-26 + +Run 40354775593 passes core and compiles/tests the generated GTK app, then fails +strict lint on redundant imports for a starter without records. Qualified derive +paths remove them; generated fixture compilation now denies warnings. Native +rendering and package/install/remove qualification remain open. + +## SDK explicit binary packaging — 2026-10-26 + +Added `msdk pack --binary --output `: matching native +architecture required, shared-library dependencies resolved from the supplied +binary with dpkg-shlibdeps, metadata validated before archive publication, +owned executable/desktop/icon/metainfo/license files included. Existing outputs +are never replaced. No build, app execution, installation or background service +is performed by the command. Generated projects now include icon/license assets +and preserve declared-service manifests for packaging. App-specific attribution +and production metadata remain release review work. + +Core architecture/metadata-injection/XML checks and strict lint pass on macOS; +actual package/native runtime qualification is Linux-only and pending. The +workflow now exercises package creation, installation, reinstall, installed +binary equality/launch and removal on a disposable runner. Full target desktop, +service/lifecycle, benchmark and owner acceptance gates remain open in the SDK +completion ledger. No owner's desktop or running panel changes. + +## SDK Linux first-run dependency correction — 2026-10-26 + +Native workflow run 40354229616 failed before GTK build: the generated-model +integration test uses offline Cargo, but serde derive/proc-macro dependencies had +not been provisioned by core Cargo tests. Added the actual test dependency and +copied the parent lock into the generated fixture before offline compilation. +This preserves offline test execution and pinned versions; it does not weaken +or skip generated-code compilation. Native build/render checks remain pending. + +## SDK standalone app generation and core reconciliation — 2026-10-26 + +Added `msdk gen` for checked descriptions: independent Cargo project, inspectable +Rust records/State/Message/event bridges, embedded document/service manifests, +real GTK executable and initial-state test. No custom backend or Rust logic is +silently invented. All six generated models compile; keyword/collision cases +and >2^53 integers round-trip exactly. Starter escaping remains covered. +Reconciled two stale core tests with the current T3 SDK identity and Usage +start page while preserving permission/page-visibility assertions. + +Core tests and strict clippy pass in the isolated macOS core workspace. New +Linux native generation/build/launch screenshot CI is pending; target desktop, +package/install, lifecycle, model usability and owner acceptance remain open. +`SDK-COMPLETION.md` preserves the full requested completion contract and next +gates; mandatory SDK/authoring and CLI docs describe the new command accurately. +No desktop installation, live account reads, kernel or panel changes. + +## SDK starter literal-name repair — 2026-10-26 + +`msdk new` now JSON-escapes supplied identity/name strings and substitutes original +placeholders once. Quotes, backslashes, Unicode, newlines and names resembling +placeholder text no longer corrupt or recursively rename generated descriptions. +Five template tests pass; actual CLI settings generation in JSON and `.msdk` +formats passes `check` and `gate` with a quoted/backslashed Unicode name. + +Verification used an isolated copy of the unchanged msdk crate plus its external +fixture files, with cached Cargo dependencies on macOS. Workspace offline testing +cannot resolve the uncached pinned Smithay Git dependency. The full isolated core +suite has two failures: inspect expects the old T3 Chat default/usage heading, +and intents expects absent tool `claudepantheonrs_send`. These are outside template +rendering and remain open; no green whole-suite or GTK/runtime claim is made. + +Next SDK completion work: reconcile those T3 contract tests; provide a complete +standalone app/build/package path; qualify versioned service errors and optional +capability lifecycle; exercise native Dock conformance (#605), and retain actual +visual/accessibility/installation and controlled model-authoring evidence (#535). +Signal/Messages remain deferred. No desktop installation or panel restart. + ## Unified native T3 panel integration — 2026-10-26 Merged Fleet PR #607 at `04fe68e6`. Owner does not require particular remote diff --git a/mseries/RUST-PANTHEON-SDK.md b/mseries/RUST-PANTHEON-SDK.md index 1bca51592..8ee2f56ed 100644 --- a/mseries/RUST-PANTHEON-SDK.md +++ b/mseries/RUST-PANTHEON-SDK.md @@ -15,12 +15,27 @@ product work and scope changes. Continue independent work while awaiting feedbac ## SDK and template direction +The owner clarified that not every app needs a native experience (2026-10-26). +Focus SDK work on reusable capabilities and a small set of representative +consumers. Keep an existing web UI, wrapper or hybrid architecture when it fits +the app. Do not require a complete native port or native feature parity for each +consumer before qualifying the SDK. A webview/hybrid integration is an explicit +implementation choice, not a currently shipped generic WebView component. + +Version identifiers, ownership and qualification boundaries are published in +[SDK compatibility](SDK-COMPATIBILITY.md). These are candidate development +contracts; whole-SDK v1 release readiness remains unproven. + +For a useful read-only service/retry example and explicit pending native gates, +follow [Home Storage developer path](SDK-GOLDEN-PATH.md). + Use the implemented `.msdk`/JSON description, rules and declared-service path for SDK apps, with app-local Rust `Services`/`Logic` for documented gaps. Native Rust GTK/Granite helpers remain available in `mseries-pantheon-kit`. Native T3 (`claude-pantheon-rs`) and the SDK-hosted T3 executable (`claude-pantheon-sdk`) are separate consumers; native features do not imply -SDK parity. Source inventory: [SDK audit](SDK-AUDIT-2026-10-23.md#2026-10-25-t3-monitoring-and-sdk-qualification-addendum). +SDK parity, and full product parity is not an SDK completion requirement. +Source inventory: [SDK audit](SDK-AUDIT-2026-10-23.md#2026-10-25-t3-monitoring-and-sdk-qualification-addendum). | Implemented path | Boundary | | --- | --- | @@ -30,10 +45,23 @@ SDK parity. Source inventory: [SDK audit](SDK-AUDIT-2026-10-23.md#2026-10-25-t3- | `FixtureServices` | Isolated UI/data scenarios, not proof of live integration. | | Native kit | Separately consumed GTK/Granite, scaling, accessibility, polling/badge helpers; lifecycle must still be qualified by the app. | -`msdk gen`, `msdk pack`, `msdk parity` and a live introspection registry remain -proposals, not commands to give an LLM as existing tools. The implemented -description generator is real; complete standalone app/package generation is -not established. Follow the [T3 priority-slice gates](APP-BUILDING-GUIDE.md#t3-priority-slice-and-sdk-qualification-gates): +`msdk gen --sdk-root /rust` now +creates a standalone Cargo project with typed records, State/Message bridges, +the embedded description and a real GTK Host executable. Neighboring +`*.services.json` manifests are embedded, but application-specific service/feed +implementations still require an app-local adapter. Custom Rust logic is rejected +with a LogicFactory instruction rather than replaced with a no-op. Generation +never installs or executes application services. See the [CLI guide](../rust/msdk/README.md). + +`msdk pack --binary --output ` +assembles a Debian package on the matching Linux architecture using dpkg-dev, +desktop-file-utils and appstream. It derives shared-library dependencies from +the supplied executable, includes desktop/AppStream/icon/license assets, validates +metadata and refuses existing outputs. It never builds, installs or runs the app. +The exact supplied binary must separately be tied to the tested source/build. +`msdk parity` and a live introspection registry remain proposals. +Native build/run, packaging and full SDK readiness are tracked separately in +[SDK-COMPLETION.md](SDK-COMPLETION.md). Follow the [T3 priority-slice gates](APP-BUILDING-GUIDE.md#t3-priority-slice-and-sdk-qualification-gates): token monitoring and RepoBar-derived GitHub overview first (#596), with Shiplog (#595) building on that data. Whole-chat parity is a separate contract. @@ -48,6 +76,16 @@ Keep service authority behind explicit versioned APIs. Preserve existing clients data, account boundaries and recovery paths during migrations. Do not import private service databases or replace transport implementations to simplify a UI. +## Runtime errors and owned work + +Read [SDK-RUNTIME-CONTRACT.md](SDK-RUNTIME-CONTRACT.md) for the implemented +`Services::invoke`/`ServiceReply` path, extension-version checks, typed private-safe +diagnostics, completed-result payload validation and owned process limits. +`msdk describe runtime` and `msdk explain CODE` expose that contract to authors. +Backend protocol/version qualification, streaming/progress and context-specific +adapter cancellation remain separate gates; the extension version is not an OS +or provider API version. + ## Fast build loop and honest delivery Use incremental debug builds, focused checks and shared caches during iteration. diff --git a/mseries/SDK-COMPATIBILITY.md b/mseries/SDK-COMPATIBILITY.md new file mode 100644 index 000000000..5f364be8f --- /dev/null +++ b/mseries/SDK-COMPATIBILITY.md @@ -0,0 +1,83 @@ +# SDK compatibility and ownership + +Status: candidate policy for the current SDK 0.1 development line. This publishes +the implemented boundaries; it does not certify whole-SDK v1 readiness. Release +qualification and evidence remain in SDK-COMPLETION.md. + +## Versions identify different contracts + +| Contract | Implemented identifier | Owner and enforcement | +| --- | --- | --- | +| Rust packages | msdk / msdk-gtk 0.1.0, edition 2024 | SDK crates in this repository; generated apps currently depend on an explicit local checkout, not a published stable crate | +| App description | `sdk: 1` | `msdk::FORMAT_VERSION`, checker and generated schema; unsupported versions are rejected before code generation or Host startup | +| Service declaration manifest | `manifest_version: 1`; omitted means legacy v1 | `msdk::vocab::SERVICE_MANIFEST_VERSION` and `load_manifest`; describes names, capabilities, arguments, results and feed fields | +| Rust service extension | `Services::api_version() == 1` | msdk runtime and msdk-gtk Host; checked before calls/feeds; separate from manifest and backend versions | +| Runtime diagnostic | `msdk.runtime.diagnostic.v1` | msdk runtime; category, static recovery text and call/source identity; excludes private arguments/output/detail | +| GTK binding and API floor | gtk4 Rust crate 0.11, `v4_20` feature | msdk-gtk Cargo manifest and generator; native headers/runtime are host dependencies, not supplied by the SDK | +| Pantheon shell protocol | `io_elementary_pantheon_shell_v1` interface, maximum version 2 | Vendored compositor protocol XML; panel client binds `min(advertised, 2)` in panel.c. Surface placement still requires a compositor implementing it | +| Real OS/network backend | Provider-specific; no universal version assigned | Backend owner and app adapter must publish protocol, version, account/scope authority, cancellation and availability behavior | + +The `v1` in a protocol's name does not override the XML interface version. +Neither a Rust service extension version nor a manifest version proves that a +Gala D-Bus service, T3 server, GitHub API or other backend is compatible. + +## Manifest loading + +The loader validates the complete manifest before publishing anything. Unknown +keys, malformed arrays/objects, invalid declared types, duplicate names within +one manifest, unsupported manifest versions and conflicting registered contracts +are errors. Identical reloads are idempotent; argument/field object order does +not change the contract. Conflict validation and publication share one registry +write lock, so concurrent loaders cannot partially publish a losing contract. +An error leaves earlier registered contracts intact and adds nothing from the +rejected manifest. CLI check/headless tools and native preview must stop on +manifest read/validation errors; they must not continue with an incomplete +contract. `check --json` emits a service-manifest diagnostic. Native preview +activation/screenshot failure is a nonzero exit, separate from owner acceptance. Successful registry declarations live for the process lifetime. + +Direct Rust `register_service`/`register_feed` are legacy one-declaration entry +points; their silent duplicate behavior is not transactional manifest loading. +Use `load_manifest` for app/plugin declarations. Register manifests at startup, +not on each event. This registry is discovery/type metadata, not permission +granting, a sandbox, a network connection or an implemented backend. + +## Compatibility and migration policy + +Descriptions, manifests and declared service payloads must be checked before +generation/launch. Unsupported versions must fail explicitly; changing only a +version number is not a migration. Keep the original input, use a compatible SDK +or migrate content with explicit review, then check, regenerate typed models and +run the app's behavior/installation tests. No automatic migration is implemented. + +Within description format 1, existing accepted component/action/property names +and payload meanings should be preserved. Additions must keep checker, schema, +discovery, text syntax, generator and Host aligned. Incompatible meaning changes +require a new format and an explicit migration path before release. Service +extensions and backend protocols evolve under their own versions. Changes to +argument types, required capabilities or result shapes are incompatible contract +changes; the loader refuses two different definitions under one registered name. + +The Rust 0.1 API is provisional. Source-breaking work must be recorded in the +handoff and consumer guide with an actionable replacement; do not advertise +stable Rust ABI or crates.io availability. Existing raw-event `Services::call` +adapters remain compatibility entry points, with their own result-validation, +cancellation and stale-context obligations. New adapters should use typed replies. +No removal timeline is promised until a release policy and consumer migration +are qualified. No released deprecation is currently declared by this document. + +## Host qualification boundary + +| Environment | Evidence and limitation | +| --- | --- | +| macOS arm64 | Core checker/rules/generator/model and real process/streaming tests pass on retained revisions; this is not a Pantheon GUI or Debian install target | +| Isolated Ubuntu 26.04 x86_64, Rust 1.93.1, GTK 4.22.4 | Prior source-matched GTK/settings app, keyboard/accessibility, light/dark/text-size and package lifecycle receipts exist; runtime/reference snapshot cb77b66 passes source-matched core/native tests, lint, eight reference captures and package lifecycle; newer typed GTK context binding has separate native regression receipts; physical Pantheon qualification stays open | +| Linux arm64 CI | Developer-path run 40363235712 passed on ed9bc5b; this does not qualify newer source or physical M-series hardware | +| Physical elementary/Pantheon on M-series | Target theme, Wayland surfaces, physical scales, hardware lifecycle and owner acceptance remain open | +| Windows | Core Rust compilation and taskbar/status host parity are not qualified; process runner currently returns unavailable outside Linux/macOS | + +A generated standalone window does not qualify panel/dock protocol behavior. +The separate native GTK/Granite kit and native T3 implementation are consumers +or adjacent libraries, not proof of SDK-hosted parity. Exact backend OS versions, +supported release distributions and the physical host matrix remain release +gates. Owners are the repository components above; this document does not invent +external maintainer commitments or support guarantees. diff --git a/mseries/SDK-COMPLETION.md b/mseries/SDK-COMPLETION.md new file mode 100644 index 000000000..f54d0a8c2 --- /dev/null +++ b/mseries/SDK-COMPLETION.md @@ -0,0 +1,53 @@ +# SDK completion and qualification ledger + +The requested outcome is a complete, tested and validated Rust Pantheon app SDK. +The product contracts are issue #535, the current APP-BUILDING-GUIDE and +RUST-PANTHEON-SDK, the sdk-bench specs/rubric, and the Dock standard proposed in +PR #605. Existing Signal/Messages deferral remains in force: use synthetic +messaging data for SDK checks; do not resume or replace those clients. + +Owner scope clarification (2026-10-26): a native experience is **not required +for every app**. Complete and validate the SDK's shipped capabilities and a +small set of representative flows. Existing web interfaces, wrappers, webviews +and hybrid apps can be retained where appropriate; do not turn SDK completion +into a project-wide native UI migration. A frontend integration must actually +exist and be tested before it is advertised; the current vocabulary does not +ship a generic WebView component. Full T3/product feature parity, consumer +redesigns and app-by-app native status ports are separate app work, not SDK +completion gates. Applicable backend/lifecycle/security contracts still apply +to interfaces the SDK actually ships or claims to support. + +A green compiler/test run is scoped evidence. SDK completion requires every +applicable row below to have retained source-matched evidence; missing evidence +is an open gate. No completion percentage is assigned. + +| Requirement | Authoritative evidence needed | Current state / next work | +| --- | --- | --- | +| Ownership/runtime/API support | Published graphics, shell, toolkit and app API versions/owners; stable/provisional/unsupported boundaries; compatibility and deprecation policy | SDK-COMPATIBILITY.md publishes candidate version/owner/migration boundaries and actual host evidence; manifest loading is versioned and atomic; exact real backend OS protocols and release/physical supported-host qualification remain open | +| Description authoring/discovery | Checker, schema, discovery and rules agree; all six starters pass; valid user strings survive generation | Starter escaping repaired; core suite includes current T3 identity/page assertions | +| Typed Rust and standalone app | `msdk gen` emits compiling records/State/Message plus a real GTK executable; original description/rules retained; custom backends explicit | All six model variants compile; actual generated settings app builds/tests/lints and runs on isolated Ubuntu 26.04 x86_64; source-matched receipts in sdk-tests/receipts/2026-10-26; hosted ARM developer-path run 40392328090 attempt 2 passes on dbf4eee, including scoped-stream core and native host checks; attempt 1 failed to open its display before accessibility registration; why the display failed remains unknown; physical target qualification remains open | +| Clean developer path | Clean checkout to useful app, recoverable service error, typed diagnostic/source context, optional capability, build/package/run guide; coding <=30 min and provisioning/wall time separately measured | Home Storage read-only sample and SDK-GOLDEN-PATH.md added; actual same-process keyboard/AT-SPI failure/retry, eight native reviewed captures, generated app build/lint and package lifecycle pass; measured novice/model trial still needed | +| Services and errors | Version mismatch/unavailable/denied/malformed data through actual adapters; bounded async/cancel/retry behavior; privacy-safe structured diagnostics | Candidate typed async replies, extension ABI checks, safe diagnostics, owned process groups and bounded Rust streaming/partial output implemented; scoped streaming and context pass core tests on macOS and hosted ARM Linux; native typed error/recovery/fixture/close checks pass on exact source; backend OS protocols and streaming/app-specific GTK adapters remain open | +| Optional lifecycle | Disabled/closed causes no extra reads, stale completions ignored, sources released; exact scope/account remains visible | Host/window watcher/process ownership and core scopes pass; explicit typed GTK reply bindings reject obsolete success/error including a second error-callback queue, with actual widget and release checks; scoped Rust streaming passes macOS and hosted ARM core tests; opt-in GTK feed context delivery passes a hosted ARM native lifecycle regression; legacy/built-in/GTK streaming/T3 context adapters and real account identity/teardown remain open | +| SDK native host/components | Source-matched light/dark, regular/compact, default/larger text and supported scales; keyboard-only primary journeys and live accessible names/roles in representative SDK consumers | Settings and Home Storage keyboard/AT-SPI and reviewed matrices qualify the SDK host on tested snapshots; target Pantheon/physical scales/owner acceptance remain open. No every-app native UI requirement | +| Shell/status module | Discoverable reusable CodexBar-derived provider/account module; Windows bottom-right and elementary status hosts; all semantics and exact interaction gates from #605 | Candidate `msdk::usage` data semantics pass macOS core tests; a candidate GTK row renderer passes a hosted ARM widget test; multi-provider previews, a scoped aggregate CodexBar read, GTK refresh/failure/retry control and reusable anchor hover, pin, dismissal and keyboard interaction pass synthetic hosted ARM checks (run 40416161840); an opt-in shared T3 host page passes local synthetic hosted/dock-mode checks with neighboring indicator stubs; live collector reads, account adapters, full presentation, actual desktop module builds and target qualification remain open; no parity claim | +| Installation/distribution | Correct executable/desktop ID/icon/metainfo; package validation, fresh install/reinstall/remove and source-installed-loaded identity | `msdk pack` implemented with actual ELF architecture/native-library dependency resolution and validated desktop/AppStream/icon/license assets; isolated x86_64 settings and current Home Storage package/install/reinstall/installed launch/binary equality/remove pass on source-matched snapshots; exact SDK/generated source fingerprints and binary/package hashes retained; arm64/target-distro/target-host qualification pending | +| Representative integrations | A small set of consumers or focused harnesses proves shipped SDK service, error, lifecycle and authority contracts; qualify any specifically advertised integration flow | Settings/Home Storage, real process work, private D-Bus and typed service/context cases supply evidence. Use existing frontends or focused adapters for any uncovered SDK contract; full T3/native product parity is separate. Messages remains deferred | +| Performance | Same hardware/workload startup/RSS/idle CPU/wakeups/render metrics; explicit build/provision/queue timings | No new performance result claimed | +| Model usability | Exact licensed model/runtime/weights/prompt/spec; clean isolated no-network trials, same rubric, failures/repairs/interventions retained; independent visual/behavior acceptance | Pinned discovery runner, four boundary tests and an offline non-root native/tool preflight are retained; initial s01 admission deferred before inference to preserve an existing resident model; independently scored cohorts, repeated runs and baseline comparisons remain open | +| Release/API readiness | All above gates audited against final immutable artifacts, docs match shipped behavior, unsupported scope explicitly recorded | SDK v1 completion remains unproven | + +## Current verification environment + +This chat's Mac has Rust but no GTK development package. Core checks use an +isolated copy of msdk and its external fixture files to avoid resolving the +unrelated pinned Smithay Git dependency in the whole-OS workspace. Generated +model compilation uses cached Cargo dependencies. This is not Linux GTK, target +Pantheon, installation, hardware or owner visual acceptance evidence. + +`mseries/sdk-tests/prepare.py NEW_DIRECTORY` creates the reproducible SDK-only +workspace, keeping the checked-in dependency lock as its starting point. The +M-series SDK developer path workflow provisions Linux separately, tests/lints +core, builds/tests/lints a generated GTK app and captures its actual executable +in light/dark isolated desktops. Its resulting locks/source/hash/screenshots are +retained. Runtime and target-host gates remain open until those are exercised. diff --git a/mseries/SDK-GOLDEN-PATH.md b/mseries/SDK-GOLDEN-PATH.md new file mode 100644 index 000000000..7636d5c41 --- /dev/null +++ b/mseries/SDK-GOLDEN-PATH.md @@ -0,0 +1,86 @@ +# Home Storage developer path + +This read-only example reports usage of the filesystem containing the current +user's home folder. It demonstrates one bounded asynchronous service call, +duplicate-submit prevention, a useful error and retry. It does not scan files, +remove data or start a background service. Closing the accepted window cancels +an unfinished check through Host process ownership. + +Status: source-matched isolated Ubuntu 26.04 x86_64 validation passes core +rules/actual command/error/retry, native generated model/build/lint, keyboard and +AT-SPI real failure/retry in the same process, eight reviewed light/dark 480/900 +width font10/15 captures, and package install/reinstall/installed launch/removal. +Receipts: sdk-tests/receipts/2026-10-26-native-runtime-reference. This is not a +measured novice/model <=30-minute trial, current ARM, physical scale, Pantheon +Wayland or owner acceptance result; those remain open. + +From a checkout on a Linux GTK 4.20+ development host with Rust 2024, GTK/Wayland +headers, pkg-config and wayland-scanner already provisioned: + +```sh +python3 mseries/sdk-tests/prepare.py /tmp/home-storage-sdk +cargo run --manifest-path /tmp/home-storage-sdk/Cargo.toml -p msdk -- \ + check /tmp/home-storage-sdk/msdk/examples/home-storage.ui.json +cargo run --manifest-path /tmp/home-storage-sdk/Cargo.toml -p msdk -- \ + gen /tmp/home-storage-sdk/msdk/examples/home-storage.ui.json \ + /tmp/home-storage-app --sdk-root /tmp/home-storage-sdk +cargo test --manifest-path /tmp/home-storage-app/Cargo.toml +cargo run --manifest-path /tmp/home-storage-app/Cargo.toml +``` + +Use new output directories: generation deliberately refuses to overwrite an +existing project. Click **Check again**. While work is pending, the action is +hidden and the app explains that closing the window cancels the operation. +On success, it displays labeled available/used/total space and used percentage from a +validated `df -Pk` report. Unsupported report shapes fail explicitly. The result +is filesystem usage, rather than a size calculation of the home folder. + +To review an unavailable backend without invoking a real command, create a +fixture containing `{"calls":{}}` and use the preview runner: + +```sh +printf '%s\n' '{"calls":{}}' > /tmp/home-storage-unavailable.json +cargo run --manifest-path /tmp/home-storage-sdk/Cargo.toml -p msdk-gtk --bin msdk-run -- \ + /tmp/home-storage-sdk/msdk/examples/home-storage.ui.json \ + --fixture /tmp/home-storage-unavailable.json +``` + +The fixture provider must return unavailable without falling through to the +actual command. Check again remains available after failure. Run the app without +the fixture to exercise recovery against the real read-only command. Fixture +results are synthetic; do not report them as real backend qualification. + +To inject an incompatible SDK extension version instead, use the same preview +command with a fixture containing `{"api_version":2,"calls":{}}`. The host +must show the incompatibility and must not run the real command. The fixture +version is an SDK extension interface version, not a backend OS protocol +version. Invalid version values are rejected when the fixture is loaded. + +`cargo test -p msdk --test golden_path` checks rules, visible recovery text, +duplicate calls and model generation. On Linux/macOS it also executes the exact +command with a child-only missing HOME, handles its actual nonzero error, and +retries with the real environment. It does not log home paths or mount output. +Native Host version/denial/malformed-result/fixture/no-fallback/close tests are +documented in SDK-RUNTIME-CONTRACT.md. Native golden-path UI qualification must +still use this exact description and a source-matched generated executable. + +Retain coding time separately from provisioning, download, compilation, queues +and wall time. The <=30-minute developer target needs a measured clean trial; +these commands and automated checks alone do not establish that result. + +Native reproduction after building the generated app: + +```sh +MSDK_PRIVATE_TEST_BUS=1 GSK_RENDERER=cairo xvfb-run -a dbus-run-session -- \ + python3 mseries/sdk-tests/home-storage-controls.py \ + --binary /tmp/home-storage-app/target/debug/msdk-homestorage \ + --output /tmp/home-storage-controls.json +bash mseries/sdk-tests/home-storage-matrix.sh \ + /tmp/home-storage-app/target/debug/msdk-homestorage /tmp/home-storage-matrix +``` + +Use the actual Cargo target directory if CARGO_TARGET_DIR is set. Both probes +require fresh output paths and synthetic isolated sessions. The matrix asserts +the GTK font profile and runs the real failure/retry flow before each generated +executable screenshot. It does not infer larger text from an ineffective scale +setting. Retain failed cases and visually review all captures before acceptance. diff --git a/mseries/SDK-RUNTIME-CONTRACT.md b/mseries/SDK-RUNTIME-CONTRACT.md new file mode 100644 index 000000000..b32a3752c --- /dev/null +++ b/mseries/SDK-RUNTIME-CONTRACT.md @@ -0,0 +1,251 @@ +# SDK service and process contract + +Status: implemented candidate contract for SDK 0.1.0; whole-SDK v1 qualification +remains tracked in SDK-COMPLETION.md. Inspect `msdk describe runtime` for the +implemented version, limits and failure codes. `msdk explain CODE` gives the +recovery message for runtime failures as well as checker diagnostics. + +## Typed service extensions + +An app supplies `msdk_gtk::host::Services` to `Host::open_with`. The primary entry +point is `invoke(ServiceCall) -> Result`. A request carries +the declared service name, arguments and an owned `ServiceReply`: + +- Return `Ok(true)` once the request is owned, including asynchronous work. Keep + its reply in that owned task and call `reply.success(payload)` or + `reply.fail(failure)` on completion. +- Return `Ok(false)` only before doing any work. This permits another runtime + adapter to handle the operation. `Err(failure)` is an owned failure and never + falls through to a real system action. +- Registered service return payloads are validated before delivery. Wrong + text/bool/none shapes become `service-malformed-data`, without logging the + offending value. Declare all supported APIs through a service manifest. +- The first terminal reply wins, even across cloned replies and worker threads. + Contradictory duplicate completion is ignored. Replies do not retain GTK. +- The Host assigns immutable service/call-source/operation identity to typed + replies and errors. Rules calls use their `/update/Message` JSON pointer; + custom Rust logic uses `/logic`. Operation IDs are host-local diagnostics, + not account identity or a substitute for context/race checks. +- `Services::stop` must retire the provider's own subscriptions, timers, workers + and pending requests. Its empty default is appropriate only when there is no + ongoing work. Closing an accepted window stops host-owned work; a vetoed close + keeps the Host usable. Late events cannot mutate a disposed Host. + +`Services::api_version()` defaults to the existing extension interface version 1. +The Host checks it before call/feed dispatch and refuses incompatible versions. +This is the SDK extension contract, **not** a declaration that an OS daemon, +D-Bus interface, T3 server or provider API uses version 1. Each real backend must +publish and negotiate its own supported protocol/version and authority boundary. +Those backend and T3 qualifications remain open. + +Existing `call`, `call_checked` and `start_feed` implementations remain compatibility +entry points. New service adapters should use `invoke`/`ServiceReply`. Legacy +raw event senders retain their own payload-validation and completion obligations; +compatibility does not qualify an old adapter automatically. Generic context +switch cancellation and app-specific adapter migration remain open gates. + +### Typed GTK reply contexts + +Before starting asynchronous work, bind its reply with +`let reply = call.reply.in_context(token)?;`. All clones share both the binding +and first-completion state, including the Host's retained clone used for a +synchronous `Err` from `invoke`. Binding twice, or after completion, returns a +typed invalid-input failure. A request cannot be rebound to a newer account to +make an old result current. + +Binding also claims the request's context ownership. A provider that binds and +then returns `Ok(false)` receives an owned unavailable failure; the Host must not +fall through to a real unscoped built-in action. Decline unowned service names +before binding. Completing a reply and then declining likewise cannot execute +fallback work. + +The Host retains the token across its typed delivery queue and checks it on the +GTK thread immediately before applying a success or reporting a failure. An +error callback retains that same token across its additional queue boundary. +This matters when an error is current when received, but the app switches +context before its callback runs. Such a callback must not overwrite the new +page with an obsolete error. The first-terminal-reply rule remains shared +across worker clones, and replies/queues do not retain the Host or GTK widgets. + +Keep `RequestContext::advance`/`close` and UI state application serialized on +that state-owner thread. Retire provider-owned workers/subscriptions and close +the provider's contexts in `Services::stop`. Scoped reply delivery prevents +stale state mutation; it does not itself cancel a network operation or stop +polling. Use scoped process ownership or the backend's explicit cancellation. + +Native private-session regression checks cover queued old success and failure, +shared binding on synchronous provider error, a context switch between failure +and callback delivery, valid current recovery, visible GTK label updates, +rebinding rejection, provider stop and Host release. These are explicit opt-in +reply bindings. They do not automatically scope legacy raw event senders, +legacy feeds, built-in service dispatch, extension negotiation before provider invoke, +streaming chunks, or T3/network adapters. The separate Rust scoped-stream API +below is opt-in; those GTK and app/backend gates remain open. + +## Context-bound feeds + +Providers can override `Services::start_feed_typed` and bind the `FeedReply` +to an app-owned `ContextToken` before starting a subscription. Deliver each +update with `push` on the GTK/state-owner thread; it checks freshness immediately +before applying the update. A bound endpoint cannot be rebound. Keep the +unbound endpoint only for creating explicitly new subscriptions, and retire +old subscriptions and reads when the context changes or the Host closes. +Binding filters stale updates; it does not cancel backend work. Legacy +`start_feed` providers continue to work without automatic context scoping. +The app remains responsible for displaying account/scope identity. + +## Errors and privacy + +`msdk::runtime::ServiceFailure` carries a `FailureKind`, service, source context, +operation ID and optional numeric version information. Categories distinguish +unavailable, incompatible, denied, invalid input, malformed data, I/O, failed +process, timeout, output limit, cancellation and busy conditions. + +`diagnostic()` emits `msdk.runtime.diagnostic.v1`. Its fields contain source +identifiers, numeric identity and a static recovery message. Command arguments, +stdout/stderr, private backend payloads and credentials are excluded. Debug and +Display use the same safe metadata/message policy. `with_detail`/`detail()` are +an explicit private-UI channel; never copy that detail to public logs/receipts. +A registered error callback receives the recoverable UI message; without one, +the Host shows its error banner. The app must provide useful Retry/Cancel states. + +The fixture provider uses this same typed route. A missing reply is an explicit +unavailable error and cannot execute a real fallback. A malformed fixture reply +is rejected. Fixture tracing records the service identifier, not its arguments. + +## Owned process work + +### App-owned request contexts + +`msdk::context::RequestContext` represents one app-owned account/page/selection +lifetime. Create one for the domain whose pending results must expire together. +Keep its owner on the UI/state thread and give workers only a `ContextToken`. +The app still owns and displays the actual account/scope identity; the SDK token +contains no account information or credentials and grants no authority. + +On an account/page/selection change, call `advance()` before issuing replacement +work. It invalidates all old tokens and returns a new token. Returning to a +previous account cannot revive its original token. `close()` permanently retires +the context; it cannot reopen. Dropping the last cloned owner also invalidates +tokens, while tokens and queued replies do not keep that owner alive. + +Use `token.wrap(value)` for asynchronous replies. Forward the resulting +`Scoped` through the app's queue intact, then call `into_current()` on the +state-owner thread immediately before applying. Both old successes and old +errors return None. Checking freshness only on the worker is insufficient: a +previously completed reply may wait in a queue until after the account changes. +Debug omits the private value, without requiring T to implement Debug. + +Context changes and consuming/applying replies must be serialized on the same +state-owner thread. `into_current()` is a freshness snapshot, not a transaction +locking arbitrary app mutations on other threads. Never unwrap a reply on the +worker and enqueue the raw value as if it remained current indefinitely. + +`msdk::process::spawn_scoped(token, command, limits, operation, complete)` binds +completed-output work to that token. It checks freshness before starting and +alongside the runner's normal cancellation/deadline checks. Advancing, closing +or dropping the owning context causes owned task cleanup and leader reaping. +Its callback receives `Scoped>`; forward that +envelope to the state owner for final delivery. This cancels task work; it is +not rollback for effects already performed by a command. + +`spawn_streaming_scoped` combines the same cancellation with a bounded +`ScopedOutputStream`. Its receive methods return `Scoped`; retain each +envelope through any UI queue and call `into_current()` on the state-owner +thread immediately before applying the bytes. Its completion is scoped too. +Dropping the subscription cancels owned work, and the usual queue/output limits +apply. This API does not automatically scope GTK feeds or external subscriptions. + +Core tests cover queued/out-of-order success and error, independent contexts, +return-to-account invalidation, last-owner drop, permanent close, an already +closed request that never executes its command, and actual process cancellation/ +reaping followed by a successful new request. GTK typed ServiceReply supports +the explicit binding described above. App-specific T3/network subscriptions are +not automatically scoped. Their adapters must carry +tokens through final delivery and retire their own reads/resources; full app +context-switch qualification remains open. Do not treat core or synthetic Host +results as that broader lifecycle acceptance. + +The GUI-independent Rust API is `msdk::process::{spawn, Limits}`. Hold the returned +`Process` for the lifetime of the operation. `cancel()` or dropping an unfinished +handle requests cancellation of its dedicated process group. The worker reaps +its leader before completion. Group signals finish before the leader is reaped, +with cancellation serialized, so PID reuse cannot target a later process. + +Implemented on Linux and macOS; unsupported platforms return a typed unavailable +failure. `/bin/sh -c` runs trusted app-authored task commands with null stdin and +nonblocking stdout/stderr pipes. Defaults are: + +| Limit | Behavior | +| --- | --- | +| 120 seconds | Monotonic deadline; timeout stops the owned group | +| 1 MiB combined stdout/stderr | Exceeding the byte budget stops the group | +| 4 concurrent Host jobs | Further calls receive a recoverable busy error | +| Rust `Limits` override | Nonzero timeout/output; output cannot exceed 16 MiB | + +`process.run` uses those defaults and delivers completed stdout to its `then` +message. Nonzero exit is a typed failure with stderr available as private detail. +Timeout/output-limit/cancellation are distinct from success. Inherited pipes do +not keep the worker waiting after the leader exits; same-group descendants are +retired. The Host clears owned handles on disposal. + +This is task-command ownership, not a sandbox or supervisor for privileged, +daemonized, detached-session or OS-wide transactions. Use an explicit OS-owned +service adapter for those lifecycles; do not route a long-running update +transaction through a short task timeout. The declarative `process.run` service +still returns completed output; progress/update UI and the updater reference-app +contract remain unfinished. + +### Rust streaming and partial output + +`msdk::process::spawn_streaming` returns `(Process, OutputStream)`. Retain both +while the operation is wanted. Drain the stream on an app worker (never block a +GTK main loop), forwarding only needed updates to the UI. Dropping either owner +cancels silent or producing work. Cancellation and completion retain the same +process-group cleanup and leader-reaping guarantees as `spawn`. + +Each `Chunk` identifies stdout/stderr and contains raw bytes. Byte order within +each stream is preserved; cross-stream order is unspecified. Chunks may split +lines or UTF-8 sequences: keep a separate decoder/buffer per stream, and choose +an explicit policy for invalid bytes. Chunk Debug shows stream and byte count, +never private content. Raw bytes and the final Output belong in private app UI, +not public diagnostics or receipts. + +The queue holds at most 32 chunks of at most 8192 bytes each (256 KiB), in +addition to the normal bounded final-output buffers. A full queue stops the +command with `process-output-limit`; the worker never waits for a slow consumer. +Already received and queued bytes remain available after timeout, cancellation, +nonzero exit or output-limit failure. Output that exceeded either bound is not +silently accepted. The completion callback is authoritative for terminal status; +stream closure alone does not mean success. The sender closes before completion +is reported, so consumers can then drain queued partial data to disconnection. +The callback runs after process cleanup; keep it short and nonblocking. + +Discovery keeps `process.streaming: false` for the completed-output description +service and reports the separate Rust streaming API/limits in +`process.rust_streaming`. This core capability does not qualify a GTK progress +adapter, stale-context handling or the updater app. Those remain open. + +## Verification + +Core real-process checks cover output/nonzero exit, timeout, combined byte limit, +flood output, inherited pipes, drop cancellation, leader reaping and same-group +child cleanup, invalid limits and invalid command arguments. Diagnostic tests +cover privacy, version mismatch, actual default-limit discovery and explanations. + +The native private-session test uses the actual Host dispatch, worker threads +and GTK state: incompatible provider is not invoked; supported version recovers; +unavailable service, malformed async reply and permission denial enter recovery; +valid typed replies recover; duplicate completion is ignored; missing fixture +reply cannot create a marker through fallback; accepted close kills a real owned +command. Run with a fresh Xvfb/D-Bus session and synthetic XDG state: + +```sh +MSDK_PRIVATE_TEST_BUS=1 XDG_DATA_HOME=/tmp/msdk-runtime-state GSK_RENDERER=cairo \ + xvfb-run -a dbus-run-session -- cargo test --manifest-path SDK/Cargo.toml \ + -p msdk-gtk --test lifecycle --test runtime -- --test-threads=1 +``` + +Use the isolated workspace from `mseries/sdk-tests/prepare.py`. Retain source, +locks, commands, results and failures separately from owner/physical-host +acceptance. These tests do not close the remaining SDK completion gates. diff --git a/mseries/SDK-USAGE-DATA.md b/mseries/SDK-USAGE-DATA.md new file mode 100644 index 000000000..bddf4f17e --- /dev/null +++ b/mseries/SDK-USAGE-DATA.md @@ -0,0 +1,114 @@ +# Usage observation semantics (candidate) + +`msdk::usage` supplies initial Rust data semantics for a future reusable usage +monitor. It does not provide collectors, authentication, a serialization +protocol, a status-area host, or native presentation. Those are still required +before the full status module can be claimed complete. + +`Scope` separates provider, source and optional account. A provider aggregate +has no account; a remote server has its own opaque source identity. Callers +must supply opaque keys rather than credentials or private paths. Debug output +omits those keys, but callers must still keep sensitive data out of their own +logs and UI. + +`Quota` requires explicit used/remaining basis points in 0–10,000 and a source +observation timestamp. Its conversion preserves the distinction between used +and remaining; a reset at or before the current time marks a fresh window +expired. Unknown observations must remain absent rather than being constructed +as zero. `State` distinguishes loading, empty, unknown, fresh, stale, +unavailable, failed, unsupported and expired; the caller owns transitions and +must not present stale or expired data as current. + +`Tokens::total` adds known input and output with overflow checking; missing +components stay unknown. Cached input and reasoning are subsets and are not +added again. `subsets_valid` detects contradictions where a known subset +exceeds its known parent. These helpers do not merge observations, establish +provider coverage, deduplicate overlapping local/server data, or infer source +semantics. Adapters must provide those guarantees from documented contracts. + +The in-memory `Snapshot` includes explicit complete/partial/unknown coverage +and groups observations by distinct scope. `validate()` rejects empty identity +keys, duplicate scopes or window keys, a fresh observation without a source +timestamp, and contradictory known token subsets. A window has its own quota +observation time; it need not equal the containing observation's timestamp. +Validation is explicit: callers must invoke it before presenting a snapshot. +This versioned Rust structure is not a versioned wire protocol and cannot by +itself prove that the collector actually covered all configured accounts. + +Each observation carries a human-readable provider label and, for account +scope, an account label separate from opaque identity keys. `selected` is +presentation context and does not filter other accounts. `Snapshot::groups()` +validates first, then preserves first-seen provider/source and account order; +provider aggregates remain separate from account observations. It does not +merge overlapping sources or implement native widgets. Provider labels must +agree within each provider/source group. Labels may contain private information; +consumers must not log them indiscriminately. + +`msdk_gtk::usage::render` is an initial read-only GTK presentation of a +validated snapshot, grouping provider/source labels, separate account rows and +quota windows. It marks stale and expired observations and does not collect or +refresh data. Callers supply a human-readable source label separately from the +opaque source key. This initial widget has not been visually reviewed against +CodexBar and does not implement status-area placement, popup interactions, +refresh, provider marks, localization, or focus/scroll preservation. It is not +an accepted implementation of the complete status-area specification. + +`msdk_gtk::usage::UsagePanel` is a candidate bounded read-only viewport. Its +`update` builds and validates replacement content before changing the displayed +snapshot, then restores the prior numeric vertical scroll offset after layout, +clamped for shorter content. It does not preserve a semantic row anchor, focus +in interactive children, or provide refresh, subscriptions or host placement. +The caller must apply context freshness and stop its own reads. + +`msdk_gtk::codexbar::decode_snapshot` is a candidate read-only decoder for +CodexBar's version 1 `--snapshot` JSON. It accepts bounded bytes and an explicit +clock/freshness policy, produces provider aggregate observations, and marks +coverage partial because this format alone does not enumerate all accounts. It +requires source timestamps for live values, rejects malformed fields and unknown +schema versions, keeps null quotas unknown, and suppresses source payloads from +decode errors. It neither runs the command nor polls or authenticates. Fresh +read and actual account-specific adapters remain separate work; no real provider +or account qualification is implied by synthetic fixtures. + +`msdk_gtk::codexbar::read_snapshot_scoped` performs one bounded `--snapshot` +request using a caller-supplied trusted absolute executable and literal argv; +it does not use a shell, schedule polling, start a daemon, or manage the existing +collector. Hold the returned process; context expiry cancels owned work. Forward +the scoped result to the state-owner thread and call `into_current` immediately +before applying it. The caller controls retries and must keep freshness current +as time passes. The result carries partial aggregate-only coverage. Diagnostic +errors omit executable paths, output and private payloads. Because the shared +process API decodes output lossily, this adapter conservatively rejects a Unicode +replacement character rather than accepting potentially corrupted JSON. + +`UsagePanel::update_scoped` consumes a `read_snapshot_scoped` reply on the +GTK/state-owner thread. It ignores expired replies after any worker/UI queue. +On a current read failure it retains the last snapshot, marks previously fresh +observations stale, and shows a generic failure notice; a later successful +snapshot replaces that state. This is opt-in: the caller still owns the +process, context transitions, retry policy and lifetime. It does not install a +status host or schedule reads. + +`msdk_gtk::codexbar_monitor::CodexBarMonitor` is an on-demand candidate +controller for a `UsagePanel`. The host opens and closes it explicitly; opening +alone does not read. `refresh` starts at most one bounded request and coalesces +duplicates until the reply reaches the GTK thread. Closing cancels the owned +process, invalidates queued results and marks retained fresh observations stale. +The callback reports idle, refreshing, updated and failed states for a host to +present. Source age is rechecked at final delivery; the controller does not +schedule polling, install status controls, authenticate or enumerate accounts. + +`msdk_gtk::usage_control::UsageControl` wraps the candidate viewport and +on-demand monitor with a refresh button, spinner and status. The host calls +`open` when its popup is shown and `close` when dismissed; opening requests one +snapshot, repeated opens do not duplicate it, and unmapping or dropping the +control cancels owned work. It does not install or select a desktop host, +schedule background polling, manage accounts, or implement provider actions. + +`msdk_gtk::usage_anchor::UsageAnchor` is a candidate GTK anchor for embedding +by a desktop status host. It opens on hover without an intentional focus grab, +pins on activation, and owns a UsageControl and its scoped read lifecycle. +The caller chooses popup position and must place the anchor in the appropriate +profile-owned status area. It does not install a Wingpanel or Windows taskbar +adapter, replace existing controls, or qualify either host. Hover-to-click, +outside dismissal, Escape, keyboard focus and teardown require native testing. diff --git a/mseries/dock-taskbar/TaskbarT3RPopover.vala b/mseries/dock-taskbar/TaskbarT3RPopover.vala index 80e80501f..716b6523b 100644 --- a/mseries/dock-taskbar/TaskbarT3RPopover.vala +++ b/mseries/dock-taskbar/TaskbarT3RPopover.vala @@ -15,6 +15,10 @@ public class Dock.TaskbarT3RPopover : GLib.Object { private Gtk.Stack pages; private Gtk.Box github_page; private Gtk.Box accounts_page; +#if MSDK_STATUS_HOST + private Gtk.Box sdk_usage_page; + private MSeries.SdkUsagePage? sdk_usage; +#endif private MSeries.CodexBarIndicator? accounts_indicator; private MSeries.RepoBarIndicator? repositories_indicator; private string status_path; @@ -69,6 +73,10 @@ public class Dock.TaskbarT3RPopover : GLib.Object { shell.append (pages); accounts_page = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); pages.add_titled (accounts_page, "usage", "Usage"); +#if MSDK_STATUS_HOST + sdk_usage_page = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + pages.add_titled (sdk_usage_page, "sdk-usage", "Plan usage"); +#endif pages.add_titled (root, "server", "T3 server"); github_page = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); pages.add_titled (github_page, "github", "GitHub"); @@ -235,6 +243,9 @@ public class Dock.TaskbarT3RPopover : GLib.Object { stop_freshness_timer (); if (repositories_indicator != null) repositories_indicator.closed (); if (accounts_indicator != null) accounts_indicator.closed (); +#if MSDK_STATUS_HOST + if (sdk_usage != null) sdk_usage.closed (); +#endif }); anchor.unmap.connect (() => { cancel_open (); @@ -271,6 +282,9 @@ public class Dock.TaskbarT3RPopover : GLib.Object { stop_freshness_timer (); if (accounts_indicator != null) accounts_indicator.closed (); if (repositories_indicator != null) repositories_indicator.closed (); +#if MSDK_STATUS_HOST + if (sdk_usage != null) sdk_usage.closed (); +#endif } private bool menu_visible () { return hosted ? host_open : popup.visible; } @@ -305,6 +319,18 @@ public class Dock.TaskbarT3RPopover : GLib.Object { } private void update_repository_page () { +#if MSDK_STATUS_HOST + if (menu_visible () && pages.visible_child_name == "sdk-usage") { + if (sdk_usage == null) { + var executable = GLib.Path.build_filename (Environment.get_home_dir (), ".local", "bin", "codexbar-linux"); + sdk_usage = new MSeries.SdkUsagePage (executable); + sdk_usage_page.append (sdk_usage.get_widget ()); + } + sdk_usage.opened (); + } else if (sdk_usage != null) { + sdk_usage.closed (); + } +#endif if (menu_visible () && pages.visible_child_name == "usage") { if (accounts_indicator == null) { accounts_indicator = new MSeries.CodexBarIndicator (true); @@ -730,6 +756,13 @@ public class Dock.TaskbarT3RPopover : GLib.Object { public override void dispose () { if (status_expiry != 0) { Source.remove (status_expiry); status_expiry = 0; } cancel_timers (); +#if MSDK_STATUS_HOST + if (sdk_usage != null) { + sdk_usage.closed (); + sdk_usage_page.remove (sdk_usage.get_widget ()); + sdk_usage = null; + } +#endif if (accounts_indicator != null) accounts_indicator.closed (); if (repositories_indicator != null) repositories_indicator.closed (); if (app_watch_id != 0) { diff --git a/mseries/dock-taskbar/prepare-source.sh b/mseries/dock-taskbar/prepare-source.sh index 9b94dca3a..2261b0090 100644 --- a/mseries/dock-taskbar/prepare-source.sh +++ b/mseries/dock-taskbar/prepare-source.sh @@ -97,3 +97,29 @@ s = p.read_text() assert s.count('new TaskbarT3RPopover (this, app)') == 1 p.write_text(s.replace('new TaskbarT3RPopover (this, app)', 'new TaskbarT3RPopover (this, ItemManager.get_icon_size () * 7 / 12)')) PYCODE + +# Opt-in SDK status page. Default builds retain the existing status experience. +# The prefix contains include/msdk-usage.h and lib/libmsdk_gtk.so. +if [[ -n ${MSDK_USAGE_PREFIX:-} ]]; then + [[ $MSDK_USAGE_PREFIX = /* && -f $MSDK_USAGE_PREFIX/include/msdk-usage.h && -f $MSDK_USAGE_PREFIX/lib/libmsdk_gtk.so ]] || { + echo 'MSDK_USAGE_PREFIX must be an absolute SDK prefix with its header and library' >&2 + exit 1 + } + cp "$repo/mseries/sdk-status-host/UsagePage.vala" "$source_dir/src/SdkUsagePage.vala" + cp "$repo/mseries/sdk-status-host/msdk-usage.vapi" "$source_dir/src/msdk-usage.vapi" + python3 - "$source_dir/src/meson.build" "$MSDK_USAGE_PREFIX" <<'PYSDK' +from pathlib import Path +import sys +p = Path(sys.argv[1]) +prefix = Path(sys.argv[2]) +s = p.read_text() +marker = 'executable(\n meson.project_name(),' +assert s.count(marker) == 1, 'Dock executable declaration changed' +setup = f"sources += ['SdkUsagePage.vala']\ndependencies += declare_dependency(compile_args: ['-I' + {str(prefix / 'include')!r}], link_args: ['-L' + {str(prefix / 'lib')!r}, '-lmsdk_gtk', '-Wl,-rpath,' + {str(prefix / 'lib')!r}])\n\n" +s = s.replace(marker, setup + marker, 1) +target = ' dependencies: dependencies,\n install: true' +assert s.count(target) == 1, 'Dock executable dependency declaration changed' +s = s.replace(target, " dependencies: dependencies,\n vala_args: ['--define=MSDK_STATUS_HOST', '--vapidir=' + meson.current_source_dir(), '--pkg=msdk-usage'],\n install: true", 1) +p.write_text(s) +PYSDK +fi diff --git a/mseries/sdk-bench/README.md b/mseries/sdk-bench/README.md index f39934241..061734167 100644 --- a/mseries/sdk-bench/README.md +++ b/mseries/sdk-bench/README.md @@ -8,6 +8,9 @@ agent) to produce the "before" column. - [RUBRIC.md](RUBRIC.md): what is recorded per run and how screenshots are judged. - [BASELINE.md](BASELINE.md): what is known about current cost, what is not, and how to measure it. - [specs/](specs/): six one-page app specs, ordered easy to hard. Each names the existing app that is its golden reference. +- [RUNNER.md](RUNNER.md): SDK-mode authoring discovery in a non-root/offline sandbox; + harness preflight is retained, while model admission and independently scored + full-spec/baseline comparisons remain separate gates. Rules: a spec is never edited after a run has been recorded against it (add `-v2` instead); a run records the model, runner, date and commit; failed runs are kept. diff --git a/mseries/sdk-bench/RUNNER.md b/mseries/sdk-bench/RUNNER.md new file mode 100644 index 000000000..64aa07c37 --- /dev/null +++ b/mseries/sdk-bench/RUNNER.md @@ -0,0 +1,69 @@ +# Controlled SDK authoring discovery + +`run-model.py` is an SDK-mode discovery runner for the existing frozen specs. +It is not a completed baseline comparison or a claim that every spec passes. +The first cohort uses s01 unchanged. This validates a representative authoring +flow, not a native port/replacement of an existing product. + +The controller runs on SER8 against its existing local Ollama service. It pins +the installed qwen3.5:4b manifest digest, packaged license, runtime/options, +prompt/spec hashes and source revision. It refuses an occupied model service at +admission; it does not download a model, restart/switch a daemon or use a second +GPU worker. Requests, responses, token counts, timing and every tool result are +retained. Only synthetic/public SDK data enters the model. Lost inference/tool +observations stop dispatch, rather than treating a timeout as proof of stopped +upstream work and retrying blindly. + +Generated Rust executes in a separate ephemeral clone of the SDK test container, +as uid2000 with zero effective/ambient capabilities and only loopback networking. +The configured limits are 4 CPUs, 6GiB RAM, 256 processes and a 16GiB root volume. +There are no owner-data mounts. The SDK and runner remain root-owned/read-only +to that user. Provision trusted dependencies/cache while networked, then remove +the inherited NIC before any model code runs. Preparation, downloads and cache +warmup are outside the model authoring timer and must be reported separately. + +The model can write bounded project source files, read its project/public SDK, +and invoke a fixed command surface. No arbitrary host command tool is exposed. +Builds are offline. The SDK-mode `pack` command packages a built Cargo binary +into the owned evidence directory; it does not install or remove the package. +The `gate` command accepts an optional `gates` path for acceptance scenarios; +without it, only the description's built-in gates are run. +Installation, removal and the remaining acceptance criteria require independent +verification. `worker.py` rejects parent/absolute/hidden paths, writes to +runner evidence/build output, oversized files and unknown commands. Code-level +side effects are contained by the separate unprivileged offline instance, not +by claiming a Rust compiler is a sandbox. Discard the owned instance after the +cohort is retained; never reuse untrusted trial state for a comparison run. + +`capture.py` is a shared external window/capture/Ctrl+Q probe. Handwritten code +does not need a private screenshot flag. The model receives the latest actual +frame for iterative feedback; independent review still judges the result. The +probe returns failure if Ctrl+Q does not close the captured application cleanly. +Mapped/captured timestamps are candidate first-window evidence. Do not report +them as a real-content first window until the image is reviewed. A `done` +action merely submits a candidate: `t_done` stays not reached until every frozen +spec acceptance and every rubric done-bar item is independently verified. + +Keep all failures, repairs, escapes to app-local Rust, vocabulary gaps and +interventions. Baseline and repeated-cohort comparisons remain open; the +worker's baseline tool restriction is preparation, not a qualified baseline +runner. Never compare an SDK discovery run with a differently provisioned or +unmeasured native run and call the speed difference a result. + +Before inference, exercise the fixed settings smoke through new/gen/build/ +pack/launch, verify native suites at the benchmark UID, archive that preflight, then +reset only its owned project/state directories. `run-model.py` requires an empty +project and refuses to overwrite an output directory. Example on the controlling +host after provisioning and verification: + +```sh +python3 run-model.py --container msdk-bench-20261026 \ + --spec specs/s01-quick-notes.md --source-commit VERIFIED_COMMIT \ + --output /tmp/msdk-authoring-s01-FIRST_UNIQUE_RUN +``` + +Retain the exact source/seed lock/environment with the run. The controller stops +at the 120-minute wall cap or its declared turn budget. A turn-budget stop is +not evidence the model failed the whole 120-minute task. Resume only after the +specific prior process/request is authoritatively terminal; this first runner +does not implement automatic interrupted-run resumption. diff --git a/mseries/sdk-bench/capture.py b/mseries/sdk-bench/capture.py new file mode 100644 index 000000000..4010fb408 --- /dev/null +++ b/mseries/sdk-bench/capture.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +"""Same external screenshot/quit probe for SDK and handwritten baseline apps.""" +import json +import os +from pathlib import Path +import subprocess +import sys +import time + +assert os.environ.get('DISPLAY') and os.environ.get('DBUS_SESSION_BUS_ADDRESS') +binary, screenshot = sys.argv[1:] +started = time.monotonic() +process = subprocess.Popen([binary]) +try: + window = None + deadline = started + 10 + while time.monotonic() < deadline: + result = subprocess.run(['xdotool', 'search', '--onlyvisible', '--pid', str(process.pid)], capture_output=True, text=True) + if result.returncode == 0 and result.stdout.strip(): + window = result.stdout.splitlines()[0] + break + if process.poll() is not None: + break + time.sleep(.04) + if window is None: + raise RuntimeError('no mapped app window within 10 seconds') + mapped = time.monotonic() - started + subprocess.run(['xdotool', 'windowsize', '--sync', window, '900', '600'], check=True) + time.sleep(.5) + subprocess.run(['import', '-window', window, screenshot], check=True, timeout=5) + captured = time.monotonic() - started + subprocess.run(['xdotool', 'windowfocus', '--sync', window], check=True) + subprocess.run(['xdotool', 'key', '--clearmodifiers', 'ctrl+q'], check=True) + try: + process.wait(timeout=3) + clean = process.returncode == 0 + except subprocess.TimeoutExpired: + clean = False + print(json.dumps({'mapped_seconds': mapped, 'captured_seconds': captured, + 'frame_bytes': Path(screenshot).stat().st_size, + 'ctrl_q_clean': clean, 'content_review': 'pending independent review'})) + if not clean: + raise SystemExit(1) +finally: + if process.poll() is None: + process.kill() + process.wait() diff --git a/mseries/sdk-bench/fixtures/noquit.py b/mseries/sdk-bench/fixtures/noquit.py new file mode 100755 index 000000000..ccca400ec --- /dev/null +++ b/mseries/sdk-bench/fixtures/noquit.py @@ -0,0 +1,11 @@ +#!/usr/bin/python3 +import gi +gi.require_version("Gtk", "4.0") +from gi.repository import Gtk +app = Gtk.Application(application_id="io.github.techmore.BenchNoQuit") +def activate(instance): + window = Gtk.ApplicationWindow(application=instance, title="No quit fixture") + window.set_child(Gtk.Label(label="Ctrl+Q intentionally unsupported")) + window.present() +app.connect("activate", activate) +raise SystemExit(app.run([])) diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/README.md b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/README.md new file mode 100644 index 000000000..3d43cb061 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/README.md @@ -0,0 +1,14 @@ +# Packaging and quit preflight — 2026-10-26 + +Harness source commit: `019aee19d70841806f46b66da0a40c0b649bf073`. +The SDK-mode fixed tool surface ran list, new, gen, offline build, pack and +launch successfully as uid 2000 in the isolated loopback-only Incus sandbox. +The generated package metadata and SHA-256 are recorded; the binary package is +not included. No package installation or removal was performed in this test. +The positive capture reported a clean Ctrl+Q. A separate trusted GTK fixture +that ignores Ctrl+Q was captured and the probe returned nonzero, with +`ctrl_q_clean: false`. Frame content remained pending independent review. + +The source and frames are synthetic. The project's owned scratch and state +were cleared after retaining these artifacts. This preflight is not a model +trial, a baseline comparison, or acceptance of the frozen specification. diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/evidence/frame-1793042942689657549.png b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/evidence/frame-1793042942689657549.png new file mode 100644 index 000000000..64c9a6f17 Binary files /dev/null and b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/evidence/frame-1793042942689657549.png differ diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/evidence/noquit.png b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/evidence/noquit.png new file mode 100644 index 000000000..3c233c4ef Binary files /dev/null and b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/evidence/noquit.png differ diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/Cargo.lock b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/Cargo.lock new file mode 100644 index 000000000..9d95f8e3e --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/Cargo.lock @@ -0,0 +1,746 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e055fa6e3e40ad6187ba25b6855eeb635d5271f8e0f0e1e9a5826b8d75bea0" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "msdk-packsmoke" +version = "0.1.0" +dependencies = [ + "gtk4", + "msdk", + "msdk-gtk", + "serde", + "serde_json", +] + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db551ad38aac61d5e0343e0eeeb0163be3115c4e23b6a025959570ee0c03c67d" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/Cargo.toml b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/Cargo.toml new file mode 100644 index 000000000..c3959072c --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "msdk-packsmoke" +version = "0.1.0" +license = "GPL-3.0-only" +edition = "2024" +publish = false + +[workspace] + +[lib] +name = "app_model" + +[dependencies] +msdk = { path = "/work/sdk/msdk" } +msdk-gtk = { path = "/work/sdk/msdk-gtk" } +gtk = { package = "gtk4", version = "0.11", features = ["v4_20"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/LICENSE b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/LICENSE new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/README.md b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/README.md new file mode 100644 index 000000000..f6f82bab3 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/README.md @@ -0,0 +1,25 @@ +# pack smoke + +Generated by `msdk gen`; SDK format 1. + +On a supported Linux GTK 4.20+ development host, with Rust 2024, pkg-config, +GTK development headers, Wayland development headers and wayland-scanner installed: + +```sh +cargo build +cargo test +cargo run +``` + +`src/lib.rs` exposes typed records, `State`, `Message::into_event` and the embedded +description. Edit `app.ui.json` for views/rules, or use a new output directory to +regenerate models after changing types. Keep the SDK checkout at `/work/sdk`; +the generated project uses explicit local dependencies and its own Cargo workspace. + +The executable runs the real GTK Host with the description's update rules and +built-in services. Custom services/feeds require an app-local `Services` adapter +and `Host::open_with`; generation does not implement those backends. Panel +placement requires the documented Pantheon shell protocol and target-host tests. +Build/launch success is separate from visual, accessibility, service, packaging +and installed desktop acceptance. No install or background service is performed +by generation. diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/app.ui.json b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/app.ui.json new file mode 100644 index 000000000..f77e7ff2a --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/app.ui.json @@ -0,0 +1,109 @@ +{ + "sdk": 1, + "app": { + "id": "io.github.techmore.PackSmoke", + "name": "pack smoke", + "icon": "preferences-system" + }, + "capabilities": [ + "filesystem:data" + ], + "state": { + "enabled": "bool", + "schedule": "text", + "show_hint": "bool" + }, + "initial": { + "enabled": true, + "schedule": "Weekdays", + "show_hint": false + }, + "persist": [ + "enabled", + "schedule" + ], + "messages": { + "SetEnabled": "bool", + "SetSchedule": "text", + "Reset": "none" + }, + "update": { + "SetEnabled": [ + { + "set": "enabled", + "to": "$payload" + }, + { + "toast": "Saved" + } + ], + "SetSchedule": [ + { + "set": "schedule", + "to": "$payload" + }, + { + "toast": "Saved" + } + ], + "Reset": [ + { + "set": "enabled", + "to": true + }, + { + "set": "schedule", + "to": "Weekdays" + }, + { + "toast": "Settings reset" + } + ] + }, + "surfaces": { + "main": { + "kind": "window", + "title": "pack smoke", + "body": { + "type": "Box", + "direction": "column", + "spacing": "large", + "children": [ + { + "type": "Text", + "text": "Work mode", + "text_style": "title" + }, + { + "type": "Card", + "children": [ + { + "type": "Switch", + "label": "Turn on work mode", + "bind": "enabled", + "on_change": "SetEnabled" + }, + { + "type": "Dropdown", + "label": "Schedule", + "bind": "schedule", + "options": [ + "Weekdays", + "Every day", + "Manual" + ], + "on_change": "SetSchedule" + } + ] + }, + { + "type": "Button", + "label": "Reset to defaults", + "on": "Reset", + "button_style": "flat" + } + ] + } + } + } +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/assets/icon.svg b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/assets/icon.svg new file mode 100644 index 000000000..964e6a0ca --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/assets/icon.svg @@ -0,0 +1 @@ + diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/src/lib.rs b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/src/lib.rs new file mode 100644 index 000000000..12497279b --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/src/lib.rs @@ -0,0 +1,50 @@ +// Generated by msdk gen. Edit the description and regenerate in a new directory. +#![allow(non_snake_case, non_camel_case_types)] +pub mod records { +} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct State { + #[serde(rename = "enabled")] + pub r#enabled: bool, + #[serde(rename = "schedule")] + pub r#schedule: String, + #[serde(rename = "show_hint")] + pub r#show_hint: bool, +} +impl State { + pub fn initial() -> Result { + Self::from_store(msdk::logic::initial_store(&document())) + } + pub fn from_store(store: msdk::logic::Store) -> Result { + serde_json::from_value(serde_json::Value::Object(store)) + } + pub fn into_store(self) -> Result { + match serde_json::to_value(self)? { + serde_json::Value::Object(store) => Ok(store), + _ => unreachable!("State serializes as an object"), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub enum Message { + r#SetEnabled(bool), + r#SetSchedule(String), + r#Reset, +} +impl Message { + pub fn into_event(self) -> (String, Option) { + match self { + Self::r#SetEnabled(value) => ("SetEnabled".into(), Some(serde_json::json!(value))), + Self::r#SetSchedule(value) => ("SetSchedule".into(), Some(serde_json::json!(value))), + Self::r#Reset => ("Reset".into(), None), + } + } +} + +/// The checked description embedded in this application. +pub fn document() -> serde_json::Value { + static REGISTER: std::sync::OnceLock<()> = std::sync::OnceLock::new(); + REGISTER.get_or_init(|| { + }); + serde_json::from_str(include_str!("../app.ui.json")).expect("generated checked description") +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/src/main.rs b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/src/main.rs new file mode 100644 index 000000000..7e0addc2d --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/src/main.rs @@ -0,0 +1,60 @@ +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +use gtk::prelude::*; + +fn main() -> gtk::glib::ExitCode { + // Screenshot mode is an explicit developer check. Normal activation keeps + // the stable app ID and presents the existing window. + let args: Vec<_> = std::env::args().skip(1).collect(); + let shot = match args.as_slice() { + [] => None, + [flag, path] if flag == "--screenshot" => Some(std::path::PathBuf::from(path)), + _ => { + eprintln!("usage: application [--screenshot output.png]"); + return gtk::glib::ExitCode::from(2); + } + }; + let app = gtk::Application::builder() + .application_id("io.github.techmore.PackSmoke") + .build(); + let quit = gtk::gio::SimpleAction::new("quit", None); + let weak = app.downgrade(); + quit.connect_activate(move |_, _| { + if let Some(app) = weak.upgrade() { + for window in app.windows() { window.close(); } + } + }); + app.add_action(&quit); + app.set_accels_for_action("app.quit", &["q"]); + let keep = RefCell::new(None::>); + let failed = Rc::new(Cell::new(false)); + let failure = failed.clone(); + app.connect_activate(move |app| { + if let Some(host) = keep.borrow().as_ref() { + host.window().present(); + return; + } + let Some(host) = msdk_gtk::host::Host::open_doc( + app, app_model::document(), None, "main", None, false, + ) else { + failure.set(true); + app.quit(); + return; + }; + if let Some(path) = shot.clone() { + let (host, app, failure) = (host.clone(), app.clone(), failure.clone()); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(800), move || { + if let Err(error) = host.screenshot(&path) { + eprintln!("screenshot failed: {error}"); + failure.set(true); + } + host.window().close(); + app.quit(); + }); + } + *keep.borrow_mut() = Some(host); + }); + let status = app.run_with_args::<&str>(&[]); + if failed.get() { gtk::glib::ExitCode::FAILURE } else { status } +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/tests/model.rs b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/tests/model.rs new file mode 100644 index 000000000..716fbaff6 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-generated/tests/model.rs @@ -0,0 +1,6 @@ +#[test] +fn initial_state_round_trips() { + let state = app_model::State::initial().expect("typed initial state"); + let store = state.clone().into_store().unwrap(); + assert_eq!(app_model::State::from_store(store).unwrap(), state); +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/README.md b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/README.md new file mode 100644 index 000000000..009d37460 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/README.md @@ -0,0 +1,12 @@ +# pack smoke + +Started from the `settings` template (A settings page: a switch, a dropdown, saved values, reset to defaults.) + +```bash +msdk check app.ui.json # structure, types, HIG rules +msdk gate app.ui.json app.gates.json # acceptance scenarios +msdk-run app.ui.json --watch # live window; edit the file and it re-renders +msdk describe # what you can use; msdk complete / explain for help +``` + +Change the state, messages, `update` rules and surfaces in `app.ui.json`; add a scenario to `app.gates.json` for every behaviour you add. diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/app.gates.json b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/app.gates.json new file mode 100644 index 000000000..76e32282b --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/app.gates.json @@ -0,0 +1,6 @@ +{ "gates": [ + { "name": "starts with the defaults", "steps": [], "expect": [{ "state": "enabled", "equals": true }, { "state": "schedule", "equals": "Weekdays" }] }, + { "name": "switching off is remembered and confirmed", "steps": [{ "send": "SetEnabled", "payload": false }], "expect": [{ "state": "enabled", "equals": false }, { "toast": "Saved" }] }, + { "name": "choosing a schedule stores it", "steps": [{ "send": "SetSchedule", "payload": "Manual" }], "expect": [{ "state": "schedule", "equals": "Manual" }] }, + { "name": "reset restores the defaults", "steps": [{ "send": "SetEnabled", "payload": false }, { "send": "Reset" }], "expect": [{ "state": "enabled", "equals": true }, { "toast": "Settings reset" }] } +] } diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/app.ui.json b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/app.ui.json new file mode 100644 index 000000000..b02e7ef4a --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/bench-app/pack-smoke/app.ui.json @@ -0,0 +1,31 @@ +{ + "sdk": 1, + "app": { "id": "io.github.techmore.PackSmoke", "name": "pack smoke", "icon": "preferences-system" }, + "capabilities": ["filesystem:data"], + "state": { "enabled": "bool", "schedule": "text", "show_hint": "bool" }, + "initial": { "enabled": true, "schedule": "Weekdays", "show_hint": false }, + "persist": ["enabled", "schedule"], + "messages": { "SetEnabled": "bool", "SetSchedule": "text", "Reset": "none" }, + "update": { + "SetEnabled": [{ "set": "enabled", "to": "$payload" }, { "toast": "Saved" }], + "SetSchedule": [{ "set": "schedule", "to": "$payload" }, { "toast": "Saved" }], + "Reset": [{ "set": "enabled", "to": true }, { "set": "schedule", "to": "Weekdays" }, { "toast": "Settings reset" }] + }, + "surfaces": { + "main": { + "kind": "window", + "title": "pack smoke", + "body": { + "type": "Box", "direction": "column", "spacing": "large", + "children": [ + { "type": "Text", "text": "Work mode", "text_style": "title" }, + { "type": "Card", "children": [ + { "type": "Switch", "label": "Turn on work mode", "bind": "enabled", "on_change": "SetEnabled" }, + { "type": "Dropdown", "label": "Schedule", "bind": "schedule", "options": ["Weekdays", "Every day", "Manual"], "on_change": "SetSchedule" } + ] }, + { "type": "Button", "label": "Reset to defaults", "on": "Reset", "button_style": "flat" } + ] + } + } + } +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/harness-sha256.txt b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/harness-sha256.txt new file mode 100644 index 000000000..996778662 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/harness-sha256.txt @@ -0,0 +1,4 @@ +86762f3b3477d2fff1d29fd8a1aab86db2948e0cbd50acfd45903ffa307101ca mseries/sdk-bench/worker.py +76ae4ab8fb952842164e5dc09ff42b4dbfd236079953d8643b08ec1fd92d8a59 mseries/sdk-bench/capture.py +364bdc7deb918a90d51ffcd4ad52a50850ef7b74e00cd23d64e4371e82903751 mseries/sdk-bench/run-model.py +ee8256dc20a3c9491f030904a6d9cab58f70e26fb932b814084098846d25d808 mseries/sdk-bench/fixtures/noquit.py diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-noquit-output.txt b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-noquit-output.txt new file mode 100644 index 000000000..f3a503cd1 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-noquit-output.txt @@ -0,0 +1,8 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[4852]: [session uid=2000 pid=4852 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=2000 pid=4854 comm="/usr/bin/python3 /opt/msdk-bench/noquit.py" label="unconfined") +dbus-daemon[4852]: [session uid=2000 pid=4852 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[4893]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=2000 pid=4854 comm="/usr/bin/python3 /opt/msdk-bench/noquit.py" label="unconfined") +dbus-daemon[4893]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{"mapped_seconds": 0.26584711589384824, "captured_seconds": 0.8346980599453673, "frame_bytes": 2773, "ctrl_q_clean": false, "content_review": "pending independent review"} diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-info.txt b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-info.txt new file mode 100644 index 000000000..a97dd06ff --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-info.txt @@ -0,0 +1,9 @@ + new Debian package, version 2.0. + size 1111628 bytes: control archive=386 bytes. + 463 bytes, 6 lines control + Package: msdk-io.github.techmore.packsmoke + Version: 0.1.0 + Architecture: amd64 + Maintainer: SDK app developer + Description: Application built with the M-series SDK + Depends: libc6 (>= 2.39), libcairo-gobject2 (>= 1.10.0), libcairo2 (>= 1.2.4), libgcc-s1 (>= 4.2), libgdk-pixbuf-2.0-0 (>= 2.22.0), libglib2.0-0t64 (>= 2.54.0), libgraphene-1.0-0 (>= 1.5.4), libgtk-4-1 (>= 4.12.0), libpango-1.0-0 (>= 1.14.0), libwayland-client0 (>= 1.20.0) diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-preflight.json b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-preflight.json new file mode 100644 index 000000000..53aff2cb3 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-preflight.json @@ -0,0 +1,137 @@ +[ + { + "action": { + "action": "list" + }, + "response": { + "ok": true, + "result": { + "files": [] + } + } + }, + { + "action": { + "action": "run", + "command": "new", + "template": "settings", + "path": "pack-smoke" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 0.02263030398171395, + "output": "created /work/bench-app/pack-smoke from `settings` (id io.github.techmore.PackSmoke); next: cd /work/bench-app/pack-smoke && msdk check app.ui.json && msdk gate app.ui.json app.gates.json\n", + "argv": [ + "/work/target/debug/msdk", + "new", + "settings", + "/work/bench-app/pack-smoke" + ] + } + } + }, + { + "action": { + "action": "run", + "command": "gen", + "path": "pack-smoke/app.ui.json", + "output": "pack-generated" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 0.02093451702967286, + "output": "created standalone Cargo application in /work/bench-app/pack-generated; next: cargo run --manifest-path /work/bench-app/pack-generated/Cargo.toml\n", + "argv": [ + "/work/target/debug/msdk", + "gen", + "/work/bench-app/pack-smoke/app.ui.json", + "/work/bench-app/pack-generated", + "--sdk-root", + "/work/sdk" + ] + } + } + }, + { + "action": { + "action": "run", + "command": "build", + "project": "pack-generated" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 4.000191212049685, + "output": " Locking 74 packages to latest Rust 1.93.1 compatible versions\n Compiling msdk-packsmoke v0.1.0 (/work/bench-app/pack-generated)\n Finished `dev` profile [unoptimized] target(s) in 3.93s\n", + "argv": [ + "/usr/bin/cargo", + "build", + "--manifest-path", + "/work/bench-app/pack-generated/Cargo.toml", + "--offline" + ] + } + } + }, + { + "action": { + "action": "run", + "command": "pack", + "project": "pack-generated" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 2.2099140870850533, + "output": "created /work/bench-app/evidence/package-1793042940367896262.deb; no installation performed\n", + "argv": [ + "/work/target/debug/msdk", + "pack", + "/work/bench-app/pack-generated", + "--binary", + "/work/bench-target/debug/msdk-packsmoke", + "--output", + "/work/bench-app/evidence/package-1793042940367896262.deb" + ], + "package": "evidence/package-1793042940367896262.deb" + } + } + }, + { + "action": { + "action": "run", + "command": "launch", + "project": "pack-generated" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 0.9050211129942909, + "output": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\ndbus-daemon[4788]: [session uid=2000 pid=4788 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.0' (uid=2000 pid=4790 comm=\"/work/bench-target/debug/msdk-packsmoke\" label=\"unconfined\")\ndbus-daemon[4788]: [session uid=2000 pid=4788 pidfd=5] Successfully activated service 'org.a11y.Bus'\ndbus-daemon[4818]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=2000 pid=4790 comm=\"/work/bench-target/debug/msdk-packsmoke\" label=\"unconfined\")\ndbus-daemon[4818]: Successfully activated service 'org.a11y.atspi.Registry'\nSpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry\n{\"mapped_seconds\": 0.17475895897950977, \"captured_seconds\": 0.746610144036822, \"frame_bytes\": 21452, \"ctrl_q_clean\": true, \"content_review\": \"pending independent review\"}\n", + "argv": [ + "xvfb-run", + "-a", + "dbus-run-session", + "--", + "/usr/bin/python3", + "/opt/msdk-bench/capture.py", + "/work/bench-target/debug/msdk-packsmoke", + "/work/bench-app/evidence/frame-1793042942689657549.png" + ], + "frame": "evidence/frame-1793042942689657549.png" + } + } + } +] \ No newline at end of file diff --git a/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-sha256.txt b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-sha256.txt new file mode 100644 index 000000000..a535b6f96 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-pack-preflight/msdk-bench-pack-sha256.txt @@ -0,0 +1 @@ +93b2e5200d831228d723c05513141fe940711e4af6cf5dbd1d4bb942e15b66ac /work/bench-app/evidence/package-1793042940367896262.deb diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/admission.json b/mseries/sdk-bench/receipts/2026-10-26-preflight/admission.json new file mode 100644 index 000000000..c6a7617da --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/admission.json @@ -0,0 +1,15 @@ +{ + "result": "deferred-before-inference", + "inference_started": false, + "reason": "conservative admission refuses an already resident model; loaded does not prove active inference", + "resident_models": [ + { + "name": "qwen3.5:2b", + "digest": "0689d44085e06d165161a8a9a1731344278cfb5aade63a3c3dbdb48ab54b130a", + "expires_at": "2026-10-26T15:17:45.380294215-04:00", + "context_length": 4096, + "size": 2336961329, + "size_vram": 2336961329 + } + ] +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/dependency-prewarm-output.txt b/mseries/sdk-bench/receipts/2026-10-26-preflight/dependency-prewarm-output.txt new file mode 100644 index 000000000..7083ef1d2 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/dependency-prewarm-output.txt @@ -0,0 +1,85 @@ + Compiling pkg-config v0.3.34 + Compiling winnow v1.0.4 + Compiling toml_datetime v1.1.2+spec-1.1.0 + Compiling target-lexicon v0.13.5 + Compiling toml_parser v1.1.5+spec-1.1.0 + Compiling serde_spanned v1.1.2 + Compiling system-deps v9.0.0 + Compiling smallvec v1.16.3 + Compiling heck v0.5.0 + Compiling toml v1.1.8+spec-1.1.0 + Compiling cfg-expr v0.20.10 + Compiling version-compare v0.2.1 + Compiling libc v0.2.191 + Compiling glib-sys v0.22.9 + Compiling proc-macro2 v1.0.107 + Compiling quote v1.0.47 + Compiling unicode-ident v1.0.27 + Compiling gobject-sys v0.22.9 + Compiling syn v3.0.9 + Compiling gio-sys v0.22.9 + Compiling futures-core v0.3.34 + Compiling slab v0.4.12 + Compiling pin-project-lite v0.2.17 + Compiling memchr v2.8.3 + Compiling futures-task v0.3.34 + Compiling bitflags v2.13.2 + Compiling futures-channel v0.3.34 + Compiling pango-sys v0.22.9 + Compiling futures-macro v0.3.34 + Compiling glib-macros v0.22.9 + Compiling futures-util v0.3.34 + Compiling futures-executor v0.3.34 + Compiling cairo-sys-rs v0.22.9 + Compiling gdk-pixbuf-sys v0.22.9 + Compiling glib v0.22.10 + Compiling equivalent v1.0.3 + Compiling hashbrown v0.17.1 + Compiling graphene-sys v0.22.9 + Compiling gdk4-sys v0.11.5 + Compiling futures-io v0.3.34 + Compiling gsk4-sys v0.11.5 + Compiling semver v1.0.28 + Compiling version_check v0.9.5 + Compiling serde_core v1.0.229 + Compiling autocfg v1.5.1 + Compiling zerocopy v0.8.63 + Compiling memoffset v0.9.1 + Compiling ahash v0.8.12 + Compiling rustc_version v0.4.1 + Compiling indexmap v2.14.2 + Compiling zmij v1.0.23 + Compiling toml_edit v0.25.17+spec-1.1.0 + Compiling field-offset v0.3.6 + Compiling gio v0.22.10 + Compiling cairo-rs v0.22.9 + Compiling gtk4-sys v0.11.5 + Compiling once_cell v1.21.4 + Compiling find-msvc-tools v0.1.15 + Compiling serde_json v1.0.154 + Compiling shlex v2.0.1 + Compiling vcpkg v0.2.15 + Compiling cfg-if v1.0.5 + Compiling libsqlite3-sys v0.30.1 + Compiling cc v1.9.0 + Compiling graphene-rs v0.22.8 + Compiling proc-macro-crate v3.5.0 + Compiling pango v0.22.9 + Compiling gdk-pixbuf v0.22.0 + Compiling gdk4 v0.11.5 + Compiling itoa v1.0.18 + Compiling foldhash v0.2.0 + Compiling gtk4-macros v0.11.5 + Compiling gsk4 v0.11.5 + Compiling msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Compiling hashbrown v0.14.5 + Compiling serde v1.0.229 + Compiling hashlink v0.9.1 + Compiling gtk4 v0.11.5 + Compiling msdk v0.1.0 (/work/sdk/msdk) + Compiling serde_derive v1.0.229 + Compiling fallible-iterator v0.3.0 + Compiling fallible-streaming-iterator v0.1.9 + Compiling rusqlite v0.32.1 + Compiling msdk-bench-dependency-seed v0.0.0 (/work/bench-seed) + Finished `dev` profile [unoptimized] target(s) in 1m 16s diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/dependency-provisioning-output.txt b/mseries/sdk-bench/receipts/2026-10-26-preflight/dependency-provisioning-output.txt new file mode 100644 index 000000000..c0c318619 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/dependency-provisioning-output.txt @@ -0,0 +1,33 @@ + Updating crates.io index + Locking 14 packages to latest Rust 1.93.1 compatible versions + Adding ahash v0.8.12 + Adding cfg-if v1.0.5 + Adding fallible-iterator v0.3.0 + Adding fallible-streaming-iterator v0.1.9 + Adding hashbrown v0.14.5 + Adding hashlink v0.9.1 + Adding libsqlite3-sys v0.30.1 + Adding once_cell v1.21.4 + Adding rusqlite v0.32.1 (available: v0.41.0) + Adding syn v2.0.119 + Adding vcpkg v0.2.15 + Adding version_check v0.9.5 + Adding zerocopy v0.8.63 + Adding zerocopy-derive v0.8.63 + Downloading crates ... + Downloaded fallible-streaming-iterator v0.1.9 + Downloaded hashlink v0.9.1 + Downloaded windows-link v0.2.1 + Downloaded once_cell v1.21.4 + Downloaded version_check v0.9.5 + Downloaded cfg-if v1.0.5 + Downloaded vcpkg v0.2.15 + Downloaded ahash v0.8.12 + Downloaded fallible-iterator v0.3.0 + Downloaded rusqlite v0.32.1 + Downloaded zerocopy-derive v0.8.63 + Downloaded hashbrown v0.14.5 + Downloaded syn v2.0.119 + Downloaded zerocopy v0.8.63 + Downloaded windows-sys v0.61.2 + Downloaded libsqlite3-sys v0.30.1 diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/Cargo.lock b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/Cargo.lock new file mode 100644 index 000000000..bc1e6f012 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/Cargo.lock @@ -0,0 +1,746 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e055fa6e3e40ad6187ba25b6855eeb635d5271f8e0f0e1e9a5826b8d75bea0" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "msdk-preflight" +version = "0.1.0" +dependencies = [ + "gtk4", + "msdk", + "msdk-gtk", + "serde", + "serde_json", +] + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db551ad38aac61d5e0343e0eeeb0163be3115c4e23b6a025959570ee0c03c67d" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/Cargo.toml b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/Cargo.toml new file mode 100644 index 000000000..ff1541c21 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "msdk-preflight" +version = "0.1.0" +license = "GPL-3.0-only" +edition = "2024" +publish = false + +[workspace] + +[lib] +name = "app_model" + +[dependencies] +msdk = { path = "/work/sdk/msdk" } +msdk-gtk = { path = "/work/sdk/msdk-gtk" } +gtk = { package = "gtk4", version = "0.11", features = ["v4_20"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/LICENSE b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/LICENSE new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/README.md b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/README.md new file mode 100644 index 000000000..ecfc66d5c --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/README.md @@ -0,0 +1,25 @@ +# preflight + +Generated by `msdk gen`; SDK format 1. + +On a supported Linux GTK 4.20+ development host, with Rust 2024, pkg-config, +GTK development headers, Wayland development headers and wayland-scanner installed: + +```sh +cargo build +cargo test +cargo run +``` + +`src/lib.rs` exposes typed records, `State`, `Message::into_event` and the embedded +description. Edit `app.ui.json` for views/rules, or use a new output directory to +regenerate models after changing types. Keep the SDK checkout at `/work/sdk`; +the generated project uses explicit local dependencies and its own Cargo workspace. + +The executable runs the real GTK Host with the description's update rules and +built-in services. Custom services/feeds require an app-local `Services` adapter +and `Host::open_with`; generation does not implement those backends. Panel +placement requires the documented Pantheon shell protocol and target-host tests. +Build/launch success is separate from visual, accessibility, service, packaging +and installed desktop acceptance. No install or background service is performed +by generation. diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/app.ui.json b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/app.ui.json new file mode 100644 index 000000000..55eb1bc74 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/app.ui.json @@ -0,0 +1,109 @@ +{ + "sdk": 1, + "app": { + "id": "io.github.techmore.Preflight", + "name": "preflight", + "icon": "preferences-system" + }, + "capabilities": [ + "filesystem:data" + ], + "state": { + "enabled": "bool", + "schedule": "text", + "show_hint": "bool" + }, + "initial": { + "enabled": true, + "schedule": "Weekdays", + "show_hint": false + }, + "persist": [ + "enabled", + "schedule" + ], + "messages": { + "SetEnabled": "bool", + "SetSchedule": "text", + "Reset": "none" + }, + "update": { + "SetEnabled": [ + { + "set": "enabled", + "to": "$payload" + }, + { + "toast": "Saved" + } + ], + "SetSchedule": [ + { + "set": "schedule", + "to": "$payload" + }, + { + "toast": "Saved" + } + ], + "Reset": [ + { + "set": "enabled", + "to": true + }, + { + "set": "schedule", + "to": "Weekdays" + }, + { + "toast": "Settings reset" + } + ] + }, + "surfaces": { + "main": { + "kind": "window", + "title": "preflight", + "body": { + "type": "Box", + "direction": "column", + "spacing": "large", + "children": [ + { + "type": "Text", + "text": "Work mode", + "text_style": "title" + }, + { + "type": "Card", + "children": [ + { + "type": "Switch", + "label": "Turn on work mode", + "bind": "enabled", + "on_change": "SetEnabled" + }, + { + "type": "Dropdown", + "label": "Schedule", + "bind": "schedule", + "options": [ + "Weekdays", + "Every day", + "Manual" + ], + "on_change": "SetSchedule" + } + ] + }, + { + "type": "Button", + "label": "Reset to defaults", + "on": "Reset", + "button_style": "flat" + } + ] + } + } + } +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/assets/icon.svg b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/assets/icon.svg new file mode 100644 index 000000000..964e6a0ca --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/assets/icon.svg @@ -0,0 +1 @@ + diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/src/lib.rs b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/src/lib.rs new file mode 100644 index 000000000..12497279b --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/src/lib.rs @@ -0,0 +1,50 @@ +// Generated by msdk gen. Edit the description and regenerate in a new directory. +#![allow(non_snake_case, non_camel_case_types)] +pub mod records { +} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct State { + #[serde(rename = "enabled")] + pub r#enabled: bool, + #[serde(rename = "schedule")] + pub r#schedule: String, + #[serde(rename = "show_hint")] + pub r#show_hint: bool, +} +impl State { + pub fn initial() -> Result { + Self::from_store(msdk::logic::initial_store(&document())) + } + pub fn from_store(store: msdk::logic::Store) -> Result { + serde_json::from_value(serde_json::Value::Object(store)) + } + pub fn into_store(self) -> Result { + match serde_json::to_value(self)? { + serde_json::Value::Object(store) => Ok(store), + _ => unreachable!("State serializes as an object"), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub enum Message { + r#SetEnabled(bool), + r#SetSchedule(String), + r#Reset, +} +impl Message { + pub fn into_event(self) -> (String, Option) { + match self { + Self::r#SetEnabled(value) => ("SetEnabled".into(), Some(serde_json::json!(value))), + Self::r#SetSchedule(value) => ("SetSchedule".into(), Some(serde_json::json!(value))), + Self::r#Reset => ("Reset".into(), None), + } + } +} + +/// The checked description embedded in this application. +pub fn document() -> serde_json::Value { + static REGISTER: std::sync::OnceLock<()> = std::sync::OnceLock::new(); + REGISTER.get_or_init(|| { + }); + serde_json::from_str(include_str!("../app.ui.json")).expect("generated checked description") +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/src/main.rs b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/src/main.rs new file mode 100644 index 000000000..6b296d654 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/src/main.rs @@ -0,0 +1,60 @@ +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +use gtk::prelude::*; + +fn main() -> gtk::glib::ExitCode { + // Screenshot mode is an explicit developer check. Normal activation keeps + // the stable app ID and presents the existing window. + let args: Vec<_> = std::env::args().skip(1).collect(); + let shot = match args.as_slice() { + [] => None, + [flag, path] if flag == "--screenshot" => Some(std::path::PathBuf::from(path)), + _ => { + eprintln!("usage: application [--screenshot output.png]"); + return gtk::glib::ExitCode::from(2); + } + }; + let app = gtk::Application::builder() + .application_id("io.github.techmore.Preflight") + .build(); + let quit = gtk::gio::SimpleAction::new("quit", None); + let weak = app.downgrade(); + quit.connect_activate(move |_, _| { + if let Some(app) = weak.upgrade() { + for window in app.windows() { window.close(); } + } + }); + app.add_action(&quit); + app.set_accels_for_action("app.quit", &["q"]); + let keep = RefCell::new(None::>); + let failed = Rc::new(Cell::new(false)); + let failure = failed.clone(); + app.connect_activate(move |app| { + if let Some(host) = keep.borrow().as_ref() { + host.window().present(); + return; + } + let Some(host) = msdk_gtk::host::Host::open_doc( + app, app_model::document(), None, "main", None, false, + ) else { + failure.set(true); + app.quit(); + return; + }; + if let Some(path) = shot.clone() { + let (host, app, failure) = (host.clone(), app.clone(), failure.clone()); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(800), move || { + if let Err(error) = host.screenshot(&path) { + eprintln!("screenshot failed: {error}"); + failure.set(true); + } + host.window().close(); + app.quit(); + }); + } + *keep.borrow_mut() = Some(host); + }); + let status = app.run_with_args::<&str>(&[]); + if failed.get() { gtk::glib::ExitCode::FAILURE } else { status } +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/tests/model.rs b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/tests/model.rs new file mode 100644 index 000000000..716fbaff6 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/generated-smoke-source/tests/model.rs @@ -0,0 +1,6 @@ +#[test] +fn initial_state_round_trips() { + let state = app_model::State::initial().expect("typed initial state"); + let store = state.clone().into_store().unwrap(); + assert_eq!(app_model::State::from_store(store).unwrap(), state); +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/harness-source-manifest.json b/mseries/sdk-bench/receipts/2026-10-26-preflight/harness-source-manifest.json new file mode 100644 index 000000000..29e1a25d5 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/harness-source-manifest.json @@ -0,0 +1,6 @@ +{ + "worker.py": "c68763cd7a69028489ea27aca3301a80b28561322324b65a5227fb59fa6a07a9", + "capture.py": "bda837618a7f597c7d8561761edf688c972813390789f9244a4c735044babe54", + "run-model.py": "85e0f7a2814bd1b4a0282e83b56212cfdb9a7169e05938f1a735c512fa00017b", + "test_worker.py": "d756b7206dd660b186f7762c9c4650e4732e4314a47bb76c1f099e9693a96d51" +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/native-unprivileged-output.txt b/mseries/sdk-bench/receipts/2026-10-26-preflight/native-unprivileged-output.txt new file mode 100644 index 000000000..af485dd77 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/native-unprivileged-output.txt @@ -0,0 +1,35 @@ + Compiling serde_core v1.0.229 + Compiling msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Compiling serde_json v1.0.154 + Compiling msdk v0.1.0 (/work/sdk/msdk) + Finished `test` profile [unoptimized] target(s) in 12.26s + Running tests/cli.rs (/work/bench-target/debug/deps/cli-bf1f6f7448344ac7) + +running 1 test +test preview_failures_have_nonzero_exit_status ... dbus-daemon[2545]: [session uid=2000 pid=2545 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=2000 pid=3505 comm="/work/bench-target/debug/msdk-run app.ui.json --sc" label="unconfined") +dbus-daemon[2545]: [session uid=2000 pid=2545 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[3529]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=2000 pid=3505 comm="/work/bench-target/debug/msdk-run app.ui.json --sc" label="unconfined") +dbus-daemon[3529]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.15s + + Running tests/lifecycle.rs (/work/bench-target/debug/deps/lifecycle-a32b65b8167f1055) + +running 1 test +test closing_stops_owned_work_ignores_late_events_and_releases_the_host ... libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.80s + + Running tests/runtime.rs (/work/bench-target/debug/deps/runtime-6bc4f4cd54f6ddf2) + +running 1 test +test extension_mismatch_recovers_and_closed_hosts_kill_owned_commands ... libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.24s + diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/sandbox.json b/mseries/sdk-bench/receipts/2026-10-26-preflight/sandbox.json new file mode 100644 index 000000000..ca011725c --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/sandbox.json @@ -0,0 +1,20 @@ +{ + "devices": { + "eth0": { + "type": "none" + }, + "root": { + "path": "/", + "pool": "default", + "size": "16GiB", + "type": "disk" + } + }, + "limits": { + "limits.cpu": "4", + "limits.memory": "6GiB", + "limits.processes": "256" + }, + "privileged": "false", + "worker_identity": "uid2000 zero CapEff/CapAmb verified by protected worker before each successful tool call" +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/sdk-source-manifest.json b/mseries/sdk-bench/receipts/2026-10-26-preflight/sdk-source-manifest.json new file mode 100644 index 000000000..1fb3de97e --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/sdk-source-manifest.json @@ -0,0 +1,82 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "4ad376777fab148090633819ce0bb7817f6e1e61784829e580af0b1e61076af6", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "f0b5585d1accb97e77a72413019e391fe2c4dc6529426feaa35d6c02dbe841e3", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/cli.rs": "98435b6c7e22db69e7f260082e5771a26ba5ae07f0e10916dfa62592386f06a6", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "93355516029dd19fc79cbe6c0b25c075c03be2aed2e935ac436118d3b9520f14", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "ddc77b65438dea97f8155f74d7b02419dd1a5f73aae92824c1227f4d223e7f2a", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "e2a8577ccc38a266c31dddec3bd69c0ebec861ca8f40cc8391a21d03299f439c", + "msdk/src/check.rs": "ffd13919cba8026562e2d7e5d8454d3e871794bbe5abfd6034f7392e1ea47529", + "msdk/src/context.rs": "a39bf8c191b68e6dd6c0f55aa471d17ce943479ca4cd6a5b83f6b58f2e00ff98", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "d6a1b238a466d0c18ea551bc4c4456e267ed19d33c0f63f9617aff100f1c1bda", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "491e63fad29fe2e6fc92f816c36cf48a8aad6696a329f6ada1b3e6addfce42a0", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "303d3581d529056bd4f3a2d7f2b0010c98de640a27dcaeebdf716c979cc1ca2e", + "msdk/src/runtime.rs": "c14f11c22d23c8f16ccf5c8ba4bb3f937d21e434bd677bccfa191c1381cab2cd", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "056b9dbcbb35daaffa43a9b8cee905e4a05c37272ebf5df3c5f9f6e458ee9c9d", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/cli_manifests.rs": "379ba88408dfd16e62a423bda643ecdf196d09da74f00f7fed7de6ae8772d9f5", + "msdk/tests/context.rs": "794ff1f2d691a1873c4a2d5020a4e90a2e5df5690df41d87a1f72fe97a07ee30", + "msdk/tests/generate.rs": "97857f431ac3657d86438d6038b60f75fe06ad9424c1f855777b8ed4c617d922", + "msdk/tests/golden_path.rs": "b7bef19bf55957c30498937b491664863291bd0c5800319452fdeb384adad714", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/manifests.rs": "c6207c7a9c8114c71c8a57c7e941357c42e57d17ae7321863ed5969b2fd2fc71", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "69b8f439ffe7b6acda821a76d4199e416245914204f5a5c4b677c7225967f48b", + "msdk/tests/streaming.rs": "462881cd911693787a5babc562f94e59469f21a05e762776a942cf60c029ce85", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-Cargo.lock b/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-Cargo.lock new file mode 100644 index 000000000..1c03fda4f --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-Cargo.lock @@ -0,0 +1,868 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde_json", +] + +[[package]] +name = "msdk-bench-dependency-seed" +version = "0.0.0" +dependencies = [ + "gtk4", + "msdk", + "msdk-gtk", + "rusqlite", + "serde", + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rusqlite" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0dae2cbca1f0ff93795713cfe0a4c02f760e3c0b8ae2ab4ec4045808ff429f" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5fe1f8f1b06191a00962174c61aa5005e0bb391a6d80d07e24d115c01a92ed8" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863ad3ac83293fb4d740aedbfdc9240dd8d1a50c1099acd76ce80ce7c7230c7f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-source/Cargo.toml b/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-source/Cargo.toml new file mode 100644 index 000000000..883c760ef --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-source/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "msdk-bench-dependency-seed" +version = "0.0.0" +edition = "2024" +publish = false +[workspace] +[dependencies] +msdk = { path = "/work/sdk/msdk" } +msdk-gtk = { path = "/work/sdk/msdk-gtk" } +gtk = { package = "gtk4", version = "0.11", features = ["v4_20"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +rusqlite = "=0.32.1" diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-source/lib.rs b/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-source/lib.rs new file mode 100644 index 000000000..2c75cc83b --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/seed-source/lib.rs @@ -0,0 +1 @@ +pub fn provisioned() -> bool { true } diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/smoke-frame.png b/mseries/sdk-bench/receipts/2026-10-26-preflight/smoke-frame.png new file mode 100644 index 000000000..081fbc2ef Binary files /dev/null and b/mseries/sdk-bench/receipts/2026-10-26-preflight/smoke-frame.png differ diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/summary.json b/mseries/sdk-bench/receipts/2026-10-26-preflight/summary.json new file mode 100644 index 000000000..47660d551 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/summary.json @@ -0,0 +1,43 @@ +{ + "schema": "msdk.bench-preflight.v1", + "harness_commit": "0ea6c0302a24b0c363393e416cf0e718349b3579", + "sdk_source_files_matched": 80, + "boundary_tests": 4, + "native_suites_uid2000": 3, + "smoke_tools": [ + "new settings", + "generate typed standalone app", + "offline build", + "actual external screenshot", + "Ctrl+Q clean exit" + ], + "smoke_build_seconds": 82.12071825901512, + "smoke_window_mapped_seconds": 0.28292891499586403, + "smoke_frame_seconds": 0.9269498030189425, + "timing_scope": "trusted harness/dependency preflight only, outside model timer; not general performance or model authoring evidence", + "smoke_visual_review": "actual fixture content visible without clipped primary controls in regular default-text capture", + "model_trial": { + "result": "deferred-before-inference", + "inference_started": false, + "reason": "conservative admission refuses an already resident model; loaded does not prove active inference", + "resident_models": [ + { + "name": "qwen3.5:2b", + "digest": "0689d44085e06d165161a8a9a1731344278cfb5aade63a3c3dbdb48ab54b130a", + "expires_at": "2026-10-26T15:17:45.380294215-04:00", + "context_length": 4096, + "size": 2336961329, + "size_vram": 2336961329 + } + ] + }, + "cohort_spec": "unchanged s01 Quick Notes", + "first_provisioning_failure": "network disabled before dependencies; terminal exit100 before any model code/inference; corrected provisioning order; original transient /tmp log was hidden by boot-time tmpfs, so no raw failure log claimed", + "model_quality_result": "UNSCORED; no inference or authoring run began", + "remaining": [ + "quiet admission for pinned qwen3.5:4b", + "controlled model run and independent full-spec/rubric audit", + "baseline/repeated comparisons", + "full SDK completion ledger" + ] +} diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/system-provisioning-output.txt b/mseries/sdk-bench/receipts/2026-10-26-preflight/system-provisioning-output.txt new file mode 100644 index 000000000..2562de8e9 --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/system-provisioning-output.txt @@ -0,0 +1,161 @@ +Hit:1 http://archive.ubuntu.com/ubuntu resolute InRelease +Get:2 http://archive.ubuntu.com/ubuntu resolute-updates InRelease [137 kB] +Get:3 http://archive.ubuntu.com/ubuntu resolute/main amd64 Components [395 kB] +Get:4 http://security.ubuntu.com/ubuntu resolute-security InRelease [137 kB] +Get:5 http://archive.ubuntu.com/ubuntu resolute/restricted amd64 Components [556 B] +Get:6 http://archive.ubuntu.com/ubuntu resolute/universe amd64 Components [4556 kB] +Get:7 http://archive.ubuntu.com/ubuntu resolute/multiverse amd64 Components [50.0 kB] +Get:8 http://archive.ubuntu.com/ubuntu resolute-updates/main amd64 Components [110 kB] +Get:9 http://archive.ubuntu.com/ubuntu resolute-updates/restricted amd64 Components [212 B] +Get:10 http://archive.ubuntu.com/ubuntu resolute-updates/universe amd64 Components [201 kB] +Get:11 http://archive.ubuntu.com/ubuntu resolute-updates/multiverse amd64 Components [216 B] +Get:12 http://security.ubuntu.com/ubuntu resolute-security/main amd64 Packages [607 kB] +Get:13 http://security.ubuntu.com/ubuntu resolute-security/main Translation-en [141 kB] +Get:14 http://security.ubuntu.com/ubuntu resolute-security/main amd64 Components [46.7 kB] +Get:15 http://security.ubuntu.com/ubuntu resolute-security/restricted amd64 Components [212 B] +Get:16 http://security.ubuntu.com/ubuntu resolute-security/universe amd64 Packages [206 kB] +Get:17 http://security.ubuntu.com/ubuntu resolute-security/universe Translation-en [67.9 kB] +Get:18 http://security.ubuntu.com/ubuntu resolute-security/universe amd64 Components [55.5 kB] +Get:19 http://security.ubuntu.com/ubuntu resolute-security/multiverse amd64 Components [212 B] +Fetched 6711 kB in 1s (5100 kB/s) +Reading package lists... +Reading package lists... +Building dependency tree... +Reading state information... +Solving dependencies... +Suggested packages: + sqlite3-doc +The following NEW packages will be installed: + libsqlite3-dev sqlite3 +0 upgraded, 2 newly installed, 0 to remove and 17 not upgraded. +Need to get 1081 kB of archives. +After this operation, 4071 kB of additional disk space will be used. +Get:1 http://archive.ubuntu.com/ubuntu resolute-updates/main amd64 libsqlite3-dev amd64 3.46.1-9ubuntu0.3 [932 kB] +Get:2 http://archive.ubuntu.com/ubuntu resolute-updates/main amd64 sqlite3 amd64 3.46.1-9ubuntu0.3 [149 kB] +Fetched 1081 kB in 0s (3838 kB/s) +Selecting previously unselected package libsqlite3-dev:amd64. +(Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 34691 files and directories currently installed.) +Preparing to unpack .../libsqlite3-dev_3.46.1-9ubuntu0.3_amd64.deb ... +Unpacking libsqlite3-dev:amd64 (3.46.1-9ubuntu0.3) ... +Selecting previously unselected package sqlite3. +Preparing to unpack .../sqlite3_3.46.1-9ubuntu0.3_amd64.deb ... +Unpacking sqlite3 (3.46.1-9ubuntu0.3) ... +Setting up libsqlite3-dev:amd64 (3.46.1-9ubuntu0.3) ... +Setting up sqlite3 (3.46.1-9ubuntu0.3) ... +Reading package lists... +Building dependency tree... +Reading state information... +Solving dependencies... +The following additional packages will be installed: + imagemagick-7-common imagemagick-7.q16 libfftw3-double3 liblqr-1-0 libltdl7 + libmagickcore-7.q16-10 libmagickwand-7.q16-10 libopenjp2-7 libraw23t64 + libwebpdemux2 libwebpmux3 +Suggested packages: + imagemagick-7-doc autotrace cups-bsd | lpr | lprng enscript ffmpeg gimp + gnuplot grads graphviz groff-base hp2xx html2ps libwmf-bin mplayer povray + radiance sane-utils texlive-base-bin transfig libraw-bin xdg-utils + libfftw3-bin libfftw3-dev libmagickcore-7.q16-10-extra +Recommended packages: + libmagickcore-7.q16-10-extra ghostscript netpbm fonts-urw-base35 +The following NEW packages will be installed: + imagemagick imagemagick-7-common imagemagick-7.q16 libfftw3-double3 + liblqr-1-0 libltdl7 libmagickcore-7.q16-10 libmagickwand-7.q16-10 + libopenjp2-7 libraw23t64 libwebpdemux2 libwebpmux3 +0 upgraded, 12 newly installed, 0 to remove and 17 not upgraded. +Need to get 4615 kB of archives. +After this operation, 15.9 MB of additional disk space will be used. +Get:1 http://archive.ubuntu.com/ubuntu resolute/main amd64 libfftw3-double3 amd64 3.3.10-2fakesync1build3 [833 kB] +Get:2 http://archive.ubuntu.com/ubuntu resolute/universe amd64 liblqr-1-0 amd64 0.4.2-2.2 [29.4 kB] +Get:3 http://archive.ubuntu.com/ubuntu resolute/main amd64 libltdl7 amd64 2.5.4-9 [43.7 kB] +Get:4 http://archive.ubuntu.com/ubuntu resolute-updates/main amd64 libopenjp2-7 amd64 2.5.4-1ubuntu0.1 [187 kB] +Get:5 http://archive.ubuntu.com/ubuntu resolute-updates/main amd64 libraw23t64 amd64 0.21.5b-1ubuntu1.1 [373 kB] +Get:6 http://archive.ubuntu.com/ubuntu resolute/main amd64 libwebpdemux2 amd64 1.5.0-0.1build1 [12.8 kB] +Get:7 http://archive.ubuntu.com/ubuntu resolute/main amd64 libwebpmux3 amd64 1.5.0-0.1build1 [26.4 kB] +Get:8 http://archive.ubuntu.com/ubuntu resolute/universe amd64 imagemagick-7-common all 8:7.1.2.18+dfsg1-1 [73.0 kB] +Get:9 http://archive.ubuntu.com/ubuntu resolute/universe amd64 libmagickcore-7.q16-10 amd64 8:7.1.2.18+dfsg1-1 [1977 kB] +Get:10 http://archive.ubuntu.com/ubuntu resolute/universe amd64 libmagickwand-7.q16-10 amd64 8:7.1.2.18+dfsg1-1 [343 kB] +Get:11 http://archive.ubuntu.com/ubuntu resolute/universe amd64 imagemagick-7.q16 amd64 8:7.1.2.18+dfsg1-1 [703 kB] +Get:12 http://archive.ubuntu.com/ubuntu resolute/universe amd64 imagemagick amd64 8:7.1.2.18+dfsg1-1 [14.1 kB] +Fetched 4615 kB in 1s (8007 kB/s) +Selecting previously unselected package libfftw3-double3:amd64. +(Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 34704 files and directories currently installed.) +Preparing to unpack .../00-libfftw3-double3_3.3.10-2fakesync1build3_amd64.deb ... +Unpacking libfftw3-double3:amd64 (3.3.10-2fakesync1build3) ... +Selecting previously unselected package liblqr-1-0:amd64. +Preparing to unpack .../01-liblqr-1-0_0.4.2-2.2_amd64.deb ... +Unpacking liblqr-1-0:amd64 (0.4.2-2.2) ... +Selecting previously unselected package libltdl7:amd64. +Preparing to unpack .../02-libltdl7_2.5.4-9_amd64.deb ... +Unpacking libltdl7:amd64 (2.5.4-9) ... +Selecting previously unselected package libopenjp2-7:amd64. +Preparing to unpack .../03-libopenjp2-7_2.5.4-1ubuntu0.1_amd64.deb ... +Unpacking libopenjp2-7:amd64 (2.5.4-1ubuntu0.1) ... +Selecting previously unselected package libraw23t64:amd64. +Preparing to unpack .../04-libraw23t64_0.21.5b-1ubuntu1.1_amd64.deb ... +Unpacking libraw23t64:amd64 (0.21.5b-1ubuntu1.1) ... +Selecting previously unselected package libwebpdemux2:amd64. +Preparing to unpack .../05-libwebpdemux2_1.5.0-0.1build1_amd64.deb ... +Unpacking libwebpdemux2:amd64 (1.5.0-0.1build1) ... +Selecting previously unselected package libwebpmux3:amd64. +Preparing to unpack .../06-libwebpmux3_1.5.0-0.1build1_amd64.deb ... +Unpacking libwebpmux3:amd64 (1.5.0-0.1build1) ... +Selecting previously unselected package imagemagick-7-common. +Preparing to unpack .../07-imagemagick-7-common_8%3a7.1.2.18+dfsg1-1_all.deb ... +Unpacking imagemagick-7-common (8:7.1.2.18+dfsg1-1) ... +Selecting previously unselected package libmagickcore-7.q16-10:amd64. +Preparing to unpack .../08-libmagickcore-7.q16-10_8%3a7.1.2.18+dfsg1-1_amd64.deb ... +Unpacking libmagickcore-7.q16-10:amd64 (8:7.1.2.18+dfsg1-1) ... +Selecting previously unselected package libmagickwand-7.q16-10:amd64. +Preparing to unpack .../09-libmagickwand-7.q16-10_8%3a7.1.2.18+dfsg1-1_amd64.deb ... +Unpacking libmagickwand-7.q16-10:amd64 (8:7.1.2.18+dfsg1-1) ... +Selecting previously unselected package imagemagick-7.q16. +Preparing to unpack .../10-imagemagick-7.q16_8%3a7.1.2.18+dfsg1-1_amd64.deb ... +Unpacking imagemagick-7.q16 (8:7.1.2.18+dfsg1-1) ... +Selecting previously unselected package imagemagick. +Preparing to unpack .../11-imagemagick_8%3a7.1.2.18+dfsg1-1_amd64.deb ... +Unpacking imagemagick (8:7.1.2.18+dfsg1-1) ... +Setting up imagemagick-7-common (8:7.1.2.18+dfsg1-1) ... +Setting up libwebpdemux2:amd64 (1.5.0-0.1build1) ... +Setting up libltdl7:amd64 (2.5.4-9) ... +Setting up libfftw3-double3:amd64 (3.3.10-2fakesync1build3) ... +Setting up libraw23t64:amd64 (0.21.5b-1ubuntu1.1) ... +Setting up liblqr-1-0:amd64 (0.4.2-2.2) ... +Setting up libopenjp2-7:amd64 (2.5.4-1ubuntu0.1) ... +Setting up libwebpmux3:amd64 (1.5.0-0.1build1) ... +Setting up libmagickcore-7.q16-10:amd64 (8:7.1.2.18+dfsg1-1) ... +Setting up libmagickwand-7.q16-10:amd64 (8:7.1.2.18+dfsg1-1) ... +Setting up imagemagick-7.q16 (8:7.1.2.18+dfsg1-1) ... +update-alternatives: using /usr/bin/compare-im7.q16 to provide /usr/bin/compare (compare) in auto mode +update-alternatives: using /usr/bin/compare-im7.q16 to provide /usr/bin/compare-im7 (compare-im7) in auto mode +update-alternatives: using /usr/bin/animate-im7.q16 to provide /usr/bin/animate (animate) in auto mode +update-alternatives: using /usr/bin/animate-im7.q16 to provide /usr/bin/animate-im7 (animate-im7) in auto mode +update-alternatives: using /usr/bin/convert-im7.q16 to provide /usr/bin/convert (convert) in auto mode +update-alternatives: using /usr/bin/convert-im7.q16 to provide /usr/bin/convert-im7 (convert-im7) in auto mode +update-alternatives: using /usr/bin/composite-im7.q16 to provide /usr/bin/composite (composite) in auto mode +update-alternatives: using /usr/bin/composite-im7.q16 to provide /usr/bin/composite-im7 (composite-im7) in auto mode +update-alternatives: using /usr/bin/conjure-im7.q16 to provide /usr/bin/conjure (conjure) in auto mode +update-alternatives: using /usr/bin/conjure-im7.q16 to provide /usr/bin/conjure-im7 (conjure-im7) in auto mode +update-alternatives: using /usr/bin/import-im7.q16 to provide /usr/bin/import (import) in auto mode +update-alternatives: using /usr/bin/import-im7.q16 to provide /usr/bin/import-im7 (import-im7) in auto mode +update-alternatives: using /usr/bin/identify-im7.q16 to provide /usr/bin/identify (identify) in auto mode +update-alternatives: using /usr/bin/identify-im7.q16 to provide /usr/bin/identify-im7 (identify-im7) in auto mode +update-alternatives: using /usr/bin/stream-im7.q16 to provide /usr/bin/stream (stream) in auto mode +update-alternatives: using /usr/bin/stream-im7.q16 to provide /usr/bin/stream-im7 (stream-im7) in auto mode +update-alternatives: using /usr/bin/display-im7.q16 to provide /usr/bin/display (display) in auto mode +update-alternatives: using /usr/bin/display-im7.q16 to provide /usr/bin/display-im7 (display-im7) in auto mode +update-alternatives: using /usr/bin/montage-im7.q16 to provide /usr/bin/montage (montage) in auto mode +update-alternatives: using /usr/bin/montage-im7.q16 to provide /usr/bin/montage-im7 (montage-im7) in auto mode +update-alternatives: using /usr/bin/mogrify-im7.q16 to provide /usr/bin/mogrify (mogrify) in auto mode +update-alternatives: using /usr/bin/mogrify-im7.q16 to provide /usr/bin/mogrify-im7 (mogrify-im7) in auto mode +update-alternatives: using /usr/bin/magick-im7.q16 to provide /usr/bin/magick (magick) in auto mode +update-alternatives: warning: skip creation of /usr/share/man/man1/magick.1.gz because associated file /usr/share/man/man1/magick-im7.q16.1.gz (of link group magick) does not exist +update-alternatives: using /usr/bin/magick-im7.q16 to provide /usr/bin/magick-im7 (magick-im7) in auto mode +update-alternatives: warning: skip creation of /usr/share/man/man1/magick-im7.1.gz because associated file /usr/share/man/man1/magick-im7.q16.1.gz (of link group magick-im7) does not exist +update-alternatives: using /usr/bin/magick-script-im7.q16 to provide /usr/bin/magick-script (magick-script) in auto mode +update-alternatives: warning: skip creation of /usr/share/man/man1/magick-script.1.gz because associated file /usr/share/man/man1/magick-script-im7.q16.1.gz (of link group magick-script) does not exist +update-alternatives: using /usr/bin/magick-script-im7.q16 to provide /usr/bin/magick-script-im7 (magick-script-im7) in auto mode +update-alternatives: warning: skip creation of /usr/share/man/man1/magick-script-im7.1.gz because associated file /usr/share/man/man1/magick-script-im7.q16.1.gz (of link group magick-script-im7) does not exist +Setting up imagemagick (8:7.1.2.18+dfsg1-1) ... +Processing triggers for hicolor-icon-theme (0.18-2build1) ... +Processing triggers for libc-bin (2.43-2ubuntu2.4) ... +Processing triggers for desktop-file-utils (0.28-1build1) ... diff --git a/mseries/sdk-bench/receipts/2026-10-26-preflight/tool-preflight.json b/mseries/sdk-bench/receipts/2026-10-26-preflight/tool-preflight.json new file mode 100644 index 000000000..85dc589ba --- /dev/null +++ b/mseries/sdk-bench/receipts/2026-10-26-preflight/tool-preflight.json @@ -0,0 +1,111 @@ +[ + { + "action": { + "action": "list" + }, + "response": { + "ok": true, + "result": { + "files": [] + } + } + }, + { + "action": { + "action": "run", + "command": "new", + "template": "settings", + "path": "preflight" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 0.02208889799658209, + "output": "created /work/bench-app/preflight from `settings` (id io.github.techmore.Preflight); next: cd /work/bench-app/preflight && msdk check app.ui.json && msdk gate app.ui.json app.gates.json\n", + "argv": [ + "/work/target/debug/msdk", + "new", + "settings", + "/work/bench-app/preflight" + ] + } + } + }, + { + "action": { + "action": "run", + "command": "gen", + "path": "preflight/app.ui.json", + "output": "preflight-generated" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 0.020914396969601512, + "output": "created standalone Cargo application in /work/bench-app/preflight-generated; next: cargo run --manifest-path /work/bench-app/preflight-generated/Cargo.toml\n", + "argv": [ + "/work/target/debug/msdk", + "gen", + "/work/bench-app/preflight/app.ui.json", + "/work/bench-app/preflight-generated", + "--sdk-root", + "/work/sdk" + ] + } + } + }, + { + "action": { + "action": "run", + "command": "build", + "project": "preflight-generated" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 82.12071825901512, + "output": " Locking 74 packages to latest Rust 1.93.1 compatible versions\n Compiling system-deps v9.0.1\n Compiling smallvec v1.16.4\n Compiling cfg-expr v0.20.10\n Compiling cc v1.10.0\n Compiling glib-sys v0.22.9\n Compiling gobject-sys v0.22.9\n Compiling gio-sys v0.22.9\n Compiling pango-sys v0.22.9\n Compiling gdk-pixbuf-sys v0.22.9\n Compiling cairo-sys-rs v0.22.9\n Compiling glib v0.22.10\n Compiling gdk4-sys v0.11.5\n Compiling graphene-sys v0.22.9\n Compiling gsk4-sys v0.11.5\n Compiling gtk4-sys v0.11.5\n Compiling msdk-gtk v0.1.0 (/work/sdk/msdk-gtk)\n Compiling gio v0.22.10\n Compiling cairo-rs v0.22.9\n Compiling graphene-rs v0.22.8\n Compiling gdk-pixbuf v0.22.0\n Compiling pango v0.22.9\n Compiling gdk4 v0.11.5\n Compiling gsk4 v0.11.5\n Compiling gtk4 v0.11.5\n Compiling msdk-preflight v0.1.0 (/work/bench-app/preflight-generated)\n Finished `dev` profile [unoptimized] target(s) in 1m 22s\n", + "argv": [ + "/usr/bin/cargo", + "build", + "--manifest-path", + "/work/bench-app/preflight-generated/Cargo.toml", + "--offline" + ] + } + } + }, + { + "action": { + "action": "run", + "command": "launch", + "project": "preflight-generated" + }, + "response": { + "ok": true, + "result": { + "code": 0, + "limit": null, + "seconds": 1.1511555950855836, + "output": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\ndbus-daemon[4547]: [session uid=2000 pid=4547 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.0' (uid=2000 pid=4549 comm=\"/work/bench-target/debug/msdk-preflight\" label=\"unconfined\")\ndbus-daemon[4547]: [session uid=2000 pid=4547 pidfd=5] Successfully activated service 'org.a11y.Bus'\ndbus-daemon[4583]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=2000 pid=4549 comm=\"/work/bench-target/debug/msdk-preflight\" label=\"unconfined\")\ndbus-daemon[4583]: Successfully activated service 'org.a11y.atspi.Registry'\nSpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry\n{\"mapped_seconds\": 0.28292891499586403, \"captured_seconds\": 0.9269498030189425, \"frame_bytes\": 21141, \"ctrl_q_clean\": true, \"content_review\": \"pending independent review\"}\n", + "argv": [ + "xvfb-run", + "-a", + "dbus-run-session", + "--", + "/usr/bin/python3", + "/opt/msdk-bench/capture.py", + "/work/bench-target/debug/msdk-preflight", + "/work/bench-app/evidence/frame-1793041874547625959.png" + ], + "frame": "evidence/frame-1793041874547625959.png" + } + } + } +] \ No newline at end of file diff --git a/mseries/sdk-bench/run-model.py b/mseries/sdk-bench/run-model.py new file mode 100644 index 000000000..ec1be2e45 --- /dev/null +++ b/mseries/sdk-bench/run-model.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +"""Pinned-model SDK authoring discovery on SER8; completion is independently judged. + +Run on the host controlling an already prepared offline uid2000 sandbox. The +model sees only public SDK material, the frozen spec and its synthetic project. +No daemon/configuration change or model download is performed. +""" +import argparse +import base64 +from datetime import datetime, timezone +import fcntl +import hashlib +import json +import re +from pathlib import Path +import subprocess +import time +import urllib.request + +MODEL = 'qwen3.5:4b' +DIGEST = 'd8b0f5e9760cd1682034f292d7ef72ec46f432149be0df7574bf2d6e92e38c04' +OPTIONS = {'seed': 17, 'temperature': .2, 'top_p': .95, 'top_k': 20, + 'num_ctx': 32768, 'num_predict': 4096, 'presence_penalty': 0.0, 'repeat_penalty': 1.0} +SYSTEM = '''You are testing an app SDK by implementing the supplied complete, frozen spec. +Return exactly ONE JSON action per turn, no Markdown. Model output is tool data. +Actions: +{"action":"write","files":{"relative/path":"complete UTF-8 file content"}} +{"action":"read","path":"relative/path","start":0} (160 lines at a time) +{"action":"list"} +{"action":"run","command":"templates|describe|new|check|render|gate|gen|build|test|clippy|fmt|launch|pack", ...} +{"action":"done","reason":"what is implemented and any remaining limitations"} +run options: describe has topic; new has template and path (new directory); +check/render/gate has path; gate optionally has gates (scenario file path); +gen has path and output (new directory); +build/test/clippy/fmt/launch/pack has project directory, default ".". +launch can select binary if there is more than one. launch captures the real app +and tests Ctrl+Q externally; your app need not implement a screenshot flag. +Use SDK descriptions/rules and generated typed Rust. App-local Rust Logic/Services +can implement missing backend behavior. Do not claim that a starter meets the +whole spec. Implement persistence and interactions; fixtures must be explicit. +SDK root /work/sdk is READ ONLY. Read SDK files with path sdk/msdk/README.md, +sdk/msdk/src/logic.rs, sdk/msdk-gtk/src/host.rs, etc. The new project is your only +writable tool surface. No shell tool, arbitrary host commands, network, owner +accounts or real user data are available. Do not alter benchmark evidence. +The source is a clean SDK snapshot; unrelated repo handoffs are intentionally absent. +Rust edition2024, GTK4 crate0.11 with v4_20, serde1 derive, serde_json1, +rusqlite0.32.1 and the SDK crates are provisioned offline. Only cached dependencies +can build. Cargo builds are offline with 2 jobs. SDK dependencies are local paths: +msdk={path="/work/sdk/msdk"}; msdk-gtk={path="/work/sdk/msdk-gtk"}. +Use templates/describe to discover actual vocabulary. Do not invent APIs or components. +The full spec is the target. Build/test/fmt/clippy, launch and repair tool errors. +Do not stop merely because a JSON description checks or a first window appears. +done submits a CANDIDATE for independent review; it never sets benchmark success. +''' + +def api(path, payload=None): + request = urllib.request.Request('http://127.0.0.1:11434/api/' + path, + data=json.dumps(payload).encode() if payload is not None else None, + headers={'Content-Type': 'application/json'}) + with urllib.request.urlopen(request, timeout=900) as response: + return json.load(response) + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('--container', required=True) +parser.add_argument('--spec', type=Path, required=True) +parser.add_argument('--output', type=Path, required=True) +parser.add_argument('--source-commit', required=True) +parser.add_argument('--max-turns', type=int, default=20) +args = parser.parse_args() +if not args.container.startswith('msdk-bench-') or not 1 <= args.max_turns <= 30: + raise SystemExit('requires an owned benchmark container and 1..30 turns') +args.output.mkdir(parents=True, exist_ok=False) +lock = open('/tmp/msdk-bench-model.lock', 'a+') +fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB) +tags = api('tags')['models'] +installed = next((model for model in tags if model['name'] == MODEL), None) +if installed is None or installed['digest'] != DIGEST: + raise SystemExit('installed model differs from pinned trial identity') +if api('ps')['models']: + raise SystemExit('model service is occupied; do not switch or replace its worker') +show = api('show', {'model': MODEL}) +if 'Apache License' not in show.get('license', ''): + raise SystemExit('expected packaged license is unavailable; do not run') +spec_text = args.spec.read_text() +available = int(next(line.split()[1] for line in Path('/proc/meminfo').read_text().splitlines() if line.startswith('MemAvailable:'))) +if available < 6 * 1024 * 1024: + raise SystemExit('insufficient spare host memory for a bounded trial; no inference started') +weights = re.search(r'sha256-([0-9a-f]{64})', show.get('modelfile', '')) +metadata = {'schema': 'msdk.authoring-discovery.v1', 'mode': 'sdk', + 'started_utc': datetime.now(timezone.utc).isoformat(), + 'source_commit': args.source_commit, 'model': installed, + 'runtime': api('version'), 'model_details': show.get('details'), + 'model_default_parameters': show.get('parameters'), + 'model_modelfile_sha256': hashlib.sha256(show.get('modelfile', '').encode()).hexdigest(), + 'model_template_sha256': hashlib.sha256(show.get('template', '').encode()).hexdigest(), + 'weights_blob_sha256': weights.group(1) if weights else None, + 'host': 'ser8', 'available_memory_kib_at_start': available, + 'model_info': show.get('model_info'), 'options': OPTIONS, + 'think': False, 'format': 'json', 'keep_alive': '2m', 'image_feedback': 'latest captured app frame only', + 'spec_sha256': hashlib.sha256(spec_text.encode()).hexdigest(), + 'spec_name': args.spec.name, 'system_prompt_sha256': hashlib.sha256(SYSTEM.encode()).hexdigest(), + 'container': args.container, 'runner': 'SDK JSON actions discovery v1', + 'human_interventions': 0, 'provisioning': 'completed before trial timer', + 'maximum_seconds': 7200, 'max_turns': args.max_turns, + 'context_policy': 'preserve system/spec; retain latest image only; trim oldest action/result pairs above 64000 serialized text bytes; project files remain readable'} +(args.output / 'metadata.json').write_text(json.dumps(metadata, indent=2) + '\n') +(args.output / 'model-LICENSE.txt').write_text(show['license']) +(args.output / 'system-prompt.txt').write_text(SYSTEM) +(args.output / 'spec.md').write_text(spec_text) +messages = [{'role': 'system', 'content': SYSTEM}, {'role': 'user', 'content': spec_text}] +started = time.monotonic() +status = {'result': 'in-progress', 't_done': 'not reached', 'first_frame_candidate_seconds': None, + 'token_input': 0, 'token_output': 0, 'tool_errors': 0, 'turns': 0} + +def worker(action): + command = ['incus', 'exec', args.container, '--user', '2000', '--group', '2000', + '--cwd', '/work/bench-app', '--env', 'HOME=/work/bench-home', + '--env', 'CARGO_HOME=/work/bench-home/.cargo', '--env', 'CARGO_TARGET_DIR=/work/bench-target', + '--env', 'CARGO_PROFILE_DEV_DEBUG=0', '--env', 'XDG_DATA_HOME=/work/bench-app-state/data', + '--env', 'XDG_CONFIG_HOME=/work/bench-app-state/config', '--env', 'XDG_CACHE_HOME=/work/bench-app-state/cache', + '--env', 'MSDK_BENCH_MODE=sdk', '--', '/usr/bin/python3', '/opt/msdk-bench/worker.py'] + result = subprocess.run(command, input=json.dumps(action), text=True, capture_output=True, timeout=180) + if result.returncode != 0: + raise RuntimeError('sandbox tool failed: ' + result.stderr[-2000:]) + return json.loads(result.stdout) + +# Verify the sandbox before sending any prompt or executing generated code. +initial = worker({'action': 'list'}) +if not initial.get('ok') or initial.get('result', {}).get('files'): + raise SystemExit('requires a verified empty non-root/offline project; no inference started') +for turn in range(1, args.max_turns + 1): + if time.monotonic() - started >= 7200: + status['result'] = '120-minute-cap' + break + loaded = api('ps')['models'] + if any(item['name'] != MODEL for item in loaded): + status['result'] = 'interrupted-other-model-work' + break + turn_dir = args.output / f'turn-{turn:02d}' + turn_dir.mkdir() + for message in messages[:-1]: + message.pop('images', None) + def text_bytes(): + return len(json.dumps([{key: value for key, value in message.items() if key != 'images'} for message in messages]).encode()) + while text_bytes() > 64000 and len(messages) > 5: + del messages[2:4] + request = {'model': MODEL, 'messages': messages, 'stream': False, 'think': False, + 'format': 'json', 'keep_alive': '2m', 'options': OPTIONS} + (turn_dir / 'request.json').write_text(json.dumps(request, indent=2)) + print(json.dumps({'turn': turn, 'phase': 'inference', 'elapsed_seconds': time.monotonic() - started}), flush=True) + phase = 'inference' + try: + response = api('chat', request) + (turn_dir / 'response.json').write_text(json.dumps(response, indent=2)) + if not response.get('done'): + raise RuntimeError('upstream returned no terminal completion') + status['token_input'] += response.get('prompt_eval_count', 0) + status['token_output'] += response.get('eval_count', 0) + content = response['message']['content'] + messages.append({'role': 'assistant', 'content': content}) + phase = 'format' + action = json.loads(content) + if action.get('action') == 'done': + status['result'] = 'candidate-needs-independent-review' + status['model_claim'] = action.get('reason') + status['turns'] = turn + break + phase = 'tool' + outcome = worker(action) + (turn_dir / 'tool-result.json').write_text(json.dumps(outcome, indent=2)) + tool_result = outcome.get('result', {}) + if tool_result.get('frame') and status['first_frame_candidate_seconds'] is None: + status['first_frame_candidate_seconds'] = time.monotonic() - started + if not outcome.get('ok') or tool_result.get('code', 0) != 0: + status['tool_errors'] += 1 + feedback = {'role': 'user', 'content': 'Tool result (untrusted data): ' + json.dumps(outcome)} + frame = tool_result.get('frame') + if frame: + path = Path(frame) + if not frame.startswith('evidence/frame-') or path.suffix != '.png' or '..' in path.parts: + raise RuntimeError('invalid captured-frame path from tool') + command = ['incus', 'exec', args.container, '--user', '2000', '--group', '2000', + '--', '/usr/bin/head', '-c', '2097153', str(Path('/work/bench-app') / path)] + pixels = subprocess.check_output(command, timeout=8) + if len(pixels) > 2097152: + feedback['content'] += '\nCaptured image exceeds the 2MiB feedback limit.' + else: + feedback['images'] = [base64.b64encode(pixels).decode()] + messages.append(feedback) + except Exception as error: + status['tool_errors'] += 1 + messages.append({'role': 'user', 'content': 'Tool/format error: ' + str(error)}) + (turn_dir / 'error.txt').write_text(str(error)) + if phase != 'format': + status['result'] = 'interrupted-' + phase + '-observation' + # A lost HTTP/Incus observation is not proof that upstream work + # stopped. Retain the attempt and stop dispatching replacements. + break + status['turns'] = turn + status['elapsed_seconds'] = time.monotonic() - started + (args.output / 'status.json').write_text(json.dumps(status, indent=2)) + print(json.dumps({'turn': turn, 'phase': 'completed', **status}), flush=True) +else: + status['result'] = 'turn-budget-before-independent-done' +status['elapsed_seconds'] = time.monotonic() - started +status['acceptance'] = 'UNSCORED: build/behavior/visual/accessibility/install audit required' +(args.output / 'status.json').write_text(json.dumps(status, indent=2) + '\n') +print(json.dumps(status, indent=2), flush=True) diff --git a/mseries/sdk-bench/test_worker.py b/mseries/sdk-bench/test_worker.py new file mode 100644 index 000000000..8ddb62893 --- /dev/null +++ b/mseries/sdk-bench/test_worker.py @@ -0,0 +1,68 @@ +import importlib.util +from pathlib import Path +import tempfile +import unittest +from unittest.mock import patch + +spec = importlib.util.spec_from_file_location('sdk_bench_worker', Path(__file__).with_name('worker.py')) +worker = importlib.util.module_from_spec(spec) +spec.loader.exec_module(worker) + +class WorkerBoundaryTests(unittest.TestCase): + def setUp(self): + self.temporary = tempfile.TemporaryDirectory() + self.root = Path(self.temporary.name) + self.old_root, self.old_sdk, self.old_mode = worker.ROOT, worker.SDK, worker.MODE + worker.ROOT = self.root / 'project' + worker.SDK = self.root / 'sdk' + worker.ROOT.mkdir() + worker.SDK.mkdir() + worker.MODE = 'sdk' + + def tearDown(self): + worker.ROOT, worker.SDK, worker.MODE = self.old_root, self.old_sdk, self.old_mode + self.temporary.cleanup() + + def test_model_paths_cannot_leave_project_or_change_runner_evidence(self): + for path in ['/etc/passwd', '../outside.rs', 'src/../../outside.rs', '.cargo/config.toml', 'evidence/fake.json', 'target/main.rs']: + with self.assertRaises(ValueError, msg=path): + worker.project_path(path, write=True) + (worker.ROOT / 'escape').symlink_to(worker.SDK, target_is_directory=True) + with self.assertRaises(ValueError): + worker.project_path('escape/overwritten.rs', write=True) + + def test_whole_write_batch_is_validated_before_any_file_is_written(self): + with self.assertRaises(ValueError): + worker.execute({'action': 'write', 'files': {'src/main.rs': 'fn main() {}', '../escape.rs': 'bad'}}) + self.assertFalse((worker.ROOT / 'src').exists()) + worker.execute({'action': 'write', 'files': {'src/main.rs': 'fn main() {}'}}) + self.assertEqual((worker.ROOT / 'src/main.rs').read_text(), 'fn main() {}') + + def test_sdk_reads_are_confined_and_baseline_cannot_use_sdk_tools(self): + (worker.SDK / 'README.md').write_text('public SDK fixture') + self.assertIn('public SDK fixture', worker.execute({'action': 'read', 'path': 'sdk/README.md'})['text']) + with self.assertRaises(ValueError): + worker.execute({'action': 'read', 'path': 'sdk/../outside'}) + worker.MODE = 'baseline' + with self.assertRaises(ValueError): + worker.execute({'action': 'read', 'path': 'sdk/README.md'}) + with self.assertRaises(ValueError): + worker.execute({'action': 'run', 'command': 'describe'}) + + def test_unknown_commands_and_large_files_are_refused(self): + with self.assertRaises(ValueError): + worker.execute({'action': 'run', 'command': 'sh -c dangerous'}) + with self.assertRaises(ValueError): + worker.execute({'action': 'write', 'files': {'src/main.rs': 'x' * 100001}}) + + def test_gate_passes_scenario_file_and_rejects_escaping_paths(self): + with patch.object(worker, 'run', return_value={'code': 0}) as run: + worker.execute({'action': 'run', 'command': 'gate', 'path': 'app.ui.json', 'gates': 'app.gates.json'}) + self.assertEqual(run.call_args.args[0], ['/work/target/debug/msdk', 'gate', + str((worker.ROOT / 'app.ui.json').resolve()), str((worker.ROOT / 'app.gates.json').resolve())]) + with self.assertRaises(ValueError): + worker.execute({'action': 'run', 'command': 'gate', 'gates': '../outside.json'}) + self.assertEqual(run.call_count, 1) + +if __name__ == '__main__': + unittest.main() diff --git a/mseries/sdk-bench/worker.py b/mseries/sdk-bench/worker.py new file mode 100644 index 000000000..74524eaa0 --- /dev/null +++ b/mseries/sdk-bench/worker.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +"""Fixed tool surface inside a non-root, offline, disposable SDK benchmark VM. + +Model output is data. It never selects a host command or writes SDK/runner files. +Generated Rust executes only in the separately isolated benchmark container. +""" +import json +import os +from pathlib import Path +import signal +import subprocess +import sys +import tempfile +import time + +ROOT = Path('/work/bench-app') +SDK = Path('/work/sdk') +TARGET = Path('/work/bench-target') +MODE = os.environ.get('MSDK_BENCH_MODE', 'sdk') + +def project_path(name, write=False): + if not isinstance(name, str) or not name or len(name) > 240: + raise ValueError('a relative project path is required') + path = Path(name) + if path.is_absolute() or '..' in path.parts or any(part.startswith('.') for part in path.parts): + raise ValueError('absolute, parent and hidden paths are not allowed') + resolved = (ROOT / path).resolve() + if not resolved.is_relative_to(ROOT.resolve()): + raise ValueError('path leaves the project') + if any(part in ('evidence', 'target') for part in path.parts): + raise ValueError('runner evidence and build outputs are not model inputs') + if write and not (path.name in ('Cargo.toml', 'Cargo.lock', 'LICENSE', 'README.md') + or path.suffix in ('.json', '.msdk', '.rs', '.svg', '.xml', '.desktop')): + raise ValueError('unsupported source file type') + return resolved + +def run(argv, cwd=ROOT, seconds=120): + env = dict(os.environ, CARGO_NET_OFFLINE='true', CARGO_BUILD_JOBS='2', + CARGO_TARGET_DIR=str(TARGET), GDK_BACKEND='x11', GSK_RENDERER='cairo') + started = time.monotonic() + with tempfile.TemporaryFile() as output: + process = subprocess.Popen(argv, cwd=cwd, env=env, stdout=output, + stderr=subprocess.STDOUT, start_new_session=True) + reason = None + try: + while True: + # Preserve the leader's identity until all group signals finish. + status = os.waitid(os.P_PID, process.pid, os.WEXITED | os.WNOHANG | os.WNOWAIT) + if status is not None: + break + if output.tell() > 2 * 1024 * 1024: + reason = 'output-limit' + break + if time.monotonic() - started >= seconds: + reason = 'timeout' + break + time.sleep(.02) + finally: + try: + os.killpg(process.pid, signal.SIGKILL) + except ProcessLookupError: + pass + code = process.wait() + output.seek(0) + text = output.read(16000).decode(errors='replace') + return {'code': code, 'limit': reason, 'seconds': time.monotonic() - started, + 'output': text, 'argv': argv} + +def binary_path(project, requested): + metadata = subprocess.check_output(['/usr/bin/cargo', 'metadata', '--offline', '--no-deps', + '--format-version', '1', '--manifest-path', str(project / 'Cargo.toml')], + text=True, env=dict(os.environ, CARGO_NET_OFFLINE='true', CARGO_TARGET_DIR=str(TARGET))) + binaries = [target['name'] for package in json.loads(metadata)['packages'] + for target in package['targets'] if 'bin' in target['kind']] + selected = requested or (binaries[0] if len(binaries) == 1 else '') + if selected not in binaries or '/' in selected: + raise ValueError('select one built Cargo binary') + return TARGET / 'debug' / selected + +def execute(request): + action = request.get('action') + if action == 'list': + files = [str(path.relative_to(ROOT)) for path in ROOT.rglob('*') + if path.is_file() and not any(part in ('evidence', 'target', '.bench-state') + for part in path.relative_to(ROOT).parts)] + return {'files': sorted(files)[:80]} + if action == 'read': + name = request.get('path', '') + if name.startswith('sdk/'): + if MODE != 'sdk': + raise ValueError('SDK source is not a baseline tool') + path = (SDK / name[4:]).resolve() + if not path.is_relative_to(SDK.resolve()) or 'target' in path.parts: + raise ValueError('path leaves SDK source') + else: + path = project_path(name) + lines = path.read_text().splitlines() + first = max(0, min(int(request.get('start', 0)), len(lines))) + return {'text': '\n'.join(lines[first:first + 160])[:16000], 'line_count': len(lines)} + if action == 'write': + files = request.get('files') + if not isinstance(files, dict) or not 1 <= len(files) <= 16: + raise ValueError('write files must be an object of 1..16 path:text entries') + checked = [] + for name, content in files.items(): + if not isinstance(content, str) or len(content.encode()) > 100000: + raise ValueError('each source file is limited to 100000 bytes') + checked.append((project_path(name, write=True), content)) + if sum(len(text.encode()) for _, text in checked) > 500000: + raise ValueError('source write exceeds the batch limit') + for path, content in checked: + path.parent.mkdir(parents=True, exist_ok=True) + if path.is_symlink(): + raise ValueError('symlink output is not permitted') + path.write_text(content) + return {'written': list(files)} + if action != 'run': + raise ValueError('supported actions: list, read, write, run, done') + command = request.get('command') + project = ROOT if request.get('project', '.') == '.' else project_path(request['project']) + if command in ('build', 'test', 'clippy', 'fmt'): + if not (project / 'Cargo.toml').is_file(): + raise ValueError('project needs Cargo.toml') + args = ['/usr/bin/cargo', command, '--manifest-path', str(project / 'Cargo.toml')] + if command != 'fmt': + args += ['--offline'] + else: + args += ['--', '--check'] + if command == 'clippy': + args += ['--all-targets', '--', '-D', 'warnings'] + return run(args, project) + if command == 'launch': + binary = binary_path(project, request.get('binary')) + shot = ROOT / 'evidence' / f'frame-{time.time_ns()}.png' + shot.parent.mkdir(exist_ok=True) + result = run(['xvfb-run', '-a', 'dbus-run-session', '--', '/usr/bin/python3', + '/opt/msdk-bench/capture.py', str(binary), str(shot)], project, 30) + result['frame'] = str(shot.relative_to(ROOT)) if shot.is_file() else None + return result + if MODE != 'sdk': + raise ValueError('SDK commands are not baseline tools') + cli = '/work/target/debug/msdk' + if command == 'describe': + topic = request.get('topic') + return run([cli, 'describe'] + ([str(topic)] if topic else [])) + if command in ('check', 'render', 'gate'): + path = project_path(request.get('path', 'app.ui.json')) + args = [cli, command, str(path)] + if command == 'gate' and 'gates' in request: + args.append(str(project_path(request['gates']))) + return run(args) + if command == 'new': + return run([cli, 'new', str(request.get('template', 'list-detail')), + str(project_path(request.get('path', 'starter')))]) + if command == 'templates': + return run([cli, 'templates']) + if command == 'gen': + return run([cli, 'gen', str(project_path(request.get('path', 'app.ui.json'))), + str(project_path(request.get('output', 'generated'))), '--sdk-root', str(SDK)]) + if command == 'pack': + binary = binary_path(project, request.get('binary')) + package = ROOT / 'evidence' / f'package-{time.time_ns()}.deb' + package.parent.mkdir(exist_ok=True) + result = run([cli, 'pack', str(project), '--binary', str(binary), '--output', str(package)], project) + result['package'] = str(package.relative_to(ROOT)) if package.is_file() else None + return result + raise ValueError('unknown fixed command') + +if __name__ == '__main__': + try: + status = dict(line.split(':', 1) for line in Path('/proc/self/status').read_text().splitlines() if ':' in line) + if (os.geteuid() != 2000 or set(os.listdir('/sys/class/net')) != {'lo'} + or int(status['CapEff'].strip(), 16) or int(status['CapAmb'].strip(), 16)): + raise RuntimeError('benchmark worker requires uid2000, zero effective/ambient capabilities and loopback-only network') + request = json.load(sys.stdin) + if not isinstance(request, dict): + raise ValueError('request must be an object') + print(json.dumps({'ok': True, 'result': execute(request)})) + except Exception as error: + print(json.dumps({'ok': False, 'error': str(error)})) diff --git a/mseries/sdk-status-host/README.md b/mseries/sdk-status-host/README.md new file mode 100644 index 000000000..5c25908d7 --- /dev/null +++ b/mseries/sdk-status-host/README.md @@ -0,0 +1,37 @@ +# SDK usage in the shared desktop status menu + +The optional **Plan usage** page embeds the SDK's aggregate CodexBar snapshot +control in `TaskbarT3RPopover`, the shared source used by the Windows-style Dock +and the unified T3 Wingpanel indicator. Existing Usage, T3 server and GitHub +pages remain intact. The SDK page reads only while selected and the menu is +open; closing or changing pages cancels owned work. Account-specific actions +remain on the existing Usage page. Snapshot coverage is partial. + +This is an opt-in development integration, not an installed or qualified +module. It needs a matching Linux architecture and GTK 4.20 or newer; do not +load it into a desktop with an older GTK. The C ABI and the Vala binding are +provisional and GTK-main-thread only. Never free a handle while its widget is +parented. The page wrapper unparents the control before destruction. + +To prepare an isolated SDK prefix on a compatible Linux test system: + +```sh +python3 mseries/sdk-tests/prepare.py /tmp/msdk-status-sdk +cargo build --manifest-path /tmp/msdk-status-sdk/Cargo.toml -p msdk-gtk --lib +mkdir -p /tmp/msdk-status-prefix/{include,lib} +cp /tmp/msdk-status-sdk/msdk-gtk/include/msdk-usage.h /tmp/msdk-status-prefix/include/ +cp /tmp/msdk-status-sdk/target/debug/libmsdk_gtk.so /tmp/msdk-status-prefix/lib/ +``` + +For an isolated Wingpanel build, configure `mseries/t3-wingpanel` with +`-Dmsdk_prefix=/tmp/msdk-status-prefix`. For an isolated pinned Dock source, +set `MSDK_USAGE_PREFIX=/tmp/msdk-status-prefix` when running +`mseries/dock-taskbar/prepare-source.sh`. These options embed an absolute +runtime library path; use a durable, architecture-matched prefix for any later +packaging. Default builds do not opt in. Neither command deploys, activates, +restarts, or changes the currently running panel. + +The local integration fixture compiles the actual shared menu with synthetic +neighboring indicators and a private CodexBar fixture, testing both hosted and +dock modes. It is not a full Wingpanel/Dock build, a real-account test, a target +desktop interaction, a visual review, or owner acceptance. diff --git a/mseries/sdk-status-host/UsagePage.vala b/mseries/sdk-status-host/UsagePage.vala new file mode 100644 index 000000000..380321cfa --- /dev/null +++ b/mseries/sdk-status-host/UsagePage.vala @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-3.0-only + * SDK usage page for a host-owned popup. The host owns visibility and calls + * opened/closed as its page or popup is selected/dismissed. */ +namespace MSeries { + public class SdkUsagePage : GLib.Object { + private Gtk.Box root; + private Msdk.UsageControl? control; + private Gtk.Label unavailable; + + public SdkUsagePage (string executable) { + root = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + unavailable = new Gtk.Label ("Usage is unavailable") { xalign = 0, wrap = true, visible = false }; + control = new Msdk.UsageControl (executable); + if (control != null) root.append (control.widget ()); + else unavailable.visible = true; + root.append (unavailable); + } + + public unowned Gtk.Widget get_widget () { return root; } + + public void opened () { + if (control != null) unavailable.visible = !control.open (); + } + + public void closed () { + if (control != null) control.close (); + } + + public override void dispose () { + closed (); + if (control != null) { + root.remove (control.widget ()); + control = null; + } + base.dispose (); + } + } +} diff --git a/mseries/sdk-status-host/msdk-usage.vapi b/mseries/sdk-status-host/msdk-usage.vapi new file mode 100644 index 000000000..88e343366 --- /dev/null +++ b/mseries/sdk-status-host/msdk-usage.vapi @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-3.0-only */ +[CCode (cprefix = "Msdk", lower_case_cprefix = "msdk_", cheader_filename = "msdk-usage.h")] +namespace Msdk { + [Compact] + [CCode (cname = "MsdkUsageControl", free_function = "msdk_usage_control_free")] + public class UsageControl { + [CCode (cname = "msdk_usage_control_new")] + public UsageControl (string absolute_executable); + [CCode (cname = "msdk_usage_control_widget")] + public unowned Gtk.Widget widget (); + [CCode (cname = "msdk_usage_control_open")] + public bool open (); + [CCode (cname = "msdk_usage_control_close")] + public void close (); + } +} diff --git a/mseries/sdk-tests/check-schema.py b/mseries/sdk-tests/check-schema.py new file mode 100644 index 000000000..6040762d5 --- /dev/null +++ b/mseries/sdk-tests/check-schema.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +"""Validate real SDK descriptions with an independent Draft 2020-12 validator.""" +import argparse +import copy +import json +from pathlib import Path +import subprocess +import tempfile +import jsonschema + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('--msdk', type=Path, required=True) +parser.add_argument('--rust-root', type=Path, required=True) +args = parser.parse_args() +cli = str(args.msdk.resolve()) +rust = args.rust_root.resolve() +schema = json.loads(subprocess.check_output([cli, 'schema'], text=True)) +jsonschema.Draft202012Validator.check_schema(schema) +validator = jsonschema.Draft202012Validator(schema) +inputs = sorted((rust / 'msdk/templates').glob('*/app.ui.json')) +inputs += sorted((rust / 'msdk/examples').glob('*.ui.json')) +inputs += sorted((rust / 'msdk/examples').glob('*.msdk')) +inputs += [rust / 'mseries-greeter/data/greeter.ui.json', rust / 'claude-pantheon-rs/sdk/t3.msdk'] +inputs = [path for path in inputs if not path.name.startswith('._')] +for path in inputs: + if path.suffix == '.msdk': + doc = json.loads(subprocess.check_output([cli, 'json', str(path)], text=True)) + else: + doc = json.loads(path.read_text()) + errors = list(validator.iter_errors(doc)) + if errors: + raise AssertionError(f'{path}: ' + '\n'.join(f'{list(e.absolute_path)}: {e.message}' for e in errors)) +base = json.loads((rust / 'msdk/templates/settings/app.ui.json').read_text()) +metadata = copy.deepcopy(base) +metadata['app'].update(version='0.1.0', license='GPL-3.0-only', website='https://example.invalid') +validator.validate(metadata) +invalid = [ + {'set': 'enabled'}, + {'toggle': True}, + {'quit': False}, + {'when': 'enabled', 'do': True}, + {'set': 'enabled', 'to': True, 'toggle': 'enabled'}, + {'call': 'process.run', 'args': []}, + {'call': 'process.run', 'args': {'command': 'true'}, 'error': 7}, +] +for action in invalid: + doc = copy.deepcopy(base) + doc['capabilities'].append('subprocess') + doc['update']['SetEnabled'] = [action] + assert list(validator.iter_errors(doc)), f'schema accepted malformed action: {action}' + with tempfile.TemporaryDirectory(prefix='msdk-schema-') as directory: + path = Path(directory) / 'invalid.ui.json' + path.write_text(json.dumps(doc)) + result = subprocess.run([cli, 'check', '--json', str(path)], capture_output=True, text=True) + assert result.returncode != 0, f'checker accepted malformed action: {action}' +print(json.dumps({'valid_descriptions': len(inputs) + 1, 'malformed_actions_rejected_by_both': len(invalid), + 'validator': 'jsonschema.Draft202012Validator'}, indent=2)) diff --git a/mseries/sdk-tests/controls.py b/mseries/sdk-tests/controls.py new file mode 100644 index 000000000..bffc64f38 --- /dev/null +++ b/mseries/sdk-tests/controls.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +"""Exercise the generated settings app with actual keyboard and AT-SPI controls. +Run inside a fresh dbus-run-session/Xvfb, never on the owner's desktop. +""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import subprocess +import tempfile +import time +import pyatspi + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('--binary', type=Path, required=True) +parser.add_argument('--output', type=Path, required=True) +args = parser.parse_args() +assert os.environ.get('MSDK_PRIVATE_TEST_BUS') == '1', 'requires an isolated test session' +assert not args.output.exists(), 'preserve prior receipts; choose a new output' +app_id = 'io.github.techmore.SdkSettings' +report = {'binary_sha256': hashlib.sha256(args.binary.read_bytes()).hexdigest(), + 'environment': 'isolated X11 / private D-Bus / synthetic XDG state', 'checks': []} + +def wait(predicate, message, timeout=8): + end = time.monotonic() + timeout + while time.monotonic() < end: + value = predicate() + if value: + return value + time.sleep(.04) + raise AssertionError(message) + +def walk(node, depth=0): + if depth > 35: + return + yield node + for child in node: + if child is not None: + yield from walk(child, depth + 1) + +def focused(node): + return any(item.getState().contains(pyatspi.STATE_FOCUSED) for item in walk(node)) + +def key(name): + subprocess.run(['xdotool', 'key', '--clearmodifiers', name], check=True) + time.sleep(.05) + +def reach(node): + for _ in range(32): + if focused(node): + return + key('Tab') + raise AssertionError(f'keyboard cannot reach {node.name!r}') + +with tempfile.TemporaryDirectory(prefix='msdk-controls-') as directory: + env = dict(os.environ, XDG_DATA_HOME=directory, XDG_CONFIG_HOME=directory + '/config') + process = subprocess.Popen([str(args.binary.resolve())], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + try: + desktop = pyatspi.Registry.getDesktop(0) + def application(): + status = process.poll() + if status is not None: + raise RuntimeError(f'generated app exited before accessibility registration (exit {status}); see process_stderr') + for app in desktop: + if app.get_process_id() == process.pid: + return app + return None + app = wait(application, 'generated app did not publish an accessibility root') + def target(name): + # A native form exposes both its visible label and its named control. + # Select the interactive accessible, not the preceding static label. + roles = {'Turn on work mode': ('toggle button', 'check box', 'switch'), + 'Schedule': ('combo box',), 'Reset to defaults': ('push button', 'button')} + return wait(lambda: next((item for item in walk(app) if item.name == name and item.getRoleName() in roles[name]), None), + f'missing accessible control {name}') + controls = {name: target(name) for name in ['Turn on work mode', 'Schedule', 'Reset to defaults']} + roles = {name: item.getRoleName() for name, item in controls.items()} + assert roles['Turn on work mode'] in ('toggle button', 'check box', 'switch'), roles + assert roles['Schedule'] == 'combo box', roles + assert roles['Reset to defaults'] in ('push button', 'button'), roles + report['accessible_roles'] = roles + report['checks'].append('live accessible names and roles') + window = subprocess.check_output(['xdotool', 'search', '--sync', '--name', '^SDK Settings$'], text=True, timeout=8).splitlines()[0] + subprocess.run(['xdotool', 'windowfocus', '--sync', window], check=True) + reach(controls['Turn on work mode']) + key('space') + state_path = Path(directory) / app_id / 'state.json' + def read_state(): + return json.loads(state_path.read_text()) if state_path.exists() else {} + wait(lambda: read_state().get('enabled') is False, 'keyboard switch did not save false') + report['checks'].append('Tab reaches switch; Space changes persisted state') + reach(controls['Schedule']) + key('space') + key('Down') + key('Return') + wait(lambda: read_state().get('schedule') == 'Every day', 'keyboard dropdown did not save selection') + report['checks'].append('Tab reaches dropdown; keyboard selection saves') + reach(controls['Reset to defaults']) + key('space') + wait(lambda: read_state().get('enabled') is True and read_state().get('schedule') == 'Weekdays', + 'keyboard reset did not restore settings') + report['checks'].append('Tab reaches reset; Space restores defaults') + key('ctrl+q') + process.wait(timeout=8) + assert process.returncode == 0, process.returncode + report['checks'].append('Ctrl+Q closes cleanly') + report['result'] = 'pass' + except Exception as error: + report['result'] = 'fail' + report['failure'] = str(error) + raise + finally: + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=3) + except subprocess.TimeoutExpired: + process.kill() + process.wait() + stdout, stderr = process.communicate(timeout=3) + # Only this synthetic process's bounded logs are retained. + report['process_stdout'] = stdout.decode(errors='replace')[-8000:] + report['process_stderr'] = stderr.decode(errors='replace')[-8000:] + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(report, indent=2) + '\n') +print(json.dumps(report, indent=2)) diff --git a/mseries/sdk-tests/font-profile.py b/mseries/sdk-tests/font-profile.py new file mode 100644 index 000000000..0b03a0c19 --- /dev/null +++ b/mseries/sdk-tests/font-profile.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +"""Assert the real GTK font configuration used by a private render profile.""" +import os +import gi +gi.require_version('Gtk', '4.0') +from gi.repository import Gtk +Gtk.init() +expected = 'Sans ' + os.environ['MSDK_MATRIX_POINTS'] +actual = Gtk.Settings.get_default().get_property('gtk-font-name') +assert actual == expected, (actual, expected) +print('GTK font profile:', actual) diff --git a/mseries/sdk-tests/home-storage-controls.py b/mseries/sdk-tests/home-storage-controls.py new file mode 100644 index 000000000..370b1c95f --- /dev/null +++ b/mseries/sdk-tests/home-storage-controls.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +"""Actual generated Home Storage keyboard flow; isolated Xvfb/D-Bus only.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import subprocess +import tempfile +import time +import pyatspi + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('--binary', type=Path, required=True) +parser.add_argument('--output', type=Path, required=True) +parser.add_argument('--screenshot', type=Path) +parser.add_argument('--width', type=int, default=900) +parser.add_argument('--config-home', type=Path) +args = parser.parse_args() +assert os.environ.get('MSDK_PRIVATE_TEST_BUS') == '1' +assert not args.output.exists(), 'preserve prior receipts' +binary = args.binary.resolve() +report = {'binary_sha256': hashlib.sha256(binary.read_bytes()).hexdigest(), + 'environment': 'private X11/D-Bus, synthetic HOME/XDG', 'checks': []} + +def wait(predicate, message, timeout=8): + end = time.monotonic() + timeout + while time.monotonic() < end: + value = predicate() + if value: + return value + time.sleep(.03) + raise AssertionError(message) + +def walk(node, depth=0): + if depth > 35: + return + yield node + for child in node: + if child is not None: + yield from walk(child, depth + 1) + +def key(name): + subprocess.run(['xdotool', 'key', '--clearmodifiers', name], check=True) + time.sleep(.04) + +with tempfile.TemporaryDirectory(prefix='msdk-home-controls-') as directory: + # The first real command must fail because this synthetic folder is absent. + # The harness fixes that condition, then retries in the SAME app process. + home = Path(directory) / 'synthetic-home' + config_home = str(args.config_home.resolve()) if args.config_home else directory + '/config' + env = dict(os.environ, HOME=str(home), XDG_DATA_HOME=directory + '/data', + XDG_CONFIG_HOME=config_home, XDG_CACHE_HOME=directory + '/cache') + command = [str(binary)] + if args.screenshot: + assert not args.screenshot.exists() + command += ['--screenshot', str(args.screenshot.resolve())] + process = subprocess.Popen(command, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + try: + desktop = pyatspi.Registry.getDesktop(0) + app = wait(lambda: next((node for node in desktop if node.get_process_id() == process.pid), None), + 'generated app did not publish accessibility root') + def has_text(fragment): + return any(fragment in (node.name or '') for node in walk(app)) + def button(): + return wait(lambda: next((node for node in walk(app) if node.name == 'Check again' + and node.getRoleName() in ('push button', 'button')), None), 'missing Check again button') + window = subprocess.check_output(['xdotool', 'search', '--sync', '--name', '^Home Storage$'], text=True, timeout=8).splitlines()[0] + subprocess.run(['xdotool', 'windowfocus', '--sync', window], check=True) + subprocess.run(['xdotool', 'windowsize', '--sync', window, str(args.width), '400'], check=True) + def activate(): + control = button() + for _ in range(32): + if any(node.getState().contains(pyatspi.STATE_FOCUSED) for node in walk(control)): + key('space') + return + key('Tab') + raise AssertionError('keyboard could not reach Check again') + report['accessible_role'] = button().getRoleName() + activate() + wait(lambda: has_text('Storage could not be checked.'), 'real command failure was not shown') + assert process.poll() is None + button() + report['checks'].append('keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action') + home.mkdir() + activate() + wait(lambda: has_text('Current filesystem usage. No files were changed.'), 'retry did not recover in the same app') + wait(lambda: has_text('Available:') and has_text('Used space:'), 'successful result is missing labeled storage output') + assert not has_text('Storage could not be checked.') + report['checks'].append('keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears') + if args.screenshot: + process.wait(timeout=8) + assert process.returncode == 0 + assert args.screenshot.is_file() and args.screenshot.stat().st_size > 0 + report['checks'].append('actual generated executable captures recovered result and exits cleanly') + else: + key('ctrl+q') + process.wait(timeout=8) + assert process.returncode == 0 + report['checks'].append('Ctrl+Q closes cleanly') + report['result'] = 'pass' + except Exception as error: + report['result'] = 'fail' + report['failure'] = str(error) + raise + finally: + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=3) + except subprocess.TimeoutExpired: + process.kill() + process.wait() + stdout, stderr = process.communicate(timeout=3) + # No filesystem output or home paths enter receipts. Diagnostics must + # omit command data and private backend details even on real failure. + report['stdout_empty'] = not stdout + report['diagnostics_omit_synthetic_home'] = str(home).encode() not in stderr + report['diagnostics'] = stderr.decode(errors='replace')[-8000:] if report['diagnostics_omit_synthetic_home'] else '[private data omitted]' + if not report['diagnostics_omit_synthetic_home']: + report['result'] = 'fail' + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(report, indent=2) + '\n') +assert report['result'] == 'pass', 'diagnostics leaked synthetic home path' +print(json.dumps(report, indent=2)) diff --git a/mseries/sdk-tests/home-storage-matrix.sh b/mseries/sdk-tests/home-storage-matrix.sh new file mode 100644 index 000000000..882aafdd4 --- /dev/null +++ b/mseries/sdk-tests/home-storage-matrix.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Generated reference app: real keyboard failure/retry before native capture. +set -euo pipefail +sdk_home_binary=$(realpath "$1") +sdk_home_output=$2 +sdk_home_probes=$(realpath "$(dirname "$0")") +test ! -e "$sdk_home_output" +mkdir -p "$sdk_home_output" +sdk_home_output=$(realpath "$sdk_home_output") +for sdk_home_theme in light dark; do + sdk_home_gtk_theme=Adwaita + if [ "$sdk_home_theme" = dark ]; then sdk_home_gtk_theme=Adwaita:dark; fi + for sdk_home_points in 10 15; do + for sdk_home_width in 480 900; do + sdk_home_case="$sdk_home_output/$sdk_home_theme-font$sdk_home_points-width$sdk_home_width" + mkdir -p "$sdk_home_case/config/gtk-4.0" + printf '[Settings]\ngtk-font-name=Sans %s\n' "$sdk_home_points" > "$sdk_home_case/config/gtk-4.0/settings.ini" + MSDK_PRIVATE_TEST_BUS=1 MSDK_MATRIX_POINTS="$sdk_home_points" \ + XDG_CONFIG_HOME="$sdk_home_case/config" GTK_THEME="$sdk_home_gtk_theme" GDK_SCALE=1 GSK_RENDERER=cairo \ + xvfb-run -a dbus-run-session -- bash -eu -c ' + python3 "$1/font-profile.py" + python3 "$1/home-storage-controls.py" --binary "$2" --output "$3/controls.json" \ + --screenshot "$3/recovered.png" --width "$4" --config-home "$3/config" + ' sdk-home "$sdk_home_probes" "$sdk_home_binary" "$sdk_home_case" "$sdk_home_width" > "$sdk_home_case/session-output.txt" 2>&1 + done + done +done diff --git a/mseries/sdk-tests/prepare.py b/mseries/sdk-tests/prepare.py new file mode 100644 index 000000000..87519e3ba --- /dev/null +++ b/mseries/sdk-tests/prepare.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +"""Copy only the SDK dependency closure; never resolve the OS/compositor workspace.""" +import argparse +from pathlib import Path +import shutil + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('destination', type=Path) +args = parser.parse_args() +root = Path(__file__).resolve().parents[2] +dest = args.destination.resolve() +dest.mkdir(parents=True, exist_ok=False) +for name in ('msdk', 'msdk-gtk'): + shutil.copytree(root / 'rust' / name, dest / name, + ignore=shutil.ignore_patterns('target', '._*', '.DS_Store')) +for relative in ('mseries-greeter/data/greeter.ui.json', + 'claude-pantheon-rs/sdk', + 'pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml'): + source = root / 'rust' / relative + target = dest / relative + target.parent.mkdir(parents=True, exist_ok=True) + if source.is_dir(): + shutil.copytree(source, target) + else: + shutil.copy2(source, target) +(dest / 'Cargo.toml').write_text('[workspace]\nmembers = ["msdk", "msdk-gtk"]\nresolver = "3"\n') +# Retain the checked-in versions as the starting lock. Cargo may prune unrelated +# OS packages; keep the resulting SDK-only lock as qualification evidence. +shutil.copy2(root / 'rust/Cargo.lock', dest / 'Cargo.lock') +print(dest) diff --git a/mseries/sdk-tests/receipts/2026-10-26-accessibility-failure/README.md b/mseries/sdk-tests/receipts/2026-10-26-accessibility-failure/README.md new file mode 100644 index 000000000..959b9696f --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-accessibility-failure/README.md @@ -0,0 +1,8 @@ +# Accessibility probe failure, 2026-10-26 + +SDK developer-path run 40392328090 attempt 1, commit dbf4eee, failed before +accessibility registration. The retained synthetic process stderr says GTK +failed to open the display. The reason the display was unavailable is unknown. +The same job's attempt 2 passed the complete workflow; this does not prove the +underlying display failure cannot recur. `controls.json` is the original +synthetic test artifact from attempt 1. No owner desktop was involved. diff --git a/mseries/sdk-tests/receipts/2026-10-26-accessibility-failure/controls.json b/mseries/sdk-tests/receipts/2026-10-26-accessibility-failure/controls.json new file mode 100644 index 000000000..f826b1ca9 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-accessibility-failure/controls.json @@ -0,0 +1,9 @@ +{ + "binary_sha256": "d618edc6ff5720271212f8042bfac298e004fbe3dd41c2bdf072c6953cc86e1f", + "environment": "isolated X11 / private D-Bus / synthetic XDG state", + "checks": [], + "result": "fail", + "failure": "generated app did not publish an accessibility root", + "process_stdout": "", + "process_stderr": "\n(msdk-sdksettings:5029): Gtk-WARNING **: 20:06:32.540: Failed to open display\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-cli-macos/Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/Cargo.lock new file mode 100644 index 000000000..ebec75e7d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/Cargo.lock @@ -0,0 +1,137 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde", + "serde_json", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-cli-macos/clippy-output.txt b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/clippy-output.txt new file mode 100644 index 000000000..b9dcb0671 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/clippy-output.txt @@ -0,0 +1 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s diff --git a/mseries/sdk-tests/receipts/2026-10-26-cli-macos/core-test-output.txt b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/core-test-output.txt new file mode 100644 index 000000000..396a0da63 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/core-test-output.txt @@ -0,0 +1,204 @@ + Compiling msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.10s + Running unittests src/lib.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-4ab7f0c78bb642ee) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-c308555b757d7c34) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/agent-ca68a0b395d353a5) + +running 4 tests +test every_diagnostic_code_has_an_explanation ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test completion_knows_values_keys_and_row_fields ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/check-a83ee1f001b74d2d) + +running 22 tests +test feeds_must_match_the_record_shape ... ok +test design_rules ... ok +test custom_component_is_reported_as_a_gap ... ok +test empty_label_and_state_binding_types ... ok +test list_actions_check_the_record ... ok +test enums_capabilities_ids_and_top_level ... ok +test examples_have_no_errors ... ok +test layout_props_validate_and_round_trip ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test missing_and_unknown_properties ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test rust_logic_and_rules_do_not_mix ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test surfaces_validate_their_own_properties ... ok +test unknown_component_suggests_the_nearest ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test services_need_capabilities_and_typed_arguments ... ok +test update_rules_are_type_checked ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/cli_manifests.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/cli_manifests-9f68281e39701226) + +running 4 tests +test checking_no_descriptions_is_not_a_successful_validation ... ok +test missing_explicit_manifest_and_missing_flag_value_are_errors ... ok +test valid_explicit_manifest_supports_check_and_gate_without_positional_confusion ... ok +test invalid_adjacent_manifest_fails_every_consumer_instead_of_printing_success ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.11s + + Running tests/generate.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/generate-5618a8097656d3fa) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.44s + + Running tests/golden_path.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/golden_path-f81c7ab40be84731) + +running 2 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/inspect.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/inspect-50e68ecb8cfe4154) + +running 5 tests +test row_buttons_show_the_key_they_send ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/intents.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/intents-4adbccfe27989abb) + +running 11 tests +test text_errors_name_the_line ... ok +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test the_schema_accepts_an_agent_block ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test t3_declares_a_clean_agent_surface ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/manifests.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/manifests-87777720cf45598d) + +running 8 tests +test malformed_later_declarations_cannot_publish_earlier_services ... ok +test malformed_shapes_unknown_fields_and_duplicate_names_are_rejected ... ok +test identical_reload_is_idempotent_even_when_argument_order_changes ... ok +test feed_shape_conflicts_are_atomic_and_identical_reloads_are_safe ... ok +test concurrent_conflicting_loads_have_one_winner_and_no_partial_publication ... ok +test unsupported_manifest_versions_are_refused_before_registration ... ok +test conflict_does_not_replace_a_contract_or_publish_other_entries ... ok +test incompatible_documents_get_migration_guidance_without_mutation ... ok + +test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/package.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/package-e0cc8be0d5ac9b9b) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/process-78a09449a9d345a2) + +running 7 tests +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test invalid_resource_limits_are_refused ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s + + Running tests/runtime.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/runtime-72e2a74824c12ecf) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/streaming.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/streaming-3ea37e5b715b6e45) + +running 5 tests +test raw_bytes_remain_exact_including_non_utf8_output ... ok +test dropping_subscription_cancels_a_silent_command ... ok +test private_partial_output_arrives_before_completion_and_survives_cancel ... ok +test slow_consumer_has_a_hard_queue_bound_and_a_terminal_failure ... ok +test timeout_keeps_already_queued_partial_output ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s + + Running tests/t3.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/t3-130bd8b0fd4fb4a1) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/templates.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/templates-daeaa23dbb377819) + +running 5 tests +test template_names_are_unique_and_documented ... ok +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test renamed_templates_stay_valid ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/text.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/text-da05419791d24613) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-cli-macos/format-output.txt b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/format-output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mseries/sdk-tests/receipts/2026-10-26-cli-macos/native-syntax-format-output.txt b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/native-syntax-format-output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mseries/sdk-tests/receipts/2026-10-26-cli-macos/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/source-manifest.json new file mode 100644 index 000000000..c49fc7854 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/source-manifest.json @@ -0,0 +1,80 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "e6d578a84f07dd40157bd605cd2e25d8d9f87683aa29350527da0181d2a82315", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "f0b5585d1accb97e77a72413019e391fe2c4dc6529426feaa35d6c02dbe841e3", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/cli.rs": "98435b6c7e22db69e7f260082e5771a26ba5ae07f0e10916dfa62592386f06a6", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "e30aa08c46b9a49a4310ca07b7895f8e44674325a9dfeee0b4068ae3529bdbdc", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "60f096eb8d896259f5a72a09006e471c1ee1d40fcd9329f6e64b42ce1b680e1f", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "e2a8577ccc38a266c31dddec3bd69c0ebec861ca8f40cc8391a21d03299f439c", + "msdk/src/check.rs": "ffd13919cba8026562e2d7e5d8454d3e871794bbe5abfd6034f7392e1ea47529", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "b47b249fd20fbaac4428f78bdf97f97a3a02b4229ebfaccd34e1c8bd8e28ba91", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "491e63fad29fe2e6fc92f816c36cf48a8aad6696a329f6ada1b3e6addfce42a0", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "0280df26ea471982ea98a828b66346bb67790718d60faff4046b5eacf393db2e", + "msdk/src/runtime.rs": "901f1d270158093dd40a797a22df2f5419d76be6569beebbab4546f1ff5e8b53", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "056b9dbcbb35daaffa43a9b8cee905e4a05c37272ebf5df3c5f9f6e458ee9c9d", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/cli_manifests.rs": "379ba88408dfd16e62a423bda643ecdf196d09da74f00f7fed7de6ae8772d9f5", + "msdk/tests/generate.rs": "97857f431ac3657d86438d6038b60f75fe06ad9424c1f855777b8ed4c617d922", + "msdk/tests/golden_path.rs": "fc622e47eb3571fd5217cd1e50bb966209daa364a093990ec265b565791dcc4f", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/manifests.rs": "c6207c7a9c8114c71c8a57c7e941357c42e57d17ae7321863ed5969b2fd2fc71", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "d147a5acac2c721e42a14e188aef1dafd0b6294ed7e177bcee2264c349305a1b", + "msdk/tests/streaming.rs": "462881cd911693787a5babc562f94e59469f21a05e762776a942cf60c029ce85", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-cli-macos/summary.json b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/summary.json new file mode 100644 index 000000000..54bb1fcc3 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-cli-macos/summary.json @@ -0,0 +1,27 @@ +{ + "schema": "msdk.validation.v1", + "source_commit": "050ea0d1bf1693b005d2efd03c51d3a9f8823d16", + "platform": "Darwin arm64", + "rust": "rustc 1.98.1 (48a229cea 2026-09-01) (Homebrew)", + "core_tests_passed": 94, + "cli_test_functions_passed": 4, + "strict_clippy": "passed", + "format": "passed", + "core_scope": [ + "real executable nonzero exits for invalid adjacent manifests across check/render/gate/complete/agent-manifest/gen", + "JSON service-manifest diagnostics", + "generation produces no output after invalid manifest", + "missing explicit manifest path and flag value rejected", + "check with no descriptions fails", + "valid explicit manifest works with check and gate" + ], + "native_scope": "Changed preview error propagation and added private-session CLI regression test; syntax/format checked only, NOT compiled or executed.", + "not_proven": [ + "Linux current source", + "native preview compilation/behavior", + "GTK streaming and stale context adapters", + "physical host qualification", + "whole SDK completion" + ], + "remote_blocker": "Source transfer to SER8 remains pending explicit authorization after automatic approval review rejected that transfer; no retry or bypass." +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-context-macos/Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-context-macos/Cargo.lock new file mode 100644 index 000000000..ebec75e7d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-context-macos/Cargo.lock @@ -0,0 +1,137 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde", + "serde_json", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-context-macos/clippy-output.txt b/mseries/sdk-tests/receipts/2026-10-26-context-macos/clippy-output.txt new file mode 100644 index 000000000..2ab277571 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-context-macos/clippy-output.txt @@ -0,0 +1 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s diff --git a/mseries/sdk-tests/receipts/2026-10-26-context-macos/core-test-output.txt b/mseries/sdk-tests/receipts/2026-10-26-context-macos/core-test-output.txt new file mode 100644 index 000000000..706a9df97 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-context-macos/core-test-output.txt @@ -0,0 +1,215 @@ + Compiling msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 3.43s + Running unittests src/lib.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-4ab7f0c78bb642ee) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-c308555b757d7c34) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/agent-ca68a0b395d353a5) + +running 4 tests +test every_diagnostic_code_has_an_explanation ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok +test completion_knows_values_keys_and_row_fields ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/check.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/check-a83ee1f001b74d2d) + +running 22 tests +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test custom_component_is_reported_as_a_gap ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test feeds_must_match_the_record_shape ... ok +test list_actions_check_the_record ... ok +test empty_label_and_state_binding_types ... ok +test design_rules ... ok +test examples_have_no_errors ... ok +test missing_and_unknown_properties ... ok +test rust_logic_and_rules_do_not_mix ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test enums_capabilities_ids_and_top_level ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test layout_props_validate_and_round_trip ... ok +test unknown_component_suggests_the_nearest ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test surfaces_validate_their_own_properties ... ok +test services_need_capabilities_and_typed_arguments ... ok +test update_rules_are_type_checked ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/cli_manifests.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/cli_manifests-9f68281e39701226) + +running 4 tests +test checking_no_descriptions_is_not_a_successful_validation ... ok +test missing_explicit_manifest_and_missing_flag_value_are_errors ... ok +test valid_explicit_manifest_supports_check_and_gate_without_positional_confusion ... ok +test invalid_adjacent_manifest_fails_every_consumer_instead_of_printing_success ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s + + Running tests/context.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/context-54a13b441f7482a4) + +running 5 tests +test last_owner_drop_and_explicit_close_retire_tokens_without_retaining_the_owner ... ok +test generations_discard_old_success_and_error_values_at_delivery ... ok +test replies_crossing_a_queue_are_checked_after_the_context_switch ... ok +test a_request_in_an_already_closed_context_never_starts_its_command ... ok +test switching_context_cancels_and_reaps_real_work_then_allows_a_new_request ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/generate.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/generate-5618a8097656d3fa) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.73s + + Running tests/golden_path.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/golden_path-f81c7ab40be84731) + +running 2 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/inspect.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/inspect-50e68ecb8cfe4154) + +running 5 tests +test list_rows_resolve_templates_and_carry_their_key ... ok +test row_buttons_show_the_key_they_send ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/intents.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/intents-4adbccfe27989abb) + +running 11 tests +test text_errors_name_the_line ... ok +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test the_schema_accepts_an_agent_block ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test t3_declares_a_clean_agent_surface ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s + + Running tests/manifests.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/manifests-87777720cf45598d) + +running 8 tests +test feed_shape_conflicts_are_atomic_and_identical_reloads_are_safe ... ok +test malformed_later_declarations_cannot_publish_earlier_services ... ok +test identical_reload_is_idempotent_even_when_argument_order_changes ... ok +test malformed_shapes_unknown_fields_and_duplicate_names_are_rejected ... ok +test conflict_does_not_replace_a_contract_or_publish_other_entries ... ok +test unsupported_manifest_versions_are_refused_before_registration ... ok +test concurrent_conflicting_loads_have_one_winner_and_no_partial_publication ... ok +test incompatible_documents_get_migration_guidance_without_mutation ... ok + +test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/package.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/package-e0cc8be0d5ac9b9b) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/process-78a09449a9d345a2) + +running 7 tests +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test invalid_resource_limits_are_refused ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s + + Running tests/runtime.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/runtime-72e2a74824c12ecf) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/streaming.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/streaming-3ea37e5b715b6e45) + +running 5 tests +test raw_bytes_remain_exact_including_non_utf8_output ... ok +test dropping_subscription_cancels_a_silent_command ... ok +test private_partial_output_arrives_before_completion_and_survives_cancel ... ok +test slow_consumer_has_a_hard_queue_bound_and_a_terminal_failure ... ok +test timeout_keeps_already_queued_partial_output ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s + + Running tests/t3.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/t3-130bd8b0fd4fb4a1) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/templates.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/templates-daeaa23dbb377819) + +running 5 tests +test template_names_are_unique_and_documented ... ok +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test renamed_templates_stay_valid ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/text.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/text-da05419791d24613) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-context-macos/format-output.txt b/mseries/sdk-tests/receipts/2026-10-26-context-macos/format-output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mseries/sdk-tests/receipts/2026-10-26-context-macos/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-context-macos/source-manifest.json new file mode 100644 index 000000000..e241666a4 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-context-macos/source-manifest.json @@ -0,0 +1,82 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "e6d578a84f07dd40157bd605cd2e25d8d9f87683aa29350527da0181d2a82315", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "f0b5585d1accb97e77a72413019e391fe2c4dc6529426feaa35d6c02dbe841e3", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/cli.rs": "98435b6c7e22db69e7f260082e5771a26ba5ae07f0e10916dfa62592386f06a6", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "e30aa08c46b9a49a4310ca07b7895f8e44674325a9dfeee0b4068ae3529bdbdc", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "60f096eb8d896259f5a72a09006e471c1ee1d40fcd9329f6e64b42ce1b680e1f", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "e2a8577ccc38a266c31dddec3bd69c0ebec861ca8f40cc8391a21d03299f439c", + "msdk/src/check.rs": "ffd13919cba8026562e2d7e5d8454d3e871794bbe5abfd6034f7392e1ea47529", + "msdk/src/context.rs": "a39bf8c191b68e6dd6c0f55aa471d17ce943479ca4cd6a5b83f6b58f2e00ff98", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "d6a1b238a466d0c18ea551bc4c4456e267ed19d33c0f63f9617aff100f1c1bda", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "491e63fad29fe2e6fc92f816c36cf48a8aad6696a329f6ada1b3e6addfce42a0", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "303d3581d529056bd4f3a2d7f2b0010c98de640a27dcaeebdf716c979cc1ca2e", + "msdk/src/runtime.rs": "89daccd75c90541928da0f7273b5d0d0082e3767d62d414a64d508e8938649ba", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "056b9dbcbb35daaffa43a9b8cee905e4a05c37272ebf5df3c5f9f6e458ee9c9d", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/cli_manifests.rs": "379ba88408dfd16e62a423bda643ecdf196d09da74f00f7fed7de6ae8772d9f5", + "msdk/tests/context.rs": "794ff1f2d691a1873c4a2d5020a4e90a2e5df5690df41d87a1f72fe97a07ee30", + "msdk/tests/generate.rs": "97857f431ac3657d86438d6038b60f75fe06ad9424c1f855777b8ed4c617d922", + "msdk/tests/golden_path.rs": "fc622e47eb3571fd5217cd1e50bb966209daa364a093990ec265b565791dcc4f", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/manifests.rs": "c6207c7a9c8114c71c8a57c7e941357c42e57d17ae7321863ed5969b2fd2fc71", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "62a863bcdf2578351a5445621fd0020c70cd21d740d0f7478756bac7976ce70f", + "msdk/tests/streaming.rs": "462881cd911693787a5babc562f94e59469f21a05e762776a942cf60c029ce85", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-context-macos/summary.json b/mseries/sdk-tests/receipts/2026-10-26-context-macos/summary.json new file mode 100644 index 000000000..7d41d57d1 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-context-macos/summary.json @@ -0,0 +1,31 @@ +{ + "schema": "msdk.validation.v1", + "source_commit": "f4c94cf4480aa7e319c9c4ee3fc0f7be803bbea8", + "platform": "Darwin arm64", + "rust": "rustc 1.98.1 (48a229cea 2026-09-01) (Homebrew)", + "core_tests_passed": 99, + "context_test_functions_passed": 5, + "strict_clippy": "passed", + "format": "passed", + "scope": [ + "queued success/error freshness at final delivery", + "independent and returning account/page generations", + "last context owner drop and permanent close", + "already closed task never executes its command", + "context change stops and reaps a real process; replacement request succeeds", + "full core regression suite" + ], + "limitations": [ + "state application and context changes must be serialized by app on state-owner thread", + "freshness snapshot is not arbitrary cross-thread transaction or side-effect rollback" + ], + "not_proven": [ + "Linux current source", + "GTK ServiceReply context integration", + "scoped streaming chunks", + "T3/network subscription teardown", + "physical host qualification", + "whole SDK completion" + ], + "remote_blocker": "SER8 updated source transfer remains pending explicit authorization after automatic approval review rejection; no retry or bypass." +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-desktop-host-ci/README.md b/mseries/sdk-tests/receipts/2026-10-26-desktop-host-ci/README.md new file mode 100644 index 000000000..36c05bf36 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-desktop-host-ci/README.md @@ -0,0 +1,3 @@ +# Desktop SDK host ARM workflow + +Hosted ARM SDK workflow run 40418084280 at commit 64ca2db passed on attempt 2, including C and Vala SDK boundaries, the shared T3 menu in hosted and dock modes with synthetic neighboring indicators, SDK core/native tests, popup interactions and package install/reinstall/remove. Attempt 1 passed both new host checks but the later usage accessibility fixture failed because GTK could not open its private X display; its synthetic receipt is retained here. The retry was requested once on that evidence. These tests do not build or load the full actual Wingpanel or Dock modules, exercise real accounts, or qualify an elementary desktop. diff --git a/mseries/sdk-tests/receipts/2026-10-26-desktop-host-ci/attempt-1-usage-controls.json b/mseries/sdk-tests/receipts/2026-10-26-desktop-host-ci/attempt-1-usage-controls.json new file mode 100644 index 000000000..a7f511122 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-desktop-host-ci/attempt-1-usage-controls.json @@ -0,0 +1,9 @@ +{ + "binary_sha256": "46c70f6d1cf651910e335dc6c4974c57b806d7b77090bd470a6bfec1f6bf8abe", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "result": "fail", + "failure": "fixture app exited early (1); see process_stderr", + "process_stdout": "", + "process_stderr": "\n(usage_control_interactive:7442): Gtk-WARNING **: 23:14:23.439: Failed to open display\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-desktop-host-local-arm/receipt.json b/mseries/sdk-tests/receipts/2026-10-26-desktop-host-local-arm/receipt.json new file mode 100644 index 000000000..f95cc0c0b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-desktop-host-local-arm/receipt.json @@ -0,0 +1,29 @@ +{ + "environment": "local Colima ARM64 VM, disposable Ubuntu 26.04 container, GTK 4.22.4, Rust 1.93.1, private X11 and D-Bus, synthetic data", + "source_sha256": { + "rust/msdk-gtk/src/usage_ffi.rs": "1321160d79bf251285411855672c3f4e7caaaf48af0768e0809f8c8db0b5c782", + "rust/msdk-gtk/src/usage_control.rs": "5b0fe6296531f4cc7ee51237a9f286dc0940106ce46e723ff2ab7a0575fb529c", + "rust/msdk-gtk/include/msdk-usage.h": "f8f63a7c7557ee8ef8f93b4fcff079b178c7e7b55f373fa2cdb3c79b2d0012aa", + "mseries/sdk-status-host/UsagePage.vala": "efcba8414d8d6279e98a285857ba52bec8e6e92137c8fd68aef5174f069119a5", + "mseries/sdk-status-host/msdk-usage.vapi": "011db5b5fe577fefbddb44eedf3716d944ab1b7447d1348583c098e40477fc29", + "mseries/dock-taskbar/TaskbarT3RPopover.vala": "8730c3e6ffee4483a735321750ce0f9d9e9c022eac7bdee94e30bc0b5136d401", + "mseries/sdk-tests/status-host-integration.vala": "7a0a596935f7ef9556a8ca5ef84dbd435aef26e42f82480245c71c6d2813d78a", + "mseries/sdk-tests/status-host-stubs.vala": "5943501cc901ec39545f18b7686048eba9b5c39920ed3768283f1ca534652f5c", + "mseries/sdk-tests/usage-host-abi.c": "e4d1002164ac80bc4c7ed00e143399612c39951f1baed2c00e8d4aa641117bfc", + "mseries/sdk-tests/usage-vala-host.vala": "6d2dc820857fd55da32b7e1cd7decb97773f009a9929ecbc012055e6c7e59b81" + }, + "checks": [ + "C host constructor, no read until open, bounded synthetic read and teardown", + "Vala page invalid executable and synthetic read lifecycle", + "shared T3 menu in hosted and dock modes with stub neighboring indicators: displays 75% remaining, page switch, no reads after close", + "msdk-gtk strict all-target clippy", + "msdk-gtk lifecycle, runtime, cli, usage and codexbar tests", + "Wingpanel Meson configuration with configure-only stub dependency", + "pinned dock source opt-in preparation" + ], + "limitations": [ + "No actual Wingpanel/Dock module build or installation", + "No elementary target desktop, real accounts, owner visual acceptance or accessibility check", + "Initial C probe failed because gtk-rs was not initialized; corrected before passing run" + ] +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/Cargo.lock new file mode 100644 index 000000000..43432a83d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/Cargo.lock @@ -0,0 +1,736 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde", + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0dae2cbca1f0ff93795713cfe0a4c02f760e3c0b8ae2ab4ec4045808ff429f" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/core-output.txt b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/core-output.txt new file mode 100644 index 000000000..59914e88c --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/core-output.txt @@ -0,0 +1,216 @@ + Compiling msdk v0.1.0 (/work/sdk/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 2.86s + Running unittests src/lib.rs (/work/target/debug/deps/msdk-12198008c2cf28cb) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/work/target/debug/deps/msdk-066bf8c57364aff7) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (/work/target/debug/deps/agent-0a6830a8255e80fe) + +running 4 tests +test completion_knows_values_keys_and_row_fields ... ok +test every_diagnostic_code_has_an_explanation ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (/work/target/debug/deps/check-7eebebae85feff28) + +running 22 tests +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test custom_component_is_reported_as_a_gap ... ok +test design_rules ... ok +test empty_label_and_state_binding_types ... ok +test feeds_must_match_the_record_shape ... ok +test list_actions_check_the_record ... ok +test layout_props_validate_and_round_trip ... ok +test examples_have_no_errors ... ok +test enums_capabilities_ids_and_top_level ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test missing_and_unknown_properties ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test rust_logic_and_rules_do_not_mix ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test services_need_capabilities_and_typed_arguments ... ok +test unknown_component_suggests_the_nearest ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test surfaces_validate_their_own_properties ... ok +test update_rules_are_type_checked ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/cli_manifests.rs (/work/target/debug/deps/cli_manifests-322c3aa3a98a1148) + +running 4 tests +test checking_no_descriptions_is_not_a_successful_validation ... ok +test missing_explicit_manifest_and_missing_flag_value_are_errors ... ok +test valid_explicit_manifest_supports_check_and_gate_without_positional_confusion ... ok +test invalid_adjacent_manifest_fails_every_consumer_instead_of_printing_success ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/context.rs (/work/target/debug/deps/context-fa90d7323a36712b) + +running 5 tests +test generations_discard_old_success_and_error_values_at_delivery ... ok +test last_owner_drop_and_explicit_close_retire_tokens_without_retaining_the_owner ... ok +test a_request_in_an_already_closed_context_never_starts_its_command ... ok +test replies_crossing_a_queue_are_checked_after_the_context_switch ... ok +test switching_context_cancels_and_reaps_real_work_then_allows_a_new_request ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/generate.rs (/work/target/debug/deps/generate-342ff3ce236eb69e) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.42s + + Running tests/golden_path.rs (/work/target/debug/deps/golden_path-487cd2efabbb362d) + +running 3 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test unsupported_storage_report_is_an_error_instead_of_invented_usage ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/inspect.rs (/work/target/debug/deps/inspect-93cd5613381dab2e) + +running 5 tests +test row_buttons_show_the_key_they_send ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/intents.rs (/work/target/debug/deps/intents-2a628da1cf662166) + +running 11 tests +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test t3_declares_a_clean_agent_surface ... ok +test text_errors_name_the_line ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test the_schema_accepts_an_agent_block ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/manifests.rs (/work/target/debug/deps/manifests-ed628cea56fae293) + +running 8 tests +test identical_reload_is_idempotent_even_when_argument_order_changes ... ok +test feed_shape_conflicts_are_atomic_and_identical_reloads_are_safe ... ok +test conflict_does_not_replace_a_contract_or_publish_other_entries ... ok +test concurrent_conflicting_loads_have_one_winner_and_no_partial_publication ... ok +test incompatible_documents_get_migration_guidance_without_mutation ... ok +test malformed_later_declarations_cannot_publish_earlier_services ... ok +test malformed_shapes_unknown_fields_and_duplicate_names_are_rejected ... ok +test unsupported_manifest_versions_are_refused_before_registration ... ok + +test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/package.rs (/work/target/debug/deps/package-049f1c780ec04a4a) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (/work/target/debug/deps/process-8eea9a1dc405af26) + +running 7 tests +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test invalid_resource_limits_are_refused ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s + + Running tests/runtime.rs (/work/target/debug/deps/runtime-5a113640c1865c5d) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/streaming.rs (/work/target/debug/deps/streaming-7df403091fac5be3) + +running 5 tests +test slow_consumer_has_a_hard_queue_bound_and_a_terminal_failure ... ok +test raw_bytes_remain_exact_including_non_utf8_output ... ok +test dropping_subscription_cancels_a_silent_command ... ok +test private_partial_output_arrives_before_completion_and_survives_cancel ... ok +test timeout_keeps_already_queued_partial_output ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s + + Running tests/t3.rs (/work/target/debug/deps/t3-27cedfaa232b366e) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/templates.rs (/work/target/debug/deps/templates-a50c0d65b47f7b22) + +running 5 tests +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test template_names_are_unique_and_documented ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test renamed_templates_stay_valid ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/text.rs (/work/target/debug/deps/text-e0d1463a25e6cd86) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-clippy-output.txt b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-clippy-output.txt new file mode 100644 index 000000000..f244f75b6 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-clippy-output.txt @@ -0,0 +1 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-core-output.txt b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-core-output.txt new file mode 100644 index 000000000..97dacf865 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-core-output.txt @@ -0,0 +1,216 @@ + Compiling msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 2.21s + Running unittests src/lib.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-4ab7f0c78bb642ee) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-c308555b757d7c34) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/agent.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/agent-ca68a0b395d353a5) + +running 4 tests +test every_diagnostic_code_has_an_explanation ... ok +test completion_knows_values_keys_and_row_fields ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/check-a83ee1f001b74d2d) + +running 22 tests +test feeds_must_match_the_record_shape ... ok +test custom_component_is_reported_as_a_gap ... ok +test design_rules ... ok +test empty_label_and_state_binding_types ... ok +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test list_actions_check_the_record ... ok +test examples_have_no_errors ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test missing_and_unknown_properties ... ok +test enums_capabilities_ids_and_top_level ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test layout_props_validate_and_round_trip ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test rust_logic_and_rules_do_not_mix ... ok +test unknown_component_suggests_the_nearest ... ok +test surfaces_validate_their_own_properties ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test services_need_capabilities_and_typed_arguments ... ok +test update_rules_are_type_checked ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/cli_manifests.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/cli_manifests-9f68281e39701226) + +running 4 tests +test checking_no_descriptions_is_not_a_successful_validation ... ok +test missing_explicit_manifest_and_missing_flag_value_are_errors ... ok +test valid_explicit_manifest_supports_check_and_gate_without_positional_confusion ... ok +test invalid_adjacent_manifest_fails_every_consumer_instead_of_printing_success ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s + + Running tests/context.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/context-54a13b441f7482a4) + +running 5 tests +test last_owner_drop_and_explicit_close_retire_tokens_without_retaining_the_owner ... ok +test generations_discard_old_success_and_error_values_at_delivery ... ok +test replies_crossing_a_queue_are_checked_after_the_context_switch ... ok +test a_request_in_an_already_closed_context_never_starts_its_command ... ok +test switching_context_cancels_and_reaps_real_work_then_allows_a_new_request ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/generate.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/generate-5618a8097656d3fa) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.52s + + Running tests/golden_path.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/golden_path-f81c7ab40be84731) + +running 3 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test unsupported_storage_report_is_an_error_instead_of_invented_usage ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/inspect.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/inspect-50e68ecb8cfe4154) + +running 5 tests +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test row_buttons_show_the_key_they_send ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/intents.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/intents-4adbccfe27989abb) + +running 11 tests +test text_errors_name_the_line ... ok +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test the_schema_accepts_an_agent_block ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test t3_declares_a_clean_agent_surface ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s + + Running tests/manifests.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/manifests-87777720cf45598d) + +running 8 tests +test conflict_does_not_replace_a_contract_or_publish_other_entries ... ok +test identical_reload_is_idempotent_even_when_argument_order_changes ... ok +test malformed_later_declarations_cannot_publish_earlier_services ... ok +test malformed_shapes_unknown_fields_and_duplicate_names_are_rejected ... ok +test feed_shape_conflicts_are_atomic_and_identical_reloads_are_safe ... ok +test concurrent_conflicting_loads_have_one_winner_and_no_partial_publication ... ok +test unsupported_manifest_versions_are_refused_before_registration ... ok +test incompatible_documents_get_migration_guidance_without_mutation ... ok + +test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/package.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/package-e0cc8be0d5ac9b9b) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/process-78a09449a9d345a2) + +running 7 tests +test invalid_resource_limits_are_refused ... ok +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s + + Running tests/runtime.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/runtime-72e2a74824c12ecf) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/streaming.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/streaming-3ea37e5b715b6e45) + +running 5 tests +test raw_bytes_remain_exact_including_non_utf8_output ... ok +test slow_consumer_has_a_hard_queue_bound_and_a_terminal_failure ... ok +test dropping_subscription_cancels_a_silent_command ... ok +test private_partial_output_arrives_before_completion_and_survives_cancel ... ok +test timeout_keeps_already_queued_partial_output ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s + + Running tests/t3.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/t3-130bd8b0fd4fb4a1) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/templates.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/templates-daeaa23dbb377819) + +running 5 tests +test template_names_are_unique_and_documented ... ok +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test renamed_templates_stay_valid ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/text.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/text-da05419791d24613) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-format-output.txt b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/macos-format-output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/native-clippy-output.txt b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/native-clippy-output.txt new file mode 100644 index 000000000..0a387baf3 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/native-clippy-output.txt @@ -0,0 +1,2 @@ + Checking msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.58s diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/native-output.txt b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/native-output.txt new file mode 100644 index 000000000..4e92e5586 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/native-output.txt @@ -0,0 +1,39 @@ + Compiling msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 2.78s + Running tests/cli.rs (/work/target/debug/deps/cli-5db54b2f9201811d) + +running 1 test +test preview_failures_have_nonzero_exit_status ... dbus-daemon[32604]: [session uid=0 pid=32604 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=33257 comm="/work/target/debug/msdk-run app.ui.json --screensh" label="unconfined") +dbus-daemon[32604]: [session uid=0 pid=32604 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[33281]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=33257 comm="/work/target/debug/msdk-run app.ui.json --screensh" label="unconfined") +dbus-daemon[33281]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.99s + + Running tests/lifecycle.rs (/work/target/debug/deps/lifecycle-01d81c06c6abf4a4) + +running 1 test +test closing_stops_owned_work_ignores_late_events_and_releases_the_host ... libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.77s + + Running tests/runtime.rs (/work/target/debug/deps/runtime-e3443b0d433d1ad6) + +running 1 test +test extension_mismatch_recovers_and_closed_hosts_kill_owned_commands ... libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +{"schema":"msdk.runtime.diagnostic.v1","code":"service-version-mismatch","service":"process.run","source":"/update/Run","operation":1,"expected_version":1,"actual_version":2,"message":"The app and service use incompatible APIs. Update them and retry."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-unavailable","service":"sdktest.absent","source":"/update/Run","operation":1,"expected_version":null,"actual_version":null,"message":"This service is unavailable. Check its installation and retry."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-malformed-data","service":"process.run","source":"/update/Run","operation":1,"expected_version":null,"actual_version":null,"message":"The service returned invalid data. Retry or update the service."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-permission-denied","service":"process.run","source":"/update/Run","operation":2,"expected_version":null,"actual_version":null,"message":"Access was denied. Check the service permissions and retry."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-io-failure","service":"process.run","source":"/update/Run","operation":6,"expected_version":null,"actual_version":null,"message":"The operation could not read or write its data. Retry the operation."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-unavailable","service":"process.run","source":"/update/Run","operation":10,"expected_version":null,"actual_version":null,"message":"This service is unavailable. Check its installation and retry."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-unavailable","service":"process.run","source":"/update/Run","operation":1,"expected_version":null,"actual_version":null,"message":"This service is unavailable. Check its installation and retry."} +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/runtime-discovery.json b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/runtime-discovery.json new file mode 100644 index 000000000..b3a6edf64 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/runtime-discovery.json @@ -0,0 +1,87 @@ +{ + "runtime": "msdk", + "rust_package_version": "0.1.0", + "app_description_format": 1, + "service_manifest_format": 1, + "extension_api_version": 1, + "diagnostic_schema": "msdk.runtime.diagnostic.v1", + "typed_failure": "msdk::runtime::ServiceFailure", + "request_context": { + "owner": "msdk::context::RequestContext", + "token": "ContextToken", + "delivery": "Scoped::into_current on the state-owner thread", + "process_api": "msdk::process::spawn_scoped", + "gtk_adapter_automatic": false, + "gtk_typed_reply": "msdk_gtk::host::ServiceReply::in_context", + "streaming_automatic": false + }, + "failure_codes": [ + { + "code": "service-unavailable", + "recovery": "This service is unavailable. Check its installation and retry." + }, + { + "code": "service-version-mismatch", + "recovery": "The app and service use incompatible APIs. Update them and retry." + }, + { + "code": "service-permission-denied", + "recovery": "Access was denied. Check the service permissions and retry." + }, + { + "code": "service-invalid-input", + "recovery": "The operation has invalid inputs. Correct them and retry." + }, + { + "code": "service-malformed-data", + "recovery": "The service returned invalid data. Retry or update the service." + }, + { + "code": "service-io-failure", + "recovery": "The operation could not read or write its data. Retry the operation." + }, + { + "code": "process-failed", + "recovery": "The command failed. Check its output and retry." + }, + { + "code": "process-timeout", + "recovery": "The command exceeded its time limit and was stopped. Retry when ready." + }, + { + "code": "process-output-limit", + "recovery": "The command exceeded its output limit and was stopped." + }, + { + "code": "service-cancelled", + "recovery": "The operation was cancelled." + }, + { + "code": "service-busy", + "recovery": "Too many operations are running. Wait for one to finish and retry." + } + ], + "extension_negotiation": "Services::api_version is checked before calls/feeds; backend OS/network protocols require their own published contract", + "process": { + "rust_api": "msdk::process::{spawn, Limits}", + "description_service": "process.run", + "default_timeout_ms": 120000, + "default_combined_output_bytes": 1048576, + "host_max_concurrent": 4, + "owned_handle_drop": "cancel same-group work and reap leader", + "streaming": false, + "rust_streaming": { + "api": "msdk::process::spawn_streaming", + "queue_chunks": 32, + "max_chunk_bytes": 8192, + "backpressure": "stop with process-output-limit", + "drop_subscription": "cancel owned command", + "partial_output": "already received or queued raw bytes survive terminal failure" + }, + "privileged_or_daemon_jobs": "use an OS-owned service adapter" + }, + "privacy": { + "diagnostic_payloads": false, + "private_ui_detail": "ServiceFailure::detail()" + } +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/source-manifest.json new file mode 100644 index 000000000..1fb3de97e --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/source-manifest.json @@ -0,0 +1,82 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "4ad376777fab148090633819ce0bb7817f6e1e61784829e580af0b1e61076af6", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "f0b5585d1accb97e77a72413019e391fe2c4dc6529426feaa35d6c02dbe841e3", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/cli.rs": "98435b6c7e22db69e7f260082e5771a26ba5ae07f0e10916dfa62592386f06a6", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "93355516029dd19fc79cbe6c0b25c075c03be2aed2e935ac436118d3b9520f14", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "ddc77b65438dea97f8155f74d7b02419dd1a5f73aae92824c1227f4d223e7f2a", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "e2a8577ccc38a266c31dddec3bd69c0ebec861ca8f40cc8391a21d03299f439c", + "msdk/src/check.rs": "ffd13919cba8026562e2d7e5d8454d3e871794bbe5abfd6034f7392e1ea47529", + "msdk/src/context.rs": "a39bf8c191b68e6dd6c0f55aa471d17ce943479ca4cd6a5b83f6b58f2e00ff98", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "d6a1b238a466d0c18ea551bc4c4456e267ed19d33c0f63f9617aff100f1c1bda", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "491e63fad29fe2e6fc92f816c36cf48a8aad6696a329f6ada1b3e6addfce42a0", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "303d3581d529056bd4f3a2d7f2b0010c98de640a27dcaeebdf716c979cc1ca2e", + "msdk/src/runtime.rs": "c14f11c22d23c8f16ccf5c8ba4bb3f937d21e434bd677bccfa191c1381cab2cd", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "056b9dbcbb35daaffa43a9b8cee905e4a05c37272ebf5df3c5f9f6e458ee9c9d", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/cli_manifests.rs": "379ba88408dfd16e62a423bda643ecdf196d09da74f00f7fed7de6ae8772d9f5", + "msdk/tests/context.rs": "794ff1f2d691a1873c4a2d5020a4e90a2e5df5690df41d87a1f72fe97a07ee30", + "msdk/tests/generate.rs": "97857f431ac3657d86438d6038b60f75fe06ad9424c1f855777b8ed4c617d922", + "msdk/tests/golden_path.rs": "b7bef19bf55957c30498937b491664863291bd0c5800319452fdeb384adad714", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/manifests.rs": "c6207c7a9c8114c71c8a57c7e941357c42e57d17ae7321863ed5969b2fd2fc71", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "69b8f439ffe7b6acda821a76d4199e416245914204f5a5c4b677c7225967f48b", + "msdk/tests/streaming.rs": "462881cd911693787a5babc562f94e59469f21a05e762776a942cf60c029ce85", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-gtk-context/summary.json b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/summary.json new file mode 100644 index 000000000..49dd82221 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-gtk-context/summary.json @@ -0,0 +1,36 @@ +{ + "schema": "msdk.validation.v1", + "source_commit": "6b7c5058c3d23cfee771da97c8ef66f2f9335c64", + "source_files_matched": 80, + "environment": "isolated Ubuntu26.04 x86_64 Rust1.93.1 GTK4.22.4 private Xvfb/D-Bus, synthetic app state", + "core_tests_passed_linux": 100, + "core_tests_passed_macos": 100, + "native_suites_passed": 3, + "strict_core_native_clippy": "passed", + "typed_gtk_context_cases": [ + "obsolete queued success and error ignored", + "context binding shared with Host clone for synchronous invoke Err", + "context retained through additional queued error callback", + "rebinding rejected", + "current recovery updates actual visible GTK labels", + "bound then declined request cannot execute real unscoped fallback", + "provider stop retires context and Host releases despite retained reply clones" + ], + "prior_arm_pass": { + "head_sha": "7a5f4d27deeabf6334ba9c3d441e39eb0374ed3a", + "developer_path_run": 40375089386, + "developer_path_job": 121755848259, + "sdk_system_monitor_run": 40375089841, + "conclusion": "success", + "scope": "completed prior foundation; newer GTK context source still needs current CI" + }, + "not_proven": [ + "automatic scope for legacy/built-in/pre-invoke negotiation/feed/streaming/T3 adapters", + "real backend version/account/read lifecycle qualification", + "current ARM context code until new CI completes", + "reusable status module and both hosts", + "controlled model/novice trials and performance", + "physical Pantheon/M-series/scale/owner acceptance", + "whole SDK completion" + ] +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/Cargo.lock new file mode 100644 index 000000000..ebec75e7d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/Cargo.lock @@ -0,0 +1,137 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde", + "serde_json", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/clippy-output.txt b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/clippy-output.txt new file mode 100644 index 000000000..2ab277571 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/clippy-output.txt @@ -0,0 +1 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s diff --git a/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/core-test-output.txt b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/core-test-output.txt new file mode 100644 index 000000000..52d110d6f --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/core-test-output.txt @@ -0,0 +1,194 @@ + Compiling msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.80s + Running unittests src/lib.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-4ab7f0c78bb642ee) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-c308555b757d7c34) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/agent-ca68a0b395d353a5) + +running 4 tests +test every_diagnostic_code_has_an_explanation ... ok +test completion_knows_values_keys_and_row_fields ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/check-a83ee1f001b74d2d) + +running 22 tests +test feeds_must_match_the_record_shape ... ok +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test design_rules ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test custom_component_is_reported_as_a_gap ... ok +test layout_props_validate_and_round_trip ... ok +test empty_label_and_state_binding_types ... ok +test list_actions_check_the_record ... ok +test examples_have_no_errors ... ok +test enums_capabilities_ids_and_top_level ... ok +test missing_and_unknown_properties ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test rust_logic_and_rules_do_not_mix ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test unknown_component_suggests_the_nearest ... ok +test services_need_capabilities_and_typed_arguments ... ok +test surfaces_validate_their_own_properties ... ok +test update_rules_are_type_checked ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/generate.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/generate-5618a8097656d3fa) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.49s + + Running tests/golden_path.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/golden_path-f81c7ab40be84731) + +running 2 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s + + Running tests/inspect.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/inspect-50e68ecb8cfe4154) + +running 5 tests +test row_buttons_show_the_key_they_send ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/intents.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/intents-4adbccfe27989abb) + +running 11 tests +test text_errors_name_the_line ... ok +test the_schema_accepts_an_agent_block ... ok +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test t3_declares_a_clean_agent_surface ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/manifests.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/manifests-87777720cf45598d) + +running 8 tests +test malformed_later_declarations_cannot_publish_earlier_services ... ok +test identical_reload_is_idempotent_even_when_argument_order_changes ... ok +test malformed_shapes_unknown_fields_and_duplicate_names_are_rejected ... ok +test concurrent_conflicting_loads_have_one_winner_and_no_partial_publication ... ok +test conflict_does_not_replace_a_contract_or_publish_other_entries ... ok +test unsupported_manifest_versions_are_refused_before_registration ... ok +test feed_shape_conflicts_are_atomic_and_identical_reloads_are_safe ... ok +test incompatible_documents_get_migration_guidance_without_mutation ... ok + +test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/package.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/package-e0cc8be0d5ac9b9b) + +running 3 tests +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok +test package_architecture_comes_from_the_binary_not_the_build_host ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/process-78a09449a9d345a2) + +running 7 tests +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test invalid_resource_limits_are_refused ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s + + Running tests/runtime.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/runtime-72e2a74824c12ecf) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/streaming.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/streaming-3ea37e5b715b6e45) + +running 5 tests +test raw_bytes_remain_exact_including_non_utf8_output ... ok +test slow_consumer_has_a_hard_queue_bound_and_a_terminal_failure ... ok +test dropping_subscription_cancels_a_silent_command ... ok +test private_partial_output_arrives_before_completion_and_survives_cancel ... ok +test timeout_keeps_already_queued_partial_output ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s + + Running tests/t3.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/t3-130bd8b0fd4fb4a1) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/templates.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/templates-daeaa23dbb377819) + +running 5 tests +test template_names_are_unique_and_documented ... ok +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test renamed_templates_stay_valid ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/text.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/text-da05419791d24613) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/failures/generator-scratch-collision-output.txt b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/failures/generator-scratch-collision-output.txt new file mode 100644 index 000000000..c9490f1b1 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/failures/generator-scratch-collision-output.txt @@ -0,0 +1,75 @@ + Compiling msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.46s + Running unittests src/lib.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-4ab7f0c78bb642ee) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/msdk-c308555b757d7c34) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/agent-ca68a0b395d353a5) + +running 4 tests +test completion_knows_values_keys_and_row_fields ... ok +test every_diagnostic_code_has_an_explanation ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/check-a83ee1f001b74d2d) + +running 22 tests +test feeds_must_match_the_record_shape ... ok +test custom_component_is_reported_as_a_gap ... ok +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test design_rules ... ok +test empty_label_and_state_binding_types ... ok +test list_actions_check_the_record ... ok +test rust_logic_and_rules_do_not_mix ... ok +test examples_have_no_errors ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test enums_capabilities_ids_and_top_level ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test layout_props_validate_and_round_trip ... ok +test missing_and_unknown_properties ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test unknown_component_suggests_the_nearest ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test surfaces_validate_their_own_properties ... ok +test services_need_capabilities_and_typed_arguments ... ok +test update_rules_are_type_checked ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/generate.rs (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk/target/debug/deps/generate-5618a8097656d3fa) + +running 3 tests +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... FAILED +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +failures: + +---- projects_are_complete_deterministic_and_never_overwrite_existing_files stdout ---- + +thread 'projects_are_complete_deterministic_and_never_overwrite_existing_files' (468574) panicked at tests/generate.rs:12:36: +called `Result::unwrap()` on an `Err` value: Os { code: 17, kind: AlreadyExists, message: "File exists" } +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + projects_are_complete_deterministic_and_never_overwrite_existing_files + +test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.04s + +error: test failed, to rerun pass `--test generate` diff --git a/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/format-output.txt b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/format-output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/source-manifest.json new file mode 100644 index 000000000..a4d0924bf --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/source-manifest.json @@ -0,0 +1,78 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "e6d578a84f07dd40157bd605cd2e25d8d9f87683aa29350527da0181d2a82315", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "eaa3f1c506168cce35c227747bbf9e00bfd5b86ce67bfd24fddc39e31739fb1a", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "e30aa08c46b9a49a4310ca07b7895f8e44674325a9dfeee0b4068ae3529bdbdc", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "60f096eb8d896259f5a72a09006e471c1ee1d40fcd9329f6e64b42ce1b680e1f", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "13813de669f087df51d4421d035f0d07ba66c1935f931092b43305740f093a79", + "msdk/src/check.rs": "ffd13919cba8026562e2d7e5d8454d3e871794bbe5abfd6034f7392e1ea47529", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "b47b249fd20fbaac4428f78bdf97f97a3a02b4229ebfaccd34e1c8bd8e28ba91", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "93bd6eec5d6bcecda6df66b6ac3742adfbb023da47c748bd1249a9923d77767e", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "0280df26ea471982ea98a828b66346bb67790718d60faff4046b5eacf393db2e", + "msdk/src/runtime.rs": "901f1d270158093dd40a797a22df2f5419d76be6569beebbab4546f1ff5e8b53", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "056b9dbcbb35daaffa43a9b8cee905e4a05c37272ebf5df3c5f9f6e458ee9c9d", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/generate.rs": "97857f431ac3657d86438d6038b60f75fe06ad9424c1f855777b8ed4c617d922", + "msdk/tests/golden_path.rs": "fc622e47eb3571fd5217cd1e50bb966209daa364a093990ec265b565791dcc4f", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/manifests.rs": "c6207c7a9c8114c71c8a57c7e941357c42e57d17ae7321863ed5969b2fd2fc71", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "d147a5acac2c721e42a14e188aef1dafd0b6294ed7e177bcee2264c349305a1b", + "msdk/tests/streaming.rs": "462881cd911693787a5babc562f94e59469f21a05e762776a942cf60c029ce85", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/summary.json b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/summary.json new file mode 100644 index 000000000..d88439b91 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-manifests-macos/summary.json @@ -0,0 +1,27 @@ +{ + "schema": "msdk.validation.v1", + "source_commit": "467729942f4f51e6ce766e8a4617cc531af7037a", + "platform": "Darwin arm64", + "rust": "rustc 1.98.1 (48a229cea 2026-09-01) (Homebrew)", + "core_tests_passed": 90, + "manifest_tests_passed": 8, + "strict_clippy": "passed", + "format": "passed", + "scope": [ + "atomic full-manifest validation and conflict rollback", + "concurrent conflicting loaders", + "idempotent service/feed reloads independent of object order", + "legacy manifest compatibility and explicit unsupported version rejection", + "incompatible document rejection and migration guidance", + "complete core regression suite" + ], + "retained_failure": "Generator-test simultaneous timestamp scratch collision; repaired exclusive-create retry and atomic serial. Original failure retained.", + "not_proven": [ + "Linux current source", + "GTK adapter qualification", + "real backend protocol negotiation", + "physical supported-host matrix", + "whole SDK completion" + ], + "remote_blocker": "Explicit authorization for updated SDK source transfer to SER8 still pending; automatic approval review rejected prior transfer and no bypass used." +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/artifacts.sha256 b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/artifacts.sha256 new file mode 100644 index 000000000..3f847de35 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/artifacts.sha256 @@ -0,0 +1,2 @@ +74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464 /work/target/debug/msdk-homestorage +d01aa58ba3a3b560c696806a788fd4772e206687ffd84241190bc19f0caf166e /work/home-storage-readable.deb diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/environment.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/environment.txt new file mode 100644 index 000000000..1f51751dd --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/environment.txt @@ -0,0 +1,2 @@ +rustc 1.93.1 (01f6ddf75 2026-02-11) (built from a source tarball) +4.22.4 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/README.md b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/README.md new file mode 100644 index 000000000..951875c13 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/README.md @@ -0,0 +1 @@ +The earlier Home Storage raw df table wrapped its header at larger text and lost column association. These actual generated-app captures were rejected. Qualified source f4c94cf / earlier binary 6442d16df25cb60c0c88403e8da6aaed12c9b18737dc44b3f11530866be268e1; repaired labeled values are in matrix/. A later probe transfer hit an existing-file permission error before any tests started; a fresh probe path preserved old evidence and the final run resumed. The initial approval block was resolved with owner-machine context and identity evidence accepted by automatic review. diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/dark-font15-width480-raw-table.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/dark-font15-width480-raw-table.png new file mode 100644 index 000000000..bf02a98bd Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/dark-font15-width480-raw-table.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/light-font15-width480-raw-table.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/light-font15-width480-raw-table.png new file mode 100644 index 000000000..da895538d Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/failures/light-font15-width480-raw-table.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/Cargo.lock new file mode 100644 index 000000000..bdccbdd5b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/Cargo.lock @@ -0,0 +1,746 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e055fa6e3e40ad6187ba25b6855eeb635d5271f8e0f0e1e9a5826b8d75bea0" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "msdk-homestorage" +version = "0.1.0" +dependencies = [ + "gtk4", + "msdk", + "msdk-gtk", + "serde", + "serde_json", +] + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db551ad38aac61d5e0343e0eeeb0163be3115c4e23b6a025959570ee0c03c67d" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/Cargo.toml b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/Cargo.toml new file mode 100644 index 000000000..bc0268697 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "msdk-homestorage" +version = "0.1.0" +license = "GPL-3.0-only" +edition = "2024" +publish = false + +[workspace] + +[lib] +name = "app_model" + +[dependencies] +msdk = { path = "/work/sdk/msdk" } +msdk-gtk = { path = "/work/sdk/msdk-gtk" } +gtk = { package = "gtk4", version = "0.11", features = ["v4_20"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/LICENSE b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/LICENSE new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/README.md b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/README.md new file mode 100644 index 000000000..e71d4f417 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/README.md @@ -0,0 +1,25 @@ +# Home Storage + +Generated by `msdk gen`; SDK format 1. + +On a supported Linux GTK 4.20+ development host, with Rust 2024, pkg-config, +GTK development headers, Wayland development headers and wayland-scanner installed: + +```sh +cargo build +cargo test +cargo run +``` + +`src/lib.rs` exposes typed records, `State`, `Message::into_event` and the embedded +description. Edit `app.ui.json` for views/rules, or use a new output directory to +regenerate models after changing types. Keep the SDK checkout at `/work/sdk`; +the generated project uses explicit local dependencies and its own Cargo workspace. + +The executable runs the real GTK Host with the description's update rules and +built-in services. Custom services/feeds require an app-local `Services` adapter +and `Host::open_with`; generation does not implement those backends. Panel +placement requires the documented Pantheon shell protocol and target-host tests. +Build/launch success is separate from visual, accessibility, service, packaging +and installed desktop acceptance. No install or background service is performed +by generation. diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/app.ui.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/app.ui.json new file mode 100644 index 000000000..6af888108 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/app.ui.json @@ -0,0 +1,150 @@ +{ + "sdk": 1, + "app": { + "id": "io.github.techmore.HomeStorage", + "name": "Home Storage", + "icon": "drive-harddisk" + }, + "capabilities": [ + "subprocess" + ], + "state": { + "ready": "bool", + "busy": "bool", + "failed": "bool", + "status": "text", + "result": "text" + }, + "initial": { + "ready": true, + "busy": false, + "failed": false, + "status": "Check available space on the filesystem containing your home folder.", + "result": "" + }, + "messages": { + "Refresh": "none", + "Loaded": "text", + "Failed": "text" + }, + "update": { + "Refresh": [ + { + "when": "ready", + "do": [ + { + "set": "ready", + "to": false + }, + { + "set": "busy", + "to": true + }, + { + "set": "failed", + "to": false + }, + { + "set": "result", + "to": "" + }, + { + "set": "status", + "to": "Checking home storage…" + }, + { + "call": "process.run", + "args": { + "command": "report=$(LC_ALL=C df -Pk \"${HOME:?Home folder is unavailable}\") || exit\nprintf '%s\\n' \"$report\" | awk 'NR==2 && NF==6 && $2 ~ /^[0-9]+$/ && $3 ~ /^[0-9]+$/ && $4 ~ /^-?[0-9]+$/ && $5 ~ /^[0-9]+%$/ { printf \"Available: %.1f MiB\\nUsed: %.1f MiB\\nTotal: %.1f MiB\\nUsed space: %s\\n\", $4/1024, $3/1024, $2/1024, $5; ok=1 } END { if (!ok || NR!=2) { print \"Storage report format is unavailable\" > \"/dev/stderr\"; exit 1 } }'" + }, + "then": "Loaded", + "error": "Failed" + } + ] + } + ], + "Loaded": [ + { + "set": "result", + "to": "$payload" + }, + { + "set": "status", + "to": "Current filesystem usage. No files were changed." + }, + { + "set": "busy", + "to": false + }, + { + "set": "ready", + "to": true + }, + { + "set": "failed", + "to": false + } + ], + "Failed": [ + { + "set": "result", + "to": "$payload" + }, + { + "set": "status", + "to": "Storage could not be checked. Review the error and try again." + }, + { + "set": "busy", + "to": false + }, + { + "set": "ready", + "to": true + }, + { + "set": "failed", + "to": true + } + ] + }, + "surfaces": { + "main": { + "kind": "window", + "title": "Home Storage", + "body": { + "type": "Box", + "direction": "column", + "spacing": "large", + "children": [ + { + "type": "Text", + "text": "Home storage", + "text_style": "title" + }, + { + "type": "Text", + "text": "{status}" + }, + { + "type": "Text", + "text": "{result}" + }, + { + "type": "Button", + "label": "Check again", + "on": "Refresh", + "visible_if": "ready", + "button_style": "suggested" + }, + { + "type": "Text", + "text": "You can close this window to cancel the check.", + "visible_if": "busy", + "text_style": "muted" + } + ] + } + } + } +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/assets/icon.svg b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/assets/icon.svg new file mode 100644 index 000000000..964e6a0ca --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/assets/icon.svg @@ -0,0 +1 @@ + diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/src/lib.rs b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/src/lib.rs new file mode 100644 index 000000000..3134fc8aa --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/src/lib.rs @@ -0,0 +1,54 @@ +// Generated by msdk gen. Edit the description and regenerate in a new directory. +#![allow(non_snake_case, non_camel_case_types)] +pub mod records { +} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct State { + #[serde(rename = "ready")] + pub r#ready: bool, + #[serde(rename = "busy")] + pub r#busy: bool, + #[serde(rename = "failed")] + pub r#failed: bool, + #[serde(rename = "status")] + pub r#status: String, + #[serde(rename = "result")] + pub r#result: String, +} +impl State { + pub fn initial() -> Result { + Self::from_store(msdk::logic::initial_store(&document())) + } + pub fn from_store(store: msdk::logic::Store) -> Result { + serde_json::from_value(serde_json::Value::Object(store)) + } + pub fn into_store(self) -> Result { + match serde_json::to_value(self)? { + serde_json::Value::Object(store) => Ok(store), + _ => unreachable!("State serializes as an object"), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub enum Message { + r#Refresh, + r#Loaded(String), + r#Failed(String), +} +impl Message { + pub fn into_event(self) -> (String, Option) { + match self { + Self::r#Refresh => ("Refresh".into(), None), + Self::r#Loaded(value) => ("Loaded".into(), Some(serde_json::json!(value))), + Self::r#Failed(value) => ("Failed".into(), Some(serde_json::json!(value))), + } + } +} + +/// The checked description embedded in this application. +pub fn document() -> serde_json::Value { + static REGISTER: std::sync::OnceLock<()> = std::sync::OnceLock::new(); + REGISTER.get_or_init(|| { + }); + serde_json::from_str(include_str!("../app.ui.json")).expect("generated checked description") +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/src/main.rs b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/src/main.rs new file mode 100644 index 000000000..969e02ec9 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/src/main.rs @@ -0,0 +1,60 @@ +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +use gtk::prelude::*; + +fn main() -> gtk::glib::ExitCode { + // Screenshot mode is an explicit developer check. Normal activation keeps + // the stable app ID and presents the existing window. + let args: Vec<_> = std::env::args().skip(1).collect(); + let shot = match args.as_slice() { + [] => None, + [flag, path] if flag == "--screenshot" => Some(std::path::PathBuf::from(path)), + _ => { + eprintln!("usage: application [--screenshot output.png]"); + return gtk::glib::ExitCode::from(2); + } + }; + let app = gtk::Application::builder() + .application_id("io.github.techmore.HomeStorage") + .build(); + let quit = gtk::gio::SimpleAction::new("quit", None); + let weak = app.downgrade(); + quit.connect_activate(move |_, _| { + if let Some(app) = weak.upgrade() { + for window in app.windows() { window.close(); } + } + }); + app.add_action(&quit); + app.set_accels_for_action("app.quit", &["q"]); + let keep = RefCell::new(None::>); + let failed = Rc::new(Cell::new(false)); + let failure = failed.clone(); + app.connect_activate(move |app| { + if let Some(host) = keep.borrow().as_ref() { + host.window().present(); + return; + } + let Some(host) = msdk_gtk::host::Host::open_doc( + app, app_model::document(), None, "main", None, false, + ) else { + failure.set(true); + app.quit(); + return; + }; + if let Some(path) = shot.clone() { + let (host, app, failure) = (host.clone(), app.clone(), failure.clone()); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(800), move || { + if let Err(error) = host.screenshot(&path) { + eprintln!("screenshot failed: {error}"); + failure.set(true); + } + host.window().close(); + app.quit(); + }); + } + *keep.borrow_mut() = Some(host); + }); + let status = app.run_with_args::<&str>(&[]); + if failed.get() { gtk::glib::ExitCode::FAILURE } else { status } +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/tests/model.rs b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/tests/model.rs new file mode 100644 index 000000000..716fbaff6 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/generated/tests/model.rs @@ -0,0 +1,6 @@ +#[test] +fn initial_state_round_trips() { + let state = app_model::State::initial().expect("typed initial state"); + let store = state.clone().into_store().unwrap(); + assert_eq!(app_model::State::from_store(store).unwrap(), state); +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/installed.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/installed.png new file mode 100644 index 000000000..e4911d767 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/installed.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..283f39430 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 10 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/recovered.png new file mode 100644 index 000000000..259b45475 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/session-output.txt new file mode 100644 index 000000000..5b782303b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width480/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +dbus-daemon[28034]: [session uid=0 pid=28034 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=28051 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28034]: [session uid=0 pid=28034 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[28062]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=28051 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28062]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..283f39430 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 10 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/recovered.png new file mode 100644 index 000000000..f3802039d Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/session-output.txt new file mode 100644 index 000000000..971be6ec2 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font10-width900/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +dbus-daemon[28121]: [session uid=0 pid=28121 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=28138 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28121]: [session uid=0 pid=28121 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[28149]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=28138 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28149]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..431c7fa26 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 15 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/recovered.png new file mode 100644 index 000000000..16e1d4567 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/session-output.txt new file mode 100644 index 000000000..2cde347d0 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width480/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +dbus-daemon[28208]: [session uid=0 pid=28208 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=28225 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28208]: [session uid=0 pid=28208 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[28236]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=28225 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28236]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..431c7fa26 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 15 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/recovered.png new file mode 100644 index 000000000..dd156fd8c Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/session-output.txt new file mode 100644 index 000000000..bcc014c29 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/dark-font15-width900/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +dbus-daemon[28293]: [session uid=0 pid=28293 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=28310 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28293]: [session uid=0 pid=28293 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[28321]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=28310 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[28321]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..283f39430 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 10 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/recovered.png new file mode 100644 index 000000000..5e708258a Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/session-output.txt new file mode 100644 index 000000000..17b82f193 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width480/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +dbus-daemon[27685]: [session uid=0 pid=27685 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=27702 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27685]: [session uid=0 pid=27685 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[27713]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=27702 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27713]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..283f39430 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 10 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/recovered.png new file mode 100644 index 000000000..8ebc04c32 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/session-output.txt new file mode 100644 index 000000000..54a02f329 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font10-width900/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +dbus-daemon[27772]: [session uid=0 pid=27772 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=27789 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27772]: [session uid=0 pid=27772 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[27800]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=27789 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27800]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..431c7fa26 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 15 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/recovered.png new file mode 100644 index 000000000..2beb9995f Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/session-output.txt new file mode 100644 index 000000000..4600affc2 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width480/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +dbus-daemon[27860]: [session uid=0 pid=27860 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=27877 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27860]: [session uid=0 pid=27860 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[27888]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=27877 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27888]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/config/gtk-4.0/settings.ini b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/config/gtk-4.0/settings.ini new file mode 100644 index 000000000..431c7fa26 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-font-name=Sans 15 diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/controls.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/controls.json new file mode 100644 index 000000000..ee7b5fabe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/recovered.png b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/recovered.png new file mode 100644 index 000000000..b7cfdbadf Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/recovered.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/session-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/session-output.txt new file mode 100644 index 000000000..014375aab --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/matrix/light-font15-width900/session-output.txt @@ -0,0 +1,22 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +dbus-daemon[27947]: [session uid=0 pid=27947 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=27964 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27947]: [session uid=0 pid=27947 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[27975]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=27964 comm="python3 /work/home-probes-readable/home-storage-co" label="unconfined") +dbus-daemon[27975]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "environment": "private X11/D-Bus, synthetic HOME/XDG", + "checks": [ + "keyboard starts actual df; absent synthetic HOME gives recoverable error and retry action", + "keyboard retry after harness creates synthetic HOME succeeds in same process; stale error disappears", + "actual generated executable captures recovered result and exits cleanly" + ], + "accessible_role": "button", + "result": "pass", + "stdout_empty": true, + "diagnostics_omit_synthetic_home": true, + "diagnostics": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n{\"schema\":\"msdk.runtime.diagnostic.v1\",\"code\":\"process-failed\",\"service\":\"process.run\",\"source\":\"/update/Refresh\",\"operation\":1,\"expected_version\":null,\"actual_version\":null,\"message\":\"The command failed. Check its output and retry.\"}\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-build-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-build-output.txt new file mode 100644 index 000000000..f244f75b6 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-build-output.txt @@ -0,0 +1 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-lint-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-lint-output.txt new file mode 100644 index 000000000..72035fefc --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-lint-output.txt @@ -0,0 +1,2 @@ + Checking msdk-homestorage v0.1.0 (/work/home-storage-readable) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.23s diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-test-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-test-output.txt new file mode 100644 index 000000000..0ae5c27cd --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-app-test-output.txt @@ -0,0 +1,29 @@ + Updating crates.io index + Locking 74 packages to latest Rust 1.93.1 compatible versions + Compiling msdk-homestorage v0.1.0 (/work/home-storage-readable) + Finished `test` profile [unoptimized + debuginfo] target(s) in 2.37s + Running unittests src/lib.rs (/work/target/debug/deps/app_model-45d230d310ab3eff) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/work/target/debug/deps/msdk_homestorage-d91d493118fbcd30) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/model.rs (/work/target/debug/deps/model-727ece104873bd21) + +running 1 test +test initial_state_round_trips ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests app_model + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-core-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-core-output.txt new file mode 100644 index 000000000..5a64f1492 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-core-output.txt @@ -0,0 +1,216 @@ + Compiling msdk v0.1.0 (/work/sdk/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.65s + Running unittests src/lib.rs (/work/target/debug/deps/msdk-12198008c2cf28cb) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/work/target/debug/deps/msdk-066bf8c57364aff7) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (/work/target/debug/deps/agent-0a6830a8255e80fe) + +running 4 tests +test completion_knows_values_keys_and_row_fields ... ok +test every_diagnostic_code_has_an_explanation ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (/work/target/debug/deps/check-7eebebae85feff28) + +running 22 tests +test design_rules ... ok +test custom_component_is_reported_as_a_gap ... ok +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test empty_label_and_state_binding_types ... ok +test feeds_must_match_the_record_shape ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test enums_capabilities_ids_and_top_level ... ok +test examples_have_no_errors ... ok +test layout_props_validate_and_round_trip ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test missing_and_unknown_properties ... ok +test list_actions_check_the_record ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test rust_logic_and_rules_do_not_mix ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok +test unknown_component_suggests_the_nearest ... ok +test surfaces_validate_their_own_properties ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test services_need_capabilities_and_typed_arguments ... ok +test update_rules_are_type_checked ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/cli_manifests.rs (/work/target/debug/deps/cli_manifests-322c3aa3a98a1148) + +running 4 tests +test checking_no_descriptions_is_not_a_successful_validation ... ok +test missing_explicit_manifest_and_missing_flag_value_are_errors ... ok +test valid_explicit_manifest_supports_check_and_gate_without_positional_confusion ... ok +test invalid_adjacent_manifest_fails_every_consumer_instead_of_printing_success ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/context.rs (/work/target/debug/deps/context-fa90d7323a36712b) + +running 5 tests +test generations_discard_old_success_and_error_values_at_delivery ... ok +test last_owner_drop_and_explicit_close_retire_tokens_without_retaining_the_owner ... ok +test a_request_in_an_already_closed_context_never_starts_its_command ... ok +test replies_crossing_a_queue_are_checked_after_the_context_switch ... ok +test switching_context_cancels_and_reaps_real_work_then_allows_a_new_request ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/generate.rs (/work/target/debug/deps/generate-342ff3ce236eb69e) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.97s + + Running tests/golden_path.rs (/work/target/debug/deps/golden_path-487cd2efabbb362d) + +running 3 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test unsupported_storage_report_is_an_error_instead_of_invented_usage ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/inspect.rs (/work/target/debug/deps/inspect-93cd5613381dab2e) + +running 5 tests +test row_buttons_show_the_key_they_send ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/intents.rs (/work/target/debug/deps/intents-2a628da1cf662166) + +running 11 tests +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test text_errors_name_the_line ... ok +test t3_declares_a_clean_agent_surface ... ok +test the_schema_accepts_an_agent_block ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/manifests.rs (/work/target/debug/deps/manifests-ed628cea56fae293) + +running 8 tests +test identical_reload_is_idempotent_even_when_argument_order_changes ... ok +test feed_shape_conflicts_are_atomic_and_identical_reloads_are_safe ... ok +test conflict_does_not_replace_a_contract_or_publish_other_entries ... ok +test concurrent_conflicting_loads_have_one_winner_and_no_partial_publication ... ok +test malformed_later_declarations_cannot_publish_earlier_services ... ok +test malformed_shapes_unknown_fields_and_duplicate_names_are_rejected ... ok +test unsupported_manifest_versions_are_refused_before_registration ... ok +test incompatible_documents_get_migration_guidance_without_mutation ... ok + +test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/package.rs (/work/target/debug/deps/package-049f1c780ec04a4a) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (/work/target/debug/deps/process-8eea9a1dc405af26) + +running 7 tests +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test invalid_resource_limits_are_refused ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s + + Running tests/runtime.rs (/work/target/debug/deps/runtime-5a113640c1865c5d) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/streaming.rs (/work/target/debug/deps/streaming-7df403091fac5be3) + +running 5 tests +test slow_consumer_has_a_hard_queue_bound_and_a_terminal_failure ... ok +test raw_bytes_remain_exact_including_non_utf8_output ... ok +test private_partial_output_arrives_before_completion_and_survives_cancel ... ok +test dropping_subscription_cancels_a_silent_command ... ok +test timeout_keeps_already_queued_partial_output ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s + + Running tests/t3.rs (/work/target/debug/deps/t3-27cedfaa232b366e) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/templates.rs (/work/target/debug/deps/templates-a50c0d65b47f7b22) + +running 5 tests +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test template_names_are_unique_and_documented ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test renamed_templates_stay_valid ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/text.rs (/work/target/debug/deps/text-e0d1463a25e6cd86) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-generate-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-generate-output.txt new file mode 100644 index 000000000..4ccc077f1 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-generate-output.txt @@ -0,0 +1 @@ +created standalone Cargo application in /work/home-storage-readable; next: cargo run --manifest-path /work/home-storage-readable/Cargo.toml diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-matrix-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-matrix-output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-native-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-native-output.txt new file mode 100644 index 000000000..11fb45852 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-native-output.txt @@ -0,0 +1,37 @@ + Compiling msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.28s + Running tests/cli.rs (/work/target/debug/deps/cli-5db54b2f9201811d) + +running 1 test +test preview_failures_have_nonzero_exit_status ... dbus-daemon[27247]: [session uid=0 pid=27247 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=27361 comm="/work/target/debug/msdk-run app.ui.json --screensh" label="unconfined") +dbus-daemon[27247]: [session uid=0 pid=27247 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[27385]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=27361 comm="/work/target/debug/msdk-run app.ui.json --screensh" label="unconfined") +dbus-daemon[27385]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.99s + + Running tests/lifecycle.rs (/work/target/debug/deps/lifecycle-01d81c06c6abf4a4) + +running 1 test +test closing_stops_owned_work_ignores_late_events_and_releases_the_host ... libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.77s + + Running tests/runtime.rs (/work/target/debug/deps/runtime-e3443b0d433d1ad6) + +running 1 test +test extension_mismatch_recovers_and_closed_hosts_kill_owned_commands ... libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +{"schema":"msdk.runtime.diagnostic.v1","code":"service-version-mismatch","service":"process.run","source":"/update/Run","operation":1,"expected_version":1,"actual_version":2,"message":"The app and service use incompatible APIs. Update them and retry."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-unavailable","service":"sdktest.absent","source":"/update/Run","operation":1,"expected_version":null,"actual_version":null,"message":"This service is unavailable. Check its installation and retry."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-malformed-data","service":"process.run","source":"/update/Run","operation":1,"expected_version":null,"actual_version":null,"message":"The service returned invalid data. Retry or update the service."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-permission-denied","service":"process.run","source":"/update/Run","operation":2,"expected_version":null,"actual_version":null,"message":"Access was denied. Check the service permissions and retry."} +{"schema":"msdk.runtime.diagnostic.v1","code":"service-unavailable","service":"process.run","source":"/update/Run","operation":1,"expected_version":null,"actual_version":null,"message":"This service is unavailable. Check its installation and retry."} +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-package-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-package-output.txt new file mode 100644 index 000000000..e7980517d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-package-output.txt @@ -0,0 +1,42 @@ +created /work/home-storage-readable.deb; no installation performed +Selecting previously unselected package msdk-io.github.techmore.homestorage. +(Reading database ... 34691 files and directories currently installed.) +Preparing to unpack .../work/home-storage-readable.deb ... +Unpacking msdk-io.github.techmore.homestorage (0.1.0) ... +Setting up msdk-io.github.techmore.homestorage (0.1.0) ... +Processing triggers for desktop-file-utils (0.28-1build1) ... +Processing triggers for hicolor-icon-theme (0.18-2build1) ... +(Reading database ... 34697 files and directories currently installed.) +Preparing to unpack .../work/home-storage-readable.deb ... +Unpacking msdk-io.github.techmore.homestorage (0.1.0) over (0.1.0) ... +Setting up msdk-io.github.techmore.homestorage (0.1.0) ... +Processing triggers for desktop-file-utils (0.28-1build1) ... +Processing triggers for hicolor-icon-theme (0.18-2build1) ... +/. +/usr +/usr/bin +/usr/bin/io.github.techmore.HomeStorage +/usr/share +/usr/share/applications +/usr/share/applications/io.github.techmore.HomeStorage.desktop +/usr/share/doc +/usr/share/doc/msdk-io.github.techmore.homestorage +/usr/share/doc/msdk-io.github.techmore.homestorage/copyright +/usr/share/icons +/usr/share/icons/hicolor +/usr/share/icons/hicolor/scalable +/usr/share/icons/hicolor/scalable/apps +/usr/share/icons/hicolor/scalable/apps/io.github.techmore.HomeStorage.svg +/usr/share/metainfo +/usr/share/metainfo/io.github.techmore.HomeStorage.metainfo.xml +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[28445]: [session uid=0 pid=28445 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.0' (uid=0 pid=28446 comm="/usr/bin/io.github.techmore.HomeStorage --screensh" label="unconfined") +dbus-daemon[28445]: [session uid=0 pid=28445 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[28468]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=28446 comm="/usr/bin/io.github.techmore.HomeStorage --screensh" label="unconfined") +dbus-daemon[28468]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +(Reading database ... 34694 files and directories currently installed.) +Removing msdk-io.github.techmore.homestorage (0.1.0) ... +Processing triggers for hicolor-icon-theme (0.18-2build1) ... +Processing triggers for desktop-file-utils (0.28-1build1) ... diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-sdk-lint-output.txt b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-sdk-lint-output.txt new file mode 100644 index 000000000..9daf5959b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/msdk-readable-sdk-lint-output.txt @@ -0,0 +1,3 @@ + Checking msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Checking msdk v0.1.0 (/work/sdk/msdk) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/qa-source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/qa-source-manifest.json new file mode 100644 index 000000000..0beeedb65 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/qa-source-manifest.json @@ -0,0 +1,5 @@ +{ + "mseries/sdk-tests/home-storage-controls.py": "a98d9e56eb4dadbf357528ea516e5beee5c9202c756b91c271f07b1c66ad56a6", + "mseries/sdk-tests/home-storage-matrix.sh": "1141970ddfed326ab3edcad3335c9a99cded4a5b6bdad2b6183dbf917bab5242", + "mseries/sdk-tests/font-profile.py": "0a7910365b44226f39abac2a747d664c0ad95821dbd113ec0f85d383a0899019" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/runtime-discovery.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/runtime-discovery.json new file mode 100644 index 000000000..d3196dea0 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/runtime-discovery.json @@ -0,0 +1,86 @@ +{ + "runtime": "msdk", + "rust_package_version": "0.1.0", + "app_description_format": 1, + "service_manifest_format": 1, + "extension_api_version": 1, + "diagnostic_schema": "msdk.runtime.diagnostic.v1", + "typed_failure": "msdk::runtime::ServiceFailure", + "request_context": { + "owner": "msdk::context::RequestContext", + "token": "ContextToken", + "delivery": "Scoped::into_current on the state-owner thread", + "process_api": "msdk::process::spawn_scoped", + "gtk_adapter_automatic": false, + "streaming_automatic": false + }, + "failure_codes": [ + { + "code": "service-unavailable", + "recovery": "This service is unavailable. Check its installation and retry." + }, + { + "code": "service-version-mismatch", + "recovery": "The app and service use incompatible APIs. Update them and retry." + }, + { + "code": "service-permission-denied", + "recovery": "Access was denied. Check the service permissions and retry." + }, + { + "code": "service-invalid-input", + "recovery": "The operation has invalid inputs. Correct them and retry." + }, + { + "code": "service-malformed-data", + "recovery": "The service returned invalid data. Retry or update the service." + }, + { + "code": "service-io-failure", + "recovery": "The operation could not read or write its data. Retry the operation." + }, + { + "code": "process-failed", + "recovery": "The command failed. Check its output and retry." + }, + { + "code": "process-timeout", + "recovery": "The command exceeded its time limit and was stopped. Retry when ready." + }, + { + "code": "process-output-limit", + "recovery": "The command exceeded its output limit and was stopped." + }, + { + "code": "service-cancelled", + "recovery": "The operation was cancelled." + }, + { + "code": "service-busy", + "recovery": "Too many operations are running. Wait for one to finish and retry." + } + ], + "extension_negotiation": "Services::api_version is checked before calls/feeds; backend OS/network protocols require their own published contract", + "process": { + "rust_api": "msdk::process::{spawn, Limits}", + "description_service": "process.run", + "default_timeout_ms": 120000, + "default_combined_output_bytes": 1048576, + "host_max_concurrent": 4, + "owned_handle_drop": "cancel same-group work and reap leader", + "streaming": false, + "rust_streaming": { + "api": "msdk::process::spawn_streaming", + "queue_chunks": 32, + "max_chunk_bytes": 8192, + "backpressure": "stop with process-output-limit", + "drop_subscription": "cancel owned command", + "partial_output": "already received or queued raw bytes survive terminal failure" + }, + "privileged_or_daemon_jobs": "use an OS-owned service adapter" + }, + "privacy": { + "diagnostic_payloads": false, + "private_ui_detail": "ServiceFailure::detail()" + } +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/sdk-Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/sdk-Cargo.lock new file mode 100644 index 000000000..43432a83d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/sdk-Cargo.lock @@ -0,0 +1,736 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde", + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0dae2cbca1f0ff93795713cfe0a4c02f760e3c0b8ae2ab4ec4045808ff429f" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/source-manifest.json new file mode 100644 index 000000000..a30b8323c --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/source-manifest.json @@ -0,0 +1,82 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "e6d578a84f07dd40157bd605cd2e25d8d9f87683aa29350527da0181d2a82315", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "f0b5585d1accb97e77a72413019e391fe2c4dc6529426feaa35d6c02dbe841e3", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/cli.rs": "98435b6c7e22db69e7f260082e5771a26ba5ae07f0e10916dfa62592386f06a6", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "e30aa08c46b9a49a4310ca07b7895f8e44674325a9dfeee0b4068ae3529bdbdc", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "ddc77b65438dea97f8155f74d7b02419dd1a5f73aae92824c1227f4d223e7f2a", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "e2a8577ccc38a266c31dddec3bd69c0ebec861ca8f40cc8391a21d03299f439c", + "msdk/src/check.rs": "ffd13919cba8026562e2d7e5d8454d3e871794bbe5abfd6034f7392e1ea47529", + "msdk/src/context.rs": "a39bf8c191b68e6dd6c0f55aa471d17ce943479ca4cd6a5b83f6b58f2e00ff98", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "d6a1b238a466d0c18ea551bc4c4456e267ed19d33c0f63f9617aff100f1c1bda", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "491e63fad29fe2e6fc92f816c36cf48a8aad6696a329f6ada1b3e6addfce42a0", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "303d3581d529056bd4f3a2d7f2b0010c98de640a27dcaeebdf716c979cc1ca2e", + "msdk/src/runtime.rs": "89daccd75c90541928da0f7273b5d0d0082e3767d62d414a64d508e8938649ba", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "056b9dbcbb35daaffa43a9b8cee905e4a05c37272ebf5df3c5f9f6e458ee9c9d", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/cli_manifests.rs": "379ba88408dfd16e62a423bda643ecdf196d09da74f00f7fed7de6ae8772d9f5", + "msdk/tests/context.rs": "794ff1f2d691a1873c4a2d5020a4e90a2e5df5690df41d87a1f72fe97a07ee30", + "msdk/tests/generate.rs": "97857f431ac3657d86438d6038b60f75fe06ad9424c1f855777b8ed4c617d922", + "msdk/tests/golden_path.rs": "b7bef19bf55957c30498937b491664863291bd0c5800319452fdeb384adad714", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/manifests.rs": "c6207c7a9c8114c71c8a57c7e941357c42e57d17ae7321863ed5969b2fd2fc71", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "62a863bcdf2578351a5445621fd0020c70cd21d740d0f7478756bac7976ce70f", + "msdk/tests/streaming.rs": "462881cd911693787a5babc562f94e59469f21a05e762776a942cf60c029ce85", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/summary.json b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/summary.json new file mode 100644 index 000000000..45a3a72e7 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-native-runtime-reference/summary.json @@ -0,0 +1,45 @@ +{ + "schema": "msdk.validation.v1", + "source_commit": "cb77b663cb25b15f3828a58eecf351bcab30e0cb", + "source_files_matched": 80, + "environment": "existing ephemeral Ubuntu 26.04 x86_64 container on verified owner SER8; Rust 1.93.1; GTK 4.22.4; private Xvfb/D-Bus; synthetic HOME/XDG", + "core_tests_passed": 100, + "native_suites_passed": [ + "CLI nonzero failure exits", + "actual D-Bus/Host lifecycle", + "typed asynchronous service errors/recovery/fixture no fallback/owned command close" + ], + "sdk_strict_clippy": "passed", + "generated_app": { + "model_tests": 1, + "build": "passed", + "strict_clippy": "passed", + "keyboard_accessibility": "actual read-only command failure for absent synthetic HOME; same-process keyboard retry after harness creates it; Ctrl+Q separately passed", + "reviewed_screenshots": 8, + "profiles": "Adwaita light/dark, requested widths480/900, asserted Sans10/15; recovered result captured", + "binary_sha256": "74b64bfb42c5a65a65e924e5d6ea49438f8e9f11471ce115f388798af40fb464", + "package_sha256": "d01aa58ba3a3b560c696806a788fd4772e206687ffd84241190bc19f0caf166e", + "package_checks": [ + "metadata/native dependency resolution", + "fresh install", + "reinstall", + "installed executable equals tested binary", + "installed launch/capture", + "remove all five owned artifact classes" + ] + }, + "prior_failures_retained": [ + "larger-text raw table readability rejected then replaced with labeled validated values", + "existing probe-file overwrite denied before tests; fresh probe path preserved evidence" + ], + "approval_status": "prior SER8 source-transfer block resolved with owner trust evidence; automatic review accepted scoped transfer", + "not_proven": [ + "current ARM source (CI pending)", + "GTK context/streaming adapter and real backend protocol qualification", + "reusable status module and both hosts", + "measured novice/exact-model trials", + "performance", + "physical Pantheon/M-series/scale/owner acceptance", + "whole SDK completion" + ] +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/Cargo.lock new file mode 100644 index 000000000..ebec75e7d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/Cargo.lock @@ -0,0 +1,137 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde", + "serde_json", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/clippy-output.txt b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/clippy-output.txt new file mode 100644 index 000000000..ce43e2b7a --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/clippy-output.txt @@ -0,0 +1 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.11s diff --git a/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/core-test-output.txt b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/core-test-output.txt new file mode 100644 index 000000000..e10e09d69 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/core-test-output.txt @@ -0,0 +1,169 @@ + Compiling msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.36s + Running unittests src/lib.rs (msdk-check/msdk/target/debug/deps/msdk-4ab7f0c78bb642ee) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (msdk-check/msdk/target/debug/deps/msdk-c308555b757d7c34) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (msdk-check/msdk/target/debug/deps/agent-ca68a0b395d353a5) + +running 4 tests +test completion_knows_values_keys_and_row_fields ... ok +test every_diagnostic_code_has_an_explanation ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (msdk-check/msdk/target/debug/deps/check-a83ee1f001b74d2d) + +running 22 tests +test custom_component_is_reported_as_a_gap ... ok +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test empty_label_and_state_binding_types ... ok +test feeds_must_match_the_record_shape ... ok +test design_rules ... ok +test examples_have_no_errors ... ok +test enums_capabilities_ids_and_top_level ... ok +test list_actions_check_the_record ... ok +test layout_props_validate_and_round_trip ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test missing_and_unknown_properties ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test rust_logic_and_rules_do_not_mix ... ok +test unknown_component_suggests_the_nearest ... ok +test surfaces_validate_their_own_properties ... ok +test services_need_capabilities_and_typed_arguments ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test update_rules_are_type_checked ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/generate.rs (msdk-check/msdk/target/debug/deps/generate-5618a8097656d3fa) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.08s + + Running tests/golden_path.rs (msdk-check/msdk/target/debug/deps/golden_path-f81c7ab40be84731) + +running 2 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/inspect.rs (msdk-check/msdk/target/debug/deps/inspect-50e68ecb8cfe4154) + +running 5 tests +test row_buttons_show_the_key_they_send ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/intents.rs (msdk-check/msdk/target/debug/deps/intents-4adbccfe27989abb) + +running 11 tests +test text_errors_name_the_line ... ok +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test the_schema_accepts_an_agent_block ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test t3_declares_a_clean_agent_surface ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/package.rs (msdk-check/msdk/target/debug/deps/package-e0cc8be0d5ac9b9b) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (msdk-check/msdk/target/debug/deps/process-78a09449a9d345a2) + +running 7 tests +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test invalid_resource_limits_are_refused ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s + + Running tests/runtime.rs (msdk-check/msdk/target/debug/deps/runtime-72e2a74824c12ecf) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/t3.rs (msdk-check/msdk/target/debug/deps/t3-130bd8b0fd4fb4a1) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/templates.rs (msdk-check/msdk/target/debug/deps/templates-daeaa23dbb377819) + +running 5 tests +test template_names_are_unique_and_documented ... ok +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test renamed_templates_stay_valid ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/text.rs (msdk-check/msdk/target/debug/deps/text-da05419791d24613) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/source-manifest.json new file mode 100644 index 000000000..85c4fd96e --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/source-manifest.json @@ -0,0 +1,76 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "e6d578a84f07dd40157bd605cd2e25d8d9f87683aa29350527da0181d2a82315", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "eaa3f1c506168cce35c227747bbf9e00bfd5b86ce67bfd24fddc39e31739fb1a", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "e30aa08c46b9a49a4310ca07b7895f8e44674325a9dfeee0b4068ae3529bdbdc", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "60f096eb8d896259f5a72a09006e471c1ee1d40fcd9329f6e64b42ce1b680e1f", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "b181fa84af298c5ae9d379a897de699a70aa1ded9f74ad251e587168e5c50ef1", + "msdk/src/check.rs": "5fdca8af4df80570c56bf509d89a9957350f067552e1e2c3277c8066e0fcc329", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "b47b249fd20fbaac4428f78bdf97f97a3a02b4229ebfaccd34e1c8bd8e28ba91", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "93bd6eec5d6bcecda6df66b6ac3742adfbb023da47c748bd1249a9923d77767e", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "e4ed621d784a9906a878c3b327ff952c93e658c3a5f2f3b1b75c72da268b2d60", + "msdk/src/runtime.rs": "8a8e56ad2bc98b178087db5eacff7d6c3a77ae8c64f7abe353961c044eec1868", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "c0e88f3cb9ad1b1e16ad7ad041e2df88fe6456409b1da6ad5994d86adfe35700", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/generate.rs": "c3db4da4abe7c482f38dcb38315d313a247fdfb36047a4ddf86ce8fc66482a5e", + "msdk/tests/golden_path.rs": "fc622e47eb3571fd5217cd1e50bb966209daa364a093990ec265b565791dcc4f", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "564e208c6df10c7b8d1f481fd29a2302b0a19848f6edf419755873a27d864481", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/summary.json b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/summary.json new file mode 100644 index 000000000..df0d09cfe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-runtime-macos/summary.json @@ -0,0 +1,25 @@ +{ + "schema": "msdk.validation.v1", + "source_commit": "8ece6a52140c68b857cebc6abca3da4818f6625d", + "platform": "Darwin arm64", + "rust": "rustc 1.98.1 (48a229cea 2026-09-01) (Homebrew)", + "core_tests_passed": 77, + "strict_clippy": "passed", + "format": "passed", + "native_current_source": "pending", + "native_blocker": "Source transfer to SER8 rejected by automatic approval review pending explicit payload/destination authorization; no retry or workaround used.", + "scope": [ + "core rules/checker/generator/model compilation", + "real macOS process bounds/cancellation/reaping", + "service diagnostic privacy and discovery", + "Home Storage exact command missing-HOME failure and real-environment retry" + ], + "not_proven": [ + "Linux current source", + "GTK current source", + "new reference app visual/accessibility/install qualification", + "real backend OS protocol compatibility", + "streaming", + "whole SDK completion" + ] +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/Cargo.lock new file mode 100644 index 000000000..ebec75e7d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/Cargo.lock @@ -0,0 +1,137 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "libc", + "serde", + "serde_json", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/clippy-output.txt b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/clippy-output.txt new file mode 100644 index 000000000..0c8e1ca8e --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/clippy-output.txt @@ -0,0 +1,2 @@ + Checking msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.79s diff --git a/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/core-test-output.txt b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/core-test-output.txt new file mode 100644 index 000000000..f619e48a2 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/core-test-output.txt @@ -0,0 +1,180 @@ + Compiling msdk v0.1.0 (/Users/seandolbec/Documents/Codex/2026-10-26/we-x20/work/msdk-check/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.95s + Running unittests src/lib.rs (msdk-check/msdk/target/debug/deps/msdk-4ab7f0c78bb642ee) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (msdk-check/msdk/target/debug/deps/msdk-c308555b757d7c34) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (msdk-check/msdk/target/debug/deps/agent-ca68a0b395d353a5) + +running 4 tests +test every_diagnostic_code_has_an_explanation ... ok +test completion_knows_values_keys_and_row_fields ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (msdk-check/msdk/target/debug/deps/check-a83ee1f001b74d2d) + +running 22 tests +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test feeds_must_match_the_record_shape ... ok +test custom_component_is_reported_as_a_gap ... ok +test design_rules ... ok +test list_actions_check_the_record ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test missing_and_unknown_properties ... ok +test enums_capabilities_ids_and_top_level ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test examples_have_no_errors ... ok +test empty_label_and_state_binding_types ... ok +test layout_props_validate_and_round_trip ... ok +test rust_logic_and_rules_do_not_mix ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test unknown_component_suggests_the_nearest ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test surfaces_validate_their_own_properties ... ok +test services_need_capabilities_and_typed_arguments ... ok +test update_rules_are_type_checked ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/generate.rs (msdk-check/msdk/target/debug/deps/generate-5618a8097656d3fa) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.48s + + Running tests/golden_path.rs (msdk-check/msdk/target/debug/deps/golden_path-f81c7ab40be84731) + +running 2 tests +test home_storage_recovers_and_prevents_duplicate_work ... ok +test home_storage_actual_command_fails_then_recovers ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/inspect.rs (msdk-check/msdk/target/debug/deps/inspect-50e68ecb8cfe4154) + +running 5 tests +test row_buttons_show_the_key_they_send ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/intents.rs (msdk-check/msdk/target/debug/deps/intents-4adbccfe27989abb) + +running 11 tests +test text_errors_name_the_line ... ok +test the_schema_accepts_an_agent_block ... ok +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test t3_declares_a_clean_agent_surface ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s + + Running tests/package.rs (msdk-check/msdk/target/debug/deps/package-e0cc8be0d5ac9b9b) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/process.rs (msdk-check/msdk/target/debug/deps/process-78a09449a9d345a2) + +running 7 tests +test dropping_an_owned_handle_cancels_instead_of_detaching_the_command ... ok +test invalid_resource_limits_are_refused ... ok +test inherited_pipes_do_not_stall_after_the_leader_exits ... ok +test cancellation_reaps_the_leader_and_stops_its_process_group ... ok +test real_output_and_nonzero_exit_are_distinct ... ok +test stdout_and_stderr_share_one_hard_byte_limit ... ok +test timeout_stops_a_real_long_running_process ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s + + Running tests/runtime.rs (msdk-check/msdk/target/debug/deps/runtime-72e2a74824c12ecf) + +running 3 tests +test incompatible_extensions_are_typed_and_recoverable ... ok +test diagnostic_and_debug_never_serialize_private_backend_details ... ok +test runtime_discovery_and_explanations_match_actual_limits_and_failures ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/streaming.rs (msdk-check/msdk/target/debug/deps/streaming-3ea37e5b715b6e45) + +running 5 tests +test raw_bytes_remain_exact_including_non_utf8_output ... ok +test dropping_subscription_cancels_a_silent_command ... ok +test private_partial_output_arrives_before_completion_and_survives_cancel ... ok +test slow_consumer_has_a_hard_queue_bound_and_a_terminal_failure ... ok +test timeout_keeps_already_queued_partial_output ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s + + Running tests/t3.rs (msdk-check/msdk/target/debug/deps/t3-130bd8b0fd4fb4a1) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/templates.rs (msdk-check/msdk/target/debug/deps/templates-daeaa23dbb377819) + +running 5 tests +test template_names_are_unique_and_documented ... ok +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test renamed_templates_stay_valid ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/text.rs (msdk-check/msdk/target/debug/deps/text-da05419791d24613) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/format-output.txt b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/format-output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/source-manifest.json new file mode 100644 index 000000000..78bd24e47 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/source-manifest.json @@ -0,0 +1,77 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "22b3d99f16db7de29078f9cf95e396e1fc19b46d7c656f5df4b86e4df956c4bd", + "msdk-gtk/src/host.rs": "e6d578a84f07dd40157bd605cd2e25d8d9f87683aa29350527da0181d2a82315", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "eaa3f1c506168cce35c227747bbf9e00bfd5b86ce67bfd24fddc39e31739fb1a", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk-gtk/tests/runtime.rs": "e30aa08c46b9a49a4310ca07b7895f8e44674325a9dfeee0b4068ae3529bdbdc", + "msdk/Cargo.toml": "1a71eecce17468f039fb6f8b1feafebf6106e883f37eac16634f26a9fa722cf8", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "1daea58a1469519bf2e47b7b9bb759eb58b642ef5d04560eff7a49533444eb74", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/home-storage.ui.json": "60f096eb8d896259f5a72a09006e471c1ee1d40fcd9329f6e64b42ce1b680e1f", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "b181fa84af298c5ae9d379a897de699a70aa1ded9f74ad251e587168e5c50ef1", + "msdk/src/check.rs": "5fdca8af4df80570c56bf509d89a9957350f067552e1e2c3277c8066e0fcc329", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "b47b249fd20fbaac4428f78bdf97f97a3a02b4229ebfaccd34e1c8bd8e28ba91", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "93bd6eec5d6bcecda6df66b6ac3742adfbb023da47c748bd1249a9923d77767e", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/process.rs": "0280df26ea471982ea98a828b66346bb67790718d60faff4046b5eacf393db2e", + "msdk/src/runtime.rs": "37eaaabfd39b5f4fb9d73669c31e884457660a6d3bdfb44f81747b272b38e059", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "c0e88f3cb9ad1b1e16ad7ad041e2df88fe6456409b1da6ad5994d86adfe35700", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/generate.rs": "c3db4da4abe7c482f38dcb38315d313a247fdfb36047a4ddf86ce8fc66482a5e", + "msdk/tests/golden_path.rs": "fc622e47eb3571fd5217cd1e50bb966209daa364a093990ec265b565791dcc4f", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/process.rs": "dcd86a351abc6d5db7e6b768a07073723ca8a956c5c05d5139b7ff53c5785446", + "msdk/tests/runtime.rs": "e9d231a250069068e4147b05d4815510809938f07b6ca9aa84e674bb42819b21", + "msdk/tests/streaming.rs": "462881cd911693787a5babc562f94e59469f21a05e762776a942cf60c029ce85", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/summary.json b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/summary.json new file mode 100644 index 000000000..d03d6a242 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-streaming-macos/summary.json @@ -0,0 +1,19 @@ +{ + "schema": "msdk.validation.v1", + "source_commit": "da9f403bff1107a3ffe7ea7fe66820d4bbc47df6", + "platform": "Darwin arm64", + "rust": "rustc 1.98.1 (48a229cea 2026-09-01) (Homebrew)", + "core_tests_passed": 82, + "streaming_tests_passed": 5, + "strict_clippy": "passed", + "format": "passed", + "streaming_scope": "Rust core raw-byte API; 32 chunks x 8192-byte bounded nonblocking queue, owned subscription cancellation, partial output after terminal failure", + "native_current_source": "pending authorization for updated source transfer to SER8", + "not_proven": [ + "Linux current source", + "GTK streaming/progress integration", + "stale-context handling", + "updater consumer", + "whole SDK completion" + ] +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-accessibility-tree/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-accessibility-tree/README.md new file mode 100644 index 000000000..5419b4d86 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-accessibility-tree/README.md @@ -0,0 +1,8 @@ +# Usage accessibility tree diagnosis — 2026-10-26 + +Hosted ARM SDK run 40405291097 on 9dac12e failed the synthetic accessibility +probe. The retained tree shows a button named `Refresh` with role `button`; the +probe expected `Refresh usage`. Thus a button existed, but its exposed name did +not match the intended explicit name. No keyboard journey was completed. The +follow-up changes the visible button label to `Refresh usage` and needs a new +native test. The earlier private X display failure remains separate. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-accessibility-tree/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-accessibility-tree/attempt.json new file mode 100644 index 000000000..dd04f1ec3 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-accessibility-tree/attempt.json @@ -0,0 +1,91 @@ +{ + "binary_sha256": "7ed2c045e5c1c07c1c0873878762520c24fc95109111c17b692be889f696be99", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "result": "fail", + "failure": "refresh button is not accessible", + "accessible_nodes": [ + { + "name": "usage_control_interactive", + "role": "application" + }, + { + "name": "Usage control test", + "role": "frame" + }, + { + "name": "", + "role": "panel" + }, + { + "name": "", + "role": "scroll pane" + }, + { + "name": "", + "role": "panel" + }, + { + "name": "", + "role": "panel" + }, + { + "name": "Usage coverage is partial", + "role": "label" + }, + { + "name": "", + "role": "panel" + }, + { + "name": "", + "role": "panel" + }, + { + "name": "Codex", + "role": "label" + }, + { + "name": "CodexBar local snapshot", + "role": "label" + }, + { + "name": "", + "role": "panel" + }, + { + "name": "Provider total", + "role": "label" + }, + { + "name": "7 day: 75% remaining", + "role": "label" + }, + { + "name": "Reset unknown", + "role": "label" + }, + { + "name": "", + "role": "separator" + }, + { + "name": "", + "role": "panel" + }, + { + "name": "Refresh complete", + "role": "label" + }, + { + "name": "Refresh", + "role": "button" + }, + { + "name": "Refresh", + "role": "label" + } + ], + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/README.md new file mode 100644 index 000000000..18f9734ee --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/README.md @@ -0,0 +1,3 @@ +# Candidate usage anchor: coordinate diagnostic + +Hosted ARM SDK run 40407270110 at commit dc1c147 failed the synthetic hover probe. The accessibility-reported anchor center was (38, 17), and X11 reported the pointer on the root window; no synthetic provider read occurred. This evidence does not establish the cause of the hover failure. The fixture was subsequently changed to export GTK widget bounds for the probe. Native validation of that change remains pending. This receipt contains synthetic data only. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/attempt.json new file mode 100644 index 000000000..a6647a8f0 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-coordinates/attempt.json @@ -0,0 +1,62 @@ +{ + "binary_sha256": "bb2726f20dc75f65b088800166009a5beb4ef417390b46362d2bb5e70f8a2e84", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "anchor_center": [ + "38", + "17" + ], + "pointer_after_hover": "X=38\nY=17\nSCREEN=0\nWINDOW=0", + "result": "fail", + "failure": "hover did not open usage popup", + "synthetic_read_count": 0, + "accessible_nodes": [ + { + "name": "usage_anchor_interactive", + "role": "application", + "showing": false + }, + { + "name": "Usage status anchor test", + "role": "frame", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "Outside", + "role": "button", + "showing": true + }, + { + "name": "Outside", + "role": "label", + "showing": true + }, + { + "name": "Usage", + "role": "button", + "showing": true + }, + { + "name": "Usage", + "role": "label", + "showing": true + } + ], + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/README.md new file mode 100644 index 000000000..4851ed116 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/README.md @@ -0,0 +1,3 @@ +# Candidate usage anchor: final ARM interaction pass + +Hosted ARM SDK run 40416161840 at commit 26a71f7 passed the synthetic isolated X11 / private D-Bus test, including hover and pointer travel, unpinned pointer exit, hover-to-click pinning without a duplicate read, outside dismissal and no closed polling, keyboard open and Escape focus restoration, and clean exit. Core, generated app, accessibility, native lifecycle and package install/reinstall/remove also passed. This qualifies the tested reusable candidate fixture, not an installed desktop status host or owner acceptance. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/attempt.json new file mode 100644 index 000000000..fbb1044e6 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-final-pass/attempt.json @@ -0,0 +1,52 @@ +{ + "binary_sha256": "b057233bf8040c16c4f90f05f9bc5e10a255e4bbbc6cdaffc2a79dd9348b1ea2", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [ + "hover opens without stealing focus and pointer travel stays open", + "unpinned popup closes after pointer leaves", + "hover-to-click pins; outside click dismisses; closed popup does not poll", + "keyboard activation opens; Escape dismisses and restores focus", + "Ctrl+Q closes cleanly" + ], + "window_geometry": { + "WINDOW": "2097157", + "X": "0", + "Y": "0", + "WIDTH": "480", + "HEIGHT": "500", + "SCREEN": "0" + }, + "gtk_anchor_bounds": { + "x": 392.0, + "y": 454.0, + "width": 76.0, + "height": 34.0 + }, + "gtk_anchor_center": [ + 430, + 471 + ], + "anchor_center": [ + "38", + "17" + ], + "pointer_after_hover": "X=430\nY=471\nSCREEN=0\nWINDOW=0", + "gtk_popup_bounds": { + "x": 291.0, + "y": 335.0, + "width": 278.0, + "height": 123.0 + }, + "x11_windows_before_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "x11_pointer_child": { + "ok": true, + "child": "0x20001e", + "root_x": 430, + "root_y": 396 + }, + "pointer_after_travel": "X=430\nY=396\nSCREEN=0\nWINDOW=0", + "x11_windows_after_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "result": "pass", + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\nanchor trace: anchor enter\nanchor trace: anchor leave\nanchor trace: popup enter\nanchor trace: popup leave\nanchor trace: popup closed\nanchor trace: anchor enter\nanchor trace: popup closed\nanchor trace: anchor leave\nanchor trace: popup enter\nanchor trace: popup leave\nanchor trace: popup closed\nanchor trace: popup enter\nanchor trace: popup closed\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail/README.md new file mode 100644 index 000000000..6b37fc20e --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail/README.md @@ -0,0 +1,8 @@ +# Candidate anchor hover failure — 2026-10-26 + +Hosted ARM SDK run 40406733431 on 5c7dcbc compiled the candidate anchor but the +private synthetic interaction probe failed: hover did not expose the popup. +The retained AT-SPI tree showed the Usage button but no popup. The original +receipt did not record pointer position or read count, so it does not establish +why hover failed. A follow-up uses the popup's mapped state for open checks and +adds synthetic pointer/read diagnostics. It requires a new native test. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail/attempt.json new file mode 100644 index 000000000..f548a0c4c --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-hover-fail/attempt.json @@ -0,0 +1,56 @@ +{ + "binary_sha256": "d890c17d013305ba216aed878bd28034e51925a8f8d7d91c8bf9a9f952a21819", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "result": "fail", + "failure": "hover did not open usage popup", + "accessible_nodes": [ + { + "name": "usage_anchor_interactive", + "role": "application", + "showing": false + }, + { + "name": "Usage status anchor test", + "role": "frame", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "Outside", + "role": "button", + "showing": true + }, + { + "name": "Outside", + "role": "label", + "showing": true + }, + { + "name": "Usage", + "role": "button", + "showing": true + }, + { + "name": "Usage", + "role": "label", + "showing": true + } + ], + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-input-target/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-input-target/README.md new file mode 100644 index 000000000..9be1838fe --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-input-target/README.md @@ -0,0 +1,3 @@ +# Candidate usage anchor: input target + +Hosted ARM run 40415441480 at commit 4570a09 failed pointer travel. XQueryPointer reported the popup window itself as the root child under the pointer (0x20001e), while GTK motion events reported a popup leave and the controller contained-pointer state was false. The subsequent candidate change checks the GDK surface under the device when the hover-close timer fires. This change requires native validation. Synthetic data only. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-input-target/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-input-target/attempt.json new file mode 100644 index 000000000..f40774131 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-input-target/attempt.json @@ -0,0 +1,95 @@ +{ + "binary_sha256": "ddf1ebb555056c506b50626d37fb3e0eec1a4daeba123a84c99d805d53e71764", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "window_geometry": { + "WINDOW": "2097157", + "X": "0", + "Y": "0", + "WIDTH": "480", + "HEIGHT": "500", + "SCREEN": "0" + }, + "gtk_anchor_bounds": { + "x": 392.0, + "y": 454.0, + "width": 76.0, + "height": 34.0 + }, + "gtk_anchor_center": [ + 430, + 471 + ], + "anchor_center": [ + "38", + "17" + ], + "pointer_after_hover": "X=430\nY=471\nSCREEN=0\nWINDOW=0", + "gtk_popup_bounds": { + "x": 291.0, + "y": 335.0, + "width": 278.0, + "height": 123.0 + }, + "x11_windows_before_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "x11_pointer_child": { + "ok": true, + "child": "0x20001e", + "root_x": 430, + "root_y": 396 + }, + "pointer_after_travel": "X=430\nY=396\nSCREEN=0\nWINDOW=0", + "x11_windows_after_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "result": "fail", + "failure": "pointer travel closed popup", + "synthetic_read_count": 1, + "accessible_nodes": [ + { + "name": "usage_anchor_interactive", + "role": "application", + "showing": false + }, + { + "name": "Usage status anchor test", + "role": "frame", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "Outside", + "role": "button", + "showing": true + }, + { + "name": "Outside", + "role": "label", + "showing": true + }, + { + "name": "Usage", + "role": "button", + "showing": true + }, + { + "name": "Usage", + "role": "label", + "showing": true + } + ], + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\nanchor trace: anchor enter\nanchor trace: anchor leave\nanchor trace: popup enter\nanchor trace: popup leave\nanchor trace: close timer anchor=false popup=false\nanchor trace: popup closed\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-pass/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-pass/README.md new file mode 100644 index 000000000..fbcab812b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-pass/README.md @@ -0,0 +1,3 @@ +# Candidate usage anchor: ARM interaction pass + +Hosted ARM SDK run 40415797379 at commit 7fa281f passed the synthetic isolated X11 / private D-Bus anchor test: hover without focus theft, pointer travel, pinning with no duplicate read, outside dismissal, no closed polling, keyboard open, Escape focus restoration and clean exit. The package installation lifecycle also passed. This is a reusable candidate fixture, not an installed status host or owner acceptance. A subsequent probe adds an explicit unpinned pointer-leave check and must be separately validated. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-pass/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-pass/attempt.json new file mode 100644 index 000000000..3e2150d55 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-pass/attempt.json @@ -0,0 +1,51 @@ +{ + "binary_sha256": "b057233bf8040c16c4f90f05f9bc5e10a255e4bbbc6cdaffc2a79dd9348b1ea2", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [ + "hover opens without stealing focus and pointer travel stays open", + "hover-to-click pins; outside click dismisses; closed popup does not poll", + "keyboard activation opens; Escape dismisses and restores focus", + "Ctrl+Q closes cleanly" + ], + "window_geometry": { + "WINDOW": "2097157", + "X": "0", + "Y": "0", + "WIDTH": "480", + "HEIGHT": "500", + "SCREEN": "0" + }, + "gtk_anchor_bounds": { + "x": 392.0, + "y": 454.0, + "width": 76.0, + "height": 34.0 + }, + "gtk_anchor_center": [ + 430, + 471 + ], + "anchor_center": [ + "38", + "17" + ], + "pointer_after_hover": "X=430\nY=471\nSCREEN=0\nWINDOW=0", + "gtk_popup_bounds": { + "x": 291.0, + "y": 335.0, + "width": 278.0, + "height": 123.0 + }, + "x11_windows_before_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "x11_pointer_child": { + "ok": true, + "child": "0x20001e", + "root_x": 430, + "root_y": 396 + }, + "pointer_after_travel": "X=430\nY=396\nSCREEN=0\nWINDOW=0", + "x11_windows_after_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "result": "pass", + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\nanchor trace: anchor enter\nanchor trace: anchor leave\nanchor trace: popup enter\nanchor trace: popup leave\nanchor trace: anchor enter\nanchor trace: popup closed\nanchor trace: anchor leave\nanchor trace: popup enter\nanchor trace: popup leave\nanchor trace: popup closed\nanchor trace: popup enter\nanchor trace: popup closed\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-transition-fail/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-transition-fail/README.md new file mode 100644 index 000000000..40ad3a921 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-transition-fail/README.md @@ -0,0 +1,3 @@ +# Candidate usage anchor: transition diagnostic + +Hosted ARM SDK run 40414571505 attempt 2 at commit 8465596 failed pointer travel. The popup surface remained at 291,335 (278x123) before and after moving to 430,396. GTK logged popup enter, popup leave, and a close timer with both motion controllers reporting false. This did not establish which X11 window received the pointer. Pinning was not reached. Attempt 1 failed earlier because its private GTK display could not be opened. Synthetic data only. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-transition-fail/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-transition-fail/attempt.json new file mode 100644 index 000000000..d40df1c62 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-transition-fail/attempt.json @@ -0,0 +1,89 @@ +{ + "binary_sha256": "ddf1ebb555056c506b50626d37fb3e0eec1a4daeba123a84c99d805d53e71764", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "window_geometry": { + "WINDOW": "2097157", + "X": "0", + "Y": "0", + "WIDTH": "480", + "HEIGHT": "500", + "SCREEN": "0" + }, + "gtk_anchor_bounds": { + "x": 392.0, + "y": 454.0, + "width": 76.0, + "height": 34.0 + }, + "gtk_anchor_center": [ + 430, + 471 + ], + "anchor_center": [ + "38", + "17" + ], + "pointer_after_hover": "X=430\nY=471\nSCREEN=0\nWINDOW=0", + "gtk_popup_bounds": { + "x": 291.0, + "y": 335.0, + "width": 278.0, + "height": 123.0 + }, + "x11_windows_before_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "pointer_after_travel": "X=430\nY=396\nSCREEN=0\nWINDOW=0", + "x11_windows_after_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "result": "fail", + "failure": "pointer travel closed popup", + "synthetic_read_count": 1, + "accessible_nodes": [ + { + "name": "usage_anchor_interactive", + "role": "application", + "showing": false + }, + { + "name": "Usage status anchor test", + "role": "frame", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "Outside", + "role": "button", + "showing": true + }, + { + "name": "Outside", + "role": "label", + "showing": true + }, + { + "name": "Usage", + "role": "button", + "showing": true + }, + { + "name": "Usage", + "role": "label", + "showing": true + } + ], + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\nanchor trace: anchor enter\nanchor trace: anchor leave\nanchor trace: popup enter\nanchor trace: popup leave\nanchor trace: close timer anchor=false popup=false\nanchor trace: popup closed\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-diagnostic/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-diagnostic/README.md new file mode 100644 index 000000000..a7b87f697 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-diagnostic/README.md @@ -0,0 +1,3 @@ +# Candidate usage anchor: pointer travel diagnostic + +Hosted ARM SDK run 40413041565 at commit c7e6cdb opened the synthetic popup and read once. X11 reported the popup at 291,335 with size 278x123; the pointer was moved to 430,396, inside that surface. The popup nevertheless closed before the probe completed its travel check. Pinning, outside dismissal and keyboard checks were not reached. A subsequent candidate change checks pointer containment when the close timer fires; that change still needs native validation. Synthetic data only. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-diagnostic/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-diagnostic/attempt.json new file mode 100644 index 000000000..184214dfd --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-diagnostic/attempt.json @@ -0,0 +1,88 @@ +{ + "binary_sha256": "7c6a0de4cb610ecf90981c987aea74e882246a92683a64feb5083a823b31a13c", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "window_geometry": { + "WINDOW": "2097157", + "X": "0", + "Y": "0", + "WIDTH": "480", + "HEIGHT": "500", + "SCREEN": "0" + }, + "gtk_anchor_bounds": { + "x": 392.0, + "y": 454.0, + "width": 76.0, + "height": 34.0 + }, + "gtk_anchor_center": [ + 430, + 471 + ], + "anchor_center": [ + "38", + "17" + ], + "pointer_after_hover": "X=430\nY=471\nSCREEN=0\nWINDOW=0", + "gtk_popup_bounds": { + "x": 291.0, + "y": 335.0, + "width": 278.0, + "height": 123.0 + }, + "x11_windows_before_travel": "\nxwininfo: Window id: 0x21f (the root window) (has no name)\n\n Root window id: 0x21f (the root window) (has no name)\n Parent window id: 0x0 (none)\n 4 children:\n 0x20001e \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 278x123+291+335 +291+335\n 1 child:\n 0x20001f (has no name): () 1x1+-1+-1 +290+334\n 0x20000a (has no name): () 1x1+-1+-1 +-1+-1\n 0x200005 \"Usage status anchor test\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 480x500+0+0 +0+0\n 1 child:\n 0x200006 (has no name): () 1x1+-1+-1 +-1+-1\n 0x200003 \"usage_anchor_interactive\": (\"usage_anchor_interactive\" \"usage_anchor_interactive\") 1x1+0+0 +0+0\n 1 child:\n 0x200004 (has no name): () 1x1+-1+-1 +-1+-1\n\n", + "pointer_after_travel": "X=430\nY=396\nSCREEN=0\nWINDOW=0", + "result": "fail", + "failure": "pointer travel closed popup", + "synthetic_read_count": 1, + "accessible_nodes": [ + { + "name": "usage_anchor_interactive", + "role": "application", + "showing": false + }, + { + "name": "Usage status anchor test", + "role": "frame", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "Outside", + "role": "button", + "showing": true + }, + { + "name": "Outside", + "role": "label", + "showing": true + }, + { + "name": "Usage", + "role": "button", + "showing": true + }, + { + "name": "Usage", + "role": "label", + "showing": true + } + ], + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/README.md new file mode 100644 index 000000000..6857cbc44 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/README.md @@ -0,0 +1,3 @@ +# Candidate usage anchor: pointer travel failure + +Hosted ARM SDK run 40412642984 at commit 98867b8 opened the synthetic popup using GTK-reported anchor bounds and recorded one synthetic provider read. The popup was no longer visible after moving the pointer toward the GTK-reported popup center. This does not establish whether the move targeted the actual X11 popup surface or whether the popup incorrectly closed during valid pointer travel. Pinning, outside dismissal, keyboard and package steps were not reached. The receipt contains synthetic data only. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/attempt.json b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/attempt.json new file mode 100644 index 000000000..cdc5d580d --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-anchor-travel-fail/attempt.json @@ -0,0 +1,86 @@ +{ + "binary_sha256": "7c6a0de4cb610ecf90981c987aea74e882246a92683a64feb5083a823b31a13c", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "window_geometry": { + "WINDOW": "2097157", + "X": "0", + "Y": "0", + "WIDTH": "480", + "HEIGHT": "500", + "SCREEN": "0" + }, + "gtk_anchor_bounds": { + "x": 392.0, + "y": 454.0, + "width": 76.0, + "height": 34.0 + }, + "gtk_anchor_center": [ + 430, + 471 + ], + "anchor_center": [ + "38", + "17" + ], + "pointer_after_hover": "X=430\nY=471\nSCREEN=0\nWINDOW=0", + "gtk_popup_bounds": { + "x": 291.0, + "y": 335.0, + "width": 278.0, + "height": 123.0 + }, + "result": "fail", + "failure": "pointer travel closed popup", + "synthetic_read_count": 1, + "accessible_nodes": [ + { + "name": "usage_anchor_interactive", + "role": "application", + "showing": false + }, + { + "name": "Usage status anchor test", + "role": "frame", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "", + "role": "panel", + "showing": true + }, + { + "name": "Outside", + "role": "button", + "showing": true + }, + { + "name": "Outside", + "role": "label", + "showing": true + }, + { + "name": "Usage", + "role": "button", + "showing": true + }, + { + "name": "Usage", + "role": "label", + "showing": true + } + ], + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-cards/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/README.md new file mode 100644 index 000000000..552cf2bc1 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/README.md @@ -0,0 +1,13 @@ +# Usage card refinement — 2026-10-26 + +Source dd96c00315bdc85de5f8fac6dadb3617ac50b65d; hosted ARM Linux SDK +developer-path run 40395621853 passed, including native widget checks and +synthetic 480×500 captures in light/dark with verified Sans 10/15. No real +accounts were used. + +Review: compared with 2026-10-26-usage-preview, the theme-derived card and +account headings improve hierarchy; stale appears once and reset text no +longer wraps awkwardly in this fixture. Text remains readable without clipping. +The component still lacks provider marks, compact quota presentation, +multi-provider/long-list review, actions, real host interactions and owner +acceptance. These screenshots do not establish full CodexBar conformance. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-dark-10.png new file mode 100644 index 000000000..0c5fa9c61 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-dark-15.png new file mode 100644 index 000000000..26a64f2b2 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-light-10.png new file mode 100644 index 000000000..e79ccdf94 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-light-15.png new file mode 100644 index 000000000..51858a39d Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-cards/usage-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/README.md new file mode 100644 index 000000000..1f14da3f4 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/README.md @@ -0,0 +1,13 @@ +# Usage control failure state — 2026-10-26 + +Hosted ARM SDK developer-path run 40403452026 passed on e1c91a8. The native +synthetic test covers one read per open, busy/disabled refresh, failure with +stale retained data, and successful retry. Four 480×500 light/dark Sans 10/15 +failure-state captures are retained; no real provider was accessed. + +Review: failure explanation, partial coverage, stale quota, recovery prompt +and Refresh button are visible without clipping in this fixture. The footer no +longer repeats the failure text. This is not measured contrast, keyboard or +AT-SPI interaction, a desktop status host, real collector validation, or owner +visual acceptance. Busy and successful states were tested in the widget tree, +not visually reviewed in these captures. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-dark-10.png new file mode 100644 index 000000000..4913e9249 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-dark-15.png new file mode 100644 index 000000000..7558217d5 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-light-10.png new file mode 100644 index 000000000..f1bec6e50 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-light-15.png new file mode 100644 index 000000000..5fe15d2be Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-final/usage-error-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/README.md new file mode 100644 index 000000000..596fefa61 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/README.md @@ -0,0 +1,13 @@ +# Usage control initial failure-state review — 2026-10-26 + +Hosted ARM SDK run 40402684685 passed on a5b0ff2. Native synthetic tests cover +one read per open, busy/disabled refresh, malformed output, stale retained +values, retry and no private stderr in labels. Four 480×500 light/dark Sans +10/15 synthetic failure screenshots are retained here; project icons were +staged only in a private fixture directory. + +Review: the failure notice, stale value and refresh button are visible and +readable in both themes/text sizes. The same failure appears in both the panel +and footer, so the footer is being revised into a recovery prompt. The captures +are not owner visual acceptance, keyboard/AT-SPI interaction, real collector or +desktop status-host evidence. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-dark-10.png new file mode 100644 index 000000000..66919c7ec Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-dark-15.png new file mode 100644 index 000000000..e009d4ee6 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-light-10.png new file mode 100644 index 000000000..8aaa46947 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-light-15.png new file mode 100644 index 000000000..ca695a1ec Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-control-first/usage-error-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/README.md new file mode 100644 index 000000000..78d9717ec --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/README.md @@ -0,0 +1,9 @@ +# Usage keyboard probe failures — 2026-10-26 + +Run 40404146612 on source 34a26fa failed twice. Attempt 1 exited before +accessibility registration because GTK could not open the isolated X display. +Attempt 2 opened the app but did not find a button named `Refresh usage` with +the expected role within the timeout. Neither attempt completed a keyboard +journey. Synthetic artifacts are retained unchanged. The cause of either failure +is not established. A follow-up adds bounded accessibility-tree diagnostics; +it must not treat these attempts as a pass. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/attempt-1.json b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/attempt-1.json new file mode 100644 index 000000000..a919fa4b8 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/attempt-1.json @@ -0,0 +1,9 @@ +{ + "binary_sha256": "7ed2c045e5c1c07c1c0873878762520c24fc95109111c17b692be889f696be99", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "result": "fail", + "failure": "fixture app exited early (1); see process_stderr", + "process_stdout": "", + "process_stderr": "\n(usage_control_interactive:7063): Gtk-WARNING **: 21:27:56.245: Failed to open display\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/attempt-2.json b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/attempt-2.json new file mode 100644 index 000000000..d1ed1a9e9 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-failures/attempt-2.json @@ -0,0 +1,9 @@ +{ + "binary_sha256": "7ed2c045e5c1c07c1c0873878762520c24fc95109111c17b692be889f696be99", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [], + "result": "fail", + "failure": "refresh button is not accessible", + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/README.md new file mode 100644 index 000000000..d64598a47 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/README.md @@ -0,0 +1,14 @@ +# Usage control keyboard and accessibility — 2026-10-26 + +Hosted ARM SDK developer-path run 40405964283 passed on 477234a. In a private +X11/D-Bus session, the synthetic app exposed `Refresh usage` with role `button`; +Tab focused it, Space triggered a failed refresh, stale data remained visible, +private stderr stayed out of the accessible tree, and Space retried successfully. +Ctrl+Q closed cleanly. The synthetic binary hash and checks are in +usage-controls.json. No real accounts or owner desktop were used. + +Four 480×500 light/dark Sans 10/15 failure-state captures were reviewed. The +explicit button label, failure notice and retry prompt fit without clipping in +this fixture. Keyboard scrolling, focus/hover/dismissal in real status hosts, +long translated labels, real collector reads and owner visual acceptance remain +open. Earlier X-display and accessible-name failures are retained separately. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-controls.json b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-controls.json new file mode 100644 index 000000000..6289c2056 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-controls.json @@ -0,0 +1,14 @@ +{ + "binary_sha256": "c713618d16748dd571b466d281bf7c49ee54e9bac88b9282f0295693f268464c", + "environment": "isolated X11 / private D-Bus / synthetic data", + "checks": [ + "Tab reaches the named refresh button", + "Space refreshes; failure keeps stale data and hides stderr", + "keyboard retry recovers", + "Ctrl+Q closes cleanly" + ], + "refresh_accessible_role": "button", + "result": "pass", + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-dark-10.png new file mode 100644 index 000000000..fa43ae866 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-dark-15.png new file mode 100644 index 000000000..f513c3b9c Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-light-10.png new file mode 100644 index 000000000..48589f858 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-light-15.png new file mode 100644 index 000000000..011089637 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-keyboard-pass/usage-error-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/README.md new file mode 100644 index 000000000..6e0b7ef2b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/README.md @@ -0,0 +1,16 @@ +# Multi-provider usage fixture — 2026-10-26 + +Hosted ARM Linux developer-path run 40396405090 passed on commit 2111eb1, +including the native multi-account/widget/scroll-range test and eight synthetic +480×500 light/dark, Sans 10/15 top/end screenshots. Existing CodexBar icon +assets were staged in an isolated XDG data directory. The fixture contains two +Codex accounts, two Claude accounts, one Grok and one OpenCode account; no +real accounts or live provider adapters were used. + +Review: the captured top and bottom show the labels, distinct accounts, +provider marks, partial coverage and unknown/unavailable states. The bottom is +reachable by a programmatic scroll. At larger text sizes only two providers are +visible at opening, so provider coverage is not sufficiently obvious as the +status specification requires. The scroll boundary clips partial cards, as +expected for this ordinary viewport; no keyboard scrolling, interactive host, +owner acceptance or complete visual conformance is established. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-10-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-10-end.png new file mode 100644 index 000000000..5a006509f Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-10-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-10.png new file mode 100644 index 000000000..e702909bf Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-15-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-15-end.png new file mode 100644 index 000000000..2aa24eb82 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-15-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-15.png new file mode 100644 index 000000000..b4c0a8a8a Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-10-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-10-end.png new file mode 100644 index 000000000..cdae55203 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-10-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-10.png new file mode 100644 index 000000000..9eec96458 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-15-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-15-end.png new file mode 100644 index 000000000..7b2f656ae Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-15-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-15.png new file mode 100644 index 000000000..0414342aa Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-multiprovider/usage-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/README.md new file mode 100644 index 000000000..6d2fd0838 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/README.md @@ -0,0 +1,13 @@ +# Usage provider overview — 2026-10-26 + +Hosted ARM Linux SDK run 40397085739 passed on 0951bde, including the GTK +multi-account/scroll regression and eight synthetic 480×500 light/dark, +Sans 10/15 top/end captures. CodexBar symbolic assets were staged only in the +isolated fixture; no real provider accounts were used. + +Review: all four provider names and partial coverage are visible on opening in +both text profiles and themes. Separate provider/account details remain in the +scrollable cards; the end capture shows Grok and OpenCode states. This resolves +the previous fixture's lack of a provider overview, but is not proof of +complete source coverage, compact quota layout, keyboard navigation, live host +interaction, long translated labels or owner visual acceptance. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-10-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-10-end.png new file mode 100644 index 000000000..583338eb2 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-10-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-10.png new file mode 100644 index 000000000..de7ee234e Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-15-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-15-end.png new file mode 100644 index 000000000..f4adc38a2 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-15-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-15.png new file mode 100644 index 000000000..58628e42e Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-10-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-10-end.png new file mode 100644 index 000000000..b5de750c6 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-10-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-10.png new file mode 100644 index 000000000..bcb9578f9 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-15-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-15-end.png new file mode 100644 index 000000000..59304406f Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-15-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-15.png new file mode 100644 index 000000000..dd611f848 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-overview/usage-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-preview/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/README.md new file mode 100644 index 000000000..200689bf7 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/README.md @@ -0,0 +1,13 @@ +# Candidate GTK usage preview — 2026-10-26 + +Source: edf7a4ee0aec0a682c1e016a69b91efcf2576d0f; SDK developer-path +run 40395051297 passed on hosted ARM Linux. Native widget-tree test passed, +and synthetic preview captures were made at 480×500 in light/dark with the +verified Sans 10 and Sans 15 profiles. No real accounts were used. + +Visual review: text is readable in both themes and the sample is not clipped, +but the component is too flat for the CodexBar reference: no visible provider +card/mark or compact account hierarchy, repeated stale labels, and awkward +wrapping at larger text. The sample does not prove long-list scrolling, source +coverage, keyboard actions, accessibility interaction, host placement or owner +approval. Do not claim status module visual or functional acceptance from this. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-dark-10.png new file mode 100644 index 000000000..620fb8bc5 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-dark-15.png new file mode 100644 index 000000000..db99d5f60 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-light-10.png new file mode 100644 index 000000000..9fc854650 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-light-15.png new file mode 100644 index 000000000..32a67bd22 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-preview/usage-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/README.md b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/README.md new file mode 100644 index 000000000..6c9a25949 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/README.md @@ -0,0 +1,13 @@ +# Refreshable usage viewport — 2026-10-26 + +Hosted ARM Linux SDK developer-path run 40397942393 passed on cc2dace. The +native widget test rejects an invalid replacement without losing current +content, performs consecutive valid updates, and checks numeric scroll offset +retention for an unchanged-height synthetic list. Preview screenshots cover +480×500, light/dark, Sans 10/15 and top/end positions with staged project icons. +No real account data or actual desktop status host was used. + +Visual review: provider overview and partial coverage remain readable at both +text sizes; cards and end-of-list provider states are visible through scrolling. +The captures do not exercise refresh, semantic row anchoring, keyboard focus, +interactive children, long translated labels or owner visual acceptance. diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-10-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-10-end.png new file mode 100644 index 000000000..dada076b0 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-10-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-10.png new file mode 100644 index 000000000..b821c6227 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-15-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-15-end.png new file mode 100644 index 000000000..cfb6aa7e2 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-15-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-15.png new file mode 100644 index 000000000..282446753 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-dark-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-10-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-10-end.png new file mode 100644 index 000000000..78ab30cc4 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-10-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-10.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-10.png new file mode 100644 index 000000000..e6198b23e Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-10.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-15-end.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-15-end.png new file mode 100644 index 000000000..c9cf8cb8b Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-15-end.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-15.png b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-15.png new file mode 100644 index 000000000..c1c5792ad Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26-usage-viewport/usage-light-15.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/controls-output.txt b/mseries/sdk-tests/receipts/2026-10-26/controls-output.txt new file mode 100644 index 000000000..11ebbf7df --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/controls-output.txt @@ -0,0 +1,24 @@ +dbus-daemon[16174]: [session uid=0 pid=16174 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.0' (uid=0 pid=16175 comm="python3 /work/controls.py --binary /work/target/de" label="unconfined") +dbus-daemon[16174]: [session uid=0 pid=16174 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16184]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16175 comm="python3 /work/controls.py --binary /work/target/de" label="unconfined") +dbus-daemon[16184]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +{ + "binary_sha256": "e68aefa505ea9f16eeb8d475d6997f4340cd10e3cfe31b9d504ed92e78c91feb", + "environment": "isolated X11 / private D-Bus / synthetic XDG state", + "checks": [ + "live accessible names and roles", + "Tab reaches switch; Space changes persisted state", + "Tab reaches dropdown; keyboard selection saves", + "Tab reaches reset; Space restores defaults", + "Ctrl+Q closes cleanly" + ], + "accessible_roles": { + "Turn on work mode": "switch", + "Schedule": "combo box", + "Reset to defaults": "button" + }, + "result": "pass", + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/controls.json b/mseries/sdk-tests/receipts/2026-10-26/controls.json new file mode 100644 index 000000000..77cccf5f7 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/controls.json @@ -0,0 +1,19 @@ +{ + "binary_sha256": "e68aefa505ea9f16eeb8d475d6997f4340cd10e3cfe31b9d504ed92e78c91feb", + "environment": "isolated X11 / private D-Bus / synthetic XDG state", + "checks": [ + "live accessible names and roles", + "Tab reaches switch; Space changes persisted state", + "Tab reaches dropdown; keyboard selection saves", + "Tab reaches reset; Space restores defaults", + "Ctrl+Q closes cleanly" + ], + "accessible_roles": { + "Turn on work mode": "switch", + "Schedule": "combo box", + "Reset to defaults": "button" + }, + "result": "pass", + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/core-output.txt b/mseries/sdk-tests/receipts/2026-10-26/core-output.txt new file mode 100644 index 000000000..30b384cb7 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/core-output.txt @@ -0,0 +1,139 @@ + Compiling msdk v0.1.0 (/work/sdk/msdk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.93s + Running unittests src/lib.rs (/work/target/debug/deps/msdk-054984f29162e1a2) + +running 1 test +test intents::tests::sha256_matches_the_known_vectors ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/work/target/debug/deps/msdk-54c77ce22c7c0035) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/agent.rs (/work/target/debug/deps/agent-f180c36d8c5dfb5e) + +running 4 tests +test completion_knows_values_keys_and_row_fields ... ok +test every_diagnostic_code_has_an_explanation ... ok +test describe_gives_a_valid_example_for_every_component ... ok +test gates_pass_for_the_example_and_fail_with_a_reason ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/check.rs (/work/target/debug/deps/check-fbb8190351ac2c9c) + +running 22 tests +test custom_component_is_reported_as_a_gap ... ok +test contrast_gate_covers_every_accent_in_both_themes_and_passes ... ok +test design_rules ... ok +test empty_label_and_state_binding_types ... ok +test feeds_must_match_the_record_shape ... ok +test corner_tokens_nest_and_concentric_radii_never_collapse ... ok +test enums_capabilities_ids_and_top_level ... ok +test list_actions_check_the_record ... ok +test layout_props_validate_and_round_trip ... ok +test list_rows_see_record_fields_and_need_key_and_empty ... ok +test missing_and_unknown_properties ... ok +test examples_have_no_errors ... ok +test messages_must_be_declared_and_payloads_must_match ... ok +test row_fields_are_not_visible_outside_the_row ... ok +test rust_logic_and_rules_do_not_mix ... ok +test stack_children_need_ids_and_tabs_bind_text ... ok +test services_need_capabilities_and_typed_arguments ... ok +test unknown_component_suggests_the_nearest ... ok +test surfaces_validate_their_own_properties ... ok +test malformed_rule_targets_and_service_callbacks_are_errors ... ok +test update_rules_are_type_checked ... ok +test schema_and_tokens_are_derived_from_the_tables ... ok + +test result: ok. 22 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/generate.rs (/work/target/debug/deps/generate-a3c088bb1d0e4cb1) + +running 3 tests +test invalid_documents_and_missing_rust_logic_fail_before_generation ... ok +test projects_are_complete_deterministic_and_never_overwrite_existing_files ... ok +test generated_models_compile_and_preserve_state_and_events ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.32s + + Running tests/inspect.rs (/work/target/debug/deps/inspect-2884d8c0b758eca4) + +running 5 tests +test row_buttons_show_the_key_they_send ... ok +test secrets_are_masked_and_missing_surfaces_are_errors ... ok +test hidden_controls_are_left_out_and_shown_when_their_flag_is_true ... ok +test list_rows_resolve_templates_and_carry_their_key ... ok +test a_stack_shows_only_the_selected_page_and_tabs_report_their_value ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/intents.rs (/work/target/debug/deps/intents-e9339f7ecd6dacf3) + +running 11 tests +test a_small_agent_block_on_quick_notes_checks_clean ... ok +test an_app_with_errors_or_without_an_agent_block_has_no_manifest ... ok +test arguments_must_match_the_single_typed_parameter ... ok +test t3_declares_a_clean_agent_surface ... ok +test mcp_tools_carry_risk_scope_and_the_manifest_hash ... ok +test text_errors_name_the_line ... ok +test the_schema_accepts_an_agent_block ... ok +test t3_intents_each_have_a_scenario_and_hostile_arguments_are_refused ... ok +test the_text_form_round_trips_and_is_idempotent ... ok +test the_manifest_hash_follows_meaning_not_spelling ... ok +test every_rule_fires ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/package.rs (/work/target/debug/deps/package-9feb0d5b7cb7cbd2) + +running 3 tests +test package_architecture_comes_from_the_binary_not_the_build_host ... ok +test desktop_fields_cannot_inject_an_extra_launcher_action ... ok +test metadata_escapes_markup_and_uses_the_same_desktop_identity ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/t3.rs (/work/target/debug/deps/t3-0a6b0d164cdefc3a) + +running 4 tests +test the_registry_knows_the_plug_in_services ... ok +test t3_checks_clean_with_its_service_manifest ... ok +test t3_passes_its_gates ... ok +test t3_is_stable_under_the_formatter ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/templates.rs (/work/target/debug/deps/templates-ebfe5b78050f45e9) + +running 5 tests +test replacement_values_are_not_expanded_as_template_placeholders ... ok +test template_names_are_unique_and_documented ... ok +test renamed_templates_stay_valid ... ok +test custom_names_are_literal_json_strings_in_every_starter ... ok +test every_template_is_valid_and_passes_its_own_gates ... ok + +test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/text.rs (/work/target/debug/deps/text-9ba5adcbdc1d1461) + +running 7 tests +test aliases_and_modifiers ... ok +test diagnostics_map_back_to_text_lines ... ok +test parse_errors_have_a_line_and_a_suggestion ... ok +test text_files_load_like_json_files ... ok +test the_design_language_example_compiles_and_checks ... ok +test every_example_round_trips_through_the_text_form ... ok +test formatting_is_idempotent ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Doc-tests msdk + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/mseries/sdk-tests/receipts/2026-10-26/environment.txt b/mseries/sdk-tests/receipts/2026-10-26/environment.txt new file mode 100644 index 000000000..e26a2152b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/environment.txt @@ -0,0 +1,10 @@ +rustc 1.93.1 (01f6ddf75 2026-02-11) (built from a source tarball) +binary: rustc +commit-hash: 01f6ddf7588f42ae2d7eb0a2f21d44e8e96674cf +commit-date: 2026-02-11 +host: x86_64-unknown-linux-gnu +release: 1.93.1 +LLVM version: 21.1.8 +cargo 1.93.1 (083ac5135 2025-12-15) (built from a source tarball) +4.22.4 +Linux x86_64 diff --git a/mseries/sdk-tests/receipts/2026-10-26/failures/controls-static-label-selection.json b/mseries/sdk-tests/receipts/2026-10-26/failures/controls-static-label-selection.json new file mode 100644 index 000000000..5d2a2ef84 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/failures/controls-static-label-selection.json @@ -0,0 +1,9 @@ +{ + "binary_sha256": "ec3312dd32f51cd4643260a31fbd950cec101eea1b16fdba5dab707cd54a97a6", + "environment": "isolated X11 / private D-Bus / synthetic XDG state", + "checks": [], + "result": "fail", + "failure": "{'Turn on work mode': 'label', 'Schedule': 'label', 'Reset to defaults': 'button'}", + "process_stdout": "", + "process_stderr": "libEGL warning: DRI3 error: Could not get DRI3 device\nlibEGL warning: Ensure your X server supports DRI3 to get accelerated rendering\n" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/failures/window-controls-before.png b/mseries/sdk-tests/receipts/2026-10-26/failures/window-controls-before.png new file mode 100644 index 000000000..52bbb7cc9 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/failures/window-controls-before.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/generated-Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26/generated-Cargo.lock new file mode 100644 index 000000000..af63a84ca --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/generated-Cargo.lock @@ -0,0 +1,745 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e055fa6e3e40ad6187ba25b6855eeb635d5271f8e0f0e1e9a5826b8d75bea0" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "msdk-sdksettings" +version = "0.1.0" +dependencies = [ + "gtk4", + "msdk", + "msdk-gtk", + "serde", + "serde_json", +] + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db551ad38aac61d5e0343e0eeeb0163be3115c4e23b6a025959570ee0c03c67d" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26/generated-output.txt b/mseries/sdk-tests/receipts/2026-10-26/generated-output.txt new file mode 100644 index 000000000..1c0325248 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/generated-output.txt @@ -0,0 +1,27 @@ + Compiling msdk v0.1.0 (/work/sdk/msdk) + Compiling msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Compiling msdk-sdksettings v0.1.0 (/work/generated2) + Finished `test` profile [unoptimized + debuginfo] target(s) in 2.64s + Running unittests src/lib.rs (/work/target/debug/deps/app_model-11143836e0c91a61) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/main.rs (/work/target/debug/deps/msdk_sdksettings-3336386daff63340) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/model.rs (/work/target/debug/deps/model-a0eac8d13416b9d5) + +running 1 test +test initial_state_round_trips ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Checking msdk v0.1.0 (/work/sdk/msdk) + Checking msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Checking msdk-sdksettings v0.1.0 (/work/generated2) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.90s diff --git a/mseries/sdk-tests/receipts/2026-10-26/generated-source/Cargo.toml b/mseries/sdk-tests/receipts/2026-10-26/generated-source/Cargo.toml new file mode 100644 index 000000000..a8adb02eb --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/generated-source/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "msdk-sdksettings" +version = "0.1.0" +license = "GPL-3.0-only" +edition = "2024" +publish = false + +[workspace] + +[lib] +name = "app_model" + +[dependencies] +msdk = { path = "/work/sdk/msdk" } +msdk-gtk = { path = "/work/sdk/msdk-gtk" } +gtk = { package = "gtk4", version = "0.11", features = ["v4_20"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" diff --git a/mseries/sdk-tests/receipts/2026-10-26/generated-source/app.ui.json b/mseries/sdk-tests/receipts/2026-10-26/generated-source/app.ui.json new file mode 100644 index 000000000..9f2a4a0d7 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/generated-source/app.ui.json @@ -0,0 +1,109 @@ +{ + "sdk": 1, + "app": { + "id": "io.github.techmore.SdkSettings", + "name": "SDK Settings", + "icon": "preferences-system" + }, + "capabilities": [ + "filesystem:data" + ], + "state": { + "enabled": "bool", + "schedule": "text", + "show_hint": "bool" + }, + "initial": { + "enabled": true, + "schedule": "Weekdays", + "show_hint": false + }, + "persist": [ + "enabled", + "schedule" + ], + "messages": { + "SetEnabled": "bool", + "SetSchedule": "text", + "Reset": "none" + }, + "update": { + "SetEnabled": [ + { + "set": "enabled", + "to": "$payload" + }, + { + "toast": "Saved" + } + ], + "SetSchedule": [ + { + "set": "schedule", + "to": "$payload" + }, + { + "toast": "Saved" + } + ], + "Reset": [ + { + "set": "enabled", + "to": true + }, + { + "set": "schedule", + "to": "Weekdays" + }, + { + "toast": "Settings reset" + } + ] + }, + "surfaces": { + "main": { + "kind": "window", + "title": "SDK Settings", + "body": { + "type": "Box", + "direction": "column", + "spacing": "large", + "children": [ + { + "type": "Text", + "text": "Work mode", + "text_style": "title" + }, + { + "type": "Card", + "children": [ + { + "type": "Switch", + "label": "Turn on work mode", + "bind": "enabled", + "on_change": "SetEnabled" + }, + { + "type": "Dropdown", + "label": "Schedule", + "bind": "schedule", + "options": [ + "Weekdays", + "Every day", + "Manual" + ], + "on_change": "SetSchedule" + } + ] + }, + { + "type": "Button", + "label": "Reset to defaults", + "on": "Reset", + "button_style": "flat" + } + ] + } + } + } +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/generated-source/src/lib.rs b/mseries/sdk-tests/receipts/2026-10-26/generated-source/src/lib.rs new file mode 100644 index 000000000..a01fe50d5 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/generated-source/src/lib.rs @@ -0,0 +1,48 @@ +// Generated by msdk gen. Edit the description and regenerate in a new directory. +#![allow(non_snake_case, non_camel_case_types)] +pub mod records {} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct State { + #[serde(rename = "enabled")] + pub r#enabled: bool, + #[serde(rename = "schedule")] + pub r#schedule: String, + #[serde(rename = "show_hint")] + pub r#show_hint: bool, +} +impl State { + pub fn initial() -> Result { + Self::from_store(msdk::logic::initial_store(&document())) + } + pub fn from_store(store: msdk::logic::Store) -> Result { + serde_json::from_value(serde_json::Value::Object(store)) + } + pub fn into_store(self) -> Result { + match serde_json::to_value(self)? { + serde_json::Value::Object(store) => Ok(store), + _ => unreachable!("State serializes as an object"), + } + } +} +#[derive(Debug, Clone, PartialEq)] +pub enum Message { + r#SetEnabled(bool), + r#SetSchedule(String), + r#Reset, +} +impl Message { + pub fn into_event(self) -> (String, Option) { + match self { + Self::r#SetEnabled(value) => ("SetEnabled".into(), Some(serde_json::json!(value))), + Self::r#SetSchedule(value) => ("SetSchedule".into(), Some(serde_json::json!(value))), + Self::r#Reset => ("Reset".into(), None), + } + } +} + +/// The checked description embedded in this application. +pub fn document() -> serde_json::Value { + static REGISTER: std::sync::OnceLock<()> = std::sync::OnceLock::new(); + REGISTER.get_or_init(|| {}); + serde_json::from_str(include_str!("../app.ui.json")).expect("generated checked description") +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/generated-source/src/main.rs b/mseries/sdk-tests/receipts/2026-10-26/generated-source/src/main.rs new file mode 100644 index 000000000..20be0b309 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/generated-source/src/main.rs @@ -0,0 +1,66 @@ +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +use gtk::prelude::*; + +fn main() -> gtk::glib::ExitCode { + // Screenshot mode is an explicit developer check. Normal activation keeps + // the stable app ID and presents the existing window. + let args: Vec<_> = std::env::args().skip(1).collect(); + let shot = match args.as_slice() { + [] => None, + [flag, path] if flag == "--screenshot" => Some(std::path::PathBuf::from(path)), + _ => { + eprintln!("usage: application [--screenshot output.png]"); + return gtk::glib::ExitCode::from(2); + } + }; + let app = gtk::Application::builder() + .application_id("io.github.techmore.SdkSettings") + .build(); + let quit = gtk::gio::SimpleAction::new("quit", None); + let weak = app.downgrade(); + quit.connect_activate(move |_, _| { + if let Some(app) = weak.upgrade() { + for window in app.windows() { + window.close(); + } + } + }); + app.add_action(&quit); + app.set_accels_for_action("app.quit", &["q"]); + let keep = RefCell::new(None::>); + let failed = Rc::new(Cell::new(false)); + let failure = failed.clone(); + app.connect_activate(move |app| { + if let Some(host) = keep.borrow().as_ref() { + host.window().present(); + return; + } + let Some(host) = + msdk_gtk::host::Host::open_doc(app, app_model::document(), None, "main", None, false) + else { + failure.set(true); + app.quit(); + return; + }; + if let Some(path) = shot.clone() { + let (host, app, failure) = (host.clone(), app.clone(), failure.clone()); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(800), move || { + if let Err(error) = host.screenshot(&path) { + eprintln!("screenshot failed: {error}"); + failure.set(true); + } + host.window().close(); + app.quit(); + }); + } + *keep.borrow_mut() = Some(host); + }); + let status = app.run_with_args::<&str>(&[]); + if failed.get() { + gtk::glib::ExitCode::FAILURE + } else { + status + } +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/identity.txt b/mseries/sdk-tests/receipts/2026-10-26/identity.txt new file mode 100644 index 000000000..092453f71 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/identity.txt @@ -0,0 +1,3 @@ +e68aefa505ea9f16eeb8d475d6997f4340cd10e3cfe31b9d504ed92e78c91feb /work/target/debug/msdk-sdksettings +e68aefa505ea9f16eeb8d475d6997f4340cd10e3cfe31b9d504ed92e78c91feb /usr/bin/io.github.techmore.SdkSettings +ebc6015c44c2adc4ebe394ef3f0561edfab0ab5900b3230130e95a0feb69f317 /work/evidence/final/settings.deb diff --git a/mseries/sdk-tests/receipts/2026-10-26/install-output.txt b/mseries/sdk-tests/receipts/2026-10-26/install-output.txt new file mode 100644 index 000000000..bf8c38bc2 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/install-output.txt @@ -0,0 +1,13 @@ +Selecting previously unselected package msdk-io.github.techmore.sdksettings. +(Reading database ... 34691 files and directories currently installed.) +Preparing to unpack .../evidence/final/settings.deb ... +Unpacking msdk-io.github.techmore.sdksettings (0.1.0) ... +Setting up msdk-io.github.techmore.sdksettings (0.1.0) ... +Processing triggers for desktop-file-utils (0.28-1build1) ... +Processing triggers for hicolor-icon-theme (0.18-2build1) ... +(Reading database ... 34697 files and directories currently installed.) +Preparing to unpack .../evidence/final/settings.deb ... +Unpacking msdk-io.github.techmore.sdksettings (0.1.0) over (0.1.0) ... +Setting up msdk-io.github.techmore.sdksettings (0.1.0) ... +Processing triggers for desktop-file-utils (0.28-1build1) ... +Processing triggers for hicolor-icon-theme (0.18-2build1) ... diff --git a/mseries/sdk-tests/receipts/2026-10-26/installed-output.txt b/mseries/sdk-tests/receipts/2026-10-26/installed-output.txt new file mode 100644 index 000000000..fec3d014b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/installed-output.txt @@ -0,0 +1,7 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16908]: [session uid=0 pid=16908 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.0' (uid=0 pid=16909 comm="/usr/bin/io.github.techmore.SdkSettings --screensh" label="unconfined") +dbus-daemon[16908]: [session uid=0 pid=16908 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16935]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16909 comm="/usr/bin/io.github.techmore.SdkSettings --screensh" label="unconfined") +dbus-daemon[16935]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry diff --git a/mseries/sdk-tests/receipts/2026-10-26/lifecycle-output.txt b/mseries/sdk-tests/receipts/2026-10-26/lifecycle-output.txt new file mode 100644 index 000000000..a6a22fb85 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/lifecycle-output.txt @@ -0,0 +1,17 @@ + Compiling msdk v0.1.0 (/work/sdk/msdk) + Compiling msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Finished `test` profile [unoptimized + debuginfo] target(s) in 2.88s + Running tests/lifecycle.rs (/work/target/debug/deps/lifecycle-db6f2c449ec8827b) + +running 1 test +test closing_stops_owned_work_ignores_late_events_and_releases_the_host ... libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[14794]: [session uid=0 pid=14794 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=15438 comm="/work/target/debug/deps/lifecycle-db6f2c449ec8827b" label="unconfined") +dbus-daemon[14794]: [session uid=0 pid=14794 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[15461]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=15438 comm="/work/target/debug/deps/lifecycle-db6f2c449ec8827b" label="unconfined") +dbus-daemon[15461]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.78s + diff --git a/mseries/sdk-tests/receipts/2026-10-26/lint-output.txt b/mseries/sdk-tests/receipts/2026-10-26/lint-output.txt new file mode 100644 index 000000000..91526fdc8 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/lint-output.txt @@ -0,0 +1,3 @@ + Checking msdk v0.1.0 (/work/sdk/msdk) + Checking msdk-gtk v0.1.0 (/work/sdk/msdk-gtk) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.95s diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix-output.txt b/mseries/sdk-tests/receipts/2026-10-26/matrix-output.txt new file mode 100644 index 000000000..06acc7f53 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/matrix-output.txt @@ -0,0 +1,80 @@ +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16247]: [session uid=0 pid=16247 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16264 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16247]: [session uid=0 pid=16247 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16292]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16264 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16292]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16321]: [session uid=0 pid=16321 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16338 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16321]: [session uid=0 pid=16321 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16366]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16338 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16366]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16396]: [session uid=0 pid=16396 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16413 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16396]: [session uid=0 pid=16396 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16441]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16413 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16441]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16470]: [session uid=0 pid=16470 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16487 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16470]: [session uid=0 pid=16470 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16515]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16487 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16515]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16544]: [session uid=0 pid=16544 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16561 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16544]: [session uid=0 pid=16544 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16589]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16561 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16589]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 10 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16618]: [session uid=0 pid=16618 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16635 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16618]: [session uid=0 pid=16618 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16663]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16635 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16663]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16693]: [session uid=0 pid=16693 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16710 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16693]: [session uid=0 pid=16693 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16738]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16710 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16738]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +GTK font profile: Sans 15 +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +dbus-daemon[16767]: [session uid=0 pid=16767 pidfd=5] Activating service name='org.a11y.Bus' requested by ':1.1' (uid=0 pid=16784 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16767]: [session uid=0 pid=16767 pidfd=5] Successfully activated service 'org.a11y.Bus' +dbus-daemon[16812]: Activating service name='org.a11y.atspi.Registry' requested by ':1.0' (uid=0 pid=16784 comm="/work/target/debug/msdk-sdksettings --screenshot /" label="unconfined") +dbus-daemon[16812]: Successfully activated service 'org.a11y.atspi.Registry' +SpiRegistry daemon is running with well-known name - org.a11y.atspi.Registry diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1-width480.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1-width480.png new file mode 100644 index 000000000..89563cc6f Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1-width480.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1-width900.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1-width900.png new file mode 100644 index 000000000..32defe512 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1-width900.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1.5-width480.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1.5-width480.png new file mode 100644 index 000000000..b8ba5b927 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1.5-width480.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1.5-width900.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1.5-width900.png new file mode 100644 index 000000000..4775837dc Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/dark-text1.5-width900.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1-width480.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1-width480.png new file mode 100644 index 000000000..541ee7630 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1-width480.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1-width900.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1-width900.png new file mode 100644 index 000000000..0051cc045 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1-width900.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1.5-width480.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1.5-width480.png new file mode 100644 index 000000000..1e7a9a497 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1.5-width480.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1.5-width900.png b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1.5-width900.png new file mode 100644 index 000000000..6d2baa9e7 Binary files /dev/null and b/mseries/sdk-tests/receipts/2026-10-26/matrix/light-text1.5-width900.png differ diff --git a/mseries/sdk-tests/receipts/2026-10-26/ownership-removal.txt b/mseries/sdk-tests/receipts/2026-10-26/ownership-removal.txt new file mode 100644 index 000000000..f1d3b030b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/ownership-removal.txt @@ -0,0 +1 @@ +all five owned artifact classes removed diff --git a/mseries/sdk-tests/receipts/2026-10-26/package-info.txt b/mseries/sdk-tests/receipts/2026-10-26/package-info.txt new file mode 100644 index 000000000..6bdbbca2c --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/package-info.txt @@ -0,0 +1,9 @@ + new Debian package, version 2.0. + size 11307984 bytes: control archive=386 bytes. + 465 bytes, 6 lines control + Package: msdk-io.github.techmore.sdksettings + Version: 0.1.0 + Architecture: amd64 + Maintainer: SDK app developer + Description: Application built with the M-series SDK + Depends: libc6 (>= 2.39), libcairo-gobject2 (>= 1.10.0), libcairo2 (>= 1.2.4), libgcc-s1 (>= 4.2), libgdk-pixbuf-2.0-0 (>= 2.22.0), libglib2.0-0t64 (>= 2.54.0), libgraphene-1.0-0 (>= 1.5.4), libgtk-4-1 (>= 4.12.0), libpango-1.0-0 (>= 1.14.0), libwayland-client0 (>= 1.20.0) diff --git a/mseries/sdk-tests/receipts/2026-10-26/package-output.txt b/mseries/sdk-tests/receipts/2026-10-26/package-output.txt new file mode 100644 index 000000000..2b01b7f4b --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/package-output.txt @@ -0,0 +1 @@ +created /work/evidence/final/settings.deb; no installation performed diff --git a/mseries/sdk-tests/receipts/2026-10-26/remove-output.txt b/mseries/sdk-tests/receipts/2026-10-26/remove-output.txt new file mode 100644 index 000000000..e33814b67 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/remove-output.txt @@ -0,0 +1,4 @@ +(Reading database ... 34694 files and directories currently installed.) +Removing msdk-io.github.techmore.sdksettings (0.1.0) ... +Processing triggers for hicolor-icon-theme (0.18-2build1) ... +Processing triggers for desktop-file-utils (0.28-1build1) ... diff --git a/mseries/sdk-tests/receipts/2026-10-26/schema.json b/mseries/sdk-tests/receipts/2026-10-26/schema.json new file mode 100644 index 000000000..07a749013 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/schema.json @@ -0,0 +1,5 @@ +{ + "valid_descriptions": 11, + "malformed_actions_rejected_by_both": 7, + "validator": "jsonschema.Draft202012Validator" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/sdk-Cargo.lock b/mseries/sdk-tests/receipts/2026-10-26/sdk-Cargo.lock new file mode 100644 index 000000000..4fa98c129 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/sdk-Cargo.lock @@ -0,0 +1,735 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "cairo-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df683f1d30b457964673a5541a4603208ef95ab6873d2a55871895cf310f3b56" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee548131103ad8f698c6725669647b9c757b3b66992dd6a026037596417bee21" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba9e9ec16c447027685b1f897b720e18e9a8afd00bd7332c483537e38086c9f" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f420376dbee041b2db374ce4573892a36222bb3f6c0c43e24f0d67eae9b646" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5209294ba3775f9b650bf78bfadeba4332089f2329b3e2f6ce0a4957a45bff" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77c579bac9eff8b84c0625d5f533da6d69988c063062fe92c2e955ede8f28eb" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eff6238a30c1f198fb3c8d3d445fa7faf211d11d9075af0772e6e0ca32ae001" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620fbafdf19dba814473e19f18e75290cb3338662f6ae35f0402affd3b2b699" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28739f914c15b87a9856000bed9cbd5b3a8afbca5e982d9a299e1601422cb5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys", +] + +[[package]] +name = "glib" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cf9e5bd8713f1990a92c422998826e0fb34824277b46bc59757373483c6694" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9597c68fa7bdf4154a3079642cd21c4dccac0b0bdd2897d82861523bf91e7b9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b38907e67e40dec9b60f858bcada952598719cb512a13eb13d6cdcd16f8295" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07595c9ba696bd9819cb6a8df39f08078f3dd679508fe052dd558492c2053834" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb856b9c558971c3f13ab692358926da710b046932a4e087aedcc35b040d7dff" +dependencies = [ + "glib", + "graphene-sys", +] + +[[package]] +name = "graphene-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97842c7543828f98aa5583aa54fcda28aa84fa2b0f8c556142177f7bbb638057" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee23d7425c5281ec5a2f40f7b69384aac66c15861d990d248e9d9c9368be464" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27900c92e47df410bbe43b51818104051e3409da43fb88547a41c0bafddfd39c" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8226c94dd0b65ba2e8fcd8ff402d380e890f6e5a6488e652a0158e827b9bf" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb906c98f0b4cc9002594e337e83f40492aa6dca22c97242f13be5b046c5f338" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd14af0137f269bdecee73404157d2a852f9651af7d68bd1023d3b8b914a14c3" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "msdk" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "msdk-gtk" +version = "0.1.0" +dependencies = [ + "cc", + "futures-channel", + "futures-util", + "gtk4", + "msdk", + "pkg-config", + "serde_json", +] + +[[package]] +name = "pango" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2022dbbd82e1c42bd950a6f1df9b98c796e725dce5ec275e03cbf9772e4efa" +dependencies = [ + "gio", + "glib", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca02d64761b74d56cdd4b437db6d73dc95e6c0d40f27e1c707952c0f09052948" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "foldhash", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0dae2cbca1f0ff93795713cfe0a4c02f760e3c0b8ae2ab4ec4045808ff429f" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mseries/sdk-tests/receipts/2026-10-26/source-manifest.json b/mseries/sdk-tests/receipts/2026-10-26/source-manifest.json new file mode 100644 index 000000000..69db83cda --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/source-manifest.json @@ -0,0 +1,69 @@ +{ + "claude-pantheon-rs/sdk/t3.fixture.json": "37495cbaea4ce77ec1554be0888cb384bb1d6cacede8566da1244a95596e1f66", + "claude-pantheon-rs/sdk/t3.gates.json": "8ab25b5fb6b0b1b160ade03a0aa0d2d7d410ad2f696fbc2ca48eda3495e01785", + "claude-pantheon-rs/sdk/t3.msdk": "c0417f6ef558fd36113cf08f04bd80ee5d159de689544a31df99c89d67163d36", + "claude-pantheon-rs/sdk/t3.services.json": "4bfe5e8af0ca6b622fb3e2cc0843568be125216eb9d71275b9687045e9c0939a", + "msdk-gtk/Cargo.toml": "3a483c4d010058d3b51a39351653f5bea9ea81052d4985280a24516353d3e002", + "msdk-gtk/build.rs": "8b24b345f7b2567bbc3d7fbba7121dd4431f7ef887ca2b91601e57438c7209ee", + "msdk-gtk/src/autohide.rs": "c37af37b4b8a3929f8e70059cfefb185f8c4723707df42fa9d2ae75b207a3d0d", + "msdk-gtk/src/fixture.rs": "502577902f8ed4db5f684127c05f4e4e772539ed3b14b08dab6abc684ebb254c", + "msdk-gtk/src/host.rs": "2f4f1be0b862a373a9571c27f11019e3eaedcf4ef77680375193e4861f0582b4", + "msdk-gtk/src/lib.rs": "5cf6314cb78b09eaae903185b9f9156957ff41b8c41d82efd9d2c1d7c8449969", + "msdk-gtk/src/main.rs": "eaa3f1c506168cce35c227747bbf9e00bfd5b86ce67bfd24fddc39e31739fb1a", + "msdk-gtk/src/panel.c": "97a79fa8ff2d954d05ef94d280462d0589652a1a046ffabbc61ffb121955d8be", + "msdk-gtk/src/panel.rs": "d5027c263e6e35d8c3ef091fbd32a6b77b98c75d2b6b945ef231a8bcfdfa4fd1", + "msdk-gtk/src/render.rs": "5b8cee9fb4d6942f9b7df9e4e0fde6c63e8494ddb86aa63d6d2ec69b84bcd6dc", + "msdk-gtk/src/services.rs": "9ea28097cd34f3a156fd3f61ab91c251feadac5cb90508ca66d9a68e2b9ac7cf", + "msdk-gtk/tests/lifecycle.rs": "7cb2118689284c03d7cd4726c40284fee4d34daaa5c33a92a5a955df171f1b24", + "msdk/Cargo.toml": "22b824bccce4db47458ca5e8225a07e397ce983702f923ed1a8d53335c414a68", + "msdk/LICENSE": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903", + "msdk/README.md": "42496af1846e02bbd14c23e629a19a8d4c2bdfa3d1f9ad37822de808f496dc55", + "msdk/data/tokens.json": "6fe6dcceb3b6dec8fbaa16cb99b58309a9cd2a864c6b0aa038fb2dcd74ffb318", + "msdk/examples/disk-space.ui.json": "c895b504c1e48def76b9adabac5622a67d2dde3977bf01e7d1e64f0b9ce6a03e", + "msdk/examples/dock.ui.json": "bab71d5d1daf4aee97f3d5cddd5d04a9036a36044b41afde1b03f6dc8bc7eb2b", + "msdk/examples/quick-notes.gates.json": "442878334e732d89f2360cd082fd9e118d23dd607ef080e775d87fe7fc601db6", + "msdk/examples/quick-notes.ui.json": "a010dc9b9c412eb2ea93cdb27df3a49daf1d68f5705ceb670221a4d982069c09", + "msdk/rustfmt.toml": "93ed1668bb2ca659e88711456b72320bf2f53369ecf278c4a61af0cb63cc3a1e", + "msdk/src/agent.rs": "4d4c9c9feeabb79f69c2957a1bdc9d95bd02c48e9a2c69745374132169745b9c", + "msdk/src/check.rs": "5fdca8af4df80570c56bf509d89a9957350f067552e1e2c3277c8066e0fcc329", + "msdk/src/contrast.rs": "3745291c77b8aae2e868fcd494f371d508bedf6b767ee17839e176f87857df25", + "msdk/src/gate.rs": "e1c29a95f8f85163c0e040ce7f2097faa6ad810e6a6c0dde5ff4d0d228207e74", + "msdk/src/generate.rs": "b3e76e46bbd48ca3b72316faa5c368b11ac84262d712f84d1d066570ffbc0743", + "msdk/src/inspect.rs": "e36f363541eaa284061ab190aa289590f80fe07f421d5a1106a7e57f4117a5ac", + "msdk/src/intents.rs": "1d4ac05bca14fc87758082065732303ca88ca747543a9f0ecd39093fde139458", + "msdk/src/lib.rs": "93f1cb63c7e73a3c8b911b2dcc326e9f34e638a09cd1fa02402485995ae684e8", + "msdk/src/logic.rs": "254302351e3e0d43607f6870e7bbc5d1af2c9c1b53ff60aab7e85d624855928a", + "msdk/src/main.rs": "93bd6eec5d6bcecda6df66b6ac3742adfbb023da47c748bd1249a9923d77767e", + "msdk/src/package.rs": "cbee1b840dcdb67c3403977022e34899dfa1750262ce47ea29efb13cc099ab58", + "msdk/src/schema.rs": "77aceed6d8a9af050d1f3a20f8c1d2c8c6f1f086ed0cbd5dde867cc44ef204db", + "msdk/src/templates.rs": "984afdd7909d0016884319ff16e2df3c9865ab40a982e05ddb56bc945ad49f24", + "msdk/src/text/lex.rs": "26a591a2d6309b2511b588280af896997dae24584f25a1f61f92b7530f68f582", + "msdk/src/text/mod.rs": "118d393dccfba52dd104b40eb45c995a9c53433fa43040219396d32d36eb7b21", + "msdk/src/text/names.rs": "2991aef49e46d3e3fc8660f81444701c1d9fc27032294643f947284ffa57337c", + "msdk/src/text/parse.rs": "fc72828fc73d42598c208423b32681e715e71f549b3af64c2d7da806e93627bd", + "msdk/src/text/print.rs": "181cf902c2972aeb608d75f5597d5286c4a4237e9b8aaf5251ab460ab87755dc", + "msdk/src/tokens.rs": "f0386b693f7e6fcec0ddf005d83389d71c87d61ab1c49bcae6c9febc4cd61d63", + "msdk/src/vocab.rs": "c0e88f3cb9ad1b1e16ad7ad041e2df88fe6456409b1da6ad5994d86adfe35700", + "msdk/templates/dashboard/app.gates.json": "50ea292e7e4168d56964d23570b3bb9fe0e3cd5f1e82de0998f0c85f1e898e58", + "msdk/templates/dashboard/app.ui.json": "4137de4f469f0434f4c017d38fe4f199fe3a7cf0df6f66e090b05b048a080b5f", + "msdk/templates/launcher-panel/app.gates.json": "0116e384c88b67981f3f734ddb19999fdf8e08b3f90d34e0d4666578aa3858b9", + "msdk/templates/launcher-panel/app.ui.json": "560e958a132c82174a128eb45e16f2365cb1a5248ec704c04ada28367101de07", + "msdk/templates/project/main.rs": "45de731ef4d3254b69f1aa0ee9b2e708de6ea1a661bbac2bd72d0f134d19a757", + "msdk/templates/settings/app.gates.json": "fe17eb506a5b221fcbb89cb7a71538146d7baa9371e4c032598e086f9e17801b", + "msdk/templates/settings/app.ui.json": "96238210097a6396726541e523805695a5b59cb218c56e365308e8186b439ce8", + "msdk/templates/task-runner/app.gates.json": "138177f75cc8fdcc15fa86dd848537231f68ac3df1df28dad5a88bf3b7152815", + "msdk/templates/task-runner/app.ui.json": "e7892497de47718eb692f8d55d6a97adca7420312aa9325f174edf1b09d20a54", + "msdk/templates/wizard/app.gates.json": "aff06f5f9c6fdce25178a07224ed164a9977d28598b17f5c299dfce88f876ed1", + "msdk/templates/wizard/app.ui.json": "6d36c8c6a2cb51804f5f0aa6b1fcec2882ef766de521b98d1ed241c4f60aee1a", + "msdk/tests/agent.rs": "9ab9008e420f153354c4f3299a3ff8451e0a8e1998d2b3e497310ddd6861747d", + "msdk/tests/check.rs": "180ab2c4fbff197db7c359e6137f4b38457f2b34110ce753d48dc61eed178b80", + "msdk/tests/generate.rs": "c3db4da4abe7c482f38dcb38315d313a247fdfb36047a4ddf86ce8fc66482a5e", + "msdk/tests/inspect.rs": "fa7f86960060130bc725c96b9dcde7bbefbf050f1119303a98012432031475d8", + "msdk/tests/intents.rs": "3a892a0abea5b89a13dd15a7e6495e377707cfc2e94ab143fb135248eecd3e68", + "msdk/tests/package.rs": "4a00fb4c008b9809bb008a85ee39d7bd25c41b94d1ecbe92fb7fb05497c5ca87", + "msdk/tests/t3.rs": "0c253e3ee0b40c8fb99b50f244ff5d5eef4e9b83b4cd279594bac5d85ab4cb2b", + "msdk/tests/templates.rs": "9df49cbb3ce5895c5c36f1b6c82fbfb3e93096cf80d8e2b7cce712afeb19031f", + "msdk/tests/text.rs": "0f2a32166c9e5334a37bdd111b82ed43abfe758a49dcc742c2d895f3c0fd6d57", + "mseries-greeter/data/greeter.ui.json": "4c5b880dee17dfbc0a4990118eaf0df3f0aacfe7767f448f9d15145972dbf93d", + "pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml": "12498aa3273701b19eb599791bac7bc5b30492b11057c9835e84c8cb70541ba4" +} diff --git a/mseries/sdk-tests/receipts/2026-10-26/summary.json b/mseries/sdk-tests/receipts/2026-10-26/summary.json new file mode 100644 index 000000000..aa311e748 --- /dev/null +++ b/mseries/sdk-tests/receipts/2026-10-26/summary.json @@ -0,0 +1,114 @@ +{ + "status": "partial SDK qualification; full goal remains active", + "source_commit": "287886e3b4399c742bf286bbaf3905b36439467d", + "source_fingerprints_matched": 67, + "environment": { + "host": "SER8", + "isolation": "new unprivileged ephemeral Incus container; private Xvfb/D-Bus; synthetic XDG state", + "os": "Ubuntu 26.04", + "architecture": "x86_64", + "rust": "1.93.1", + "gtk": "4.22.4", + "renderer": "cairo", + "container_limits": { + "memory": "6GiB", + "cpu": 4 + } + }, + "verified": { + "core_tests_passed": 65, + "strict_core_and_runtime_lint": "pass", + "generated_app_build_tests_lint": "pass", + "native_dbus_lifecycle": "pass: enabled reads, close veto, accepted close, stopped polling, ignored late events, disabled zero reads, Host released", + "schema": { + "valid_descriptions": 11, + "malformed_actions_rejected_by_both": 7, + "validator": "jsonschema.Draft202012Validator" + }, + "keyboard_accessibility": [ + "live accessible names and roles", + "Tab reaches switch; Space changes persisted state", + "Tab reaches dropdown; keyboard selection saves", + "Tab reaches reset; Space restores defaults", + "Ctrl+Q closes cleanly" + ], + "render_matrix": { + "screenshots": 8, + "themes": [ + "Adwaita light", + "Adwaita dark" + ], + "widths": [ + 480, + 900 + ], + "height": 400, + "font_profiles": [ + "Sans 10", + "Sans 15" + ], + "font_setting_asserted": true, + "reviewer": "Codex visual inspection", + "result": "labels/actions readable and unclipped in all eight captured states", + "owner_accepted": false + }, + "package": "AppStream/desktop validation; actual ELF architecture and native dependencies; fresh install, reinstall, byte equality, installed launch and all owned files removed" + }, + "artifact_sha256": { + "built_and_installed_binary": "e68aefa505ea9f16eeb8d475d6997f4340cd10e3cfe31b9d504ed92e78c91feb", + "development_deb": "ebc6015c44c2adc4ebe394ef3f0561edfab0ab5900b3230130e95a0feb69f317" + }, + "retained_failures": [ + "first CI offline generated test lacked provisioned serde derive; fixed dependency/lock", + "generated empty records module had unused imports; fixed qualified derives", + "Azure CI provisioning exceeded 25 minute job limit; official Ubuntu ports selected", + "AppStream rejected uppercase developer ID and absent homepage; corrected metadata", + "initial custom window controls were oversized; native theme controls restored", + "first AT-SPI probe selected static labels; repaired selection of named interactive roles", + "GDK_DPI_SCALE had no visible effect; those images are excluded from larger-text acceptance; real GTK font profiles now asserted", + "schema probe encountered AppleDouble metadata from an early source archive; filter and source preparation corrected" + ], + "ci_reference_runs": [ + "https://github.com/techmore/ElementaryOS_MSeries/actions/runs/40354229616", + "https://github.com/techmore/ElementaryOS_MSeries/actions/runs/40354775593", + "https://github.com/techmore/ElementaryOS_MSeries/actions/runs/40355512113" + ], + "remaining": [ + "versioned OS/service API and structured recoverable errors", + "bounded/cancelable/streaming process work and app adapter lifecycle", + "reusable native status module and both desktop-profile host contracts", + "T3 real provider/account/GitHub semantic and interaction conformance", + "complete golden path and controlled repeated model usability trials", + "same-host resource/performance baseline", + "supported architecture/distro packaging and target Pantheon/physical scale/owner acceptance", + "final v1 compatibility/deprecation contract and full requirement audit" + ], + "qualification_limits": [ + "settings starter scenario only", + "no physical Apple Silicon/Wayland/owner desktop acceptance", + "no GPU performance or screen-reader narration result", + "no model trial or 30-minute novice claim", + "development metadata must be reviewed before public app distribution", + "Signal/Messages remain deferred" + ], + "harness_sha256": { + "check-schema.py": "076d5cfb001fc1a8b0bc9aff9e5691c8c93f8f1315633033e745dc34d2c6a62f", + "controls.py": "6fc6cdb5463c7f9eb07b6353ff3f62d406af78ccbfcd4480073006a677462ba2", + "font-profile.py": "0a7910365b44226f39abac2a747d664c0ad95821dbd113ec0f85d383a0899019", + "prepare.py": "93b81dedef01caa7afaf7275557a20bafabbb822972f6febe56edad74b29e4b3", + "render-matrix.sh": "466c1d5afccdcc24cf8732cc5626326719baee9e01b9e2a77aaa5d95bd6609ff", + "source-manifest.py": "be345646804d6d1c54eef7ed3a8b0ea50fa946583037c94a19baf12ae5088868" + }, + "retained_output_files": { + "installed": "installed-output.txt", + "controls": "controls-output.txt", + "core": "core-output.txt", + "lint": "lint-output.txt", + "lifecycle": "lifecycle-output.txt", + "generated": "generated-output.txt", + "remove": "remove-output.txt", + "matrix": "matrix-output.txt", + "install": "install-output.txt", + "package": "package-output.txt" + } +} diff --git a/mseries/sdk-tests/render-matrix.sh b/mseries/sdk-tests/render-matrix.sh new file mode 100644 index 000000000..5eae64e95 --- /dev/null +++ b/mseries/sdk-tests/render-matrix.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Actual generated executable; private desktops and synthetic state only. +set -euo pipefail +sdk_matrix_binary=$(realpath "$1") +sdk_matrix_output=$2 +sdk_matrix_probe=$(realpath "$(dirname "$0")/font-profile.py") +test ! -e "$sdk_matrix_output" +mkdir -p "$sdk_matrix_output" +sdk_matrix_output=$(realpath "$sdk_matrix_output") +for sdk_matrix_theme in light dark; do + sdk_matrix_gtk_theme=Adwaita + if [ "$sdk_matrix_theme" = dark ]; then sdk_matrix_gtk_theme=Adwaita:dark; fi + for sdk_matrix_text in 1 1.5; do + for sdk_matrix_width in 480 900; do + sdk_matrix_file="$sdk_matrix_output/$sdk_matrix_theme-text$sdk_matrix_text-width$sdk_matrix_width.png" + sdk_matrix_points=10 + if [ "$sdk_matrix_text" = 1.5 ]; then sdk_matrix_points=15; fi + sdk_matrix_config="$sdk_matrix_output/config-$sdk_matrix_theme-$sdk_matrix_text-$sdk_matrix_width" + mkdir -p "$sdk_matrix_config/gtk-4.0" + printf '[Settings]\ngtk-font-name=Sans %s\n' "$sdk_matrix_points" > "$sdk_matrix_config/gtk-4.0/settings.ini" + MSDK_MATRIX_PROBE="$sdk_matrix_probe" MSDK_MATRIX_POINTS="$sdk_matrix_points" MSDK_MATRIX_BIN="$sdk_matrix_binary" MSDK_MATRIX_FILE="$sdk_matrix_file" \ + MSDK_MATRIX_WIDTH="$sdk_matrix_width" XDG_DATA_HOME="$sdk_matrix_output/state" \ + XDG_CONFIG_HOME="$sdk_matrix_config" GTK_THEME="$sdk_matrix_gtk_theme" \ + GDK_SCALE=1 GSK_RENDERER=cairo \ + xvfb-run -a dbus-run-session -- bash -eu -c ' + python3 "$MSDK_MATRIX_PROBE" + "$MSDK_MATRIX_BIN" --screenshot "$MSDK_MATRIX_FILE" & + sdk_matrix_pid=$! + trap '\''kill "$sdk_matrix_pid" 2>/dev/null || true'\'' EXIT + sdk_matrix_window=$(timeout 8 xdotool search --sync --name "^SDK Settings$" | head -1) + xdotool windowsize --sync "$sdk_matrix_window" "$MSDK_MATRIX_WIDTH" 400 + wait "$sdk_matrix_pid" + trap - EXIT + ' + test -s "$sdk_matrix_file" + done + done +done diff --git a/mseries/sdk-tests/source-manifest.py b/mseries/sdk-tests/source-manifest.py new file mode 100644 index 000000000..4f613ad5b --- /dev/null +++ b/mseries/sdk-tests/source-manifest.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +"""Fingerprint the exact SDK source/fixture closure independently of build caches.""" +import argparse +import hashlib +import json +import os +from pathlib import Path + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('rust_root', type=Path) +args = parser.parse_args() +root = args.rust_root.resolve() +files = [] +for name in ('msdk', 'msdk-gtk', 'claude-pantheon-rs/sdk'): + for directory, children, names in os.walk(root / name): + children[:] = sorted(child for child in children if child not in ('target', '.git', '__pycache__')) + for filename in sorted(names): + if filename == 'Cargo.lock' or filename.startswith('._'): + continue + files.append(Path(directory) / filename) +files += [root / 'mseries-greeter/data/greeter.ui.json', + root / 'pantheon-compositor/protocol/pantheon-desktop-shell-v1.xml'] +manifest = {str(path.relative_to(root)): hashlib.sha256(path.read_bytes()).hexdigest() for path in sorted(files)} +print(json.dumps(manifest, indent=2, sort_keys=True)) diff --git a/mseries/sdk-tests/status-host-integration.vala b/mseries/sdk-tests/status-host-integration.vala new file mode 100644 index 000000000..083fbe636 --- /dev/null +++ b/mseries/sdk-tests/status-host-integration.vala @@ -0,0 +1,71 @@ +/* Exercises the shared T3 menu in either status host, with isolated neighbors. */ +private Gtk.Stack? find_pages (Gtk.Widget widget) { + if (widget is Gtk.Stack) { + var stack = (Gtk.Stack) widget; + if (stack.get_child_by_name ("sdk-usage") != null) return stack; + } + for (var child = widget.get_first_child (); child != null; child = child.get_next_sibling ()) { + var found = find_pages (child); + if (found != null) return found; + } + return null; +} +private bool has_label (Gtk.Widget widget, string expected) { + if (widget is Gtk.Label && ((Gtk.Label) widget).label == expected) return true; + for (var child = widget.get_first_child (); child != null; child = child.get_next_sibling ()) + if (has_label (child, expected)) return true; + return false; +} +private bool wait_label (Gtk.Widget widget, string expected) { + for (int i = 0; i < 500; i++) { + while (GLib.MainContext.default ().iteration (false)) { } + if (has_label (widget, expected)) return true; + GLib.Thread.usleep (10000); + } + return false; +} +private bool wait_reads (string path, int expected) { + for (int i = 0; i < 500; i++) { + while (GLib.MainContext.default ().iteration (false)) { } + try { + string text; + if (GLib.FileUtils.get_contents (path, out text) && text.length == expected) return true; + } catch (GLib.Error error) { } + GLib.Thread.usleep (10000); + } + return false; +} +int main (string[] args) { + assert (args.length == 3); + bool hosted = args[2] == "wingpanel"; + assert (hosted || args[2] == "dock"); + Gtk.init (); + var window = new Gtk.Window (); + var anchor = new Gtk.Button.with_label ("T3"); + var host = new Dock.TaskbarT3RPopover (anchor, 28, hosted); + window.child = hosted ? host.get_host_widget () : anchor; + window.present (); + if (hosted) host.open_host (); + else host.toggle_from_icon (); + assert (!GLib.FileUtils.test (args[1], GLib.FileTest.EXISTS)); + var pages = find_pages (hosted ? (Gtk.Widget) window : (Gtk.Widget) anchor); + assert (pages != null); + pages.visible_child_name = "sdk-usage"; + assert (wait_reads (args[1], 1)); + assert (wait_label (pages, "7 day: 75% remaining")); + pages.visible_child_name = "server"; + pages.visible_child_name = "sdk-usage"; + assert (wait_reads (args[1], 2)); + host.close_host (); + window.child = null; + for (int i = 0; i < 50; i++) { + while (GLib.MainContext.default ().iteration (false)) { } + GLib.Thread.usleep (10000); + } + string read_log; + assert (GLib.FileUtils.get_contents (args[1], out read_log)); + assert (read_log.length == 2); + host.dispose (); + window.destroy (); + return 0; +} diff --git a/mseries/sdk-tests/status-host-stubs.vala b/mseries/sdk-tests/status-host-stubs.vala new file mode 100644 index 000000000..bb50326b1 --- /dev/null +++ b/mseries/sdk-tests/status-host-stubs.vala @@ -0,0 +1,17 @@ +/* Synthetic neighboring indicators for an isolated shared-menu integration test. */ +namespace MSeries { + public class CodexBarIndicator : GLib.Object { + private Gtk.Box widget = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + public CodexBarIndicator (bool on_demand = false) { } + public Gtk.Widget get_widget () { return widget; } + public void opened () { } + public void closed () { } + } + public class RepoBarIndicator : GLib.Object { + private Gtk.Box widget = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + public RepoBarIndicator (bool on_demand = false) { } + public Gtk.Widget get_widget () { return widget; } + public void opened () { } + public void closed () { } + } +} diff --git a/mseries/sdk-tests/usage-anchor-controls.py b/mseries/sdk-tests/usage-anchor-controls.py new file mode 100644 index 000000000..244f18fce --- /dev/null +++ b/mseries/sdk-tests/usage-anchor-controls.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +"""Private X11/AT-SPI probe for the candidate usage status anchor.""" +import argparse +import datetime +import ctypes +import ctypes.util +import hashlib +import json +import os +from pathlib import Path +import shlex +import subprocess +import tempfile +import time +import pyatspi + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('--binary', type=Path, required=True) +parser.add_argument('--output', type=Path, required=True) +args = parser.parse_args() +assert os.environ.get('MSDK_PRIVATE_TEST_BUS') == '1', 'requires an isolated test session' +assert not args.output.exists(), 'preserve prior receipts; choose a new output' +report = {'binary_sha256': hashlib.sha256(args.binary.read_bytes()).hexdigest(), + 'environment': 'isolated X11 / private D-Bus / synthetic data', 'checks': []} + + +def walk(node, depth=0): + if depth > 35: + return + yield node + for child in node: + if child is not None: + yield from walk(child, depth + 1) + + +def key(name): + subprocess.run(['xdotool', 'key', '--clearmodifiers', name], check=True) + time.sleep(.05) + + +def point(item): + rect = item.queryComponent().getExtents(pyatspi.DESKTOP_COORDS) + assert rect.width > 0 and rect.height > 0, 'accessible control has no on-screen bounds' + return str(rect.x + rect.width // 2), str(rect.y + rect.height // 2) + + +def move_point(position): + subprocess.run(['xdotool', 'mousemove', '--sync', *map(str, position)], check=True) + + +def x11_pointer_child(): + # XQueryPointer reports the actual root child receiving pointer input, + # including shaped popup windows; xdotool's WINDOW is the active window. + x = ctypes.CDLL(ctypes.util.find_library('X11')) + x.XOpenDisplay.argtypes = [ctypes.c_char_p] + x.XOpenDisplay.restype = ctypes.c_void_p + x.XDefaultRootWindow.argtypes = [ctypes.c_void_p] + x.XDefaultRootWindow.restype = ctypes.c_ulong + x.XQueryPointer.argtypes = [ctypes.c_void_p, ctypes.c_ulong, ctypes.POINTER(ctypes.c_ulong), + ctypes.POINTER(ctypes.c_ulong), *([ctypes.POINTER(ctypes.c_int)] * 4), + ctypes.POINTER(ctypes.c_uint)] + x.XCloseDisplay.argtypes = [ctypes.c_void_p] + display = x.XOpenDisplay(None) + if not display: + raise RuntimeError('cannot open X display for pointer diagnostic') + try: + root, child = ctypes.c_ulong(), ctypes.c_ulong() + rx, ry, wx, wy = (ctypes.c_int() for _ in range(4)) + mask = ctypes.c_uint() + ok = x.XQueryPointer(display, x.XDefaultRootWindow(display), ctypes.byref(root), ctypes.byref(child), + ctypes.byref(rx), ctypes.byref(ry), ctypes.byref(wx), ctypes.byref(wy), ctypes.byref(mask)) + return {'ok': bool(ok), 'child': hex(child.value), 'root_x': rx.value, 'root_y': ry.value} + finally: + x.XCloseDisplay(display) + + +with tempfile.TemporaryDirectory(prefix='msdk-usage-anchor-') as directory: + root = Path(directory) + marker, executable = root / 'reads', root / 'fixture' + geometry, popup_geometry = root / 'geometry.json', root / 'popup.json' + observed = datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z') + snapshot = {'schemaVersion': 1, 'entries': [{'provider': 'codex', 'updatedAt': observed, + 'windows': [{'key': 'week', 'label': '7 day', 'remaining': 75, 'resetsAt': ''}]}]} + executable.write_text('#!/bin/sh\nprintf x >> ' + shlex.quote(str(marker)) + '\nprintf %s ' + + shlex.quote(json.dumps(snapshot)) + '\n') + executable.chmod(0o700) + env = dict(os.environ, XDG_DATA_HOME=str(root / 'data'), XDG_CONFIG_HOME=str(root / 'config'), + MSDK_ANCHOR_GEOMETRY=str(geometry), MSDK_POPUP_GEOMETRY=str(popup_geometry), MSDK_ANCHOR_TRACE="1") + with tempfile.TemporaryFile() as stdout, tempfile.TemporaryFile() as stderr: + subprocess.run(['xdotool', 'mousemove', '--sync', '0', '0'], check=True) + process = subprocess.Popen([str(args.binary.resolve()), str(executable)], env=env, stdout=stdout, stderr=stderr) + app = None + try: + def wait(predicate, message, timeout=8): + end = time.monotonic() + timeout + while time.monotonic() < end: + if process.poll() is not None: + raise RuntimeError(f'fixture app exited early ({process.returncode}); see process_stderr') + value = predicate() + if value: + return value + time.sleep(.04) + raise AssertionError(message) + desktop = pyatspi.Registry.getDesktop(0) + app = wait(lambda: next((x for x in desktop if x.get_process_id() == process.pid), None), 'missing accessibility root') + def button(name): + return next((item for item in walk(app) if item.name == name and item.getRoleName() in ('button', 'push button') + and item.getState().contains(pyatspi.STATE_SHOWING)), None) + anchor = wait(lambda: button('Usage'), 'missing usage anchor') + outside = wait(lambda: button('Outside'), 'missing outside fixture control') + window = subprocess.check_output(['xdotool', 'search', '--sync', '--name', '^Usage status anchor test$'], text=True, timeout=8).splitlines()[0] + subprocess.run(['xdotool', 'windowfocus', '--sync', window], check=True) + wait(geometry.exists, 'fixture did not export widget geometry') + bounds = json.loads(geometry.read_text()) + window_geometry = dict(line.split('=', 1) for line in subprocess.check_output( + ['xdotool', 'getwindowgeometry', '--shell', window], text=True).splitlines() if '=' in line) + def gtk_center(rect): + assert rect['width'] > 0 and rect['height'] > 0, 'GTK widget has no bounds' + return (round(int(window_geometry['X']) + rect['x'] + rect['width'] / 2), + round(int(window_geometry['Y']) + rect['y'] + rect['height'] / 2)) + report['window_geometry'] = window_geometry + report['gtk_anchor_bounds'] = bounds['anchor'] + report['gtk_anchor_center'] = gtk_center(bounds['anchor']) + def reach(item): + for _ in range(32): + if item.getState().contains(pyatspi.STATE_FOCUSED): + return + key('Tab') + raise AssertionError(f'keyboard cannot reach {item.name}') + reach(outside) + time.sleep(.6) + assert not marker.exists(), 'closed anchor must not read' + report['anchor_center'] = list(point(anchor)) + move_point(gtk_center(bounds['anchor'])) + report['pointer_after_hover'] = subprocess.check_output(['xdotool', 'getmouselocation', '--shell'], text=True).strip() + refresh = wait(lambda: button('Refresh usage'), 'hover did not open usage popup') + wait(lambda: marker.exists() and marker.read_text() == 'x', 'hover did not trigger one read') + assert outside.getState().contains(pyatspi.STATE_FOCUSED), 'hover must not steal focus' + wait(popup_geometry.exists, 'fixture did not export popup geometry') + popup_bounds = json.loads(popup_geometry.read_text()) + report['gtk_popup_bounds'] = popup_bounds + report['x11_windows_before_travel'] = subprocess.check_output( + ['xwininfo', '-root', '-tree'], text=True) + move_point(gtk_center(popup_bounds)) + report['x11_pointer_child'] = x11_pointer_child() + report['pointer_after_travel'] = subprocess.check_output( + ['xdotool', 'getmouselocation', '--shell'], text=True).strip() + time.sleep(.2) + report['x11_windows_after_travel'] = subprocess.check_output( + ['xwininfo', '-root', '-tree'], text=True) + time.sleep(.45) + assert button('Refresh usage') is not None, 'pointer travel closed popup' + report['checks'].append('hover opens without stealing focus and pointer travel stays open') + move_point(gtk_center(bounds['outside'])) + wait(lambda: button('Refresh usage') is None, 'unpinned popup did not close after pointer left') + assert marker.read_text() == 'x', 'hover close must not duplicate the read' + report['checks'].append('unpinned popup closes after pointer leaves') + move_point(gtk_center(bounds['anchor'])) + wait(lambda: button('Refresh usage'), 'second hover did not reopen popup') + wait(lambda: marker.read_text() == 'xx', 'second hover did not issue one read') + subprocess.run(['xdotool', 'click', '1'], check=True) + move_point(gtk_center(bounds['outside'])) + time.sleep(.65) + assert button('Refresh usage') is not None, 'hover-to-click did not pin popup' + assert marker.read_text() == 'xx', 'pinning must not duplicate read' + subprocess.run(['xdotool', 'click', '1'], check=True) + wait(lambda: button('Refresh usage') is None, 'outside click did not dismiss popup') + time.sleep(.6) + assert marker.read_text() == 'xx', 'closed popup must not poll' + report['checks'].append('hover-to-click pins; outside click dismisses; closed popup does not poll') + reach(anchor) + key('space') + wait(lambda: button('Refresh usage'), 'keyboard activation did not open popup') + wait(lambda: marker.read_text() == 'xxx', 'keyboard opening did not issue one read') + key('Escape') + wait(lambda: button('Refresh usage') is None, 'Escape did not dismiss popup') + wait(lambda: anchor.getState().contains(pyatspi.STATE_FOCUSED), 'Escape did not restore anchor focus') + report['checks'].append('keyboard activation opens; Escape dismisses and restores focus') + key('ctrl+q') + process.wait(timeout=8) + assert process.returncode == 0, process.returncode + report['checks'].append('Ctrl+Q closes cleanly') + report['result'] = 'pass' + except Exception as error: + report['result'] = 'fail' + report['failure'] = str(error) + report['synthetic_read_count'] = len(marker.read_text()) if marker.exists() else 0 + if app is not None: + try: + report['accessible_nodes'] = [{'name': (item.name or '')[:160], 'role': item.getRoleName(), + 'showing': item.getState().contains(pyatspi.STATE_SHOWING)} for item in walk(app)][:100] + except Exception as diagnostic_error: + report['accessibility_diagnostic_error'] = type(diagnostic_error).__name__ + raise + finally: + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=3) + except subprocess.TimeoutExpired: + process.kill(); process.wait() + stdout.seek(0); stderr.seek(0) + report['process_stdout'] = stdout.read()[-8000:].decode(errors='replace') + report['process_stderr'] = stderr.read()[-8000:].decode(errors='replace') + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(report, indent=2) + '\n') +print(json.dumps(report, indent=2)) diff --git a/mseries/sdk-tests/usage-controls.py b/mseries/sdk-tests/usage-controls.py new file mode 100644 index 000000000..83e66ee57 --- /dev/null +++ b/mseries/sdk-tests/usage-controls.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Private synthetic keyboard/AT-SPI refresh, failure and retry probe.""" +import argparse +import datetime +import hashlib +import json +import os +from pathlib import Path +import shlex +import subprocess +import tempfile +import time +import pyatspi + +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('--binary', type=Path, required=True) +parser.add_argument('--output', type=Path, required=True) +args = parser.parse_args() +assert os.environ.get('MSDK_PRIVATE_TEST_BUS') == '1', 'requires an isolated test session' +assert not args.output.exists(), 'preserve prior receipts; choose a new output' +report = {'binary_sha256': hashlib.sha256(args.binary.read_bytes()).hexdigest(), + 'environment': 'isolated X11 / private D-Bus / synthetic data', 'checks': []} + + +def walk(node, depth=0): + if depth > 35: + return + yield node + for child in node: + if child is not None: + yield from walk(child, depth + 1) + + +def key(name): + subprocess.run(['xdotool', 'key', '--clearmodifiers', name], check=True) + time.sleep(.05) + + +with tempfile.TemporaryDirectory(prefix='msdk-usage-controls-') as directory: + root = Path(directory) + marker, fail, executable = root / 'reads', root / 'fail', root / 'fixture' + observed = datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z') + snapshot = {'schemaVersion': 1, 'entries': [{'provider': 'codex', 'updatedAt': observed, + 'windows': [{'key': 'week', 'label': '7 day', 'remaining': 75, 'resetsAt': ''}]}]} + executable.write_text('#!/bin/sh\nprintf x >> ' + shlex.quote(str(marker)) + '\n' + + 'if [ -f ' + shlex.quote(str(fail)) + ' ]; then\n' + + "printf 'synthetic-private-error' >&2\nprintf 'invalid-json'\nelse\nprintf '%s' " + + shlex.quote(json.dumps(snapshot)) + '\nfi\n') + executable.chmod(0o700) + env = dict(os.environ, XDG_DATA_HOME=str(root / 'data'), XDG_CONFIG_HOME=str(root / 'config')) + with tempfile.TemporaryFile() as stdout, tempfile.TemporaryFile() as stderr: + process = subprocess.Popen([str(args.binary.resolve()), str(executable)], env=env, stdout=stdout, stderr=stderr) + app = None + try: + def wait(predicate, message, timeout=8): + end = time.monotonic() + timeout + while time.monotonic() < end: + if process.poll() is not None: + raise RuntimeError(f'fixture app exited early ({process.returncode}); see process_stderr') + value = predicate() + if value: + return value + time.sleep(.04) + raise AssertionError(message) + + desktop = pyatspi.Registry.getDesktop(0) + def application(): + return next((app for app in desktop if app.get_process_id() == process.pid), None) + app = wait(application, 'fixture app did not publish an accessibility root') + def named(name): + return next((item for item in walk(app) if item.name == name), None) + button = wait(lambda: next((item for item in walk(app) if item.name == 'Refresh usage' + and item.getRoleName() in ('push button', 'button')), None), 'refresh button is not accessible') + report['refresh_accessible_role'] = button.getRoleName() + wait(lambda: named('Refresh complete'), 'initial synthetic read did not finish') + assert marker.read_text() == 'x', 'opening must issue exactly one read' + window = subprocess.check_output(['xdotool', 'search', '--sync', '--name', '^Usage control test$'], text=True, timeout=8).splitlines()[0] + subprocess.run(['xdotool', 'windowfocus', '--sync', window], check=True) + def reach(): + for _ in range(32): + if button.getState().contains(pyatspi.STATE_FOCUSED): + return + key('Tab') + raise AssertionError('keyboard cannot reach refresh') + reach() + report['checks'].append('Tab reaches the named refresh button') + fail.write_text('fail') + key('space') + wait(lambda: named('Retry when ready'), 'keyboard refresh did not show failure') + assert marker.read_text() == 'xx', 'keyboard refresh must issue one read' + wait(lambda: named('Stale'), 'last-known data was not marked stale') + assert any('Couldn\'t refresh usage' in item.name for item in walk(app) if item.name) + assert not any('synthetic-private-error' in item.name for item in walk(app) if item.name) + report['checks'].append('Space refreshes; failure keeps stale data and hides stderr') + fail.unlink() + wait(lambda: button.getState().contains(pyatspi.STATE_SENSITIVE), 'refresh did not re-enable') + reach() + key('space') + wait(lambda: named('Refresh complete'), 'keyboard retry did not recover') + assert marker.read_text() == 'xxx', 'keyboard retry must issue one read' + report['checks'].append('keyboard retry recovers') + key('ctrl+q') + process.wait(timeout=8) + assert process.returncode == 0, process.returncode + report['checks'].append('Ctrl+Q closes cleanly') + report['result'] = 'pass' + except Exception as error: + report['result'] = 'fail' + report['failure'] = str(error) + if app is not None: + try: + report['accessible_nodes'] = [ + {'name': (item.name or '')[:160], 'role': item.getRoleName()} + for item in walk(app) + ][:100] + except Exception as diagnostic_error: + report['accessibility_diagnostic_error'] = type(diagnostic_error).__name__ + raise + finally: + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=3) + except subprocess.TimeoutExpired: + process.kill() + process.wait() + stdout.seek(0); stderr.seek(0) + report['process_stdout'] = stdout.read()[-8000:].decode(errors='replace') + report['process_stderr'] = stderr.read()[-8000:].decode(errors='replace') + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(report, indent=2) + '\n') +print(json.dumps(report, indent=2)) diff --git a/mseries/sdk-tests/usage-host-abi.c b/mseries/sdk-tests/usage-host-abi.c new file mode 100644 index 000000000..e62e4da4e --- /dev/null +++ b/mseries/sdk-tests/usage-host-abi.c @@ -0,0 +1,31 @@ +/* Isolated C host: test the SDK control boundary without a desktop panel. */ +#include "msdk-usage.h" +#include + +int main(int argc, char **argv) { + g_assert_cmpint(argc, ==, 3); + gtk_init(); + g_assert_null(msdk_usage_control_new(NULL)); + g_assert_null(msdk_usage_control_new("relative-program")); + MsdkUsageControl *control = msdk_usage_control_new(argv[1]); + g_assert_nonnull(control); + GtkWidget *content = msdk_usage_control_widget(control); + g_assert_nonnull(content); + GtkWidget *window = gtk_window_new(); + gtk_window_set_child(GTK_WINDOW(window), content); + gtk_window_present(GTK_WINDOW(window)); + while (g_main_context_iteration(NULL, FALSE)) {} + g_assert_false(g_file_test(argv[2], G_FILE_TEST_EXISTS)); + g_assert_true(msdk_usage_control_open(control)); + gint64 deadline = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND; + while (!g_file_test(argv[2], G_FILE_TEST_EXISTS) && g_get_monotonic_time() < deadline) { + while (g_main_context_iteration(NULL, FALSE)) {} + g_usleep(10000); + } + g_assert_true(g_file_test(argv[2], G_FILE_TEST_EXISTS)); + msdk_usage_control_close(control); + gtk_window_set_child(GTK_WINDOW(window), NULL); + msdk_usage_control_free(control); + gtk_window_destroy(GTK_WINDOW(window)); + return 0; +} diff --git a/mseries/sdk-tests/usage-vala-host.vala b/mseries/sdk-tests/usage-vala-host.vala new file mode 100644 index 000000000..654a879a7 --- /dev/null +++ b/mseries/sdk-tests/usage-vala-host.vala @@ -0,0 +1,33 @@ +/* Isolated Vala host: exercises the page used by desktop status hosts. */ +int main (string[] args) { + assert (args.length == 3); + Gtk.init (); + var unavailable = new MSeries.SdkUsagePage ("relative-program"); + unavailable.opened (); + unavailable.closed (); + unavailable.dispose (); + MSeries.SdkUsagePage? page = new MSeries.SdkUsagePage (args[1]); + var window = new Gtk.Window (); + window.child = page.get_widget (); + window.present (); + assert (!GLib.FileUtils.test (args[2], GLib.FileTest.EXISTS)); + page.opened (); + var loop = new GLib.MainLoop (); + int attempts = 0; + bool read = false; + GLib.Timeout.add (20, () => { + read = GLib.FileUtils.test (args[2], GLib.FileTest.EXISTS); + if (read || ++attempts >= 250) { + loop.quit (); + return GLib.Source.REMOVE; + } + return GLib.Source.CONTINUE; + }); + loop.run (); + page.closed (); + window.child = null; + page = null; + window.destroy (); + assert (read); + return 0; +} diff --git a/mseries/t3-wingpanel/meson.build b/mseries/t3-wingpanel/meson.build index b2859dc4d..a6d2ea35d 100644 --- a/mseries/t3-wingpanel/meson.build +++ b/mseries/t3-wingpanel/meson.build @@ -2,11 +2,21 @@ project('mseries-t3-wingpanel', 'vala', 'c', version: '0.1.0', meson_version: '> wingpanel = dependency('wingpanel-9') deps = [wingpanel, dependency('granite-7', version: '>= 7.7.0'), dependency('json-glib-1.0'), meson.get_compiler('c').find_library('m')] python = find_program('python3') +sdk_prefix = get_option('msdk_prefix') +sdk_vala_args = [] +if sdk_prefix != '' + deps += declare_dependency(compile_args: ['-I' + sdk_prefix / 'include'], + link_args: ['-L' + sdk_prefix / 'lib', '-lmsdk_gtk', '-Wl,-rpath,' + sdk_prefix / 'lib']) + sdk_vala_args = ['--define=MSDK_STATUS_HOST', '--vapidir=' + meson.current_source_dir() / '../sdk-status-host', '--pkg=msdk-usage'] +endif source_paths = ['Indicator.vala', '../dock-taskbar/TaskbarT3RPopover.vala', '../codexbar-wingpanel/JsonBoundary.vala', '../codexbar-wingpanel/HelperProcess.vala', '../codexbar-wingpanel/AccountDialog.vala', '../codexbar-wingpanel/PanelPreferences.vala', '../codexbar-wingpanel/RefreshPolicy.vala', '../codexbar-wingpanel/QuotaEta.vala', '../codexbar-wingpanel/Presentation.vala'] +if sdk_prefix != '' + source_paths += ['../sdk-status-host/UsagePage.vala'] +endif sources = [] foreach path : source_paths sources += configure_file(input: path, output: path.split('/')[-1], copy: true) @@ -15,9 +25,9 @@ foreach component : ['codexbar', 'repobar'] sources += custom_target(component + '-embedded', input: '../' + component + '-wingpanel/Indicator.vala', output: component + '.vala', command: [python, files('embedded-source.py'), '@INPUT@', '@OUTPUT@']) endforeach -shared_module('mseries-t3', sources, dependencies: deps, install: true, +shared_module('mseries-t3', sources, dependencies: deps, vala_args: sdk_vala_args, install: true, install_dir: wingpanel.get_variable(pkgconfig: 'indicatorsdir') / '../mseries-pending-indicators') -probe = executable('probe', sources, 'probe.vala', dependencies: deps) +probe = executable('probe', sources, 'probe.vala', dependencies: deps, vala_args: sdk_vala_args) # Keep native account/repository settings available in both local and Debian installs. settings_model = configure_file(input: '../codexbar-wingpanel/settings/SettingsModel.vala', output: 'SettingsModel.vala', copy: true) diff --git a/mseries/t3-wingpanel/meson_options.txt b/mseries/t3-wingpanel/meson_options.txt new file mode 100644 index 000000000..da5341a2c --- /dev/null +++ b/mseries/t3-wingpanel/meson_options.txt @@ -0,0 +1 @@ +option('msdk_prefix', type: 'string', value: '', description: 'Optional SDK usage host prefix (lib and include directories)') diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c35ae2c01..616baa5cc 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1881,6 +1881,8 @@ dependencies = [ name = "msdk" version = "0.1.0" dependencies = [ + "libc", + "serde", "serde_json", ] diff --git a/rust/msdk-gtk/Cargo.toml b/rust/msdk-gtk/Cargo.toml index 4a7156f77..36ac4f7db 100644 --- a/rust/msdk-gtk/Cargo.toml +++ b/rust/msdk-gtk/Cargo.toml @@ -8,6 +8,7 @@ description = "Interpreter runtime for msdk app descriptions: renders them with [lib] name = "msdk_gtk" +crate-type = ["rlib", "cdylib"] [[bin]] name = "msdk-run" diff --git a/rust/msdk-gtk/examples/usage_anchor_interactive.rs b/rust/msdk-gtk/examples/usage_anchor_interactive.rs new file mode 100644 index 000000000..b4a7b32f2 --- /dev/null +++ b/rust/msdk-gtk/examples/usage_anchor_interactive.rs @@ -0,0 +1,87 @@ +//! Private-session anchor fixture. It does not install a desktop status host. +use gtk::prelude::*; +use msdk::usage::{Coverage, Snapshot}; + +fn main() -> gtk::glib::ExitCode { + let executable = std::env::args_os() + .nth(1) + .expect("synthetic executable path"); + let app = gtk::Application::builder() + .application_id("io.github.techmore.MsdkUsageAnchorTest") + .flags(gtk::gio::ApplicationFlags::NON_UNIQUE) + .build(); + let quit = gtk::gio::SimpleAction::new("quit", None); + let weak_app = app.downgrade(); + quit.connect_activate(move |_, _| { + if let Some(app) = weak_app.upgrade() { + app.quit(); + } + }); + app.add_action(&quit); + app.set_accels_for_action("app.quit", &["q"]); + app.connect_activate(move |app| { + let snapshot = Snapshot { + coverage: Coverage::Unknown, + observations: vec![], + }; + let anchor = msdk_gtk::usage_anchor::UsageAnchor::new( + &snapshot, + 0, + executable.clone().into(), + u64::MAX, + gtk::PositionType::Top, + ) + .unwrap(); + let column = gtk::Box::new(gtk::Orientation::Vertical, 8); + let spacer = gtk::Box::new(gtk::Orientation::Vertical, 0); + spacer.set_vexpand(true); + column.append(&spacer); + let row = gtk::Box::new(gtk::Orientation::Horizontal, 8); + row.set_halign(gtk::Align::End); + row.set_margin_end(12); + row.set_margin_bottom(12); + let outside = gtk::Button::with_label("Outside"); + row.append(&outside); + row.append(anchor.button()); + column.append(&row); + let window = gtk::ApplicationWindow::builder() + .application(app) + .title("Usage status anchor test") + .default_width(480) + .default_height(500) + .child(&column) + .build(); + if let Some(path) = std::env::var_os("MSDK_ANCHOR_GEOMETRY") { + let button = anchor.button().clone(); + let window_for_bounds = window.clone(); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(800), move || { + if let (Some(anchor), Some(outside)) = (button.compute_bounds(&window_for_bounds), outside.compute_bounds(&window_for_bounds)) { + let value = serde_json::json!({"anchor":{"x":anchor.x(),"y":anchor.y(),"width":anchor.width(),"height":anchor.height()},"outside":{"x":outside.x(),"y":outside.y(),"width":outside.width(),"height":outside.height()}}); + let _ = std::fs::write(path, value.to_string()); + } + }); + } + if let Some(path) = std::env::var_os("MSDK_POPUP_GEOMETRY") { + let weak_window = window.downgrade(); + anchor.popover().connect_map(move |popup| { + let popup = popup.clone(); + let path = path.clone(); + let weak_window = weak_window.clone(); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(150), move || { + if let Some(window) = weak_window.upgrade() + && let Some(rect) = popup.compute_bounds(&window) + { + let value = serde_json::json!({"x":rect.x(),"y":rect.y(),"width":rect.width(),"height":rect.height()}); + let _ = std::fs::write(path, value.to_string()); + } + }); + }); + } + window.connect_close_request(move |_| { + let _keep_alive = &anchor; + gtk::glib::Propagation::Proceed + }); + window.present(); + }); + app.run_with_args::<&str>(&[]) +} diff --git a/rust/msdk-gtk/examples/usage_control_interactive.rs b/rust/msdk-gtk/examples/usage_control_interactive.rs new file mode 100644 index 000000000..be0530ecc --- /dev/null +++ b/rust/msdk-gtk/examples/usage_control_interactive.rs @@ -0,0 +1,57 @@ +//! Private-session fixture for keyboard and accessibility tests. No real accounts. +use gtk::prelude::*; +use msdk::usage::{Coverage, Snapshot}; + +fn main() -> gtk::glib::ExitCode { + let executable = std::env::args_os() + .nth(1) + .expect("synthetic executable path"); + let app = gtk::Application::builder() + .application_id("io.github.techmore.MsdkUsageInteractive") + .flags(gtk::gio::ApplicationFlags::NON_UNIQUE) + .build(); + let quit = gtk::gio::SimpleAction::new("quit", None); + let weak_app = app.downgrade(); + quit.connect_activate(move |_, _| { + if let Some(app) = weak_app.upgrade() { + app.quit(); + } + }); + app.add_action(&quit); + app.set_accels_for_action("app.quit", &["q"]); + app.connect_activate(move |app| { + let snapshot = Snapshot { + coverage: Coverage::Unknown, + observations: vec![], + }; + let control = msdk_gtk::usage_control::UsageControl::new( + &snapshot, + 0, + executable.clone().into(), + u64::MAX, + ) + .unwrap(); + control.widget().set_margin_top(12); + control.widget().set_margin_bottom(12); + control.widget().set_margin_start(12); + control.widget().set_margin_end(12); + let window = gtk::ApplicationWindow::builder() + .application(app) + .title("Usage control test") + .default_width(480) + .default_height(500) + .child(control.widget()) + .build(); + let opened = control.open(); + window.connect_close_request(move |_| { + control.close(); + gtk::glib::Propagation::Proceed + }); + window.present(); + if let Err(error) = opened { + eprintln!("synthetic fixture failed to start: {error}"); + app.quit(); + } + }); + app.run_with_args::<&str>(&[]) +} diff --git a/rust/msdk-gtk/examples/usage_control_preview.rs b/rust/msdk-gtk/examples/usage_control_preview.rs new file mode 100644 index 000000000..f8d42e0b6 --- /dev/null +++ b/rust/msdk-gtk/examples/usage_control_preview.rs @@ -0,0 +1,112 @@ +//! Synthetic failure-state preview; the executable is supplied by the CI fixture. +use gtk::gdk; +use gtk::prelude::*; +use msdk::usage::{ + Coverage, Observation, Quota, QuotaUnit, Scope, Snapshot, Source, State, Window, +}; +use std::cell::Cell; +use std::rc::Rc; + +fn main() { + let mut args = std::env::args_os().skip(1); + let output = std::path::PathBuf::from(args.next().expect("output PNG")); + let executable = std::path::PathBuf::from(args.next().expect("synthetic executable")); + let app = gtk::Application::builder() + .application_id("io.github.techmore.MsdkUsageControlPreview") + .flags(gtk::gio::ApplicationFlags::NON_UNIQUE) + .build(); + let failed = Rc::new(Cell::new(false)); + let outcome = failed.clone(); + app.connect_activate(move |app| { + let snapshot = Snapshot { + coverage: Coverage::Partial, + observations: vec![Observation { + scope: Scope { + provider: "codex".into(), + source: Source::LocalClient, + account: None, + }, + provider_label: "Codex".into(), + source_label: "Synthetic local source".into(), + account_label: None, + selected: false, + state: State::Fresh, + observed_at: Some(100), + windows: vec![Window { + key: "week".into(), + label: "7 day".into(), + quota: Some(Quota::new(2500, QuotaUnit::Used, 100, None).unwrap()), + }], + tokens: None, + }], + }; + let control = + msdk_gtk::usage_control::UsageControl::new(&snapshot, 150, executable.clone(), 300) + .unwrap(); + control.widget().set_margin_top(12); + control.widget().set_margin_bottom(12); + control.widget().set_margin_start(12); + control.widget().set_margin_end(12); + let window = gtk::ApplicationWindow::builder() + .application(app) + .title("Usage error preview") + .default_width(480) + .default_height(500) + .child(control.widget()) + .build(); + window.present(); + if let Err(error) = control.open() { + eprintln!("fixture could not start: {error}"); + outcome.set(true); + app.quit(); + return; + } + let app = app.clone(); + let path = output.clone(); + let failed = outcome.clone(); + let deadline = std::time::Instant::now() + std::time::Duration::from_secs(8); + gtk::glib::timeout_add_local(std::time::Duration::from_millis(50), move || { + if control.status_label().text() != "Retry when ready" + && std::time::Instant::now() < deadline + { + return gtk::glib::ControlFlow::Continue; + } + let result = (|| -> Result<(), String> { + if control.status_label().text() != "Retry when ready" { + return Err("fixture failure was not shown".into()); + } + let (width, height) = (window.width(), window.height()); + if width <= 0 || height <= 0 { + return Err("window has no size".into()); + } + let paintable = gtk::WidgetPaintable::new(Some(&window)); + let image = gtk::Snapshot::new(); + paintable.snapshot( + image.upcast_ref::(), + width as f64, + height as f64, + ); + let node = image.to_node().ok_or("nothing to draw")?; + let renderer = window + .native() + .and_then(|native| native.renderer()) + .ok_or("no renderer")?; + renderer + .render_texture(&node, None) + .save_to_png(&path) + .map_err(|error| error.to_string()) + })(); + if let Err(error) = result { + eprintln!("preview capture failed: {error}"); + failed.set(true); + } + control.close(); + app.quit(); + gtk::glib::ControlFlow::Break + }); + }); + app.run_with_args::<&str>(&[]); + if failed.get() { + std::process::exit(1); + } +} diff --git a/rust/msdk-gtk/examples/usage_preview.rs b/rust/msdk-gtk/examples/usage_preview.rs new file mode 100644 index 000000000..2058741ef --- /dev/null +++ b/rust/msdk-gtk/examples/usage_preview.rs @@ -0,0 +1,161 @@ +//! Synthetic read-only preview for native screenshot review; no real accounts. +use gtk::gdk; +use gtk::prelude::*; +use msdk::usage::{ + Coverage, Observation, Quota, QuotaUnit, Scope, Snapshot, Source, State, Window, +}; +use std::cell::Cell; +use std::rc::Rc; + +fn main() { + let output = std::env::args() + .nth(1) + .expect("usage: usage_preview OUTPUT.png"); + let app = gtk::Application::builder() + .application_id("io.github.techmore.MsdkUsagePreview") + .flags(gtk::gio::ApplicationFlags::NON_UNIQUE) + .build(); + let failed = Rc::new(Cell::new(false)); + let outcome = failed.clone(); + app.connect_activate(move |app| { + let base = Observation { + scope: Scope { + provider: "claude".into(), + source: Source::LocalClient, + account: Some("fixture-one".into()), + }, + provider_label: "Claude".into(), + source_label: "This device".into(), + account_label: Some("Work account".into()), + selected: true, + state: State::Fresh, + observed_at: Some(100), + windows: vec![Window { + key: "week".into(), + label: "7 day".into(), + quota: Some(Quota::new(2500, QuotaUnit::Used, 100, None).unwrap()), + }], + tokens: None, + }; + let other = Observation { + scope: Scope { + account: Some("fixture-two".into()), + ..base.scope.clone() + }, + account_label: Some("Personal account with a longer label".into()), + selected: false, + state: State::Stale, + ..base.clone() + }; + let codex = Observation { + scope: Scope { + provider: "codex".into(), + account: Some("fixture-three".into()), + ..base.scope.clone() + }, + provider_label: "Codex".into(), + account_label: Some("Primary account".into()), + ..base.clone() + }; + let codex_other = Observation { + scope: Scope { + account: Some("fixture-four".into()), + ..codex.scope.clone() + }, + account_label: Some("Second account".into()), + selected: false, + ..codex.clone() + }; + let grok = Observation { + scope: Scope { + provider: "grok".into(), + account: Some("fixture-five".into()), + ..base.scope.clone() + }, + provider_label: "Grok".into(), + account_label: Some("Grok account".into()), + selected: false, + state: State::Unknown, + windows: vec![Window { + key: "week".into(), + label: "7 day".into(), + quota: None, + }], + ..base.clone() + }; + let opencode = Observation { + scope: Scope { + provider: "opencode".into(), + account: Some("fixture-six".into()), + ..base.scope.clone() + }, + provider_label: "OpenCode".into(), + account_label: Some("OpenCode account".into()), + selected: false, + state: State::Unavailable, + windows: vec![], + ..base.clone() + }; + let snapshot = Snapshot { + coverage: Coverage::Partial, + observations: vec![base, other, codex, codex_other, grok, opencode], + }; + let panel = + msdk_gtk::usage::UsagePanel::new(&snapshot, 150).expect("synthetic snapshot is valid"); + let scroll = panel.widget().clone(); + scroll.set_margin_top(12); + scroll.set_margin_bottom(12); + scroll.set_margin_start(12); + scroll.set_margin_end(12); + let window = gtk::ApplicationWindow::builder() + .application(app) + .title("Usage preview") + .default_width(480) + .default_height(500) + .child(&scroll) + .build(); + window.present(); + if std::env::var_os("MSDK_USAGE_SCROLL_END").is_some() { + let adjustment = scroll.vadjustment(); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(900), move || { + adjustment.set_value(adjustment.upper() - adjustment.page_size()); + }); + } + let app = app.clone(); + let path = output.clone(); + let failed = outcome.clone(); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(1500), move || { + let result = (|| -> Result<(), String> { + let (width, height) = (window.width(), window.height()); + if width <= 0 || height <= 0 { + return Err("window has no size".into()); + } + let paintable = gtk::WidgetPaintable::new(Some(&window)); + let snapshot = gtk::Snapshot::new(); + paintable.snapshot( + snapshot.upcast_ref::(), + width as f64, + height as f64, + ); + let node = snapshot.to_node().ok_or("nothing to draw")?; + let renderer = window + .native() + .and_then(|native| native.renderer()) + .ok_or("no renderer")?; + renderer + .render_texture(&node, None) + .save_to_png(&path) + .map_err(|error| error.to_string()) + })(); + if let Err(error) = result { + eprintln!("preview capture failed: {error}"); + failed.set(true); + } + app.quit(); + }); + }); + app.run_with_args::<&str>(&[]); + if failed.get() { + std::process::exit(1); + } +} diff --git a/rust/msdk-gtk/include/msdk-usage.h b/rust/msdk-gtk/include/msdk-usage.h new file mode 100644 index 000000000..a8f52bca8 --- /dev/null +++ b/rust/msdk-gtk/include/msdk-usage.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-3.0-only */ +#pragma once +#include +#include + +/* GTK main thread only. The handle owns a reference to its widget. Unparent + * that widget before freeing the handle. Returned widget is transfer-none. */ +typedef struct MsdkUsageControl MsdkUsageControl; +MsdkUsageControl *msdk_usage_control_new(const char *absolute_executable); +GtkWidget *msdk_usage_control_widget(MsdkUsageControl *handle); +bool msdk_usage_control_open(MsdkUsageControl *handle); +void msdk_usage_control_close(MsdkUsageControl *handle); +void msdk_usage_control_free(MsdkUsageControl *handle); diff --git a/rust/msdk-gtk/src/codexbar.rs b/rust/msdk-gtk/src/codexbar.rs new file mode 100644 index 000000000..92d3f5922 --- /dev/null +++ b/rust/msdk-gtk/src/codexbar.rs @@ -0,0 +1,214 @@ +//! Read-only decoding of CodexBar's v1 provider snapshot. This does not launch +//! CodexBar, poll, authenticate, enumerate accounts or claim full coverage. +use msdk::usage::{ + Coverage, Observation, Quota, QuotaUnit, Scope, Snapshot, Source, State, Window, +}; +use serde_json::Value; + +const MAX_BYTES: usize = 2 * 1024 * 1024; +const MAX_PROVIDERS: usize = 128; +const MAX_WINDOWS: usize = 128; + +/// Deliberately contains no source payload, identifiers, paths or credentials. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DecodeError { + TooLarge, + Malformed, + UnsupportedVersion, + InvalidField, + TooManyItems, +} + +/// Public failures contain no command path, stdout, stderr or source payload. +#[derive(Debug)] +pub enum SnapshotReadError { + Process(msdk::runtime::ServiceFailure), + Decode(DecodeError), + Clock, +} + +/// Perform one bounded, read-only `--snapshot` request against a trusted +/// absolute executable. No polling or service management is started. The +/// caller retains the returned process and forwards the scoped result to the +/// state-owner thread for `into_current` immediately before applying it. +pub fn read_snapshot_scoped( + context: msdk::context::ContextToken, + executable: std::path::PathBuf, + max_age_seconds: u64, + operation: u64, + complete: impl FnOnce(msdk::context::Scoped>) + Send + 'static, +) -> Result { + let limits = msdk::process::Limits { + timeout: std::time::Duration::from_secs(5), + output_bytes: MAX_BYTES, + }; + msdk::process::spawn_program_scoped( + context, + executable, + vec!["--snapshot".into()], + limits, + operation, + move |reply| { + complete(reply.map(|result| { + let output = result.map_err(SnapshotReadError::Process)?; + // The process API returns lossy text. Reject replacement characters + // conservatively rather than accepting a potentially corrupted JSON. + if output.stdout.contains('\u{fffd}') { + return Err(SnapshotReadError::Decode(DecodeError::Malformed)); + } + let elapsed = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map_err(|_| SnapshotReadError::Clock)?; + let now = i64::try_from(elapsed.as_secs()).map_err(|_| SnapshotReadError::Clock)?; + decode_snapshot(output.stdout.as_bytes(), now, max_age_seconds) + .map_err(SnapshotReadError::Decode) + })) + }, + ) +} + +fn optional_text<'a>(value: &'a Value, key: &str) -> Result, DecodeError> { + match value.get(key) { + None | Some(Value::Null) => Ok(None), + Some(Value::String(text)) => Ok(Some(text)), + _ => Err(DecodeError::InvalidField), + } +} +fn optional_bool(value: &Value, key: &str) -> Result { + match value.get(key) { + None | Some(Value::Null) => Ok(false), + Some(Value::Bool(value)) => Ok(*value), + _ => Err(DecodeError::InvalidField), + } +} +fn timestamp(value: Option<&str>) -> Result, DecodeError> { + match value { + None | Some("") => Ok(None), + Some(text) => gtk::glib::DateTime::from_iso8601(text, None) + .map(|date| Some(date.to_unix())) + .map_err(|_| DecodeError::InvalidField), + } +} +fn provider_label(key: &str) -> &str { + match key { + "codex" => "Codex", + "claude" => "Claude", + "grok" => "Grok", + "opencode" | "opencodego" => "OpenCode", + other => other, + } +} + +/// Decode the provider aggregate view emitted by `codexbar-linux --snapshot`. +/// `now` and `max_age_seconds` describe the consumer's freshness policy; they +/// never replace the source's `updatedAt`. Future timestamps are unknown. +/// An absent/null remaining value stays unknown and is never converted to zero. +pub fn decode_snapshot( + bytes: &[u8], + now: i64, + max_age_seconds: u64, +) -> Result { + if bytes.len() > MAX_BYTES { + return Err(DecodeError::TooLarge); + } + let root: Value = serde_json::from_slice(bytes).map_err(|_| DecodeError::Malformed)?; + if !root.is_object() { + return Err(DecodeError::Malformed); + } + if root.get("schemaVersion").and_then(Value::as_u64) != Some(1) { + return Err(DecodeError::UnsupportedVersion); + } + let entries = root + .get("entries") + .and_then(Value::as_array) + .ok_or(DecodeError::InvalidField)?; + if entries.len() > MAX_PROVIDERS { + return Err(DecodeError::TooManyItems); + } + let stale = optional_bool(&root, "stale")?; + let busy = optional_bool(&root, "busy")?; + let global_error = optional_text(&root, "error")?.is_some_and(|error| !error.is_empty()); + let mut observations = Vec::new(); + for entry in entries { + if !entry.is_object() { + return Err(DecodeError::InvalidField); + } + let provider = optional_text(entry, "provider")? + .filter(|key| !key.trim().is_empty()) + .ok_or(DecodeError::InvalidField)?; + let observed = timestamp(optional_text(entry, "updatedAt")?)?; + let failed = + global_error || optional_text(entry, "error")?.is_some_and(|error| !error.is_empty()); + let windows = match entry.get("windows") { + None | Some(Value::Null) => &[][..], + Some(Value::Array(windows)) => windows.as_slice(), + _ => return Err(DecodeError::InvalidField), + }; + if windows.len() > MAX_WINDOWS { + return Err(DecodeError::TooManyItems); + } + let state = match observed { + None if failed => State::Unavailable, + None if busy => State::Loading, + None => State::Unknown, + Some(time) if time > now => State::Unknown, + Some(_) if failed || stale => State::Stale, + Some(time) if now.saturating_sub(time) as u64 > max_age_seconds => State::Stale, + Some(_) if windows.is_empty() => State::Empty, + Some(_) => State::Fresh, + }; + let mut decoded_windows = Vec::new(); + for window in windows { + if !window.is_object() { + return Err(DecodeError::InvalidField); + } + let key = optional_text(window, "key")? + .filter(|key| !key.trim().is_empty()) + .ok_or(DecodeError::InvalidField)?; + let label = optional_text(window, "label")? + .filter(|label| !label.trim().is_empty()) + .ok_or(DecodeError::InvalidField)?; + let reset = timestamp(optional_text(window, "resetsAt")?)?; + let remaining = match window.get("remaining") { + None | Some(Value::Null) => None, + Some(Value::Number(value)) => { + let number = value + .as_f64() + .filter(|n| n.is_finite() && (0.0..=100.0).contains(n)) + .ok_or(DecodeError::InvalidField)?; + Some((number * 100.0).round() as u16) + } + _ => return Err(DecodeError::InvalidField), + }; + let quota = observed + .zip(remaining) + .and_then(|(time, value)| Quota::new(value, QuotaUnit::Remaining, time, reset)); + decoded_windows.push(Window { + key: key.into(), + label: label.into(), + quota, + }); + } + observations.push(Observation { + scope: Scope { + provider: provider.into(), + source: Source::LocalClient, + account: None, + }, + provider_label: provider_label(provider).into(), + source_label: "CodexBar local snapshot".into(), + account_label: None, + selected: false, + state, + observed_at: observed, + windows: decoded_windows, + tokens: None, + }); + } + let snapshot = Snapshot { + coverage: Coverage::Partial, + observations, + }; + snapshot.validate().map_err(|_| DecodeError::InvalidField)?; + Ok(snapshot) +} diff --git a/rust/msdk-gtk/src/codexbar_monitor.rs b/rust/msdk-gtk/src/codexbar_monitor.rs new file mode 100644 index 000000000..4b9929149 --- /dev/null +++ b/rust/msdk-gtk/src/codexbar_monitor.rs @@ -0,0 +1,170 @@ +//! Explicit, on-demand ownership of one CodexBar snapshot request. No polling, +//! authentication or desktop status-host installation is performed here. +use crate::codexbar::{SnapshotReadError, read_snapshot_scoped}; +use crate::usage::{ScopedUpdate, UsagePanel}; +use futures_channel::oneshot; +use msdk::context::RequestContext; +use msdk::runtime::ServiceFailure; +use std::cell::{Cell, RefCell}; +use std::path::PathBuf; +use std::rc::Rc; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum RefreshState { + Idle, + Refreshing, + Updated, + Failed, +} +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum RefreshStart { + Started, + Coalesced, + Closed, +} + +struct Inner { + panel: Rc, + executable: PathBuf, + max_age_seconds: u64, + context: RequestContext, + process: RefCell>, + active: Cell, + operation: Cell, + changed: Box, +} +impl Drop for Inner { + fn drop(&mut self) { + self.context.close(); + self.process.get_mut().take(); + } +} + +/// All methods and state notifications run on the GTK/state-owner thread. +/// Keep the monitor alive while the host is open; dropping it cancels owned work. +pub struct CodexBarMonitor { + inner: Rc, +} +impl CodexBarMonitor { + pub fn new( + panel: Rc, + executable: PathBuf, + max_age_seconds: u64, + changed: impl Fn(RefreshState) + 'static, + ) -> Self { + Self { + inner: Rc::new(Inner { + panel, + executable, + max_age_seconds, + context: RequestContext::new(), + process: RefCell::new(None), + active: Cell::new(false), + operation: Cell::new(0), + changed: Box::new(changed), + }), + } + } + /// Opening does not itself read or schedule work. + pub fn open(&self) { + self.inner.active.set(true); + } + pub fn is_busy(&self) -> bool { + self.inner.process.borrow().is_some() + } + /// Invalidates queued replies, cancels the owned read and marks retained + /// values stale. Closing or reopening does not start a read. + pub fn close(&self) { + if !self.inner.active.replace(false) { + return; + } + self.inner.context.advance(); + self.inner.process.borrow_mut().take(); + let _ = self.inner.panel.mark_stale(now().unwrap_or(0)); + (self.inner.changed)(RefreshState::Idle); + } + /// Explicit single refresh. Duplicate requests coalesce until final delivery. + pub fn refresh(&self) -> Result { + if !self.inner.active.get() { + return Ok(RefreshStart::Closed); + } + if self.is_busy() { + return Ok(RefreshStart::Coalesced); + } + let token = self + .inner + .context + .advance() + .expect("active monitor owns an open context"); + let operation = self.inner.operation.get().wrapping_add(1); + self.inner.operation.set(operation); + let (sender, receiver) = oneshot::channel(); + let process = match read_snapshot_scoped( + token.clone(), + self.inner.executable.clone(), + self.inner.max_age_seconds, + operation, + move |reply| { + let _ = sender.send(reply); + }, + ) { + Ok(process) => process, + Err(error) => { + let reply = token.wrap(Err(SnapshotReadError::Process(error.clone()))); + let _ = self.inner.panel.update_scoped(reply, now().unwrap_or(0)); + (self.inner.changed)(RefreshState::Failed); + return Err(error); + } + }; + *self.inner.process.borrow_mut() = Some(process); + let weak = Rc::downgrade(&self.inner); + let delivery_token = token.clone(); + gtk::glib::spawn_future_local(async move { + let delivery = receiver.await; + let Some(inner) = weak.upgrade() else { return }; + if !inner.active.get() || !delivery_token.is_current() { + return; + } + let reply = match delivery { + Ok(reply) => reply, + Err(_) => { + delivery_token.wrap(Err(SnapshotReadError::Process(ServiceFailure::new( + msdk::runtime::FailureKind::Unavailable, + "codexbar.snapshot", + "/runtime/codexbar.snapshot", + operation, + )))) + } + }; + let time = now(); + let reply = match time { + Some(now) => reply.map(|result| { + result.map(|mut snapshot| { + snapshot.refresh_freshness(now, inner.max_age_seconds); + snapshot + }) + }), + None => reply.map(|_| Err(SnapshotReadError::Clock)), + }; + match inner.panel.update_scoped(reply, time.unwrap_or(0)) { + Ok(ScopedUpdate::Expired) => (), + Ok(ScopedUpdate::Applied) => { + inner.process.borrow_mut().take(); + (inner.changed)(RefreshState::Updated); + } + Ok(ScopedUpdate::ReadFailed(_)) | Err(_) => { + inner.process.borrow_mut().take(); + (inner.changed)(RefreshState::Failed); + } + } + }); + (self.inner.changed)(RefreshState::Refreshing); + Ok(RefreshStart::Started) + } +} +fn now() -> Option { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .ok() + .and_then(|duration| i64::try_from(duration.as_secs()).ok()) +} diff --git a/rust/msdk-gtk/src/fixture.rs b/rust/msdk-gtk/src/fixture.rs index 4c17afaeb..ad474c3e0 100644 --- a/rust/msdk-gtk/src/fixture.rs +++ b/rust/msdk-gtk/src/fixture.rs @@ -11,11 +11,12 @@ use std::rc::Rc; use futures_channel::mpsc::UnboundedSender; use serde_json::Value; -use crate::host::{Event, Services}; +use crate::host::{Event, ServiceCall, Services}; pub struct FixtureServices { feeds: BTreeMap, calls: BTreeMap, + api_version: u32, } impl FixtureServices { @@ -29,29 +30,66 @@ impl FixtureServices { FixtureServices { feeds: map("feeds"), calls: map("calls"), + api_version: msdk::runtime::SERVICES_API_VERSION, } } + /// Parse an optional fixture extension version for compatibility testing. + pub fn try_from_json(v: &Value) -> Result { + let mut fixture = Self::from_json(v); + if let Some(version) = v.get("api_version") { + fixture.api_version = version + .as_u64() + .and_then(|n| u32::try_from(n).ok()) + .ok_or_else(|| { + "fixture api_version must be an unsigned 32-bit integer".to_string() + })?; + } + Ok(fixture) + } + pub fn load(path: &std::path::Path) -> Result { let text = std::fs::read_to_string(path).map_err(|e| e.to_string())?; - serde_json::from_str(&text) - .map(|v| FixtureServices::from_json(&v)) - .map_err(|e| e.to_string()) + let value = serde_json::from_str(&text).map_err(|e| e.to_string())?; + FixtureServices::try_from_json(&value) } } impl Services for FixtureServices { + fn api_version(&self) -> u32 { + self.api_version + } + fn invoke(&self, call: ServiceCall) -> Result { + let Some(value) = self.calls.get(&call.service) else { + return Err(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::Unavailable, + &call.service, + "/fixture/calls", + 0, + )); + }; + eprintln!( + "{}", + serde_json::json!({"schema":"msdk.fixture.call.v1", "service":call.service}) + ); + call.reply.success(if value.is_null() { + None + } else { + Some(value.clone()) + }); + Ok(true) + } fn call( &self, service: &str, - args: &BTreeMap, + _args: &BTreeMap, then: Option, _error: Option, tx: UnboundedSender, ) -> bool { eprintln!( - "fixture: {service} {}", - serde_json::to_string(args).unwrap_or_default() + "{}", + serde_json::json!({"schema":"msdk.fixture.call.v1", "service":service}) ); if let (Some(m), Some(reply)) = (then, self.calls.get(service)) { let _ = tx.unbounded_send((m, Some(reply.clone()))); diff --git a/rust/msdk-gtk/src/host.rs b/rust/msdk-gtk/src/host.rs index 3a9c84654..f8d10018d 100644 --- a/rust/msdk-gtk/src/host.rs +++ b/rust/msdk-gtk/src/host.rs @@ -18,21 +18,204 @@ use crate::render::{self, D, Dispatcher, Refresh}; /// A message from outside the widgets (a worker thread, a service): name and payload. pub type Event = (String, Option); +/// A typed request. An owned async task keeps the reply, which never retains GTK. +pub struct ServiceCall { + pub service: String, + pub args: std::collections::BTreeMap, + pub reply: ServiceReply, +} + +enum ReplyOutcome { + Event(Event), + Failure(msdk::runtime::ServiceFailure, Option), +} +struct ReplyDelivery { + outcome: ReplyOutcome, + context: Option, +} +#[derive(Default)] +struct ReplyState { + completed: bool, + context: Option, +} +#[derive(Clone)] +pub struct ServiceReply { + state: std::sync::Arc>, + service: String, + source: String, + operation: u64, + expected: Option, + then: Option, + error: Option, + events: UnboundedSender, + deliveries: UnboundedSender, +} +impl ServiceReply { + /// Bind once, before starting work. All clones share this binding and the + /// first-completion state. Host checks freshness at final callback delivery. + pub fn in_context( + self, + token: msdk::context::ContextToken, + ) -> Result { + { + let mut state = self.state.lock().unwrap_or_else(|error| error.into_inner()); + if state.completed || state.context.is_some() { + return Err(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::InvalidInput, + &self.service, + &self.source, + self.operation, + )); + } + state.context = Some(token); + } + Ok(self) + } + fn claim(&self) -> Option> { + let mut state = self.state.lock().unwrap_or_else(|error| error.into_inner()); + if state.completed { + return None; + } + state.completed = true; + Some(state.context.clone()) + } + fn is_completed(&self) -> bool { + self.state + .lock() + .unwrap_or_else(|error| error.into_inner()) + .completed + } + fn is_bound(&self) -> bool { + self.state + .lock() + .unwrap_or_else(|error| error.into_inner()) + .context + .is_some() + } + /// Validate the declared result before delivering it into app state. + pub fn success(&self, payload: Option) { + use msdk::vocab::Payload; + let valid = match self.expected { + None => true, + Some(Payload::None) => payload.is_none(), + Some(Payload::Text) => payload.as_ref().is_some_and(Value::is_string), + Some(Payload::Bool) => payload.as_ref().is_some_and(Value::is_boolean), + }; + if !valid { + return self.fail(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::MalformedData, + &self.service, + &self.source, + self.operation, + )); + } + let Some(context) = self.claim() else { + return; + }; + if let Some(message) = &self.then { + let _ = self.deliveries.unbounded_send(ReplyDelivery { + outcome: ReplyOutcome::Event((message.clone(), payload)), + context, + }); + } + } + /// Private detail may reach the app UI; it is omitted from diagnostics. + pub fn fail(&self, mut failure: msdk::runtime::ServiceFailure) { + let Some(context) = self.claim() else { + return; + }; + failure.service = self.service.clone(); + failure.source = self.source.clone(); + failure.operation = self.operation; + let _ = self.deliveries.unbounded_send(ReplyDelivery { + outcome: ReplyOutcome::Failure(failure, self.error.clone()), + context, + }); + } +} + +/// A feed delivery endpoint used on the GTK/state-owner thread. The context +/// binding is opt-in and does not stop the provider's subscription or reads. +#[derive(Clone)] +pub struct FeedReply { + push: Rc, + context: Option, +} +impl FeedReply { + /// Bind a fresh endpoint before starting work for an account or view. + /// Rebinding an endpoint would revive stale work, so it is rejected. + pub fn in_context(mut self, token: msdk::context::ContextToken) -> Result { + if self.context.is_some() { + return Err("feed reply already has a context"); + } + self.context = Some(token); + Ok(self) + } + /// Deliver on the same thread that owns the context and host state. + pub fn push(&self, value: Value) { + if self.context.as_ref().is_none_or(|token| token.is_current()) { + (self.push)(value); + } + } +} + /// Builds the app's Rust logic once the host exists; it gets a sender for events from its own threads. /// System access an app can plug in: named services (`call`) and live feeds. Crates such as the T3 client implement it; /// `FixtureServices` answers from a JSON file so an app can run before its real backend exists. pub trait Services { + /// Primary typed dispatch. Return true once owned (including async work). + /// Returning false permits fallback, so start no work in that case. + fn invoke(&self, call: ServiceCall) -> Result { + self.call_checked( + &call.service, + &call.args, + call.reply.then, + call.reply.error, + call.reply.events, + ) + } + /// Version of the SDK extension interface (not the backend's OS/network API). + /// Legacy providers implement this existing v1 interface implicitly. + fn api_version(&self) -> u32 { + msdk::runtime::SERVICES_API_VERSION + } /// Handles `service`; returns false when this provider does not own it. Replies go to `tx` as events. fn call( + &self, + _service: &str, + _args: &std::collections::BTreeMap, + _then: Option, + _error: Option, + _tx: UnboundedSender, + ) -> bool { + false + } + /// Typed dispatch. An error is owned by this provider: the Host reports it + /// without falling through to a real system action. Legacy call() remains + /// the default implementation for existing providers. + fn call_checked( &self, service: &str, args: &std::collections::BTreeMap, then: Option, error: Option, tx: UnboundedSender, - ) -> bool; + ) -> Result { + Ok(self.call(service, args, then, error, tx)) + } /// Starts `feed`, calling `push` with the whole list now and whenever it changes. False when not owned. - fn start_feed(&self, feed: &str, push: Rc) -> bool; + fn start_feed(&self, _feed: &str, _push: Rc) -> bool { + false + } + /// Typed feed entry point. Override to bind a context before starting work; + /// legacy providers continue through `start_feed` without automatic scoping. + fn start_feed_typed(&self, feed: &str, reply: FeedReply) -> bool { + self.start_feed(feed, Rc::new(move |value| reply.push(value))) + } + /// Called once when this host closes. Implementations must cancel owned work + /// and retire callbacks; adapters shared across hosts must scope ownership. + /// The default is for providers with no ongoing work (e.g. fixtures). + fn stop(&self) {} } pub type LogicFactory = Box) -> Box>; @@ -54,6 +237,45 @@ pub struct Host { surface: String, mtime: Cell>, me: RefCell>, + closed: Cell, + reload_source: RefCell>, + window_watches: RefCell>, + processes: RefCell>, + failures: UnboundedSender<(msdk::runtime::ServiceFailure, Option)>, + operation: Cell, + replies: UnboundedSender, +} + +// Widgets keep a dispatcher, never the Host itself. Otherwise Host -> widgets +// -> signal closures -> Host forms a permanent reference cycle after closing. +struct WeakDispatcher(Weak); +impl Dispatcher for WeakDispatcher { + fn send(&self, msg: &str, payload: Option) { + if let Some(host) = self.0.upgrade() { + Dispatcher::send(host.as_ref(), msg, payload); + } + } + fn get(&self, key: &str) -> Option { + self.0 + .upgrade() + .and_then(|host| Dispatcher::get(host.as_ref(), key)) + } + fn set(&self, key: &str, value: Value) { + if let Some(host) = self.0.upgrade() { + Dispatcher::set(host.as_ref(), key, value); + } + } + fn confirm(&self, text: &str, then: Box) { + if let Some(host) = self.0.upgrade() { + Dispatcher::confirm(host.as_ref(), text, then); + } + } +} + +impl Drop for Host { + fn drop(&mut self) { + self.dispose(); + } } fn read_doc(path: &Path) -> Result { @@ -158,6 +380,8 @@ impl Host { ); } let (tx, mut rx) = unbounded::(); + let (failures, mut failure_events) = unbounded(); + let (replies, mut reply_events) = unbounded::(); let custom_logic = logic.is_some(); let logic: Box = match logic { Some(make) => make(tx.clone()), @@ -210,26 +434,71 @@ impl Host { surface: surface.to_string(), mtime: Cell::new(path.and_then(mtime)), me: RefCell::new(Weak::new()), + closed: Cell::new(false), + reload_source: RefCell::new(None), + window_watches: RefCell::new(Vec::new()), + processes: RefCell::new(Vec::new()), + failures, + operation: Cell::new(0), + replies, }); *host.me.borrow_mut() = Rc::downgrade(&host); host.rebuild(); - let h = host.clone(); + let weak = Rc::downgrade(&host); glib::spawn_future_local(async move { while let Some((msg, payload)) = rx.next().await { - h.send(&msg, payload); + let Some(host) = weak.upgrade() else { break }; + host.send(&msg, payload); + } + }); + let weak = Rc::downgrade(&host); + glib::spawn_future_local(async move { + while let Some((failure, callback)) = failure_events.next().await { + let Some(host) = weak.upgrade() else { break }; + host.runtime_failure(failure, callback); + } + }); + let weak = Rc::downgrade(&host); + glib::spawn_future_local(async move { + while let Some(delivery) = reply_events.next().await { + let Some(host) = weak.upgrade() else { break }; + if delivery + .context + .as_ref() + .is_some_and(|token| !token.is_current()) + { + continue; + } + match delivery.outcome { + ReplyOutcome::Event((message, payload)) => host.send(&message, payload), + ReplyOutcome::Failure(failure, callback) => { + host.runtime_failure_in_context(failure, callback, delivery.context) + } + } + } + }); + let weak = Rc::downgrade(&host); + host.window.connect_unrealize(move |_| { + if let Some(host) = weak.upgrade() { + host.dispose(); } }); host.start_feeds(); if watch && host.path.is_some() { - let h = host.clone(); - glib::timeout_add_local(std::time::Duration::from_millis(400), move || { - let now = h.path.as_deref().and_then(mtime); - if now != h.mtime.get() { - h.mtime.set(now); - h.reload(); - } - glib::ControlFlow::Continue - }); + let weak = Rc::downgrade(&host); + let source = + glib::timeout_add_local(std::time::Duration::from_millis(400), move || { + let Some(h) = weak.upgrade() else { + return glib::ControlFlow::Break; + }; + let now = h.path.as_deref().and_then(mtime); + if now != h.mtime.get() { + h.mtime.set(now); + h.reload(); + } + glib::ControlFlow::Continue + }); + *host.reload_source.borrow_mut() = Some(source); } if host.doc.borrow()["surfaces"][surface]["kind"] == "panel" { let weak = Rc::downgrade(&host); @@ -247,6 +516,26 @@ impl Host { &self.window } + /// Retire host-owned polling/reload work and provider callbacks exactly once. + /// Late events are ignored. Closing the primary window calls this automatically. + pub fn dispose(&self) { + if self.closed.replace(true) { + return; + } + if let Some(source) = self.reload_source.borrow_mut().take() { + source.remove(); + } + self.window_watches.borrow_mut().clear(); + self.processes.borrow_mut().clear(); + if let Some(services) = &self.services { + services.stop(); + } + let extra = std::mem::take(&mut *self.extra.borrow_mut()); + for (_, window) in extra { + window.destroy(); + } + } + /// Sends a message as if a control had (used for start-up messages and feeds). pub fn post(&self, msg: &str, payload: Option) { Dispatcher::send(self, msg, payload); @@ -266,15 +555,27 @@ impl Host { && feed != "windows.list" && let Some(sv) = &self.services { + if let Err(failure) = msdk::runtime::negotiate_service( + sv.api_version(), + feed, + &format!("/feeds/{key}"), + self.next_operation(), + ) { + self.runtime_failure(failure, None); + continue; + } let (weak, key) = (self.me.borrow().clone(), key.clone()); - let started = sv.start_feed( + let started = sv.start_feed_typed( feed, - Rc::new(move |list| { - if let Some(h) = weak.upgrade() { - h.set(&key, list); - h.post("_feed", Some(json!(key))); - } - }), + FeedReply { + context: None, + push: Rc::new(move |list| { + if let Some(h) = weak.upgrade() { + h.set(&key, list); + h.post("_feed", Some(json!(key))); + } + }), + }, ); if !started { eprintln!("msdk-run: nothing provides the feed `{feed}`"); @@ -283,18 +584,57 @@ impl Host { } if name.as_str() == Some("windows.list") { let weak = self.me.borrow().clone(); - crate::services::watch_windows(move |list| { + let watch = crate::services::watch_windows(move |list| { if let Some(h) = weak.upgrade() { h.set(&key, list); h.post("_feed", Some(json!(key))); } }); + self.window_watches.borrow_mut().push(watch); } } } fn dispatcher(&self) -> D { - self.me.borrow().upgrade().expect("host alive") as D + Rc::new(WeakDispatcher(self.me.borrow().clone())) + } + + fn next_operation(&self) -> u64 { + let operation = self.operation.get().wrapping_add(1); + self.operation.set(operation); + operation + } + + fn runtime_failure(&self, failure: msdk::runtime::ServiceFailure, callback: Option) { + self.runtime_failure_in_context(failure, callback, None); + } + fn runtime_failure_in_context( + &self, + failure: msdk::runtime::ServiceFailure, + callback: Option, + context: Option, + ) { + if context.as_ref().is_some_and(|token| !token.is_current()) { + return; + } + if self.closed.get() { + return; + } + eprintln!("{}", failure.diagnostic()); + let mut message = failure.to_string(); + // Details belong to the app's private UI, never to diagnostic output. + if let Some(detail) = failure.detail().filter(|detail| !detail.is_empty()) { + message.push('\n'); + message.push_str(detail); + } + if let Some(callback) = callback { + let _ = self.replies.unbounded_send(ReplyDelivery { + outcome: ReplyOutcome::Event((callback, Some(json!(message)))), + context, + }); + } else { + self.show_error(&message); + } } /// Builds the surface's widgets from the current document. @@ -318,7 +658,6 @@ impl Host { // menu beside them, the title in the middle and the app's own actions on the right. let header = gtk::HeaderBar::new(); header.add_css_class("msdk-titlebar"); - header.set_decoration_layout(Some("close,minimize,maximize:")); header.pack_start(&self.options_button(&doc)); let items: Vec<&Value> = surf["header"] .as_array() @@ -390,6 +729,9 @@ impl Host { /// Re-reads the file. A description with errors keeps the previous UI and shows the first error in a banner. pub fn reload(&self) { + if self.closed.get() { + return; + } let Some(path) = &self.path else { return }; let doc = match read_doc(path) { Ok(d) => d, @@ -608,7 +950,7 @@ impl Host { } } - fn apply(&self, e: Effect) { + fn apply(&self, e: Effect, source: &str) { match e { Effect::Toast(t) => self.show_toast(&t), Effect::Quit => self.window.close(), @@ -624,12 +966,57 @@ impl Host { then, error, } => { - let tx = self.tx.clone(); - if let Some(sv) = &self.services - && sv.call(&service, &args, then.clone(), error.clone(), tx.clone()) + let operation = self.next_operation(); + if let Some(provider) = &self.services + && let Err(failure) = msdk::runtime::negotiate_service( + provider.api_version(), + &service, + source, + operation, + ) { + self.runtime_failure(failure, error); return; } + let tx = self.tx.clone(); + if let Some(sv) = &self.services { + let reply = ServiceReply { + state: std::sync::Arc::new(std::sync::Mutex::new(ReplyState::default())), + service: service.clone(), + source: source.into(), + operation, + expected: msdk::vocab::service(&service).map(|service| service.then), + then: then.clone(), + error: error.clone(), + events: tx.clone(), + deliveries: self.replies.clone(), + }; + let reply_errors = reply.clone(); + match sv.invoke(ServiceCall { + service: service.clone(), + args: args.clone(), + reply, + }) { + Ok(true) => return, + Ok(false) if reply_errors.is_completed() => { + return; + } + Ok(false) if reply_errors.is_bound() => { + reply_errors.fail(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::Unavailable, + &service, + source, + operation, + )); + return; + } + Ok(false) => {} + Err(failure) => { + reply_errors.fail(failure); + return; + } + } + } let fail = move |tx: &UnboundedSender, error: &Option, why: String| { if let Some(m) = error { @@ -638,37 +1025,52 @@ impl Host { }; match service.as_str() { "process.run" => { + self.processes + .borrow_mut() + .retain(|process| !process.is_finished()); + if self.processes.borrow().len() >= msdk::runtime::MAX_HOST_PROCESSES { + self.runtime_failure( + msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::Busy, + &service, + source, + operation, + ), + error, + ); + return; + } let cmd = args .get("command") .and_then(Value::as_str) .unwrap_or("") .to_string(); - std::thread::spawn(move || { - match std::process::Command::new("sh") - .arg("-c") - .arg(&cmd) - .output() - { - Ok(o) if o.status.success() => { + let failures = self.failures.clone(); + let completion_source = source.to_string(); + let error2 = error.clone(); + let process = msdk::process::spawn( + cmd, + msdk::process::Limits::default(), + operation, + move |result| match result { + Ok(output) => { if let Some(m) = then { let _ = tx.unbounded_send(( m, - Some(json!( - String::from_utf8_lossy(&o.stdout) - .trim_end() - .to_string() - )), + Some(json!(output.stdout.trim_end())), )); } } - Ok(o) => fail( - &tx, - &error, - String::from_utf8_lossy(&o.stderr).trim().to_string(), - ), - Err(e) => fail(&tx, &error, e.to_string()), - } - }); + Err(mut failure) => { + failure.source = completion_source; + let _ = failures.unbounded_send((failure, error2)); + } + }, + ); + match process { + Ok(process) => self.processes.borrow_mut().push(process), + Err(failure) => self.runtime_failure(failure, error), + } } "power.poweroff" | "power.reboot" => { let verb = if service.ends_with("poweroff") { @@ -688,10 +1090,14 @@ impl Host { fail(&tx, &error, e); } } - other => fail( - &tx, - &error, - format!("service {other} is not available in this runtime yet"), + other => self.runtime_failure( + msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::Unavailable, + other, + source, + operation, + ), + error, ), } } @@ -701,12 +1107,20 @@ impl Host { impl Dispatcher for Host { fn send(&self, msg: &str, payload: Option) { + if self.closed.get() { + return; + } let effects = { let mut st = self.store.borrow_mut(); self.logic.borrow_mut().update(&mut st, msg, payload) }; + let source = if self.custom_logic { + "/logic".into() + } else { + format!("/update/{}", msg.replace('~', "~0").replace('/', "~1")) + }; for e in effects { - self.apply(e); + self.apply(e, &source); } self.persist(); self.refresh(); @@ -717,10 +1131,16 @@ impl Dispatcher for Host { } fn set(&self, key: &str, v: Value) { + if self.closed.get() { + return; + } self.store.borrow_mut().insert(key.to_string(), v); } fn confirm(&self, text: &str, then: Box) { + if self.closed.get() { + return; + } let dlg = gtk::AlertDialog::builder() .message(text) .buttons(["Cancel", "Continue"]) diff --git a/rust/msdk-gtk/src/lib.rs b/rust/msdk-gtk/src/lib.rs index 45b0dfe5c..a3bc6cb59 100644 --- a/rust/msdk-gtk/src/lib.rs +++ b/rust/msdk-gtk/src/lib.rs @@ -7,8 +7,14 @@ pub mod host; pub use msdk::logic; pub mod autohide; +pub mod codexbar; +pub mod codexbar_monitor; pub mod fixture; pub mod render; pub mod services; +pub mod usage; +pub mod usage_anchor; +pub mod usage_control; +pub mod usage_ffi; mod panel; diff --git a/rust/msdk-gtk/src/main.rs b/rust/msdk-gtk/src/main.rs index 0ed8e18ae..c8be11b5b 100644 --- a/rust/msdk-gtk/src/main.rs +++ b/rust/msdk-gtk/src/main.rs @@ -53,16 +53,33 @@ fn main() -> gtk::glib::ExitCode { } else { dir }; + let entries = match std::fs::read_dir(dir) + .and_then(|entries| entries.collect::, _>>()) + { + Ok(entries) => entries, + Err(error) => { + eprintln!("{}: {error}", dir.display()); + return gtk::glib::ExitCode::FAILURE; + } + }; manifests.extend( - std::fs::read_dir(dir) + entries .into_iter() - .flatten() - .flatten() - .map(|e| e.path()) - .filter(|p| p.to_string_lossy().ends_with(".services.json")), + .map(|entry| entry.path()) + .filter(|path| path.to_string_lossy().ends_with(".services.json")), ); } - manifests.extend(opt("--services").map(PathBuf::from)); + for (index, argument) in args.iter().enumerate() { + if argument == "--services" { + let Some(path) = args.get(index + 1).filter(|path| !path.starts_with("--")) else { + eprintln!("--services requires a manifest path"); + return gtk::glib::ExitCode::FAILURE; + }; + manifests.push(path.into()); + } + } + manifests.sort(); + manifests.dedup(); for m in manifests { if let Err(e) = std::fs::read_to_string(&m) .map_err(|e| e.to_string()) @@ -70,6 +87,7 @@ fn main() -> gtk::glib::ExitCode { .and_then(|v| msdk::vocab::load_manifest(&v)) { eprintln!("{}: {e}", m.display()); + return gtk::glib::ExitCode::FAILURE; } } let services: Option> = match opt("--fixture") { @@ -84,11 +102,14 @@ fn main() -> gtk::glib::ExitCode { }; let shot = opt("--screenshot"); let keep = RefCell::new(None); + let failed = Rc::new(std::cell::Cell::new(false)); + let activation_failed = failed.clone(); app.connect_activate(move |app| { let doc = match msdk::text::load(&path) { Ok((d, _)) => d, Err(e) => { eprintln!("{}: {e}", path.display()); + activation_failed.set(true); return app.quit(); } }; @@ -104,12 +125,16 @@ fn main() -> gtk::glib::ExitCode { Some(h) => { if let Some(out) = shot.clone() { let (h2, app2) = (h.clone(), app.clone()); + let screenshot_failed = activation_failed.clone(); gtk::glib::timeout_add_local_once( std::time::Duration::from_millis(1800), move || { match h2.screenshot(std::path::Path::new(&out)) { Ok(()) => println!("wrote {out}"), - Err(e) => eprintln!("screenshot: {e}"), + Err(e) => { + screenshot_failed.set(true); + eprintln!("screenshot: {e}"); + } } app2.quit(); }, @@ -117,8 +142,16 @@ fn main() -> gtk::glib::ExitCode { } *keep.borrow_mut() = Some(h); } - None => app.quit(), + None => { + activation_failed.set(true); + app.quit(); + } } }); - app.run_with_args::<&str>(&[]) + let status = app.run_with_args::<&str>(&[]); + if failed.get() { + gtk::glib::ExitCode::FAILURE + } else { + status + } } diff --git a/rust/msdk-gtk/src/render.rs b/rust/msdk-gtk/src/render.rs index 00ac1e44c..1e36b0cad 100644 --- a/rust/msdk-gtk/src/render.rs +++ b/rust/msdk-gtk/src/render.rs @@ -241,7 +241,20 @@ fn build(node: &Value, d: &D, row: &Row) -> Built { dd2.set_selected(i as u32); } })); - dd.upcast() + let row = gtk::Box::new(gtk::Orientation::Horizontal, 12); + if let Some(label) = s(node, "label") { + let label = gtk::Label::builder() + .label(label) + .xalign(0.0) + .hexpand(true) + .wrap(true) + .build(); + label.set_mnemonic_widget(Some(&dd)); + row.append(&label); + } + dd.set_valign(gtk::Align::Center); + row.append(&dd); + row.upcast() } "List" => list(node, d, row, &mut refresh), "Transcript" => transcript(node, d, row, &mut refresh), diff --git a/rust/msdk-gtk/src/services.rs b/rust/msdk-gtk/src/services.rs index d072fed84..6ad906026 100644 --- a/rust/msdk-gtk/src/services.rs +++ b/rust/msdk-gtk/src/services.rs @@ -27,7 +27,7 @@ async fn proxy() -> Result { .await } -/// Parses the reply of `GetWindows`: `a(ua{sv})` inside a one-tuple. +/// Parses the reply of `GetWindows`: `a(ta{sv})` inside a one-tuple. fn parse_windows(reply: &glib::Variant) -> Vec { let Some(list) = reply.try_child_value(0) else { return vec![]; @@ -57,10 +57,29 @@ async fn poll(p: &gio::DBusProxy, on: &Rc) { } } -/// Calls `on` with the current window list now, on every compositor change signal, and every two seconds as a safety net. -pub fn watch_windows(on: impl Fn(Value) + 'static) { +/// An owned watcher. Dropping it cancels its pending D-Bus call, signal listener +/// and safety polling task. It must be retained only while the feature is active. +pub struct WindowWatch(glib::JoinHandle<()>); + +impl Drop for WindowWatch { + fn drop(&mut self) { + self.0.abort(); + } +} + +struct SignalConnection(gio::DBusProxy, Option); +impl Drop for SignalConnection { + fn drop(&mut self) { + if let Some(handler) = self.1.take() { + self.0.disconnect(handler); + } + } +} + +/// Calls `on` now, on compositor change signals, and every two seconds while owned. +pub fn watch_windows(on: impl Fn(Value) + 'static) -> WindowWatch { let on: Rc = Rc::new(on); - glib::spawn_future_local(async move { + WindowWatch(glib::spawn_future_local(async move { let p = match proxy().await { Ok(p) => p, Err(e) => { @@ -69,22 +88,22 @@ pub fn watch_windows(on: impl Fn(Value) + 'static) { }; // The signal handler must be thread-safe, so it only pokes a channel that this thread listens to. let (poke, mut pokes) = futures_channel::mpsc::unbounded::<()>(); - p.connect_g_signal(move |_, _, signal, _| { + let handler = p.connect_g_signal(move |_, _, signal, _| { if matches!(signal, "WindowsChanged" | "RunningApplicationsChanged") { let _ = poke.unbounded_send(()); } }); - let (p2, on2) = (p.clone(), on.clone()); - glib::spawn_future_local(async move { - while pokes.next().await.is_some() { - poll(&p2, &on2).await; - } - }); + let _signals = SignalConnection(p.clone(), Some(handler)); loop { poll(&p, &on).await; - glib::timeout_future(Duration::from_secs(2)).await; + // One task owns all work; signals cannot create overlapping reads. + futures_util::future::select( + Box::pin(pokes.next()), + Box::pin(glib::timeout_future(Duration::from_secs(2))), + ) + .await; } - }); + })) } pub fn focus_window(id: &str) { diff --git a/rust/msdk-gtk/src/usage.rs b/rust/msdk-gtk/src/usage.rs new file mode 100644 index 000000000..21437aac1 --- /dev/null +++ b/rust/msdk-gtk/src/usage.rs @@ -0,0 +1,299 @@ +//! Candidate reusable usage rows. Host placement, refresh, authentication, +//! focus/dismissal and provider collectors belong to separate adapters. +use gtk::prelude::*; +use msdk::usage::{Coverage, Observation, Snapshot, SnapshotError, State}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +thread_local! { static STYLE_INSTALLED: Cell = const { Cell::new(false) }; } + +fn install_style() { + STYLE_INSTALLED.with(|installed| { + if installed.get() { + return; + } + if let Some(display) = gtk::gdk::Display::default() { + let css = gtk::CssProvider::new(); + css.load_from_string(".msdk-usage .usage-card { padding: 10px; border-radius: 10px; background: alpha(currentColor, 0.045); box-shadow: inset 0 0 0 1px alpha(currentColor, 0.06); } .msdk-usage .usage-provider { font-weight: 700; } .msdk-usage .usage-account { font-weight: 600; } .msdk-usage .usage-detail { opacity: 0.8; } "); + gtk::style_context_add_provider_for_display(&display, &css, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); + installed.set(true); + } + }); +} + +fn label(text: &str) -> gtk::Label { + let label = gtk::Label::new(Some(text)); + label.set_xalign(0.0); + label.set_wrap(true); + label +} + +// Match the optional marks installed by the existing CodexBar package. Keep +// the provider label visible whether or not that package or icon exists. +fn provider_mark(provider: &str) -> Option { + let icon = match provider { + "codex" => "mseries-codexbar-openai-symbolic", + "claude" => "mseries-codexbar-claude-symbolic", + "grok" => "mseries-codexbar-grok-symbolic", + "opencode" | "opencodego" => "mseries-codexbar-opencode-symbolic", + _ => return None, + }; + let display = gtk::gdk::Display::default()?; + if !gtk::IconTheme::for_display(&display).has_icon(icon) { + return None; + } + let image = gtk::Image::from_icon_name(icon); + image.set_pixel_size(18); + Some(image) +} + +fn state_text(state: State) -> &'static str { + match state { + State::Loading => "Loading", + State::Empty => "No usage", + State::Unknown => "Unknown", + State::Fresh => "Current", + State::Stale => "Stale", + State::Unavailable => "Unavailable", + State::Failed => "Refresh failed", + State::Unsupported => "Unsupported", + State::Expired => "Expired — refresh required", + } +} + +fn append_observation(parent: >k::Box, observation: &Observation, now: i64) { + let heading = observation + .account_label + .as_deref() + .unwrap_or("Provider total"); + let title = if observation.selected { + format!("{heading} · Selected") + } else { + heading.to_string() + }; + let row = gtk::Box::new(gtk::Orientation::Vertical, 3); + let heading = label(&title); + heading.add_css_class("usage-account"); + row.append(&heading); + if observation.state != State::Fresh { + let status = label(state_text(observation.state)); + status.add_css_class("usage-detail"); + row.append(&status); + } + for window in &observation.windows { + let value = match window.quota { + Some(quota) + if matches!( + quota.state_at(observation.state, now), + State::Fresh | State::Stale + ) => + { + let basis = quota.remaining_basis_points(); + let reset = quota + .reset_at() + .and_then(|at| gtk::glib::DateTime::from_unix_local(at).ok()) + .and_then(|at| at.format("%x %X").ok()) + .map(|at| format!("Resets {at}")) + .unwrap_or_else(|| "Reset unknown".into()); + let value = if basis % 100 == 0 { + format!("{}%", basis / 100) + } else { + format!("{}.{:02}%", basis / 100, basis % 100) + }; + let detail = label(&reset); + detail.add_css_class("usage-detail"); + let line = format!("{}: {value} remaining", window.label); + row.append(&label(&line)); + row.append(&detail); + continue; + } + Some(quota) => format!( + "{}: {}", + window.label, + state_text(quota.state_at(observation.state, now)) + ), + None => format!("{}: Unknown", window.label), + }; + row.append(&label(&value)); + } + if let Some(tokens) = observation.tokens { + let value = match (observation.state, tokens.total()) { + (State::Fresh, Some(total)) => format!("Tokens: {total}"), + (State::Stale, Some(total)) => format!("Tokens: {total}"), + (_, Some(_)) => format!("Tokens: {}", state_text(observation.state)), + (_, None) => "Tokens: Unknown".into(), + }; + row.append(&label(&value)); + } + parent.append(&row); +} + +/// Build a fresh, read-only view from a validated snapshot. The caller owns +/// updates and must preserve focus/scroll when embedding it in an interactive +/// host. This function neither starts polling nor performs account actions. +pub fn render(snapshot: &Snapshot, now: i64) -> Result { + let groups = snapshot.groups()?; + install_style(); + let root = gtk::Box::new(gtk::Orientation::Vertical, 12); + root.add_css_class("msdk-usage"); + if groups.is_empty() { + root.append(&label(match snapshot.coverage { + Coverage::Complete => "No usage available", + Coverage::Partial => "Usage coverage is partial", + Coverage::Unknown => "Usage coverage is unknown", + })); + } else { + // Show provider coverage before the scrollable cards. A provider can + // appear at several sources; list its name once without merging cards. + let mut seen = std::collections::HashSet::new(); + let names: Vec<&str> = groups + .iter() + .filter_map(|group| seen.insert(group.provider).then_some(group.label)) + .collect(); + if names.len() > 1 { + root.append(&label(&format!("Providers: {}", names.join(" · ")))); + } + if !matches!(snapshot.coverage, Coverage::Complete) { + root.append(&label(match snapshot.coverage { + Coverage::Partial => "Usage coverage is partial", + _ => "Usage coverage is unknown", + })); + } + } + for group in groups { + let card = gtk::Box::new(gtk::Orientation::Vertical, 6); + card.add_css_class("usage-card"); + let header = gtk::Box::new(gtk::Orientation::Horizontal, 6); + if let Some(mark) = provider_mark(group.provider) { + header.append(&mark); + } + let heading = label(group.label); + heading.add_css_class("usage-provider"); + header.append(&heading); + card.append(&header); + let source = label(group.source_label); + source.add_css_class("usage-detail"); + card.append(&source); + if let Some(aggregate) = group.aggregate { + append_observation(&card, aggregate, now); + } + for account in group.accounts { + append_observation(&card, account, now); + } + root.append(&card); + } + Ok(root) +} + +/// Read-only, bounded usage viewport for embedding in a host. Providers and +/// hosts retain responsibility for refresh, context lifetime and actions. +pub struct UsagePanel { + scroll: gtk::ScrolledWindow, + generation: Rc>, + pending_position: Rc>>, + snapshot: RefCell, +} + +/// The final state-thread result of applying a context-bound read. +pub enum ScopedUpdate { + Applied, + Expired, + ReadFailed(crate::codexbar::SnapshotReadError), +} + +impl UsagePanel { + pub fn new(snapshot: &Snapshot, now: i64) -> Result { + let content = render(snapshot, now)?; + let scroll = gtk::ScrolledWindow::builder() + .hscrollbar_policy(gtk::PolicyType::Never) + .vscrollbar_policy(gtk::PolicyType::Automatic) + .child(&content) + .build(); + Ok(Self { + scroll, + generation: Rc::new(Cell::new(0)), + pending_position: Rc::new(Cell::new(None)), + snapshot: RefCell::new(snapshot.clone()), + }) + } + + pub fn widget(&self) -> >k::ScrolledWindow { + &self.scroll + } + + /// Validate and build before replacing the current content. A rejected + /// snapshot leaves the current view intact. Restore the previous numeric + /// scroll offset after layout, clamped if the new content is shorter. + /// This does not promise semantic row anchoring or preserve focus in an + /// interactive child; the current rows contain no interactive actions. + pub fn update(&self, snapshot: &Snapshot, now: i64) -> Result<(), SnapshotError> { + let content = render(snapshot, now)?; + self.replace(content, snapshot.clone()); + Ok(()) + } + + /// Invalidate the freshness of retained values without starting a read. + pub fn mark_stale(&self, now: i64) -> Result<(), SnapshotError> { + let mut stale = self.snapshot.borrow().clone(); + for observation in &mut stale.observations { + if observation.state == State::Fresh { + observation.state = State::Stale; + } + } + self.update(&stale, now) + } + + /// Apply on the GTK/state-owner thread, after any cross-thread queue. An + /// expired response is ignored. A failed read retains last-known data as + /// stale and adds a visible failure notice without exposing private output. + pub fn update_scoped( + &self, + reply: msdk::context::Scoped>, + now: i64, + ) -> Result { + match reply.into_current() { + None => Ok(ScopedUpdate::Expired), + Some(Ok(snapshot)) => { + self.update(&snapshot, now)?; + Ok(ScopedUpdate::Applied) + } + Some(Err(error)) => { + let mut stale = self.snapshot.borrow().clone(); + for observation in &mut stale.observations { + if observation.state == State::Fresh { + observation.state = State::Stale; + } + } + let content = render(&stale, now)?; + content.prepend(&label( + "Couldn't refresh usage. Showing last-known data where available.", + )); + self.replace(content, stale); + Ok(ScopedUpdate::ReadFailed(error)) + } + } + } + + fn replace(&self, content: gtk::Box, snapshot: Snapshot) { + let adjustment = self.scroll.vadjustment(); + let position = self + .pending_position + .get() + .unwrap_or_else(|| adjustment.value()); + self.pending_position.set(Some(position)); + let generation = self.generation.get().wrapping_add(1); + self.generation.set(generation); + self.scroll.set_child(Some(&content)); + *self.snapshot.borrow_mut() = snapshot; + let current = self.generation.clone(); + let pending = self.pending_position.clone(); + gtk::glib::timeout_add_local_once(std::time::Duration::from_millis(50), move || { + if current.get() == generation { + adjustment.set_value( + position.min((adjustment.upper() - adjustment.page_size()).max(0.0)), + ); + pending.set(None); + } + }); + } +} diff --git a/rust/msdk-gtk/src/usage_anchor.rs b/rust/msdk-gtk/src/usage_anchor.rs new file mode 100644 index 000000000..927ae95d7 --- /dev/null +++ b/rust/msdk-gtk/src/usage_anchor.rs @@ -0,0 +1,253 @@ +//! Candidate reusable GTK status anchor. Host placement and profile-specific +//! installation are deliberately external to this widget. +use crate::usage_control::UsageControl; +use gtk::prelude::*; +use msdk::usage::{Snapshot, SnapshotError}; +use std::cell::{Cell, RefCell}; +use std::path::PathBuf; +use std::rc::{Rc, Weak}; +use std::time::Duration; + +struct Inner { + button: gtk::Button, + popup: gtk::Popover, + control: UsageControl, + anchor_motion: gtk::EventControllerMotion, + popup_motion: gtk::EventControllerMotion, + pinned: Cell, + changing_mode: Cell, + open_timer: RefCell>, + close_timer: RefCell>, +} +impl Inner { + fn cancel(timer: &RefCell>) { + if let Some(source) = timer.borrow_mut().take() { + source.remove(); + } + } + fn show(&self, interactive: bool) { + Self::cancel(&self.close_timer); + if self.popup.is_mapped() { + if interactive { + // GTK hides a visible popover when autohide changes. Close and + // reopen it while retaining the same control/read lifecycle. + self.changing_mode.set(true); + self.control.preserve_during_unmap(true); + self.popup.popdown(); + self.popup.set_autohide(true); + self.pinned.set(true); + self.popup.popup(); + self.control.preserve_during_unmap(false); + self.changing_mode.set(false); + if !self.popup.is_mapped() { + self.closed(); + } + } + return; + } + self.pinned.set(interactive); + self.popup.set_autohide(interactive); + let _ = self.control.open(); + self.popup.popup(); + } + fn schedule_open(this: &Rc) { + Self::cancel(&this.close_timer); + if this.open_timer.borrow().is_some() || this.popup.is_mapped() { + return; + } + let weak = Rc::downgrade(this); + let source = gtk::glib::timeout_add_local_once(Duration::from_millis(250), move || { + if let Some(inner) = weak.upgrade() { + inner.open_timer.borrow_mut().take(); + inner.show(false); + } + }); + *this.open_timer.borrow_mut() = Some(source); + } + fn schedule_close(this: &Rc) { + Self::cancel(&this.open_timer); + Self::cancel(&this.close_timer); + if this.pinned.get() { + return; + } + let weak = Rc::downgrade(this); + let source = gtk::glib::timeout_add_local(Duration::from_millis(450), move || { + let Some(inner) = weak.upgrade() else { + return gtk::glib::ControlFlow::Break; + }; + // Crossing events can report a leave while the device is still on + // the popover's native surface. Check the surface itself and keep + // this UI-only timer alive until the pointer actually leaves. + let on_popup_surface = inner.popup.surface().is_some_and(|surface| { + inner + .popup + .display() + .default_seat() + .and_then(|seat| seat.pointer()) + .is_some_and(|pointer| { + pointer.surface_at_position().0.as_ref() == Some(&surface) + }) + }); + if inner.anchor_motion.contains_pointer() + || inner.popup_motion.contains_pointer() + || on_popup_surface + { + return gtk::glib::ControlFlow::Continue; + } + inner.close_timer.borrow_mut().take(); + inner.popup.popdown(); + gtk::glib::ControlFlow::Break + }); + *this.close_timer.borrow_mut() = Some(source); + } + fn closed(&self) { + if std::env::var_os("MSDK_ANCHOR_TRACE").is_some() { + eprintln!("anchor trace: popup closed"); + } + if self.changing_mode.get() { + return; + } + self.pinned.set(false); + Self::cancel(&self.open_timer); + Self::cancel(&self.close_timer); + self.control.close(); + } +} +impl Drop for Inner { + fn drop(&mut self) { + Self::cancel(&self.open_timer); + Self::cancel(&self.close_timer); + self.control.close(); + if self.popup.parent().is_some() { + self.popup.unparent(); + } + } +} + +/// Host-owned status anchor. The profile must place `button()` in its actual +/// status area and call neither open nor refresh while it is closed. Dropping +/// this object releases timers, popup and owned read; no background polling. +pub struct UsageAnchor { + inner: Rc, +} +impl UsageAnchor { + pub fn new( + initial: &Snapshot, + now: i64, + executable: PathBuf, + max_age_seconds: u64, + position: gtk::PositionType, + ) -> Result { + let control = UsageControl::new(initial, now, executable, max_age_seconds)?; + let button = gtk::Button::with_label("Usage"); + button.add_css_class("flat"); + button.set_tooltip_text(Some("Usage status")); + let popup = gtk::Popover::builder() + .position(position) + .autohide(false) + .has_arrow(false) + .child(control.widget()) + .build(); + popup.set_parent(&button); + let inner = Rc::new(Inner { + button, + popup, + control, + anchor_motion: gtk::EventControllerMotion::new(), + popup_motion: gtk::EventControllerMotion::new(), + pinned: Cell::new(false), + changing_mode: Cell::new(false), + open_timer: RefCell::new(None), + close_timer: RefCell::new(None), + }); + let weak = Rc::downgrade(&inner); + inner.button.connect_clicked(move |_| { + if let Some(inner) = weak.upgrade() { + Inner::cancel(&inner.open_timer); + if inner.popup.is_mapped() && inner.pinned.get() { + inner.popup.popdown(); + } else { + inner.show(true); + } + } + }); + let motion = inner.anchor_motion.clone(); + let weak = Rc::downgrade(&inner); + motion.connect_enter(move |_, _, _| { + if std::env::var_os("MSDK_ANCHOR_TRACE").is_some() { + eprintln!("anchor trace: anchor enter"); + } + if let Some(inner) = weak.upgrade() { + Inner::schedule_open(&inner); + } + }); + let weak = Rc::downgrade(&inner); + motion.connect_leave(move |_| { + if std::env::var_os("MSDK_ANCHOR_TRACE").is_some() { + eprintln!("anchor trace: anchor leave"); + } + if let Some(inner) = weak.upgrade() { + Inner::schedule_close(&inner); + } + }); + inner.button.add_controller(motion); + let motion = inner.popup_motion.clone(); + let weak = Rc::downgrade(&inner); + motion.connect_enter(move |_, _, _| { + if std::env::var_os("MSDK_ANCHOR_TRACE").is_some() { + eprintln!("anchor trace: popup enter"); + } + if let Some(inner) = weak.upgrade() { + Inner::cancel(&inner.close_timer); + } + }); + let weak = Rc::downgrade(&inner); + motion.connect_leave(move |_| { + if std::env::var_os("MSDK_ANCHOR_TRACE").is_some() { + eprintln!("anchor trace: popup leave"); + } + if let Some(inner) = weak.upgrade() { + Inner::schedule_close(&inner); + } + }); + inner.popup.add_controller(motion); + let weak = Rc::downgrade(&inner); + inner.popup.connect_closed(move |_| { + if let Some(inner) = weak.upgrade() { + inner.closed(); + } + }); + let keys = gtk::EventControllerKey::new(); + let weak: Weak = Rc::downgrade(&inner); + keys.connect_key_pressed(move |_, key, _, _| { + if key == gtk::gdk::Key::Escape { + if let Some(inner) = weak.upgrade() { + inner.popup.popdown(); + inner.button.grab_focus(); + } + gtk::glib::Propagation::Stop + } else { + gtk::glib::Propagation::Proceed + } + }); + inner.popup.add_controller(keys); + let weak = Rc::downgrade(&inner); + inner.button.connect_unmap(move |_| { + if let Some(inner) = weak.upgrade() { + Inner::cancel(&inner.open_timer); + Inner::cancel(&inner.close_timer); + inner.popup.popdown(); + inner.closed(); + } + }); + Ok(Self { inner }) + } + pub fn button(&self) -> >k::Button { + &self.inner.button + } + /// The host owns placement; exposing the popup also permits host-specific + /// positioning and isolated interaction inspection. + pub fn popover(&self) -> >k::Popover { + &self.inner.popup + } +} diff --git a/rust/msdk-gtk/src/usage_control.rs b/rust/msdk-gtk/src/usage_control.rs new file mode 100644 index 000000000..f2760673a --- /dev/null +++ b/rust/msdk-gtk/src/usage_control.rs @@ -0,0 +1,144 @@ +//! Embeddable read-only usage view with explicit open/close ownership. +//! This is not a desktop status-area host or an account-action interface. +use crate::codexbar_monitor::{CodexBarMonitor, RefreshState}; +use crate::usage::UsagePanel; +use gtk::prelude::*; +use msdk::runtime::ServiceFailure; +use msdk::usage::{Snapshot, SnapshotError}; +use std::cell::Cell; +use std::path::PathBuf; +use std::rc::Rc; + +pub struct UsageControl { + root: gtk::Box, + refresh: gtk::Button, + status: gtk::Label, + monitor: Rc, + opened: Rc>, + preserve_unmap: Rc>, +} + +impl UsageControl { + /// The caller supplies a trusted absolute executable and an initial, + /// validated snapshot. No process runs until the host opens the control. + pub fn new( + initial: &Snapshot, + now: i64, + executable: PathBuf, + max_age_seconds: u64, + ) -> Result { + let panel = Rc::new(UsagePanel::new(initial, now)?); + panel.widget().set_vexpand(true); + let root = gtk::Box::new(gtk::Orientation::Vertical, 6); + root.append(panel.widget()); + root.append(>k::Separator::new(gtk::Orientation::Horizontal)); + let footer = gtk::Box::new(gtk::Orientation::Horizontal, 8); + let status = gtk::Label::new(Some("Usage not open")); + status.set_xalign(0.0); + status.set_hexpand(true); + status.set_wrap(true); + status.add_css_class("dim-label"); + let spinner = gtk::Spinner::new(); + spinner.set_visible(false); + let refresh = gtk::Button::with_label("Refresh usage"); + refresh.set_tooltip_text(Some("Refresh usage")); + refresh.update_property(&[gtk::accessible::Property::Label("Refresh usage")]); + refresh.set_sensitive(false); + footer.append(&status); + footer.append(&spinner); + footer.append(&refresh); + root.append(&footer); + let (weak_status, weak_spinner, weak_refresh) = + (status.downgrade(), spinner.downgrade(), refresh.downgrade()); + let monitor = Rc::new(CodexBarMonitor::new( + panel, + executable, + max_age_seconds, + move |state| { + let (Some(status), Some(spinner), Some(refresh)) = ( + weak_status.upgrade(), + weak_spinner.upgrade(), + weak_refresh.upgrade(), + ) else { + return; + }; + let (text, busy, enabled) = match state { + RefreshState::Idle => ("Usage not open", false, false), + RefreshState::Refreshing => ("Refreshing usage…", true, false), + RefreshState::Updated => ("Refresh complete", false, true), + RefreshState::Failed => ("Retry when ready", false, true), + }; + status.set_text(text); + refresh.set_sensitive(enabled); + spinner.set_visible(busy); + if busy { + spinner.start(); + } else { + spinner.stop(); + } + }, + )); + let weak_monitor = Rc::downgrade(&monitor); + refresh.connect_clicked(move |_| { + if let Some(monitor) = weak_monitor.upgrade() { + let _ = monitor.refresh(); + } + }); + let opened = Rc::new(Cell::new(false)); + let weak_monitor = Rc::downgrade(&monitor); + let opened_on_unmap = opened.clone(); + let preserve_unmap = Rc::new(Cell::new(false)); + let preserve_on_unmap = preserve_unmap.clone(); + root.connect_unmap(move |_| { + if preserve_on_unmap.get() { + return; + } + opened_on_unmap.set(false); + if let Some(monitor) = weak_monitor.upgrade() { + monitor.close(); + } + }); + Ok(Self { + root, + refresh, + status, + monitor, + opened, + preserve_unmap, + }) + } + + // Used only during a synchronous popup mode transition. Ordinary unmaps + // still close and cancel the monitor. + pub(crate) fn preserve_during_unmap(&self, preserve: bool) { + self.preserve_unmap.set(preserve); + } + pub fn widget(&self) -> >k::Box { + &self.root + } + pub fn refresh_button(&self) -> >k::Button { + &self.refresh + } + pub fn status_label(&self) -> >k::Label { + &self.status + } + /// A new open requests one bounded snapshot; repeated opens do nothing. + pub fn open(&self) -> Result<(), ServiceFailure> { + if self.opened.replace(true) { + return Ok(()); + } + self.monitor.open(); + self.monitor.refresh()?; + Ok(()) + } + pub fn close(&self) { + if self.opened.replace(false) { + self.monitor.close(); + } + } +} +impl Drop for UsageControl { + fn drop(&mut self) { + self.close(); + } +} diff --git a/rust/msdk-gtk/src/usage_ffi.rs b/rust/msdk-gtk/src/usage_ffi.rs new file mode 100644 index 000000000..5e5960136 --- /dev/null +++ b/rust/msdk-gtk/src/usage_ffi.rs @@ -0,0 +1,98 @@ +//! C boundary for embedding the SDK usage control in GTK hosts. +//! All calls, including destruction, must occur on the GTK main thread. +use crate::usage_control::UsageControl; +use gtk::glib::translate::ToGlibPtr; +use gtk::prelude::*; +use msdk::usage::{Coverage, Snapshot}; +use std::ffi::{CStr, c_char}; +use std::path::PathBuf; +use std::ptr; +use std::time::{SystemTime, UNIX_EPOCH}; + +/// An opaque host-owned usage control. The returned widget is borrowed and +/// stays valid until the handle is freed; the host must unparent it first. +pub struct MsdkUsageControl(UsageControl); + +/// Create a control without starting a collector or making a read. +/// +/// # Safety +/// `executable` must be a valid, NUL-terminated UTF-8 string for this call. +/// GTK must be initialized, and the caller must use the GTK main thread. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn msdk_usage_control_new( + executable: *const c_char, +) -> *mut MsdkUsageControl { + if executable.is_null() { + return ptr::null_mut(); + } + // A Vala/C host can initialize GTK without initializing gtk-rs's own + // main-thread bookkeeping. gtk::init is idempotent on the GTK thread. + if gtk::init().is_err() { + return ptr::null_mut(); + } + // SAFETY: the caller promises a valid NUL-terminated string. + let Ok(executable) = (unsafe { CStr::from_ptr(executable) }).to_str() else { + return ptr::null_mut(); + }; + let executable = PathBuf::from(executable); + if !executable.is_absolute() { + return ptr::null_mut(); + } + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_or(0, |d| d.as_secs().min(i64::MAX as u64) as i64); + let initial = Snapshot { + coverage: Coverage::Unknown, + observations: vec![], + }; + match UsageControl::new(&initial, now, executable, 300) { + Ok(control) => Box::into_raw(Box::new(MsdkUsageControl(control))), + Err(_) => ptr::null_mut(), + } +} + +/// # Safety +/// `handle` must be a live handle returned by `msdk_usage_control_new`, on the GTK thread. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn msdk_usage_control_widget( + handle: *mut MsdkUsageControl, +) -> *mut gtk::ffi::GtkWidget { + // SAFETY: the caller guarantees handle validity; null is accepted. + unsafe { handle.as_ref() }.map_or(ptr::null_mut(), |handle| { + handle + .0 + .widget() + .upcast_ref::() + .to_glib_none() + .0 + }) +} + +/// # Safety +/// `handle` must be a live handle returned by `msdk_usage_control_new`, on the GTK thread. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn msdk_usage_control_open(handle: *mut MsdkUsageControl) -> bool { + // SAFETY: the caller guarantees handle validity; null is accepted. + unsafe { handle.as_ref() }.is_some_and(|handle| handle.0.open().is_ok()) +} + +/// # Safety +/// `handle` must be a live handle returned by `msdk_usage_control_new`, on the GTK thread. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn msdk_usage_control_close(handle: *mut MsdkUsageControl) { + // SAFETY: the caller guarantees handle validity; null is accepted. + if let Some(handle) = unsafe { handle.as_ref() } { + handle.0.close(); + } +} + +/// # Safety +/// `handle` must be null or a live handle returned by `msdk_usage_control_new`. +/// Its widget must be unparented, and it must not be used again after this call. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn msdk_usage_control_free(handle: *mut MsdkUsageControl) { + if !handle.is_null() { + // SAFETY: the caller transfers the unique handle back exactly once. + drop(unsafe { Box::from_raw(handle) }); + } +} diff --git a/rust/msdk-gtk/tests/cli.rs b/rust/msdk-gtk/tests/cli.rs new file mode 100644 index 000000000..37563bacf --- /dev/null +++ b/rust/msdk-gtk/tests/cli.rs @@ -0,0 +1,50 @@ +//! Run in the same isolated Xvfb/private D-Bus environment as lifecycle/runtime. +use std::process::Command; + +#[test] +fn preview_failures_have_nonzero_exit_status() { + assert_eq!(std::env::var("MSDK_PRIVATE_TEST_BUS").as_deref(), Ok("1")); + let stamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos(); + let root = + std::env::temp_dir().join(format!("msdk-preview-cli-{}-{stamp}", std::process::id())); + std::fs::create_dir(&root).unwrap(); + struct Cleanup(std::path::PathBuf); + impl Drop for Cleanup { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.0); + } + } + let _cleanup = Cleanup(root.clone()); + let run = |args: &[&str]| { + Command::new(env!("CARGO_BIN_EXE_msdk-run")) + .current_dir(&root) + .args(args) + .output() + .unwrap() + }; + std::fs::write( + root.join("app.ui.json"), + include_str!("../../msdk/examples/home-storage.ui.json"), + ) + .unwrap(); + std::fs::write(root.join("bad.services.json"), r#"{"manifest_version":2}"#).unwrap(); + let result = run(&["app.ui.json"]); + assert!(!result.status.success()); + assert!( + String::from_utf8_lossy(&result.stderr).contains("unsupported service manifest version") + ); + std::fs::remove_file(root.join("bad.services.json")).unwrap(); + let result = run(&["app.ui.json", "--services"]); + assert!(!result.status.success()); + assert!(String::from_utf8_lossy(&result.stderr).contains("requires a manifest path")); + let result = run(&["app.ui.json", "--surface", "absent"]); + assert!(!result.status.success()); + assert!(String::from_utf8_lossy(&result.stderr).contains("no surface")); + let result = run(&["app.ui.json", "--screenshot", "missing-parent/capture.png"]); + assert!(!result.status.success()); + assert!(String::from_utf8_lossy(&result.stderr).contains("screenshot:")); + assert!(!root.join("missing-parent/capture.png").exists()); +} diff --git a/rust/msdk-gtk/tests/codexbar.rs b/rust/msdk-gtk/tests/codexbar.rs new file mode 100644 index 000000000..9ef629067 --- /dev/null +++ b/rust/msdk-gtk/tests/codexbar.rs @@ -0,0 +1,212 @@ +use msdk::usage::{Coverage, State}; +use msdk_gtk::codexbar::{DecodeError, decode_snapshot}; +use serde_json::{Value, json}; + +const NOW: i64 = 1_767_225_600; // 2026-01-01T00:00:00Z +fn fixture() -> Value { + json!({"schemaVersion":1,"stale":false,"busy":false,"error":"", "entries":[ + {"provider":"codex","updatedAt":"2026-01-01T00:00:00Z","error":"", "windows":[ + {"key":"week","label":"7 day","remaining":75.25,"resetsAt":"2026-01-02T00:00:00Z"}, + {"key":"hour","label":"5 hour","remaining":null,"resetsAt":""}]}, + {"provider":"claude","updatedAt":"","error":"unavailable", "windows":[]} + ]}) +} +fn decode(value: &Value, now: i64) -> Result { + decode_snapshot(&serde_json::to_vec(value).unwrap(), now, 300) +} + +#[test] +fn actual_shape_keeps_aggregate_scope_partial_coverage_and_unknown_values() { + let snapshot = decode(&fixture(), NOW).unwrap(); + assert_eq!(snapshot.coverage, Coverage::Partial); + assert_eq!(snapshot.observations.len(), 2); + let codex = &snapshot.observations[0]; + assert_eq!(codex.state, State::Fresh); + assert!(codex.scope.account.is_none()); + assert_eq!( + codex.windows[0].quota.unwrap().remaining_basis_points(), + 7525 + ); + assert!(codex.windows[1].quota.is_none()); + assert_eq!(snapshot.observations[1].state, State::Unavailable); +} + +#[test] +fn freshness_uses_source_time_and_expired_reset_is_not_current() { + let snapshot = decode(&fixture(), NOW + 301).unwrap(); + assert_eq!(snapshot.observations[0].state, State::Stale); + let snapshot = decode(&fixture(), NOW - 1).unwrap(); + assert_eq!(snapshot.observations[0].state, State::Unknown); + let snapshot = decode_snapshot( + &serde_json::to_vec(&fixture()).unwrap(), + NOW + 86400, + 100000, + ) + .unwrap(); + assert_eq!( + snapshot.observations[0].windows[0] + .quota + .unwrap() + .state_at(State::Fresh, NOW + 86400), + State::Expired + ); +} + +#[test] +fn malformed_or_future_contracts_are_rejected_without_payload_in_errors() { + let mut value = fixture(); + value["schemaVersion"] = json!(2); + assert!(matches!( + decode(&value, NOW), + Err(DecodeError::UnsupportedVersion) + )); + let mut value = fixture(); + value["entries"][0]["windows"][0]["remaining"] = json!(101); + assert!(matches!( + decode(&value, NOW), + Err(DecodeError::InvalidField) + )); + let mut value = fixture(); + value["entries"][0]["updatedAt"] = json!("private-sensitive-invalid"); + let error = match decode(&value, NOW) { + Err(error) => error, + Ok(_) => panic!("invalid time was accepted"), + }; + assert!(!format!("{error:?}").contains("private-sensitive-invalid")); + let mut value = fixture(); + value["entries"][0]["windows"][0]["remaining"] = json!("0"); + assert!(matches!( + decode(&value, NOW), + Err(DecodeError::InvalidField) + )); + assert!(matches!( + decode_snapshot(&vec![b' '; 2 * 1024 * 1024 + 1], NOW, 300), + Err(DecodeError::TooLarge) + )); +} + +#[test] +fn failed_read_retains_stale_measurements_without_claiming_success() { + let mut value = fixture(); + value["entries"][0]["error"] = json!("synthetic failure"); + let snapshot = decode(&value, NOW).unwrap(); + assert_eq!(snapshot.observations[0].state, State::Stale); + assert_eq!( + snapshot.observations[0].windows[0] + .quota + .unwrap() + .remaining_basis_points(), + 7525 + ); +} + +#[cfg(unix)] +#[test] +fn bounded_reader_runs_a_synthetic_executable_and_expires_old_replies() { + use msdk::context::RequestContext; + use msdk_gtk::codexbar::{SnapshotReadError, read_snapshot_scoped}; + use std::os::unix::fs::PermissionsExt; + use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; + let stamp = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos(); + let dir = + std::env::temp_dir().join(format!("msdk-codexbar-test-{}-{stamp}", std::process::id())); + std::fs::create_dir(&dir).unwrap(); + struct Cleanup(std::path::PathBuf); + impl Drop for Cleanup { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.0); + } + } + let _cleanup = Cleanup(dir.clone()); + let executable = dir.join("fixture ' ; not-a-shell-command"); + let json = serde_json::to_string(&fixture()).unwrap(); + std::fs::write( + &executable, + format!("#!/bin/sh\n[ \"$1\" = --snapshot ] || exit 9\nprintf '%s' '{json}'\n"), + ) + .unwrap(); + std::fs::set_permissions(&executable, std::fs::Permissions::from_mode(0o700)).unwrap(); + let context = RequestContext::new(); + let (tx, rx) = std::sync::mpsc::channel(); + let task = read_snapshot_scoped( + context.token().unwrap(), + executable.clone(), + u64::MAX, + 71, + move |reply| tx.send(reply).unwrap(), + ) + .unwrap(); + let snapshot = rx + .recv_timeout(Duration::from_secs(3)) + .unwrap() + .into_current() + .unwrap() + .unwrap(); + assert!(task.is_finished()); + assert_eq!( + snapshot.observations[0].windows[0] + .quota + .unwrap() + .remaining_basis_points(), + 7525 + ); + assert_eq!(snapshot.coverage, Coverage::Partial); + + std::fs::write( + &executable, + "#!/bin/sh\nprintf 'synthetic-private-error' >&2\nprintf 'not-json'\n", + ) + .unwrap(); + let (tx, rx) = std::sync::mpsc::channel(); + let _task = read_snapshot_scoped( + context.token().unwrap(), + executable.clone(), + 300, + 72, + move |reply| tx.send(reply).unwrap(), + ) + .unwrap(); + let result = rx + .recv_timeout(Duration::from_secs(3)) + .unwrap() + .into_current() + .unwrap(); + match result { + Err(SnapshotReadError::Decode(DecodeError::Malformed)) => (), + Err(error) => panic!("unexpected error: {error:?}"), + Ok(_) => panic!("malformed snapshot accepted"), + } + + let marker = dir.join("started"); + let marker_string = marker.to_str().unwrap().replace('\'', "'\\''"); + std::fs::write( + &executable, + format!("#!/bin/sh\nprintf started > '{marker_string}'\nexec sleep 20\n"), + ) + .unwrap(); + let (tx, rx) = std::sync::mpsc::channel(); + let task = read_snapshot_scoped( + context.token().unwrap(), + executable, + 300, + 73, + move |reply| tx.send(reply).unwrap(), + ) + .unwrap(); + let deadline = Instant::now() + Duration::from_secs(3); + while !marker.exists() && Instant::now() < deadline { + std::thread::sleep(Duration::from_millis(5)); + } + assert!(marker.exists(), "the owned test executable must start"); + context.advance().unwrap(); + assert!( + rx.recv_timeout(Duration::from_secs(3)) + .unwrap() + .into_current() + .is_none() + ); + assert!(task.is_finished()); +} diff --git a/rust/msdk-gtk/tests/lifecycle.rs b/rust/msdk-gtk/tests/lifecycle.rs new file mode 100644 index 000000000..4bdb4d394 --- /dev/null +++ b/rust/msdk-gtk/tests/lifecycle.rs @@ -0,0 +1,239 @@ +//! Native ownership checks. Run under a private D-Bus session and Xvfb. +use gtk::prelude::*; +use msdk_gtk::host::{FeedReply, Host, Services}; +use msdk_gtk::render::Dispatcher; +use serde_json::{Value, json}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +struct Provider { + stops: Rc>, + feeds: Rc>, +} + +struct ScopedProvider { + context: msdk::context::RequestContext, + sink: Rc>>, + stops: Rc>, +} +impl Services for ScopedProvider { + fn start_feed_typed(&self, _: &str, reply: FeedReply) -> bool { + *self.sink.borrow_mut() = Some(reply.in_context(self.context.token().unwrap()).unwrap()); + true + } + fn stop(&self) { + self.context.close(); + self.stops.set(self.stops.get() + 1); + } +} +impl Services for Provider { + fn api_version(&self) -> u32 { + // An incompatible optional extension must not disable the host's own + // windows.list implementation. + msdk::runtime::SERVICES_API_VERSION + 1 + } + fn call( + &self, + _: &str, + _: &std::collections::BTreeMap, + _: Option, + _: Option, + _: futures_channel::mpsc::UnboundedSender, + ) -> bool { + false + } + fn start_feed(&self, _: &str, _: Rc) -> bool { + self.feeds.set(self.feeds.get() + 1); + false + } + fn stop(&self) { + self.stops.set(self.stops.get() + 1); + } +} + +#[test] +fn closing_stops_owned_work_ignores_late_events_and_releases_the_host() { + assert_eq!( + std::env::var("MSDK_PRIVATE_TEST_BUS").as_deref(), + Ok("1"), + "run with MSDK_PRIVATE_TEST_BUS=1 under a new dbus-run-session" + ); + gtk::init().expect("run native test under Xvfb"); + let bus = + gtk::gio::bus_get_sync(gtk::gio::BusType::Session, gtk::gio::Cancellable::NONE).unwrap(); + let reply = bus + .call_sync( + Some("org.freedesktop.DBus"), + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "RequestName", + Some(&("org.pantheon.gala", 4_u32).to_variant()), + None, + gtk::gio::DBusCallFlags::NONE, + 1000, + gtk::gio::Cancellable::NONE, + ) + .unwrap(); + assert_eq!( + reply.child_get::(0), + 1, + "never replace an existing compositor service" + ); + let node = gtk::gio::DBusNodeInfo::for_xml( + r#" + + "#, + ) + .unwrap(); + let reads = Rc::new(Cell::new(0)); + let calls = reads.clone(); + let registration = bus + .register_object("/org/pantheon/gala/DesktopInterface", &node.interfaces()[0]) + .method_call(move |_, _, _, _, method, _, invocation| { + assert_eq!(method, "GetWindows"); + calls.set(calls.get() + 1); + let properties: std::collections::HashMap = [ + ("app-id".into(), "com.example.Fixture".to_variant()), + ("title".into(), "Fixture window".to_variant()), + ("has-focus".into(), true.to_variant()), + ("demands-attention".into(), false.to_variant()), + ] + .into_iter() + .collect(); + invocation.return_value(Some(&(vec![(7_u64, properties)],).to_variant())); + }) + .build() + .unwrap(); + let pump = |duration: std::time::Duration| { + let end = std::time::Instant::now() + duration; + let context = gtk::glib::MainContext::default(); + while std::time::Instant::now() < end { + while context.pending() { + context.iteration(false); + } + std::thread::sleep(std::time::Duration::from_millis(2)); + } + }; + let app = gtk::Application::builder() + .application_id("com.example.MsdkLifecycleTest") + .flags(gtk::gio::ApplicationFlags::NON_UNIQUE) + .build(); + app.register(gtk::gio::Cancellable::NONE).unwrap(); + let mut doc: Value = + serde_json::from_str(include_str!("../../msdk/templates/settings/app.ui.json")).unwrap(); + doc["app"]["id"] = json!("com.example.MsdkLifecycleTest"); + // This scenario has no persistent data and never invokes real services. + doc["persist"] = json!([]); + let disabled_doc = doc.clone(); + msdk::vocab::load_manifest(&json!({"feeds":[{"name":"sdktest.lifecycle.feed","capability":"network","fields":{"id":"text"}}]})).unwrap(); + doc["capabilities"] = json!(["windows", "network"]); + doc["types"] = json!({"Win":{"id":"text","app_id":"text","title":"text","focused":"bool","attention":"bool"}}); + doc["types"]["Other"] = json!({"id":"text"}); + doc["state"]["windows"] = json!("list"); + doc["state"]["other"] = json!("list"); + doc["feeds"] = json!({"windows":"windows.list", "other":"sdktest.lifecycle.feed"}); + let stops = Rc::new(Cell::new(0)); + let feeds = Rc::new(Cell::new(0)); + let provider = Rc::new(Provider { + stops: stops.clone(), + feeds: feeds.clone(), + }); + let host = Host::open_with(&app, doc, None, "main", None, Some(provider), false).unwrap(); + let weak = Rc::downgrade(&host); + assert_eq!(host.get("enabled"), Some(json!(true))); + pump(std::time::Duration::from_millis(300)); + assert!( + reads.get() > 0, + "the enabled feed must execute a real D-Bus read" + ); + assert_eq!(host.get("windows").unwrap()[0]["id"], "7"); + assert_eq!( + feeds.get(), + 0, + "an incompatible provider must not receive its own feed" + ); + let veto = host + .window() + .connect_close_request(|_| gtk::glib::Propagation::Stop); + host.window().close(); + host.post("SetEnabled", Some(json!(false))); + assert_eq!( + host.get("enabled"), + Some(json!(false)), + "a vetoed close must leave the host usable" + ); + assert_eq!(stops.get(), 0); + host.post("SetEnabled", Some(json!(true))); + host.window().disconnect(veto); + let read_count = reads.get(); + host.window().close(); + pump(std::time::Duration::from_millis(2200)); + assert_eq!( + reads.get(), + read_count, + "closing must stop real safety polling" + ); + assert_eq!(stops.get(), 1); + host.post("SetEnabled", Some(json!(false))); + host.set("enabled", json!(false)); + assert_eq!( + host.get("enabled"), + Some(json!(true)), + "late work must not mutate a retired host" + ); + host.dispose(); + assert_eq!(stops.get(), 1, "provider teardown is idempotent"); + drop(host); + let context = gtk::glib::MainContext::default(); + for _ in 0..20 { + if !context.pending() { + break; + } + context.iteration(false); + } + assert!( + weak.upgrade().is_none(), + "widget dispatchers and event receiver must not retain the host" + ); + let disabled = Host::open_doc(&app, disabled_doc, None, "main", None, false).unwrap(); + pump(std::time::Duration::from_millis(2200)); + assert_eq!( + reads.get(), + read_count, + "an undeclared optional feed must do no reads" + ); + disabled.window().close(); + drop(disabled); + + let mut scoped_doc: Value = + serde_json::from_str(include_str!("../../msdk/templates/settings/app.ui.json")).unwrap(); + scoped_doc["app"]["id"] = json!("com.example.MsdkScopedFeedTest"); + scoped_doc["persist"] = json!([]); + scoped_doc["capabilities"] = json!(["network"]); + scoped_doc["types"] = json!({"Other":{"id":"text"}}); + scoped_doc["state"]["other"] = json!("list"); + scoped_doc["feeds"] = json!({"other":"sdktest.lifecycle.feed"}); + let context = msdk::context::RequestContext::new(); + let sink = Rc::new(RefCell::new(None)); + let scoped_stops = Rc::new(Cell::new(0)); + let provider = Rc::new(ScopedProvider { + context: context.clone(), + sink: sink.clone(), + stops: scoped_stops.clone(), + }); + let scoped_host = + Host::open_with(&app, scoped_doc, None, "main", None, Some(provider), false).unwrap(); + let old = sink.borrow().as_ref().unwrap().clone(); + old.push(json!([{"id":"current"}])); + assert_eq!(scoped_host.get("other"), Some(json!([{"id":"current"}]))); + context.advance().unwrap(); + old.push(json!([{"id":"obsolete"}])); + assert_eq!(scoped_host.get("other"), Some(json!([{"id":"current"}]))); + assert!(old.clone().in_context(context.token().unwrap()).is_err()); + scoped_host.window().close(); + assert_eq!(scoped_stops.get(), 1); + old.push(json!([{"id":"after-close"}])); + assert_eq!(scoped_host.get("other"), Some(json!([{"id":"current"}]))); + drop(scoped_host); + bus.unregister_object(registration).unwrap(); +} diff --git a/rust/msdk-gtk/tests/runtime.rs b/rust/msdk-gtk/tests/runtime.rs new file mode 100644 index 000000000..87023dd09 --- /dev/null +++ b/rust/msdk-gtk/tests/runtime.rs @@ -0,0 +1,470 @@ +//! Actual host dispatch and process ownership in an isolated display/session. +use gtk::prelude::*; +use msdk_gtk::host::{Event, Host, ServiceCall, Services}; +use msdk_gtk::render::Dispatcher; +use serde_json::{Value, json}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; +use std::time::{Duration, Instant}; + +struct Versioned { + version: Rc>, + calls: Rc>, +} +impl Services for Versioned { + fn api_version(&self) -> u32 { + self.version.get() + } + fn call( + &self, + _: &str, + _: &std::collections::BTreeMap, + then: Option, + _: Option, + tx: futures_channel::mpsc::UnboundedSender, + ) -> bool { + assert_eq!( + self.version.get(), + 1, + "incompatible provider must never be dispatched" + ); + self.calls.set(self.calls.get() + 1); + tx.unbounded_send((then.unwrap(), Some(json!("recovered")))) + .unwrap(); + true + } + fn start_feed(&self, _: &str, _: Rc) -> bool { + false + } +} +struct Typed(Rc>); +impl Services for Typed { + fn invoke(&self, call: ServiceCall) -> Result { + let mode = self.0.get(); + std::thread::spawn(move || { + if mode == 1 { + call.reply + .success(Some(json!({"private":"synthetic-private-payload"}))); + } else if mode == 2 { + call.reply.fail( + msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::PermissionDenied, + "", + "", + 0, + ) + .with_detail("synthetic-private-detail".into()), + ); + } else { + call.reply.success(Some(json!("typed recovery"))); + // Contradictory duplicate completion cannot overwrite success. + call.reply.fail(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::Io, + "", + "", + 0, + )); + } + }); + Ok(true) + } +} + +struct ContextServices { + context: msdk::context::RequestContext, + pending: Rc>>, + deny: Rc>, + decline: Rc>, +} +impl Services for ContextServices { + fn invoke(&self, call: ServiceCall) -> Result { + if call.service == "sdktest.context.switch" { + self.context.advance().unwrap(); + call.reply.success(None); + } else { + let reply = call.reply.in_context(self.context.token().unwrap())?; + if self.decline.get() { + return Ok(false); + } + if self.deny.get() { + return Err(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::PermissionDenied, + "", + "", + 0, + )); + } + self.pending.borrow_mut().push(reply); + } + Ok(true) + } + fn stop(&self) { + self.context.close(); + self.pending.borrow_mut().clear(); + } +} + +fn pump_until(ready: impl Fn() -> bool) { + let deadline = Instant::now() + Duration::from_secs(3); + let context = gtk::glib::MainContext::default(); + while !ready() && Instant::now() < deadline { + while context.pending() { + context.iteration(false); + } + std::thread::sleep(Duration::from_millis(2)); + } + assert!(ready(), "native runtime operation did not settle"); +} +fn visible_labels(widget: >k::Widget) -> String { + if !widget.is_visible() { + return String::new(); + } + let mut text = widget + .downcast_ref::() + .map(|label| label.text().to_string()) + .unwrap_or_default(); + let mut child = widget.first_child(); + while let Some(node) = child { + text.push('\n'); + text.push_str(&visible_labels(&node)); + child = node.next_sibling(); + } + text +} +fn document() -> Value { + let mut doc: Value = + serde_json::from_str(include_str!("../../msdk/templates/settings/app.ui.json")).unwrap(); + doc["app"]["id"] = json!("com.example.MsdkRuntime"); + doc["persist"] = json!([]); + doc["capabilities"] = json!(["subprocess"]); + doc["state"]["out"] = json!("text"); + doc["state"]["failed"] = json!("bool"); + doc["messages"]["Run"] = json!("none"); + doc["messages"]["Done"] = json!("text"); + doc["messages"]["Failed"] = json!("text"); + doc["update"]["Run"] = json!([{"call":"process.run","args":{"command":"printf synthetic-private-argument"},"then":"Done","error":"Failed"}]); + doc["update"]["Done"] = json!([{"set":"out","to":"$payload"},{"set":"failed","to":false}]); + doc["update"]["Failed"] = json!([{"set":"out","to":"$payload"},{"set":"failed","to":true}]); + doc["surfaces"]["main"]["body"]["children"] + .as_array_mut() + .unwrap() + .push(json!({"type":"Text","text":"{out}"})); + doc +} +#[test] +fn extension_mismatch_recovers_and_closed_hosts_kill_owned_commands() { + assert_eq!(std::env::var("MSDK_PRIVATE_TEST_BUS").as_deref(), Ok("1")); + gtk::init().unwrap(); + let app = gtk::Application::builder() + .application_id("com.example.MsdkRuntimeTest") + .flags(gtk::gio::ApplicationFlags::NON_UNIQUE) + .build(); + app.register(gtk::gio::Cancellable::NONE).unwrap(); + let version = Rc::new(Cell::new(2)); + let calls = Rc::new(Cell::new(0)); + let provider = Rc::new(Versioned { + version: version.clone(), + calls: calls.clone(), + }); + let host = + Host::open_with(&app, document(), None, "main", None, Some(provider), false).unwrap(); + host.post("Run", None); + pump_until(|| host.get("failed") == Some(json!(true))); + assert_eq!(calls.get(), 0); + assert!( + host.get("out") + .unwrap() + .as_str() + .unwrap() + .contains("incompatible") + ); + version.set(1); + host.post("Run", None); + pump_until(|| host.get("out") == Some(json!("recovered"))); + assert_eq!(calls.get(), 1); + assert_eq!(host.get("failed"), Some(json!(false))); + host.window().close(); + drop(host); + + msdk::vocab::load_manifest(&json!({"services":[{"name":"sdktest.absent","capability":"subprocess","then":"text","args":{}}]})).unwrap(); + let mut unavailable_doc = document(); + unavailable_doc["update"]["Run"][0] = + json!({"call":"sdktest.absent","args":{},"then":"Done","error":"Failed"}); + let unavailable = Host::open_doc(&app, unavailable_doc, None, "main", None, false).unwrap(); + unavailable.post("Run", None); + pump_until(|| unavailable.get("failed") == Some(json!(true))); + assert!( + unavailable + .get("out") + .unwrap() + .as_str() + .unwrap() + .contains("unavailable") + ); + unavailable.window().close(); + drop(unavailable); + + let mode = Rc::new(Cell::new(1)); + let typed = Host::open_with( + &app, + document(), + None, + "main", + None, + Some(Rc::new(Typed(mode.clone()))), + false, + ) + .unwrap(); + typed.post("Run", None); + pump_until(|| typed.get("failed") == Some(json!(true))); + assert!( + typed + .get("out") + .unwrap() + .as_str() + .unwrap() + .contains("invalid data") + ); + assert!( + !typed + .get("out") + .unwrap() + .as_str() + .unwrap() + .contains("synthetic-private-payload") + ); + mode.set(2); + typed.post("Run", None); + pump_until(|| { + typed + .get("out") + .unwrap() + .as_str() + .unwrap() + .contains("Access was denied") + }); + assert!( + typed + .get("out") + .unwrap() + .as_str() + .unwrap() + .contains("synthetic-private-detail") + ); + mode.set(0); + typed.post("Run", None); + pump_until(|| typed.get("out") == Some(json!("typed recovery"))); + assert_eq!(typed.get("failed"), Some(json!(false))); + typed.window().close(); + drop(typed); + + msdk::vocab::load_manifest(&json!({"services":[{"name":"sdktest.context.switch","capability":"subprocess","args":{}}]})).unwrap(); + let scope = msdk::context::RequestContext::new(); + let pending = Rc::new(RefCell::new(Vec::new())); + let deny = Rc::new(Cell::new(false)); + let decline = Rc::new(Cell::new(false)); + let provider = Rc::new(ContextServices { + context: scope.clone(), + pending: pending.clone(), + deny: deny.clone(), + decline: decline.clone(), + }); + let mut scoped_doc = document(); + scoped_doc["state"]["applied"] = json!("number"); + for message in ["Done", "Failed"] { + scoped_doc["update"][message] + .as_array_mut() + .unwrap() + .push(json!({"add":"applied","by":1})); + } + scoped_doc["messages"]["RunSwitch"] = json!("none"); + scoped_doc["messages"]["SwitchNow"] = json!("text"); + scoped_doc["update"]["RunSwitch"] = json!([{"call":"process.run","args":{"command":"not executed"},"then":"SwitchNow","error":"Failed"}]); + scoped_doc["update"]["SwitchNow"] = json!([{"call":"sdktest.context.switch","args":{}}]); + let scoped = + Host::open_with(&app, scoped_doc, None, "main", None, Some(provider), false).unwrap(); + scoped.post("Run", None); + scoped.post("Run", None); + let old = std::mem::take(&mut *pending.borrow_mut()); + old[0].success(Some(json!("obsolete success"))); + old[1].fail(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::PermissionDenied, + "", + "", + 0, + )); + scope.advance().unwrap(); + scoped.post("Run", None); + let current = pending.borrow_mut().pop().unwrap(); + assert_eq!( + current + .clone() + .in_context(scope.token().unwrap()) + .err() + .unwrap() + .kind, + msdk::runtime::FailureKind::InvalidInput + ); + current.success(Some(json!("fresh scoped result"))); + pump_until(|| scoped.get("out") == Some(json!("fresh scoped result"))); + assert_eq!(scoped.get("applied"), Some(json!(1))); + assert_eq!(scoped.get("failed"), Some(json!(false))); + let labels = visible_labels(scoped.window().upcast_ref()); + assert!(labels.contains("fresh scoped result") && !labels.contains("obsolete success")); + + // Host retains a reply clone before invoke(). A binding made inside the + // provider must also protect the Host's synchronous Err path. + deny.set(true); + scoped.post("Run", None); + scope.advance().unwrap(); + deny.set(false); + scoped.post("Run", None); + pending + .borrow_mut() + .pop() + .unwrap() + .success(Some(json!("after synchronous denial"))); + pump_until(|| scoped.get("out") == Some(json!("after synchronous denial"))); + assert_eq!(scoped.get("applied"), Some(json!(2))); + assert_eq!(scoped.get("failed"), Some(json!(false))); + + // A current error is processed first, enqueueing its callback. The next + // delivery switches contexts BEFORE that callback runs. The callback must + // carry its token across the second queue boundary too. + scoped.post("Run", None); + scoped.post("RunSwitch", None); + let transition = std::mem::take(&mut *pending.borrow_mut()); + let previous = scope.token().unwrap(); + transition[0].fail(msdk::runtime::ServiceFailure::new( + msdk::runtime::FailureKind::Io, + "", + "", + 0, + )); + transition[1].success(Some(json!("switch"))); + pump_until(|| !previous.is_current()); + scoped.post("Run", None); + pending + .borrow_mut() + .pop() + .unwrap() + .success(Some(json!("after callback race"))); + pump_until(|| scoped.get("out") == Some(json!("after callback race"))); + assert_eq!( + scoped.get("applied"), + Some(json!(3)), + "obsolete error callback must not apply after a switch" + ); + assert_eq!(scoped.get("failed"), Some(json!(false))); + decline.set(true); + scoped.post("Run", None); + pump_until(|| { + scoped + .get("out") + .unwrap() + .as_str() + .unwrap() + .contains("service is unavailable") + }); + assert_eq!(scoped.get("failed"), Some(json!(true))); + assert_eq!( + scoped.get("applied"), + Some(json!(4)), + "a bound request cannot execute the real built-in fallback" + ); + decline.set(false); + scoped.post("Run", None); + pending + .borrow_mut() + .pop() + .unwrap() + .success(Some(json!("after declined binding"))); + pump_until(|| scoped.get("out") == Some(json!("after declined binding"))); + assert_eq!(scoped.get("failed"), Some(json!(false))); + scoped.window().close(); + assert!(scope.token().is_none()); + let weak = Rc::downgrade(&scoped); + drop(scoped); + assert!(weak.upgrade().is_none()); + + let stamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos(); + let path = std::env::temp_dir().join(format!("msdk-host-{}-{stamp}.pid", std::process::id())); + let quoted = path.to_string_lossy().replace('\'', "'\\''"); + let mut fixture_doc = document(); + fixture_doc["update"]["Run"][0]["args"]["command"] = json!(format!("touch '{quoted}'")); + let fixture = Rc::new(msdk_gtk::fixture::FixtureServices::from_json( + &json!({"calls":{}}), + )); + let fixture_host = + Host::open_with(&app, fixture_doc, None, "main", None, Some(fixture), false).unwrap(); + fixture_host.post("Run", None); + pump_until(|| fixture_host.get("failed") == Some(json!(true))); + assert!( + !path.exists(), + "missing fixture reply must never execute a real fallback" + ); + fixture_host.window().close(); + drop(fixture_host); + + let incompatible = + msdk_gtk::fixture::FixtureServices::try_from_json(&json!({"api_version":2,"calls":{}})) + .unwrap(); + assert!( + msdk_gtk::fixture::FixtureServices::try_from_json(&json!({"api_version":"2"})).is_err() + ); + assert!( + msdk_gtk::fixture::FixtureServices::try_from_json(&json!({"api_version":4294967296_u64})) + .is_err() + ); + let mut mismatch_doc = document(); + mismatch_doc["update"]["Run"][0]["args"]["command"] = json!(format!("touch '{quoted}'")); + let mismatch = Host::open_with( + &app, + mismatch_doc, + None, + "main", + None, + Some(Rc::new(incompatible)), + false, + ) + .unwrap(); + mismatch.post("Run", None); + pump_until(|| mismatch.get("failed") == Some(json!(true))); + assert!( + mismatch + .get("out") + .unwrap() + .as_str() + .unwrap() + .contains("incompatible") + ); + assert!( + !path.exists(), + "incompatible fixture must never execute a real fallback" + ); + mismatch.window().close(); + drop(mismatch); + + let mut doc = document(); + doc["update"]["Run"][0]["args"]["command"] = + json!(format!("printf '%s' \"$$\" > '{quoted}'; exec sleep 20")); + let host = Host::open_doc(&app, doc, None, "main", None, false).unwrap(); + host.post("Run", None); + pump_until(|| path.exists()); + let pid = std::fs::read_to_string(&path).unwrap(); + host.window().close(); + let alive = || { + std::process::Command::new("kill") + .args(["-0", pid.trim()]) + .stderr(std::process::Stdio::null()) + .status() + .unwrap() + .success() + }; + pump_until(|| !alive()); + assert_ne!(host.get("out"), Some(json!("done"))); + std::fs::remove_file(path).unwrap(); +} diff --git a/rust/msdk-gtk/tests/usage.rs b/rust/msdk-gtk/tests/usage.rs new file mode 100644 index 000000000..02cbdf2e9 --- /dev/null +++ b/rust/msdk-gtk/tests/usage.rs @@ -0,0 +1,487 @@ +//! Run under a private D-Bus session and Xvfb. +use gtk::prelude::*; +use msdk::usage::{ + Coverage, Observation, Quota, QuotaUnit, Scope, Snapshot, Source, State, Window, +}; + +fn labels(widget: >k::Widget, output: &mut Vec) { + if let Some(label) = widget.downcast_ref::() { + output.push(label.text().to_string()); + } + let mut child = widget.first_child(); + while let Some(current) = child { + labels(¤t, output); + child = current.next_sibling(); + } +} + +#[test] +fn usage_rows_preserve_accounts_and_do_not_show_expired_quota_as_live() { + assert_eq!(std::env::var("MSDK_PRIVATE_TEST_BUS").as_deref(), Ok("1")); + gtk::init().unwrap(); + let first = Observation { + scope: Scope { + provider: "claude".into(), + source: Source::LocalClient, + account: Some("a".into()), + }, + provider_label: "Claude".into(), + source_label: "This device".into(), + account_label: Some("Work".into()), + selected: true, + state: State::Fresh, + observed_at: Some(100), + windows: vec![Window { + key: "week".into(), + label: "7 day".into(), + quota: Some(Quota::new(2500, QuotaUnit::Used, 100, Some(200)).unwrap()), + }], + tokens: None, + }; + let second = Observation { + scope: Scope { + account: Some("b".into()), + ..first.scope.clone() + }, + account_label: Some("Personal".into()), + selected: false, + state: State::Unknown, + windows: vec![Window { + key: "week".into(), + label: "7 day".into(), + quota: None, + }], + ..first.clone() + }; + let snapshot = Snapshot { + coverage: Coverage::Partial, + observations: vec![first, second], + }; + let root = msdk_gtk::usage::render(&snapshot, 200).unwrap(); + let mut text = Vec::new(); + labels(root.upcast_ref(), &mut text); + for expected in [ + "Claude", + "This device", + "Work · Selected", + "Personal", + "7 day: Expired — refresh required", + "7 day: Unknown", + "Usage coverage is partial", + ] { + assert!( + text.iter().any(|value| value == expected), + "missing {expected}: {text:?}" + ); + } + assert!( + !text.iter().any(|value| value.contains("75%")), + "expired quota cannot appear current" + ); + let stale = Observation { + state: State::Stale, + windows: vec![Window { + key: "week".into(), + label: "7 day".into(), + quota: Some(Quota::new(2500, QuotaUnit::Used, 100, None).unwrap()), + }], + ..snapshot.observations[1].clone() + }; + let stale_view = msdk_gtk::usage::render( + &Snapshot { + coverage: Coverage::Complete, + observations: vec![stale], + }, + 200, + ) + .unwrap(); + let mut stale_text = Vec::new(); + labels(stale_view.upcast_ref(), &mut stale_text); + assert_eq!( + stale_text + .iter() + .filter(|value| value.as_str() == "Stale") + .count(), + 1 + ); + assert!( + stale_text + .iter() + .any(|value| value == "7 day: 75% remaining") + ); + assert!(stale_text.iter().any(|value| value == "Reset unknown")); + + let mut many = Vec::new(); + for (provider, display, count) in [ + ("codex", "Codex", 2), + ("claude", "Claude", 2), + ("grok", "Grok", 1), + ("opencode", "OpenCode", 1), + ] { + for index in 0..count { + let mut item = snapshot.observations[0].clone(); + item.scope.provider = provider.into(); + item.scope.account = Some(format!("fixture-{index}")); + item.provider_label = display.into(); + item.account_label = Some(format!("{display} account {index}")); + item.selected = index == 0; + many.push(item); + } + } + let mut many_snapshot = Snapshot { + coverage: Coverage::Partial, + observations: many, + }; + let panel = msdk_gtk::usage::UsagePanel::new(&many_snapshot, 150).unwrap(); + let scroll = panel.widget().clone(); + let mut all_text = Vec::new(); + labels(scroll.upcast_ref(), &mut all_text); + assert_eq!( + all_text.first().map(String::as_str), + Some("Providers: Codex · Claude · Grok · OpenCode") + ); + assert_eq!( + all_text.get(1).map(String::as_str), + Some("Usage coverage is partial") + ); + for expected in [ + "Codex account 1", + "Claude account 1", + "Grok account 0", + "OpenCode account 0", + ] { + assert!( + all_text + .iter() + .any(|value| value == expected || value == &format!("{expected} · Selected")) + ); + } + let window = gtk::Window::builder() + .default_width(360) + .default_height(300) + .child(&scroll) + .build(); + window.present(); + let context = gtk::glib::MainContext::default(); + let deadline = std::time::Instant::now() + std::time::Duration::from_secs(3); + while scroll.vadjustment().upper() <= scroll.vadjustment().page_size() + && std::time::Instant::now() < deadline + { + context.iteration(false); + std::thread::sleep(std::time::Duration::from_millis(10)); + } + let adjustment = scroll.vadjustment(); + assert!( + adjustment.upper() > adjustment.page_size(), + "long content must scroll" + ); + adjustment.set_value(adjustment.upper() - adjustment.page_size()); + assert!( + adjustment.value() > 0.0, + "the last provider must be reachable by scrolling" + ); + let position = adjustment.value(); + let invalid = Snapshot { + coverage: Coverage::Partial, + observations: vec![ + many_snapshot.observations[0].clone(), + many_snapshot.observations[0].clone(), + ], + }; + assert!(panel.update(&invalid, 150).is_err()); + let mut before = Vec::new(); + labels(scroll.upcast_ref(), &mut before); + assert!( + before + .iter() + .any(|value| value == "OpenCode account 0 · Selected") + ); + many_snapshot.observations[0].account_label = Some("Updated account".into()); + panel.update(&many_snapshot, 150).unwrap(); + panel.update(&many_snapshot, 150).unwrap(); + let deadline = std::time::Instant::now() + std::time::Duration::from_millis(500); + while std::time::Instant::now() < deadline { + context.iteration(false); + std::thread::sleep(std::time::Duration::from_millis(5)); + } + assert!( + (adjustment.value() - position).abs() < 1.0, + "refresh preserves the numeric scroll offset" + ); + let mut updated = Vec::new(); + labels(scroll.upcast_ref(), &mut updated); + assert!( + updated + .iter() + .any(|value| value == "Updated account · Selected") + ); + window.close(); + let source = br#"{"schemaVersion":1,"entries":[{"provider":"codex","updatedAt":"2026-01-01T00:00:00Z","windows":[{"key":"week","label":"7 day","remaining":75,"resetsAt":"2026-01-02T00:00:00Z"}]}]}"#; + let parsed = msdk_gtk::codexbar::decode_snapshot(source, 1_767_225_600, 300).unwrap(); + let source_view = msdk_gtk::usage::render(&parsed, 1_767_225_600).unwrap(); + let mut parsed_text = Vec::new(); + labels(source_view.upcast_ref(), &mut parsed_text); + for expected in [ + "Codex", + "Provider total", + "7 day: 75% remaining", + "Usage coverage is partial", + ] { + assert!( + parsed_text.iter().any(|value| value == expected), + "missing {expected}: {parsed_text:?}" + ); + } + #[cfg(unix)] + { + use msdk::context::RequestContext; + use msdk_gtk::usage::ScopedUpdate; + use std::os::unix::fs::PermissionsExt; + use std::time::{Duration, SystemTime, UNIX_EPOCH}; + + let stamp = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos(); + let dir = + std::env::temp_dir().join(format!("msdk-usage-feed-{}-{stamp}", std::process::id())); + std::fs::create_dir(&dir).unwrap(); + struct Cleanup(std::path::PathBuf); + impl Drop for Cleanup { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.0); + } + } + let _cleanup = Cleanup(dir.clone()); + let executable = dir.join("synthetic-snapshot"); + std::fs::write( + &executable, + format!( + "#!/bin/sh\nprintf '%s' '{}'\n", + std::str::from_utf8(source).unwrap() + ), + ) + .unwrap(); + std::fs::set_permissions(&executable, std::fs::Permissions::from_mode(0o700)).unwrap(); + let context = RequestContext::new(); + let panel = msdk_gtk::usage::UsagePanel::new(&snapshot, 1_767_225_600).unwrap(); + let (tx, rx) = std::sync::mpsc::channel(); + let _task = msdk_gtk::codexbar::read_snapshot_scoped( + context.token().unwrap(), + executable.clone(), + u64::MAX, + 90, + move |reply| tx.send(reply).unwrap(), + ) + .unwrap(); + let reply = rx.recv_timeout(Duration::from_secs(3)).unwrap(); + assert!(matches!( + panel.update_scoped(reply, 1_767_225_600).unwrap(), + ScopedUpdate::Applied + )); + let mut current = Vec::new(); + labels(panel.widget().upcast_ref(), &mut current); + assert!(current.iter().any(|value| value == "7 day: 75% remaining")); + + let (tx, rx) = std::sync::mpsc::channel(); + let _task = msdk_gtk::codexbar::read_snapshot_scoped( + context.token().unwrap(), + executable.clone(), + u64::MAX, + 91, + move |reply| tx.send(reply).unwrap(), + ) + .unwrap(); + let queued = rx.recv_timeout(Duration::from_secs(3)).unwrap(); + context.advance().unwrap(); + assert!(matches!( + panel.update_scoped(queued, 1_767_225_600).unwrap(), + ScopedUpdate::Expired + )); + let mut after_old = Vec::new(); + labels(panel.widget().upcast_ref(), &mut after_old); + assert_eq!( + after_old, current, + "expired queued replies must not mutate the view" + ); + + std::fs::write( + &executable, + "#!/bin/sh\nprintf 'synthetic-private-error' >&2\nprintf 'not-json'\n", + ) + .unwrap(); + let (tx, rx) = std::sync::mpsc::channel(); + let _task = msdk_gtk::codexbar::read_snapshot_scoped( + context.token().unwrap(), + executable.clone(), + u64::MAX, + 92, + move |reply| tx.send(reply).unwrap(), + ) + .unwrap(); + let failed = rx.recv_timeout(Duration::from_secs(3)).unwrap(); + assert!(matches!( + panel.update_scoped(failed, 1_767_225_600).unwrap(), + ScopedUpdate::ReadFailed(_) + )); + let mut after_failure = Vec::new(); + labels(panel.widget().upcast_ref(), &mut after_failure); + assert!( + after_failure + .iter() + .any(|value| value.contains("Couldn't refresh usage")) + ); + assert!(after_failure.iter().any(|value| value == "Stale")); + assert!( + after_failure + .iter() + .any(|value| value == "7 day: 75% remaining") + ); + assert!( + !after_failure + .iter() + .any(|value| value.contains("synthetic-private-error")) + ); + + use msdk_gtk::codexbar_monitor::{CodexBarMonitor, RefreshStart, RefreshState}; + let marker = dir.join("reads"); + let safe_marker = marker.to_str().unwrap().replace('\'', "'\\''"); + let script = format!( + "#!/bin/sh\nprintf x >> '{safe_marker}'\nsleep 0.2\nprintf '%s' '{}'\n", + std::str::from_utf8(source).unwrap() + ); + std::fs::write(&executable, &script).unwrap(); + let panel = + std::rc::Rc::new(msdk_gtk::usage::UsagePanel::new(&snapshot, 1_767_225_600).unwrap()); + let states = std::rc::Rc::new(std::cell::RefCell::new(Vec::new())); + let received = states.clone(); + let monitor = CodexBarMonitor::new(panel.clone(), executable.clone(), 0, move |state| { + received.borrow_mut().push(state) + }); + assert_eq!(monitor.refresh().unwrap(), RefreshStart::Closed); + assert!(!marker.exists(), "closed monitor must not start reads"); + monitor.open(); + assert!(!marker.exists(), "opening alone does not poll"); + assert_eq!(monitor.refresh().unwrap(), RefreshStart::Started); + assert_eq!(monitor.refresh().unwrap(), RefreshStart::Coalesced); + let main = gtk::glib::MainContext::default(); + let deadline = std::time::Instant::now() + Duration::from_secs(4); + while !states.borrow().contains(&RefreshState::Updated) + && std::time::Instant::now() < deadline + { + main.iteration(false); + std::thread::sleep(Duration::from_millis(5)); + } + assert!(states.borrow().contains(&RefreshState::Updated)); + assert!(!monitor.is_busy()); + assert_eq!(std::fs::read_to_string(&marker).unwrap(), "x"); + let mut aged = Vec::new(); + labels(panel.widget().upcast_ref(), &mut aged); + assert!( + aged.iter().any(|value| value == "Stale"), + "source age is rechecked on final delivery" + ); + + std::fs::write( + &executable, + format!("#!/bin/sh\nprintf x >> '{safe_marker}'\nexec sleep 20\n"), + ) + .unwrap(); + assert_eq!(monitor.refresh().unwrap(), RefreshStart::Started); + let deadline = std::time::Instant::now() + Duration::from_secs(3); + while std::fs::read_to_string(&marker).unwrap().len() < 2 + && std::time::Instant::now() < deadline + { + main.iteration(false); + std::thread::sleep(Duration::from_millis(5)); + } + assert_eq!(std::fs::read_to_string(&marker).unwrap(), "xx"); + monitor.close(); + assert!(!monitor.is_busy()); + assert_eq!(monitor.refresh().unwrap(), RefreshStart::Closed); + std::fs::write(&executable, &script).unwrap(); + monitor.open(); + assert_eq!(monitor.refresh().unwrap(), RefreshStart::Started); + let deadline = std::time::Instant::now() + Duration::from_secs(4); + while (monitor.is_busy() || std::fs::read_to_string(&marker).unwrap().len() < 3) + && std::time::Instant::now() < deadline + { + main.iteration(false); + std::thread::sleep(Duration::from_millis(5)); + } + assert!( + !monitor.is_busy(), + "old completion must not clear or block the new read" + ); + assert_eq!(std::fs::read_to_string(&marker).unwrap(), "xxx"); + assert_eq!( + states + .borrow() + .iter() + .filter(|&&state| state == RefreshState::Updated) + .count(), + 2 + ); + monitor.close(); + + let control = msdk_gtk::usage_control::UsageControl::new( + &snapshot, + 1_767_225_600, + executable.clone(), + 0, + ) + .unwrap(); + assert!(!control.refresh_button().is_sensitive()); + control.open().unwrap(); + control.open().unwrap(); + assert!(!control.refresh_button().is_sensitive()); + assert_eq!(control.status_label().text(), "Refreshing usage…"); + let deadline = std::time::Instant::now() + Duration::from_secs(4); + while control.status_label().text() != "Refresh complete" + && std::time::Instant::now() < deadline + { + main.iteration(false); + std::thread::sleep(Duration::from_millis(5)); + } + assert_eq!(control.status_label().text(), "Refresh complete"); + assert!(control.refresh_button().is_sensitive()); + assert_eq!( + std::fs::read_to_string(&marker).unwrap(), + "xxxx", + "repeated open must not duplicate reads" + ); + std::fs::write(&executable, format!("#!/bin/sh\nprintf x >> '{safe_marker}'\nprintf 'synthetic-private-error' >&2\nprintf 'not-json'\n")).unwrap(); + control.refresh_button().emit_clicked(); + let deadline = std::time::Instant::now() + Duration::from_secs(4); + while control.status_label().text() != "Retry when ready" + && std::time::Instant::now() < deadline + { + main.iteration(false); + std::thread::sleep(Duration::from_millis(5)); + } + assert_eq!(control.status_label().text(), "Retry when ready"); + assert!(control.refresh_button().is_sensitive()); + let mut failure_text = Vec::new(); + labels(control.widget().upcast_ref(), &mut failure_text); + assert!(failure_text.iter().any(|value| value == "Stale")); + assert!( + !failure_text + .iter() + .any(|value| value.contains("synthetic-private-error")) + ); + std::fs::write(&executable, &script).unwrap(); + control.refresh_button().emit_clicked(); + let deadline = std::time::Instant::now() + Duration::from_secs(4); + while control.status_label().text() != "Refresh complete" + && std::time::Instant::now() < deadline + { + main.iteration(false); + std::thread::sleep(Duration::from_millis(5)); + } + assert_eq!(control.status_label().text(), "Refresh complete"); + assert_eq!(std::fs::read_to_string(&marker).unwrap(), "xxxxxx"); + control.close(); + assert!(!control.refresh_button().is_sensitive()); + assert_eq!(control.status_label().text(), "Usage not open"); + } +} diff --git a/rust/msdk/Cargo.toml b/rust/msdk/Cargo.toml index c4397896d..c9b74e1e5 100644 --- a/rust/msdk/Cargo.toml +++ b/rust/msdk/Cargo.toml @@ -15,3 +15,11 @@ path = "src/main.rs" [dependencies] serde_json = { version = "1", features = ["preserve_order"] } + +[dev-dependencies] +# Generated model compilation is an offline integration test, so its derive +# dependency must be provisioned by Cargo before running the test executable. +serde = { version = "1", features = ["derive"] } + +[target.'cfg(unix)'.dependencies] +libc = "0.2" diff --git a/rust/msdk/LICENSE b/rust/msdk/LICENSE new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/rust/msdk/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/rust/msdk/README.md b/rust/msdk/README.md index 6d66df60d..3ed67c15e 100644 --- a/rust/msdk/README.md +++ b/rust/msdk/README.md @@ -1,17 +1,106 @@ -# msdk (Phase 1 core) +# M-series app SDK core and CLI -The closed UI vocabulary of the M-series app SDK and `msdk check`. No GUI dependencies; builds in seconds. -Design and rationale: [mseries/PLATFORM-PLAN.md](../../mseries/PLATFORM-PLAN.md). Benchmark: [mseries/sdk-bench](../../mseries/sdk-bench/). +The core provides descriptions (`.msdk` and JSON), checker/discovery/schema, +typed rules, semantic inspection, acceptance scenarios and standalone Rust app +generation. GTK hosting is in `msdk-gtk`. API/release status and remaining +qualification gates: [SDK completion ledger](../../mseries/SDK-COMPLETION.md). -```bash -cargo run -p msdk -- check msdk/examples/quick-notes.ui.json # one line per problem, with a JSON path, a code and a fix -cargo run -p msdk -- components # the vocabulary as JSON (prompts, grammar generation) +From `rust/`: + +```sh +cargo run -p msdk -- templates +cargo run -p msdk -- new settings /tmp/my-settings --id com.example.MySettings --name 'My Settings' +cargo run -p msdk -- check /tmp/my-settings/app.ui.json +cargo run -p msdk -- gate /tmp/my-settings/app.ui.json /tmp/my-settings/app.gates.json +cargo run -p msdk -- gen /tmp/my-settings/app.ui.json /tmp/my-settings-app --sdk-root "$PWD" +cargo run --manifest-path /tmp/my-settings-app/Cargo.toml ``` -Format v0 is JSON so a small model can be constrained to it with a grammar. An app description has `app`, -`capabilities`, `state` (text, bool, number, list), `messages` and a `window` built only from the components -listed by `msdk components`. `Custom` is the escape hatch and always raises a warning; each use is a vocabulary -gap to record in `mseries/sdk-bench/GAPS.md`. +Use new output directories: `new` and `gen` refuse existing destinations. Keep +the SDK checkout available; generated Cargo dependencies use its canonical local +paths. Generation creates an independent workspace so app builds do not resolve +the compositor/whole OS. The full OS workspace can still resolve unrelated Git +dependencies when building the CLI; use `mseries/sdk-tests/prepare.py` for the +isolated SDK workspace when those sources are unavailable. + +The supported native build path requires Linux, Rust 2024, GTK 4.20+ development +headers, pkg-config, Wayland headers and wayland-scanner. Generation/core checks +also run without GTK. Actual supported runtime and target-host acceptance remain +qualification gates; the generator is not a native macOS GTK port. + +`gen` emits a Cargo manifest, description, `src/lib.rs` (record structs, `State`, +`Message::into_event`, embedded document), `src/main.rs` (real GTK Host), initial +state round-trip test and app README. Number fields use `serde_json::Number` so +large integer measurements remain exact. Source names are preserved in serde +fields; Rust keywords/non-identifiers get collision-free Rust identifiers. +The executable provides standard Ctrl+Q and supports `--screenshot output.png` for isolated render checks and +exits unsuccessfully if opening/rendering fails. Ordinary launches use the +stable application ID and reactivate the existing window. + +Custom service manifests next to the source description are embedded and +registered by `app_model::document()`. They declare types, not implementations: +implement `Services` and switch to `Host::open_with` for those backends. For +custom Rust logic, use generated models plus an explicit `LogicFactory`; +project generation rejects missing custom logic instead of inventing behavior. +Generation does not call services, provision credentials or install artifacts. + +After generation, `cargo fmt`, `cargo test --all-targets` and +`cargo clippy --all-targets -- -D warnings` check the standalone source. Changes +to the description's types require regenerating models in a new directory and +reviewing app-local changes. Views/rules stay inspectable in `app.ui.json`. + +`msdk-run description --watch` is the separate interpreter preview loop. +`describe`, `complete`, `explain`, `schema` and `components` derive from the +checker vocabulary. `render` produces a semantic tree; `gate` runs headless +state/effect scenarios. Neither executes a real backend or proves live GTK +accessibility. `parity`, Studio and a live introspection registry are not +implemented commands. + +## Package the application + +After building on the matching Linux architecture, with `dpkg-dev`, +`desktop-file-utils` and `appstream` installed: + +```sh +msdk pack /tmp/my-settings-app --binary /path/to/built/executable --output /tmp/my-settings.deb --version 0.1.0 +``` + +Supply the actual executable path (including any `CARGO_TARGET_DIR` override). +`pack` derives architecture from ELF and native-library dependencies using +`dpkg-shlibdeps`, validates desktop/AppStream metadata and builds with +`dpkg-deb --root-owner-group`. The installed executable/desktop/icon IDs all use +the description's complete app ID. The package includes an editable generated +SVG icon and the project's license. Generated code links the GPL-3.0-only SDK; +review app metadata, attribution and assets before public distribution. + +Packaging never builds, installs or launches the app, and refuses an existing +output. Use the platform's package manager for explicit installation/removal. +There are no generated background units or removal scripts; removing the package +retires its owned executable, launcher, metadata, icon and docs. Per-user app +state remains under the runtime's XDG data location. Package correctness and +source-to-installed identity are checked separately from target-desktop +interaction, accessibility and acceptance. The native CI exercises fresh install, +reinstall, installed launch and removal in a disposable Linux runner. + +Validation helpers live in `mseries/sdk-tests/`: independent JSON Schema versus +checker scenarios, actual keyboard/AT-SPI controls, a real private D-Bus lifecycle +test, and compact/light/dark render profiles with asserted GTK 10/15-point fonts. +Run native probes under fresh Xvfb and D-Bus sessions with synthetic XDG state; +never borrow the owner's desktop session. Exact remaining gates and environment +limits are recorded in the completion ledger. + +## Runtime services and diagnostics + +`msdk describe runtime` lists actual limits and failure codes; `msdk explain CODE` +provides recovery guidance. Modern backends implement +`msdk_gtk::host::Services::invoke(ServiceCall)` and complete its owned +`ServiceReply` with typed success/failure. The Host validates registered payloads, +blocks incompatible extensions, routes failures to the app or banner and ignores +duplicate terminal replies. Legacy provider entry points remain compatible. -Not here yet: the `logic.rs` side (State/Msg/update), the runtime that renders the tree (Relm4 spike or own -runtime on gtk4-rs + granite-rs), `msdk shot`, `msdk pack`. +`msdk::process::spawn` provides owned Linux/macOS task groups, timeout and output +limits; the GTK Host cancels its own jobs on accepted close. Runtime diagnostic, +Debug and Display output omit private payloads; private UI detail is explicit. +See [the full contract and verification commands](../../mseries/SDK-RUNTIME-CONTRACT.md). +Streaming/progress, backend protocol negotiation and app-specific context/race +qualification remain open. diff --git a/rust/msdk/examples/home-storage.ui.json b/rust/msdk/examples/home-storage.ui.json new file mode 100644 index 000000000..a5979361f --- /dev/null +++ b/rust/msdk/examples/home-storage.ui.json @@ -0,0 +1,150 @@ +{ + "sdk": 1, + "app": { + "id": "io.github.techmore.HomeStorage", + "name": "Home Storage", + "icon": "drive-harddisk" + }, + "capabilities": [ + "subprocess" + ], + "state": { + "ready": "bool", + "busy": "bool", + "failed": "bool", + "status": "text", + "result": "text" + }, + "initial": { + "ready": true, + "busy": false, + "failed": false, + "status": "Check available space on the filesystem containing your home folder.", + "result": "" + }, + "messages": { + "Refresh": "none", + "Loaded": "text", + "Failed": "text" + }, + "update": { + "Refresh": [ + { + "when": "ready", + "do": [ + { + "set": "ready", + "to": false + }, + { + "set": "busy", + "to": true + }, + { + "set": "failed", + "to": false + }, + { + "set": "result", + "to": "" + }, + { + "set": "status", + "to": "Checking home storage\u2026" + }, + { + "call": "process.run", + "args": { + "command": "report=$(LC_ALL=C df -Pk \"${HOME:?Home folder is unavailable}\") || exit\nprintf '%s\\n' \"$report\" | awk 'NR==2 && NF==6 && $2 ~ /^[0-9]+$/ && $3 ~ /^[0-9]+$/ && $4 ~ /^-?[0-9]+$/ && $5 ~ /^[0-9]+%$/ { printf \"Available: %.1f MiB\\nUsed: %.1f MiB\\nTotal: %.1f MiB\\nUsed space: %s\\n\", $4/1024, $3/1024, $2/1024, $5; ok=1 } END { if (!ok || NR!=2) { print \"Storage report format is unavailable\" > \"/dev/stderr\"; exit 1 } }'" + }, + "then": "Loaded", + "error": "Failed" + } + ] + } + ], + "Loaded": [ + { + "set": "result", + "to": "$payload" + }, + { + "set": "status", + "to": "Current filesystem usage. No files were changed." + }, + { + "set": "busy", + "to": false + }, + { + "set": "ready", + "to": true + }, + { + "set": "failed", + "to": false + } + ], + "Failed": [ + { + "set": "result", + "to": "$payload" + }, + { + "set": "status", + "to": "Storage could not be checked. Review the error and try again." + }, + { + "set": "busy", + "to": false + }, + { + "set": "ready", + "to": true + }, + { + "set": "failed", + "to": true + } + ] + }, + "surfaces": { + "main": { + "kind": "window", + "title": "Home Storage", + "body": { + "type": "Box", + "direction": "column", + "spacing": "large", + "children": [ + { + "type": "Text", + "text": "Home storage", + "text_style": "title" + }, + { + "type": "Text", + "text": "{status}" + }, + { + "type": "Text", + "text": "{result}" + }, + { + "type": "Button", + "label": "Check again", + "on": "Refresh", + "visible_if": "ready", + "button_style": "suggested" + }, + { + "type": "Text", + "text": "You can close this window to cancel the check.", + "visible_if": "busy", + "text_style": "muted" + } + ] + } + } + } +} diff --git a/rust/msdk/src/agent.rs b/rust/msdk/src/agent.rs index 52deccbfd..0eb54003d 100644 --- a/rust/msdk/src/agent.rs +++ b/rust/msdk/src/agent.rs @@ -35,6 +35,9 @@ fn props_json(ps: &[Prop]) -> Value { /// Describes a component, surface kind, service, feed or enum, with a minimal valid example. pub fn describe(name: &str) -> Option { + if name == "runtime" { + return Some(crate::runtime::description()); + } if let Some(c) = vocab::component(name) { let mut ex = serde_json::Map::new(); ex.insert("type".into(), json!(c.name)); @@ -73,6 +76,7 @@ pub fn describe(name: &str) -> Option { /// Every name `describe` knows, for "what can I use?". pub fn catalogue() -> Value { json!({ + "runtime": crate::runtime::description(), "components": vocab::COMPONENTS.iter().map(|c| json!({ "name": c.name, "about": c.about })).collect::>(), "surfaces": vocab::SURFACES.iter().map(|s| json!({ "name": s.name, "role": s.role })).collect::>(), "services": vocab::services().into_iter().map(|s| json!({ "name": s.name, "about": s.about })).collect::>(), @@ -301,10 +305,19 @@ fn complete_update(doc: &Value, segs: &[String], state: &[(String, String)]) -> /// One-paragraph explanation and the usual repair for each diagnostic code. pub fn explain(code: &str) -> Option<&'static str> { + if let Some(kind) = crate::runtime::FailureKind::ALL.iter().find(|kind| kind.code() == code) { + return Some(kind.message()); + } Some(match code { "bad-json" => "The file is not valid JSON. Check commas, quotes and brackets near the reported line.", + "missing-input" => "Supply at least one app description to check.", + "service-manifest" => { + "A service manifest could not be read or validated. Fix its path, version or declarations, then retry; the command did not continue with an incomplete contract." + } "not-object" => "The document, a component or an action must be a JSON object { ... }.", - "unsupported-sdk-version" => "Add \"sdk\": 1 at the top of the document.", + "unsupported-sdk-version" => { + "Declare the supported sdk format for a new document. For an incompatible existing document, use a compatible SDK or migrate its content; do not just relabel the version." + } "unknown-property" => { "That key is not part of this component or section. The fix line suggests the nearest valid name; `msdk describe ` lists them all." } diff --git a/rust/msdk/src/check.rs b/rust/msdk/src/check.rs index d18e2d182..a80386e5e 100644 --- a/rust/msdk/src/check.rs +++ b/rust/msdk/src/check.rs @@ -136,7 +136,11 @@ pub fn check(doc: &Value) -> Vec { "/sdk", "unsupported-sdk-version", format!("`sdk` must be {}", crate::FORMAT_VERSION), - Some(format!("add \"sdk\": {}", crate::FORMAT_VERSION)), + Some(if root.contains_key("sdk") { + "use a compatible SDK or migrate the document; do not change only its version number".into() + } else { + format!("add \"sdk\": {}", crate::FORMAT_VERSION) + }), ), } cx.caps = root @@ -949,6 +953,14 @@ fn check_actions(v: &Value, path: &str, payload: Payload, cx: &mut Cx) { } } let target = obj.get(verb.as_str()).and_then(Value::as_str); + if matches!(verb.as_str(), "add" | "toggle" | "toast" | "open" | "close" | "when") && target.is_none() { + cx.err(&format!("{ap}/{verb}"), "wrong-type", format!("`{verb}` needs a text target"), None); + continue; + } + if verb.as_str() == "quit" && obj.get("quit") != Some(&Value::Bool(true)) { + cx.err(&format!("{ap}/quit"), "wrong-type", "`quit` must be true".into(), None); + continue; + } let state_ty = |cx: &mut Cx, key: &str| -> Option { let t = cx.state.get(key).cloned(); if t.is_some() { @@ -1143,6 +1155,14 @@ fn check_actions(v: &Value, path: &str, payload: Payload, cx: &mut Cx) { } } "call" => { + if obj.get("args").is_some_and(|args| !args.is_object()) { + cx.err(&format!("{ap}/args"), "wrong-type", "`args` must be an object".into(), None); + } + for slot in ["then", "error"] { + if obj.get(slot).is_some_and(|message| !message.is_string()) { + cx.err(&format!("{ap}/{slot}"), "wrong-type", format!("`{slot}` names a message"), None); + } + } let Some(name) = target else { cx.err(&ap, "wrong-type", "`call` names a service".into(), None); continue; diff --git a/rust/msdk/src/context.rs b/rust/msdk/src/context.rs new file mode 100644 index 000000000..bca63adad --- /dev/null +++ b/rust/msdk/src/context.rs @@ -0,0 +1,98 @@ +//! Request generations for a single app-owned account/page/selection context. +//! Context identity remains the app's responsibility; no account data is stored. +use std::sync::{ + Arc, Mutex, + atomic::{AtomicBool, Ordering}, +}; + +struct Inner(Mutex>); +impl Drop for Inner { + fn drop(&mut self) { + if let Some(token) = self.0.get_mut().unwrap_or_else(|error| error.into_inner()) { + token.active.store(false, Ordering::SeqCst); + } + } +} + +/// Clones share ownership. The last owner dropping invalidates pending replies; +/// tokens and queued replies do not retain that ownership. +#[derive(Clone)] +pub struct RequestContext(Arc); +impl Default for RequestContext { + fn default() -> Self { + Self(Arc::new(Inner(Mutex::new(Some(ContextToken::new()))))) + } +} +impl RequestContext { + pub fn new() -> Self { + Self::default() + } + + pub fn token(&self) -> Option { + self.0.0.lock().unwrap_or_else(|error| error.into_inner()).clone() + } + + /// Invalidate every pending reply in this context and start a fresh + /// generation. A closed context cannot reopen; create a new owner instead. + pub fn advance(&self) -> Option { + let mut current = self.0.0.lock().unwrap_or_else(|error| error.into_inner()); + let previous = current.as_ref()?; + previous.active.store(false, Ordering::SeqCst); + let next = ContextToken::new(); + *current = Some(next.clone()); + Some(next) + } + + /// Permanently invalidate the context, including tokens held by workers. + pub fn close(&self) { + if let Some(token) = self.0.0.lock().unwrap_or_else(|error| error.into_inner()).take() { + token.active.store(false, Ordering::SeqCst); + } + } +} + +#[derive(Clone)] +pub struct ContextToken { + active: Arc, +} +impl ContextToken { + fn new() -> Self { + Self { active: Arc::new(AtomicBool::new(true)) } + } + pub fn is_current(&self) -> bool { + self.active.load(Ordering::SeqCst) + } + /// Preserve the token until delivery, including time spent in a UI queue. + pub fn wrap(&self, value: T) -> Scoped { + Scoped { token: self.clone(), value } + } +} +impl std::fmt::Debug for ContextToken { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ContextToken").field("current", &self.is_current()).finish() + } +} + +/// A reply that must be checked at its final consumer, not on the worker before +/// enqueueing. Debug omits its private value, without requiring T: Debug. +pub struct Scoped { + token: ContextToken, + value: T, +} +impl Scoped { + /// Transform a reply without discarding its final-delivery freshness check. + pub fn map(self, f: impl FnOnce(T) -> U) -> Scoped { + Scoped { token: self.token, value: f(self.value) } + } + /// Consume on the UI/state owner's thread immediately before applying. + /// This is a freshness snapshot, not a lock around arbitrary app mutation: + /// serialize context switches and state application on that same thread. + pub fn into_current(self) -> Option { + self.token.is_current().then_some(self.value) + } +} +impl std::fmt::Debug for Scoped { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Scoped").field("current", &self.token.is_current()).finish_non_exhaustive() + } +} diff --git a/rust/msdk/src/generate.rs b/rust/msdk/src/generate.rs new file mode 100644 index 000000000..2b22da3ac --- /dev/null +++ b/rust/msdk/src/generate.rs @@ -0,0 +1,177 @@ +//! Inspectable Rust models and standalone GTK projects from checked descriptions. +//! Generation never executes app services or installs anything. + +use std::collections::BTreeMap; +use std::path::Path; + +use serde_json::Value; + +fn literal(value: &str) -> String { + format!("{value:?}") +} + +// Preserve ordinary names, including Rust keywords, and encode the few names +// Rust cannot represent as raw identifiers. The prefix is reserved by encoding +// user names beginning with it too, so distinct source names cannot collide. +fn ident(name: &str) -> String { + if !name.is_empty() + && name != "_" + && !matches!(name, "self" | "Self" | "super" | "crate") + && !name.starts_with("msdk_encoded_") + && !name.as_bytes()[0].is_ascii_digit() + && name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') + { + format!("r#{name}") + } else { + format!("msdk_encoded_{}", name.as_bytes().iter().map(|b| format!("{b:02x}")).collect::()) + } +} + +fn rust_type(ty: &str) -> Result { + Ok(match ty { + "text" => "String".into(), + "bool" => "bool".into(), + "number" => "serde_json::Number".into(), + t if t.starts_with("list<") && t.ends_with('>') => { + format!("Vec", ident(&t[5..t.len() - 1])) + } + other => return Err(format!("gen: unsupported type {other:?}")), + }) +} + +fn checked(doc: &Value) -> Result<(), String> { + let errors: Vec<_> = + crate::check(doc).into_iter().filter(|d| d.severity == crate::Severity::Error).map(|d| d.to_string()).collect(); + if errors.is_empty() { Ok(()) } else { Err(errors.join("\n")) } +} + +/// Generate typed records, State and Message, with lossless JSON/event bridges. +/// Number uses serde_json::Number rather than rounding integer observations to f64. +pub fn models(doc: &Value) -> Result { + checked(doc)?; + let mut out = String::from( + "// Generated by msdk gen. Edit the description and regenerate in a new directory.\n\ + #![allow(non_snake_case, non_camel_case_types)]\n\ + pub mod records {\n", + ); + for (name, fields) in doc["types"].as_object().into_iter().flatten() { + out.push_str(&format!( + " #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]\n pub struct {} {{\n", + ident(name) + )); + for (name, ty) in fields.as_object().into_iter().flatten() { + let ty = rust_type(ty.as_str().ok_or("gen: field type must be a string")?)?; + out.push_str(&format!( + " #[serde(rename = {})]\n pub {}: {ty},\n", + literal(name), + ident(name) + )); + } + out.push_str(" }\n"); + } + out.push_str("}\n#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]\npub struct State {\n"); + for (name, ty) in doc["state"].as_object().into_iter().flatten() { + let ty = rust_type(ty.as_str().ok_or("gen: state type must be a string")?)?; + out.push_str(&format!(" #[serde(rename = {})]\n pub {}: {ty},\n", literal(name), ident(name))); + } + out.push_str("}\nimpl State {\n pub fn initial() -> Result {\n Self::from_store(msdk::logic::initial_store(&document()))\n }\n pub fn from_store(store: msdk::logic::Store) -> Result {\n serde_json::from_value(serde_json::Value::Object(store))\n }\n pub fn into_store(self) -> Result {\n match serde_json::to_value(self)? {\n serde_json::Value::Object(store) => Ok(store),\n _ => unreachable!(\"State serializes as an object\"),\n }\n }\n}\n#[derive(Debug, Clone, PartialEq)]\npub enum Message {\n"); + for (name, ty) in doc["messages"].as_object().into_iter().flatten() { + let payload = if ty == "none" { + String::new() + } else { + format!("({})", rust_type(ty.as_str().ok_or("gen: message type must be a string")?)?) + }; + out.push_str(&format!(" {}{payload},\n", ident(name))); + } + out.push_str("}\nimpl Message {\n pub fn into_event(self) -> (String, Option) {\n match self {\n"); + for (name, ty) in doc["messages"].as_object().into_iter().flatten() { + let (pat, payload): (String, String) = if ty == "none" { + (String::new(), "None".into()) + } else { + ("(value)".into(), "Some(serde_json::json!(value))".into()) + }; + out.push_str(&format!(" Self::{}{pat} => ({}.into(), {payload}),\n", ident(name), literal(name))); + } + out.push_str(" }\n }\n}\n\n/// The checked description embedded in this application.\npub fn document() -> serde_json::Value {\n serde_json::from_str(include_str!(\"../app.ui.json\")).expect(\"generated checked description\")\n}\n"); + Ok(out) +} + +/// Return a complete standalone Cargo project without mutating the filesystem. +/// Custom service manifests are not silently invented or replaced by fixtures. +pub fn project(doc: &Value, sdk_root: &Path) -> Result, String> { + project_with_manifests(doc, sdk_root, &[]) +} + +pub fn project_with_manifests( + doc: &Value, + sdk_root: &Path, + manifests: &[Value], +) -> Result, String> { + for manifest in manifests { + crate::vocab::load_manifest(manifest)?; + } + checked(doc)?; + if doc["logic"] == "rust" { + return Err( + "gen: Rust logic must be supplied by the app; use models() and Host::open_with with a LogicFactory".into(), + ); + } + let root = sdk_root.canonicalize().map_err(|e| format!("gen: SDK root: {e}"))?; + for name in ["msdk", "msdk-gtk"] { + if !root.join(name).join("Cargo.toml").is_file() { + return Err(format!("gen: SDK root must contain {name}/Cargo.toml")); + } + } + let surfaces = doc["surfaces"].as_object().ok_or("gen: missing surfaces")?; + let surface = + if surfaces.contains_key("main") { "main" } else { surfaces.keys().next().ok_or("gen: no surface")? }; + let id = doc["app"]["id"].as_str().ok_or("gen: missing app id")?; + let package = format!("msdk-{}", id.rsplit('.').next().unwrap_or("app").replace('_', "-").to_ascii_lowercase()); + let root_text = root.to_str().ok_or("gen: SDK root must be UTF-8")?; + let mut files = BTreeMap::new(); + files.insert("assets/icon.svg".into(), crate::package::DEFAULT_ICON.into()); + files.insert("LICENSE".into(), include_str!("../LICENSE").into()); + files.insert("Cargo.toml".into(), format!( + "[package]\nname = {package:?}\nversion = \"0.1.0\"\nlicense = \"GPL-3.0-only\"\nedition = \"2024\"\npublish = false\n\n[workspace]\n\n[lib]\nname = \"app_model\"\n\n[dependencies]\nmsdk = {{ path = {} }}\nmsdk-gtk = {{ path = {} }}\ngtk = {{ package = \"gtk4\", version = \"0.11\", features = [\"v4_20\"] }}\nserde = {{ version = \"1\", features = [\"derive\"] }}\nserde_json = \"1\"\n", + serde_json::to_string(&format!("{root_text}/msdk")).unwrap(), + serde_json::to_string(&format!("{root_text}/msdk-gtk")).unwrap(), + )); + files.insert("app.ui.json".into(), serde_json::to_string_pretty(doc).map_err(|e| e.to_string())? + "\n"); + let mut model = models(doc)?; + let mut registration = String::new(); + for (index, manifest) in manifests.iter().enumerate() { + let manifest = serde_json::to_string(manifest).map_err(|e| e.to_string())?; + files.insert(format!("app-{index}.services.json"), manifest.clone()); + registration.push_str(&format!(" msdk::vocab::load_manifest(&serde_json::from_str({}).expect(\"embedded service manifest\")).expect(\"checked service manifest\");\n", literal(&manifest))); + } + model = model.replace( + "pub fn document() -> serde_json::Value {\n", + &format!("pub fn document() -> serde_json::Value {{\n static REGISTER: std::sync::OnceLock<()> = std::sync::OnceLock::new();\n REGISTER.get_or_init(|| {{\n{registration} }});\n"), + ); + files.insert("src/lib.rs".into(), model); + files.insert( + "src/main.rs".into(), + include_str!("../templates/project/main.rs") + .replace("@APP_ID@", &literal(id)) + .replace("@SURFACE@", &literal(surface)), + ); + files.insert("README.md".into(), format!( + "# {}\n\nGenerated by `msdk gen`; SDK format {}.\n\nOn a supported Linux GTK 4.20+ development host, with Rust 2024, pkg-config,\nGTK development headers, Wayland development headers and wayland-scanner installed:\n\n```sh\ncargo build\ncargo test\ncargo run\n```\n\n`src/lib.rs` exposes typed records, `State`, `Message::into_event` and the embedded\ndescription. Edit `app.ui.json` for views/rules, or use a new output directory to\nregenerate models after changing types. Keep the SDK checkout at `{root_text}`;\nthe generated project uses explicit local dependencies and its own Cargo workspace.\n\nThe executable runs the real GTK Host with the description's update rules and\nbuilt-in services. Custom services/feeds require an app-local `Services` adapter\nand `Host::open_with`; generation does not implement those backends. Panel\nplacement requires the documented Pantheon shell protocol and target-host tests.\nBuild/launch success is separate from visual, accessibility, service, packaging\nand installed desktop acceptance. No install or background service is performed\nby generation.\n", + doc["app"]["name"].as_str().unwrap_or("SDK app"), crate::FORMAT_VERSION, + )); + files.insert("tests/model.rs".into(), "#[test]\nfn initial_state_round_trips() {\n let state = app_model::State::initial().expect(\"typed initial state\");\n let store = state.clone().into_store().unwrap();\n assert_eq!(app_model::State::from_store(store).unwrap(), state);\n}\n".into()); + Ok(files) +} + +/// Creates a new directory exclusively; existing projects are never overwritten. +pub fn write_project(dir: &Path, files: &BTreeMap) -> Result<(), String> { + std::fs::create_dir(dir).map_err(|e| format!("gen: {}: {e}", dir.display()))?; + for (name, body) in files { + let path = dir.join(name); + if let Some(parent) = path.parent() { + std::fs::create_dir_all(parent).map_err(|e| e.to_string())?; + } + std::fs::write(path, body).map_err(|e| e.to_string())?; + } + Ok(()) +} diff --git a/rust/msdk/src/intents.rs b/rust/msdk/src/intents.rs index eddf86ca1..5b0ccb616 100644 --- a/rust/msdk/src/intents.rs +++ b/rust/msdk/src/intents.rs @@ -110,7 +110,7 @@ pub fn diagnose(root: &Map) -> Vec { None, ); } - if !desc.as_str().is_some_and(|d| !d.trim().is_empty()) { + if desc.as_str().is_none_or(|d| d.trim().is_empty()) { err( &path, "agent-scope-needs-description", @@ -230,7 +230,7 @@ pub fn diagnose(root: &Map) -> Vec { Some("add `confirm`".into()), ); } - if rank(r) >= 1 && !i.get("verify").and_then(Value::as_str).is_some_and(|v| !v.trim().is_empty()) { + if rank(r) >= 1 && i.get("verify").and_then(Value::as_str).is_none_or(|v| v.trim().is_empty()) { err( &path, "agent-needs-verify", @@ -277,7 +277,7 @@ pub fn diagnose(root: &Map) -> Vec { fix: Some("add `show draft` (the state keys that make up the action)".into()), }); } - if !i.get("about").and_then(Value::as_str).is_some_and(|a| !a.trim().is_empty()) { + if i.get("about").and_then(Value::as_str).is_none_or(|a| a.trim().is_empty()) { err( &path, "agent-needs-about", diff --git a/rust/msdk/src/lib.rs b/rust/msdk/src/lib.rs index 536b3fb7d..19e8bbaf6 100644 --- a/rust/msdk/src/lib.rs +++ b/rust/msdk/src/lib.rs @@ -8,15 +8,21 @@ pub mod agent; mod check; +pub mod context; pub mod contrast; pub mod gate; +pub mod generate; pub mod inspect; pub mod intents; pub mod logic; +pub mod package; +pub mod process; +pub mod runtime; pub mod schema; pub mod templates; pub mod text; pub mod tokens; +pub mod usage; pub mod vocab; pub use check::{Diagnostic, Severity, check}; diff --git a/rust/msdk/src/main.rs b/rust/msdk/src/main.rs index 7fe06ee39..9b5b305e9 100644 --- a/rust/msdk/src/main.rs +++ b/rust/msdk/src/main.rs @@ -36,7 +36,10 @@ fn main() -> ExitCode { } }, Some("complete") if args.len() > 2 => { - load_services(Some(&args[1]), &args); + if let Err(error) = load_services(Some(&args[1]), &args) { + eprintln!("{error}"); + return ExitCode::FAILURE; + } let doc = match load(&args[1]) { Ok((d, _)) => d, Err(e) => { @@ -80,9 +83,11 @@ fn main() -> ExitCode { ExitCode::SUCCESS } Some("new") if args.len() > 2 => run_new(&args[1..]), + Some("gen") if args.len() > 2 => run_gen(&args[1..]), + Some("pack") if args.len() > 1 => run_pack(&args[1..]), _ => { eprintln!( - "usage: msdk check [--json] ...\n msdk describe [Name] | explain | complete \n msdk gate [gates.json]\n msdk agent-manifest [--mcp] [--services f.json]\n msdk render [--surface NAME] [--state JSON] [--json]\n msdk fmt [--check|--stdout] ... | text | json \n msdk templates | new