Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
dc3117d
Promote nodes accepted by merged #45 to review: reviewed
claude Oct 29, 2026
5382f9d
Advance watermark to 44bfeab; bump reviewed_at on signature-only prev…
claude Oct 29, 2026
dd7b7db
Sync app area for lgse/strata#1934, #1909, #1918, #1837
claude Oct 29, 2026
4a02c6b
Sync integration and operations areas for lgse/strata#1909, #1837
claude Oct 29, 2026
15f6a78
Sync settings and remote areas for lgse/strata#1918, #1934, #1909, #1837
claude Oct 29, 2026
7c24678
Sync browser area for lgse/strata#1837, #1909; add administrator-acce…
claude Oct 29, 2026
b511f29
Apply round-1 review fixes in app and devices
claude Oct 29, 2026
187945e
Apply round-1 review fixes in settings and remote
claude Oct 29, 2026
7de27ac
Apply round-1 review fixes in browser, integration, and operations; r…
claude Oct 29, 2026
796514e
Apply round-2 review fixes in integration, operations, app, and devices
claude Oct 29, 2026
488b8f0
Apply round-2 review fixes in app dialogs, updates, and sweep
claude Oct 29, 2026
182dff4
Apply round-2 review fixes in browser
claude Oct 29, 2026
02df0f6
Apply round-2 review fixes in settings and remote; regenerate indexes
claude Oct 29, 2026
ba8a84c
Apply round-3 review fixes in app
claude Oct 29, 2026
e71559d
Apply round-3 review fixes in integration and operations
claude Oct 29, 2026
6c3c777
Apply round-3 review fixes in browser; move folder-peek admin bullet …
claude Oct 29, 2026
dd64a41
Apply round-3 review fixes in settings and remote; regenerate indexes
claude Oct 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 138 additions & 137 deletions README.md

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion features/app/accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Accessibility
status: shipped
origin: {issue: lgse/strata#341, pr: lgse/strata#415}
branch: null
reviewed_at: 73b3258ff9da7fd5f8b279e442e4fbf576850deb
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: draft
code: [src/ui/accessibility.rs]
tests: [src/ui/accessibility/tests.rs, tests/qa/scenarios/accessibility, tests/qa/scenarios/dialogs_and_menus/entry-menu-named-actions.jsonl]
Expand All @@ -21,6 +21,8 @@ App-wide accessible semantics for screen readers and AT-SPI automation. It cover

- In every view, each entry is named with its display name and described as "Folder" or "File". lgse/strata#415
- A symbolic link is described as "Folder link" or "File link", a dangling link as "Broken link", and any other file type as "Other". lgse/strata#415 (unverified)
- Once metadata loads, a local folder the user can't read or enter is described as "Folder that requires administrator access". lgse/strata#1837
- A link to such a folder is described as "Folder link that requires administrator access". lgse/strata#1837 (unverified)
- Each pane is a group named after its directory and described as "Columns view", "Icons view", or "List view". lgse/strata#415
- The entry list inside a pane is named after its directory and described as "Files". lgse/strata#415
- In an empty, unreadable, or still-loading directory, the focusable pane is named after the directory. lgse/strata#1533
Expand Down
3 changes: 2 additions & 1 deletion features/app/dialogs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Modal dialogs
status: shipped
origin: {issue: lgse/strata#88, pr: lgse/strata#91}
branch: null
reviewed_at: 73b3258ff9da7fd5f8b279e442e4fbf576850deb
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: draft
code: [src/ui/modal.rs, src/ui/modal/layout.rs, src/ui/controls.rs, src/ui/blur.rs]
tests: [src/ui/modal/tests.rs, src/ui/controls/tests.rs, src/ui/window/tests/keyboard_dispatch/overlay_focus.rs, tests/qa/scenarios/dialogs_and_menus/dismissed-overlays-return-focus.jsonl]
Expand Down Expand Up @@ -33,6 +33,7 @@ The shared shell behind Strata's action dialogs: the blurred backdrop, open and
- Confirmation dialogs open with the confirm button focused, so Enter confirms and Escape cancels: Permanently delete, Empty Trash, Restore, paste and archive Replace, Run, and Forget saved password. lgse/strata#1206
- With focus outside a text field, Enter activates the focused button and toggles a focused checkbox or switch, so Enter with Cancel focused cancels. lgse/strata#1052, lgse/strata#175 (unverified)
- With focus outside a text field, an unmodified arrow key moves focus to the nearest button, menu button, checkbox, switch, or entry in that direction; Down on a menu button opens its menu. lgse/strata#175 (unverified)
- An error dialog that offers Open as Administrator opens with that button focused, and its cancel button reads Close. lgse/strata#1837 (unverified)
- While a dialog is open, focus that moves outside it is returned to the dialog's layer, not to a button inside it. lgse/strata#1432

### Focus after closing
Expand Down
4 changes: 2 additions & 2 deletions features/app/infrastructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ title: Shared location model and listing adapter
status: shipped
origin: {issue: lgse/strata#14, pr: lgse/strata#27}
branch: null
reviewed_at: 73b3258ff9da7fd5f8b279e442e4fbf576850deb
review: draft
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: reviewed
code: [src/model/mod.rs, src/ui/settings.rs, src/adapters/local_files.rs, src/ui/mod.rs, src/main.rs, src/app/mod.rs, src/adapters/mod.rs, src/services/mod.rs, src/ui/resize_feedback.rs, src/ui/preferences/trashed.rs, src/adapters/volume/mounts.rs, src/adapters/volume/mount_snapshot.rs, README.md, THIRD_PARTY_LICENSES.md, data/licenses, data/strata.gresource.xml, AGENTS.md, typos.toml, clippy.toml, Cargo.toml, Cargo.lock, mise.toml, mise.lock, scripts/benchmark-scroll.py, src/build_info.rs, src/services/native_fs.rs, src/ui/keys/bindings.rs, src/ui/keys/bindings/**, build.rs, deny.toml, scripts/quality.sh, scripts/quality_ci.py, scripts/test-headless.py, scripts/integration_tests.py, src/ui/settings/install_command.rs, src/adapters/local_operations/fs_ops.rs, src/adapters/local_operations/native_fs.rs, src/adapters/local_operations/work_queue.rs, src/trusted_command.rs, src/adapters/gio_close.rs, src/adapters/volume/mount_watch.rs, src/adapters/volume/mount_lanes.rs, src/adapters/local_operations/probes.rs, src/util/ui_thread.rs, src/util/ui_thread/**, scripts/trace-main-io.py, tests/qa/main-io-allowlist.toml, .agents/skills, .claude/skills, .gitignore, .cursor/CLOUD.md, .dockerignore, CONTRIBUTING.md, scripts/check.sh, src/qa.rs, src/qa/**, src/ui/accessibility/qa.rs, scripts/qa*.sh, scripts/qa_*.py, scripts/lib/qa-container.sh, scripts/headless/**, scripts/image_*.py, tests/container/**, tests/fixtures/harness.json, src/logging.rs, src/metrics.rs, src/services/listeners.rs, src/services/network_error.rs, src/ui/close_guard.rs, src/ui/browser/paths.rs, src/ui/browser/entry_animation.rs, data/icons/scalable/actions/**, .github, .gitattributes, CLAUDE.md, LICENSE, rustfmt.toml, skills-lock.json, docs/assets, docs/evidence, scripts/discord_triage.py, scripts/profile-fixture.sh, scripts/generate-fixture.sh, scripts/quality-durations.json, scripts/release_version.py, scripts/start-dev.sh, src/services/package_manager.rs, src/ui/browser/location.rs]
tests: [src/model/tests.rs, src/adapters/local_files/tests.rs, src/adapters/local_files/tests/browse.rs, src/adapters/volume/mounts/tests.rs, src/test_support.rs, src/test_support/**, scripts/test_benchmark_scroll.py, src/build_info/tests.rs, scripts/test_quality_ci.py, scripts/test_quality_runner.py, scripts/test_headless_runner.py, scripts/test_integration_tests.py, src/ui/settings/install_command/tests.rs, src/trusted_command/tests.rs, src/adapters/gio_close/tests.rs, src/adapters/local_operations/tests/closes.rs, src/adapters/volume/mount_watch/tests.rs, src/adapters/volume/mount_lanes/tests.rs, src/adapters/local_operations/probes/tests.rs, src/adapters/local_operations/fs_ops/tests.rs, src/adapters/volume/mounts/tests/byte_paths.rs, scripts/test_trace_main_io.py, tests/qa.rs, tests/qa/*.rs, tests/qa/foreign_drag_source.py, tests/qa/baselines/**, src/qa/tests.rs, src/qa/tests/**, scripts/test_qa_*.py, scripts/test_image_*.py, tests/qa/scenarios/visual_baselines, src/logging/tests.rs, src/metrics/tests.rs, src/services/listeners/tests.rs, src/services/network_error/tests.rs, scripts/test_discord_triage.py, scripts/test_makefile.py, scripts/test_release_version.py, src/tests.rs, src/ui/preferences/tests/preferences.rs, src/ui/window/tests/preferences.rs, tests/qa/fixtures/file_drag_source.py, src/services/package_manager/tests.rs, src/ui/browser/location/tests.rs]
docs: [docs/performance-baseline.md, docs/hardened-configuration.md, docs/unsafe-code.md, docs/testing.md, docs/packaging.md]
Expand Down
2 changes: 1 addition & 1 deletion features/app/keyboard-shortcuts/remapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Remappable shortcuts per map
status: shipped
origin: {issue: lgse/strata#1884, pr: lgse/strata#1885}
branch: null
reviewed_at: 73b3258ff9da7fd5f8b279e442e4fbf576850deb
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: draft
code: [src/ui/keys/command.rs, src/ui/keys/alias.rs, src/ui/keys/capture.rs, src/ui/keys/conflicts.rs, src/ui/preferences/keymap.rs, src/ui/window/keyboard/direct.rs, src/ui/settings/keyboard.rs]
tests: [src/ui/keys/command/tests.rs, src/ui/keys/alias/tests.rs, src/ui/keys/conflicts/tests.rs, src/ui/preferences/tests/keymap.rs, src/ui/settings/keyboard/tests.rs, src/ui/window/tests/keyboard_dispatch/keymap_overrides.rs, src/ui/window/tests/keyboard_dispatch/keymap_conflicts.rs, src/ui/window/tests/keyboard_dispatch/structural_aliases.rs, src/ui/window/tests/keyboard_dispatch/direct_commands.rs, tests/qa/scenarios/keymap]
Expand Down
4 changes: 2 additions & 2 deletions features/app/packaging/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Packaging and installation
status: shipped
origin: {issue: lgse/strata#49, pr: lgse/strata#182}
branch: null
reviewed_at: 86df474dc0e8352e0e2098637a017cc4c77a8c44
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: draft
code: [data/io.github.lgse.Strata.desktop, data/icons/scalable/apps/io.github.lgse.Strata.svg]
tests: []
Expand All @@ -21,7 +21,7 @@ How Strata reaches a desktop: the desktop entry and application icon that let sh

- `io.github.lgse.Strata.desktop` sets `Icon=io.github.lgse.Strata` and `StartupWMClass=io.github.lgse.Strata`, matching the GTK application ID. lgse/strata#182
- The entry declares `MimeType=inode/directory;` and `Categories=Utility;FileTools;FileManager;`, so it can be the default folder handler. lgse/strata#182
- The entry carries translated `GenericName`, `Comment`, and `Keywords` for fr, de, es, ja, pt_BR, ko, vi, it, ru, zh_CN, and zh_TW. lgse/strata#1519, lgse/strata#1583, lgse/strata#1745 (unverified)
- The entry carries translated `GenericName`, `Comment`, and `Keywords` for fr, hu, de, es, ja, pt_BR, ko, vi, it, ru, zh_CN, and zh_TW. lgse/strata#1519, lgse/strata#1583, lgse/strata#1745, lgse/strata#1918 (unverified)
- The application icon is bundled in the GResource and set as GTK's default window icon name. lgse/strata#182
- The application icon draws the logo in blue and violet gradients on a rounded tile. The tile fades from `#414868` at the top to `#1b1c27` at the bottom. lgse/strata#1838 (unverified)
- Release archives contain `io.github.lgse.Strata.desktop` and `io.github.lgse.Strata.svg` beside the `strata` binary. lgse/strata#182
Expand Down
3 changes: 2 additions & 1 deletion features/app/packaging/installer.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Release installer
status: shipped
origin: {issue: lgse/strata#329, pr: lgse/strata#330}
branch: null
reviewed_at: 86df474dc0e8352e0e2098637a017cc4c77a8c44
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: draft
code: [install.sh, data/locales/installer.json, scripts/installer_messages.py]
tests: [scripts/test_installer.py, scripts/testdata]
Expand Down Expand Up @@ -118,6 +118,7 @@ related: [integration/file-manager-interface, integration/portal-file-chooser/se
- With `LANGUAGE=zz:fr` and `LC_ALL=C.UTF-8`, the plan reads "Installer dans <path>". lgse/strata#1730 (unverified)
- With `LANGUAGE=fr` and `LC_ALL=C`, the plan reads "Install to <path>". lgse/strata#1730 (unverified)
- `zh_TW`, `zh_HK`, `zh_MO`, and `zh-Hant…` show Traditional Chinese messages; every other `zh` locale shows Simplified Chinese. lgse/strata#1745
- A `hu` locale, such as `LANG=hu_HU.UTF-8`, shows Hungarian messages: the banner reads "Interaktív telepítő" and the plan "Telepítés ide: <path>". lgse/strata#1918 (unverified)
- Paths in messages show literally, even when they hold `&` or `%{version}`. lgse/strata#1730 (unverified)
- The installer ignores the language saved in Strata's Settings. lgse/strata#1730

Expand Down
33 changes: 28 additions & 5 deletions features/app/updates/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@ title: Updates
status: shipped
origin: {issue: null, pr: lgse/strata#22}
branch: null
reviewed_at: 86df474dc0e8352e0e2098637a017cc4c77a8c44
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: draft
code: [src/services/update_check.rs]
code: [src/services/update_check.rs, src/ui/settings/update_status.rs]
tests: [src/services/update_check/tests.rs, src/ui/settings/tests/updates.rs]
docs: [docs/preferences.md]
docs: [docs/preferences.md, docs/packaging.md]
related: [browser/sidebar]
---

## Summary

Checking GitHub for a newer Strata release, the Settings → Updates page, release notes, and the sidebar update notice. Children: `app/updates/release-channels` (Stable, Preview, Nightly, and Return to stable), `app/updates/install` (signed in-place install, rollback, and restart), `app/updates/release-picker` (installing a chosen release), and `app/updates/package-managed` (AUR, Omarchy, and pacman installs).
Checking GitHub for a newer Strata release, the Settings → Updates page, release notes, and the sidebar update notice. A build made with `STRATA_UPDATER=disabled` leaves the updater out. Children: `app/updates/release-channels` (Stable, Preview, Nightly, and Return to stable), `app/updates/install` (signed in-place install, rollback, and restart), `app/updates/release-picker` (installing a chosen release), and `app/updates/package-managed` (AUR, Omarchy, and pacman installs).

## Behavior

### Builds without the updater

- A build made with `STRATA_UPDATER=disabled` has no Updates entry in the Settings navigation and no Updates page. lgse/strata#1934
- Such a build never starts an automatic check, so the sidebar update notice never appears. lgse/strata#1934
- A build with `STRATA_UPDATER` unset or `enabled` keeps the Updates page and update checks. lgse/strata#1934
- `STRATA_UPDATER` is trimmed before it is read, and an empty value also keeps the updater. lgse/strata#1934 (unverified)
- A build with any other value, such as `disable`, fails with `STRATA_UPDATER must be "enabled" or "disabled"`. lgse/strata#1934

### Checking

- With "Check for updates automatically" on, a window's first themed frame starts a check unless one completed in this process within 24 hours. lgse/strata#944, lgse/strata#326
Expand All @@ -40,6 +48,14 @@ Checking GitHub for a newer Strata release, the Settings → Updates page, relea
- Before a check, the status row reads "Version X", adding the build kind, such as "Release candidate", for a prerelease build. lgse/strata#97
- After a check, the row title reads "Strata is up to date", "An update is available", or "Couldn’t check for updates". lgse/strata#51 (unverified)
- A failed check shows its reason and a "View releases on GitHub" link. lgse/strata#22 (unverified)
- A check whose worker ends without a result fails with the reason "An unexpected system error occurred". lgse/strata#1909 (unverified)
- Settings → Updates opened after the startup check completed shows that check's result, without Check now or another request. lgse/strata#1909
- When a startup or manual check completes, every open Settings → Updates row shows its result. lgse/strata#1909
- Check now in one Settings window leaves other windows' rows, including an offer's Install button, unchanged until its result lands. lgse/strata#1909
- On a pacman or Omarchy install with a Preview or Nightly preference, a startup offer shows on the Updates row. lgse/strata#1909
- That offer carries its package-managed action, such as "Check again" on pacman. lgse/strata#1909 (unverified)
- Turning automatic checks on or off, or changing the channel, resets every open row to "Check for updates" and Check now. lgse/strata#1909
- That reset skips a row mid-check or with an install underway. lgse/strata#1909
- An available update shows its notes inline, titled "Available release · vX" with its change count and publication date. lgse/strata#51
- Turning automatic checks off clears the sidebar notice in every window; turning them on runs a check. lgse/strata#944, lgse/strata#1554
- The Release channel menu is insensitive while automatic checks are off. lgse/strata#97 (unverified)
Expand Down Expand Up @@ -76,18 +92,24 @@ Update checks use GitHub's unauthenticated REST API, limited to 60 requests per
- Strata caches instead of changing the source. A published `latest.json` was heavier, `releases.atom` carries HTML notes, and shipping an API token was rejected (lgse/strata#181).
- GitHub answers unauthenticated conditional requests with `200`, so the 6-hour floor and the per-tag notes cache do the actual saving (lgse/strata#197).
- The first automatic check of each session bypasses the cache so a fresh launch never shows stale release information. Disabling the cache for every check was rejected as wasteful (lgse/strata#325).
- Results are broadcast to every window, and the last offer is cached for windows opened later (lgse/strata#866).
- Results are broadcast to every window, and a window opened later gets the last offer as its sidebar notice (lgse/strata#866, lgse/strata#1909).
- The last completed result, whether an offer, up to date, or a failure, is one shared snapshot. Every Settings → Updates row renders it, including rows opened later (lgse/strata#1909).
- Check now clears only the shared snapshot and the sidebar notice. Clearing every row dropped another window's offer and Install button until the result arrived (lgse/strata#1909).
- Each check carries a generation number. A result superseded by a newer check is dropped, so a Preview result cannot land after a switch to Stable (lgse/strata#97).
- Checks and package-manager detection run off the GTK thread, after the first frame rather than on a fixed 8-second delay (lgse/strata#944).
- A release-notes failure never blocks an eligible update; the GitHub release page stays available as a fallback (lgse/strata#48).
- The release list hides unsigned releases, because they would fail install verification (lgse/strata#1779, lgse/strata#1781).
- One 100-release page let older signed stable releases fall off, since nightlies are never pruned. Paging stops where signed history ends, and 5 requests stay inside the unauthenticated rate limit (lgse/strata#1781).
- Distributions whose packages deliver updates build with `STRATA_UPDATER=disabled`. Reusing the AUR `install-source.toml` marker was rejected, because its update check and wording are AUR-specific (lgse/strata#1933).
- The switch accepts only `enabled` and `disabled`, so a typo fails the build instead of shipping an updater (lgse/strata#1934).
- HTML comments are stripped only in the client, and only from release notes. Published releases already carry the comment, and `--generate-notes` adds it to every body. Markdown file previews still show comments (lgse/strata#1464, lgse/strata#1570).

## History

| Date | PR | Type | Change |
| --- | --- | --- | --- |
| 2026-10-29 | lgse/strata#1909 | fix | Shared one completed update-check result with every Settings → Updates row, so a page opened after the startup check shows it. |
| 2026-10-29 | lgse/strata#1934 | feat | Added the `STRATA_UPDATER=disabled` build switch, which leaves the updater out for distributions whose packages deliver updates. |
| 2026-10-20 | lgse/strata#1781 | feat | Added "Install a specific release", listing the channel's signed releases so users can roll back or switch builds. |
| 2026-10-15 | lgse/strata#1609 | fix | Opened Omarchy Update in Omarchy's floating presentation terminal, so its output stays open after the update ends or fails. |
| 2026-09-16 | lgse/strata#1068 | fix | Removed the horizontal inset from the sidebar update notice. |
Expand All @@ -99,4 +121,5 @@ Update checks use GitHub's unauthenticated REST API, limited to 60 requests per

## Known gaps

- A Settings → Updates row with an install underway ignores newer check results. A cancelled or failed install keeps its status until the next check result. lgse/strata#1909
- Releases older than the 500 newest on GitHub are not listed, because the release list is capped at 5 requests of 100. lgse/strata#1781
3 changes: 2 additions & 1 deletion features/app/updates/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: In-place update install
status: shipped
origin: {issue: lgse/strata#24, pr: lgse/strata#26}
branch: null
reviewed_at: 86df474dc0e8352e0e2098637a017cc4c77a8c44
reviewed_at: 44bfeab305cfb68993bafcf4794fe0bbf7ff1433
review: draft
code: [src/services/update_install.rs, src/services/update_install/**, data/update-keys.json, scripts/sign_update_manifest.py]
tests: [src/services/update_install/tests.rs, src/services/update_install/review_tests.rs, src/services/update_install/archive/tests.rs, src/services/update_install/command/tests.rs, src/services/update_install/download/tests.rs, src/services/update_install/manifest/tests.rs, src/ui/settings/tests/update_dialog.rs, scripts/test_sign_update_manifest.py, tests/fixtures/signed-update]
Expand Down Expand Up @@ -90,6 +90,7 @@ Downloading a release, authenticating it against a signed manifest, replacing th
- Every install writes the same executable, so one guard spans all windows. Staging paths are also unique per install against leftovers from a killed process (lgse/strata#97).
- Old instances are found through `/proc` and signalled through a pidfd, so a reused PID is never signalled (lgse/strata#1201).
- The installer accepts a rollback because it compares the requested tag with the signed manifest's tag, not version order (lgse/strata#1781).
- A build made with `STRATA_UPDATER=disabled` has no Updates page, so no control starts an install. The install service still refuses to run there, as `docs/packaging.md` states (lgse/strata#1934).
- Desktop metadata is only refreshed, never created, so an update does not add a launcher the user never installed (lgse/strata#182).

## History
Expand Down
Loading
Loading