* Retire SSH worktree metadata an authoritative scan proved gone
The metadata fallback's protection against resurrecting externally deleted
worktrees lived only in renderer module state, so it died on every reload
while the SSH WorktreeMeta it guarded against persists forever
(gcStaleWorktreeMeta exempts any repo with a connectionId, because a local
existsSync cannot probe a remote path). Repro: `git worktree remove` on the
SSH host, let the authoritative scan purge the row, restart — the startup
fetch runs before SSH connects and the fallback re-lists the deleted
worktree as a ghost row.
Chose option (a), deleting the stale persisted meta in main, over persisting
the removal memory: the metadata is the thing that outlives the worktree, and
Orca's own removals already delete it (removeWorktreeMetadataAndTransientState),
so external removals now converge on the same end state instead of accumulating
a second, parallel tombstone list that would itself need eviction. The
in-session memory stays for the window before the async delete lands.
New `worktrees:forgetRemovedForExecutionHost` only accepts SSH hosts, requires
an exact repo owner, skips metas owned by another host, and refuses folder
repos — a folder workspace's meta IS the workspace record (gcStaleWorktreeMeta
skips those keys for the same reason) and no remote scan can retire one. The
renderer only calls it from the authoritative-removal path, so a mere
disconnect never deletes anything.
Also:
- hoist resetAuthoritativelyRemovedWorktreeMemoryForTests into a top-level
beforeEach; removeWorktree writes that memory too, so suppression could leak
across describes and silently hide a row.
- cover the requireAuthoritative gate that skips the fallback, which had no test.
- replace the raw NUL byte committed inside the coalesce-key template literal
with a \0 escape; it made the file scan as binary to grep/ripgrep.
* test(worktrees): verify non-authoritative fallback skips removal
The non-authoritative fallback must not trigger worktree cleanup when it observes an absence — only an authoritative scan should. Tighten the expectation to ensure cleanup happens exactly once, when new data arrives after the connection state changes.