* fix: retain prepared checkout cleanup ownership after timeout
* test: retain capacity for unregistered preparation leftovers
* fix: keep expired cleanup admission outside retry budget
* fix: verify original preparation registration before removal
* Retain preparation authority through bounded capacity recovery
* Exercise preparation cleanup failures through real filesystem fixtures
* Inject root mkdir failure without obstructing checkout absence proof
* Match the host filesystem path in preparation failure coverage
* Align preparation fixtures with physical cleanup ownership
* Await owned recovery in the fleet cleanup control
* Release abandoned preparation cleanup maintenance leases
* Match cleanup test identity paths on Windows
* Wait for completed preparation disposal in maintenance regression
* Await final cleanup state in maintenance controls
* chore(lint): bump oxlint to 1.91, add perf lint rules and perf audits
* fix(lint): await promises returned inside try/catch/finally for return-await
Prepare typescript/return-await with error-handling-correctness-only: await
returns whose catch or finally was meant to cover them, and suppress the eight
sites where the catch must not re-handle the returned promise.
* chore(lint): enable return-await (error-handling-correctness-only); exempt secondary-scan directives in the changed gate
* refactor(mobile): move file preview discard modal into its own module
Keeps MobileFilePreviewScreen under the 400-line limit after merging main.
---------
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
* perf(main): overlap independent fs probes on git status, agent detection and orcad startup
* perf: skip per-entry copies in git change list and tab hydration; drop unused activity barrel
* Keep a lifetime owner for claimed worktree preparation
* Record preparation ownership loss before retirement
* Type the preparation lock-write fixture without an assertion
* Revoke preparation cleanup when ownership changes
* fix(git): refuse unsafe branch switches in an existing workspace
The phone's Switch branch ran `git checkout` with no checks: uncommitted
files moved to the other branch, and a switch could land under a working
agent or mid-rebase. One host check now covers every client: it refuses,
with a plain reason, when files are uncommitted, a merge/rebase/
cherry-pick/revert is in progress, HEAD is detached or unborn, another
git action is running, or an agent in the checkout is working or waiting
for approval. Checks and the checkout run under a per-checkout lock.
After a switch the host clears the old branch's review links and push
target and tells every client, so a phone-only host stays correct, and
records that the user chose the branch so first-work naming never
renames it. The open Commits list follows the new branch.
* fix(git): review round 1 repairs for the guarded branch switch
- check out through the provider so the user's switch keeps the interactive git queue
- a landed switch that Windows left files behind on now tells the user instead of reporting success
- never let a Windows yes/no prompt hold the switch lock
- refuse submodule edits that submodule ignore config hides from status
- record the switch on the target host's metadata row and never fail a landed switch on bookkeeping
- read workspace paths from their ids instead of scanning the catalog on every switch
- admit agent rows like the sidebar roster (listed tab, or a live terminal by pane, tab or handle)
- move the host-side switch hooks into their own module
* test: type the new switch test fakes instead of casting them
* fix(git): second repair round for the guarded branch switch
- report files Windows left behind from git's own unlink warnings, not a status re-read, so
ordinary branch differences and submodule commit changes are never called failures
- the phone refreshes its branch and files after a switch that landed with a warning
- refuse only edits inside a submodule its ignore config hides, never a commit mismatch alone,
reading status without optional locks in the interactive queue
- read the agent process probe when a switch runs, not while the runtime is constructed
- check the agent's checkout path before terminal liveness and build the tab list once per switch
- the runtime wiring test no longer reaches real git
* fix(git): scope the switch's agent check to the checkout and keep landed-switch outcomes honest
- find candidate agents by checkout path first; build terminal liveness once, only from this
checkout's terminals and its workspaces' saved tabs; probe candidates together and re-read
the snapshot once; no work for unrelated workspaces (contract test at N and 10N)
- a checkout that fails after HEAD moved is recorded as landed; files left behind are named only
when git reports it could not replace them, otherwise git's own error is shown
- parse git's unlink warnings for paths with apostrophes
- the phone keeps the refusal or warning visible while it reloads the branch
- cover a submodule that is only at another commit
* fix(git): name git's own error when a switch lands after a failing hook; use the shared unlink parser
* fix(git): keep the switch's agent check flat for unrelated folder workspaces
- read folder workspace directories once per switch instead of a linear search per row and terminal
- re-read each candidate's current status by pane key instead of rebuilding the whole snapshot
- skip the hidden-submodule status pass in repos without submodules
- the cost contract covers folder workspaces, many in-checkout agents and PTY passes
- a real-git test covers a switch that lands before a failing post-checkout hook
* fix(git): never quote git's progress line as a landed switch's error; fixed clock in the cost test
* fix(git): decide the hidden-submodule check from the index, not a visible .gitmodules
* perf(git): read only index modes for the submodule shortcut so large repos stay under the output cap