diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index dc284473c3a..b61372d6821 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -80,7 +80,6 @@ on: - 'src/main/ai-vault/parsing/session-scanner-jsonl-reader.test.ts' - 'src/main/ai-vault/parsing/session-scanner-jsonl-reader.ts' - 'src/main/ai-vault/parsing/session-scanner-messages.ts' - - 'src/main/ai-vault/parsing/session-scanner-parse-wsl-stall.test.ts' - 'src/main/ai-vault/parsing/session-scanner-text-normalization.ts' - 'src/main/ai-vault/parsing/session-scanner-token-values.ts' - 'src/main/ai-vault/prompts/session-scanner-first-user-prompt-capture.ts' @@ -94,7 +93,6 @@ on: - 'src/main/ai-vault/scope/session-scanner-scope-inventory.ts' - 'src/main/ai-vault/scope/session-scanner-scope-walk.test.ts' - 'src/main/ai-vault/scope/session-scanner-scope-walk.ts' - - 'src/main/ai-vault/scope/session-scanner-scope.test.ts' - 'src/main/ai-vault/session-scanner.ts' - 'src/shared/error-message.ts' - 'src/shared/surrogate-safe-text-slice.ts' @@ -213,7 +211,6 @@ on: - 'src/main/ai-vault/parsing/session-scanner-jsonl-reader.test.ts' - 'src/main/ai-vault/parsing/session-scanner-jsonl-reader.ts' - 'src/main/ai-vault/parsing/session-scanner-messages.ts' - - 'src/main/ai-vault/parsing/session-scanner-parse-wsl-stall.test.ts' - 'src/main/ai-vault/parsing/session-scanner-text-normalization.ts' - 'src/main/ai-vault/parsing/session-scanner-token-values.ts' - 'src/main/ai-vault/prompts/session-scanner-first-user-prompt-capture.ts' @@ -227,7 +224,6 @@ on: - 'src/main/ai-vault/scope/session-scanner-scope-inventory.ts' - 'src/main/ai-vault/scope/session-scanner-scope-walk.test.ts' - 'src/main/ai-vault/scope/session-scanner-scope-walk.ts' - - 'src/main/ai-vault/scope/session-scanner-scope.test.ts' - 'src/main/ai-vault/session-scanner.ts' - 'src/shared/error-message.ts' - 'src/shared/surrogate-safe-text-slice.ts' diff --git a/config/flaky-test-pattern-baseline.txt b/config/flaky-test-pattern-baseline.txt index 0e5b0379dd2..7e08db6906f 100644 --- a/config/flaky-test-pattern-baseline.txt +++ b/config/flaky-test-pattern-baseline.txt @@ -114,7 +114,6 @@ 1 test-no-real-time-wait:src/main/agent-hooks/installation/scripts/posix-hook-json-stdin-reader.test.ts 2 test-no-real-time-wait:src/main/agent-hooks/server/testing/http/server-transport-interference.test.ts 1 test-no-real-time-wait:src/main/agent-hooks/server/testing/main-agent/server-turn-ended-at.test.ts -1 test-no-real-time-wait:src/main/agent-hooks/server/testing/main-agent/server-turn-started-at.test.ts 1 test-no-real-time-wait:src/main/ai-vault/scanners/opencode/reader-transport/session-scanner-opencode-sqlite-process.test.ts 1 test-no-real-time-wait:src/main/antigravity/windows-hook-json-post.test.ts 1 test-no-real-time-wait:src/main/antigravity/windows-hook-payload-delivery.test.ts @@ -184,7 +183,6 @@ 3 test-no-real-time-wait:src/renderer/src/components/activity/activity-auto-mark-read-loop.react185.test.tsx 1 test-no-real-time-wait:src/renderer/src/components/terminal-pane/layout/split/resolve-split-cwd.test.ts 2 test-no-real-time-wait:src/renderer/src/components/terminal-pane/pty-connection/emulation/fish-color-scheme-child-stdin.node-pty.test.ts -1 test-no-real-time-wait:src/renderer/src/components/terminal-pane/viewport/terminal-fit-restore.test.ts 1 test-no-real-time-wait:src/renderer/src/hooks/runtime-project-refresh-scheduler.test.ts 2 test-no-real-time-wait:src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-removal-preflight.test.ts 2 test-no-real-time-wait:src/shared/__tests__/process-host/windows-tree-kill-late-taskkill.win32.test.ts @@ -357,7 +355,6 @@ 2 test-no-wall-clock:src/main/agent-hooks/installation/commands/windows-native-hook-exe-hosts.test.ts 2 test-no-wall-clock:src/main/agent-hooks/installation/scripts/managed-hook-timeout.test.ts 1 test-no-wall-clock:src/main/agent-hooks/server/testing/http/server-endpoint-file-lifecycle.test.ts -4 test-no-wall-clock:src/main/agent-hooks/server/testing/identity/server-launch-resume-identity.test.ts 3 test-no-wall-clock:src/main/agent-hooks/server/testing/replay/spool.test.ts 3 test-no-wall-clock:src/main/agent-hooks/server/testing/structured-ingress/server-ingest-structured-status.test.ts 1 test-no-wall-clock:src/main/ai-vault/parse-cache/session-parse-cache-preview-upgrade.test.ts @@ -383,15 +380,11 @@ 1 test-no-wall-clock:src/main/daemon/transport/framing/testing/daemon-stream-binary-negotiation.test.ts 2 test-no-wall-clock:src/main/external-conversations/external-conversation-cancel-settlement.test.ts 3 test-no-wall-clock:src/main/external-conversations/external-conversation-cancel.test.ts -2 test-no-wall-clock:src/main/git/command-runner/host-routing/git-command-resolution-windows-checkout.test.ts 1 test-no-wall-clock:src/main/git/refs/maintenance/pack-refs-lock-ownership.test.ts 2 test-no-wall-clock:src/main/git/refs/maintenance/repo-ref-maintenance-real-git.test.ts 1 test-no-wall-clock:src/main/git/source-control/diffs/blob-absence-real-git.test.ts 2 test-no-wall-clock:src/main/git/worktrees/catalog/worktree-created-description-real-git.test.ts -3 test-no-wall-clock:src/main/github/pull-requests/refresh/pr-refresh-coordinator-active-visible-priority.test.ts 8 test-no-wall-clock:src/main/github/pull-requests/refresh/pr-refresh-coordinator-alias-coalescing.test.ts -3 test-no-wall-clock:src/main/github/pull-requests/refresh/pr-refresh-coordinator-completion-order.test.ts -2 test-no-wall-clock:src/main/github/pull-requests/refresh/pr-refresh-queue-growth-bound.test.ts 2 test-no-wall-clock:src/main/grok/grok-hook-stdin-no-eof.test.ts 1 test-no-wall-clock:src/main/ipc/terminal-render-desync-evidence.test.ts 2 test-no-wall-clock:src/main/ipc/worktrees-orphan-directory-cleanup.test.ts @@ -472,7 +465,6 @@ 2 test-no-wall-clock:src/main/wsl/execution/wsl-runner.wsl.test.ts 3 test-no-wall-clock:src/main/wsl/orcad/wsl-orcad-real-distro-lane.test.ts 1 test-no-wall-clock:src/renderer/src/components/activity/activity-auto-mark-read-loop.react185.test.tsx -2 test-no-wall-clock:src/renderer/src/components/artifacts/ArtifactCollection.test.tsx 1 test-no-wall-clock:src/renderer/src/components/browser-pane/assemble-chrome/browser-workspace-pane.adoption-chrome.test.tsx 1 test-no-wall-clock:src/renderer/src/components/sidebar/workspace-card/review/use-workspace-reference-details.test.tsx 1 test-no-wall-clock:src/renderer/src/components/sidebar/worktree-list/listing/WorktreeList.lineage-agent-expansion-coupling.test.tsx diff --git a/config/mobile-ci.vitest.config.mjs b/config/mobile-ci.vitest.config.mjs index 4ffea10cb0a..0835fe96fe5 100644 --- a/config/mobile-ci.vitest.config.mjs +++ b/config/mobile-ci.vitest.config.mjs @@ -5,7 +5,6 @@ import original from '../mobile/vitest.config.ts' const nodeFiles = [ 'scripts/check-tests-typecheck-incremental-cache.test.ts', 'src/mock-server-key-pair.test.ts', - 'src/mobile-release/prepare-android-release-script.test.ts', 'src/navigation/query-string-named-exports.test.ts', 'src/terminal/document/native-document-bundle.test.ts', 'src/transport/encryption/mobile-e2ee-v2-client-session.test.ts', diff --git a/config/reliability-gates.jsonc b/config/reliability-gates.jsonc index 02add88aab4..d885321aec3 100644 --- a/config/reliability-gates.jsonc +++ b/config/reliability-gates.jsonc @@ -2260,27 +2260,25 @@ "providers": ["local", "ssh", "remote-runtime"], "coveredPlatforms": ["macos"], "coveredProviders": [], - "coverageNotes": "Audit5718 companion to audit5715 retires the whole worktree-checks-review-index.test.ts suite. Its remaining same-ID local/SSH Worktree-object review-index isolation alarm is intentionally lost without equivalent replacement. Remove its standalone selector, narrow two compound selectors, and remove its testFiles/assertionRefs entries. Two complete dated failed receipts selecting this suite through command/currentCommand are retired unchanged into knownGaps; they do not validate any remaining selector. All unrelated selectors, assertions and receipts retain only their original scope. No fresh execution, current import reachability, provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit5658 integrates source audit5652: retire the whole web-session-tabs-sync-mirror-identity.test.ts suite and its exact active selectors. Intentionally lose same-id host mirror snapshot and removal isolation alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3663 renews approved3644/3645/3648/amended3651 at privatec1ef: remove10authored/26finite across7changedtestpaths,4whole drivers; retain23authored/24finite including actualcmdkStrictMode defaultcursor race. Retire version1.5.0/1.5.1→shrinksImages capability threshold and launch-to-prompt wiring alarm. Surviving prompt tests explicitly supply capability and do not replace wiring coverage. Retire resolved-before-personOnly precedence; hook-gone/live-dialog guidance; stale-incarnation versus live-looking dialog classification; delayed/clipped warning extraction and wait-for-paint wiring; 3row setting/personOnly approve/deny/disclaimer suggestion composition;13row setting/reason/person/coordinator admission, close/mail attribution, terminal delivery/refusal/preanswered/personOnly/dropped-allow handler propagation alarms. Real state/access/SQLite effects occur; these genuine losses are accepted, not mocked-away. Retire full command extraction from serialized JSON in worker receipt and nontruncation alarm; no rendering, actual worker approval or native shell proof. Retire2row extra-source first/last order and controlled default cursor projection, plus generic open-palette livefolder add/remove render alarm. Explicitly supersede rawexact297KEEP refresh. Keep actualcmdk/StrictMode default cursor race driver; no default-suite loss claim. No equivalent replacement asserted. Retained queue/commit/retryownership/filebudget, terminalfreshness/provenance/competing-answer, RPC DB-effect, qualifiedfolder/runtimehandoff and lingering-reopen cases have distinct scope. Audit3675 preserves the upstream revised unreported-approval close regression, its escalation helper and adapted survivors. Source-only static renewal; no runner/compiler/app/native/remote/CI claim. Upstream41390host-owned approvalwatch/report lifetime reviewed separately; no new lifetime test removed. Preserve all earlier metadata/evidence. Audit3381 intentionally removes the entire Cmd-J host-qualified candidate-ownership suite and its active selectors/assertion. The hidden same-id sibling ambiguity regression alarm is lost without replacement. The complete original dated failed receipt below is retired verbatim, including both command and currentCommand, rather than reassigned as validation of remaining selectors. Other complete receipts retain their exact original scopes; remaining browser/simulator/workspace/e2e selectors do not imply equivalent ownership protection. No fresh execution is claimed. Audit3359 retires the whole ensure-simulator-tab-behavior suite: host-collision reuse, host stamping, inactive creation and unknown-owner routing alarms are intentionally lost without equivalent replacement. Its standalone command is removed and four compound commands narrowed. Three complete dated receipts selecting that source through currentCommand are retired verbatim, including their compound historical selectors; no retained test inherits their validation. Seven unrelated macOS receipts retain their original scope. No fresh runtime/UI, simulator, provider, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit 3301 removes the orphaned mobile file-close fallback and ordinary cross-content MRU examples from tabs-open-close-lifecycle.test.ts. Earlier descriptions of retained MRU coverage are historical. Audit5612 retires the remaining integrated mobile markdown close/frame-settlement suite, accepting loss of its closed-editor snapshot republishing alarm without replacement or fresh validation. Preserve the existing administrative failed receipt and all complete retired receipts verbatim, along with selectors and unrelated assertions; no equivalent replacement or fresh Cmd-J, native or remote result is claimed. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit2729 reduces browser-page-palette-activation.test.ts: separate SSH/paired-runtime alias forwarding, distinct multigroup views accepted, and remote-folder activation forwarding alarms are removed. Collision refusal, preactivation address-bar focus capture, owning-group activation state and missing-tab refusal remain byte-identical. No equivalent replacement, fresh gate execution or actual host/browser delivery evidence is claimed. Prior coverage account: Audit2697 browser source review (metadata followup2702): Reduce src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts by four authored/expanded cases without replacement. The remaining three cases preserve only their existing same-ID execution-host separation, absent stamped-owner refusal and ambiguous legacy-bucket refusal scope. Intentionally lose duplicate backing-tab-ID suppression, multiple unified-browser claims of one workspace, foreign-worktree unified-tab rejection, and the 1000-workspace output/internal getter-read budget alarm. These are real removed alarms; the retained host cases are not equivalent replacements. Current test-value policy rejects internal getter/read budgets; no replacement performance or measured-cost claim is made. Keep existing nonempty selectors and the retained same-ID browser assertionRef. No fresh gate execution or reduced-source validation is supplied; dated receipts, results, commands and historical coverage accounts remain within their original source scope. No live browser activation, physical provider, mixed-version execution, mobile, native UI, platform hardware, soak or timing result is added. Prior coverage account (preserved verbatim): Audit2266 reduces cmd-j-host-qualified-candidate-ownership.test.ts to the scoped open-tab hidden same-ID legacy ambiguity refusal. Separate browser/simulator paired-runtime alias and current-row projections, generic workspace host projection and hostless explicit-owner refusal examples are removed without equivalent replacement. No fresh gate execution, browser activation, physical host, simulator or remote delivery evidence is claimed. Historical dated receipts and budgets remain raw-byte exact. Prior coverage account: Audit1899 replays sealed Audit1895: workspace-session-schema.test.ts keeps only cross-workspace truncated-tab salvage and legacy browser-history cap normalization. Four current commands and testFiles retain that reduced source; no current assertionRef or active receipt selects it. SSH file-owner, isolated browser partition, launch/title/quick-command fields, recency, structured-chat/view-mode and remote browser identity hydration alarms are intentionally lost. Existing retired receipt strings and unrelated active receipts remain verbatim. No equivalent replacement, new Cmd-J gate execution, native simulator or remote/browser restore proof is claimed. Historical coverage account before Audit1899: Audit1494 removes use-open-tab-search.test.ts. Supplied host/worktree/title/ranking projections, simple subscription updates and result-array identity alarms are retired. No actual activation or navigation occurred in that suite. No equivalent replacement coverage or fresh Cmd-J gate validation is claimed. Historical receipts remain scoped to their original selectors. Audit1433 narrows worktree-checks-review-index.test.ts to same-ID local/SSH object-key review isolation. Local provider/cache lookup, GitLab preference, suppression/legacy fallback, explicit-PR authority, physical-versus-runtime review isolation, and branchless-workspace alarms are intentionally removed. No equivalent replacement coverage is claimed. Historical receipts and commands remain unchanged and do not certify the reduced source. Historical coverage account: Audit1396 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1308 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Deterministic candidate-builder contracts inject local and paired-runtime worktrees with the same bare id into the real aggregated tab buckets, including folder workspaces and a paired runtime transporting an SSH-owned worktree. A mirror contract preserves distinct same-id runtime tabs. A paired Electron journey verifies both visible browser rows and both visible simulator rows, then requires each selection to render its owning active tab and update backing host-qualified state. The test-value audit narrowed simulator-palette-search.test.ts to the recency tie, same-id host isolation, ambiguous legacy host rejection and oversized-input getter tripwire. Supplied timestamp, empty-query context ordering, host projection, alias/range, metadata matching, active-tab score, over-token/whitespace and malformed display-name fallback examples were removed. Their separate alarms are lost; retained candidate and activation contracts do not establish equivalent coverage. Historical run commands and results remain historical. The audit also removed the standalone workspace-tab-palette-search suite: supplied row, title, metadata, alias, range, ranking and ownership examples no longer provide their separate alarms. Other retained contracts are not replacement coverage. The mirror-identity fixture now retains same-id sibling-runtime isolation and the repeated-frame subscriber tripwire only. Supplied field, owner, alias and mapping examples are removed; their separate alarms are lost. The retained sibling-runtime case is not equivalent coverage for them. The test-value audit removed tabs-open-close-lifecycle host-stamping examples and ordinary tab/group operations from tabs-pane-layout-operations. Local-null, explicit-runtime and SSH-without-active-host stamp assertions are lost; retained mobile/MRU and subscriber/atomic split cases do not replace them. Candidate and live Cmd-J evidence retains its own scope. Historical commands, outcomes and narratives remain historical. Audit1308: src/renderer/src/lib/browser-palette-search.test.ts removed. Browser-palette token and pasted-query size-guard work alarms disappear. No equivalent replacement coverage is claimed. Audit1386: src/renderer/src/lib/open-mobile-emulator-tab.test.ts reduced. Duplicate attach count and null-tab creation retry/guard reset standalone alarms removed; no simulator device used. No equivalent replacement coverage is claimed. Existing exact unaffected receipts and their platform/provider/budget claims remain scoped to unchanged selectors. Changed optional selectors have no new execution result. Audit1396: src/renderer/src/lib/simulator-palette-search.test.ts reduced. Lose simulator-specific lastFocusedAt tie-order alarm; identity/routing and pre-scan size fence remain. No native simulator or real remote launch claim. No equivalent replacement coverage is claimed. Audit1402: src/renderer/src/runtime/web-session-tabs-sync-mirror-identity.test.ts reduced. Loses repeated no-op frame store-notification budget; independent cross-runtime resource preservation remains. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result.", + "coverageNotes": "Audit5779 companion to audit5775: Retire the complete browser palette activation suite. Colliding child-ID pre-mutation refusal, focus intent captured before page removal, correct split selection and missing authoritative wrapper refusal alarms are intentionally lost without replacement. Narrow three compound commands and remove one testFiles entry. Complete dated evidenceRuns are unchanged; none selects these retired suites and none validates narrowed selectors. All unrelated remaining assertions and selectors retain their original scope, without replacement certification. No fresh execution or current import reachability result is claimed. Complete prior account preserved verbatim below as historical: Audit5765 companion to audit5760 retires the whole simulator-palette-search.test.ts suite. Direct same-ID local/remote simulator candidate ownership and ambiguous hostless legacy refusal alarms are intentionally lost without equivalent replacement. Four compound unit commands are narrowed and its testFiles entry removed. Browser candidate and paired Cmd-J selection assertions remain unchanged, with only their original scope; they are not certified as replacements. All complete dated evidenceRuns remain unchanged; none selects this removed suite, and none validates changed commands. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account is preserved verbatim below as historical, including any older then-retained coverage claim: Audit5718 companion to audit5715 retires the whole worktree-checks-review-index.test.ts suite. Its remaining same-ID local/SSH Worktree-object review-index isolation alarm is intentionally lost without equivalent replacement. Remove its standalone selector, narrow two compound selectors, and remove its testFiles/assertionRefs entries. Two complete dated failed receipts selecting this suite through command/currentCommand are retired unchanged into knownGaps; they do not validate any remaining selector. All unrelated selectors, assertions and receipts retain only their original scope. No fresh execution, current import reachability, provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit5658 integrates source audit5652: retire the whole web-session-tabs-sync-mirror-identity.test.ts suite and its exact active selectors. Intentionally lose same-id host mirror snapshot and removal isolation alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3663 renews approved3644/3645/3648/amended3651 at privatec1ef: remove10authored/26finite across7changedtestpaths,4whole drivers; retain23authored/24finite including actualcmdkStrictMode defaultcursor race. Retire version1.5.0/1.5.1→shrinksImages capability threshold and launch-to-prompt wiring alarm. Surviving prompt tests explicitly supply capability and do not replace wiring coverage. Retire resolved-before-personOnly precedence; hook-gone/live-dialog guidance; stale-incarnation versus live-looking dialog classification; delayed/clipped warning extraction and wait-for-paint wiring; 3row setting/personOnly approve/deny/disclaimer suggestion composition;13row setting/reason/person/coordinator admission, close/mail attribution, terminal delivery/refusal/preanswered/personOnly/dropped-allow handler propagation alarms. Real state/access/SQLite effects occur; these genuine losses are accepted, not mocked-away. Retire full command extraction from serialized JSON in worker receipt and nontruncation alarm; no rendering, actual worker approval or native shell proof. Retire2row extra-source first/last order and controlled default cursor projection, plus generic open-palette livefolder add/remove render alarm. Explicitly supersede rawexact297KEEP refresh. Keep actualcmdk/StrictMode default cursor race driver; no default-suite loss claim. No equivalent replacement asserted. Retained queue/commit/retryownership/filebudget, terminalfreshness/provenance/competing-answer, RPC DB-effect, qualifiedfolder/runtimehandoff and lingering-reopen cases have distinct scope. Audit3675 preserves the upstream revised unreported-approval close regression, its escalation helper and adapted survivors. Source-only static renewal; no runner/compiler/app/native/remote/CI claim. Upstream41390host-owned approvalwatch/report lifetime reviewed separately; no new lifetime test removed. Preserve all earlier metadata/evidence. Audit3381 intentionally removes the entire Cmd-J host-qualified candidate-ownership suite and its active selectors/assertion. The hidden same-id sibling ambiguity regression alarm is lost without replacement. The complete original dated failed receipt below is retired verbatim, including both command and currentCommand, rather than reassigned as validation of remaining selectors. Other complete receipts retain their exact original scopes; remaining browser/simulator/workspace/e2e selectors do not imply equivalent ownership protection. No fresh execution is claimed. Audit3359 retires the whole ensure-simulator-tab-behavior suite: host-collision reuse, host stamping, inactive creation and unknown-owner routing alarms are intentionally lost without equivalent replacement. Its standalone command is removed and four compound commands narrowed. Three complete dated receipts selecting that source through currentCommand are retired verbatim, including their compound historical selectors; no retained test inherits their validation. Seven unrelated macOS receipts retain their original scope. No fresh runtime/UI, simulator, provider, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit 3301 removes the orphaned mobile file-close fallback and ordinary cross-content MRU examples from tabs-open-close-lifecycle.test.ts. Earlier descriptions of retained MRU coverage are historical. Audit5612 retires the remaining integrated mobile markdown close/frame-settlement suite, accepting loss of its closed-editor snapshot republishing alarm without replacement or fresh validation. Preserve the existing administrative failed receipt and all complete retired receipts verbatim, along with selectors and unrelated assertions; no equivalent replacement or fresh Cmd-J, native or remote result is claimed. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit2729 reduces browser-page-palette-activation.test.ts: separate SSH/paired-runtime alias forwarding, distinct multigroup views accepted, and remote-folder activation forwarding alarms are removed. Collision refusal, preactivation address-bar focus capture, owning-group activation state and missing-tab refusal remain byte-identical. No equivalent replacement, fresh gate execution or actual host/browser delivery evidence is claimed. Prior coverage account: Audit2697 browser source review (metadata followup2702): Reduce src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts by four authored/expanded cases without replacement. The remaining three cases preserve only their existing same-ID execution-host separation, absent stamped-owner refusal and ambiguous legacy-bucket refusal scope. Intentionally lose duplicate backing-tab-ID suppression, multiple unified-browser claims of one workspace, foreign-worktree unified-tab rejection, and the 1000-workspace output/internal getter-read budget alarm. These are real removed alarms; the retained host cases are not equivalent replacements. Current test-value policy rejects internal getter/read budgets; no replacement performance or measured-cost claim is made. Keep existing nonempty selectors and the retained same-ID browser assertionRef. No fresh gate execution or reduced-source validation is supplied; dated receipts, results, commands and historical coverage accounts remain within their original source scope. No live browser activation, physical provider, mixed-version execution, mobile, native UI, platform hardware, soak or timing result is added. Prior coverage account (preserved verbatim): Audit2266 reduces cmd-j-host-qualified-candidate-ownership.test.ts to the scoped open-tab hidden same-ID legacy ambiguity refusal. Separate browser/simulator paired-runtime alias and current-row projections, generic workspace host projection and hostless explicit-owner refusal examples are removed without equivalent replacement. No fresh gate execution, browser activation, physical host, simulator or remote delivery evidence is claimed. Historical dated receipts and budgets remain raw-byte exact. Prior coverage account: Audit1899 replays sealed Audit1895: workspace-session-schema.test.ts keeps only cross-workspace truncated-tab salvage and legacy browser-history cap normalization. Four current commands and testFiles retain that reduced source; no current assertionRef or active receipt selects it. SSH file-owner, isolated browser partition, launch/title/quick-command fields, recency, structured-chat/view-mode and remote browser identity hydration alarms are intentionally lost. Existing retired receipt strings and unrelated active receipts remain verbatim. No equivalent replacement, new Cmd-J gate execution, native simulator or remote/browser restore proof is claimed. Historical coverage account before Audit1899: Audit1494 removes use-open-tab-search.test.ts. Supplied host/worktree/title/ranking projections, simple subscription updates and result-array identity alarms are retired. No actual activation or navigation occurred in that suite. No equivalent replacement coverage or fresh Cmd-J gate validation is claimed. Historical receipts remain scoped to their original selectors. Audit1433 narrows worktree-checks-review-index.test.ts to same-ID local/SSH object-key review isolation. Local provider/cache lookup, GitLab preference, suppression/legacy fallback, explicit-PR authority, physical-versus-runtime review isolation, and branchless-workspace alarms are intentionally removed. No equivalent replacement coverage is claimed. Historical receipts and commands remain unchanged and do not certify the reduced source. Historical coverage account: Audit1396 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1308 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Deterministic candidate-builder contracts inject local and paired-runtime worktrees with the same bare id into the real aggregated tab buckets, including folder workspaces and a paired runtime transporting an SSH-owned worktree. A mirror contract preserves distinct same-id runtime tabs. A paired Electron journey verifies both visible browser rows and both visible simulator rows, then requires each selection to render its owning active tab and update backing host-qualified state. The test-value audit narrowed simulator-palette-search.test.ts to the recency tie, same-id host isolation, ambiguous legacy host rejection and oversized-input getter tripwire. Supplied timestamp, empty-query context ordering, host projection, alias/range, metadata matching, active-tab score, over-token/whitespace and malformed display-name fallback examples were removed. Their separate alarms are lost; retained candidate and activation contracts do not establish equivalent coverage. Historical run commands and results remain historical. The audit also removed the standalone workspace-tab-palette-search suite: supplied row, title, metadata, alias, range, ranking and ownership examples no longer provide their separate alarms. Other retained contracts are not replacement coverage. The mirror-identity fixture now retains same-id sibling-runtime isolation and the repeated-frame subscriber tripwire only. Supplied field, owner, alias and mapping examples are removed; their separate alarms are lost. The retained sibling-runtime case is not equivalent coverage for them. The test-value audit removed tabs-open-close-lifecycle host-stamping examples and ordinary tab/group operations from tabs-pane-layout-operations. Local-null, explicit-runtime and SSH-without-active-host stamp assertions are lost; retained mobile/MRU and subscriber/atomic split cases do not replace them. Candidate and live Cmd-J evidence retains its own scope. Historical commands, outcomes and narratives remain historical. Audit1308: src/renderer/src/lib/browser-palette-search.test.ts removed. Browser-palette token and pasted-query size-guard work alarms disappear. No equivalent replacement coverage is claimed. Audit1386: src/renderer/src/lib/open-mobile-emulator-tab.test.ts reduced. Duplicate attach count and null-tab creation retry/guard reset standalone alarms removed; no simulator device used. No equivalent replacement coverage is claimed. Existing exact unaffected receipts and their platform/provider/budget claims remain scoped to unchanged selectors. Changed optional selectors have no new execution result. Audit1396: src/renderer/src/lib/simulator-palette-search.test.ts reduced. Lose simulator-specific lastFocusedAt tie-order alarm; identity/routing and pre-scan size fence remain. No native simulator or real remote launch claim. No equivalent replacement coverage is claimed. Audit1402: src/renderer/src/runtime/web-session-tabs-sync-mirror-identity.test.ts reduced. Loses repeated no-op frame store-notification budget; independent cross-runtime resource preservation remains. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result.", "motivatingLinks": [ "https://linear.app/stably/issue/STA-4965", "https://github.com/stablyai/orca/pull/15371" ], "invariant": "Candidate identity is the tuple of execution-host identity and worktree identity: same-id sibling hosts retain separate correct browser, simulator, and workspace tabs, each tab appears exactly once, and selection activates its owning host.", - "oracle": "Audit5718 companion to audit5715 retires the whole worktree-checks-review-index.test.ts suite. Its remaining same-ID local/SSH Worktree-object review-index isolation alarm is intentionally lost without equivalent replacement. Remove its standalone selector, narrow two compound selectors, and remove its testFiles/assertionRefs entries. Two complete dated failed receipts selecting this suite through command/currentCommand are retired unchanged into knownGaps; they do not validate any remaining selector. All unrelated selectors, assertions and receipts retain only their original scope. No fresh execution, current import reachability, provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit5658 integrates source audit5652: retire the whole web-session-tabs-sync-mirror-identity.test.ts suite and its exact active selectors. Intentionally lose same-id host mirror snapshot and removal isolation alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3663 renews approved3644/3645/3648/amended3651 at privatec1ef: remove10authored/26finite across7changedtestpaths,4whole drivers; retain23authored/24finite including actualcmdkStrictMode defaultcursor race. Retire version1.5.0/1.5.1→shrinksImages capability threshold and launch-to-prompt wiring alarm. Surviving prompt tests explicitly supply capability and do not replace wiring coverage. Retire resolved-before-personOnly precedence; hook-gone/live-dialog guidance; stale-incarnation versus live-looking dialog classification; delayed/clipped warning extraction and wait-for-paint wiring; 3row setting/personOnly approve/deny/disclaimer suggestion composition;13row setting/reason/person/coordinator admission, close/mail attribution, terminal delivery/refusal/preanswered/personOnly/dropped-allow handler propagation alarms. Real state/access/SQLite effects occur; these genuine losses are accepted, not mocked-away. Retire full command extraction from serialized JSON in worker receipt and nontruncation alarm; no rendering, actual worker approval or native shell proof. Retire2row extra-source first/last order and controlled default cursor projection, plus generic open-palette livefolder add/remove render alarm. Explicitly supersede rawexact297KEEP refresh. Keep actualcmdk/StrictMode default cursor race driver; no default-suite loss claim. No equivalent replacement asserted. Retained queue/commit/retryownership/filebudget, terminalfreshness/provenance/competing-answer, RPC DB-effect, qualifiedfolder/runtimehandoff and lingering-reopen cases have distinct scope. Audit3675 preserves the upstream revised unreported-approval close regression, its escalation helper and adapted survivors. Source-only static renewal; no runner/compiler/app/native/remote/CI claim. Upstream41390host-owned approvalwatch/report lifetime reviewed separately; no new lifetime test removed. Preserve all earlier metadata/evidence. Audit3381 intentionally removes the entire Cmd-J host-qualified candidate-ownership suite and its active selectors/assertion. The hidden same-id sibling ambiguity regression alarm is lost without replacement. The complete original dated failed receipt below is retired verbatim, including both command and currentCommand, rather than reassigned as validation of remaining selectors. Other complete receipts retain their exact original scopes; remaining browser/simulator/workspace/e2e selectors do not imply equivalent ownership protection. No fresh execution is claimed. Audit3359 retires the whole ensure-simulator-tab-behavior suite: host-collision reuse, host stamping, inactive creation and unknown-owner routing alarms are intentionally lost without equivalent replacement. Its standalone command is removed and four compound commands narrowed. Three complete dated receipts selecting that source through currentCommand are retired verbatim, including their compound historical selectors; no retained test inherits their validation. Seven unrelated macOS receipts retain their original scope. No fresh runtime/UI, simulator, provider, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit 3301 removes the orphaned mobile file-close fallback and ordinary cross-content MRU examples from tabs-open-close-lifecycle.test.ts. Earlier descriptions of retained MRU coverage are historical. Audit5612 retires the remaining integrated mobile markdown close/frame-settlement suite, accepting loss of its closed-editor snapshot republishing alarm without replacement or fresh validation. Preserve the existing administrative failed receipt and all complete retired receipts verbatim, along with selectors and unrelated assertions; no equivalent replacement or fresh Cmd-J, native or remote result is claimed. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit2697 browser source review (metadata followup2702): Reduce src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts by four authored/expanded cases without replacement. The remaining three cases preserve only their existing same-ID execution-host separation, absent stamped-owner refusal and ambiguous legacy-bucket refusal scope. Intentionally lose duplicate backing-tab-ID suppression, multiple unified-browser claims of one workspace, foreign-worktree unified-tab rejection, and the 1000-workspace output/internal getter-read budget alarm. These are real removed alarms; the retained host cases are not equivalent replacements. Current test-value policy rejects internal getter/read budgets; no replacement performance or measured-cost claim is made. Keep existing nonempty selectors and the retained same-ID browser assertionRef. No fresh gate execution or reduced-source validation is supplied; dated receipts, results, commands and historical coverage accounts remain within their original source scope. No live browser activation, physical provider, mixed-version execution, mobile, native UI, platform hardware, soak or timing result is added. Prior coverage account (preserved verbatim): Audit2266 current retained source checks only that scoped open-tab search rejects hostless legacy browser, simulator and workspace tabs when a hidden same-ID sibling host remains in the ownership catalog. Reduced selectors require fresh validation; existing historical receipts do not validate the changed source. Prior oracle account: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Aggregate two hosts' tabs under one intentionally colliding worktree id, stamp each unified tab with its execution host, and require exactly one candidate per owner. Repeat with an SSH physical owner transported by a paired-runtime alias. Independently require each browser and simulator Cmd-J selection to update activeWorkspaceExecutionHostId plus its owning workspace/group and render the selected tab active. Ambiguous legacy tabs without ownership fail closed.", + "oracle": "Audit5779 companion to audit5775: Retire the complete browser palette activation suite. Colliding child-ID pre-mutation refusal, focus intent captured before page removal, correct split selection and missing authoritative wrapper refusal alarms are intentionally lost without replacement. Narrow three compound commands and remove one testFiles entry. Complete dated evidenceRuns are unchanged; none selects these retired suites and none validates narrowed selectors. All unrelated remaining assertions and selectors retain their original scope, without replacement certification. No fresh execution or current import reachability result is claimed. Complete prior account preserved verbatim below as historical: Audit5765 companion to audit5760 retires the whole simulator-palette-search.test.ts suite. Direct same-ID local/remote simulator candidate ownership and ambiguous hostless legacy refusal alarms are intentionally lost without equivalent replacement. Four compound unit commands are narrowed and its testFiles entry removed. Browser candidate and paired Cmd-J selection assertions remain unchanged, with only their original scope; they are not certified as replacements. All complete dated evidenceRuns remain unchanged; none selects this removed suite, and none validates changed commands. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account is preserved verbatim below as historical, including any older then-retained coverage claim: Audit5718 companion to audit5715 retires the whole worktree-checks-review-index.test.ts suite. Its remaining same-ID local/SSH Worktree-object review-index isolation alarm is intentionally lost without equivalent replacement. Remove its standalone selector, narrow two compound selectors, and remove its testFiles/assertionRefs entries. Two complete dated failed receipts selecting this suite through command/currentCommand are retired unchanged into knownGaps; they do not validate any remaining selector. All unrelated selectors, assertions and receipts retain only their original scope. No fresh execution, current import reachability, provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit5658 integrates source audit5652: retire the whole web-session-tabs-sync-mirror-identity.test.ts suite and its exact active selectors. Intentionally lose same-id host mirror snapshot and removal isolation alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3663 renews approved3644/3645/3648/amended3651 at privatec1ef: remove10authored/26finite across7changedtestpaths,4whole drivers; retain23authored/24finite including actualcmdkStrictMode defaultcursor race. Retire version1.5.0/1.5.1→shrinksImages capability threshold and launch-to-prompt wiring alarm. Surviving prompt tests explicitly supply capability and do not replace wiring coverage. Retire resolved-before-personOnly precedence; hook-gone/live-dialog guidance; stale-incarnation versus live-looking dialog classification; delayed/clipped warning extraction and wait-for-paint wiring; 3row setting/personOnly approve/deny/disclaimer suggestion composition;13row setting/reason/person/coordinator admission, close/mail attribution, terminal delivery/refusal/preanswered/personOnly/dropped-allow handler propagation alarms. Real state/access/SQLite effects occur; these genuine losses are accepted, not mocked-away. Retire full command extraction from serialized JSON in worker receipt and nontruncation alarm; no rendering, actual worker approval or native shell proof. Retire2row extra-source first/last order and controlled default cursor projection, plus generic open-palette livefolder add/remove render alarm. Explicitly supersede rawexact297KEEP refresh. Keep actualcmdk/StrictMode default cursor race driver; no default-suite loss claim. No equivalent replacement asserted. Retained queue/commit/retryownership/filebudget, terminalfreshness/provenance/competing-answer, RPC DB-effect, qualifiedfolder/runtimehandoff and lingering-reopen cases have distinct scope. Audit3675 preserves the upstream revised unreported-approval close regression, its escalation helper and adapted survivors. Source-only static renewal; no runner/compiler/app/native/remote/CI claim. Upstream41390host-owned approvalwatch/report lifetime reviewed separately; no new lifetime test removed. Preserve all earlier metadata/evidence. Audit3381 intentionally removes the entire Cmd-J host-qualified candidate-ownership suite and its active selectors/assertion. The hidden same-id sibling ambiguity regression alarm is lost without replacement. The complete original dated failed receipt below is retired verbatim, including both command and currentCommand, rather than reassigned as validation of remaining selectors. Other complete receipts retain their exact original scopes; remaining browser/simulator/workspace/e2e selectors do not imply equivalent ownership protection. No fresh execution is claimed. Audit3359 retires the whole ensure-simulator-tab-behavior suite: host-collision reuse, host stamping, inactive creation and unknown-owner routing alarms are intentionally lost without equivalent replacement. Its standalone command is removed and four compound commands narrowed. Three complete dated receipts selecting that source through currentCommand are retired verbatim, including their compound historical selectors; no retained test inherits their validation. Seven unrelated macOS receipts retain their original scope. No fresh runtime/UI, simulator, provider, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit 3301 removes the orphaned mobile file-close fallback and ordinary cross-content MRU examples from tabs-open-close-lifecycle.test.ts. Earlier descriptions of retained MRU coverage are historical. Audit5612 retires the remaining integrated mobile markdown close/frame-settlement suite, accepting loss of its closed-editor snapshot republishing alarm without replacement or fresh validation. Preserve the existing administrative failed receipt and all complete retired receipts verbatim, along with selectors and unrelated assertions; no equivalent replacement or fresh Cmd-J, native or remote result is claimed. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit2697 browser source review (metadata followup2702): Reduce src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts by four authored/expanded cases without replacement. The remaining three cases preserve only their existing same-ID execution-host separation, absent stamped-owner refusal and ambiguous legacy-bucket refusal scope. Intentionally lose duplicate backing-tab-ID suppression, multiple unified-browser claims of one workspace, foreign-worktree unified-tab rejection, and the 1000-workspace output/internal getter-read budget alarm. These are real removed alarms; the retained host cases are not equivalent replacements. Current test-value policy rejects internal getter/read budgets; no replacement performance or measured-cost claim is made. Keep existing nonempty selectors and the retained same-ID browser assertionRef. No fresh gate execution or reduced-source validation is supplied; dated receipts, results, commands and historical coverage accounts remain within their original source scope. No live browser activation, physical provider, mixed-version execution, mobile, native UI, platform hardware, soak or timing result is added. Prior coverage account (preserved verbatim): Audit2266 current retained source checks only that scoped open-tab search rejects hostless legacy browser, simulator and workspace tabs when a hidden same-ID sibling host remains in the ownership catalog. Reduced selectors require fresh validation; existing historical receipts do not validate the changed source. Prior oracle account: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Aggregate two hosts' tabs under one intentionally colliding worktree id, stamp each unified tab with its execution host, and require exactly one candidate per owner. Repeat with an SSH physical owner transported by a paired-runtime alias. Independently require each browser and simulator Cmd-J selection to update activeWorkspaceExecutionHostId plus its owning workspace/group and render the selected tab active. Ambiguous legacy tabs without ownership fail closed.", "commands": [ "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx", - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts", - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts", - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts", - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts", "pnpm exec playwright test tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", "SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1" ], "testFiles": [ "src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx", "src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts", - "src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts", - "src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts", "src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts", "src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts", "tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts" @@ -2412,7 +2410,13 @@ "Audit5718 exact original complete testFiles, historical selectors only; removed/narrowed commands do not inherit validation:\n[\n \"src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\",\n \"src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx\",\n \"src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts\",\n \"src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts\",\n \"src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts\",\n \"src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts\",\n \"src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts\",\n \"tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts\"\n ]", "Audit5718 exact original complete assertionRefs, historical selectors only; removed/narrowed commands do not inherit validation:\n[\n {\n \"file\": \"src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\",\n \"assertions\": [\"same-id local and SSH worktrees keep separate review-index results\"]\n },\n {\n \"file\": \"src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts\",\n \"assertions\": [\n \"same-id local and remote browser tabs appear once under their owning hosts\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts\",\n \"assertions\": [\n \"both browser selections activate and render their owning host and workspace\",\n \"both simulator selections activate and render their owning host and group\"\n ]\n }\n ]", "Audit5718 retires this complete dated receipt because its command/currentCommand selects the deleted review-index suite. The unchanged original receipt is historical, not validation of remaining selectors. Original receipt verbatim:\n{\n \"date\": \"2026-08-20\",\n \"runner\": \"local\",\n \"platform\": \"macos\",\n \"command\": \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\",\n \"result\": \"failed\",\n \"durationSeconds\": 0.2,\n \"summary\": \"The final review-cache oracle failed 1/6: a runtime-owned SSH worktree exposed the physical host's cached pull request.\",\n \"currentCommand\": \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\"\n }", - "Audit5718 retires this complete dated receipt because its command/currentCommand selects the deleted review-index suite. The unchanged original receipt is historical, not validation of remaining selectors. Original receipt verbatim:\n{\n \"date\": \"2026-08-20\",\n \"runner\": \"local\",\n \"platform\": \"macos\",\n \"command\": \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\",\n \"result\": \"failed\",\n \"durationSeconds\": 0.4,\n \"summary\": \"The exact-head clean-round oracle failed 1/6: after the host-qualified index rejected a physical SSH review, the palette document still surfaced its unqualified legacy cache entry for the runtime-owned worktree.\",\n \"currentCommand\": \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\"\n }" + "Audit5718 retires this complete dated receipt because its command/currentCommand selects the deleted review-index suite. The unchanged original receipt is historical, not validation of remaining selectors. Original receipt verbatim:\n{\n \"date\": \"2026-08-20\",\n \"runner\": \"local\",\n \"platform\": \"macos\",\n \"command\": \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\",\n \"result\": \"failed\",\n \"durationSeconds\": 0.4,\n \"summary\": \"The exact-head clean-round oracle failed 1/6: after the host-qualified index rejected a physical SSH review, the palette document still surfaced its unqualified legacy cache entry for the runtime-owned worktree.\",\n \"currentCommand\": \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/cmd-j/worktree-checks-review-index.test.ts\"\n }", + "Audit5765 exact original complete commands JSON value, preserved verbatim as historical selector metadata; removed/narrowed selectors have no new validation:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts\",\n \"pnpm exec playwright test tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"\n ]", + "Audit5765 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; removed/narrowed selectors have no new validation:\n[\n \"src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx\",\n \"src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts\",\n \"src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts\",\n \"src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts\",\n \"src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts\",\n \"src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts\",\n \"tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts\"\n ]", + "Audit5765 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; removed/narrowed selectors have no new validation:\n[\n {\n \"file\": \"src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts\",\n \"assertions\": [\n \"same-id local and remote browser tabs appear once under their owning hosts\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts\",\n \"assertions\": [\n \"both browser selections activate and render their owning host and workspace\",\n \"both simulator selections activate and render their owning host and group\"\n ]\n }\n ]", + "Audit5779 exact original complete commands JSON value, preserved verbatim as historical selector metadata; changed selectors have no new validation:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts\",\n \"pnpm exec playwright test tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"\n ]", + "Audit5779 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; changed selectors have no new validation:\n[\n \"src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx\",\n \"src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts\",\n \"src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts\",\n \"src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts\",\n \"src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts\",\n \"src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts\",\n \"tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts\"\n ]", + "Audit5779 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; changed selectors have no new validation:\n[\n {\n \"file\": \"src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts\",\n \"assertions\": [\n \"same-id local and remote browser tabs appear once under their owning hosts\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-cmd-j-host-qualified-tabs.spec.ts\",\n \"assertions\": [\n \"both browser selections activate and render their owning host and workspace\",\n \"both simulator selections activate and render their owning host and group\"\n ]\n }\n ]" ], "demotionRule": "Cannot promote if a same-id sibling tab duplicates, disappears, activates another host, or if ambiguous unstamped ownership is guessed." }, @@ -2579,7 +2583,7 @@ "providers": ["local", "local-daemon", "ssh-daemon", "ssh-relay", "paired-runtime"], "coveredPlatforms": ["macos", "linux"], "coveredProviders": ["local", "local-daemon", "ssh-relay", "paired-runtime"], - "coverageNotes": "Audit5714 retires the whole shell-startup-output-scanner suite, accepting selected two-chunk byte preservation, identity ordering, held-prefix drain and post-marker flag alarms without equivalent replacement or fresh execution. Active selectors/assertion references are reduced; historical native/live receipts remain unchanged. Audit5535 removes the whole line-editor-ready-output-scanner.test.ts literal sequence table. Split-sequence detection alarms are intentionally lost without equivalent replacement. Its prospective selectors are removed; prior red/green and live receipts remain historical and do not validate this reduced selector. Audit 3959 retires the whole session.test.ts driver (27 authored / 33 finite cases): startup/echo filtering, readiness input gates, ownership confirmation, detach authority, and termination retry/exit ordering alarms are intentionally lost. No equivalent replacement or fresh runtime validation is claimed. Audit1683 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1627 removes low-value mocked daemon projections, scalar tables and duplicate terminal examples without equivalent replacement coverage. Per-source reviews record retained terminal content preservation, process ownership refusal and recovery boundaries together with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Real macOS node-pty integration covers zsh 5.9 .zshenv/.zprofile and bash 3.2 profile replacement shells, including exec -a names, same-shell and child-process silent reads, a blocking zle-line-init hook, non-shell readline replacements, and a non-shell image renamed zsh. A real Fish PTY proves marker stripping is byte-exact and does not render bracketed-paste control text. Ubuntu 20.04/Bash 5.0 and Ubuntu 24.04/Bash 5.2 containers cover scalar and array PROMPT_COMMAND composition, including real zoxide on 24.04. Deterministic owner contracts cover local, daemon, and SSH relay identity/readiness composition plus provider-owned delivery; explicit terminal-paste remains renderer-owned. Live isolated journeys cover a macOS headed desktop owner with paired web client, headless orca serve with paired web client, and a Docker Linux OpenSSH/Bash target with one readiness-time reconnect. Linux desktop, WSL/Windows, live zsh-over-SSH, and physical remote hosts remain gaps.", + "coverageNotes": "Audit5743 removes whole identity-scanner/browser retirement/RPC dispatch test suites from active selectors, accepting incremental OSC identity framing, in-memory page retirement generation fencing and spied-runtime SQL dispatch authority/rollback alarms without equivalent replacement or fresh execution. Remaining dated evidence keeps its exact independent selector scope. Historical prior account (preserved verbatim): Audit5714 retires the whole shell-startup-output-scanner suite, accepting selected two-chunk byte preservation, identity ordering, held-prefix drain and post-marker flag alarms without equivalent replacement or fresh execution. Active selectors/assertion references are reduced; historical native/live receipts remain unchanged. Audit5535 removes the whole line-editor-ready-output-scanner.test.ts literal sequence table. Split-sequence detection alarms are intentionally lost without equivalent replacement. Its prospective selectors are removed; prior red/green and live receipts remain historical and do not validate this reduced selector. Audit 3959 retires the whole session.test.ts driver (27 authored / 33 finite cases): startup/echo filtering, readiness input gates, ownership confirmation, detach authority, and termination retry/exit ordering alarms are intentionally lost. No equivalent replacement or fresh runtime validation is claimed. Audit1683 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1627 removes low-value mocked daemon projections, scalar tables and duplicate terminal examples without equivalent replacement coverage. Per-source reviews record retained terminal content preservation, process ownership refusal and recovery boundaries together with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Real macOS node-pty integration covers zsh 5.9 .zshenv/.zprofile and bash 3.2 profile replacement shells, including exec -a names, same-shell and child-process silent reads, a blocking zle-line-init hook, non-shell readline replacements, and a non-shell image renamed zsh. A real Fish PTY proves marker stripping is byte-exact and does not render bracketed-paste control text. Ubuntu 20.04/Bash 5.0 and Ubuntu 24.04/Bash 5.2 containers cover scalar and array PROMPT_COMMAND composition, including real zoxide on 24.04. Deterministic owner contracts cover local, daemon, and SSH relay identity/readiness composition plus provider-owned delivery; explicit terminal-paste remains renderer-owned. Live isolated journeys cover a macOS headed desktop owner with paired web client, headless orca serve with paired web client, and a Docker Linux OpenSSH/Bash target with one readiness-time reconnect. Linux desktop, WSL/Windows, live zsh-over-SSH, and physical remote hosts remain gaps.", "motivatingLinks": [ "https://github.com/stablyai/orca/issues/13767", "https://linear.app/stably/issue/STA-4067", @@ -2592,15 +2596,14 @@ "invariant": "Shell startup scanning preserves every non-Orca output byte in order across arbitrary PTY chunk boundaries. Bash scalar and supported array PROMPT_COMMAND values preserve user bytes, hook order, and foreground exit status while emitting exactly one OSC 133 A/C/D lifecycle without syntax errors. Before user startup files run, the wrapper publishes its shell PID. If a later exec discards the ready marker, proof-based recovery releases queued startup input only after the launched shell's actual executable image with that exact PID owns the PTY foreground, emits its post-hook line-editor enable sequence, and exposes zle/readline termios; startup reads, line-init hooks, child foreground processes, and non-shell readline replacements cannot trigger that proof. The existing bounded compatibility timeout may enqueue input without proof, but must not publish readiness, lose or duplicate that input across reconnect, or execute it before the replacement shell can accept it.", "oracle": "Audit1683 retires changed-source assertion and execution scope without equivalent replacement coverage. Existing unchanged-selector receipts remain scoped to their original sources. Historical prior-source oracle: Split Fish output immediately after the ready marker and after the following ESC introducer; local and daemon owners must emit the exact ESC [ ? 2004 h bytes and headless xterm must not render literal control text. Run the real generated wrappers under node-pty with disposable zsh, bash, and Fish startup files. Exercise Bash scalar and array PROMPT_COMMAND values with empty, repeated, escaped, whitespace, control-byte, odd-backslash, status-mutating, DEBUG-trap, zoxide, and RHEL-style hooks; require exact A,C,D:0,A,C,D:1,A,C ordering and byte preservation. Plain and exec -a replacement shells must receive one queued command at their first completed line editor without waiting for the 15-second timeout. The identical oracle must time out without the startup identity and prompt fallback. Same-shell reads, child-process reads, a blocking zle-line-init hook, sqlite3, and sqlite3 renamed zsh must not trigger prompt fallback. Relay owner coverage must use the same lossless scanner composition and release through the same prompt contract.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts src/main/daemon/shell-readiness/testing/bash-prompt-command-composition.test.ts src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts src/shared/terminal/pty/native-process/shell-process-readiness.test.ts src/main/daemon/shell-readiness/testing/shell-ready.test.ts src/main/providers/local-pty/local-pty-shell-ready-marker-scan.test.ts src/main/providers/local-pty/local-pty-shell-ready-startup-command.test.ts src/main/providers/local-pty/local-pty-shell-ready-wrapper-generation.test.ts", - "pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts src/shared/terminal/pty/native-process/shell-process-readiness.test.ts src/main/daemon/shell-readiness/testing/shell-ready.test.ts src/main/providers/local-pty/local-pty-shell-ready-marker-scan.test.ts src/main/providers/local-pty/local-pty-shell-ready-startup-command.test.ts src/main/providers/local-pty/local-pty-shell-ready-wrapper-generation.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts src/main/daemon/shell-readiness/testing/bash-prompt-command-composition.test.ts src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts src/shared/terminal/pty/native-process/shell-process-readiness.test.ts src/main/daemon/shell-readiness/testing/shell-ready.test.ts src/main/providers/local-pty/local-pty-shell-ready-marker-scan.test.ts src/main/providers/local-pty/local-pty-shell-ready-startup-command.test.ts src/main/providers/local-pty/local-pty-shell-ready-wrapper-generation.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts src/shared/terminal/pty/native-process/shell-process-readiness.test.ts src/main/daemon/shell-readiness/testing/shell-ready.test.ts src/main/providers/local-pty/local-pty-shell-ready-marker-scan.test.ts src/main/providers/local-pty/local-pty-shell-ready-startup-command.test.ts src/main/providers/local-pty/local-pty-shell-ready-wrapper-generation.test.ts", "pnpm exec vitest run --config config/vitest.config.ts --maxWorkers=1 src/main/daemon/shell-readiness/testing/shell-ready.test.ts", "ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-startup-exec-readiness.spec.ts --config tests/playwright.config.ts --project electron-headless --project electron-headful --workers=1" ], "testFiles": [ "src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts", "src/main/daemon/shell-readiness/testing/bash-prompt-command-composition.test.ts", - "src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts", "src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts", "src/shared/terminal/pty/native-process/shell-process-readiness.test.ts", "src/main/daemon/shell-readiness/testing/shell-ready.test.ts", @@ -2661,7 +2664,8 @@ "The pre-existing timeout backstop can still deliver queued input to a non-shell replacement after it expires; this fallback prevents indefinite startup hangs and is unchanged by the prompt fallback.", "The fallback restores safe startup-command delivery but cannot recreate OSC 133 hooks or overlay restores already discarded by exec.", "Startup code running in the launched shell can deliberately spoof the public line-editor enable sequence after configuring matching termios; the existing timeout path already trusts a public OSC marker from the same startup code.", - "Audit1878 removes the ptsName getter/shape table and mocked platform stty-argv table from pty-slave-line-discipline-echo.test.ts, and the unset-PATH sh-versus-/bin/sh helper comparison from shell-process-readiness.test.ts. Retained parser/probe promise state and real-filesystem/process tests have their original platform and injected-process limits; no equivalent replacement or fresh broad readiness-gate result is claimed." + "Audit1878 removes the ptsName getter/shape table and mocked platform stty-argv table from pty-slave-line-discipline-echo.test.ts, and the unset-PATH sh-versus-/bin/sh helper comparison from shell-process-readiness.test.ts. Retained parser/probe promise state and real-filesystem/process tests have their original platform and injected-process limits; no equivalent replacement or fresh broad readiness-gate result is claimed.", + "Audit5743 exact original active selector fields before whole suite removal (historical, not current coverage): {\"commands\":[\"pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts src/main/daemon/shell-readiness/testing/bash-prompt-command-composition.test.ts src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts src/main/pty/shell-startup/shell-startup-output-scanner.test.ts src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts src/shared/terminal/pty/native-process/shell-process-readiness.test.ts src/main/daemon/shell-readiness/testing/shell-ready.test.ts src/main/providers/local-pty/local-pty-shell-ready-marker-scan.test.ts src/main/providers/local-pty/local-pty-shell-ready-startup-command.test.ts src/main/providers/local-pty/local-pty-shell-ready-wrapper-generation.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts src/main/pty/shell-startup/shell-startup-output-scanner.test.ts src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts src/shared/terminal/pty/native-process/shell-process-readiness.test.ts src/main/daemon/shell-readiness/testing/shell-ready.test.ts src/main/providers/local-pty/local-pty-shell-ready-marker-scan.test.ts src/main/providers/local-pty/local-pty-shell-ready-startup-command.test.ts src/main/providers/local-pty/local-pty-shell-ready-wrapper-generation.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts --maxWorkers=1 src/main/daemon/shell-readiness/testing/shell-ready.test.ts src/main/pty/shell-startup/shell-startup-output-scanner.test.ts\",\"ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-startup-exec-readiness.spec.ts --config tests/playwright.config.ts --project electron-headless --project electron-headful --workers=1\"],\"testFiles\":[\"src/main/daemon/shell-readiness/testing/repro-13767-shell-ready-marker-lost-to-exec.test.ts\",\"src/main/daemon/shell-readiness/testing/bash-prompt-command-composition.test.ts\",\"src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts\",\"src/main/pty/shell-startup/shell-startup-output-scanner.test.ts\",\"src/shared/terminal/pty/native-process/pty-slave-line-discipline-echo.test.ts\",\"src/shared/terminal/pty/native-process/shell-process-readiness.test.ts\",\"src/main/daemon/shell-readiness/testing/shell-ready.test.ts\",\"src/main/providers/local-pty/local-pty-shell-ready-marker-scan.test.ts\",\"src/main/providers/local-pty/local-pty-shell-ready-startup-command.test.ts\",\"src/main/providers/local-pty/local-pty-shell-ready-wrapper-generation.test.ts\",\"tests/e2e/paired-startup-exec-readiness.spec.ts\"],\"assertionRefs\":[{\"file\":\"src/main/pty/shell-startup/shell-startup-output-scanner.test.ts\",\"assertions\":[\"Fish bracketed-paste output stays byte-exact across marker and ESC chunk splits\",\"every byte after readiness is preserved across every chunk boundary, even when it resembles an identity marker\",\"pre-ready identity and readiness markers strip across every chunk boundary without reordering prompt output\",\"incomplete scanner prefixes drain in byte order\"]},{\"file\":\"tests/e2e/paired-startup-exec-readiness.spec.ts\",\"assertions\":[\"a headed desktop owner and paired client recover startup exec on one stable owning PTY\",\"an isolated headless orca serve owner provides the same exact-once output and input contract\"]}]}" ], "demotionRule": "Keep experimental or demote if prompt fallback enters a normal, child, or line-init read; a non-shell executable triggers prompt fallback; the identified shell PID is not foreground; delivery duplicates; ordinary startup output spawns probes; probe attempts exceed four; or the focused gate flakes without an identified harness defect." }, @@ -4695,7 +4699,7 @@ "providers": ["local", "remote-runtime", "ssh", "wsl"], "coveredPlatforms": ["macos", "linux"], "coveredProviders": [], - "coverageNotes": "Audit5577 removes the entire src/main/runtime/browser-host/reconciliation/browser-host-page-placement-replacement.test.ts suite and its active selectors/assertion reference. The mocked replacement-page placement lifecycle sample alarms are intentionally retired without equivalent replacement or fresh gate evidence. Unrelated dated receipts retain their exact original scopes. Historical account follows: Audit5434 deletes the direct browser page inventory suite. URL-copy/duplicate-page preparation and whole-snapshot refusal for an unencodable page alarms are intentionally lost without equivalent replacement. Remove the deleted file from its compound command and testFiles. Other selectors/assertions and all three unrelated complete dated receipts retain their exact scope; no fresh full-gate execution is claimed. Historical prior account (preserved verbatim): Audit5429 trims paired browser-host composition and reconnect tests. Retire composition close-order/whenClosed wiring and explicit inventory-refresh reattachment/publication/cardinality alarms without equivalent replacement. Keep generation/recovery ownership and completed-mutation replay at their existing narrower scope. The removed composition close assertion is retired; surviving file commands remain valid selectors. No fresh full-gate execution or validation of reduced selectors is claimed. All three unrelated complete dated receipts retain their original exact fields and scope. Historical prior account (preserved verbatim): Audit4014 removes the complete browser client page command integration suite and its active command token, test selector and assertion reference. Its synthetic guest lifecycle still exercised real executor/dispatcher/Session/WebContents registry composition: navigation normalization, generation reclaim, spontaneous destruction inventory revocation, and exactly-once route/policy retirement alarms are intentionally lost. Electron guest navigation, proxy resolution and renderer lifecycle were supplied test ports; no equivalent replacement or fresh execution is claimed. The three unrelated active dated receipts and all prior historical strings remain unchanged. Historical prior account (preserved verbatim): Audit3381 intentionally removes the entire browser network tunnel protocol suite and active selectors/assertion. Static envelope/dispatch protocol alarms are lost without equivalent replacement. Remaining tunnel session and stream tests have narrower scopes. All three unrelated complete dated receipts are preserved verbatim with their original selectors; no fresh execution claimed. Module layout SSH policy: Retire the dynamic-forward launch argument/default inventory. The retained actual startup-cancellation entry case covers cancellation classification and termination/probe cleanup requests with supplied process/socket boundaries, not real SSH launch flags or live forwarding. Remove only the retired launch-flags assertion; unrelated dated receipts and their executed commands remain unchanged. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit1991: Remove the ordinary browser-host release/sub-cap and exact socket-close counter aliases. Retain the two actual admitted-device fairness and shared ask/browser/wait budget callbacks, which call server handlers with fake WebSockets and controlled pending RPCs. Preserve all3 unrelated dated receipts. No real browser placement or remote tunnel deployment is proved by this admission suite. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Delete the mocked browser placement mutation and projection suites and both prospective selectors. Preserve3 unrelated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1973: Remove stale production-registration and negotiated metadata aliases, compound refusal/cleanup aliases, isolated descriptor/route/memory/cleanup microcases. Retain exact negotiated command settlement, duplicate/conflict fencing, ready/replay ordering, superseded-connection cleanup, second-host refusal, ungranted target refusal, public connector redaction, revocation race and route replacement aliases within injected-port scope. Reconciliation and all3 unrelated dated receipts remain unchanged. Whole original changed dated receipts are retired, never narrowed or transferred. This metadata review claims no fresh execution, equivalent replacement, provider/PTY, live remote/mobile, rendered, cross-platform, soak or measured-budget result. Historical prior account (preserved verbatim): Audit1918 narrows browser-host-command-ledger-capacity: intentionally loses injected per-page/global cache expiry-count ceilings and authority/command/result cloning inventory alarms. Retain valid commands/testFile and the oversized-wire pre-admission and delivery-failure outstanding-outcome assertions, backed by unchanged retained real-ledger callbacks with supplied browser delivery. These survivors are not equivalent replacement coverage for the deleted cache/cloning examples. Existing three exact unrelated tunnel/wire receipts retain their original scope; no fresh reduced-gate, real browser/provider, native/platform, soak or measured-budget result is added. Historical prior account (preserved verbatim): Audit1900 reduces ws-outbound-backpressure-queue by seven authored definitions while retaining ten. Current source19 assertions still describe distinct direct/queued aggregate admission, cooperative drain ordering and aggregate claim release. Existing commands, testFiles and all three source19 assertions remain valid and unchanged. The affected2026-11-04 Linux44tests/4files/5.58s receipt is retired whole as historical evidence. The other three unchanged-selector browser receipts retain their exact original scope. Reduced selectors have no fresh integrated, physical-device, mixed-host, soak or measured-budget result. Historical prior account (preserved verbatim): Audit1709 removes low-value test definitions and retires affected assertion or execution-receipt claims without equivalent replacement coverage. Per-source reviews bound retained behavior and injected/native/remote limits. Unchanged assertions and receipts keep their original scope; gates lacking current active evidence are downgraded. Historical scope before this audit: Audit1687 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1686 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1571 removes mock forwarding, capability/schema inventories, private predicates, supplied error/result replays, and filesystem-mocked persistence checks without equivalent replacement claims. Retained changed tests also exercise real local permission-file reread, registry proxy rollback/credential retirement, site display recovery, and pending sender/credential/document admission with injected Electron/UI producers. Retained network tests exercise owned stream credit/cleanup, generation and retirement fences, real loopback proxy/SOCKS bytes and file-backed binding state. SSH/WSL/paired runtime, native sessions, authority producers and storage clears remain injected; simulated relaunch uses filesystem mocks. The unchanged profile-retirement suite was statically reviewed and not rerun. No actual SSH/WSL runtime, native Chromium jar deletion, durable process restart, remote DNS or external site proof. Receipts selecting changed tests are retired and unaffected receipts remain unchanged. Historical scope before this audit: Audit1563 retires mock cookie inventories, summary/flag/counter checks, historical replacement/replay narratives and setup-only alarms without equivalent replacement coverage. Retained changed cases exercise owned admission and cleanup, real staged-file lifetime, JSON/SQLite/WAL/schema compatibility, synthetic encryption and native Electron SameSite storage. Session/CDP/credential/write/renderer producers remain injected where recorded. Seven unchanged native definitions are not rerun locally; known stale registry-stub fixtures are not executable proof. Receipts selecting modified tests are retired; unaffected exact-selector receipts remain unchanged. Historical scope before this audit: Audit1559 removes mocked host/lease/reconciliation, event/flag/counter, forwarding, inventory and retry-budget alarms without equivalent replacement coverage. Retained cases establish owned promise, registry, rollback, admission and cleanup boundaries with injected Electron/renderer/host inputs; actual local sockets, file staging and Buffer collection are scoped in the PR. Receipts selecting modified tests are retired; unaffected exact-selector receipts remain historical evidence only. No live paired runtime, rendered browser/profile/TLS or device claim. Historical scope before this audit: Audit1401 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1340 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Deterministic protocol, registry, injected-socket, and loopback-listener tests cover strict framing, remote-DNS targets, exact destination-write and source-consumption credit, at most 256 streams per route with pending opens counted inside that cap, 1024 admitted opens per 10-second monotonic window, an 8 MiB per-route application-buffer ledger, shared 32 MiB browser-host and 128 MiB process ledgers across application copies, encrypted client queues, and native WebSocket bufferedAmount, bounded byte/claim/socket-source counts, a four-frame queued-drain quantum, authority epochs, exact host selection, one host per authenticated connection, four hosts per paired device, eight global browser-host polls with four per authenticated paired device, a shared ask/host ceiling that retains one quarter for waits, bounded initial and reconnect runtime_busy recovery, long-poll metering and disconnect abort, monotonic host/page/route generations without page tombstones, two-phase exact page retirement with cancellation, connection-owned cleanup, exact client revocation, stale and replaced fences, retired stream IDs, half-close and close ordering, SOCKS CONNECT, bind/close races, listener wildcard normalization, unsupported commands, unavailable routes, and raw/terminal binary-handler isolation. Page commands use a separately echoed v1 attach negotiation, exact authority/host/page generations, bounded command IDs and sequences, and bounded create/navigate payloads; legacy attaches still receive only the unchanged ready/revoked event shapes. A second optional reconciliation subprotocol gates bounded reclaim, close, and restore payloads behind exact attach/ready echo, complete inventory, command negotiation, reconnect authority, and command-result authority; the production client advertises it only with the matching command and inventory capabilities. Exact guest or app-renderer loss marks one page generation outcome-unknown, coalesces a bounded negotiated inventory reattach, closes or retires the dead generation, and allocates a fresh generation before URL restore; explicit close is not misclassified as a crash. Mixed-version mutation tests project hidden client pages before activate, close, split, reorder, and move-to-group admission, preserve hidden raw order slots, translate visible insertion indices, and project mutation snapshots. A production server orchestrator consumes each immutable inventory once, reserves target generations without exposing placement, emits only negotiated ledger commands, commits after exact completed proof, preserves unrelated and server placements, aborts an attempt when connection authority enters reconnect grace, and requires fresh inventory after failure or abort. The production client dispatcher additionally proves per-page FIFO execution, exact payload-matched duplicate replay, frozen command/result snapshots, a global retired-generation floor, transactional admission, bounded pages/active commands/queues/per-page and global result cache/concurrency, create dependency failure, cancellation, deduplicated retirement joining, and bounded close without late-result overwrite. The server ledger owns issue order and immutable command/result snapshots, bounds outstanding commands, active pages, and per-page/global replay caches, releases active-page capacity after an exact completed close while retaining bounded result replay, validates the shared wire payload before admission, requires live delivery and exact placement, authenticates results to the negotiated connection and paired lease, rejects gaps and conflicting replay, and fences outstanding outcomes at exact retirement. Negotiated command results reuse the authenticated attach socket through bounded nested JSON requests; exact ID routing, reverse-order replies, unknown and duplicate IDs, timeout teardown, serialization failure, aggregate queue accounting, acknowledgement validation, and the unchanged non-v1 path are deterministic. A stable local listener rejects CONNECT while offline or reconnecting, retains its address across replacement, requires a strictly increasing tunnel generation, ignores late superseded callbacks, propagates tunnel protocol failure to the route owner, and recycles exhausted stream IDs only after generation replacement. Reconnect uses the unchanged native v1 attach payload and capability pair; SSH descriptors alone add an execution-host capability and require a runtime-minted grant bound to the exact browser-host lease. Exact SSH provider epoch and connection generation fence ssh2 forwardOut and one non-interactive standalone system-SSH dynamic forward per route. Unit tests preserve domain-form SOCKS requests, sanitize remote errors, bound stderr, cancel startup, release timed-out and synchronously failed sockets, and release routes once. An ephemeral Docker sshd resolves a container-only domain and returns a unique HTTP marker through both ssh2 and the actual system-OpenSSH dynamic-forward adapter without touching the user's SSH files; authority loss fences the ssh2 route. The execution runtime charges route application bytes to the same per-host/process policy; its existing E2EE owner separately caps native outbound buffers process-wide. Production-registered browser-host and paired-runtime methods lease one exact host, prove attach, command delivery, and result settlement share one exact connection identity, then carry SOCKS and HTTP bytes over a dedicated E2EE socket to the fenced execution-host revision and prove route close destroys the destination socket. The production desktop adapter now composes one exact host per environment pairing revision with the page executor, current renderer selector, route Session/WebContents registries, and one reference-counted route per canonical execution-host key. Negotiated same-client control reconnect retains exact authority, placements, grants, dispatcher dedupe, executor guests, and listener addresses; it fences tunnels immediately, blocks route admission, reattaches command delivery only after ready, and replays unsettled commands without repeating completed mutations. Terminal release, replacement, legacy disconnect, and reconnect-grace expiry make only the exact host generation's client placements non-cancellable retirement-pending while retaining capacity until exact cleanup; reconnect grace preserves them. Environment replacement and app shutdown still serialize transport closure before page cleanup and force-close every remaining route. The production placement preparation starts the exact desktop adapter and advertises host/tunnel capabilities only when the paired Electron client is eligible. Node stream-internal high-water bytes, strict cross-route scheduling, and physical cross-platform evidence remain uncovered. The two Docker remote-only SSH browser routing journeys now run in the dedicated Linux ssh-browser-network-route CI job on full runs and their mapped source/test changes; 2 baseline and 6 repeated cases passed with no skips/retries on 2026-09-06. The removed retry-arithmetic and attach-request inventory suites are not current coverage; retained lease and composition suites exercise admission retry, cleanup, inventory negotiation, and reconnect behavior. Test-value audit1293 removes src/main/browser/network/tunnels/browser-network-tunnel-client-memory-budget.test.ts (4 authored cases). Their isolated assertions no longer run; surviving tests are not claimed as equivalent coverage. Fresh execution against the candidate SHA is required. Audit1302: src/main/browser/client-pages/lifecycle/browser-client-page-unavailability.test.ts: Every route/guest lifecycle/currentness/navigation/renderer/automation authority is supplied by fake callbacks, then unavailability listener is invoked manually and private inventory/mock calls are checked. No guest destruction, renderer disconnect or actual reconciliation/close consumer. Lose generation fence/reconcile-once/missing-renderer-close branch alarms; no equivalent replacement. Reduced selectors require fresh validation; prior full-suite receipts do not validate removed or changed coverage. No equivalent replacement or physical-provider claim. Audit1318: src/shared/remote-runtime/requests/remote-runtime-subscription-request.test.ts: Retain actual local encrypted WebSocket subscription concurrency routing when host replies out of order, plus an exception thrown by a real ws consumer callback being turned into a subscription error. Server is a test-shaped handshake/response producer using production crypto, not actual runtime host/auth authority or independent cryptographic oracle. Remove happy second-request duplicate, unknown/duplicate-ID branches, fixed32 capacity, serialization/capacity/timeouts and fake memory release/admission call-count scenarios; intentionally lose those alarms. Reduced selectors need fresh validation; historical full-suite receipts do not validate the changed coverage. No equivalent replacement or physical-provider claim. Audit1340: src/main/runtime/runtime-binary-message-router.test.ts removed. Connection mode conflict exceptions and one terminal/raw callback each. No equivalent replacement coverage is claimed. Audit1352: focused Linux unit selections validated on source head b638e07d395b76af3ba6b03761a1a0fe7e5e026e. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1360: focused Linux unit selections validated on source head 415c9cffc2d10024131ec4b6721767a22195de6d. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1371 removes the reconciliation protocol/capability echo inventory from browser-client-host-reconciliation.test.ts. The pending command result refusal without exact authority and later accepted acknowledgement callback remains byte-identical. The narrow negotiation echo alarm is intentionally lost; no equivalent browser/authenticated transport proof is claimed. Existing receipts with unchanged selectors retain only their original scope. Audit1401: src/main/browser/client-pages/lifecycle/browser-client-page-inventory.test.ts reduced. Loses deterministic equal-length URL compaction tie-breaking and reversed-input invariance alarm. No equivalent replacement coverage is claimed.", + "coverageNotes": "Audit5743 removes whole identity-scanner/browser retirement/RPC dispatch test suites from active selectors, accepting incremental OSC identity framing, in-memory page retirement generation fencing and spied-runtime SQL dispatch authority/rollback alarms without equivalent replacement or fresh execution. Remaining dated evidence keeps its exact independent selector scope. Historical prior account (preserved verbatim): Audit5577 removes the entire src/main/runtime/browser-host/reconciliation/browser-host-page-placement-replacement.test.ts suite and its active selectors/assertion reference. The mocked replacement-page placement lifecycle sample alarms are intentionally retired without equivalent replacement or fresh gate evidence. Unrelated dated receipts retain their exact original scopes. Historical account follows: Audit5434 deletes the direct browser page inventory suite. URL-copy/duplicate-page preparation and whole-snapshot refusal for an unencodable page alarms are intentionally lost without equivalent replacement. Remove the deleted file from its compound command and testFiles. Other selectors/assertions and all three unrelated complete dated receipts retain their exact scope; no fresh full-gate execution is claimed. Historical prior account (preserved verbatim): Audit5429 trims paired browser-host composition and reconnect tests. Retire composition close-order/whenClosed wiring and explicit inventory-refresh reattachment/publication/cardinality alarms without equivalent replacement. Keep generation/recovery ownership and completed-mutation replay at their existing narrower scope. The removed composition close assertion is retired; surviving file commands remain valid selectors. No fresh full-gate execution or validation of reduced selectors is claimed. All three unrelated complete dated receipts retain their original exact fields and scope. Historical prior account (preserved verbatim): Audit4014 removes the complete browser client page command integration suite and its active command token, test selector and assertion reference. Its synthetic guest lifecycle still exercised real executor/dispatcher/Session/WebContents registry composition: navigation normalization, generation reclaim, spontaneous destruction inventory revocation, and exactly-once route/policy retirement alarms are intentionally lost. Electron guest navigation, proxy resolution and renderer lifecycle were supplied test ports; no equivalent replacement or fresh execution is claimed. The three unrelated active dated receipts and all prior historical strings remain unchanged. Historical prior account (preserved verbatim): Audit3381 intentionally removes the entire browser network tunnel protocol suite and active selectors/assertion. Static envelope/dispatch protocol alarms are lost without equivalent replacement. Remaining tunnel session and stream tests have narrower scopes. All three unrelated complete dated receipts are preserved verbatim with their original selectors; no fresh execution claimed. Module layout SSH policy: Retire the dynamic-forward launch argument/default inventory. The retained actual startup-cancellation entry case covers cancellation classification and termination/probe cleanup requests with supplied process/socket boundaries, not real SSH launch flags or live forwarding. Remove only the retired launch-flags assertion; unrelated dated receipts and their executed commands remain unchanged. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit1991: Remove the ordinary browser-host release/sub-cap and exact socket-close counter aliases. Retain the two actual admitted-device fairness and shared ask/browser/wait budget callbacks, which call server handlers with fake WebSockets and controlled pending RPCs. Preserve all3 unrelated dated receipts. No real browser placement or remote tunnel deployment is proved by this admission suite. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Delete the mocked browser placement mutation and projection suites and both prospective selectors. Preserve3 unrelated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1973: Remove stale production-registration and negotiated metadata aliases, compound refusal/cleanup aliases, isolated descriptor/route/memory/cleanup microcases. Retain exact negotiated command settlement, duplicate/conflict fencing, ready/replay ordering, superseded-connection cleanup, second-host refusal, ungranted target refusal, public connector redaction, revocation race and route replacement aliases within injected-port scope. Reconciliation and all3 unrelated dated receipts remain unchanged. Whole original changed dated receipts are retired, never narrowed or transferred. This metadata review claims no fresh execution, equivalent replacement, provider/PTY, live remote/mobile, rendered, cross-platform, soak or measured-budget result. Historical prior account (preserved verbatim): Audit1918 narrows browser-host-command-ledger-capacity: intentionally loses injected per-page/global cache expiry-count ceilings and authority/command/result cloning inventory alarms. Retain valid commands/testFile and the oversized-wire pre-admission and delivery-failure outstanding-outcome assertions, backed by unchanged retained real-ledger callbacks with supplied browser delivery. These survivors are not equivalent replacement coverage for the deleted cache/cloning examples. Existing three exact unrelated tunnel/wire receipts retain their original scope; no fresh reduced-gate, real browser/provider, native/platform, soak or measured-budget result is added. Historical prior account (preserved verbatim): Audit1900 reduces ws-outbound-backpressure-queue by seven authored definitions while retaining ten. Current source19 assertions still describe distinct direct/queued aggregate admission, cooperative drain ordering and aggregate claim release. Existing commands, testFiles and all three source19 assertions remain valid and unchanged. The affected2026-11-04 Linux44tests/4files/5.58s receipt is retired whole as historical evidence. The other three unchanged-selector browser receipts retain their exact original scope. Reduced selectors have no fresh integrated, physical-device, mixed-host, soak or measured-budget result. Historical prior account (preserved verbatim): Audit1709 removes low-value test definitions and retires affected assertion or execution-receipt claims without equivalent replacement coverage. Per-source reviews bound retained behavior and injected/native/remote limits. Unchanged assertions and receipts keep their original scope; gates lacking current active evidence are downgraded. Historical scope before this audit: Audit1687 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1686 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1571 removes mock forwarding, capability/schema inventories, private predicates, supplied error/result replays, and filesystem-mocked persistence checks without equivalent replacement claims. Retained changed tests also exercise real local permission-file reread, registry proxy rollback/credential retirement, site display recovery, and pending sender/credential/document admission with injected Electron/UI producers. Retained network tests exercise owned stream credit/cleanup, generation and retirement fences, real loopback proxy/SOCKS bytes and file-backed binding state. SSH/WSL/paired runtime, native sessions, authority producers and storage clears remain injected; simulated relaunch uses filesystem mocks. The unchanged profile-retirement suite was statically reviewed and not rerun. No actual SSH/WSL runtime, native Chromium jar deletion, durable process restart, remote DNS or external site proof. Receipts selecting changed tests are retired and unaffected receipts remain unchanged. Historical scope before this audit: Audit1563 retires mock cookie inventories, summary/flag/counter checks, historical replacement/replay narratives and setup-only alarms without equivalent replacement coverage. Retained changed cases exercise owned admission and cleanup, real staged-file lifetime, JSON/SQLite/WAL/schema compatibility, synthetic encryption and native Electron SameSite storage. Session/CDP/credential/write/renderer producers remain injected where recorded. Seven unchanged native definitions are not rerun locally; known stale registry-stub fixtures are not executable proof. Receipts selecting modified tests are retired; unaffected exact-selector receipts remain unchanged. Historical scope before this audit: Audit1559 removes mocked host/lease/reconciliation, event/flag/counter, forwarding, inventory and retry-budget alarms without equivalent replacement coverage. Retained cases establish owned promise, registry, rollback, admission and cleanup boundaries with injected Electron/renderer/host inputs; actual local sockets, file staging and Buffer collection are scoped in the PR. Receipts selecting modified tests are retired; unaffected exact-selector receipts remain historical evidence only. No live paired runtime, rendered browser/profile/TLS or device claim. Historical scope before this audit: Audit1401 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1340 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Deterministic protocol, registry, injected-socket, and loopback-listener tests cover strict framing, remote-DNS targets, exact destination-write and source-consumption credit, at most 256 streams per route with pending opens counted inside that cap, 1024 admitted opens per 10-second monotonic window, an 8 MiB per-route application-buffer ledger, shared 32 MiB browser-host and 128 MiB process ledgers across application copies, encrypted client queues, and native WebSocket bufferedAmount, bounded byte/claim/socket-source counts, a four-frame queued-drain quantum, authority epochs, exact host selection, one host per authenticated connection, four hosts per paired device, eight global browser-host polls with four per authenticated paired device, a shared ask/host ceiling that retains one quarter for waits, bounded initial and reconnect runtime_busy recovery, long-poll metering and disconnect abort, monotonic host/page/route generations without page tombstones, two-phase exact page retirement with cancellation, connection-owned cleanup, exact client revocation, stale and replaced fences, retired stream IDs, half-close and close ordering, SOCKS CONNECT, bind/close races, listener wildcard normalization, unsupported commands, unavailable routes, and raw/terminal binary-handler isolation. Page commands use a separately echoed v1 attach negotiation, exact authority/host/page generations, bounded command IDs and sequences, and bounded create/navigate payloads; legacy attaches still receive only the unchanged ready/revoked event shapes. A second optional reconciliation subprotocol gates bounded reclaim, close, and restore payloads behind exact attach/ready echo, complete inventory, command negotiation, reconnect authority, and command-result authority; the production client advertises it only with the matching command and inventory capabilities. Exact guest or app-renderer loss marks one page generation outcome-unknown, coalesces a bounded negotiated inventory reattach, closes or retires the dead generation, and allocates a fresh generation before URL restore; explicit close is not misclassified as a crash. Mixed-version mutation tests project hidden client pages before activate, close, split, reorder, and move-to-group admission, preserve hidden raw order slots, translate visible insertion indices, and project mutation snapshots. A production server orchestrator consumes each immutable inventory once, reserves target generations without exposing placement, emits only negotiated ledger commands, commits after exact completed proof, preserves unrelated and server placements, aborts an attempt when connection authority enters reconnect grace, and requires fresh inventory after failure or abort. The production client dispatcher additionally proves per-page FIFO execution, exact payload-matched duplicate replay, frozen command/result snapshots, a global retired-generation floor, transactional admission, bounded pages/active commands/queues/per-page and global result cache/concurrency, create dependency failure, cancellation, deduplicated retirement joining, and bounded close without late-result overwrite. The server ledger owns issue order and immutable command/result snapshots, bounds outstanding commands, active pages, and per-page/global replay caches, releases active-page capacity after an exact completed close while retaining bounded result replay, validates the shared wire payload before admission, requires live delivery and exact placement, authenticates results to the negotiated connection and paired lease, rejects gaps and conflicting replay, and fences outstanding outcomes at exact retirement. Negotiated command results reuse the authenticated attach socket through bounded nested JSON requests; exact ID routing, reverse-order replies, unknown and duplicate IDs, timeout teardown, serialization failure, aggregate queue accounting, acknowledgement validation, and the unchanged non-v1 path are deterministic. A stable local listener rejects CONNECT while offline or reconnecting, retains its address across replacement, requires a strictly increasing tunnel generation, ignores late superseded callbacks, propagates tunnel protocol failure to the route owner, and recycles exhausted stream IDs only after generation replacement. Reconnect uses the unchanged native v1 attach payload and capability pair; SSH descriptors alone add an execution-host capability and require a runtime-minted grant bound to the exact browser-host lease. Exact SSH provider epoch and connection generation fence ssh2 forwardOut and one non-interactive standalone system-SSH dynamic forward per route. Unit tests preserve domain-form SOCKS requests, sanitize remote errors, bound stderr, cancel startup, release timed-out and synchronously failed sockets, and release routes once. An ephemeral Docker sshd resolves a container-only domain and returns a unique HTTP marker through both ssh2 and the actual system-OpenSSH dynamic-forward adapter without touching the user's SSH files; authority loss fences the ssh2 route. The execution runtime charges route application bytes to the same per-host/process policy; its existing E2EE owner separately caps native outbound buffers process-wide. Production-registered browser-host and paired-runtime methods lease one exact host, prove attach, command delivery, and result settlement share one exact connection identity, then carry SOCKS and HTTP bytes over a dedicated E2EE socket to the fenced execution-host revision and prove route close destroys the destination socket. The production desktop adapter now composes one exact host per environment pairing revision with the page executor, current renderer selector, route Session/WebContents registries, and one reference-counted route per canonical execution-host key. Negotiated same-client control reconnect retains exact authority, placements, grants, dispatcher dedupe, executor guests, and listener addresses; it fences tunnels immediately, blocks route admission, reattaches command delivery only after ready, and replays unsettled commands without repeating completed mutations. Terminal release, replacement, legacy disconnect, and reconnect-grace expiry make only the exact host generation's client placements non-cancellable retirement-pending while retaining capacity until exact cleanup; reconnect grace preserves them. Environment replacement and app shutdown still serialize transport closure before page cleanup and force-close every remaining route. The production placement preparation starts the exact desktop adapter and advertises host/tunnel capabilities only when the paired Electron client is eligible. Node stream-internal high-water bytes, strict cross-route scheduling, and physical cross-platform evidence remain uncovered. The two Docker remote-only SSH browser routing journeys now run in the dedicated Linux ssh-browser-network-route CI job on full runs and their mapped source/test changes; 2 baseline and 6 repeated cases passed with no skips/retries on 2026-09-06. The removed retry-arithmetic and attach-request inventory suites are not current coverage; retained lease and composition suites exercise admission retry, cleanup, inventory negotiation, and reconnect behavior. Test-value audit1293 removes src/main/browser/network/tunnels/browser-network-tunnel-client-memory-budget.test.ts (4 authored cases). Their isolated assertions no longer run; surviving tests are not claimed as equivalent coverage. Fresh execution against the candidate SHA is required. Audit1302: src/main/browser/client-pages/lifecycle/browser-client-page-unavailability.test.ts: Every route/guest lifecycle/currentness/navigation/renderer/automation authority is supplied by fake callbacks, then unavailability listener is invoked manually and private inventory/mock calls are checked. No guest destruction, renderer disconnect or actual reconciliation/close consumer. Lose generation fence/reconcile-once/missing-renderer-close branch alarms; no equivalent replacement. Reduced selectors require fresh validation; prior full-suite receipts do not validate removed or changed coverage. No equivalent replacement or physical-provider claim. Audit1318: src/shared/remote-runtime/requests/remote-runtime-subscription-request.test.ts: Retain actual local encrypted WebSocket subscription concurrency routing when host replies out of order, plus an exception thrown by a real ws consumer callback being turned into a subscription error. Server is a test-shaped handshake/response producer using production crypto, not actual runtime host/auth authority or independent cryptographic oracle. Remove happy second-request duplicate, unknown/duplicate-ID branches, fixed32 capacity, serialization/capacity/timeouts and fake memory release/admission call-count scenarios; intentionally lose those alarms. Reduced selectors need fresh validation; historical full-suite receipts do not validate the changed coverage. No equivalent replacement or physical-provider claim. Audit1340: src/main/runtime/runtime-binary-message-router.test.ts removed. Connection mode conflict exceptions and one terminal/raw callback each. No equivalent replacement coverage is claimed. Audit1352: focused Linux unit selections validated on source head b638e07d395b76af3ba6b03761a1a0fe7e5e026e. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1360: focused Linux unit selections validated on source head 415c9cffc2d10024131ec4b6721767a22195de6d. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1371 removes the reconciliation protocol/capability echo inventory from browser-client-host-reconciliation.test.ts. The pending command result refusal without exact authority and later accepted acknowledgement callback remains byte-identical. The narrow negotiation echo alarm is intentionally lost; no equivalent browser/authenticated transport proof is claimed. Existing receipts with unchanged selectors retain only their original scope. Audit1401: src/main/browser/client-pages/lifecycle/browser-client-page-inventory.test.ts reduced. Loses deterministic equal-length URL compaction tie-breaking and reversed-input invariance alarm. No equivalent replacement coverage is claimed.", "motivatingLinks": [ "https://linear.app/stably/issue/STA-4150/refactor-remote-browser-to-client-hosted-electron-webviews" ], @@ -4703,7 +4707,7 @@ "oracle": "Audit5434 deletes the direct browser page inventory suite. URL-copy/duplicate-page preparation and whole-snapshot refusal for an unencodable page alarms are intentionally lost without equivalent replacement. Remove the deleted file from its compound command and testFiles. Other selectors/assertions and all three unrelated complete dated receipts retain their exact scope; no fresh full-gate execution is claimed. Historical prior account (preserved verbatim): Audit5429 trims paired browser-host composition and reconnect tests. Retire composition close-order/whenClosed wiring and explicit inventory-refresh reattachment/publication/cardinality alarms without equivalent replacement. Keep generation/recovery ownership and completed-mutation replay at their existing narrower scope. The removed composition close assertion is retired; surviving file commands remain valid selectors. No fresh full-gate execution or validation of reduced selectors is claimed. All three unrelated complete dated receipts retain their original exact fields and scope. Historical prior account (preserved verbatim): Audit4014 removes the complete browser client page command integration suite and its active command token, test selector and assertion reference. Its synthetic guest lifecycle still exercised real executor/dispatcher/Session/WebContents registry composition: navigation normalization, generation reclaim, spontaneous destruction inventory revocation, and exactly-once route/policy retirement alarms are intentionally lost. Electron guest navigation, proxy resolution and renderer lifecycle were supplied test ports; no equivalent replacement or fresh execution is claimed. The three unrelated active dated receipts and all prior historical strings remain unchanged. Historical prior account (preserved verbatim): Test-value audit3842 retires four ws-outbound queue unit probes: direct empty-queue send failure, configured drain quantum/zero-delay reschedule, injected aggregate claim/release accounting, and supplied unwritable drain guard. Their exact alarms are intentionally lost; retained queue behaviors are not equivalent replacements. All source-file commands remain valid. No fresh execution or measured-budget evidence is claimed. Historical prior account (preserved verbatim): Test-value audit removes the retired suite and its active selectors/assertions. Retire the paired-host late subscription smoke: it checks a mocked close count and startup rejection, without remote unsubscribe or successor outcomes. Audit3381 intentionally removes the entire browser network tunnel protocol suite and active selectors/assertion. Static envelope/dispatch protocol alarms are lost without equivalent replacement. Remaining tunnel session and stream tests have narrower scopes. All three unrelated complete dated receipts are preserved verbatim with their original selectors; no fresh execution claimed. Module layout SSH policy: Retire the dynamic-forward launch argument/default inventory. The retained actual startup-cancellation entry case covers cancellation classification and termination/probe cleanup requests with supplied process/socket boundaries, not real SSH launch flags or live forwarding. Remove only the retired launch-flags assertion; unrelated dated receipts and their executed commands remain unchanged. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit1991: Remove the ordinary browser-host release/sub-cap and exact socket-close counter aliases. Retain the two actual admitted-device fairness and shared ask/browser/wait budget callbacks, which call server handlers with fake WebSockets and controlled pending RPCs. Preserve all3 unrelated dated receipts. No real browser placement or remote tunnel deployment is proved by this admission suite. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Delete the mocked browser placement mutation and projection suites and both prospective selectors. Preserve3 unrelated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1973: Remove stale production-registration and negotiated metadata aliases, compound refusal/cleanup aliases, isolated descriptor/route/memory/cleanup microcases. Retain exact negotiated command settlement, duplicate/conflict fencing, ready/replay ordering, superseded-connection cleanup, second-host refusal, ungranted target refusal, public connector redaction, revocation race and route replacement aliases within injected-port scope. Reconciliation and all3 unrelated dated receipts remain unchanged. Whole original changed dated receipts are retired, never narrowed or transferred. This metadata review claims no fresh execution, equivalent replacement, provider/PTY, live remote/mobile, rendered, cross-platform, soak or measured-budget result. Historical prior account (preserved verbatim): Audit1918 narrows browser-host-command-ledger-capacity: intentionally loses injected per-page/global cache expiry-count ceilings and authority/command/result cloning inventory alarms. Retain valid commands/testFile and the oversized-wire pre-admission and delivery-failure outstanding-outcome assertions, backed by unchanged retained real-ledger callbacks with supplied browser delivery. These survivors are not equivalent replacement coverage for the deleted cache/cloning examples. Existing three exact unrelated tunnel/wire receipts retain their original scope; no fresh reduced-gate, real browser/provider, native/platform, soak or measured-budget result is added. Historical prior account (preserved verbatim): Audit1900 reduces ws-outbound-backpressure-queue by seven authored definitions while retaining ten. Current source19 assertions still describe distinct direct/queued aggregate admission, cooperative drain ordering and aggregate claim release. Existing commands, testFiles and all three source19 assertions remain valid and unchanged. The affected2026-11-04 Linux44tests/4files/5.58s receipt is retired whole as historical evidence. The other three unchanged-selector browser receipts retain their exact original scope. Reduced selectors have no fresh integrated, physical-device, mixed-host, soak or measured-budget result. Historical prior account (preserved verbatim): Audit1709 retires changed-source assertion and execution scope without equivalent replacement coverage. Existing unchanged-selector receipts remain scoped to their original sources. Historical prior-source oracle: Audit1687 retires changed-source assertion and execution scope without equivalent replacement coverage. Existing unchanged-selector receipts remain scoped to their original sources. Historical prior-source oracle: Audit1686 retires changed-source assertion and execution scope without equivalent replacement coverage. Existing unchanged-selector receipts remain scoped to their original sources. Historical prior-source oracle: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Attach two browser hosts and require unqualified selection to fail ambiguous while exact selection succeeds. Reject a second identity on one connection and a fifth identity for one paired device, release one exact lease, then admit its replacement without starving another device. Admit four hosts from one authenticated device and a host from a second, reject the first device's fifth host, and release only the first device's exact counters while the second remains live. Fill asks and hosts to their shared ceiling, retain a quarter of the total budget for ordinary waits, close both sockets, and prove every global, class, and device counter releases. Reject one initial host attach with the unchanged runtime_busy response, then require bounded client-specific jitter to attach when capacity returns; repeated rejection and explicit close must release every timer and subscription. Replace one same-device connection, require the old subscription and route to fence, then prove late old cleanup leaves the new generation live. Mint an exact execution-host grant, reject a different key, prove late old grant cleanup leaves its replacement, and invalidate every grant with lease replacement. Reject client-to-client, client-to-server, server-to-server, and server-to-client placement overwrite until exact retirement. Begin retirement once idempotently, reject client use and every replacement while pending, cancel the exact token to restore the same placement, and reject delayed cancellation or completion after a newer retirement begins. On explicit release, replacement, legacy disconnect, and reconnect-grace expiry, require only the exact host generation's client placements to become non-cancellable retirement-pending before lease settlement; preserve negotiated grace, other hosts, server placements, replacements, and capacity until exact completion. Complete only the exact pending token, retain capacity until completion, and require a reused client page ID to receive a higher global generation without retaining a tombstone. Require a client page through the exact runtime, epoch, host, and page tuple; reject every mismatch, released or replaced leases, retirement-pending pages, retired pages, server placements, invalid identities, and the 257th live placement. Admit 1024 opens in one monotonic 10-second window and reject the 1025th until the window expires. Fill 8 MiB across destination-to-client queues and separately across unsettled client-to-destination writes, release one exact retired stream, admit one replacement, and require the next byte claim to close the route without stale-callback or reentrant-close underflow. Across multiple routes, charge application copies, encrypted queue entries, and dynamic native socket bytes to one 32 MiB browser-host and 128 MiB process ceiling; reject zero-byte claim/socket-source floods, fence released leases, synchronously release JavaScript queue claims while retaining native claims through exact socket close, and yield a parked queue after four frames without reordering. Route nested responses by exact ID under reordering, reject unknown and duplicate IDs, cap pending requests and queued bytes, and tear down every concurrent waiter once on timeout or close. Drive one real paired attach, command, and result through one exact connection ID; reject missing send support and malformed or wrong-runtime acknowledgements while preserving old non-v1 attaches. Drop an authenticated transport, require the same listener to reject CONNECT before and during reconnect, attach the exact existing native v1 payload and capability pair to a strictly newer generation, ignore late old callbacks, and roll an exhausted stream-ID ledger only by replacing the generation. Require SSH descriptors to add an execution-host capability and exact grant, reject missing grants and stale provider authority before resolver or binary registration, pass exact domains to ssh2 and system-SSH SOCKS without local resolution, sanitize connector diagnostics, and close every stream and standalone route process once on timeout, synchronous failure, or rotation. Drive the accepted lease through real paired E2EE native SOCKS-to-HTTP and ephemeral Docker ssh2 remote-only DNS journeys, then exercise exact frame, credit, half-close, stale-stream, remote-DNS, unsupported-command, offline, and teardown assertions.", "commands": [ "pnpm exec vitest run --config config/vitest.config.ts src/main/browser/routing/guest-authority/browser-route-webcontents-registry.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-reconnect.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts src/main/runtime/browser/client-pages/runtime-browser-client-page-recovery.test.ts", - "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/commands/browser-host-command-ledger.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/methods/browser/browser-client-host-reconciliation.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/browser/client-pages/execution/browser-client-page-command-executor.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser/browser-client-host.test.ts", @@ -4729,7 +4733,6 @@ "testFiles": [ "src/main/browser/routing/guest-authority/browser-route-webcontents-registry.test.ts", "src/main/runtime/browser/client-pages/runtime-browser-client-page-recovery.test.ts", - "src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts", "src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts", "src/main/runtime/browser-host/commands/browser-host-command-ledger.test.ts", "src/main/runtime/browser-host/commands/browser-host-command-ledger-capacity.test.ts", @@ -5090,7 +5093,8 @@ "Test-value audit3842 removes four authored/four finite outbound queue probes and the count80 row from each of three inbound queue declarations (zero extra authored removals, three extra finite removals). Direct fast-path failure, synthetic work quantum, injected aggregate callback accounting, supplied unwritable guard, and repeated eighty-payload alarms are accepted losses without equivalent replacement claims. Remaining inbound count8 cases retain actual WeakRef/GC and FIFO/rejection observations. All three unrelated dated gate receipts retain their original command/results/counts and are not fresh validation of changed sources.", "Audit5429 removes composition close-order and explicit reconnect-refresh alarms. No replacement equivalence or full-gate execution. Retired assertion: fails closed without racing page cleanup when handlers do not settle", "Audit5434 retires browser-client-page-inventory.test.ts preparation/duplicate/optional-snapshot refusal alarms without equivalent replacement.", - "Audit5577 exact prior command before retired suite selector removal: pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement-replacement.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts" + "Audit5577 exact prior command before retired suite selector removal: pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement-replacement.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts", + "Audit5743 exact original active selector fields before whole suite removal (historical, not current coverage): {\"commands\":[\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/routing/guest-authority/browser-route-webcontents-registry.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-reconnect.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts src/main/runtime/browser/client-pages/runtime-browser-client-page-recovery.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/commands/browser-host-command-ledger.test.ts src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/methods/browser/browser-client-host-reconciliation.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/client-pages/execution/browser-client-page-command-executor.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser/browser-client-host.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/client-pages/lifecycle/browser-client-page-reconciliation-adapters.test.ts src/main/browser/routing/sessions/browser-route-prepared-page-rekey.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/network/tunnels/browser-network-tunnel-session.test.ts src/main/browser/network/tunnels/remote-browser-socks-server.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/network/tunnels/browser-network-tunnel-client.test.ts src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts src/main/runtime/rpc/methods/browser/browser-network-tunnel.test.ts src/main/runtime/browser/network/browser-network-tunnel-paired-runtime.integration.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/network/tunnels/browser-network-tunnel-outbound-memory-budget.test.ts src/main/browser/network/tunnels/browser-network-tunnel-session-aggregate-memory.test.ts src/shared/ws-outbound-backpressure-queue.test.ts src/shared/remote-runtime/remote-runtime-client.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/shared/ws-outbound-backpressure-queue.test.ts src/shared/remote-runtime/remote-runtime-client.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser/browser-client-host.test.ts src/main/runtime/rpc/methods/browser/browser-network-tunnel.test.ts src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts src/main/runtime/browser/network/browser-network-tunnel-paired-runtime.integration.test.ts src/main/browser/network/tunnels/browser-network-tunnel-client.test.ts src/main/browser/network/tunnels/browser-network-tunnel-session.test.ts src/main/browser/network/tunnels/browser-network-tunnel-session-aggregate-memory.test.ts src/main/browser/network/tunnels/browser-network-tunnel-outbound-memory-budget.test.ts src/main/browser/network/tunnels/remote-browser-socks-server.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser/browser-client-host.test.ts src/main/runtime/rpc/methods/browser/browser-network-tunnel.test.ts src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts src/main/runtime/browser/network/browser-network-tunnel-paired-runtime.integration.test.ts src/main/browser/network/tunnels/browser-network-tunnel-client.test.ts src/main/browser/network/tunnels/browser-network-tunnel-session.test.ts src/main/browser/network/tunnels/remote-browser-socks-server.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/shared/remote-runtime/remote-runtime-client.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/shared/remote-runtime/requests/remote-runtime-subscription-request.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/client-hosts/commands/browser-client-host-command-dispatcher.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/client-hosts/commands/browser-client-host-command-dispatcher.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-reconnect.test.ts src/main/browser/client-hosts/commands/browser-client-host-command-dispatcher.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/network/client-routes/browser-client-network-route-registry.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-reconnect.test.ts src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts src/main/runtime/browser-host/commands/browser-host-command-ledger.test.ts src/main/runtime/browser-host/commands/browser-host-command-ledger-capacity.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser/browser-client-host.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/network/client-routes/browser-client-network-route-registry.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-reconnect.test.ts src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts src/main/runtime/browser-host/commands/browser-host-command-ledger.test.ts src/main/runtime/browser-host/commands/browser-host-command-ledger-capacity.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser/browser-client-host.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/network/client-routes/browser-client-network-route-registry.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-registry.test.ts src/main/browser/client-pages/execution/browser-client-page-command-executor.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/commands/browser-host-command-ledger.test.ts src/main/runtime/browser-host/commands/browser-host-command-ledger-capacity.test.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser/browser-client-host.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts src/main/browser/network/execution-routes/browser-network-deferred-socket.test.ts src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts src/main/runtime/rpc/methods/browser/browser-network-tunnel.test.ts src/main/browser/network/execution-routes/ssh-browser-network-execution-route.test.ts src/main/browser/network/tunnels/system-ssh-socks-client-socket.test.ts src/main/ssh/system-transport/forwarding/system-ssh-dynamic-forward-process.test.ts src/main/ssh/system-transport/forwarding/system-ssh-forward-process.test.ts src/main/ssh/system-transport/system-ssh-operations.test.ts src/main/ssh/port-forwarding/ssh-port-forward.test.ts\",\"ORCA_RUN_DOCKER_SSH_BROWSER_E2E=1 pnpm exec vitest run --config config/vitest.config.ts tests/e2e/ssh-browser-network-execution-route.docker.unit.test.ts\",\"ORCA_RUN_DOCKER_SSH_BROWSER_E2E=1 node_modules/.bin/vitest run --config config/vitest.config.ts tests/e2e/ssh-browser-network-execution-route.docker.unit.test.ts\"],\"testFiles\":[\"src/main/browser/routing/guest-authority/browser-route-webcontents-registry.test.ts\",\"src/main/runtime/browser/client-pages/runtime-browser-client-page-recovery.test.ts\",\"src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts\",\"src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts\",\"src/main/runtime/browser-host/commands/browser-host-command-ledger.test.ts\",\"src/main/runtime/browser-host/commands/browser-host-command-ledger-capacity.test.ts\",\"src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts\",\"src/main/runtime/rpc/methods/browser/browser-client-host.test.ts\",\"src/main/runtime/rpc/methods/browser/browser-client-host-reconciliation.test.ts\",\"src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-reconnect.test.ts\",\"src/main/browser/network/client-routes/browser-client-network-route-registry.test.ts\",\"src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts\",\"src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-registry.test.ts\",\"src/main/browser/client-pages/execution/browser-client-page-command-executor.test.ts\",\"src/main/browser/client-pages/lifecycle/browser-client-page-reconciliation-adapters.test.ts\",\"src/main/browser/routing/sessions/browser-route-prepared-page-rekey.test.ts\",\"src/main/browser/client-hosts/commands/browser-client-host-command-dispatcher.test.ts\",\"src/main/browser/network/tunnels/browser-network-tunnel-session.test.ts\",\"src/main/browser/network/tunnels/browser-network-tunnel-session-aggregate-memory.test.ts\",\"src/main/browser/network/tunnels/browser-network-tunnel-client.test.ts\",\"src/main/browser/network/tunnels/browser-network-tunnel-outbound-memory-budget.test.ts\",\"src/main/browser/network/execution-routes/browser-network-deferred-socket.test.ts\",\"src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts\",\"src/main/browser/network/execution-routes/ssh-browser-network-execution-route.test.ts\",\"src/main/browser/network/tunnels/system-ssh-socks-client-socket.test.ts\",\"src/main/ssh/system-transport/forwarding/system-ssh-dynamic-forward-process.test.ts\",\"src/main/ssh/port-forwarding/ssh-port-forward.test.ts\",\"src/main/browser/network/tunnels/remote-browser-socks-server.test.ts\",\"src/main/runtime/rpc/methods/browser/browser-network-tunnel.test.ts\",\"src/main/runtime/browser/network/browser-network-tunnel-paired-runtime.integration.test.ts\",\"src/shared/remote-runtime/remote-runtime-client.test.ts\",\"src/shared/remote-runtime/requests/remote-runtime-subscription-request.test.ts\",\"src/shared/ws-outbound-backpressure-queue.test.ts\",\"tests/e2e/ssh-browser-network-execution-route.docker.unit.test.ts\"],\"assertionRefs\":[{\"file\":\"src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-reconnect.test.ts\",\"assertions\":[\"an acknowledged mutation replay uses the preserved dispatcher result without rerunning its handler\"]},{\"file\":\"src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-composition.test.ts\",\"assertions\":[\"waits for old handlers and ignores their late callbacks before replacement\",\"keeps one command gate across repeated loss while fencing stale route recovery\"]},{\"file\":\"src/main/browser/client-pages/execution/browser-client-page-command-executor.test.ts\",\"assertions\":[\"joins concurrent cleanup callers and holds resources until exact native destruction\"]},{\"file\":\"src/main/browser/client-pages/lifecycle/browser-client-page-reconciliation-adapters.test.ts\",\"assertions\":[\"destroys a guest rekeyed during an authority transition instead of granting navigation\"]},{\"file\":\"src/main/browser/routing/sessions/browser-route-prepared-page-rekey.test.ts\",\"assertions\":[\"prepared authority rekeys without changing its opaque capability token\",\"stale, occupied, cross-page, and cross-renderer targets fail without mutation\"]},{\"file\":\"src/main/browser/client-hosts/lifecycle/paired-runtime-browser-client-host-registry.test.ts\",\"assertions\":[\"keeps a failed authority transition tombstoned until cleanup settles\"]},{\"file\":\"src/main/browser/network/client-routes/browser-client-network-route-registry.test.ts\",\"assertions\":[\"retains one exact route until its final page releases it\",\"keeps an ambiguously closed route fenced until final registry cleanup\",\"retires old authority routes without destroying them before exact page cleanup\",\"aborts a stale route recovery without retaining its retry timer\",\"fails bounded recovery after one route exhausts grace without leaking timers\",\"mints a fresh route for a retain that lands while the previous one is closing\",\"waits for a route still closing before reporting retirement\",\"rejects a retain the moment its signal aborts mid-startup\",\"refuses a retain that waited out a closing route onto a retired registry\",\"reports a failed final cleanup to an awaiting retirement\"]},{\"file\":\"src/main/browser/client-hosts/commands/browser-client-host-command-dispatcher.test.ts\",\"assertions\":[\"keeps a timed-out retirement fenced until its handler actually settles\",\"bounds close while canceling queued and non-cooperative handlers\"]},{\"file\":\"src/main/runtime/browser-host/commands/browser-host-command-ledger-capacity.test.ts\",\"assertions\":[\"oversized wire payloads fail before page, sequence, or delivery admission\",\"new issue delivery failure closes the ledger and fences every outstanding outcome\"]},{\"file\":\"src/main/runtime/rpc/methods/browser/browser-client-host.test.ts\",\"assertions\":[\"negotiated exact reattach emits ready before replaying the unchanged unsettled command\",\"reattach before old cleanup preserves the same authority and ends only the superseded connection stream\",\"only the exact negotiated connection, paired device, and live page placement can settle a server-owned command\",\"exact duplicate results are idempotent while conflicts and stale or retired placement fail closed\",\"a second browser-host identity on one authenticated connection is rejected\"]},{\"file\":\"src/main/runtime/rpc/methods/browser/browser-client-host-reconciliation.test.ts\",\"assertions\":[\"command result settlement requires the exact negotiated reconciliation authority\"]},{\"file\":\"src/main/browser/network/tunnels/browser-network-tunnel-session.test.ts\",\"assertions\":[\"replenishes client credit only after the destination write settles\",\"keeps concurrent streams alive when late data arrives for a retired stream\",\"flushes credited destination bytes before close\",\"caps aggregate retained destination bytes and releases exact stream accounting\",\"caps unsettled destination writes and releases retirement exactly once\",\"releases queued bytes once when an accepted send closes reentrantly\"]},{\"file\":\"src/main/browser/network/tunnels/browser-network-tunnel-session-aggregate-memory.test.ts\",\"assertions\":[\"multiple execution-host routes share browser-host application-byte admission in both traffic directions\",\"route close releases aggregate claims exactly before stale destination-write callbacks\"]},{\"file\":\"src/main/browser/network/tunnels/browser-network-tunnel-client.test.ts\",\"assertions\":[\"preserves remote DNS and waits for an opened acknowledgement\",\"sends only credited bytes in bounded frames and replenishes consumed input\",\"ignores a retired stream frame but rejects a never-allocated stream ID\",\"never reuses stream IDs within one generation after its bounded ledger exhausts\",\"replenishes only bytes settled after the readable consumer takes them\",\"fails closed when pending tiny destination frames exceed the chunk cap\",\"drains data that precedes a remote close before retiring the socket\"]},{\"file\":\"src/main/browser/network/tunnels/browser-network-tunnel-outbound-memory-budget.test.ts\",\"assertions\":[\"application, encrypted-queue, and native socket bytes share one host ceiling\",\"distinct hosts share one process ceiling with exact release\",\"zero-byte claims, socket sources, hosts, and leases have independent bounds\",\"released leases cannot admit work and retained owners keep exact accounting alive\",\"unavailable native-buffer evidence fails closed until its exact source releases\"]},{\"file\":\"src/main/browser/network/tunnels/remote-browser-socks-server.test.ts\",\"assertions\":[\"domain CONNECT preserves the final execution-host DNS target\",\"unsupported commands and unavailable routes open no fallback destination\"]},{\"file\":\"src/main/runtime/rpc/methods/browser/browser-network-tunnel.test.ts\",\"assertions\":[\"ungranted or wrong-key SSH routes are rejected before resolver or binary registration\",\"connector diagnostics are mapped to a stable public error without local path disclosure\",\"grant revocation aborts connector startup immediately and cannot race through route admission\",\"the server allocates route generations and fences the replaced route\"]},{\"file\":\"src/main/browser/network/execution-routes/paired-runtime-browser-network-route.test.ts\",\"assertions\":[\"closes a subscription that resolves after route teardown\",\"settles startup when close follows subscription acquisition before readiness\",\"bounds the post-auth readiness wait\",\"binds and releases the exact browser-host outbound memory lease\",\"keeps one listener fail-closed and accepts an increasing replacement generation\",\"ignores late callbacks from a superseded transport\",\"recovers again after a second transport death\",\"rejects a non-increasing replacement generation and remains retryable\",\"fences a ready generation even when the replacement closes before its await resumes\",\"replaces the tunnel generation before recycling a bounded stream ID\"]},{\"file\":\"src/main/browser/network/execution-routes/browser-network-deferred-socket.test.ts\",\"assertions\":[\"destroy before source attachment emits one close and destroys a late source\",\"source close after destroy cannot emit duplicate wrapper close\"]},{\"file\":\"src/main/browser/network/execution-routes/ssh-browser-network-execution-route.test.ts\",\"assertions\":[\"does not adopt a replacement ssh2 client under the captured authority\",\"releases a deferred socket when forwardOut throws during disconnect\",\"aborts system SSH startup when route authorization is revoked\",\"reaches external sites over ssh2 through the host proxy and keeps local names direct\",\"dials directly while the host environment is unreadable and adopts it once a retry reads it\",\"reaches external sites over system SSH through the host proxy\"]},{\"file\":\"src/main/browser/network/tunnels/system-ssh-socks-client-socket.test.ts\",\"assertions\":[\"the internal SOCKS5 client encodes the exact destination as a domain request\"]},{\"file\":\"src/main/ssh/system-transport/forwarding/system-ssh-dynamic-forward-process.test.ts\",\"assertions\":[\"authority invalidation cancels an in-progress SSH launch and destroys its active readiness probe immediately\"]},{\"file\":\"tests/e2e/ssh-browser-network-execution-route.docker.unit.test.ts\",\"assertions\":[\"an ephemeral sshd resolves a container-only domain and returns a unique HTTP marker\",\"the real ssh2 forwardOut receives that exact domain and provider loss fences the route\",\"one non-interactive system-OpenSSH dynamic forward passes the same remote-only oracle and closes cleanly\"]},{\"file\":\"src/shared/remote-runtime/requests/remote-runtime-subscription-request.test.ts\",\"assertions\":[\"nested JSON responses route by exact request ID under reverse-order delivery\"]},{\"file\":\"src/shared/remote-runtime/remote-runtime-client.test.ts\",\"assertions\":[\"the authenticated socket binds the optional tunnel capability\",\"the dedicated outbound queue reports hard overflow instead of dropping a frame\",\"encrypted queue claims release synchronously while native socket ownership remains charged through exact close\"]},{\"file\":\"src/shared/ws-outbound-backpressure-queue.test.ts\",\"assertions\":[\"direct and already-retained queued frames use distinct aggregate admission semantics\"]}]}" ], "demotionRule": "Keep experimental or demote if a self-asserted or ambiguous host can receive a route, an SSH descriptor bypasses capability, lease-bound grant, or provider-authority checks, late cleanup can remove a replacement, a route can resolve names on the desktop, exceed a byte or stream bound, replenish credit before destination settlement, accept a stale or non-increasing generation, reuse a stream ID within one generation, lose or bypass its fail-closed listener during reconnect, expose the SOCKS listener off-loopback, accept BIND/UDP, or fall back when the selected route is unavailable." }, @@ -5418,32 +5422,22 @@ "providers": ["remote-runtime"], "coveredPlatforms": ["macos", "linux"], "coveredProviders": ["remote-runtime"], - "coverageNotes": "The retained fake-clock scheduler cases check bounded exhaustion, rejected attempts continuing to exhaustion, in-flight cancellation, and one queued replacement chain. Direct transient-success counted-delay, healthy-budget reset, and pending-cancellation cases were removed. Existing lifecycle and paired-runtime coverage remain separate and were not re-reviewed as equivalent replacements in this audit. The historical headless paired journey disconnects the real runtime, shows Reconnect, reconnects the same host, and requires a new frame. Headed paired-server, Windows, sleep/wake, and real network-partition evidence remain uncollected.", + "coverageNotes": "Audit5758 companion to audit5754 intentionally retires the whole remote-browser-stream-restart-scheduler.test.ts suite. Direct fake-clock bounded exhaustion, rejected-attempt continuation, in-flight cancellation without re-arm and one replacement-chain alarms are lost without equivalent replacement. The unit command is narrowed and scheduler testFiles/assertionRefs entries removed. Separate lifecycle and paired-runtime selector assertions/evidence keep only their original scope and are not reassessed as replacements. No fresh execution, current import reachability or native/platform coverage is claimed. Complete prior account preserved verbatim as historical, including references to then-retained scheduler cases: The retained fake-clock scheduler cases check bounded exhaustion, rejected attempts continuing to exhaustion, in-flight cancellation, and one queued replacement chain. Direct transient-success counted-delay, healthy-budget reset, and pending-cancellation cases were removed. Existing lifecycle and paired-runtime coverage remain separate and were not re-reviewed as equivalent replacements in this audit. The historical headless paired journey disconnects the real runtime, shows Reconnect, reconnects the same host, and requires a new frame. Headed paired-server, Windows, sleep/wake, and real network-partition evidence remain uncollected.", "motivatingLinks": [ "https://github.com/stablyai/orca/pull/12787", "https://linear.app/stably/issue/STA-3483" ], "invariant": "A current remote browser stream that closes must retry transient failures on one counted, capped backoff chain. Cancellation, pane or runtime supersession, missing pages, and permanent failures stop that chain without stale state mutation. A stream that stays healthy refills the budget; a silent or flapping stream cannot retry forever. Exhaustion and every non-retrying failure leave an actionable Reconnect control, and manual reconnect creates a fresh stream without resurrecting stale subscriptions.", - "oracle": "The retained direct scheduler oracles require finite exhaustion, continuation after rejected attempts, cancellation of in-flight ownership without re-arming, and one queued replacement chain. Existing lifecycle assertions separately describe stale pane/operation/stream/page/runtime refusal, liveness, and manual recovery; they are not claimed equivalent to removed direct scheduler cases. The paired-runtime oracle paints a remote frame, disconnects its owning runtime, observes the bounded-retry notice and Reconnect control, reconnects, and requires a different frame object URL.", + "oracle": "Audit5758 companion to audit5754 intentionally retires the whole remote-browser-stream-restart-scheduler.test.ts suite. Direct fake-clock bounded exhaustion, rejected-attempt continuation, in-flight cancellation without re-arm and one replacement-chain alarms are lost without equivalent replacement. The unit command is narrowed and scheduler testFiles/assertionRefs entries removed. Separate lifecycle and paired-runtime selector assertions/evidence keep only their original scope and are not reassessed as replacements. No fresh execution, current import reachability or native/platform coverage is claimed. Complete prior account preserved verbatim as historical, including references to then-retained scheduler cases: The retained direct scheduler oracles require finite exhaustion, continuation after rejected attempts, cancellation of in-flight ownership without re-arming, and one queued replacement chain. Existing lifecycle assertions separately describe stale pane/operation/stream/page/runtime refusal, liveness, and manual recovery; they are not claimed equivalent to removed direct scheduler cases. The paired-runtime oracle paints a remote frame, disconnects its owning runtime, observes the bounded-retry notice and Reconnect control, reconnects, and requires a different frame object URL.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts", "pnpm exec playwright test tests/e2e/paired-remote-browser-stream-reconnect.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1" ], "testFiles": [ "src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts", - "src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts", "tests/e2e/paired-remote-browser-stream-reconnect.spec.ts" ], "assertionRefs": [ - { - "file": "src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts", - "assertions": [ - "budget exhaustion stops exactly once", - "cancellation retires an in-flight attempt without re-arming", - "a close during an in-flight attempt queues one replacement chain", - "rejected attempts continue until budget exhaustion" - ] - }, { "file": "src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts", "assertions": [ @@ -5502,7 +5496,10 @@ "Live Linux and Windows evidence is uncollected.", "Audit1833 removed direct transient-success counted-delay, healthy-budget reset, and pending-cancellation cases. No equivalent lifecycle coverage is claimed.", "Audit1833 retires this complete dated local receipt because the selected scheduler was reduced; its 61 tests and currentCommand are not current candidate validation. Original receipt verbatim: {\"date\":\"2026-08-07\",\"runner\":\"local\",\"platform\":\"macos\",\"command\":\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-errors.test.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-status.test.ts\",\"currentCommand\":\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts\",\"result\":\"passed\",\"durationSeconds\":0.36,\"summary\":\"Four focused files passed 61 deterministic error, status, scheduler, lifecycle, in-flight ownership, stale-rejection, liveness, and cleanup tests.\"}", - "Historical red/green description retired from current completeness evidence, not re-executed by audit1833: {\"status\":\"complete\",\"evidence\":\"The byte-identical scheduler oracle fails with the reschedule disabled at one attempt instead of four and passes after restoration. On the PR head, the delayed handoff oracle counted two scheduled attempts instead of one, and the late stale-rejection oracle lost the replacement ready deadline and never offered reconnect; both pass after the ownership fixes. Current main structurally contains the original one-shot timer dead end. The focused suite passes 61 tests, and the isolated paired-runtime CI journey passes both disconnect and cold-open recovery scenarios.\"}" + "Historical red/green description retired from current completeness evidence, not re-executed by audit1833: {\"status\":\"complete\",\"evidence\":\"The byte-identical scheduler oracle fails with the reschedule disabled at one attempt instead of four and passes after restoration. On the PR head, the delayed handoff oracle counted two scheduled attempts instead of one, and the late stale-rejection oracle lost the replacement ready deadline and never offered reconnect; both pass after the ownership fixes. Current main structurally contains the original one-shot timer dead end. The focused suite passes 61 tests, and the isolated paired-runtime CI journey passes both disconnect and cold-open recovery scenarios.\"}", + "Audit5758 exact original complete commands JSON value, preserved verbatim as historical selector metadata; removed/narrowed selector is not validated by old evidence:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts\",\n \"pnpm exec playwright test tests/e2e/paired-remote-browser-stream-reconnect.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"\n ]", + "Audit5758 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; removed/narrowed selector is not validated by old evidence:\n[\n \"src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts\",\n \"src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts\",\n \"tests/e2e/paired-remote-browser-stream-reconnect.spec.ts\"\n ]", + "Audit5758 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; removed/narrowed selector is not validated by old evidence:\n[\n {\n \"file\": \"src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts\",\n \"assertions\": [\n \"budget exhaustion stops exactly once\",\n \"cancellation retires an in-flight attempt without re-arming\",\n \"a close during an in-flight attempt queues one replacement chain\",\n \"rejected attempts continue until budget exhaustion\"\n ]\n },\n {\n \"file\": \"src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts\",\n \"assertions\": [\n \"dropped, silent, and flapping streams converge on a bounded retry or actionable stop\",\n \"stale, superseded, missing-page, and permanent-failure work cannot mutate the current pane\",\n \"manual reopen starts a fresh budget and adopts one current subscription\",\n \"a late stale rejection cannot clear the replacement stream's ready deadline\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-remote-browser-stream-reconnect.spec.ts\",\n \"assertions\": [\n \"a real paired-runtime disconnect ends with an actionable Reconnect control\",\n \"manual reconnect paints a new remote frame instead of retaining only the frozen frame\",\n \"a pane whose first open fails can recover from no prior subscription\"\n ]\n }\n ]" ], "demotionRule": "Keep experimental or demote if retries can stop before recovery or exhaustion, continue after exhaustion, run in parallel, mutate a superseded pane, hide the Reconnect control, leak a subscription or timer, or fail to paint a new frame after manual reconnect." }, @@ -6646,15 +6643,15 @@ "providers": ["local", "wsl", "ssh", "remote-runtime"], "coveredPlatforms": ["windows"], "coveredProviders": [], - "coverageNotes": "Audit5687 integrates source audit5681: retire the complete repos-update-serialization.test.ts suite and its exact active selectors. Intentionally lose same-repository queued-update ordering, independent repository/host progress, latest metadata preservation and failed-predecessor recovery alarms without replacement. Remaining sources and receipts retain only their own exact scopes. No fresh execution, equivalent replacement, platform or remote result is claimed. Historical prior account (preserved verbatim): Audit5658 integrates source audit5652: retire the whole repos-project-group-create-race.test.ts suite and its exact active selectors. Intentionally lose late project-group creation versus fresh renamed row and captured owner after focus changes alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit2371 reduces repos-project-group-create-race.test.ts by removing the two-host generic failed-create-response/no-op example. Its alarm that a failed create reply leaves an intervening refreshed state untouched is intentionally lost. The surviving refreshed-field and original-owner races do not supply equivalent replacement coverage. No fresh execution or red/green evidence validates the reduced source; unrelated physical Windows/WSL receipt retains its original command and scope. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit1396 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1342 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): A deterministic Windows-mode renderer oracle keeps an active WSL project and explicit-local Floating Workspace mounted together with disjoint agent inventories, then independently asserts discovery and launch authority. A headed physical Windows 2 journey with real Ubuntu WSL2 independently verified the rendered inventory and native PowerShell launch; SSH and paired-runtime behavior retain their existing contract coverage. The test-value audit removes standalone WSL/provider argument inventories and basic supplied-result/cache-clear examples from detected-agents.test.ts. It retains shared in-flight detection, cached-context return, repair/retry, stale-response fencing, SSH refresh/pruning and old-server fallback behavior. These retained tests do not replace the removed route-argument alarms or execute a live WSL/remote probe. Historical commands, counts and results remain unchanged. The later test-value audit removes narrow refusal/reset ledgers, a settled-project eviction/reacquisition example, a simple stale-success variant and redundant plain-text draft cleanup examples. local-detected-agent-state retains independent inventory completion orders, preference-change fencing, full-refresh loading settlement, refresh failure/retry, native-versus-WSL separation, subscriber broadcast bounds and in-flight project eviction. The removed settled-context sibling-preservation/reacquisition alarm is intentionally lost; retained cases are not equivalent replacements and no live provider execution is claimed. Historical commands, counts and results remain unchanged. The test-value audit retires the standalone project-runtime registrar from repos-project-mutations.test.ts. Its updateProject runtime-preference example no longer checks clearing detectedAgentIds, isDetectingAgents and isRefreshingAgents or dispatch of orca:installed-agent-skills-changed. This narrow invalidation alarm is lost; no equivalent replacement is claimed. Historical executed commands, counts and results remain unchanged. Audit1342: src/renderer/src/hooks/useAgentDetectionTarget.test.ts removed. Floating/runtime/hydration/stamped owner key selection, scanning count and malformed decode fallback matrices disappear. No equivalent replacement coverage is claimed. Audit1396: src/renderer/src/components/terminal-pane/pty-connection-pending-spawn.spec.ts reduced. Lose standalone debug-state retention/log silence alarm. React StrictMode is not mounted; bindings manually simulate remount over mocked transport. No equivalent replacement coverage is claimed.", + "coverageNotes": "Audit5772 companion to audit5768: Retire both project-host capability and lifecycle suites. Direct unsupported setup/clone and missing run-context capability refusals, ambiguous same-ID setup delete/update and explicit missing-host delete refusal alarms are intentionally lost without equivalent replacement. Narrow one compound unit command and remove both testFiles entries. All existing assertions, including project purge assertions changed by a separate predecessor packet, are left exactly at this source pin for parent composition. Complete dated evidenceRuns and unrelated selectors/assertions are unchanged; none selects these retired suites and none validates the narrowed command. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account preserved verbatim below as historical, including any older then-retained coverage claim: Audit5765 companion to audit5760 retires the whole repos-remove-project-purge-leak.test.ts suite. Direct canonical per-worktree map purge, removed-project agent inventory eviction and unrelated-project survival alarms are intentionally lost without equivalent replacement. One compound unit command is narrowed and its testFiles entry and full assertionRef removed. Detection/local-inventory assertions and the Windows WSL/Floating journey retain only their original scope; they are not certified as replacements. All complete dated evidenceRuns remain unchanged; none selects this removed suite, and none validates changed commands. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account is preserved verbatim below as historical, including any older then-retained coverage claim: Audit5687 integrates source audit5681: retire the complete repos-update-serialization.test.ts suite and its exact active selectors. Intentionally lose same-repository queued-update ordering, independent repository/host progress, latest metadata preservation and failed-predecessor recovery alarms without replacement. Remaining sources and receipts retain only their own exact scopes. No fresh execution, equivalent replacement, platform or remote result is claimed. Historical prior account (preserved verbatim): Audit5658 integrates source audit5652: retire the whole repos-project-group-create-race.test.ts suite and its exact active selectors. Intentionally lose late project-group creation versus fresh renamed row and captured owner after focus changes alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit2371 reduces repos-project-group-create-race.test.ts by removing the two-host generic failed-create-response/no-op example. Its alarm that a failed create reply leaves an intervening refreshed state untouched is intentionally lost. The surviving refreshed-field and original-owner races do not supply equivalent replacement coverage. No fresh execution or red/green evidence validates the reduced source; unrelated physical Windows/WSL receipt retains its original command and scope. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit1396 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1342 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): A deterministic Windows-mode renderer oracle keeps an active WSL project and explicit-local Floating Workspace mounted together with disjoint agent inventories, then independently asserts discovery and launch authority. A headed physical Windows 2 journey with real Ubuntu WSL2 independently verified the rendered inventory and native PowerShell launch; SSH and paired-runtime behavior retain their existing contract coverage. The test-value audit removes standalone WSL/provider argument inventories and basic supplied-result/cache-clear examples from detected-agents.test.ts. It retains shared in-flight detection, cached-context return, repair/retry, stale-response fencing, SSH refresh/pruning and old-server fallback behavior. These retained tests do not replace the removed route-argument alarms or execute a live WSL/remote probe. Historical commands, counts and results remain unchanged. The later test-value audit removes narrow refusal/reset ledgers, a settled-project eviction/reacquisition example, a simple stale-success variant and redundant plain-text draft cleanup examples. local-detected-agent-state retains independent inventory completion orders, preference-change fencing, full-refresh loading settlement, refresh failure/retry, native-versus-WSL separation, subscriber broadcast bounds and in-flight project eviction. The removed settled-context sibling-preservation/reacquisition alarm is intentionally lost; retained cases are not equivalent replacements and no live provider execution is claimed. Historical commands, counts and results remain unchanged. The test-value audit retires the standalone project-runtime registrar from repos-project-mutations.test.ts. Its updateProject runtime-preference example no longer checks clearing detectedAgentIds, isDetectingAgents and isRefreshingAgents or dispatch of orca:installed-agent-skills-changed. This narrow invalidation alarm is lost; no equivalent replacement is claimed. Historical executed commands, counts and results remain unchanged. Audit1342: src/renderer/src/hooks/useAgentDetectionTarget.test.ts removed. Floating/runtime/hydration/stamped owner key selection, scanning count and malformed decode fallback matrices disappear. No equivalent replacement coverage is claimed. Audit1396: src/renderer/src/components/terminal-pane/pty-connection-pending-spawn.spec.ts reduced. Lose standalone debug-state retention/log silence alarm. React StrictMode is not mounted; bindings manually simulate remount over mocked transport. No equivalent replacement coverage is claimed.", "motivatingLinks": [ "https://linear.app/stably/issue/STA-4027/p1-floating-workspace-agent-detection-still-uses-active-wsl-project", "https://github.com/stablyai/orca/pull/13995" ], "invariant": "Every agent launch surface must advertise the provider set detected on its explicit execution authority and launch on that same authority; a local Floating Workspace must never inherit an unrelated active project's WSL, SSH, or paired-runtime context.", - "oracle": "Audit5687 integrates source audit5681: retire the complete repos-update-serialization.test.ts suite and its exact active selectors. Intentionally lose same-repository queued-update ordering, independent repository/host progress, latest metadata preservation and failed-predecessor recovery alarms without replacement. Remaining sources and receipts retain only their own exact scopes. No fresh execution, equivalent replacement, platform or remote result is claimed. Historical prior account (preserved verbatim): Audit5658 integrates source audit5652: retire the whole repos-project-group-create-race.test.ts suite and its exact active selectors. Intentionally lose late project-group creation versus fresh renamed row and captured owner after focus changes alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit2371 reduces repos-project-group-create-race.test.ts by removing the two-host generic failed-create-response/no-op example. Its alarm that a failed create reply leaves an intervening refreshed state untouched is intentionally lost. The surviving refreshed-field and original-owner races do not supply equivalent replacement coverage. No fresh execution or red/green evidence validates the reduced source; unrelated physical Windows/WSL receipt retains its original command and scope. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Model an active WSL project and a native-Windows Floating Workspace with WSL-only Claude and host-only Codex. Keep both detection consumers mounted, require their advertised sets to stay disjoint through refresh, require the legacy active-project inventory to remain unchanged, then independently assert the Floating launch call and PTY transport select local IPC with no WSL project runtime.", + "oracle": "Audit5772 companion to audit5768: Retire both project-host capability and lifecycle suites. Direct unsupported setup/clone and missing run-context capability refusals, ambiguous same-ID setup delete/update and explicit missing-host delete refusal alarms are intentionally lost without equivalent replacement. Narrow one compound unit command and remove both testFiles entries. All existing assertions, including project purge assertions changed by a separate predecessor packet, are left exactly at this source pin for parent composition. Complete dated evidenceRuns and unrelated selectors/assertions are unchanged; none selects these retired suites and none validates the narrowed command. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account preserved verbatim below as historical, including any older then-retained coverage claim: Audit5765 companion to audit5760 retires the whole repos-remove-project-purge-leak.test.ts suite. Direct canonical per-worktree map purge, removed-project agent inventory eviction and unrelated-project survival alarms are intentionally lost without equivalent replacement. One compound unit command is narrowed and its testFiles entry and full assertionRef removed. Detection/local-inventory assertions and the Windows WSL/Floating journey retain only their original scope; they are not certified as replacements. All complete dated evidenceRuns remain unchanged; none selects this removed suite, and none validates changed commands. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account is preserved verbatim below as historical, including any older then-retained coverage claim: Audit5687 integrates source audit5681: retire the complete repos-update-serialization.test.ts suite and its exact active selectors. Intentionally lose same-repository queued-update ordering, independent repository/host progress, latest metadata preservation and failed-predecessor recovery alarms without replacement. Remaining sources and receipts retain only their own exact scopes. No fresh execution, equivalent replacement, platform or remote result is claimed. Historical prior account (preserved verbatim): Audit5658 integrates source audit5652: retire the whole repos-project-group-create-race.test.ts suite and its exact active selectors. Intentionally lose late project-group creation versus fresh renamed row and captured owner after focus changes alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit2371 reduces repos-project-group-create-race.test.ts by removing the two-host generic failed-create-response/no-op example. Its alarm that a failed create reply leaves an intervening refreshed state untouched is intentionally lost. The surviving refreshed-field and original-owner races do not supply equivalent replacement coverage. No fresh execution or red/green evidence validates the reduced source; unrelated physical Windows/WSL receipt retains its original command and scope. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Model an active WSL project and a native-Windows Floating Workspace with WSL-only Claude and host-only Codex. Keep both detection consumers mounted, require their advertised sets to stay disjoint through refresh, require the legacy active-project inventory to remain unchanged, then independently assert the Floating launch call and PTY transport select local IPC with no WSL project runtime.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/hooks/useDetectedAgents.test.tsx src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts src/renderer/src/store/projects/repos-project-host-capability.test.ts src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts --reporter=verbose", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/hooks/useDetectedAgents.test.tsx src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts --reporter=verbose", "Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace" ], "testFiles": [ @@ -6662,10 +6659,7 @@ "src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts", "src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts", "src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts", - "src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts", - "src/renderer/src/store/projects/repos-project-host-capability.test.ts", - "src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts", - "src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts" + "src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts" ], "assertionRefs": [ { @@ -6682,12 +6676,6 @@ "refresh supersedes stale detection and failed cold refresh remains retryable", "project removal evicts in-flight context state" ] - }, - { - "file": "src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts", - "assertions": [ - "removing one project evicts its authority-scoped agent inventory without disturbing another project" - ] } ], "evidenceRuns": [ @@ -6747,7 +6735,13 @@ "Audit5658/source5652 intentional loss: late project-group creation versus fresh renamed row and captured owner after focus changes alarms removed wholesale. No equivalent replacement or fresh validation of reduced selectors; historical receipts preserve exact original scope.", "Audit5658 exact original complete commands: [\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/hooks/useDetectedAgents.test.tsx src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts src/renderer/src/store/project-groups/repos-project-group-create-race.test.ts src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts src/renderer/src/store/projects/repos-project-host-capability.test.ts src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts src/renderer/src/store/repos/repos-update-serialization.test.ts --reporter=verbose\",\"Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace\"]", "Audit5658 exact original complete testFiles: [\"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\"src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts\",\"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\"src/renderer/src/store/project-groups/repos-project-group-create-race.test.ts\",\"src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts\",\"src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts\",\"src/renderer/src/store/projects/repos-project-host-capability.test.ts\",\"src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts\",\"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\",\"src/renderer/src/store/repos/repos-update-serialization.test.ts\"]", - "Audit5687 original complete active selector and receipt fields (historical native semantic values; not current coverage): {\"commands\":[\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/hooks/useDetectedAgents.test.tsx src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts src/renderer/src/store/projects/repos-project-host-capability.test.ts src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts src/renderer/src/store/repos/repos-update-serialization.test.ts --reporter=verbose\",\"Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace\"],\"testFiles\":[\"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\"src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts\",\"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\"src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts\",\"src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts\",\"src/renderer/src/store/projects/repos-project-host-capability.test.ts\",\"src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts\",\"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\",\"src/renderer/src/store/repos/repos-update-serialization.test.ts\"],\"assertionRefs\":[{\"file\":\"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\"assertions\":[\"the active WSL project advertises only its WSL agent while Floating advertises only the native-host agent\",\"Floating refresh preserves both scoped inventories and does not overwrite the legacy active-project inventory\"]},{\"file\":\"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\"assertions\":[\"same-context callers deduplicate without cached broadcast fanout\",\"refresh supersedes stale detection and failed cold refresh remains retryable\",\"project removal evicts in-flight context state\"]},{\"file\":\"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\",\"assertions\":[\"removing one project evicts its authority-scoped agent inventory without disturbing another project\"]}],\"evidenceRuns\":[{\"date\":\"2026-08-12\",\"runner\":\"manual\",\"platform\":\"windows\",\"command\":\"Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace\",\"result\":\"passed\",\"durationSeconds\":22.3,\"summary\":\"Environment abfee683-80eb-4ac3-ada0-da5d1b6303a6, runtime b3bea13e-f6b7-41e7-b850-0a118f7eda38: Floating advertised native Claude/Codex without WSL-only Gemini and launched Claude through native PowerShell with local host ownership while the WSL project remained active.\"}]}" + "Audit5687 original complete active selector and receipt fields (historical native semantic values; not current coverage): {\"commands\":[\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/hooks/useDetectedAgents.test.tsx src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts src/renderer/src/store/projects/repos-project-host-capability.test.ts src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts src/renderer/src/store/repos/repos-update-serialization.test.ts --reporter=verbose\",\"Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace\"],\"testFiles\":[\"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\"src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts\",\"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\"src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts\",\"src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts\",\"src/renderer/src/store/projects/repos-project-host-capability.test.ts\",\"src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts\",\"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\",\"src/renderer/src/store/repos/repos-update-serialization.test.ts\"],\"assertionRefs\":[{\"file\":\"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\"assertions\":[\"the active WSL project advertises only its WSL agent while Floating advertises only the native-host agent\",\"Floating refresh preserves both scoped inventories and does not overwrite the legacy active-project inventory\"]},{\"file\":\"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\"assertions\":[\"same-context callers deduplicate without cached broadcast fanout\",\"refresh supersedes stale detection and failed cold refresh remains retryable\",\"project removal evicts in-flight context state\"]},{\"file\":\"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\",\"assertions\":[\"removing one project evicts its authority-scoped agent inventory without disturbing another project\"]}],\"evidenceRuns\":[{\"date\":\"2026-08-12\",\"runner\":\"manual\",\"platform\":\"windows\",\"command\":\"Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace\",\"result\":\"passed\",\"durationSeconds\":22.3,\"summary\":\"Environment abfee683-80eb-4ac3-ada0-da5d1b6303a6, runtime b3bea13e-f6b7-41e7-b850-0a118f7eda38: Floating advertised native Claude/Codex without WSL-only Gemini and launched Claude through native PowerShell with local host ownership while the WSL project remained active.\"}]}", + "Audit5765 exact original complete commands JSON value, preserved verbatim as historical selector metadata; removed/narrowed selectors have no new validation:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/hooks/useDetectedAgents.test.tsx src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts src/renderer/src/store/projects/repos-project-host-capability.test.ts src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts --reporter=verbose\",\n \"Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace\"\n ]", + "Audit5765 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; removed/narrowed selectors have no new validation:\n[\n \"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\n \"src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts\",\n \"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\n \"src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts\",\n \"src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts\",\n \"src/renderer/src/store/projects/repos-project-host-capability.test.ts\",\n \"src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts\",\n \"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\"\n ]", + "Audit5765 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; removed/narrowed selectors have no new validation:\n[\n {\n \"file\": \"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\n \"assertions\": [\n \"the active WSL project advertises only its WSL agent while Floating advertises only the native-host agent\",\n \"Floating refresh preserves both scoped inventories and does not overwrite the legacy active-project inventory\"\n ]\n },\n {\n \"file\": \"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\n \"assertions\": [\n \"same-context callers deduplicate without cached broadcast fanout\",\n \"refresh supersedes stale detection and failed cold refresh remains retryable\",\n \"project removal evicts in-flight context state\"\n ]\n },\n {\n \"file\": \"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\",\n \"assertions\": [\n \"removing one project evicts its authority-scoped agent inventory without disturbing another project\"\n ]\n }\n ]", + "Audit5772 exact original complete commands JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/hooks/useDetectedAgents.test.tsx src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts src/renderer/src/store/projects/repos-project-host-capability.test.ts src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts --reporter=verbose\",\n \"Headed Electron/CDP STA-4027 journey on Orca environment windows 2 with a selected Ubuntu-24.04 WSL project and local Floating Workspace\"\n ]", + "Audit5772 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n \"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\n \"src/renderer/src/store/slices/agent-inventory/detected-agents.test.ts\",\n \"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\n \"src/renderer/src/store/project-groups/repos-project-groups-delete.test.ts\",\n \"src/renderer/src/store/project-groups/repos-project-groups-owner-routing.test.ts\",\n \"src/renderer/src/store/projects/repos-project-host-capability.test.ts\",\n \"src/renderer/src/store/projects/repos-project-host-lifecycle.test.ts\",\n \"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\"\n ]", + "Audit5772 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n {\n \"file\": \"src/renderer/src/hooks/useDetectedAgents.test.tsx\",\n \"assertions\": [\n \"the active WSL project advertises only its WSL agent while Floating advertises only the native-host agent\",\n \"Floating refresh preserves both scoped inventories and does not overwrite the legacy active-project inventory\"\n ]\n },\n {\n \"file\": \"src/renderer/src/store/slices/agent-inventory/local-detected-agent-state.test.ts\",\n \"assertions\": [\n \"same-context callers deduplicate without cached broadcast fanout\",\n \"refresh supersedes stale detection and failed cold refresh remains retryable\",\n \"project removal evicts in-flight context state\"\n ]\n },\n {\n \"file\": \"src/renderer/src/store/repos/repos-remove-project-purge-leak.test.ts\",\n \"assertions\": [\n \"removing one project evicts its authority-scoped agent inventory without disturbing another project\"\n ]\n }\n ]" ], "demotionRule": "Demote if discovery and launch can resolve different authorities, a scoped Floating probe overwrites the active-project inventory, or local context selection adds recurring scans or retained in-flight entries." }, @@ -8008,13 +8002,13 @@ "providers": ["paired-runtime", "ssh"], "coveredPlatforms": ["macos"], "coveredProviders": [], - "coverageNotes": "Audit5571 removes the entire unrelated-PTY mobile heartbeat callback suite and its active selectors; its bookkeeping alarm is intentionally lost without equivalent replacement or fresh runtime evidence. Fourteen unrelated dated receipts retain their exact original scopes. Historical account follows: Audit5534 removes the whole last-active retention TTL selector suite (one authored/finite case). Its absolute-TTL and inside-boundary alarm is intentionally lost without equivalent replacement or fresh execution. Active command/file selectors drop only that suite; historical receipts remain at their original scope. Audit4362 intentionally deletes the imported stale-waiter retry and manually assembled OSC9999 mobile-republish cases, plus the mocked missing-worktree cleanup suite (4 authored / 5 finite cases in three suites). Lost alarms include repeated unread worker_done pointers, working-to-waiting mobile status publication, missing-worktree filtering, and scoped daemon shutdown with unrelated duplicate identities. No replacement coverage or new platform proof is claimed. Audit3994 retires two authored callbacks imported by the shared construction test driver: split OSC 9999 carry and rendererless status ownership, plus OpenCode permission text taking priority in status and tui-idle refusal. Remaining imports and selectors keep their scope. No equivalent replacement or fresh gate execution is claimed. Audit3580: Retire the whole one-case runtime host environment prototype/subclass suite. Intentionally lose the exact configured lower-case Windows Claude home to account-identity normalization and host-account override precedence alarm previously retained by Audit3129. No equivalent replacement or fresh runtime validation is claimed. Earlier dated keep statements below describe their historical source scope; the current suite is removed. Audit3563 scope: retire the whole Kiro OSC/hook identity suite and the OpenCode2 identity-only case; reduce Codex cached startup child-retirement and missing-session-ID tables to one case each (2 authored/4 finite removals). Intentionally lose Kiro alias/session continuity, OpenCode2 completed OSC identity continuity, cached replacement without relay-generation restart, and missing-previous-ID context-preservation alarms. Remaining provider, remote compatibility, persistence and cross-session pollution cases are not equivalent replacements. Also remove the private Codex roster-size assertion while retaining public child-absence checks. Historical evidence retains its original source scope; no new execution or transferred pass validates these reductions. Audit3446 composes ROOT-adopted3441/independent3442: intentionally removes100 authored registrations/119 potential expanded cases (118 conditional-active before platform gates) across16 sources, retaining11 authored/13 expanded cases and deleting6 whole suites. Two parent registrar import/call cleanups and the unused68line CLI recording fixture carry zero test credit. No equivalent replacement or fresh execution is claimed. The decorative fanout suite retains only real OSC9999 ingestion through runtime/title heartbeat/viewer past the stale boundary, preserving stateStartedAt and clearing expired prompt metadata. Spinner volume/zero-work inventories, Pi/Grok frame tables, rich-status and foreground-reset examples are retired. Existing receipts for separate paired-terminal sources retain their original scopes. Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3342 removes three supplied activation/inventory fallback and same-handle retry examples; their fallback/retry alarms are intentionally lost without equivalent replacement. The exact mounted-HUB pending old-stream-end versus replacement-snapshot registration and its assertion remain. Unrelated dated macOS receipts retain only their original scope; no fresh runtime, provider, performance, mobile, mixed-version or cross-platform validation is claimed. NEXT46 terminal-owner layout and whole-case policy: src/renderer/src/components/terminal-pane/pty-connection/tests/pty-connection-hidden-replay.test.ts, src/renderer/src/components/terminal-pane/pty-connection/tests/pty-connection-visibility-and-exit.test.ts, src/renderer/src/runtime/hosted-terminals/streams/remote-runtime-terminal-stall-recovery.test.ts. Complete retired/reduced selectors lose their listed alarms; retained cases have no transferred historical pass or equivalent replacement coverage. Unaffected dated receipts retain only their original exact scopes. This metadata edit is not fresh execution evidence. Historical prior account (preserved verbatim): Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: restarts only the stream whose renderer delivery credit never settles — An unreturned renderer delivery credit stalls only its stream, leaving healthy sibling/shared transport alive. Fake-clock deadline plus real multiplexer unsubscribe isolates recovery ownership.; probes then restarts a stream when an entered command receives no frames — Entered command produces no output; actual multiplexer must probe then close only its stalled stream after probe timeout. Distinct response liveness from parser credit.; establishes a probe baseline before recovering an unsequenced stream — 142-line manual five-probe baseline/regression sequence derives request IDs from encoded mock traffic and checks repeated no-close/close choreography. Oversized algorithm/state-machine example; no actual renderer/host command or recovery delivery. Retires unsequenced/unchanged/regressed baseline classification alarms.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces remote-runtime-pty-transport-unpublished-host-graph.test.ts, retiring its direct published-empty-graph omission-to-pane-exit alarm. The unchanged bounded unpublished-frame/pushed-recovery and stale-handle park/manual-retry cases are narrower, not equivalent replacements. Both complete three-case Linux receipts dated 2026-11-04 are archived as historical, including source heads; they do not validate this reduced selector. Remaining fourteen active receipts are macOS only. No fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3318 composes adopted sources 3310, 3313 and 3317: intentionally retires 71 authored declarations and 102 expanded cases, including whole terminal-detach agent-retention, seeded batch/single open-files equivalence, shallow context-menu shortcut-badge, mocked active-workspace delete-dispatch, workspace session hydration, SSH target cleanup, editor session hydration and worktree terminal purge suites. Lost alarms include chained transfer alias and immediate close/exit retention; batch/single divergence, survivor/selection/map preservation and input nonmutation across 400 imperative seeds (one registered case); disconnected pending-handle retry, authoritative absences/close-record shortcut/older-host absence and published-presence/unpublished-frame examples; published empty host-graph omission to pane exit; legacy search ranking/exclusion fallback; provider request upgrade/dedupe/finalizer ownership; asynchronous PR suppression/primary-change and same-number different-repository URL rejection. Deletion routing loses host/instance qualification, paired and legacy mapping, folder ownership, active-versus-hover/menu-row selection, ambiguity, modal/editable/creation/view/main/deleting/missing guards and shortcut advertisement. Unchanged real keyboard/hover/confirmation/catalog E2E remains narrower, not an equivalent replacement. Additional losses include scripted old-host disk/UTF-8/noop/baseline and landed/unlanded lost-reply/replacement-retry outcomes; ordinary/repeated healthy-link reattach; cross-owner terminal/chat binding; oversized replay permanent-unavailable classification; floating reveal keyboard ownership/close/disable/listener disposal; naming/retained-turn/Sleep/error/close/reject status tables; SSH membership prune/new-target-only reads and environment/local bucket isolation; same-frame receipt capacity and positive bare/headless publisher readmission. These actual regression alarms are deliberately lost; no fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3312 composes adopted sources 3302 and 3308: deliberately retires 33 authored declarations and 36 expanded cases, including the whole backend startup-focus, active-browser IPC-close-routing, remote-browser-creation and agent-terminal-presence suites. Intentionally lost alarms cover distinct six-pane reconnect handles; SSH host label/Connect callback, unhydrated visit cleanup, repo cache aliases and hidden worktree/tab/PTY cleanup; adopted-agent startup focus and viewer navigation/reuse; staged, pageless, source, stale and orphan browser-close routing; web local-materialization refusal, desktop incapable-host fallback, failed/thrown remote creation and paired-web sign-in refusal; BOM/NUL and remote/local custom-editor byte-read examples; immediate folder activation and unread clearing; and batching idle/coalescing, accumulated byte ceiling, leading-edge-disabled, standalone synchronous oversize rejection, validation yield, deferred pending-tail order and both viewport-clear examples. The newly reintroduced agent-terminal-presence suite also loses actual terminal-status membership positive and nonterminal-status callback suppression alarms, including the recent 40916 guard regression; the older different 2133 presence-suite history remains historical and receives zero duplicate removal credit. These real regression alarms are intentionally lost. The unchanged survivors provide narrower coverage, with no equivalent replacement or fresh gate, provider, rendered, remote/mobile, mixed-version, cross-platform, soak or measured-budget validation claimed. Audit 3301 combines adopted source batches 3296 and 3299: retire 27 authored declarations and 36 expanded scenarios, including six whole suites. Intentionally lost alarms cover failed-verification/recovery/restart counters and mocked hosting/toast; early overlapping pane-read scheduling/count; unreadable removal listing draft guard; bulk-purge remote-qualified and raw-local guard maps; initial-snapshot blank/mode/oversize/printable/fresh-spawn callback and replay examples; fallback mobile file close and ordinary MRU; default queue overload/drain; seeded browser-page reuse and supplied missing-page URL recreation; ambiguous sleep/hibernation owner refusal and untouched bindings/origins; ordinary selection/activity/fallback priority; skip-remote success and retained hints; supplied structured-chat unsent retention and scoped removal draft eviction; caller-chat focus precedence; open/draft PR cache eviction and merged-head fallback result inventories. Retained adverse-ordering and ownership cases are narrower and do not establish equivalent replacements. No fresh runtime, native, physical provider, cross-platform, mobile or mixed-version evidence is claimed. Audit 3292 combines adopted 3285/3287/3289/3293 removals: 40 authored declarations and 47 expanded scenarios, including whole frame-editor-view, ambiguous remote-delete-refusal, unverifiable-host subscription and editor-close cleanup suites. The previously reviewed dock-badge suite was already removed upstream in PR 40895 and receives zero new removal credit. Intentionally retired alarms include background browser selection and last-tab landing; main startup fallback, SSH project cleanup/survivor routing, exact-PR contradiction/saved-push positives, replay/sidecar rollback and wrapped remote error normalization; records/snapshot missing-diff hydration, ambiguous folder-owner delete refusal, focus no-op notifications, nested editor context-only cache check, pending broadcast-first status and ordinary four-confirmation aggregation; preview-source frontmatter pruning, approved local/runtime agent dispatch, non-GitHub legacy PR cache invalidation, stale merged-head transient-error fallback, empty-queue immediate query reply and unverified-to-concrete preflight risk. Additional intentionally retired alarms are injected host subscription/unsubscribe counts, synthetic editor reveal/draft/fallback/scoped close, ambiguous unread refusals and hidden mark/read roundtrip, immediate connect backoff/noError, positive mirrored evidence-clock renewal, supplied VM failure/success projections and git-local/folder-SSH wake permutations. Remaining temporal/ownership cases are narrower; no equivalent replacement or fresh execution is claimed. Audit 3283 removes 20 authored declarations and 31 expanded scenarios, including two whole suites. Retired alarms cover PR refresh-state pruning, shared runtime subscription cleanup and store isolation, language content-change routing and older completion ownership, ordinary panel retry-timer cleanup and pending loading, four hosted-review lifetime permutations, mocked terminal creation error/order wiring, five sleep-inventory variants with pending-frame-only assertions, palette fallback/composite highlights, Windows/UNC encoded-editor input rows, mixed-repository partial failure counts, title setters and generated-title bypass/replacement, five window-close coordinator delegation/guard/finally branches, and ambiguous-old-record frame reveal. These regression checks are intentionally lost under the test-value audit; retained cases are not equivalent replacements. Prior coverage notes and receipts remain historical. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit 3256 removes these specific alarms from the broad root unit commands: skill dialog active-share selection, close and pending-share handoff; simple keyed-record deletion; marker live-region insertion, simple landing and nine baseline policy examples; General search/control navigation inventory; orphan-count cache bootstrap; seven Codex code classifications and HTTP 429 warning mapping; two skill unread-root verdict examples; peer-mail payload and conversation-ID rejection; and the GitHub organization TABLE text-field optimistic rollback/failed-envelope example. These include real behaviors; retained tests do not provide equivalent coverage for every removed scenario. Mobile losses are recorded separately and are not coverage of these root commands. Audit3246 retires NewRowsMarker reveal/no-repeat and pane-scoped beforeinput checks; skill-owner option availability/count/dedup/order; six styled Input/Textarea IME forwarding rows; the static Codex/OpenCode smart-key inventory; tab-map AST ratchet diagnostic fixtures; child-roster work-budget and retained-aggregate alarms; malformed persisted floating-cwd fallback/no-crash/empty exact-root checks; the unanswered-host empty-list discriminator; the direct invalidated-cache commit-false assertion; one redundant digit-keyup IME row; cached non-supported Claude title-generator rows; and the duplicate late naming-result singleton. These root broad commands lose those specific alarms without equivalent replacement. Distinct retained owner/state checks have their own bounded claims; the real scheduler still rejects stale response data, while the direct false-return alarm is retired. Audit3231 retires supported-host restore-pane key mapping, closed/open creation-sidebar toggle visibility, unrelated scope-error/null classification and quick-submit reveal/no-create checks. These broad commands lose those real narrow alarms; no replacement coverage is claimed. Audit3219 removes the synthetic Cmd+J extra-source suite; this broad command no longer checks its match/tie placement and selection, announced count, empty-query cap, or workspace hiding with retained recent tabs. No replacement coverage is claimed. Audit3209 composes approved sources3202/3206: deliberately retires seven authored/expanded cases in four whole suites without equivalent replacement. Work-item queries lose real GitHub/GitLab oversized ASCII secret-prefix empty-query and whitespace-before-trim refusal alarms; inputs share the imported size bound and exercise only its fast length branch, with no multibyte or actual provider/exposure guarantee. Skill sharing loses complete/partial managed-bundle and destination-ambiguity association checks plus three negative origin/path/scheme admission examples; these do not establish uploaded contents, arbitrary-URL fetching, authorization or execution. Retain exact originless-project direct-link fallback, cloud-delete confirmation, bundled-target repair/owner isolation and explicit Windows-host preference over stale WSL suites. Rejected3201 runtime-preference removal is excluded. No real cloud/network/host/disk, mobile or mixed-version execution validation is claimed. Audit3200 composes approved source3194: deliberately retires thirteen authored registrations/twenty-seven expanded cases in six whole automation host/list policy suites without equivalent replacement. Real RPC category/retryability and wrapped-timeout recognition, unscoped-failure/scoped-success health evidence precedence, exact-ID create selectors and per-run workspace omission, paired-web local/SSH/absent host catalog routing, incompatible/removed/unhydrated/offline execution health, runtime-before-nested-SSH recovery dispatch, and no-owned-focus/successor/foreign-list focus policy alarms are consciously lost. Retain exact20line orphan allow/refuse/precondition and exact90line cross-host same-ID search suites. No retry-timer/fence lifecycle, actual reconnect/network/write delivery, native focus, mobile/mixed-version runtime or disk persistence coverage is claimed. Audit3191 combines approved source3182/3187/3188: deliberately retires thirteen authored Vitest registrations and fifteen expanded cases, including five whole suites, without equivalent replacement. Attachment intake loses real portal/native-capture terminal interception and unowned-container refusal, immediate child-only committed availability/claim-ref negotiation and delivery, and direct-target over stable focused/background composer routing through disable/re-enable/remount and independent question focus. Exact destination/cache/draft and final-stat owner/workspace/File-release suites remain; they do not replace Surface recipient routing. Automation authoring loses destination runtime catalog membership, local/direct-SSH exclusion of paired-runtime repos, unknown-runtime empty catalog, logical project/host/setup/repo/path context payload, and missing/nonready setup refusal; these were genuine direct helper alarms, while exact schedule transformation, legacy schedule and setup-decision suites remain. Agent picker loses setup-chat/terminal/missing-installer/unsupported-or-unknown-host row projection samples and the ordinary unsearched menu variant; the entire original26-line resume recipe suite remains, including reported bypass versus default/absent permission modes, as does the exact search-result menu callback with its fixtures, model/effort commits and staged Arguments reopen outcome. Rejected predecessor3180 full recipe deletion is excluded. No actual native drag/cursor/focus/IME, upload bytes or disk/restart persistence, full automation save/scheduler/runtime transport, real resume-process flags/environment delivery, or native menu/rendered layout validation is claimed. Audit3178 combines source3169/3170/3175: deliberately retires eight authored units (six Vitest cases and two imperative custom relay scenarios), including two whole suites, without equivalent replacement. Voice Section loses per-model pending-delete isolation across interleaved A/B completion and the two-success refresh-call alarm; exact VoicePane delayed key-clear/newer enabled-toggle merge remains and does not replace row deletion coverage. Speech loses dedicated rating-scale/inclusive-ceiling, unsupported-versus-unmeasured, explicit/system-language precedence/locale alias, accuracy versus fast named/default/best-measured selection, and unmeasured/no-match examples; exact offered-user-pick versus retired-selection case and its fixture remain. Relay loses legacy ping-delivery count/liveness sampled before the silence deadline and grouped malformed Bearer/host-ID 401/429 routing checks; twelve real Worker/DurableObject/shipped-client scenarios remain, not equivalent replacement for those narrow alarms. Six prior speech cases are not all deleted: approved successor3175 keeps the original user-choice case. No actual credential/file persistence, native/GPU/engine/download delivery, production assignment policy or deployed-runtime validation is claimed by this reduction. Audit3165 combines source3160/3162: deliberately retires six authored/expanded cases across three whole suites without equivalent replacement. Launch/status losses: observed React-render pending/resuming coordination across settings and deferred offer read; stale-offer reread suppressing dialog reopen; held-local-chat recovery visibility with new-chat preferences off; disabled-local admission avoiding offer RPC despite an injected but unconsumed paired-tab fixture; and run-only lost-reply uncertainty reachability until direct viewed-run retirement. Launch probe does not prove arbitrary synchronous-store atomicity, the paired fixture is not remote runtime enrollment, and the status case directly marks viewed state rather than rendering the summary. Crew-hook losses: old-host method_not_found cache persists across party changes but is released by independently supplied connection generation/verified pairing status or pairing revision, with actual frame publication and teardown. These are real narrow coordination, admission, uncertainty and mixed-version cache alarms consciously lost. Exact web verified-runtime writer handoff guard remains; it does not replace those alarms or prove live host/native/mobile delivery. Audit3156 combines3147/3150/3152/3153/3154: deliberately retires39authored/40expanded native-chat recovery cases, eight whole suites and two orphan test-support files without equivalent replacement. Lost alarms: lost-reply unconfirmed reconciliation, skipped rows/counts and missed-frame repair, unknown/pending outcome and omitted-failure-list compatibility, uncertain history after dismissal, retry/refusal/dismiss lifecycle, hidden/consumed picker ownership, result-tree keyboard focus/disclosure and all-skipped retirement; unconfirmed-over-conflict guidance and failed-chat changes despite older host timestamps; nearest-listed ancestor/cyclic forest shape, descendant membership, host ordering/missing-host local fallback; skipped/readiness/admission counts, provisional skip/progress monotonicity, early per-chat verdicts with batch pending protection, older-host waiting, start-slot/delivery distinction, retry-over-failure and unknown-after-withdrawal attention; remote snooze/reconnect/reoffer, unseen mixed summary through open/close, watched completion retirement, new success beside old failure, failed-reread mixed-result preservation, filter/collapse completion resets, retry summary replacement and current-offer/history selection; cross-host workspace identity, rendered cyclic reachability, nested tri-state/toggle propagation, project eligibility isolation and collapse preserving selection. Exact fallback-list completion barrier, batched verdict/cleanup retention, stale-read versus dismissal publication race, and requested-but-never-rendered finished-run retirement remain; they do not replace retired alarms. Audit3146 combines source reviews3132/3133/3135/3138/3143: intentionally retire20authored/31expanded cases without equivalent replacement. Provider-session losses: structured-native terminal-resume exclusion, metadata-less completed identity, new-turn completion clearing, Pi provider-only/periodic/manual promotion, changed-transcript launch-config isolation, Pi/omp/prime-agent completed-session remote/manual-shutdown promotion, and quit/done precedence over heartbeat. Side-thread/question losses: finished-pane acquisition, hidden title/recap states, local/relay/relay-done conversation takeover with prompt/session/child resets, plain-message abandonment, compaction/session replacement and completion resets. Codex startup losses: incoming-owner cached child replacement, old-relay foreign live-session correction, completed foreign-root turn-fact permutations. Transcript losses: real temporary-JSONL partial sibling/final-child completion, unlabelled child attribution, compact cached replay preservation and100/1000completed-child roster retention/release. Compiler-ratchet losses: valid-line uncompiled-list parser grammar examples and injected-existence stale-path filtering; these did not exercise actual filesystem canonicalization or build exclusion. These are real lifecycle, ownership, replay, liveness and retention alarms, including recent#40246 regressions, deliberately lost. Retained conditional record replacement, clockless root/SSH owner isolation, persisted main-thread fork rejection, partial/final question-answer lifetime, cached-roster/missing-ID/live HTTP/durable startup boundaries and restarted-relay refusal/acceptance do not replace those losses. No native/SSH/WSL execution or equivalent coverage is claimed. Audit3128 scoped coverage reduction: Audit3121 removes VoiceDictationLanguageSetting.test.tsx (Spanish-to-es callback and unsupported-model Korean option presence) and voice-speech-model-rows.test.ts (provider/language-order/retired-on-disk list policy); these real narrow alarms are deliberately retired without replacement. VoiceSpeechModelSection per-model concurrent deletion remains unchanged. Audit3122 removes the direct absolute/parent-segment sparse-directory exception-type sample and the five-row IPC sparse-preset error-code/non-save table (two authored/six expanded cases). Those real typed-validation and IPC refusal/error-code alarms are deliberately retired. Keep both real symlink/junction floating-directory trust cases and the minimal RPC structured validation-reason serialization case. The RPC case does not replace IPC save/refusal behavior, typed normalization for both path inputs, actual Git sparse checkout or rendered localization. No equivalent replacement or fresh test/runtime/platform/remote/performance validation is claimed. Audit3124 removes ExperimentalPane.test.tsx (ordinary Pet switch callback), WorkspaceDirectorySetting.test.tsx (padded absolute saved-path normalization/no-write blur), and repository-search.perf.test.ts (navigation/selected-pane builder-call policy, fixture cardinality/nonempty entries and renamed project keyword inclusion). These real narrow alarms are retired without replacement; RepositoryPane.search.test.tsx search-to-sparse-editor request remains unchanged. Audit3129: resolver Windows case-insensitive and POSIX case-sensitive configured-env composition plus mocked-base launch-preflight Windows composition are intentionally no longer checked by the two deleted suites. No equivalent coverage claimed. Keep runtime-structured-agent-host-env.test.ts unchanged: configured Windows Claude-home account identity and host-account precedence remain checked. Audit3114 incorporates source3101: retire three structured Claude child-environment wrapper cases covering inherited stamp isolation/default and explicit entrypoint, Windows SDK-key canonicalization/default/duplicate-key order, and configured lookup/final environment/config-dir conjunction. Keep direct auth/session sanitation and Windows-versus-Linux overlay checks, actual executable lookup from supplied inherited PATH, native Windows child environment delivery, and stale option-mutation fencing. These are not equivalent replacements for the retired wrapper alarms. No fresh test/runtime, real login-shell probe, Claude SDK startup, remote/mixed-version, UI or performance result is claimed. Audit3114 incorporates source3105: retire 17 authored/20 expanded daemon launch-note cases, including the entire two-case SessionLaunchNote suite. Deliberately lose split-marker carry across same-token re-arm, stale-token retirement refusal, foreground tri-state and serial settlement, omitted-note/no-incarnation mixed-version policy, sticky retirement, first-incarnation/replacement launch preservation and held-launch precedence. Keep only the unchanged unresolved foreground-read race against a later finished attach. Supplied notes/foreground and runtime calls do not establish actual daemon/main restart, SSH, native Windows observation, mobile UI, equivalent replacement or fresh runtime/performance validation. Audit3114 incorporates source3109: retire six authored/35 expanded pricing cases: 21 accepted model-name examples, 10 unsupported/future-model fail-closed examples, malformed TTL clamp, unknown-model estimate refusal, flat-model long-context disregard and oversized long-context clamp. Keep mixed five-minute/one-hour write allocation and short/all-long/mixed long-context allocation with original fixed oracles. Real parser/refusal/bounds alarms are knowingly lost without equivalent replacement; retained tests do not validate provider rates, actual billing or request threshold classification. Preserve the archived usage-scan-append source-freeze receipt without transferring historical execution/performance credit. No fresh runtime result is claimed. Audit3108 source-only reduction (3094/3095/3100): retire 27 authored/30 expanded cases, including complete markdown view-state, file-preview link-open and CLI agent-server-route suites, without replacement. Deliberate losses include preview visibility/reference lifetime and same-path owners; SSH stat, directory/missing-target, explicit-null owner, nonmarkdown line/column, local URI routing, remote-to-client guard and same-file reuse; document-preview source-owner/folder/reuse routing, stable grant location and outside-workspace POSIX/Windows request projection; and verified remote CLI send/check refusal, suggested --on argv/copy, shell no-probe bypass, unverified-launch admission and older-peer refusal. Retain two markdown source-runtime/qualified-reveal alarms, one stale grant-rejection fence and two remote read/mutation evidence policies, with original callbacks. Final last-wins reveal did not prove transient cancellation; CLI prerequisite did not prove no real send, and envelope tests do not execute server refusal. No fresh runtime, rendered UI, actual file/SSH/paired transport, authorization, mixed-version or performance result is claimed. Audit3096 source-only reduction (3087/3088): retire 69 authored/76 expanded cases, including complete recovery-portals and reconnect-banner suites. Intentionally lose dead/default TUI replay, generated alternate-frame style composition, reset/mode/dimension and legacy missing-mode-boundary alarms, UI notice/action/reveal policies, and isolated recovery lifecycle variants, without equivalent replacement. Retained registrations and callbacks are unchanged; headless cells are not pixels, and no fresh runtime, host, SSH, WSL, rendered-app or performance result is claimed. Audit3086 source-only reduction (3079/3080/3081): intentionally retire 93 authored/100 expanded mock-boundary cases, including the complete spawn-errors and SSH reconnect overlay suites, without replacement. Retired alarms include spawn classification/ownership, reply ceilings and renderer-write failure recovery, disconnect/detach fencing branches, authority facts, and overlay retry/visibility wiring. Retained callbacks are unchanged; no fresh execution, real PTY/SSH, rendered UI, or performance result is claimed. The direct side-effect-facts selector retains six cases: replay exclusion, live sequence handling, stale disposer ownership, one handoff drain, drain-before-snapshot, and stale replacement-snapshot refusal. Successful current-entry snapshot application is not witnessed by the retained snapshot case. Audit2432: The broad unit command loses the isolated BranchPicker open-change notification sample. Its unique true/false callback alarm is intentionally retired; reopening/status-refresh behavior was not exercised. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2425: The broad unit command loses the workspace-copy-status supplied readError forwarding sample. It did not exercise the branch-switch blocking promised by its title. This alarm is intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2417: The broad unit command loses two ordinary clean Git cherry-pick/revert success samples and two terminal startup foreground-read work-budget samples. These unique alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2412: The broad unit command loses the whole six-case fake-React-hook scroll-anchor suite, two generic draft-retention samples, a simple new-agent order sample, a real history-publication batching-count sample, an unmounted handoff abort/timer sample and three basic WSL preview/error samples. These alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2404: The broad unit command loses the standalone share-name lookup 503 propagation suite, initial deletion placement-kind sample, direct changed-mtime stale sample, first-pass rollback existence example and abandoned-preparation directory sample. These exact alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2397 review amendment: The broad unit command loses three standalone suites, two partial-case definitions and two URL table rows across package/download/placement tests. Keep initial wrong-port authorization, modified independent-copy digest refusal and abort-after-begin cancellation dispatch. The remaining alarms are deliberately retired; no equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2393 current-parent refresh2401: Remove the basic skill-install service alias sample and original public managed-remove receiptless refusal case. Preserve the upstream request ownership suite and transaction interruption coverage. No equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2389: The broad unit command loses the missing-preview suite, plain-global destination sample and prepublished-receipt recovery example. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2385: The broad unit command loses four authored walker/staging/protocol examples (six expanded cases); no equivalent replacement or fresh validation is claimed for the reduced suite. Audit2383: The unscoped Vitest command no longer includes the removed Antigravity catalogue suite; its exact provider-root/owner example has no equivalent replacement or fresh validation claim. Audit2377/2381: The unscoped Vitest command includes the reduced bundled-skill and native-discovery suites; the eight removed backup/legacy/catalogue/symlink/SSH-builder examples have no replacement-equivalence or fresh validation claim here. Audit2162: Reduced inventory-authority source intentionally loses the examples recorded in knownGaps; historical execution is not validation of changed bytes. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2095 current-parent preparation2126: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2090 (sources2088/2089): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2086 (sources2082/2083): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/runtime/orca-runtime-tests/terminal-handles-part-02.spec.ts: recovers a moved SSH pane through the tab it now sits in, not the one its lease froze; reports a plain expired orphan; does not report a pane whose only recent lease was superseded; does not report a pane whose only recent lease had its relay id recycled; picks the eligible orphan over a superseded predecessor that matches first; collects the same tabs the per-tab reader reports, in one sweep of the leases; reports no candidate when no lease names any of the worktree tabs. src/main/runtime/orca-runtime-tests/runtime-availability.spec.ts: starts unavailable with no authoritative window; reports the configured Windows terminal shell on status; reports floating workspace availability from settings on status; polls floating tabs with targeted PTY liveness and no repo/provider inventory; hydrates persisted tabs when the store cannot report repos; advertises browser screencast only when a renderer window is available; routes mobile Codex reset consumption through the account mutation coordinator; maps a definite pre-provider rejection into an authoritative current snapshot. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2003: Remove SSH/absent-inventory attach refusal, later-subscriber retry, no-view adoption/takeback, provider-tail/unknown-read projections, failed-keystroke retry and simpler loss reattach examples. Keep the existing-subscriber inventory-ready retry alias only at its retained callback, plus retained held-input cancellation/replacement and overlapping attach/loss fences. The inventory driver also loses the whole empty-worktree-publication registration and folder-host/unverifiable scalar examples. Retire the entire dated10-case attach receipt; retain16 independent receipts only in their original scopes. No retained-memory or real-daemon measurement follows from supplied provider inventories. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1991: Remove initial-snapshot sequence-domain, limited-tail/truncation and unknown-output-sequence aliases whose callbacks are removed. The source retains partial-chunk replay and requested-snapshot retry/admission at supplied snapshot/data seams, not equivalent replacement or measured retained-memory proof. Preserve the existing stream/pending-wait capacity aliases only to their retained owning multiplex callbacks with supplied PTY resolutions. Removing the sibling-PTY heartbeat dedup work-count sample does not establish a new decorative fanout budget; the unrelated-PTY cancellation fence survives. Preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Remove the reasonless-close selector and narrow census aliases to actual retained runtime and injected-inventory callbacks. The removed synthetic census-dedup and isolated pre-boundary timing cases receive no replacement credit; preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1939 (sources1934/1935): Delete the synthetic watcher-synchronization and partial-reconciliation suites. Retire all affected host-fact, capability-owner, activation-residue and retention-cap aliases because the remaining callbacks do not establish those full claims. Keep exact local hook/timer, byte-stream side effects, exit/disposal, scroll-intent cleanup and deterministic local rank/TTL progression callbacks within their mocked-host scope. No physical paired-host retention, resource budget or equivalent replacement evidence is assigned. The generic broad test command remains a runnable discovery command, never a dated execution receipt. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete the complete hook-agent-status projection suite and its two behavioral assertion aliases. Supplied stored hook/title/resume/staleness/rename/question/generation/PTY-retirement/snapshot-version projections are intentionally lost. The separate osc-status-scan gate mentions this source only in existing historical notes and receives no mutation. No measured hidden-output retention, CPU/RSS or resource budget result is claimed by the deleted source or this audit. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Module ownership cleanup retires the modeled cold-park private watcher/render/work-count suites under the current test policy. Their assertions are no longer active evidence. Retained lifecycle tests and headed/headless journeys do not establish equivalent coverage for those removed harness alarms. Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1634 removes low-value IPC, filesystem and runtime projections, argument inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained cancellation, ownership, authorization, filesystem and SQLite boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1627 removes low-value mocked daemon projections, scalar tables and duplicate terminal examples without equivalent replacement coverage. Per-source reviews record retained terminal content preservation, process ownership refusal and recovery boundaries together with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Retained exact unchanged-source receipts remain the only current execution evidence. Reduced selectors have no fresh execution result. Audit1417 intentionally deletes src/renderer/src/components/terminal-pane/pty-connection-hidden-tui-snapshot-replay.spec.ts: Loses rich hidden snapshot sequence replay/grid resize and forced repaint after hidden snapshot alarms, including live-trigger deduplication. deletes src/renderer/src/components/terminal-pane/terminal-cold-park-verdict-loop.test.tsx: Loses modeled React oscillation alarm; real pane/watchers are not exercised. deletes src/renderer/src/runtime/remote-runtime-terminal-parse-backpressure.test.ts: Loses delayed credit until parsing, malformed frame/unknown stream handling, discarded transformed output recovery and failed ACK rearm alarms. No equivalent replacement coverage or fresh result is claimed. Historical coverage account: Audit1412 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): This audit removes the browser response-after-manual-disconnect example. Its distinct in-flight response fencing alarm is lost; retained queued-call disconnect tests are not an equivalent replacement. Historical commands and results remain historical. Deterministic headed macOS runs launch an isolated Orca desktop server and a separate paired web client. A byte-identical headless run uses an isolated `orca serve` host. Both create six real paired host PTYs with bounded high-output scrollback, prove sustained output while all six client xterms are warm-mounted but hidden causes zero renderer scheduler work, then drive 180 timed real-PTY spinner frames through a second production `session.tabs.subscribeAll` transport and the real Zustand store. Each worktree must publish and apply only its exact initial-working and final-idle titles. Both topologies ordinary-park five xterms without enabling the lossy retention budget, assert bounded cells/heap/timer lag, then restore the bounded authoritative tail exactly once on the original PTY including output produced while parked and continued input/output. The headed oracle additionally keeps every remote target workspace and terminal unmounted in the host renderer before and after client recovery. Production-parity React contracts reproduce and remove the independent cold-park watcher/title feedback loop, including memo-cache discard, StrictMode cleanup replay, detached split-PTY replacement, and the zero-park fast path. A deterministic cross-boundary contract drives 24 real PTY trackers in distinct worktrees through 2,880 decorative spinner and bare-native redraw chunks and counts host publications, serialized bytes, renderer apply calls, and store mutations while preserving exact per-PTY raw chunks and per-worktree semantic transitions. Fake-clock continuation beyond the 30-minute stale boundary requires one deduplicated refresh per worktree every 15 minutes, globally spaced by at least 50 ms, with every mirrored working status still fresh. Exact-identical Pi plus rotating normalized Pi/Grok frames renew coarse working/permission state; rich prompt/tool/question fields retain their original 30-minute lease, and `stateStartedAt`/acknowledgement identity remain stable across title/hook source swaps. A separate headed desktop-client journey relaunches the host main process while retaining the daemon and a daemon-backgrounded PTY, then requires first-observation foreground sync and continued input/output on the same PTY. Unit coverage keeps layout versions out of snapshot output high-waters when a restored snapshot has no output sequence and retries an existing subscriber only after authoritative provider inventory proves the retained PTY exists. Separate headed/headless ACK-starvation tests recover one stalled stream without replacing its PTY. A headed output-drop oracle proves a successful snapshot probe cannot certify a stale live stream when the authoritative PTY sequence advanced beyond the client high-water. Unit coverage requires an unsequenced client to establish a first-probe baseline, remain attached at the same sequence, and recover only after a later probe advances. A capability-disabled run proves legacy hosts retain the prior lossy limit/TTL fallback. Unit tests cover exact-owner capability routing, raw-stream release, singleton side-effect facts with timed handoff cleanup, 64 simultaneous synthetic-title sources with zero decorative client events after convergence, per-client late-subscribe recovery, semantic bell/title transitions, local animation-frame preservation, legacy no-output-pause delivery gating with exact snapshot restore, provider-authoritative snapshots, 128 active streams plus retry after a 129th-stream capacity rejection, capacity-pressure backoff, full split-leaf remint reconciliation, truncation, and manual-disconnect queue fencing. Linux, Windows, live SSH, and production-scale paired hosts remain gaps. The audit removed the E2E parking override/debug-handle suite. Override exposure guards, delay/retention independence, TTL filtering and debug-handle forwarding alarms are lost. Retained real parking journeys do not establish equivalent test-harness configuration coverage. The test-value audit removes separate responsive-stream, intervening-control-frame and capacity-error classification examples. Retained multiplexer checks use fake clocks and captured transport callbacks; their per-stream isolation, deadline and probe-baseline assertions do not prove an actual host restart or equivalent replacement coverage. Historical run commands and results remain historical. The test-value audit removes the standalone retained/live metadata projection and additive-preference negative example from runtime-client-events.test.ts. Its remaining case checks partial-authority event admission through a captured callback; it does not establish full-pair projection, actual peer delivery or equivalent replacement coverage. Historical commands and results remain historical. The isolated accepted-handle-events observer suite is removed. Its runtime/worktree/pane membership, once-only delivery and listener-release ledger alarms are lost. Live hidden-retention evidence does not establish equivalent observer coverage. Audit1292: The entire host-session mirror empty-inventory settle suite is removed. Live-unpublished versus genuinely-empty hydration, same-ID revision response/in-flight fencing and cleared-tracking pending-probe invalidation alarms are lost. The singleton store and inventories were mocked; no real host census or resume delivery or equivalent replacement coverage is claimed. Audit1302: src/main/runtime/session-tabs-inventory-publication.test.ts: Keep actual runtime public inventory authority across renderer epochs/resync, fallback, aborts and invalid graph publishers. Remove copied nonempty publication, private scan counters/collector and known-host replacement, fake refresh that performs the restoration itself, environment capability flag, and private resume-store characterization whose fixture supplies reservation/rollback ordering. Lose isolated refresh/churn/receiver/capability and copied-payload wiring alarms; no equivalent replacement. Reduced selectors require fresh validation; prior full-suite receipts do not validate removed or changed coverage. No equivalent replacement or physical-provider claim. Audit1312 removes low-value imported specs from aggregate test drivers; old whole-driver execution receipts are archived. Retained registrations are unchanged. No equivalent replacement coverage is claimed. Audit1318: src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts: Retain real local encrypted WebSocket regressions for pre-ready socket replacement preserving a request, close-before-ready logical subscription cleanup, unrelated RPC surviving another deadline, and pending setup abort leaving a sibling pending. Host server is synthetic and uses production crypto; kept scenarios also retain internal diagnostics/memory assertions unchanged. Remove happy routing, authority-envelope, unknown-ID/log, cleanup enum, binary, keepalive/liveness and production-budget/private socket inventories; intentionally lose those alarms, no physical host authorization, independent crypto or remote provider claim. Reduced selectors need fresh validation; historical full-suite receipts do not validate the changed coverage. No equivalent replacement or physical-provider claim. Audit1346 removes the entire private-state-injected session-tabs rich-status boundary suite. Its stale task/question, neutral-title preservation, owner-change and provider-generation alarms are intentionally lost. Retained real terminal journeys do not establish equivalent replacement coverage. The prior mixed 42-contract execution receipt is historical and must not validate the reduced current selector; fresh validation remains required. Audit1352: focused Linux unit selections validated on source head b638e07d395b76af3ba6b03761a1a0fe7e5e026e. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1360: focused Linux unit selections validated on source head 415c9cffc2d10024131ec4b6721767a22195de6d. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1383: src/main/runtime/orca-runtime-tests/worktree-native-chat-setup.spec.ts reduced. Lose command-list/receipt/default/background activation matrices whose provider spawn returns canned IDs. Retained test proves actual tab allocation separation, not terminal startup. No equivalent replacement coverage is claimed. Existing exact unaffected receipts and their platform/provider/budget claims remain scoped to unchanged selectors. Changed optional selectors have no new execution result. Audit1391: src/renderer/src/components/terminal-pane/pty-connection-remote-pause-drop-notice.spec.ts reduced. Lose repeated quiet switches avoiding snapshots and legacy host without drop-report capability requesting a snapshot. Retained imported registrar uses fake transport/xterm writes, exercising real gap/restore lifecycle rather than actual terminal rendering. No equivalent replacement coverage is claimed. The existing primary-selector receipt and its claims remain scoped to their unchanged sources; the broad optional command has no new execution result. Audit1396: src/renderer/src/components/terminal-pane/terminal-parked-watcher-reconciliation.test.ts reduced. Retire standalone reconcile set output and positive untouchedFreshSpawn/workspaceOwner copying alarms; no native watcher execution claim. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1401: src/main/runtime/orca-runtime-tests/mobile-session-tabs-duplicate-pty-repair.spec.ts removed. Loses listing-on-already-repaired-data alarm; it never established runtime repair invocation. src/main/runtime/orca-runtime-tests/mobile-session-tabs-split-agent-tab.spec.ts removed. Loses actual mobile split sibling shell versus recorded-agent resume command alarms; no equivalent coverage asserted. src/main/runtime/orca-runtime-tests/worktree-native-chat-setup.spec.ts removed. Loses separate setup/startup tab result in that manually assembled path. src/main/runtime/orca-runtime.test.ts reduced. Driver registration/import of a whole-deleted selected spec is removed; directly authored cases remain unchanged. No extra authored removal credit. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1402: src/renderer/src/components/terminal-pane/pty-connection-park-reveal-model-snapshot.spec.ts reduced. Loses basic paired serialize/initial replay forwarding check; hidden alt-frame grid/precedence policy remains. No real terminal renderer claim. No equivalent replacement coverage is claimed. The existing primary-selector receipt and its claims remain scoped to their unchanged sources; the broad optional command has no new execution result. Audit1412: src/main/runtime/mobile-session-tabs-agent-status-heartbeat.test.ts reduced. Loses FIFO fairness/spacing, semantic bypass/cancellation, delayed-boundary scheduling and teardown timer-cleanup alarms. Retained fixed emission cases do not replace those outcomes. No equivalent replacement coverage is claimed.", + "coverageNotes": "Audit5772 companion to audit5768: Retire the whole hidden-view parking policy suite. Direct oldest/cap/TTL/last-active worktree ranking and equal-hidden-time tab activation-order alarms are intentionally lost without equivalent replacement. Narrow one compound unit command and remove the parking testFiles entry. Physical parking/restoration/stream-budget selectors and assertions remain unchanged at their own exact scope; they are not certified as replacements. Complete dated evidenceRuns and unrelated selectors/assertions are unchanged; none selects these retired suites and none validates the narrowed command. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account preserved verbatim below as historical, including any older then-retained coverage claim: Audit5571 removes the entire unrelated-PTY mobile heartbeat callback suite and its active selectors; its bookkeeping alarm is intentionally lost without equivalent replacement or fresh runtime evidence. Fourteen unrelated dated receipts retain their exact original scopes. Historical account follows: Audit5534 removes the whole last-active retention TTL selector suite (one authored/finite case). Its absolute-TTL and inside-boundary alarm is intentionally lost without equivalent replacement or fresh execution. Active command/file selectors drop only that suite; historical receipts remain at their original scope. Audit4362 intentionally deletes the imported stale-waiter retry and manually assembled OSC9999 mobile-republish cases, plus the mocked missing-worktree cleanup suite (4 authored / 5 finite cases in three suites). Lost alarms include repeated unread worker_done pointers, working-to-waiting mobile status publication, missing-worktree filtering, and scoped daemon shutdown with unrelated duplicate identities. No replacement coverage or new platform proof is claimed. Audit3994 retires two authored callbacks imported by the shared construction test driver: split OSC 9999 carry and rendererless status ownership, plus OpenCode permission text taking priority in status and tui-idle refusal. Remaining imports and selectors keep their scope. No equivalent replacement or fresh gate execution is claimed. Audit3580: Retire the whole one-case runtime host environment prototype/subclass suite. Intentionally lose the exact configured lower-case Windows Claude home to account-identity normalization and host-account override precedence alarm previously retained by Audit3129. No equivalent replacement or fresh runtime validation is claimed. Earlier dated keep statements below describe their historical source scope; the current suite is removed. Audit3563 scope: retire the whole Kiro OSC/hook identity suite and the OpenCode2 identity-only case; reduce Codex cached startup child-retirement and missing-session-ID tables to one case each (2 authored/4 finite removals). Intentionally lose Kiro alias/session continuity, OpenCode2 completed OSC identity continuity, cached replacement without relay-generation restart, and missing-previous-ID context-preservation alarms. Remaining provider, remote compatibility, persistence and cross-session pollution cases are not equivalent replacements. Also remove the private Codex roster-size assertion while retaining public child-absence checks. Historical evidence retains its original source scope; no new execution or transferred pass validates these reductions. Audit3446 composes ROOT-adopted3441/independent3442: intentionally removes100 authored registrations/119 potential expanded cases (118 conditional-active before platform gates) across16 sources, retaining11 authored/13 expanded cases and deleting6 whole suites. Two parent registrar import/call cleanups and the unused68line CLI recording fixture carry zero test credit. No equivalent replacement or fresh execution is claimed. The decorative fanout suite retains only real OSC9999 ingestion through runtime/title heartbeat/viewer past the stale boundary, preserving stateStartedAt and clearing expired prompt metadata. Spinner volume/zero-work inventories, Pi/Grok frame tables, rich-status and foreground-reset examples are retired. Existing receipts for separate paired-terminal sources retain their original scopes. Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3342 removes three supplied activation/inventory fallback and same-handle retry examples; their fallback/retry alarms are intentionally lost without equivalent replacement. The exact mounted-HUB pending old-stream-end versus replacement-snapshot registration and its assertion remain. Unrelated dated macOS receipts retain only their original scope; no fresh runtime, provider, performance, mobile, mixed-version or cross-platform validation is claimed. NEXT46 terminal-owner layout and whole-case policy: src/renderer/src/components/terminal-pane/pty-connection/tests/pty-connection-hidden-replay.test.ts, src/renderer/src/components/terminal-pane/pty-connection/tests/pty-connection-visibility-and-exit.test.ts, src/renderer/src/runtime/hosted-terminals/streams/remote-runtime-terminal-stall-recovery.test.ts. Complete retired/reduced selectors lose their listed alarms; retained cases have no transferred historical pass or equivalent replacement coverage. Unaffected dated receipts retain only their original exact scopes. This metadata edit is not fresh execution evidence. Historical prior account (preserved verbatim): Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: restarts only the stream whose renderer delivery credit never settles — An unreturned renderer delivery credit stalls only its stream, leaving healthy sibling/shared transport alive. Fake-clock deadline plus real multiplexer unsubscribe isolates recovery ownership.; probes then restarts a stream when an entered command receives no frames — Entered command produces no output; actual multiplexer must probe then close only its stalled stream after probe timeout. Distinct response liveness from parser credit.; establishes a probe baseline before recovering an unsequenced stream — 142-line manual five-probe baseline/regression sequence derives request IDs from encoded mock traffic and checks repeated no-close/close choreography. Oversized algorithm/state-machine example; no actual renderer/host command or recovery delivery. Retires unsequenced/unchanged/regressed baseline classification alarms.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces remote-runtime-pty-transport-unpublished-host-graph.test.ts, retiring its direct published-empty-graph omission-to-pane-exit alarm. The unchanged bounded unpublished-frame/pushed-recovery and stale-handle park/manual-retry cases are narrower, not equivalent replacements. Both complete three-case Linux receipts dated 2026-11-04 are archived as historical, including source heads; they do not validate this reduced selector. Remaining fourteen active receipts are macOS only. No fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3318 composes adopted sources 3310, 3313 and 3317: intentionally retires 71 authored declarations and 102 expanded cases, including whole terminal-detach agent-retention, seeded batch/single open-files equivalence, shallow context-menu shortcut-badge, mocked active-workspace delete-dispatch, workspace session hydration, SSH target cleanup, editor session hydration and worktree terminal purge suites. Lost alarms include chained transfer alias and immediate close/exit retention; batch/single divergence, survivor/selection/map preservation and input nonmutation across 400 imperative seeds (one registered case); disconnected pending-handle retry, authoritative absences/close-record shortcut/older-host absence and published-presence/unpublished-frame examples; published empty host-graph omission to pane exit; legacy search ranking/exclusion fallback; provider request upgrade/dedupe/finalizer ownership; asynchronous PR suppression/primary-change and same-number different-repository URL rejection. Deletion routing loses host/instance qualification, paired and legacy mapping, folder ownership, active-versus-hover/menu-row selection, ambiguity, modal/editable/creation/view/main/deleting/missing guards and shortcut advertisement. Unchanged real keyboard/hover/confirmation/catalog E2E remains narrower, not an equivalent replacement. Additional losses include scripted old-host disk/UTF-8/noop/baseline and landed/unlanded lost-reply/replacement-retry outcomes; ordinary/repeated healthy-link reattach; cross-owner terminal/chat binding; oversized replay permanent-unavailable classification; floating reveal keyboard ownership/close/disable/listener disposal; naming/retained-turn/Sleep/error/close/reject status tables; SSH membership prune/new-target-only reads and environment/local bucket isolation; same-frame receipt capacity and positive bare/headless publisher readmission. These actual regression alarms are deliberately lost; no fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3312 composes adopted sources 3302 and 3308: deliberately retires 33 authored declarations and 36 expanded cases, including the whole backend startup-focus, active-browser IPC-close-routing, remote-browser-creation and agent-terminal-presence suites. Intentionally lost alarms cover distinct six-pane reconnect handles; SSH host label/Connect callback, unhydrated visit cleanup, repo cache aliases and hidden worktree/tab/PTY cleanup; adopted-agent startup focus and viewer navigation/reuse; staged, pageless, source, stale and orphan browser-close routing; web local-materialization refusal, desktop incapable-host fallback, failed/thrown remote creation and paired-web sign-in refusal; BOM/NUL and remote/local custom-editor byte-read examples; immediate folder activation and unread clearing; and batching idle/coalescing, accumulated byte ceiling, leading-edge-disabled, standalone synchronous oversize rejection, validation yield, deferred pending-tail order and both viewport-clear examples. The newly reintroduced agent-terminal-presence suite also loses actual terminal-status membership positive and nonterminal-status callback suppression alarms, including the recent 40916 guard regression; the older different 2133 presence-suite history remains historical and receives zero duplicate removal credit. These real regression alarms are intentionally lost. The unchanged survivors provide narrower coverage, with no equivalent replacement or fresh gate, provider, rendered, remote/mobile, mixed-version, cross-platform, soak or measured-budget validation claimed. Audit 3301 combines adopted source batches 3296 and 3299: retire 27 authored declarations and 36 expanded scenarios, including six whole suites. Intentionally lost alarms cover failed-verification/recovery/restart counters and mocked hosting/toast; early overlapping pane-read scheduling/count; unreadable removal listing draft guard; bulk-purge remote-qualified and raw-local guard maps; initial-snapshot blank/mode/oversize/printable/fresh-spawn callback and replay examples; fallback mobile file close and ordinary MRU; default queue overload/drain; seeded browser-page reuse and supplied missing-page URL recreation; ambiguous sleep/hibernation owner refusal and untouched bindings/origins; ordinary selection/activity/fallback priority; skip-remote success and retained hints; supplied structured-chat unsent retention and scoped removal draft eviction; caller-chat focus precedence; open/draft PR cache eviction and merged-head fallback result inventories. Retained adverse-ordering and ownership cases are narrower and do not establish equivalent replacements. No fresh runtime, native, physical provider, cross-platform, mobile or mixed-version evidence is claimed. Audit 3292 combines adopted 3285/3287/3289/3293 removals: 40 authored declarations and 47 expanded scenarios, including whole frame-editor-view, ambiguous remote-delete-refusal, unverifiable-host subscription and editor-close cleanup suites. The previously reviewed dock-badge suite was already removed upstream in PR 40895 and receives zero new removal credit. Intentionally retired alarms include background browser selection and last-tab landing; main startup fallback, SSH project cleanup/survivor routing, exact-PR contradiction/saved-push positives, replay/sidecar rollback and wrapped remote error normalization; records/snapshot missing-diff hydration, ambiguous folder-owner delete refusal, focus no-op notifications, nested editor context-only cache check, pending broadcast-first status and ordinary four-confirmation aggregation; preview-source frontmatter pruning, approved local/runtime agent dispatch, non-GitHub legacy PR cache invalidation, stale merged-head transient-error fallback, empty-queue immediate query reply and unverified-to-concrete preflight risk. Additional intentionally retired alarms are injected host subscription/unsubscribe counts, synthetic editor reveal/draft/fallback/scoped close, ambiguous unread refusals and hidden mark/read roundtrip, immediate connect backoff/noError, positive mirrored evidence-clock renewal, supplied VM failure/success projections and git-local/folder-SSH wake permutations. Remaining temporal/ownership cases are narrower; no equivalent replacement or fresh execution is claimed. Audit 3283 removes 20 authored declarations and 31 expanded scenarios, including two whole suites. Retired alarms cover PR refresh-state pruning, shared runtime subscription cleanup and store isolation, language content-change routing and older completion ownership, ordinary panel retry-timer cleanup and pending loading, four hosted-review lifetime permutations, mocked terminal creation error/order wiring, five sleep-inventory variants with pending-frame-only assertions, palette fallback/composite highlights, Windows/UNC encoded-editor input rows, mixed-repository partial failure counts, title setters and generated-title bypass/replacement, five window-close coordinator delegation/guard/finally branches, and ambiguous-old-record frame reveal. These regression checks are intentionally lost under the test-value audit; retained cases are not equivalent replacements. Prior coverage notes and receipts remain historical. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit 3256 removes these specific alarms from the broad root unit commands: skill dialog active-share selection, close and pending-share handoff; simple keyed-record deletion; marker live-region insertion, simple landing and nine baseline policy examples; General search/control navigation inventory; orphan-count cache bootstrap; seven Codex code classifications and HTTP 429 warning mapping; two skill unread-root verdict examples; peer-mail payload and conversation-ID rejection; and the GitHub organization TABLE text-field optimistic rollback/failed-envelope example. These include real behaviors; retained tests do not provide equivalent coverage for every removed scenario. Mobile losses are recorded separately and are not coverage of these root commands. Audit3246 retires NewRowsMarker reveal/no-repeat and pane-scoped beforeinput checks; skill-owner option availability/count/dedup/order; six styled Input/Textarea IME forwarding rows; the static Codex/OpenCode smart-key inventory; tab-map AST ratchet diagnostic fixtures; child-roster work-budget and retained-aggregate alarms; malformed persisted floating-cwd fallback/no-crash/empty exact-root checks; the unanswered-host empty-list discriminator; the direct invalidated-cache commit-false assertion; one redundant digit-keyup IME row; cached non-supported Claude title-generator rows; and the duplicate late naming-result singleton. These root broad commands lose those specific alarms without equivalent replacement. Distinct retained owner/state checks have their own bounded claims; the real scheduler still rejects stale response data, while the direct false-return alarm is retired. Audit3231 retires supported-host restore-pane key mapping, closed/open creation-sidebar toggle visibility, unrelated scope-error/null classification and quick-submit reveal/no-create checks. These broad commands lose those real narrow alarms; no replacement coverage is claimed. Audit3219 removes the synthetic Cmd+J extra-source suite; this broad command no longer checks its match/tie placement and selection, announced count, empty-query cap, or workspace hiding with retained recent tabs. No replacement coverage is claimed. Audit3209 composes approved sources3202/3206: deliberately retires seven authored/expanded cases in four whole suites without equivalent replacement. Work-item queries lose real GitHub/GitLab oversized ASCII secret-prefix empty-query and whitespace-before-trim refusal alarms; inputs share the imported size bound and exercise only its fast length branch, with no multibyte or actual provider/exposure guarantee. Skill sharing loses complete/partial managed-bundle and destination-ambiguity association checks plus three negative origin/path/scheme admission examples; these do not establish uploaded contents, arbitrary-URL fetching, authorization or execution. Retain exact originless-project direct-link fallback, cloud-delete confirmation, bundled-target repair/owner isolation and explicit Windows-host preference over stale WSL suites. Rejected3201 runtime-preference removal is excluded. No real cloud/network/host/disk, mobile or mixed-version execution validation is claimed. Audit3200 composes approved source3194: deliberately retires thirteen authored registrations/twenty-seven expanded cases in six whole automation host/list policy suites without equivalent replacement. Real RPC category/retryability and wrapped-timeout recognition, unscoped-failure/scoped-success health evidence precedence, exact-ID create selectors and per-run workspace omission, paired-web local/SSH/absent host catalog routing, incompatible/removed/unhydrated/offline execution health, runtime-before-nested-SSH recovery dispatch, and no-owned-focus/successor/foreign-list focus policy alarms are consciously lost. Retain exact20line orphan allow/refuse/precondition and exact90line cross-host same-ID search suites. No retry-timer/fence lifecycle, actual reconnect/network/write delivery, native focus, mobile/mixed-version runtime or disk persistence coverage is claimed. Audit3191 combines approved source3182/3187/3188: deliberately retires thirteen authored Vitest registrations and fifteen expanded cases, including five whole suites, without equivalent replacement. Attachment intake loses real portal/native-capture terminal interception and unowned-container refusal, immediate child-only committed availability/claim-ref negotiation and delivery, and direct-target over stable focused/background composer routing through disable/re-enable/remount and independent question focus. Exact destination/cache/draft and final-stat owner/workspace/File-release suites remain; they do not replace Surface recipient routing. Automation authoring loses destination runtime catalog membership, local/direct-SSH exclusion of paired-runtime repos, unknown-runtime empty catalog, logical project/host/setup/repo/path context payload, and missing/nonready setup refusal; these were genuine direct helper alarms, while exact schedule transformation, legacy schedule and setup-decision suites remain. Agent picker loses setup-chat/terminal/missing-installer/unsupported-or-unknown-host row projection samples and the ordinary unsearched menu variant; the entire original26-line resume recipe suite remains, including reported bypass versus default/absent permission modes, as does the exact search-result menu callback with its fixtures, model/effort commits and staged Arguments reopen outcome. Rejected predecessor3180 full recipe deletion is excluded. No actual native drag/cursor/focus/IME, upload bytes or disk/restart persistence, full automation save/scheduler/runtime transport, real resume-process flags/environment delivery, or native menu/rendered layout validation is claimed. Audit3178 combines source3169/3170/3175: deliberately retires eight authored units (six Vitest cases and two imperative custom relay scenarios), including two whole suites, without equivalent replacement. Voice Section loses per-model pending-delete isolation across interleaved A/B completion and the two-success refresh-call alarm; exact VoicePane delayed key-clear/newer enabled-toggle merge remains and does not replace row deletion coverage. Speech loses dedicated rating-scale/inclusive-ceiling, unsupported-versus-unmeasured, explicit/system-language precedence/locale alias, accuracy versus fast named/default/best-measured selection, and unmeasured/no-match examples; exact offered-user-pick versus retired-selection case and its fixture remain. Relay loses legacy ping-delivery count/liveness sampled before the silence deadline and grouped malformed Bearer/host-ID 401/429 routing checks; twelve real Worker/DurableObject/shipped-client scenarios remain, not equivalent replacement for those narrow alarms. Six prior speech cases are not all deleted: approved successor3175 keeps the original user-choice case. No actual credential/file persistence, native/GPU/engine/download delivery, production assignment policy or deployed-runtime validation is claimed by this reduction. Audit3165 combines source3160/3162: deliberately retires six authored/expanded cases across three whole suites without equivalent replacement. Launch/status losses: observed React-render pending/resuming coordination across settings and deferred offer read; stale-offer reread suppressing dialog reopen; held-local-chat recovery visibility with new-chat preferences off; disabled-local admission avoiding offer RPC despite an injected but unconsumed paired-tab fixture; and run-only lost-reply uncertainty reachability until direct viewed-run retirement. Launch probe does not prove arbitrary synchronous-store atomicity, the paired fixture is not remote runtime enrollment, and the status case directly marks viewed state rather than rendering the summary. Crew-hook losses: old-host method_not_found cache persists across party changes but is released by independently supplied connection generation/verified pairing status or pairing revision, with actual frame publication and teardown. These are real narrow coordination, admission, uncertainty and mixed-version cache alarms consciously lost. Exact web verified-runtime writer handoff guard remains; it does not replace those alarms or prove live host/native/mobile delivery. Audit3156 combines3147/3150/3152/3153/3154: deliberately retires39authored/40expanded native-chat recovery cases, eight whole suites and two orphan test-support files without equivalent replacement. Lost alarms: lost-reply unconfirmed reconciliation, skipped rows/counts and missed-frame repair, unknown/pending outcome and omitted-failure-list compatibility, uncertain history after dismissal, retry/refusal/dismiss lifecycle, hidden/consumed picker ownership, result-tree keyboard focus/disclosure and all-skipped retirement; unconfirmed-over-conflict guidance and failed-chat changes despite older host timestamps; nearest-listed ancestor/cyclic forest shape, descendant membership, host ordering/missing-host local fallback; skipped/readiness/admission counts, provisional skip/progress monotonicity, early per-chat verdicts with batch pending protection, older-host waiting, start-slot/delivery distinction, retry-over-failure and unknown-after-withdrawal attention; remote snooze/reconnect/reoffer, unseen mixed summary through open/close, watched completion retirement, new success beside old failure, failed-reread mixed-result preservation, filter/collapse completion resets, retry summary replacement and current-offer/history selection; cross-host workspace identity, rendered cyclic reachability, nested tri-state/toggle propagation, project eligibility isolation and collapse preserving selection. Exact fallback-list completion barrier, batched verdict/cleanup retention, stale-read versus dismissal publication race, and requested-but-never-rendered finished-run retirement remain; they do not replace retired alarms. Audit3146 combines source reviews3132/3133/3135/3138/3143: intentionally retire20authored/31expanded cases without equivalent replacement. Provider-session losses: structured-native terminal-resume exclusion, metadata-less completed identity, new-turn completion clearing, Pi provider-only/periodic/manual promotion, changed-transcript launch-config isolation, Pi/omp/prime-agent completed-session remote/manual-shutdown promotion, and quit/done precedence over heartbeat. Side-thread/question losses: finished-pane acquisition, hidden title/recap states, local/relay/relay-done conversation takeover with prompt/session/child resets, plain-message abandonment, compaction/session replacement and completion resets. Codex startup losses: incoming-owner cached child replacement, old-relay foreign live-session correction, completed foreign-root turn-fact permutations. Transcript losses: real temporary-JSONL partial sibling/final-child completion, unlabelled child attribution, compact cached replay preservation and100/1000completed-child roster retention/release. Compiler-ratchet losses: valid-line uncompiled-list parser grammar examples and injected-existence stale-path filtering; these did not exercise actual filesystem canonicalization or build exclusion. These are real lifecycle, ownership, replay, liveness and retention alarms, including recent#40246 regressions, deliberately lost. Retained conditional record replacement, clockless root/SSH owner isolation, persisted main-thread fork rejection, partial/final question-answer lifetime, cached-roster/missing-ID/live HTTP/durable startup boundaries and restarted-relay refusal/acceptance do not replace those losses. No native/SSH/WSL execution or equivalent coverage is claimed. Audit3128 scoped coverage reduction: Audit3121 removes VoiceDictationLanguageSetting.test.tsx (Spanish-to-es callback and unsupported-model Korean option presence) and voice-speech-model-rows.test.ts (provider/language-order/retired-on-disk list policy); these real narrow alarms are deliberately retired without replacement. VoiceSpeechModelSection per-model concurrent deletion remains unchanged. Audit3122 removes the direct absolute/parent-segment sparse-directory exception-type sample and the five-row IPC sparse-preset error-code/non-save table (two authored/six expanded cases). Those real typed-validation and IPC refusal/error-code alarms are deliberately retired. Keep both real symlink/junction floating-directory trust cases and the minimal RPC structured validation-reason serialization case. The RPC case does not replace IPC save/refusal behavior, typed normalization for both path inputs, actual Git sparse checkout or rendered localization. No equivalent replacement or fresh test/runtime/platform/remote/performance validation is claimed. Audit3124 removes ExperimentalPane.test.tsx (ordinary Pet switch callback), WorkspaceDirectorySetting.test.tsx (padded absolute saved-path normalization/no-write blur), and repository-search.perf.test.ts (navigation/selected-pane builder-call policy, fixture cardinality/nonempty entries and renamed project keyword inclusion). These real narrow alarms are retired without replacement; RepositoryPane.search.test.tsx search-to-sparse-editor request remains unchanged. Audit3129: resolver Windows case-insensitive and POSIX case-sensitive configured-env composition plus mocked-base launch-preflight Windows composition are intentionally no longer checked by the two deleted suites. No equivalent coverage claimed. Keep runtime-structured-agent-host-env.test.ts unchanged: configured Windows Claude-home account identity and host-account precedence remain checked. Audit3114 incorporates source3101: retire three structured Claude child-environment wrapper cases covering inherited stamp isolation/default and explicit entrypoint, Windows SDK-key canonicalization/default/duplicate-key order, and configured lookup/final environment/config-dir conjunction. Keep direct auth/session sanitation and Windows-versus-Linux overlay checks, actual executable lookup from supplied inherited PATH, native Windows child environment delivery, and stale option-mutation fencing. These are not equivalent replacements for the retired wrapper alarms. No fresh test/runtime, real login-shell probe, Claude SDK startup, remote/mixed-version, UI or performance result is claimed. Audit3114 incorporates source3105: retire 17 authored/20 expanded daemon launch-note cases, including the entire two-case SessionLaunchNote suite. Deliberately lose split-marker carry across same-token re-arm, stale-token retirement refusal, foreground tri-state and serial settlement, omitted-note/no-incarnation mixed-version policy, sticky retirement, first-incarnation/replacement launch preservation and held-launch precedence. Keep only the unchanged unresolved foreground-read race against a later finished attach. Supplied notes/foreground and runtime calls do not establish actual daemon/main restart, SSH, native Windows observation, mobile UI, equivalent replacement or fresh runtime/performance validation. Audit3114 incorporates source3109: retire six authored/35 expanded pricing cases: 21 accepted model-name examples, 10 unsupported/future-model fail-closed examples, malformed TTL clamp, unknown-model estimate refusal, flat-model long-context disregard and oversized long-context clamp. Keep mixed five-minute/one-hour write allocation and short/all-long/mixed long-context allocation with original fixed oracles. Real parser/refusal/bounds alarms are knowingly lost without equivalent replacement; retained tests do not validate provider rates, actual billing or request threshold classification. Preserve the archived usage-scan-append source-freeze receipt without transferring historical execution/performance credit. No fresh runtime result is claimed. Audit3108 source-only reduction (3094/3095/3100): retire 27 authored/30 expanded cases, including complete markdown view-state, file-preview link-open and CLI agent-server-route suites, without replacement. Deliberate losses include preview visibility/reference lifetime and same-path owners; SSH stat, directory/missing-target, explicit-null owner, nonmarkdown line/column, local URI routing, remote-to-client guard and same-file reuse; document-preview source-owner/folder/reuse routing, stable grant location and outside-workspace POSIX/Windows request projection; and verified remote CLI send/check refusal, suggested --on argv/copy, shell no-probe bypass, unverified-launch admission and older-peer refusal. Retain two markdown source-runtime/qualified-reveal alarms, one stale grant-rejection fence and two remote read/mutation evidence policies, with original callbacks. Final last-wins reveal did not prove transient cancellation; CLI prerequisite did not prove no real send, and envelope tests do not execute server refusal. No fresh runtime, rendered UI, actual file/SSH/paired transport, authorization, mixed-version or performance result is claimed. Audit3096 source-only reduction (3087/3088): retire 69 authored/76 expanded cases, including complete recovery-portals and reconnect-banner suites. Intentionally lose dead/default TUI replay, generated alternate-frame style composition, reset/mode/dimension and legacy missing-mode-boundary alarms, UI notice/action/reveal policies, and isolated recovery lifecycle variants, without equivalent replacement. Retained registrations and callbacks are unchanged; headless cells are not pixels, and no fresh runtime, host, SSH, WSL, rendered-app or performance result is claimed. Audit3086 source-only reduction (3079/3080/3081): intentionally retire 93 authored/100 expanded mock-boundary cases, including the complete spawn-errors and SSH reconnect overlay suites, without replacement. Retired alarms include spawn classification/ownership, reply ceilings and renderer-write failure recovery, disconnect/detach fencing branches, authority facts, and overlay retry/visibility wiring. Retained callbacks are unchanged; no fresh execution, real PTY/SSH, rendered UI, or performance result is claimed. The direct side-effect-facts selector retains six cases: replay exclusion, live sequence handling, stale disposer ownership, one handoff drain, drain-before-snapshot, and stale replacement-snapshot refusal. Successful current-entry snapshot application is not witnessed by the retained snapshot case. Audit2432: The broad unit command loses the isolated BranchPicker open-change notification sample. Its unique true/false callback alarm is intentionally retired; reopening/status-refresh behavior was not exercised. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2425: The broad unit command loses the workspace-copy-status supplied readError forwarding sample. It did not exercise the branch-switch blocking promised by its title. This alarm is intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2417: The broad unit command loses two ordinary clean Git cherry-pick/revert success samples and two terminal startup foreground-read work-budget samples. These unique alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2412: The broad unit command loses the whole six-case fake-React-hook scroll-anchor suite, two generic draft-retention samples, a simple new-agent order sample, a real history-publication batching-count sample, an unmounted handoff abort/timer sample and three basic WSL preview/error samples. These alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2404: The broad unit command loses the standalone share-name lookup 503 propagation suite, initial deletion placement-kind sample, direct changed-mtime stale sample, first-pass rollback existence example and abandoned-preparation directory sample. These exact alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2397 review amendment: The broad unit command loses three standalone suites, two partial-case definitions and two URL table rows across package/download/placement tests. Keep initial wrong-port authorization, modified independent-copy digest refusal and abort-after-begin cancellation dispatch. The remaining alarms are deliberately retired; no equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2393 current-parent refresh2401: Remove the basic skill-install service alias sample and original public managed-remove receiptless refusal case. Preserve the upstream request ownership suite and transaction interruption coverage. No equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2389: The broad unit command loses the missing-preview suite, plain-global destination sample and prepublished-receipt recovery example. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2385: The broad unit command loses four authored walker/staging/protocol examples (six expanded cases); no equivalent replacement or fresh validation is claimed for the reduced suite. Audit2383: The unscoped Vitest command no longer includes the removed Antigravity catalogue suite; its exact provider-root/owner example has no equivalent replacement or fresh validation claim. Audit2377/2381: The unscoped Vitest command includes the reduced bundled-skill and native-discovery suites; the eight removed backup/legacy/catalogue/symlink/SSH-builder examples have no replacement-equivalence or fresh validation claim here. Audit2162: Reduced inventory-authority source intentionally loses the examples recorded in knownGaps; historical execution is not validation of changed bytes. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2095 current-parent preparation2126: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2090 (sources2088/2089): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2086 (sources2082/2083): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/runtime/orca-runtime-tests/terminal-handles-part-02.spec.ts: recovers a moved SSH pane through the tab it now sits in, not the one its lease froze; reports a plain expired orphan; does not report a pane whose only recent lease was superseded; does not report a pane whose only recent lease had its relay id recycled; picks the eligible orphan over a superseded predecessor that matches first; collects the same tabs the per-tab reader reports, in one sweep of the leases; reports no candidate when no lease names any of the worktree tabs. src/main/runtime/orca-runtime-tests/runtime-availability.spec.ts: starts unavailable with no authoritative window; reports the configured Windows terminal shell on status; reports floating workspace availability from settings on status; polls floating tabs with targeted PTY liveness and no repo/provider inventory; hydrates persisted tabs when the store cannot report repos; advertises browser screencast only when a renderer window is available; routes mobile Codex reset consumption through the account mutation coordinator; maps a definite pre-provider rejection into an authoritative current snapshot. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2003: Remove SSH/absent-inventory attach refusal, later-subscriber retry, no-view adoption/takeback, provider-tail/unknown-read projections, failed-keystroke retry and simpler loss reattach examples. Keep the existing-subscriber inventory-ready retry alias only at its retained callback, plus retained held-input cancellation/replacement and overlapping attach/loss fences. The inventory driver also loses the whole empty-worktree-publication registration and folder-host/unverifiable scalar examples. Retire the entire dated10-case attach receipt; retain16 independent receipts only in their original scopes. No retained-memory or real-daemon measurement follows from supplied provider inventories. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1991: Remove initial-snapshot sequence-domain, limited-tail/truncation and unknown-output-sequence aliases whose callbacks are removed. The source retains partial-chunk replay and requested-snapshot retry/admission at supplied snapshot/data seams, not equivalent replacement or measured retained-memory proof. Preserve the existing stream/pending-wait capacity aliases only to their retained owning multiplex callbacks with supplied PTY resolutions. Removing the sibling-PTY heartbeat dedup work-count sample does not establish a new decorative fanout budget; the unrelated-PTY cancellation fence survives. Preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Remove the reasonless-close selector and narrow census aliases to actual retained runtime and injected-inventory callbacks. The removed synthetic census-dedup and isolated pre-boundary timing cases receive no replacement credit; preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1939 (sources1934/1935): Delete the synthetic watcher-synchronization and partial-reconciliation suites. Retire all affected host-fact, capability-owner, activation-residue and retention-cap aliases because the remaining callbacks do not establish those full claims. Keep exact local hook/timer, byte-stream side effects, exit/disposal, scroll-intent cleanup and deterministic local rank/TTL progression callbacks within their mocked-host scope. No physical paired-host retention, resource budget or equivalent replacement evidence is assigned. The generic broad test command remains a runnable discovery command, never a dated execution receipt. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete the complete hook-agent-status projection suite and its two behavioral assertion aliases. Supplied stored hook/title/resume/staleness/rename/question/generation/PTY-retirement/snapshot-version projections are intentionally lost. The separate osc-status-scan gate mentions this source only in existing historical notes and receives no mutation. No measured hidden-output retention, CPU/RSS or resource budget result is claimed by the deleted source or this audit. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Module ownership cleanup retires the modeled cold-park private watcher/render/work-count suites under the current test policy. Their assertions are no longer active evidence. Retained lifecycle tests and headed/headless journeys do not establish equivalent coverage for those removed harness alarms. Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1634 removes low-value IPC, filesystem and runtime projections, argument inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained cancellation, ownership, authorization, filesystem and SQLite boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1627 removes low-value mocked daemon projections, scalar tables and duplicate terminal examples without equivalent replacement coverage. Per-source reviews record retained terminal content preservation, process ownership refusal and recovery boundaries together with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Retained exact unchanged-source receipts remain the only current execution evidence. Reduced selectors have no fresh execution result. Audit1417 intentionally deletes src/renderer/src/components/terminal-pane/pty-connection-hidden-tui-snapshot-replay.spec.ts: Loses rich hidden snapshot sequence replay/grid resize and forced repaint after hidden snapshot alarms, including live-trigger deduplication. deletes src/renderer/src/components/terminal-pane/terminal-cold-park-verdict-loop.test.tsx: Loses modeled React oscillation alarm; real pane/watchers are not exercised. deletes src/renderer/src/runtime/remote-runtime-terminal-parse-backpressure.test.ts: Loses delayed credit until parsing, malformed frame/unknown stream handling, discarded transformed output recovery and failed ACK rearm alarms. No equivalent replacement coverage or fresh result is claimed. Historical coverage account: Audit1412 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): This audit removes the browser response-after-manual-disconnect example. Its distinct in-flight response fencing alarm is lost; retained queued-call disconnect tests are not an equivalent replacement. Historical commands and results remain historical. Deterministic headed macOS runs launch an isolated Orca desktop server and a separate paired web client. A byte-identical headless run uses an isolated `orca serve` host. Both create six real paired host PTYs with bounded high-output scrollback, prove sustained output while all six client xterms are warm-mounted but hidden causes zero renderer scheduler work, then drive 180 timed real-PTY spinner frames through a second production `session.tabs.subscribeAll` transport and the real Zustand store. Each worktree must publish and apply only its exact initial-working and final-idle titles. Both topologies ordinary-park five xterms without enabling the lossy retention budget, assert bounded cells/heap/timer lag, then restore the bounded authoritative tail exactly once on the original PTY including output produced while parked and continued input/output. The headed oracle additionally keeps every remote target workspace and terminal unmounted in the host renderer before and after client recovery. Production-parity React contracts reproduce and remove the independent cold-park watcher/title feedback loop, including memo-cache discard, StrictMode cleanup replay, detached split-PTY replacement, and the zero-park fast path. A deterministic cross-boundary contract drives 24 real PTY trackers in distinct worktrees through 2,880 decorative spinner and bare-native redraw chunks and counts host publications, serialized bytes, renderer apply calls, and store mutations while preserving exact per-PTY raw chunks and per-worktree semantic transitions. Fake-clock continuation beyond the 30-minute stale boundary requires one deduplicated refresh per worktree every 15 minutes, globally spaced by at least 50 ms, with every mirrored working status still fresh. Exact-identical Pi plus rotating normalized Pi/Grok frames renew coarse working/permission state; rich prompt/tool/question fields retain their original 30-minute lease, and `stateStartedAt`/acknowledgement identity remain stable across title/hook source swaps. A separate headed desktop-client journey relaunches the host main process while retaining the daemon and a daemon-backgrounded PTY, then requires first-observation foreground sync and continued input/output on the same PTY. Unit coverage keeps layout versions out of snapshot output high-waters when a restored snapshot has no output sequence and retries an existing subscriber only after authoritative provider inventory proves the retained PTY exists. Separate headed/headless ACK-starvation tests recover one stalled stream without replacing its PTY. A headed output-drop oracle proves a successful snapshot probe cannot certify a stale live stream when the authoritative PTY sequence advanced beyond the client high-water. Unit coverage requires an unsequenced client to establish a first-probe baseline, remain attached at the same sequence, and recover only after a later probe advances. A capability-disabled run proves legacy hosts retain the prior lossy limit/TTL fallback. Unit tests cover exact-owner capability routing, raw-stream release, singleton side-effect facts with timed handoff cleanup, 64 simultaneous synthetic-title sources with zero decorative client events after convergence, per-client late-subscribe recovery, semantic bell/title transitions, local animation-frame preservation, legacy no-output-pause delivery gating with exact snapshot restore, provider-authoritative snapshots, 128 active streams plus retry after a 129th-stream capacity rejection, capacity-pressure backoff, full split-leaf remint reconciliation, truncation, and manual-disconnect queue fencing. Linux, Windows, live SSH, and production-scale paired hosts remain gaps. The audit removed the E2E parking override/debug-handle suite. Override exposure guards, delay/retention independence, TTL filtering and debug-handle forwarding alarms are lost. Retained real parking journeys do not establish equivalent test-harness configuration coverage. The test-value audit removes separate responsive-stream, intervening-control-frame and capacity-error classification examples. Retained multiplexer checks use fake clocks and captured transport callbacks; their per-stream isolation, deadline and probe-baseline assertions do not prove an actual host restart or equivalent replacement coverage. Historical run commands and results remain historical. The test-value audit removes the standalone retained/live metadata projection and additive-preference negative example from runtime-client-events.test.ts. Its remaining case checks partial-authority event admission through a captured callback; it does not establish full-pair projection, actual peer delivery or equivalent replacement coverage. Historical commands and results remain historical. The isolated accepted-handle-events observer suite is removed. Its runtime/worktree/pane membership, once-only delivery and listener-release ledger alarms are lost. Live hidden-retention evidence does not establish equivalent observer coverage. Audit1292: The entire host-session mirror empty-inventory settle suite is removed. Live-unpublished versus genuinely-empty hydration, same-ID revision response/in-flight fencing and cleared-tracking pending-probe invalidation alarms are lost. The singleton store and inventories were mocked; no real host census or resume delivery or equivalent replacement coverage is claimed. Audit1302: src/main/runtime/session-tabs-inventory-publication.test.ts: Keep actual runtime public inventory authority across renderer epochs/resync, fallback, aborts and invalid graph publishers. Remove copied nonempty publication, private scan counters/collector and known-host replacement, fake refresh that performs the restoration itself, environment capability flag, and private resume-store characterization whose fixture supplies reservation/rollback ordering. Lose isolated refresh/churn/receiver/capability and copied-payload wiring alarms; no equivalent replacement. Reduced selectors require fresh validation; prior full-suite receipts do not validate removed or changed coverage. No equivalent replacement or physical-provider claim. Audit1312 removes low-value imported specs from aggregate test drivers; old whole-driver execution receipts are archived. Retained registrations are unchanged. No equivalent replacement coverage is claimed. Audit1318: src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts: Retain real local encrypted WebSocket regressions for pre-ready socket replacement preserving a request, close-before-ready logical subscription cleanup, unrelated RPC surviving another deadline, and pending setup abort leaving a sibling pending. Host server is synthetic and uses production crypto; kept scenarios also retain internal diagnostics/memory assertions unchanged. Remove happy routing, authority-envelope, unknown-ID/log, cleanup enum, binary, keepalive/liveness and production-budget/private socket inventories; intentionally lose those alarms, no physical host authorization, independent crypto or remote provider claim. Reduced selectors need fresh validation; historical full-suite receipts do not validate the changed coverage. No equivalent replacement or physical-provider claim. Audit1346 removes the entire private-state-injected session-tabs rich-status boundary suite. Its stale task/question, neutral-title preservation, owner-change and provider-generation alarms are intentionally lost. Retained real terminal journeys do not establish equivalent replacement coverage. The prior mixed 42-contract execution receipt is historical and must not validate the reduced current selector; fresh validation remains required. Audit1352: focused Linux unit selections validated on source head b638e07d395b76af3ba6b03761a1a0fe7e5e026e. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1360: focused Linux unit selections validated on source head 415c9cffc2d10024131ec4b6721767a22195de6d. Historical statements above retain their original scope. Intentional test losses are recorded in knownGaps; these runs claim no physical-provider, p95, rendered E2E or cross-platform validation. Audit1383: src/main/runtime/orca-runtime-tests/worktree-native-chat-setup.spec.ts reduced. Lose command-list/receipt/default/background activation matrices whose provider spawn returns canned IDs. Retained test proves actual tab allocation separation, not terminal startup. No equivalent replacement coverage is claimed. Existing exact unaffected receipts and their platform/provider/budget claims remain scoped to unchanged selectors. Changed optional selectors have no new execution result. Audit1391: src/renderer/src/components/terminal-pane/pty-connection-remote-pause-drop-notice.spec.ts reduced. Lose repeated quiet switches avoiding snapshots and legacy host without drop-report capability requesting a snapshot. Retained imported registrar uses fake transport/xterm writes, exercising real gap/restore lifecycle rather than actual terminal rendering. No equivalent replacement coverage is claimed. The existing primary-selector receipt and its claims remain scoped to their unchanged sources; the broad optional command has no new execution result. Audit1396: src/renderer/src/components/terminal-pane/terminal-parked-watcher-reconciliation.test.ts reduced. Retire standalone reconcile set output and positive untouchedFreshSpawn/workspaceOwner copying alarms; no native watcher execution claim. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1401: src/main/runtime/orca-runtime-tests/mobile-session-tabs-duplicate-pty-repair.spec.ts removed. Loses listing-on-already-repaired-data alarm; it never established runtime repair invocation. src/main/runtime/orca-runtime-tests/mobile-session-tabs-split-agent-tab.spec.ts removed. Loses actual mobile split sibling shell versus recorded-agent resume command alarms; no equivalent coverage asserted. src/main/runtime/orca-runtime-tests/worktree-native-chat-setup.spec.ts removed. Loses separate setup/startup tab result in that manually assembled path. src/main/runtime/orca-runtime.test.ts reduced. Driver registration/import of a whole-deleted selected spec is removed; directly authored cases remain unchanged. No extra authored removal credit. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1402: src/renderer/src/components/terminal-pane/pty-connection-park-reveal-model-snapshot.spec.ts reduced. Loses basic paired serialize/initial replay forwarding check; hidden alt-frame grid/precedence policy remains. No real terminal renderer claim. No equivalent replacement coverage is claimed. The existing primary-selector receipt and its claims remain scoped to their unchanged sources; the broad optional command has no new execution result. Audit1412: src/main/runtime/mobile-session-tabs-agent-status-heartbeat.test.ts reduced. Loses FIFO fairness/spacing, semantic bypass/cancellation, delayed-boundary scheduling and teardown timer-cleanup alarms. Retained fixed emission cases do not replace those outcomes. No equivalent replacement coverage is claimed.", "motivatingLinks": [ "https://github.com/stablyai/orca/issues/8652", "https://github.com/stablyai/orca/pull/10625" ], "invariant": "A host advertising terminal.paired-parking.v1 keeps the PTY and bounded authoritative history alive while an ordinary hidden-view park destroys the client xterm and releases its raw per-PTY stream. Reveal must restore up to the requested 5,000 rows, parked-time side effects/output, the same PTY identity, and continued input/output. Parked watcher synchronization compares parking semantics rather than fresh object identity, owns setup and cleanup across StrictMode replay, reconciles real PTY/layout changes, and performs no terminal-state scan when nothing is parked. After a host main-process relaunch, unknown local delivery-sync state must not be treated as proof that a surviving daemon PTY is already foregrounded. An empty headed session-tab inventory is authoritative only after the current renderer graph generation publishes a complete inventory and every execution host answers the PTY census; unpublished, resync-pending, transport-failed, and partially scoped inventories remain unverifiable, while genuinely authoritative empty and non-empty inventories settle and a scope-less legacy empty keeps its pre-authority best-effort settle so outdated hosts retain agent auto-resume. The unpublished-empty regression must keep the resume dispatch parked with exactly one daemon process/writer; restoring unconditional empty hydration must release one dispatch and create two live writers. If subscription precedes provider readiness, authoritative inventory must reconsider that existing subscriber without spawning, resizing, or changing reconnect state. A snapshot without an output high-water must keep it unknown rather than borrowing a layout version that can suppress newer live output. Hosts without the capability must gate hidden raw output before xterm scheduling and repaint from the authoritative snapshot on reveal while retaining the existing limit/TTL force-parking fallback. After the first semantic title state, decorative spinner frequency must add zero paired client-event frames and zero full session-tabs work between status-freshness leases regardless of hidden worktree count. Continuous working or permission evidence may refresh each affected worktree once per 15 minutes through one globally spaced FIFO so current and legacy viewers do not decay before 30 minutes; sibling PTYs share that worktree refresh, while local title animation, raw output, and semantic title, status, bell, completion, and query facts remain intact. A paired terminal stream whose delivery credits stop progressing must replace only that stream; command silence first probes authoritative state and replaces the stream if the probe times out or proves the PTY advanced beyond the client's delivered output sequence. When no comparable delivery high-water exists, the first sequenced probe establishes a baseline and only later advancement proves staleness. A same-sequence snapshot remains valid proof of a responsive silent command. A successful status probe may replace a pre-ready shared-control socket without rejecting or duplicating calls already waiting for that transport. Manual disconnect must retain pairing while preventing queued or passive calls and subscriptions from recreating transport until explicit Connect. A paired pane reconnecting to a relaunched host that has not yet published its window graph (an unpublished frame, bare or client-projected) must stay in recovery rather than retire, and the host's first published snapshot carrying the surface must reattach it; a published frame lacking the surface still retires it. The placeholder is only ever sent before the host's graph first publishes; afterwards a worktree with no tabs gets a real empty answer, pushed once to any client that asked during startup, so a paired client opening a never-opened host worktree still gets its first terminal.", - "oracle": "Audit4362 intentionally deletes the imported stale-waiter retry and manually assembled OSC9999 mobile-republish cases, plus the mocked missing-worktree cleanup suite (4 authored / 5 finite cases in three suites). Lost alarms include repeated unread worker_done pointers, working-to-waiting mobile status publication, missing-worktree filtering, and scoped daemon shutdown with unrelated duplicate identities. No replacement coverage or new platform proof is claimed. Audit3832 deliberately retires76 authored/79 finite cases:75 runtime compatibility cases/78 finite cases across14 fragments, plus one localization extractor default-flag case. Three whole runtime fragments are deleted;27 authored/30 finite cases remain across the reviewed sources. This gate retains only its own selected scope; no equivalent replacement or fresh runtime/native/remote evidence is claimed. Runtime component A: Audit3828 composes3822 with independent3824: deliberately retires49 authored/52 finite cases from seven compatibility fragments, leaving15 authored/18 finite cases and deleting two entire fragments. Accepted losses: positive folder-worker recovery/materialization and reveal deadline; persisted-key normalization and legacy split/group/focus projection; fixed stale CAS refusal; occupied/alias/restored/preallocated terminal-handle variants; fixed OpenCode/Cursor/Claude/Codex/Antigravity classification, readiness, title and management examples; direct private-map browser authority projections; browser-focus and OMP title projection; already-aborted claim cleanup. Additional3824 loss: src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts :: does not poll a wrapper foreground for a speculative CLI prompt send :: Speculative retryForegroundWrappers:false check must return false on a wrapper after one foreground read, without polling the supplied later codex response. These real bounded alarms are deliberately retired for low marginal value. Retained callbacks are unchanged and provide only their own bounded scope, not equivalent replacement. Historical receipts do not validate reduced callbacks. No fresh runtime/native/SSH/WSL/phone/browser evidence or full transitive closure is claimed. Runtime component B: Audit3834 deliberately retires26 authored/26 finite cases from seven fresh compatibility fragments, leaving10/10 and deleting the one-case saved-binding reattachment fragment. Original position58 is excluded: its existing substantive3578 KEEP7 review remains historical, with no fresh credit. Accepted losses: fixed hook/provider-session identities and stale metadata refusal; decorative/pre-title foreground ordering variants; saved-binding surface reattachment; saved-row exit ghost removal and silent activation selection; unsupported headless wake; positive pending materialization/group projections; per-caller navigation selection; positive SSH hydration/read partition; laptop mobile publication/buffer and background/pending/status projections; abnormal/unregistered SSH grace, normal-exit refusal, persisted SSH hydration, positive serve reattachment, pending-agent launch arguments and direct seeded running-launch admission guard. These are real bounded alarms deliberately retired for low marginal value. Retained cases preserve their own distinct deferred foreground coalescing, usable handle continuity, stale inventory refresh, concurrent browser snapshot preservation, renderer graph fencing, caller dedup isolation, SSH partition writes, runtime split lifetime, independent relay-ready publication, lease admission/state/expiry. The direct running-launch no-spawn guard alarm is deliberately retired; no remaining owning-launch refusal coverage is claimed. Historical runs do not validate reduced callbacks. No equivalent replacement, runtime/native/SSH/WSL/phone/browser result or full transitive closure is claimed. Additional extractor loss: config/scripts/localization/source-extraction/audit-localization-native-dialogs.test.mjs :: does not change the existing renderer scan by default :: Default options must omit the five native-only fields in this supplied snippet. No equivalent replacement is claimed. Historical prior account (preserved verbatim): Audit3814 deliberately retires60 authored/60 finite cases:53runtime compatibility cases,4native XCTest methods and3Python clipboard methods, including the entire StableElementIndexes suite. Clipboard cuts retire the one-over-cap sample, incoming-offer destruction trace and sequential20-copy replay; actual wire, FD/pipe, startup and Xvfb/GTK boundaries remain without equivalent replacement claims. Accepted losses include narrow terminal-send payload/provider projections, legacy and direct no-op/error permutations, timing/work-count examples, private state/title/activity projections and fixture-driven readiness examples, individually enumerated below. These include real bounded production alarms consciously retired for marginal value; retained failed writes, duplicate submission, stale capture, transcript/ring and allocation fences are not equivalent replacements. No fresh native/remote/browser execution or complete transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3806 deliberately retires40 authored/40 finite runtime compatibility cases, including the terminal-side-effect-facts-part03 headless-snapshots-part02 and agent-status-and-waits-part03 fragments, plus20 scalar Swift precondition sites. Lost runtime alarms include status/title/attention projection examples, simple renderer/headless frame restoration and status waiting outcomes detailed in the accepted-loss ledger. Swift cuts retire duplicate generation-map/schema/navigation/bridge and notification-wrapper assertions; no standalone native program is deleted. These include real bounded production alarms consciously retired for marginal value. Retained races, pending writes/reflow, namespace and waiter ownership are not equivalent replacements. No fresh native/remote/browser execution or full transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3798 deliberately retires21 authored/24 finite compatibility cases, including the entire SSH-worktree-lifecycle and repository-project-operations fragments. Accepted losses include navigation-only settings acknowledgement, browser session cleanup and host preservation projections, window positive/policy-state examples, terminal recovery/reload and no-incarnation remint examples, terminal listing compatibility/malformed IDs, directory browse/sort/Windows path smoke, SSH create refusal/manual lineage, recursive parent-folder creation and fork/origin/avatar/icon projections. Real bounded production alarms are consciously retired for marginal value; retained authority races, cleanup/clone ownership, pending waiters, nested-folder and scan invalidation cases are not equivalent replacements. No fresh native/remote/browser execution or full transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3580: Retire the whole one-case runtime host environment prototype/subclass suite. Intentionally lose the exact configured lower-case Windows Claude home to account-identity normalization and host-account override precedence alarm previously retained by Audit3129. No equivalent replacement or fresh runtime validation is claimed. Earlier dated keep statements below describe their historical source scope; the current suite is removed. Audit3563 scope: retire the whole Kiro OSC/hook identity suite and the OpenCode2 identity-only case; reduce Codex cached startup child-retirement and missing-session-ID tables to one case each (2 authored/4 finite removals). Intentionally lose Kiro alias/session continuity, OpenCode2 completed OSC identity continuity, cached replacement without relay-generation restart, and missing-previous-ID context-preservation alarms. Remaining provider, remote compatibility, persistence and cross-session pollution cases are not equivalent replacements. Also remove the private Codex roster-size assertion while retaining public child-absence checks. Historical evidence retains its original source scope; no new execution or transferred pass validates these reductions. Audit3446 composes ROOT-adopted3441/independent3442: intentionally removes100 authored registrations/119 potential expanded cases (118 conditional-active before platform gates) across16 sources, retaining11 authored/13 expanded cases and deleting6 whole suites. Two parent registrar import/call cleanups and the unused68line CLI recording fixture carry zero test credit. No equivalent replacement or fresh execution is claimed. The decorative fanout suite retains only real OSC9999 ingestion through runtime/title heartbeat/viewer past the stale boundary, preserving stateStartedAt and clearing expired prompt metadata. Spinner volume/zero-work inventories, Pi/Grok frame tables, rich-status and foreground-reset examples are retired. Existing receipts for separate paired-terminal sources retain their original scopes. Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3342 removes three supplied activation/inventory fallback and same-handle retry examples; their fallback/retry alarms are intentionally lost without equivalent replacement. The exact mounted-HUB pending old-stream-end versus replacement-snapshot registration and its assertion remain. Unrelated dated macOS receipts retain only their original scope; no fresh runtime, provider, performance, mobile, mixed-version or cross-platform validation is claimed. Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: restarts only the stream whose renderer delivery credit never settles — An unreturned renderer delivery credit stalls only its stream, leaving healthy sibling/shared transport alive. Fake-clock deadline plus real multiplexer unsubscribe isolates recovery ownership.; probes then restarts a stream when an entered command receives no frames — Entered command produces no output; actual multiplexer must probe then close only its stalled stream after probe timeout. Distinct response liveness from parser credit.; establishes a probe baseline before recovering an unsequenced stream — 142-line manual five-probe baseline/regression sequence derives request IDs from encoded mock traffic and checks repeated no-close/close choreography. Oversized algorithm/state-machine example; no actual renderer/host command or recovery delivery. Retires unsequenced/unchanged/regressed baseline classification alarms.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces remote-runtime-pty-transport-unpublished-host-graph.test.ts, retiring its direct published-empty-graph omission-to-pane-exit alarm. The unchanged bounded unpublished-frame/pushed-recovery and stale-handle park/manual-retry cases are narrower, not equivalent replacements. Both complete three-case Linux receipts dated 2026-11-04 are archived as historical, including source heads; they do not validate this reduced selector. Remaining fourteen active receipts are macOS only. No fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3318 composes adopted sources 3310, 3313 and 3317: intentionally retires 71 authored declarations and 102 expanded cases, including whole terminal-detach agent-retention, seeded batch/single open-files equivalence, shallow context-menu shortcut-badge, mocked active-workspace delete-dispatch, workspace session hydration, SSH target cleanup, editor session hydration and worktree terminal purge suites. Lost alarms include chained transfer alias and immediate close/exit retention; batch/single divergence, survivor/selection/map preservation and input nonmutation across 400 imperative seeds (one registered case); disconnected pending-handle retry, authoritative absences/close-record shortcut/older-host absence and published-presence/unpublished-frame examples; published empty host-graph omission to pane exit; legacy search ranking/exclusion fallback; provider request upgrade/dedupe/finalizer ownership; asynchronous PR suppression/primary-change and same-number different-repository URL rejection. Deletion routing loses host/instance qualification, paired and legacy mapping, folder ownership, active-versus-hover/menu-row selection, ambiguity, modal/editable/creation/view/main/deleting/missing guards and shortcut advertisement. Unchanged real keyboard/hover/confirmation/catalog E2E remains narrower, not an equivalent replacement. Additional losses include scripted old-host disk/UTF-8/noop/baseline and landed/unlanded lost-reply/replacement-retry outcomes; ordinary/repeated healthy-link reattach; cross-owner terminal/chat binding; oversized replay permanent-unavailable classification; floating reveal keyboard ownership/close/disable/listener disposal; naming/retained-turn/Sleep/error/close/reject status tables; SSH membership prune/new-target-only reads and environment/local bucket isolation; same-frame receipt capacity and positive bare/headless publisher readmission. These actual regression alarms are deliberately lost; no fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3312 composes adopted sources 3302 and 3308: deliberately retires 33 authored declarations and 36 expanded cases, including the whole backend startup-focus, active-browser IPC-close-routing, remote-browser-creation and agent-terminal-presence suites. Intentionally lost alarms cover distinct six-pane reconnect handles; SSH host label/Connect callback, unhydrated visit cleanup, repo cache aliases and hidden worktree/tab/PTY cleanup; adopted-agent startup focus and viewer navigation/reuse; staged, pageless, source, stale and orphan browser-close routing; web local-materialization refusal, desktop incapable-host fallback, failed/thrown remote creation and paired-web sign-in refusal; BOM/NUL and remote/local custom-editor byte-read examples; immediate folder activation and unread clearing; and batching idle/coalescing, accumulated byte ceiling, leading-edge-disabled, standalone synchronous oversize rejection, validation yield, deferred pending-tail order and both viewport-clear examples. The newly reintroduced agent-terminal-presence suite also loses actual terminal-status membership positive and nonterminal-status callback suppression alarms, including the recent 40916 guard regression; the older different 2133 presence-suite history remains historical and receives zero duplicate removal credit. These real regression alarms are intentionally lost. The unchanged survivors provide narrower coverage, with no equivalent replacement or fresh gate, provider, rendered, remote/mobile, mixed-version, cross-platform, soak or measured-budget validation claimed. Audit 3301 combines adopted source batches 3296 and 3299: retire 27 authored declarations and 36 expanded scenarios, including six whole suites. Intentionally lost alarms cover failed-verification/recovery/restart counters and mocked hosting/toast; early overlapping pane-read scheduling/count; unreadable removal listing draft guard; bulk-purge remote-qualified and raw-local guard maps; initial-snapshot blank/mode/oversize/printable/fresh-spawn callback and replay examples; fallback mobile file close and ordinary MRU; default queue overload/drain; seeded browser-page reuse and supplied missing-page URL recreation; ambiguous sleep/hibernation owner refusal and untouched bindings/origins; ordinary selection/activity/fallback priority; skip-remote success and retained hints; supplied structured-chat unsent retention and scoped removal draft eviction; caller-chat focus precedence; open/draft PR cache eviction and merged-head fallback result inventories. Retained adverse-ordering and ownership cases are narrower and do not establish equivalent replacements. No fresh runtime, native, physical provider, cross-platform, mobile or mixed-version evidence is claimed. Audit 3292 combines adopted 3285/3287/3289/3293 removals: 40 authored declarations and 47 expanded scenarios, including whole frame-editor-view, ambiguous remote-delete-refusal, unverifiable-host subscription and editor-close cleanup suites. The previously reviewed dock-badge suite was already removed upstream in PR 40895 and receives zero new removal credit. Intentionally retired alarms include background browser selection and last-tab landing; main startup fallback, SSH project cleanup/survivor routing, exact-PR contradiction/saved-push positives, replay/sidecar rollback and wrapped remote error normalization; records/snapshot missing-diff hydration, ambiguous folder-owner delete refusal, focus no-op notifications, nested editor context-only cache check, pending broadcast-first status and ordinary four-confirmation aggregation; preview-source frontmatter pruning, approved local/runtime agent dispatch, non-GitHub legacy PR cache invalidation, stale merged-head transient-error fallback, empty-queue immediate query reply and unverified-to-concrete preflight risk. Additional intentionally retired alarms are injected host subscription/unsubscribe counts, synthetic editor reveal/draft/fallback/scoped close, ambiguous unread refusals and hidden mark/read roundtrip, immediate connect backoff/noError, positive mirrored evidence-clock renewal, supplied VM failure/success projections and git-local/folder-SSH wake permutations. Remaining temporal/ownership cases are narrower; no equivalent replacement or fresh execution is claimed. Audit 3283 removes 20 authored declarations and 31 expanded scenarios, including two whole suites. Retired alarms cover PR refresh-state pruning, shared runtime subscription cleanup and store isolation, language content-change routing and older completion ownership, ordinary panel retry-timer cleanup and pending loading, four hosted-review lifetime permutations, mocked terminal creation error/order wiring, five sleep-inventory variants with pending-frame-only assertions, palette fallback/composite highlights, Windows/UNC encoded-editor input rows, mixed-repository partial failure counts, title setters and generated-title bypass/replacement, five window-close coordinator delegation/guard/finally branches, and ambiguous-old-record frame reveal. These regression checks are intentionally lost under the test-value audit; retained cases are not equivalent replacements. Prior coverage notes and receipts remain historical. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit 3256 removes these specific alarms from the broad root unit commands: skill dialog active-share selection, close and pending-share handoff; simple keyed-record deletion; marker live-region insertion, simple landing and nine baseline policy examples; General search/control navigation inventory; orphan-count cache bootstrap; seven Codex code classifications and HTTP 429 warning mapping; two skill unread-root verdict examples; peer-mail payload and conversation-ID rejection; and the GitHub organization TABLE text-field optimistic rollback/failed-envelope example. These include real behaviors; retained tests do not provide equivalent coverage for every removed scenario. Mobile losses are recorded separately and are not coverage of these root commands. Audit3246 retires NewRowsMarker reveal/no-repeat and pane-scoped beforeinput checks; skill-owner option availability/count/dedup/order; six styled Input/Textarea IME forwarding rows; the static Codex/OpenCode smart-key inventory; tab-map AST ratchet diagnostic fixtures; child-roster work-budget and retained-aggregate alarms; malformed persisted floating-cwd fallback/no-crash/empty exact-root checks; the unanswered-host empty-list discriminator; the direct invalidated-cache commit-false assertion; one redundant digit-keyup IME row; cached non-supported Claude title-generator rows; and the duplicate late naming-result singleton. These root broad commands lose those specific alarms without equivalent replacement. Distinct retained owner/state checks have their own bounded claims; the real scheduler still rejects stale response data, while the direct false-return alarm is retired. Audit3231 retires supported-host restore-pane key mapping, closed/open creation-sidebar toggle visibility, unrelated scope-error/null classification and quick-submit reveal/no-create checks. These broad commands lose those real narrow alarms; no replacement coverage is claimed. Audit3219 removes the synthetic Cmd+J extra-source suite; this broad command no longer checks its match/tie placement and selection, announced count, empty-query cap, or workspace hiding with retained recent tabs. No replacement coverage is claimed. Audit3209 composes approved sources3202/3206: deliberately retires seven authored/expanded cases in four whole suites without equivalent replacement. Work-item queries lose real GitHub/GitLab oversized ASCII secret-prefix empty-query and whitespace-before-trim refusal alarms; inputs share the imported size bound and exercise only its fast length branch, with no multibyte or actual provider/exposure guarantee. Skill sharing loses complete/partial managed-bundle and destination-ambiguity association checks plus three negative origin/path/scheme admission examples; these do not establish uploaded contents, arbitrary-URL fetching, authorization or execution. Retain exact originless-project direct-link fallback, cloud-delete confirmation, bundled-target repair/owner isolation and explicit Windows-host preference over stale WSL suites. Rejected3201 runtime-preference removal is excluded. No real cloud/network/host/disk, mobile or mixed-version execution validation is claimed. Audit3200 composes approved source3194: deliberately retires thirteen authored registrations/twenty-seven expanded cases in six whole automation host/list policy suites without equivalent replacement. Real RPC category/retryability and wrapped-timeout recognition, unscoped-failure/scoped-success health evidence precedence, exact-ID create selectors and per-run workspace omission, paired-web local/SSH/absent host catalog routing, incompatible/removed/unhydrated/offline execution health, runtime-before-nested-SSH recovery dispatch, and no-owned-focus/successor/foreign-list focus policy alarms are consciously lost. Retain exact20line orphan allow/refuse/precondition and exact90line cross-host same-ID search suites. No retry-timer/fence lifecycle, actual reconnect/network/write delivery, native focus, mobile/mixed-version runtime or disk persistence coverage is claimed. Audit3191 combines approved source3182/3187/3188: deliberately retires thirteen authored Vitest registrations and fifteen expanded cases, including five whole suites, without equivalent replacement. Attachment intake loses real portal/native-capture terminal interception and unowned-container refusal, immediate child-only committed availability/claim-ref negotiation and delivery, and direct-target over stable focused/background composer routing through disable/re-enable/remount and independent question focus. Exact destination/cache/draft and final-stat owner/workspace/File-release suites remain; they do not replace Surface recipient routing. Automation authoring loses destination runtime catalog membership, local/direct-SSH exclusion of paired-runtime repos, unknown-runtime empty catalog, logical project/host/setup/repo/path context payload, and missing/nonready setup refusal; these were genuine direct helper alarms, while exact schedule transformation, legacy schedule and setup-decision suites remain. Agent picker loses setup-chat/terminal/missing-installer/unsupported-or-unknown-host row projection samples and the ordinary unsearched menu variant; the entire original26-line resume recipe suite remains, including reported bypass versus default/absent permission modes, as does the exact search-result menu callback with its fixtures, model/effort commits and staged Arguments reopen outcome. Rejected predecessor3180 full recipe deletion is excluded. No actual native drag/cursor/focus/IME, upload bytes or disk/restart persistence, full automation save/scheduler/runtime transport, real resume-process flags/environment delivery, or native menu/rendered layout validation is claimed. Audit3178 combines source3169/3170/3175: deliberately retires eight authored units (six Vitest cases and two imperative custom relay scenarios), including two whole suites, without equivalent replacement. Voice Section loses per-model pending-delete isolation across interleaved A/B completion and the two-success refresh-call alarm; exact VoicePane delayed key-clear/newer enabled-toggle merge remains and does not replace row deletion coverage. Speech loses dedicated rating-scale/inclusive-ceiling, unsupported-versus-unmeasured, explicit/system-language precedence/locale alias, accuracy versus fast named/default/best-measured selection, and unmeasured/no-match examples; exact offered-user-pick versus retired-selection case and its fixture remain. Relay loses legacy ping-delivery count/liveness sampled before the silence deadline and grouped malformed Bearer/host-ID 401/429 routing checks; twelve real Worker/DurableObject/shipped-client scenarios remain, not equivalent replacement for those narrow alarms. Six prior speech cases are not all deleted: approved successor3175 keeps the original user-choice case. No actual credential/file persistence, native/GPU/engine/download delivery, production assignment policy or deployed-runtime validation is claimed by this reduction. Audit3165 combines source3160/3162: deliberately retires six authored/expanded cases across three whole suites without equivalent replacement. Launch/status losses: observed React-render pending/resuming coordination across settings and deferred offer read; stale-offer reread suppressing dialog reopen; held-local-chat recovery visibility with new-chat preferences off; disabled-local admission avoiding offer RPC despite an injected but unconsumed paired-tab fixture; and run-only lost-reply uncertainty reachability until direct viewed-run retirement. Launch probe does not prove arbitrary synchronous-store atomicity, the paired fixture is not remote runtime enrollment, and the status case directly marks viewed state rather than rendering the summary. Crew-hook losses: old-host method_not_found cache persists across party changes but is released by independently supplied connection generation/verified pairing status or pairing revision, with actual frame publication and teardown. These are real narrow coordination, admission, uncertainty and mixed-version cache alarms consciously lost. Exact web verified-runtime writer handoff guard remains; it does not replace those alarms or prove live host/native/mobile delivery. Audit3156 combines3147/3150/3152/3153/3154: deliberately retires39authored/40expanded native-chat recovery cases, eight whole suites and two orphan test-support files without equivalent replacement. Lost alarms: lost-reply unconfirmed reconciliation, skipped rows/counts and missed-frame repair, unknown/pending outcome and omitted-failure-list compatibility, uncertain history after dismissal, retry/refusal/dismiss lifecycle, hidden/consumed picker ownership, result-tree keyboard focus/disclosure and all-skipped retirement; unconfirmed-over-conflict guidance and failed-chat changes despite older host timestamps; nearest-listed ancestor/cyclic forest shape, descendant membership, host ordering/missing-host local fallback; skipped/readiness/admission counts, provisional skip/progress monotonicity, early per-chat verdicts with batch pending protection, older-host waiting, start-slot/delivery distinction, retry-over-failure and unknown-after-withdrawal attention; remote snooze/reconnect/reoffer, unseen mixed summary through open/close, watched completion retirement, new success beside old failure, failed-reread mixed-result preservation, filter/collapse completion resets, retry summary replacement and current-offer/history selection; cross-host workspace identity, rendered cyclic reachability, nested tri-state/toggle propagation, project eligibility isolation and collapse preserving selection. Exact fallback-list completion barrier, batched verdict/cleanup retention, stale-read versus dismissal publication race, and requested-but-never-rendered finished-run retirement remain; they do not replace retired alarms. Audit3146 combines source reviews3132/3133/3135/3138/3143: intentionally retire20authored/31expanded cases without equivalent replacement. Provider-session losses: structured-native terminal-resume exclusion, metadata-less completed identity, new-turn completion clearing, Pi provider-only/periodic/manual promotion, changed-transcript launch-config isolation, Pi/omp/prime-agent completed-session remote/manual-shutdown promotion, and quit/done precedence over heartbeat. Side-thread/question losses: finished-pane acquisition, hidden title/recap states, local/relay/relay-done conversation takeover with prompt/session/child resets, plain-message abandonment, compaction/session replacement and completion resets. Codex startup losses: incoming-owner cached child replacement, old-relay foreign live-session correction, completed foreign-root turn-fact permutations. Transcript losses: real temporary-JSONL partial sibling/final-child completion, unlabelled child attribution, compact cached replay preservation and100/1000completed-child roster retention/release. Compiler-ratchet losses: valid-line uncompiled-list parser grammar examples and injected-existence stale-path filtering; these did not exercise actual filesystem canonicalization or build exclusion. These are real lifecycle, ownership, replay, liveness and retention alarms, including recent#40246 regressions, deliberately lost. Retained conditional record replacement, clockless root/SSH owner isolation, persisted main-thread fork rejection, partial/final question-answer lifetime, cached-roster/missing-ID/live HTTP/durable startup boundaries and restarted-relay refusal/acceptance do not replace those losses. No native/SSH/WSL execution or equivalent coverage is claimed. Audit3128 scoped coverage reduction: Audit3121 removes VoiceDictationLanguageSetting.test.tsx (Spanish-to-es callback and unsupported-model Korean option presence) and voice-speech-model-rows.test.ts (provider/language-order/retired-on-disk list policy); these real narrow alarms are deliberately retired without replacement. VoiceSpeechModelSection per-model concurrent deletion remains unchanged. Audit3122 removes the direct absolute/parent-segment sparse-directory exception-type sample and the five-row IPC sparse-preset error-code/non-save table (two authored/six expanded cases). Those real typed-validation and IPC refusal/error-code alarms are deliberately retired. Keep both real symlink/junction floating-directory trust cases and the minimal RPC structured validation-reason serialization case. The RPC case does not replace IPC save/refusal behavior, typed normalization for both path inputs, actual Git sparse checkout or rendered localization. No equivalent replacement or fresh test/runtime/platform/remote/performance validation is claimed. Audit3124 removes ExperimentalPane.test.tsx (ordinary Pet switch callback), WorkspaceDirectorySetting.test.tsx (padded absolute saved-path normalization/no-write blur), and repository-search.perf.test.ts (navigation/selected-pane builder-call policy, fixture cardinality/nonempty entries and renamed project keyword inclusion). These real narrow alarms are retired without replacement; RepositoryPane.search.test.tsx search-to-sparse-editor request remains unchanged. Audit3129: resolver Windows case-insensitive and POSIX case-sensitive configured-env composition plus mocked-base launch-preflight Windows composition are intentionally no longer checked by the two deleted suites. No equivalent coverage claimed. Keep runtime-structured-agent-host-env.test.ts unchanged: configured Windows Claude-home account identity and host-account precedence remain checked. Audit3114 incorporates source3101: retire three structured Claude child-environment wrapper cases covering inherited stamp isolation/default and explicit entrypoint, Windows SDK-key canonicalization/default/duplicate-key order, and configured lookup/final environment/config-dir conjunction. Keep direct auth/session sanitation and Windows-versus-Linux overlay checks, actual executable lookup from supplied inherited PATH, native Windows child environment delivery, and stale option-mutation fencing. These are not equivalent replacements for the retired wrapper alarms. No fresh test/runtime, real login-shell probe, Claude SDK startup, remote/mixed-version, UI or performance result is claimed. Audit3114 incorporates source3105: retire 17 authored/20 expanded daemon launch-note cases, including the entire two-case SessionLaunchNote suite. Deliberately lose split-marker carry across same-token re-arm, stale-token retirement refusal, foreground tri-state and serial settlement, omitted-note/no-incarnation mixed-version policy, sticky retirement, first-incarnation/replacement launch preservation and held-launch precedence. Keep only the unchanged unresolved foreground-read race against a later finished attach. Supplied notes/foreground and runtime calls do not establish actual daemon/main restart, SSH, native Windows observation, mobile UI, equivalent replacement or fresh runtime/performance validation. Audit3114 incorporates source3109: retire six authored/35 expanded pricing cases: 21 accepted model-name examples, 10 unsupported/future-model fail-closed examples, malformed TTL clamp, unknown-model estimate refusal, flat-model long-context disregard and oversized long-context clamp. Keep mixed five-minute/one-hour write allocation and short/all-long/mixed long-context allocation with original fixed oracles. Real parser/refusal/bounds alarms are knowingly lost without equivalent replacement; retained tests do not validate provider rates, actual billing or request threshold classification. Preserve the archived usage-scan-append source-freeze receipt without transferring historical execution/performance credit. No fresh runtime result is claimed. Audit3108 source-only reduction (3094/3095/3100): retire 27 authored/30 expanded cases, including complete markdown view-state, file-preview link-open and CLI agent-server-route suites, without replacement. Deliberate losses include preview visibility/reference lifetime and same-path owners; SSH stat, directory/missing-target, explicit-null owner, nonmarkdown line/column, local URI routing, remote-to-client guard and same-file reuse; document-preview source-owner/folder/reuse routing, stable grant location and outside-workspace POSIX/Windows request projection; and verified remote CLI send/check refusal, suggested --on argv/copy, shell no-probe bypass, unverified-launch admission and older-peer refusal. Retain two markdown source-runtime/qualified-reveal alarms, one stale grant-rejection fence and two remote read/mutation evidence policies, with original callbacks. Final last-wins reveal did not prove transient cancellation; CLI prerequisite did not prove no real send, and envelope tests do not execute server refusal. No fresh runtime, rendered UI, actual file/SSH/paired transport, authorization, mixed-version or performance result is claimed. Audit3096 source-only reduction (3087/3088): retire 69 authored/76 expanded cases, including complete recovery-portals and reconnect-banner suites. Intentionally lose dead/default TUI replay, generated alternate-frame style composition, reset/mode/dimension and legacy missing-mode-boundary alarms, UI notice/action/reveal policies, and isolated recovery lifecycle variants, without equivalent replacement. Retained registrations and callbacks are unchanged; headless cells are not pixels, and no fresh runtime, host, SSH, WSL, rendered-app or performance result is claimed. Audit3086 source-only reduction (3079/3080/3081): intentionally retire 93 authored/100 expanded mock-boundary cases, including the complete spawn-errors and SSH reconnect overlay suites, without replacement. Retired alarms include spawn classification/ownership, reply ceilings and renderer-write failure recovery, disconnect/detach fencing branches, authority facts, and overlay retry/visibility wiring. Retained callbacks are unchanged; no fresh execution, real PTY/SSH, rendered UI, or performance result is claimed. The direct side-effect-facts selector retains six cases: replay exclusion, live sequence handling, stale disposer ownership, one handoff drain, drain-before-snapshot, and stale replacement-snapshot refusal. Successful current-entry snapshot application is not witnessed by the retained snapshot case. Audit2432: The broad unit command loses the isolated BranchPicker open-change notification sample. Its unique true/false callback alarm is intentionally retired; reopening/status-refresh behavior was not exercised. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2425: The broad unit command loses the workspace-copy-status supplied readError forwarding sample. It did not exercise the branch-switch blocking promised by its title. This alarm is intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2417: The broad unit command loses two ordinary clean Git cherry-pick/revert success samples and two terminal startup foreground-read work-budget samples. These unique alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2412: The broad unit command loses the whole six-case fake-React-hook scroll-anchor suite, two generic draft-retention samples, a simple new-agent order sample, a real history-publication batching-count sample, an unmounted handoff abort/timer sample and three basic WSL preview/error samples. These alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2404: The broad unit command loses the standalone share-name lookup 503 propagation suite, initial deletion placement-kind sample, direct changed-mtime stale sample, first-pass rollback existence example and abandoned-preparation directory sample. These exact alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2397 review amendment: The broad unit command loses three standalone suites, two partial-case definitions and two URL table rows across package/download/placement tests. Keep initial wrong-port authorization, modified independent-copy digest refusal and abort-after-begin cancellation dispatch. The remaining alarms are deliberately retired; no equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2393 current-parent refresh2401: Remove the basic skill-install service alias sample and original public managed-remove receiptless refusal case. Preserve the upstream request ownership suite and transaction interruption coverage. No equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2389: The broad unit command loses the missing-preview suite, plain-global destination sample and prepublished-receipt recovery example. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2385: The broad unit command loses four authored walker/staging/protocol examples (six expanded cases); no equivalent replacement or fresh validation is claimed for the reduced suite. Audit2383: The unscoped Vitest command no longer includes the removed Antigravity catalogue suite; its exact provider-root/owner example has no equivalent replacement or fresh validation claim. Audit2377/2381: The unscoped Vitest command includes the reduced bundled-skill and native-discovery suites; the eight removed backup/legacy/catalogue/symlink/SSH-builder examples have no replacement-equivalence or fresh validation claim here. Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2095 current-parent preparation2126: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2090 (sources2088/2089): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2086 (sources2082/2083): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/runtime/orca-runtime-tests/terminal-handles-part-02.spec.ts: recovers a moved SSH pane through the tab it now sits in, not the one its lease froze; reports a plain expired orphan; does not report a pane whose only recent lease was superseded; does not report a pane whose only recent lease had its relay id recycled; picks the eligible orphan over a superseded predecessor that matches first; collects the same tabs the per-tab reader reports, in one sweep of the leases; reports no candidate when no lease names any of the worktree tabs. src/main/runtime/orca-runtime-tests/runtime-availability.spec.ts: starts unavailable with no authoritative window; reports the configured Windows terminal shell on status; reports floating workspace availability from settings on status; polls floating tabs with targeted PTY liveness and no repo/provider inventory; hydrates persisted tabs when the store cannot report repos; advertises browser screencast only when a renderer window is available; routes mobile Codex reset consumption through the account mutation coordinator; maps a definite pre-provider rejection into an authoritative current snapshot. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2003: Remove SSH/absent-inventory attach refusal, later-subscriber retry, no-view adoption/takeback, provider-tail/unknown-read projections, failed-keystroke retry and simpler loss reattach examples. Keep the existing-subscriber inventory-ready retry alias only at its retained callback, plus retained held-input cancellation/replacement and overlapping attach/loss fences. The inventory driver also loses the whole empty-worktree-publication registration and folder-host/unverifiable scalar examples. Retire the entire dated10-case attach receipt; retain16 independent receipts only in their original scopes. No retained-memory or real-daemon measurement follows from supplied provider inventories. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1991: Remove initial-snapshot sequence-domain, limited-tail/truncation and unknown-output-sequence aliases whose callbacks are removed. The source retains partial-chunk replay and requested-snapshot retry/admission at supplied snapshot/data seams, not equivalent replacement or measured retained-memory proof. Preserve the existing stream/pending-wait capacity aliases only to their retained owning multiplex callbacks with supplied PTY resolutions. Removing the sibling-PTY heartbeat dedup work-count sample does not establish a new decorative fanout budget; the unrelated-PTY cancellation fence survives. Preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Remove the reasonless-close selector and narrow census aliases to actual retained runtime and injected-inventory callbacks. The removed synthetic census-dedup and isolated pre-boundary timing cases receive no replacement credit; preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1939 (sources1934/1935): Delete the synthetic watcher-synchronization and partial-reconciliation suites. Retire all affected host-fact, capability-owner, activation-residue and retention-cap aliases because the remaining callbacks do not establish those full claims. Keep exact local hook/timer, byte-stream side effects, exit/disposal, scroll-intent cleanup and deterministic local rank/TTL progression callbacks within their mocked-host scope. No physical paired-host retention, resource budget or equivalent replacement evidence is assigned. The generic broad test command remains a runnable discovery command, never a dated execution receipt. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete the complete hook-agent-status projection suite and its two behavioral assertion aliases. Supplied stored hook/title/resume/staleness/rename/question/generation/PTY-retirement/snapshot-version projections are intentionally lost. The separate osc-status-scan gate mentions this source only in existing historical notes and receives no mutation. No measured hidden-output retention, CPU/RSS or resource budget result is claimed by the deleted source or this audit. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Retained exact unchanged-source receipts remain the only current execution evidence. Reduced selectors have no fresh execution result. Historical pre-audit oracle account for changed sources: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Run one byte-identical six-terminal oracle against an isolated headed desktop host and an isolated headless `orca serve` host. Stage at least 1,000,000 xterm cells, hide all six warm managers, emit an initial working title followed by 30 timed real-PTY spinner frames and a final idle title per worktree, and observe a second real session-tabs subscription plus the production renderer store. Require exactly two transport envelopes and two title mutations per worktree, no decorative title crossing either boundary, and positive decoded-envelope bytes. Enable ordinary parking with the lossy retention budget disabled, require exactly one mounted manager and five parked tabs, at most 45% retained cells, no more than 16 MiB heap growth, and under 500 ms timer drift. In headed mode, require the host renderer to remain on its original workspace with zero target terminal managers mounted throughout client park, reveal, and live I/O. While a tab is parked, require authoritative terminal.read to observe new PTY output; reveal it and require the original PTY, a marker within the requested 5,000-row history, the parked marker, and post-reveal input/output. Drive 24 real PTY title trackers in distinct worktrees through 40 decorative spinner frames each, then 40 spinner frames alternating with Cursor's bare native identity redraw, using fake clocks. Require all 2,880 raw chunks exactly and zero host session-tabs publications, serialized bytes, renderer apply calls, and renderer store mutations. Continue decorative evidence beyond 30 minutes, require exactly one refresh per worktree per 15-minute lease through a FIFO spaced by at least 50 ms, and require all 24 viewer statuses to remain working and fresh; then require one exact semantic idle transition and one visible-output chunk per PTY. Require ordinary and interior-Braille title changes to publish. Drive 64 host PTYs through ten 80 ms synthetic title frames, require zero paired client events after the first frame per PTY while all 640 local frames remain observable, attach a late client and require one current frame per PTY, then require semantic bell and idle transitions on both clients. Reconstruct a legacy subscribed stream with no outputPause capability, hide a chatty pane, require no hidden xterm writes, reveal it, and require one authoritative snapshot plus continued live output. Drop and acknowledge output only for one original paired-client stream, prove the fixture process consumed input while the host model advanced and the client stayed stale, then require the command snapshot probe to replace that stream, repaint exact fixture output, preserve authoritative PTY identity and target-tab cardinality, and resume live I/O. For a client without a delivered sequence, require the first numeric probe to establish a baseline without replacement, a same-sequence probe to remain attached, and a later advanced probe to replace only that stream. Withhold the first encrypted shared-control ready frame, start one RPC, trigger a status-probe refresh, and require two connections, one host delivery, successful response, and zero retained request bytes. Admit 128 active streams, reject the 129th as retryable, release one stream, then require the retry to attach and publish a snapshot without multiplying retained subscribers. Disable terminal.paired-parking.v1 and require the same oracle to fail before parking, while the legacy limit-one fallback separately passes. Also preserve truncated first paint, ACK-starved same-PTY recovery, responsive silent-command snapshot probes, dead-stream probe timeout recovery, and queued manual-disconnect fencing.", + "oracle": "Audit5772 companion to audit5768: Retire the whole hidden-view parking policy suite. Direct oldest/cap/TTL/last-active worktree ranking and equal-hidden-time tab activation-order alarms are intentionally lost without equivalent replacement. Narrow one compound unit command and remove the parking testFiles entry. Physical parking/restoration/stream-budget selectors and assertions remain unchanged at their own exact scope; they are not certified as replacements. Complete dated evidenceRuns and unrelated selectors/assertions are unchanged; none selects these retired suites and none validates the narrowed command. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account preserved verbatim below as historical, including any older then-retained coverage claim: Audit4362 intentionally deletes the imported stale-waiter retry and manually assembled OSC9999 mobile-republish cases, plus the mocked missing-worktree cleanup suite (4 authored / 5 finite cases in three suites). Lost alarms include repeated unread worker_done pointers, working-to-waiting mobile status publication, missing-worktree filtering, and scoped daemon shutdown with unrelated duplicate identities. No replacement coverage or new platform proof is claimed. Audit3832 deliberately retires76 authored/79 finite cases:75 runtime compatibility cases/78 finite cases across14 fragments, plus one localization extractor default-flag case. Three whole runtime fragments are deleted;27 authored/30 finite cases remain across the reviewed sources. This gate retains only its own selected scope; no equivalent replacement or fresh runtime/native/remote evidence is claimed. Runtime component A: Audit3828 composes3822 with independent3824: deliberately retires49 authored/52 finite cases from seven compatibility fragments, leaving15 authored/18 finite cases and deleting two entire fragments. Accepted losses: positive folder-worker recovery/materialization and reveal deadline; persisted-key normalization and legacy split/group/focus projection; fixed stale CAS refusal; occupied/alias/restored/preallocated terminal-handle variants; fixed OpenCode/Cursor/Claude/Codex/Antigravity classification, readiness, title and management examples; direct private-map browser authority projections; browser-focus and OMP title projection; already-aborted claim cleanup. Additional3824 loss: src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts :: does not poll a wrapper foreground for a speculative CLI prompt send :: Speculative retryForegroundWrappers:false check must return false on a wrapper after one foreground read, without polling the supplied later codex response. These real bounded alarms are deliberately retired for low marginal value. Retained callbacks are unchanged and provide only their own bounded scope, not equivalent replacement. Historical receipts do not validate reduced callbacks. No fresh runtime/native/SSH/WSL/phone/browser evidence or full transitive closure is claimed. Runtime component B: Audit3834 deliberately retires26 authored/26 finite cases from seven fresh compatibility fragments, leaving10/10 and deleting the one-case saved-binding reattachment fragment. Original position58 is excluded: its existing substantive3578 KEEP7 review remains historical, with no fresh credit. Accepted losses: fixed hook/provider-session identities and stale metadata refusal; decorative/pre-title foreground ordering variants; saved-binding surface reattachment; saved-row exit ghost removal and silent activation selection; unsupported headless wake; positive pending materialization/group projections; per-caller navigation selection; positive SSH hydration/read partition; laptop mobile publication/buffer and background/pending/status projections; abnormal/unregistered SSH grace, normal-exit refusal, persisted SSH hydration, positive serve reattachment, pending-agent launch arguments and direct seeded running-launch admission guard. These are real bounded alarms deliberately retired for low marginal value. Retained cases preserve their own distinct deferred foreground coalescing, usable handle continuity, stale inventory refresh, concurrent browser snapshot preservation, renderer graph fencing, caller dedup isolation, SSH partition writes, runtime split lifetime, independent relay-ready publication, lease admission/state/expiry. The direct running-launch no-spawn guard alarm is deliberately retired; no remaining owning-launch refusal coverage is claimed. Historical runs do not validate reduced callbacks. No equivalent replacement, runtime/native/SSH/WSL/phone/browser result or full transitive closure is claimed. Additional extractor loss: config/scripts/localization/source-extraction/audit-localization-native-dialogs.test.mjs :: does not change the existing renderer scan by default :: Default options must omit the five native-only fields in this supplied snippet. No equivalent replacement is claimed. Historical prior account (preserved verbatim): Audit3814 deliberately retires60 authored/60 finite cases:53runtime compatibility cases,4native XCTest methods and3Python clipboard methods, including the entire StableElementIndexes suite. Clipboard cuts retire the one-over-cap sample, incoming-offer destruction trace and sequential20-copy replay; actual wire, FD/pipe, startup and Xvfb/GTK boundaries remain without equivalent replacement claims. Accepted losses include narrow terminal-send payload/provider projections, legacy and direct no-op/error permutations, timing/work-count examples, private state/title/activity projections and fixture-driven readiness examples, individually enumerated below. These include real bounded production alarms consciously retired for marginal value; retained failed writes, duplicate submission, stale capture, transcript/ring and allocation fences are not equivalent replacements. No fresh native/remote/browser execution or complete transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3806 deliberately retires40 authored/40 finite runtime compatibility cases, including the terminal-side-effect-facts-part03 headless-snapshots-part02 and agent-status-and-waits-part03 fragments, plus20 scalar Swift precondition sites. Lost runtime alarms include status/title/attention projection examples, simple renderer/headless frame restoration and status waiting outcomes detailed in the accepted-loss ledger. Swift cuts retire duplicate generation-map/schema/navigation/bridge and notification-wrapper assertions; no standalone native program is deleted. These include real bounded production alarms consciously retired for marginal value. Retained races, pending writes/reflow, namespace and waiter ownership are not equivalent replacements. No fresh native/remote/browser execution or full transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3798 deliberately retires21 authored/24 finite compatibility cases, including the entire SSH-worktree-lifecycle and repository-project-operations fragments. Accepted losses include navigation-only settings acknowledgement, browser session cleanup and host preservation projections, window positive/policy-state examples, terminal recovery/reload and no-incarnation remint examples, terminal listing compatibility/malformed IDs, directory browse/sort/Windows path smoke, SSH create refusal/manual lineage, recursive parent-folder creation and fork/origin/avatar/icon projections. Real bounded production alarms are consciously retired for marginal value; retained authority races, cleanup/clone ownership, pending waiters, nested-folder and scan invalidation cases are not equivalent replacements. No fresh native/remote/browser execution or full transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3580: Retire the whole one-case runtime host environment prototype/subclass suite. Intentionally lose the exact configured lower-case Windows Claude home to account-identity normalization and host-account override precedence alarm previously retained by Audit3129. No equivalent replacement or fresh runtime validation is claimed. Earlier dated keep statements below describe their historical source scope; the current suite is removed. Audit3563 scope: retire the whole Kiro OSC/hook identity suite and the OpenCode2 identity-only case; reduce Codex cached startup child-retirement and missing-session-ID tables to one case each (2 authored/4 finite removals). Intentionally lose Kiro alias/session continuity, OpenCode2 completed OSC identity continuity, cached replacement without relay-generation restart, and missing-previous-ID context-preservation alarms. Remaining provider, remote compatibility, persistence and cross-session pollution cases are not equivalent replacements. Also remove the private Codex roster-size assertion while retaining public child-absence checks. Historical evidence retains its original source scope; no new execution or transferred pass validates these reductions. Audit3446 composes ROOT-adopted3441/independent3442: intentionally removes100 authored registrations/119 potential expanded cases (118 conditional-active before platform gates) across16 sources, retaining11 authored/13 expanded cases and deleting6 whole suites. Two parent registrar import/call cleanups and the unused68line CLI recording fixture carry zero test credit. No equivalent replacement or fresh execution is claimed. The decorative fanout suite retains only real OSC9999 ingestion through runtime/title heartbeat/viewer past the stale boundary, preserving stateStartedAt and clearing expired prompt metadata. Spinner volume/zero-work inventories, Pi/Grok frame tables, rich-status and foreground-reset examples are retired. Existing receipts for separate paired-terminal sources retain their original scopes. Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3342 removes three supplied activation/inventory fallback and same-handle retry examples; their fallback/retry alarms are intentionally lost without equivalent replacement. The exact mounted-HUB pending old-stream-end versus replacement-snapshot registration and its assertion remain. Unrelated dated macOS receipts retain only their original scope; no fresh runtime, provider, performance, mobile, mixed-version or cross-platform validation is claimed. Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: restarts only the stream whose renderer delivery credit never settles — An unreturned renderer delivery credit stalls only its stream, leaving healthy sibling/shared transport alive. Fake-clock deadline plus real multiplexer unsubscribe isolates recovery ownership.; probes then restarts a stream when an entered command receives no frames — Entered command produces no output; actual multiplexer must probe then close only its stalled stream after probe timeout. Distinct response liveness from parser credit.; establishes a probe baseline before recovering an unsequenced stream — 142-line manual five-probe baseline/regression sequence derives request IDs from encoded mock traffic and checks repeated no-close/close choreography. Oversized algorithm/state-machine example; no actual renderer/host command or recovery delivery. Retires unsequenced/unchanged/regressed baseline classification alarms.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces remote-runtime-pty-transport-unpublished-host-graph.test.ts, retiring its direct published-empty-graph omission-to-pane-exit alarm. The unchanged bounded unpublished-frame/pushed-recovery and stale-handle park/manual-retry cases are narrower, not equivalent replacements. Both complete three-case Linux receipts dated 2026-11-04 are archived as historical, including source heads; they do not validate this reduced selector. Remaining fourteen active receipts are macOS only. No fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3318 composes adopted sources 3310, 3313 and 3317: intentionally retires 71 authored declarations and 102 expanded cases, including whole terminal-detach agent-retention, seeded batch/single open-files equivalence, shallow context-menu shortcut-badge, mocked active-workspace delete-dispatch, workspace session hydration, SSH target cleanup, editor session hydration and worktree terminal purge suites. Lost alarms include chained transfer alias and immediate close/exit retention; batch/single divergence, survivor/selection/map preservation and input nonmutation across 400 imperative seeds (one registered case); disconnected pending-handle retry, authoritative absences/close-record shortcut/older-host absence and published-presence/unpublished-frame examples; published empty host-graph omission to pane exit; legacy search ranking/exclusion fallback; provider request upgrade/dedupe/finalizer ownership; asynchronous PR suppression/primary-change and same-number different-repository URL rejection. Deletion routing loses host/instance qualification, paired and legacy mapping, folder ownership, active-versus-hover/menu-row selection, ambiguity, modal/editable/creation/view/main/deleting/missing guards and shortcut advertisement. Unchanged real keyboard/hover/confirmation/catalog E2E remains narrower, not an equivalent replacement. Additional losses include scripted old-host disk/UTF-8/noop/baseline and landed/unlanded lost-reply/replacement-retry outcomes; ordinary/repeated healthy-link reattach; cross-owner terminal/chat binding; oversized replay permanent-unavailable classification; floating reveal keyboard ownership/close/disable/listener disposal; naming/retained-turn/Sleep/error/close/reject status tables; SSH membership prune/new-target-only reads and environment/local bucket isolation; same-frame receipt capacity and positive bare/headless publisher readmission. These actual regression alarms are deliberately lost; no fresh gate, provider, rendered, mobile, mixed-version, cross-platform, soak or measured-budget validation is claimed. Audit 3312 composes adopted sources 3302 and 3308: deliberately retires 33 authored declarations and 36 expanded cases, including the whole backend startup-focus, active-browser IPC-close-routing, remote-browser-creation and agent-terminal-presence suites. Intentionally lost alarms cover distinct six-pane reconnect handles; SSH host label/Connect callback, unhydrated visit cleanup, repo cache aliases and hidden worktree/tab/PTY cleanup; adopted-agent startup focus and viewer navigation/reuse; staged, pageless, source, stale and orphan browser-close routing; web local-materialization refusal, desktop incapable-host fallback, failed/thrown remote creation and paired-web sign-in refusal; BOM/NUL and remote/local custom-editor byte-read examples; immediate folder activation and unread clearing; and batching idle/coalescing, accumulated byte ceiling, leading-edge-disabled, standalone synchronous oversize rejection, validation yield, deferred pending-tail order and both viewport-clear examples. The newly reintroduced agent-terminal-presence suite also loses actual terminal-status membership positive and nonterminal-status callback suppression alarms, including the recent 40916 guard regression; the older different 2133 presence-suite history remains historical and receives zero duplicate removal credit. These real regression alarms are intentionally lost. The unchanged survivors provide narrower coverage, with no equivalent replacement or fresh gate, provider, rendered, remote/mobile, mixed-version, cross-platform, soak or measured-budget validation claimed. Audit 3301 combines adopted source batches 3296 and 3299: retire 27 authored declarations and 36 expanded scenarios, including six whole suites. Intentionally lost alarms cover failed-verification/recovery/restart counters and mocked hosting/toast; early overlapping pane-read scheduling/count; unreadable removal listing draft guard; bulk-purge remote-qualified and raw-local guard maps; initial-snapshot blank/mode/oversize/printable/fresh-spawn callback and replay examples; fallback mobile file close and ordinary MRU; default queue overload/drain; seeded browser-page reuse and supplied missing-page URL recreation; ambiguous sleep/hibernation owner refusal and untouched bindings/origins; ordinary selection/activity/fallback priority; skip-remote success and retained hints; supplied structured-chat unsent retention and scoped removal draft eviction; caller-chat focus precedence; open/draft PR cache eviction and merged-head fallback result inventories. Retained adverse-ordering and ownership cases are narrower and do not establish equivalent replacements. No fresh runtime, native, physical provider, cross-platform, mobile or mixed-version evidence is claimed. Audit 3292 combines adopted 3285/3287/3289/3293 removals: 40 authored declarations and 47 expanded scenarios, including whole frame-editor-view, ambiguous remote-delete-refusal, unverifiable-host subscription and editor-close cleanup suites. The previously reviewed dock-badge suite was already removed upstream in PR 40895 and receives zero new removal credit. Intentionally retired alarms include background browser selection and last-tab landing; main startup fallback, SSH project cleanup/survivor routing, exact-PR contradiction/saved-push positives, replay/sidecar rollback and wrapped remote error normalization; records/snapshot missing-diff hydration, ambiguous folder-owner delete refusal, focus no-op notifications, nested editor context-only cache check, pending broadcast-first status and ordinary four-confirmation aggregation; preview-source frontmatter pruning, approved local/runtime agent dispatch, non-GitHub legacy PR cache invalidation, stale merged-head transient-error fallback, empty-queue immediate query reply and unverified-to-concrete preflight risk. Additional intentionally retired alarms are injected host subscription/unsubscribe counts, synthetic editor reveal/draft/fallback/scoped close, ambiguous unread refusals and hidden mark/read roundtrip, immediate connect backoff/noError, positive mirrored evidence-clock renewal, supplied VM failure/success projections and git-local/folder-SSH wake permutations. Remaining temporal/ownership cases are narrower; no equivalent replacement or fresh execution is claimed. Audit 3283 removes 20 authored declarations and 31 expanded scenarios, including two whole suites. Retired alarms cover PR refresh-state pruning, shared runtime subscription cleanup and store isolation, language content-change routing and older completion ownership, ordinary panel retry-timer cleanup and pending loading, four hosted-review lifetime permutations, mocked terminal creation error/order wiring, five sleep-inventory variants with pending-frame-only assertions, palette fallback/composite highlights, Windows/UNC encoded-editor input rows, mixed-repository partial failure counts, title setters and generated-title bypass/replacement, five window-close coordinator delegation/guard/finally branches, and ambiguous-old-record frame reveal. These regression checks are intentionally lost under the test-value audit; retained cases are not equivalent replacements. Prior coverage notes and receipts remain historical. Audit 3273 removes 14 authored declarations and 19 expanded scenarios across four whole suites and eight partial suites. Retired alarms cover saved-local cancellation/layout ownership, ambiguous-owner warning reset, folder attachment routing, VM false-capability bypass, abandoned reveal warmup cleanup and viewport claim deduplication/rearming, quiet unrelated remote-removal refusal, startup-command one-shot consumption, repository/floating recovery-ledger rows, fake-React pinned-scroll intent, split-ratio state identity/subscriber suppression and fractional change, cross-host project-group join refusal, three PR request-lifetime permutations, upstream-status preservation on error, and unresolved Git-owner refusal. These regression checks are intentionally lost under the test-value audit; retained scenarios are not equivalent replacements. Historical coverage receipts remain historical, including gate35 subscriber claims. Audit 3256 removes these specific alarms from the broad root unit commands: skill dialog active-share selection, close and pending-share handoff; simple keyed-record deletion; marker live-region insertion, simple landing and nine baseline policy examples; General search/control navigation inventory; orphan-count cache bootstrap; seven Codex code classifications and HTTP 429 warning mapping; two skill unread-root verdict examples; peer-mail payload and conversation-ID rejection; and the GitHub organization TABLE text-field optimistic rollback/failed-envelope example. These include real behaviors; retained tests do not provide equivalent coverage for every removed scenario. Mobile losses are recorded separately and are not coverage of these root commands. Audit3246 retires NewRowsMarker reveal/no-repeat and pane-scoped beforeinput checks; skill-owner option availability/count/dedup/order; six styled Input/Textarea IME forwarding rows; the static Codex/OpenCode smart-key inventory; tab-map AST ratchet diagnostic fixtures; child-roster work-budget and retained-aggregate alarms; malformed persisted floating-cwd fallback/no-crash/empty exact-root checks; the unanswered-host empty-list discriminator; the direct invalidated-cache commit-false assertion; one redundant digit-keyup IME row; cached non-supported Claude title-generator rows; and the duplicate late naming-result singleton. These root broad commands lose those specific alarms without equivalent replacement. Distinct retained owner/state checks have their own bounded claims; the real scheduler still rejects stale response data, while the direct false-return alarm is retired. Audit3231 retires supported-host restore-pane key mapping, closed/open creation-sidebar toggle visibility, unrelated scope-error/null classification and quick-submit reveal/no-create checks. These broad commands lose those real narrow alarms; no replacement coverage is claimed. Audit3219 removes the synthetic Cmd+J extra-source suite; this broad command no longer checks its match/tie placement and selection, announced count, empty-query cap, or workspace hiding with retained recent tabs. No replacement coverage is claimed. Audit3209 composes approved sources3202/3206: deliberately retires seven authored/expanded cases in four whole suites without equivalent replacement. Work-item queries lose real GitHub/GitLab oversized ASCII secret-prefix empty-query and whitespace-before-trim refusal alarms; inputs share the imported size bound and exercise only its fast length branch, with no multibyte or actual provider/exposure guarantee. Skill sharing loses complete/partial managed-bundle and destination-ambiguity association checks plus three negative origin/path/scheme admission examples; these do not establish uploaded contents, arbitrary-URL fetching, authorization or execution. Retain exact originless-project direct-link fallback, cloud-delete confirmation, bundled-target repair/owner isolation and explicit Windows-host preference over stale WSL suites. Rejected3201 runtime-preference removal is excluded. No real cloud/network/host/disk, mobile or mixed-version execution validation is claimed. Audit3200 composes approved source3194: deliberately retires thirteen authored registrations/twenty-seven expanded cases in six whole automation host/list policy suites without equivalent replacement. Real RPC category/retryability and wrapped-timeout recognition, unscoped-failure/scoped-success health evidence precedence, exact-ID create selectors and per-run workspace omission, paired-web local/SSH/absent host catalog routing, incompatible/removed/unhydrated/offline execution health, runtime-before-nested-SSH recovery dispatch, and no-owned-focus/successor/foreign-list focus policy alarms are consciously lost. Retain exact20line orphan allow/refuse/precondition and exact90line cross-host same-ID search suites. No retry-timer/fence lifecycle, actual reconnect/network/write delivery, native focus, mobile/mixed-version runtime or disk persistence coverage is claimed. Audit3191 combines approved source3182/3187/3188: deliberately retires thirteen authored Vitest registrations and fifteen expanded cases, including five whole suites, without equivalent replacement. Attachment intake loses real portal/native-capture terminal interception and unowned-container refusal, immediate child-only committed availability/claim-ref negotiation and delivery, and direct-target over stable focused/background composer routing through disable/re-enable/remount and independent question focus. Exact destination/cache/draft and final-stat owner/workspace/File-release suites remain; they do not replace Surface recipient routing. Automation authoring loses destination runtime catalog membership, local/direct-SSH exclusion of paired-runtime repos, unknown-runtime empty catalog, logical project/host/setup/repo/path context payload, and missing/nonready setup refusal; these were genuine direct helper alarms, while exact schedule transformation, legacy schedule and setup-decision suites remain. Agent picker loses setup-chat/terminal/missing-installer/unsupported-or-unknown-host row projection samples and the ordinary unsearched menu variant; the entire original26-line resume recipe suite remains, including reported bypass versus default/absent permission modes, as does the exact search-result menu callback with its fixtures, model/effort commits and staged Arguments reopen outcome. Rejected predecessor3180 full recipe deletion is excluded. No actual native drag/cursor/focus/IME, upload bytes or disk/restart persistence, full automation save/scheduler/runtime transport, real resume-process flags/environment delivery, or native menu/rendered layout validation is claimed. Audit3178 combines source3169/3170/3175: deliberately retires eight authored units (six Vitest cases and two imperative custom relay scenarios), including two whole suites, without equivalent replacement. Voice Section loses per-model pending-delete isolation across interleaved A/B completion and the two-success refresh-call alarm; exact VoicePane delayed key-clear/newer enabled-toggle merge remains and does not replace row deletion coverage. Speech loses dedicated rating-scale/inclusive-ceiling, unsupported-versus-unmeasured, explicit/system-language precedence/locale alias, accuracy versus fast named/default/best-measured selection, and unmeasured/no-match examples; exact offered-user-pick versus retired-selection case and its fixture remain. Relay loses legacy ping-delivery count/liveness sampled before the silence deadline and grouped malformed Bearer/host-ID 401/429 routing checks; twelve real Worker/DurableObject/shipped-client scenarios remain, not equivalent replacement for those narrow alarms. Six prior speech cases are not all deleted: approved successor3175 keeps the original user-choice case. No actual credential/file persistence, native/GPU/engine/download delivery, production assignment policy or deployed-runtime validation is claimed by this reduction. Audit3165 combines source3160/3162: deliberately retires six authored/expanded cases across three whole suites without equivalent replacement. Launch/status losses: observed React-render pending/resuming coordination across settings and deferred offer read; stale-offer reread suppressing dialog reopen; held-local-chat recovery visibility with new-chat preferences off; disabled-local admission avoiding offer RPC despite an injected but unconsumed paired-tab fixture; and run-only lost-reply uncertainty reachability until direct viewed-run retirement. Launch probe does not prove arbitrary synchronous-store atomicity, the paired fixture is not remote runtime enrollment, and the status case directly marks viewed state rather than rendering the summary. Crew-hook losses: old-host method_not_found cache persists across party changes but is released by independently supplied connection generation/verified pairing status or pairing revision, with actual frame publication and teardown. These are real narrow coordination, admission, uncertainty and mixed-version cache alarms consciously lost. Exact web verified-runtime writer handoff guard remains; it does not replace those alarms or prove live host/native/mobile delivery. Audit3156 combines3147/3150/3152/3153/3154: deliberately retires39authored/40expanded native-chat recovery cases, eight whole suites and two orphan test-support files without equivalent replacement. Lost alarms: lost-reply unconfirmed reconciliation, skipped rows/counts and missed-frame repair, unknown/pending outcome and omitted-failure-list compatibility, uncertain history after dismissal, retry/refusal/dismiss lifecycle, hidden/consumed picker ownership, result-tree keyboard focus/disclosure and all-skipped retirement; unconfirmed-over-conflict guidance and failed-chat changes despite older host timestamps; nearest-listed ancestor/cyclic forest shape, descendant membership, host ordering/missing-host local fallback; skipped/readiness/admission counts, provisional skip/progress monotonicity, early per-chat verdicts with batch pending protection, older-host waiting, start-slot/delivery distinction, retry-over-failure and unknown-after-withdrawal attention; remote snooze/reconnect/reoffer, unseen mixed summary through open/close, watched completion retirement, new success beside old failure, failed-reread mixed-result preservation, filter/collapse completion resets, retry summary replacement and current-offer/history selection; cross-host workspace identity, rendered cyclic reachability, nested tri-state/toggle propagation, project eligibility isolation and collapse preserving selection. Exact fallback-list completion barrier, batched verdict/cleanup retention, stale-read versus dismissal publication race, and requested-but-never-rendered finished-run retirement remain; they do not replace retired alarms. Audit3146 combines source reviews3132/3133/3135/3138/3143: intentionally retire20authored/31expanded cases without equivalent replacement. Provider-session losses: structured-native terminal-resume exclusion, metadata-less completed identity, new-turn completion clearing, Pi provider-only/periodic/manual promotion, changed-transcript launch-config isolation, Pi/omp/prime-agent completed-session remote/manual-shutdown promotion, and quit/done precedence over heartbeat. Side-thread/question losses: finished-pane acquisition, hidden title/recap states, local/relay/relay-done conversation takeover with prompt/session/child resets, plain-message abandonment, compaction/session replacement and completion resets. Codex startup losses: incoming-owner cached child replacement, old-relay foreign live-session correction, completed foreign-root turn-fact permutations. Transcript losses: real temporary-JSONL partial sibling/final-child completion, unlabelled child attribution, compact cached replay preservation and100/1000completed-child roster retention/release. Compiler-ratchet losses: valid-line uncompiled-list parser grammar examples and injected-existence stale-path filtering; these did not exercise actual filesystem canonicalization or build exclusion. These are real lifecycle, ownership, replay, liveness and retention alarms, including recent#40246 regressions, deliberately lost. Retained conditional record replacement, clockless root/SSH owner isolation, persisted main-thread fork rejection, partial/final question-answer lifetime, cached-roster/missing-ID/live HTTP/durable startup boundaries and restarted-relay refusal/acceptance do not replace those losses. No native/SSH/WSL execution or equivalent coverage is claimed. Audit3128 scoped coverage reduction: Audit3121 removes VoiceDictationLanguageSetting.test.tsx (Spanish-to-es callback and unsupported-model Korean option presence) and voice-speech-model-rows.test.ts (provider/language-order/retired-on-disk list policy); these real narrow alarms are deliberately retired without replacement. VoiceSpeechModelSection per-model concurrent deletion remains unchanged. Audit3122 removes the direct absolute/parent-segment sparse-directory exception-type sample and the five-row IPC sparse-preset error-code/non-save table (two authored/six expanded cases). Those real typed-validation and IPC refusal/error-code alarms are deliberately retired. Keep both real symlink/junction floating-directory trust cases and the minimal RPC structured validation-reason serialization case. The RPC case does not replace IPC save/refusal behavior, typed normalization for both path inputs, actual Git sparse checkout or rendered localization. No equivalent replacement or fresh test/runtime/platform/remote/performance validation is claimed. Audit3124 removes ExperimentalPane.test.tsx (ordinary Pet switch callback), WorkspaceDirectorySetting.test.tsx (padded absolute saved-path normalization/no-write blur), and repository-search.perf.test.ts (navigation/selected-pane builder-call policy, fixture cardinality/nonempty entries and renamed project keyword inclusion). These real narrow alarms are retired without replacement; RepositoryPane.search.test.tsx search-to-sparse-editor request remains unchanged. Audit3129: resolver Windows case-insensitive and POSIX case-sensitive configured-env composition plus mocked-base launch-preflight Windows composition are intentionally no longer checked by the two deleted suites. No equivalent coverage claimed. Keep runtime-structured-agent-host-env.test.ts unchanged: configured Windows Claude-home account identity and host-account precedence remain checked. Audit3114 incorporates source3101: retire three structured Claude child-environment wrapper cases covering inherited stamp isolation/default and explicit entrypoint, Windows SDK-key canonicalization/default/duplicate-key order, and configured lookup/final environment/config-dir conjunction. Keep direct auth/session sanitation and Windows-versus-Linux overlay checks, actual executable lookup from supplied inherited PATH, native Windows child environment delivery, and stale option-mutation fencing. These are not equivalent replacements for the retired wrapper alarms. No fresh test/runtime, real login-shell probe, Claude SDK startup, remote/mixed-version, UI or performance result is claimed. Audit3114 incorporates source3105: retire 17 authored/20 expanded daemon launch-note cases, including the entire two-case SessionLaunchNote suite. Deliberately lose split-marker carry across same-token re-arm, stale-token retirement refusal, foreground tri-state and serial settlement, omitted-note/no-incarnation mixed-version policy, sticky retirement, first-incarnation/replacement launch preservation and held-launch precedence. Keep only the unchanged unresolved foreground-read race against a later finished attach. Supplied notes/foreground and runtime calls do not establish actual daemon/main restart, SSH, native Windows observation, mobile UI, equivalent replacement or fresh runtime/performance validation. Audit3114 incorporates source3109: retire six authored/35 expanded pricing cases: 21 accepted model-name examples, 10 unsupported/future-model fail-closed examples, malformed TTL clamp, unknown-model estimate refusal, flat-model long-context disregard and oversized long-context clamp. Keep mixed five-minute/one-hour write allocation and short/all-long/mixed long-context allocation with original fixed oracles. Real parser/refusal/bounds alarms are knowingly lost without equivalent replacement; retained tests do not validate provider rates, actual billing or request threshold classification. Preserve the archived usage-scan-append source-freeze receipt without transferring historical execution/performance credit. No fresh runtime result is claimed. Audit3108 source-only reduction (3094/3095/3100): retire 27 authored/30 expanded cases, including complete markdown view-state, file-preview link-open and CLI agent-server-route suites, without replacement. Deliberate losses include preview visibility/reference lifetime and same-path owners; SSH stat, directory/missing-target, explicit-null owner, nonmarkdown line/column, local URI routing, remote-to-client guard and same-file reuse; document-preview source-owner/folder/reuse routing, stable grant location and outside-workspace POSIX/Windows request projection; and verified remote CLI send/check refusal, suggested --on argv/copy, shell no-probe bypass, unverified-launch admission and older-peer refusal. Retain two markdown source-runtime/qualified-reveal alarms, one stale grant-rejection fence and two remote read/mutation evidence policies, with original callbacks. Final last-wins reveal did not prove transient cancellation; CLI prerequisite did not prove no real send, and envelope tests do not execute server refusal. No fresh runtime, rendered UI, actual file/SSH/paired transport, authorization, mixed-version or performance result is claimed. Audit3096 source-only reduction (3087/3088): retire 69 authored/76 expanded cases, including complete recovery-portals and reconnect-banner suites. Intentionally lose dead/default TUI replay, generated alternate-frame style composition, reset/mode/dimension and legacy missing-mode-boundary alarms, UI notice/action/reveal policies, and isolated recovery lifecycle variants, without equivalent replacement. Retained registrations and callbacks are unchanged; headless cells are not pixels, and no fresh runtime, host, SSH, WSL, rendered-app or performance result is claimed. Audit3086 source-only reduction (3079/3080/3081): intentionally retire 93 authored/100 expanded mock-boundary cases, including the complete spawn-errors and SSH reconnect overlay suites, without replacement. Retired alarms include spawn classification/ownership, reply ceilings and renderer-write failure recovery, disconnect/detach fencing branches, authority facts, and overlay retry/visibility wiring. Retained callbacks are unchanged; no fresh execution, real PTY/SSH, rendered UI, or performance result is claimed. The direct side-effect-facts selector retains six cases: replay exclusion, live sequence handling, stale disposer ownership, one handoff drain, drain-before-snapshot, and stale replacement-snapshot refusal. Successful current-entry snapshot application is not witnessed by the retained snapshot case. Audit2432: The broad unit command loses the isolated BranchPicker open-change notification sample. Its unique true/false callback alarm is intentionally retired; reopening/status-refresh behavior was not exercised. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2425: The broad unit command loses the workspace-copy-status supplied readError forwarding sample. It did not exercise the branch-switch blocking promised by its title. This alarm is intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2417: The broad unit command loses two ordinary clean Git cherry-pick/revert success samples and two terminal startup foreground-read work-budget samples. These unique alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2412: The broad unit command loses the whole six-case fake-React-hook scroll-anchor suite, two generic draft-retention samples, a simple new-agent order sample, a real history-publication batching-count sample, an unmounted handoff abort/timer sample and three basic WSL preview/error samples. These alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2404: The broad unit command loses the standalone share-name lookup 503 propagation suite, initial deletion placement-kind sample, direct changed-mtime stale sample, first-pass rollback existence example and abandoned-preparation directory sample. These exact alarms are intentionally retired without equivalent replacement or fresh validation of the reduced selector. Audit2397 review amendment: The broad unit command loses three standalone suites, two partial-case definitions and two URL table rows across package/download/placement tests. Keep initial wrong-port authorization, modified independent-copy digest refusal and abort-after-begin cancellation dispatch. The remaining alarms are deliberately retired; no equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2393 current-parent refresh2401: Remove the basic skill-install service alias sample and original public managed-remove receiptless refusal case. Preserve the upstream request ownership suite and transaction interruption coverage. No equivalent complete replacement or fresh validation of the reduced selector is claimed. Audit2389: The broad unit command loses the missing-preview suite, plain-global destination sample and prepublished-receipt recovery example. No equivalent replacement or fresh validation of the reduced selector is claimed. Audit2385: The broad unit command loses four authored walker/staging/protocol examples (six expanded cases); no equivalent replacement or fresh validation is claimed for the reduced suite. Audit2383: The unscoped Vitest command no longer includes the removed Antigravity catalogue suite; its exact provider-root/owner example has no equivalent replacement or fresh validation claim. Audit2377/2381: The unscoped Vitest command includes the reduced bundled-skill and native-discovery suites; the eight removed backup/legacy/catalogue/symlink/SSH-builder examples have no replacement-equivalence or fresh validation claim here. Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2095 current-parent preparation2126: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2090 (sources2088/2089): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2086 (sources2082/2083): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/runtime/orca-runtime-tests/terminal-handles-part-02.spec.ts: recovers a moved SSH pane through the tab it now sits in, not the one its lease froze; reports a plain expired orphan; does not report a pane whose only recent lease was superseded; does not report a pane whose only recent lease had its relay id recycled; picks the eligible orphan over a superseded predecessor that matches first; collects the same tabs the per-tab reader reports, in one sweep of the leases; reports no candidate when no lease names any of the worktree tabs. src/main/runtime/orca-runtime-tests/runtime-availability.spec.ts: starts unavailable with no authoritative window; reports the configured Windows terminal shell on status; reports floating workspace availability from settings on status; polls floating tabs with targeted PTY liveness and no repo/provider inventory; hydrates persisted tabs when the store cannot report repos; advertises browser screencast only when a renderer window is available; routes mobile Codex reset consumption through the account mutation coordinator; maps a definite pre-provider rejection into an authoritative current snapshot. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2003: Remove SSH/absent-inventory attach refusal, later-subscriber retry, no-view adoption/takeback, provider-tail/unknown-read projections, failed-keystroke retry and simpler loss reattach examples. Keep the existing-subscriber inventory-ready retry alias only at its retained callback, plus retained held-input cancellation/replacement and overlapping attach/loss fences. The inventory driver also loses the whole empty-worktree-publication registration and folder-host/unverifiable scalar examples. Retire the entire dated10-case attach receipt; retain16 independent receipts only in their original scopes. No retained-memory or real-daemon measurement follows from supplied provider inventories. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1991: Remove initial-snapshot sequence-domain, limited-tail/truncation and unknown-output-sequence aliases whose callbacks are removed. The source retains partial-chunk replay and requested-snapshot retry/admission at supplied snapshot/data seams, not equivalent replacement or measured retained-memory proof. Preserve the existing stream/pending-wait capacity aliases only to their retained owning multiplex callbacks with supplied PTY resolutions. Removing the sibling-PTY heartbeat dedup work-count sample does not establish a new decorative fanout budget; the unrelated-PTY cancellation fence survives. Preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Remove the reasonless-close selector and narrow census aliases to actual retained runtime and injected-inventory callbacks. The removed synthetic census-dedup and isolated pre-boundary timing cases receive no replacement credit; preserve17 unrelated dated receipts. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1939 (sources1934/1935): Delete the synthetic watcher-synchronization and partial-reconciliation suites. Retire all affected host-fact, capability-owner, activation-residue and retention-cap aliases because the remaining callbacks do not establish those full claims. Keep exact local hook/timer, byte-stream side effects, exit/disposal, scroll-intent cleanup and deterministic local rank/TTL progression callbacks within their mocked-host scope. No physical paired-host retention, resource budget or equivalent replacement evidence is assigned. The generic broad test command remains a runnable discovery command, never a dated execution receipt. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete the complete hook-agent-status projection suite and its two behavioral assertion aliases. Supplied stored hook/title/resume/staleness/rename/question/generation/PTY-retirement/snapshot-version projections are intentionally lost. The separate osc-status-scan gate mentions this source only in existing historical notes and receives no mutation. No measured hidden-output retention, CPU/RSS or resource budget result is claimed by the deleted source or this audit. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Retained exact unchanged-source receipts remain the only current execution evidence. Reduced selectors have no fresh execution result. Historical pre-audit oracle account for changed sources: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Run one byte-identical six-terminal oracle against an isolated headed desktop host and an isolated headless `orca serve` host. Stage at least 1,000,000 xterm cells, hide all six warm managers, emit an initial working title followed by 30 timed real-PTY spinner frames and a final idle title per worktree, and observe a second real session-tabs subscription plus the production renderer store. Require exactly two transport envelopes and two title mutations per worktree, no decorative title crossing either boundary, and positive decoded-envelope bytes. Enable ordinary parking with the lossy retention budget disabled, require exactly one mounted manager and five parked tabs, at most 45% retained cells, no more than 16 MiB heap growth, and under 500 ms timer drift. In headed mode, require the host renderer to remain on its original workspace with zero target terminal managers mounted throughout client park, reveal, and live I/O. While a tab is parked, require authoritative terminal.read to observe new PTY output; reveal it and require the original PTY, a marker within the requested 5,000-row history, the parked marker, and post-reveal input/output. Drive 24 real PTY title trackers in distinct worktrees through 40 decorative spinner frames each, then 40 spinner frames alternating with Cursor's bare native identity redraw, using fake clocks. Require all 2,880 raw chunks exactly and zero host session-tabs publications, serialized bytes, renderer apply calls, and renderer store mutations. Continue decorative evidence beyond 30 minutes, require exactly one refresh per worktree per 15-minute lease through a FIFO spaced by at least 50 ms, and require all 24 viewer statuses to remain working and fresh; then require one exact semantic idle transition and one visible-output chunk per PTY. Require ordinary and interior-Braille title changes to publish. Drive 64 host PTYs through ten 80 ms synthetic title frames, require zero paired client events after the first frame per PTY while all 640 local frames remain observable, attach a late client and require one current frame per PTY, then require semantic bell and idle transitions on both clients. Reconstruct a legacy subscribed stream with no outputPause capability, hide a chatty pane, require no hidden xterm writes, reveal it, and require one authoritative snapshot plus continued live output. Drop and acknowledge output only for one original paired-client stream, prove the fixture process consumed input while the host model advanced and the client stayed stale, then require the command snapshot probe to replace that stream, repaint exact fixture output, preserve authoritative PTY identity and target-tab cardinality, and resume live I/O. For a client without a delivered sequence, require the first numeric probe to establish a baseline without replacement, a same-sequence probe to remain attached, and a later advanced probe to replace only that stream. Withhold the first encrypted shared-control ready frame, start one RPC, trigger a status-probe refresh, and require two connections, one host delivery, successful response, and zero retained request bytes. Admit 128 active streams, reject the 129th as retryable, release one stream, then require the retry to attach and publish a snapshot without multiplying retained subscribers. Disable terminal.paired-parking.v1 and require the same oracle to fail before parking, while the legacy limit-one fallback separately passes. Also preserve truncated first paint, ACK-starved same-PTY recovery, responsive silent-command snapshot probes, dead-stream probe timeout recovery, and queued manual-disconnect fencing.", "commands": [ "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-unpublished-host-graph.test.ts", "ORCA_BACKGROUND_LAUNCH=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-host-quit-reconnect-input.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", @@ -8022,7 +8016,7 @@ "ORCA_BACKGROUND_LAUNCH=1 pnpm exec playwright test tests/e2e/paired-client-first-terminal-unopened-host-worktree.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", "pnpm exec vitest run --config config/vitest.config.ts tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts --maxWorkers=1", "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/parking/lifecycle/use-terminal-tab-cold-parking.test.ts --maxWorkers=1", - "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/construction/orca-runtime.test.ts src/main/runtime/rpc/terminal/terminal-multiplex-initial-snapshot-buffering.test.ts src/main/runtime/rpc/terminal/terminal-multiplex-pty-wait-capacity.test.ts src/main/runtime/rpc/terminal/terminal-subscribe-buffer.test.ts src/renderer/src/components/terminal-pane/pty-transport/output/terminal-side-effect-facts-handler.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-activation-inventory-fallback.test.ts src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-tab-watchers.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/web/web-preload-api-runtime-environment.test.ts src/main/ipc/runtime-environments/pairing/runtime-environments-pairing.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/construction/orca-runtime.test.ts src/main/runtime/rpc/terminal/terminal-multiplex-initial-snapshot-buffering.test.ts src/main/runtime/rpc/terminal/terminal-multiplex-pty-wait-capacity.test.ts src/main/runtime/rpc/terminal/terminal-subscribe-buffer.test.ts src/renderer/src/components/terminal-pane/pty-transport/output/terminal-side-effect-facts-handler.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-activation-inventory-fallback.test.ts src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-tab-watchers.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/web/web-preload-api-runtime-environment.test.ts src/main/ipc/runtime-environments/pairing/runtime-environments-pairing.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/terminal/adoption/terminal-subscriber-driven-daemon-attach.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/session-tabs/runtime-inventory-publication-authority.test.ts src/main/runtime/rpc/methods/session-tabs/session-tabs-inventory-census-race.test.ts src/main/daemon/terminal-host/testing/terminal-host-agent-session.test.ts tests/e2e/session-tabs-empty-inventory-daemon-oracle.unit.test.ts --maxWorkers=1", "pnpm exec vitest run --config config/vitest.config.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts", @@ -8054,7 +8048,6 @@ "src/main/daemon/terminal-host/testing/terminal-host-agent-session.test.ts", "tests/e2e/session-tabs-empty-inventory-daemon-oracle.unit.test.ts", "src/renderer/src/components/terminal-pane/pty-transport/output/terminal-side-effect-facts-handler.test.ts", - "src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts", "src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-tab-watchers.test.ts", "src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts", "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-activation-inventory-fallback.test.ts", @@ -8476,7 +8469,10 @@ "Audit3446 composes ROOT-adopted3441/independent3442: intentionally removes100 authored registrations/119 potential expanded cases (118 conditional-active before platform gates) across16 sources, retaining11 authored/13 expanded cases and deleting6 whole suites. Two parent registrar import/call cleanups and the unused68line CLI recording fixture carry zero test credit. No equivalent replacement or fresh execution is claimed. The decorative fanout suite retains only real OSC9999 ingestion through runtime/title heartbeat/viewer past the stale boundary, preserving stateStartedAt and clearing expired prompt metadata. Spinner volume/zero-work inventories, Pi/Grok frame tables, rich-status and foreground-reset examples are retired. Existing receipts for separate paired-terminal sources retain their original scopes. All prior notes and complete dated receipts retain their original scopes.", "Audit3446 archived original assertionRef after source reduction; historical scope only, raw original object follows:\n{\n \"file\": \"tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts\",\n \"assertions\": [\n \"2,880 decorative spinner and bare-native real-PTY OSC chunks publish zero session-tabs snapshots or serialized bytes after semantic convergence\",\n \"the viewer performs zero snapshot applies and zero store mutations during decorative activity\",\n \"after 30 minutes, one globally spaced refresh per worktree keeps every mirrored working status fresh\",\n \"exact Pi and rotating normalized Pi/Grok frames renew explicit and fallback status without changing stateStartedAt or acknowledgement semantics\",\n \"matching title evidence renews retained OSC hook status without resetting stateStartedAt, then drops unverifiable prompt metadata after the hook row expires\",\n \"renderer-authored rich status keeps its original lease, then renews only coarse title-confirmed state and provider identity\",\n \"ordinary-shell title transitions replace working stateStartedAt with the completion transition time\",\n \"decorative heartbeats remain blocked until unknown foreground ownership resolves, then resume at the bounded interval\",\n \"tracked terminal state reset clears delayed foreground ownership markers\",\n \"raw chunks, semantic idle transitions, and visible output remain exact\"\n ]\n }", "Audit3832 deliberately retires76 authored/79 finite cases:75 runtime compatibility cases/78 finite cases across14 fragments, plus one localization extractor default-flag case. Three whole runtime fragments are deleted;27 authored/30 finite cases remain across the reviewed sources. This gate retains only its own selected scope; no equivalent replacement or fresh runtime/native/remote evidence is claimed. Runtime component A: Audit3828 composes3822 with independent3824: deliberately retires49 authored/52 finite cases from seven compatibility fragments, leaving15 authored/18 finite cases and deleting two entire fragments. Accepted losses: positive folder-worker recovery/materialization and reveal deadline; persisted-key normalization and legacy split/group/focus projection; fixed stale CAS refusal; occupied/alias/restored/preallocated terminal-handle variants; fixed OpenCode/Cursor/Claude/Codex/Antigravity classification, readiness, title and management examples; direct private-map browser authority projections; browser-focus and OMP title projection; already-aborted claim cleanup. Additional3824 loss: src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts :: does not poll a wrapper foreground for a speculative CLI prompt send :: Speculative retryForegroundWrappers:false check must return false on a wrapper after one foreground read, without polling the supplied later codex response. These real bounded alarms are deliberately retired for low marginal value. Retained callbacks are unchanged and provide only their own bounded scope, not equivalent replacement. Historical receipts do not validate reduced callbacks. No fresh runtime/native/SSH/WSL/phone/browser evidence or full transitive closure is claimed. Runtime component B: Audit3834 deliberately retires26 authored/26 finite cases from seven fresh compatibility fragments, leaving10/10 and deleting the one-case saved-binding reattachment fragment. Original position58 is excluded: its existing substantive3578 KEEP7 review remains historical, with no fresh credit. Accepted losses: fixed hook/provider-session identities and stale metadata refusal; decorative/pre-title foreground ordering variants; saved-binding surface reattachment; saved-row exit ghost removal and silent activation selection; unsupported headless wake; positive pending materialization/group projections; per-caller navigation selection; positive SSH hydration/read partition; laptop mobile publication/buffer and background/pending/status projections; abnormal/unregistered SSH grace, normal-exit refusal, persisted SSH hydration, positive serve reattachment, pending-agent launch arguments and direct seeded running-launch admission guard. These are real bounded alarms deliberately retired for low marginal value. Retained cases preserve their own distinct deferred foreground coalescing, usable handle continuity, stale inventory refresh, concurrent browser snapshot preservation, renderer graph fencing, caller dedup isolation, SSH partition writes, runtime split lifetime, independent relay-ready publication, lease admission/state/expiry. The direct running-launch no-spawn guard alarm is deliberately retired; no remaining owning-launch refusal coverage is claimed. Historical runs do not validate reduced callbacks. No equivalent replacement, runtime/native/SSH/WSL/phone/browser result or full transitive closure is claimed. Additional extractor loss: config/scripts/localization/source-extraction/audit-localization-native-dialogs.test.mjs :: does not change the existing renderer scan by default :: Default options must omit the five native-only fields in this supplied snippet. No equivalent replacement is claimed.", - "Audit5571 exact prior command before retired heartbeat selector removal: pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/session-lifecycle/publication/mobile-session-tabs-agent-status-heartbeat.test.ts tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts --maxWorkers=1" + "Audit5571 exact prior command before retired heartbeat selector removal: pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/session-lifecycle/publication/mobile-session-tabs-agent-status-heartbeat.test.ts tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts --maxWorkers=1", + "Audit5772 exact original complete commands JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-unpublished-host-graph.test.ts\",\n \"ORCA_BACKGROUND_LAUNCH=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-host-quit-reconnect-input.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/terminal/query/runtime-terminal-inventory-contracts.test.ts\",\n \"ORCA_BACKGROUND_LAUNCH=1 pnpm exec playwright test tests/e2e/paired-client-first-terminal-unopened-host-worktree.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\",\n \"pnpm exec vitest run --config config/vitest.config.ts tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts --maxWorkers=1\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/parking/lifecycle/use-terminal-tab-cold-parking.test.ts --maxWorkers=1\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/construction/orca-runtime.test.ts src/main/runtime/rpc/terminal/terminal-multiplex-initial-snapshot-buffering.test.ts src/main/runtime/rpc/terminal/terminal-multiplex-pty-wait-capacity.test.ts src/main/runtime/rpc/terminal/terminal-subscribe-buffer.test.ts src/renderer/src/components/terminal-pane/pty-transport/output/terminal-side-effect-facts-handler.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-activation-inventory-fallback.test.ts src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-tab-watchers.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/web/web-preload-api-runtime-environment.test.ts src/main/ipc/runtime-environments/pairing/runtime-environments-pairing.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/terminal/adoption/terminal-subscriber-driven-daemon-attach.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/session-tabs/runtime-inventory-publication-authority.test.ts src/main/runtime/rpc/methods/session-tabs/session-tabs-inventory-census-race.test.ts src/main/daemon/terminal-host/testing/terminal-host-agent-session.test.ts tests/e2e/session-tabs-empty-inventory-daemon-oracle.unit.test.ts --maxWorkers=1\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-host-restart-background-sync.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\",\n \"ORCA_E2E_FORWARD_APP_LOGS=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-host-restart-background-sync.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1 --repeat-each=10 --max-failures=1\",\n \"ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-truncated-tail-first-paint.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-lossy-initial-snapshot.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"ORCA_E2E_WEB_CLIENT=1 ORCA_E2E_DISABLE_PAIRED_TERMINAL_PARKING=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-truncated-tail-first-paint.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-stall-recovery.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-probe-gap-recovery.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/headless-paired-remote-terminal-stall-recovery.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"ORCA_E2E_WEB_CLIENT=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-retention-memory.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-retention-memory.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\",\n \"ORCA_E2E_WEB_CLIENT=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/headless-paired-remote-terminal-retention-memory.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/terminal-parked-memory.spec.ts --config tests/playwright.config.ts --project electron-headful --workers=1\"\n ]", + "Audit5772 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n \"tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts\",\n \"src/renderer/src/components/terminal-pane/parking/lifecycle/use-terminal-tab-cold-parking.test.ts\",\n \"src/main/runtime/construction/orca-runtime.test.ts\",\n \"src/renderer/src/web/web-preload-api-runtime-environment.test.ts\",\n \"src/main/ipc/runtime-environments/pairing/runtime-environments-pairing.test.ts\",\n \"src/main/runtime/rpc/terminal/terminal-multiplex-initial-snapshot-buffering.test.ts\",\n \"src/main/runtime/rpc/terminal/terminal-multiplex-pty-wait-capacity.test.ts\",\n \"src/main/runtime/rpc/terminal/terminal-subscribe-buffer.test.ts\",\n \"src/main/runtime/terminal/adoption/terminal-subscriber-driven-daemon-attach.test.ts\",\n \"src/main/runtime/session-tabs/runtime-inventory-publication-authority.test.ts\",\n \"src/main/runtime/rpc/methods/session-tabs/session-tabs-inventory-census-race.test.ts\",\n \"src/main/daemon/terminal-host/testing/terminal-host-agent-session.test.ts\",\n \"tests/e2e/session-tabs-empty-inventory-daemon-oracle.unit.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/output/terminal-side-effect-facts-handler.test.ts\",\n \"src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts\",\n \"src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-tab-watchers.test.ts\",\n \"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-activation-inventory-fallback.test.ts\",\n \"src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts\",\n \"tests/e2e/paired-remote-terminal-lossy-initial-snapshot.spec.ts\",\n \"tests/e2e/paired-remote-terminal-truncated-tail-first-paint.spec.ts\",\n \"tests/e2e/paired-remote-terminal-stall-recovery.spec.ts\",\n \"tests/e2e/paired-remote-terminal-probe-gap-recovery.spec.ts\",\n \"tests/e2e/headless-paired-remote-terminal-stall-recovery.spec.ts\",\n \"tests/e2e/paired-remote-terminal-retention-memory.spec.ts\",\n \"tests/e2e/headless-paired-remote-terminal-retention-memory.spec.ts\",\n \"tests/e2e/terminal-parked-memory.spec.ts\",\n \"tests/e2e/paired-remote-terminal-host-restart-background-sync.spec.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-unpublished-host-graph.test.ts\",\n \"tests/e2e/paired-remote-terminal-host-quit-reconnect-input.spec.ts\",\n \"src/main/runtime/terminal/query/runtime-terminal-inventory-contracts.test.ts\",\n \"tests/e2e/paired-client-first-terminal-unopened-host-worktree.spec.ts\"\n ]", + "Audit5772 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n {\n \"file\": \"tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts\",\n \"assertions\": [\n \"real OSC9999 hook status remains live through title heartbeats without resetting stateStartedAt, then loses unverifiable prompt metadata after its original lease expires\"\n ]\n },\n {\n \"file\": \"src/main/runtime/terminal/adoption/terminal-subscriber-driven-daemon-attach.test.ts\",\n \"assertions\": [\"retries an existing subscriber when provider inventory becomes ready\"]\n },\n {\n \"file\": \"src/main/runtime/rpc/methods/session-tabs/session-tabs-inventory-census-race.test.ts\",\n \"assertions\": [\n \"creation and removal at the census release edge are subsumed once, and a delayed pre-boundary change is not replayed\",\n \"post-boundary creation and removal replay after the initial snapshot in sequence order\",\n \"create/remove/recreate transitions are preserved without collapse\",\n \"a post-boundary projected-state change is delivered without a new snapshot revision\",\n \"an older coalesced callback cannot overwrite a newer immediate change\",\n \"initialization churn publishes only the latest projected state and repeated structural overflow fails after bounded recollection\",\n \"disconnect aborts the census and removes the real runtime listener\"\n ]\n },\n {\n \"file\": \"tests/e2e/session-tabs-empty-inventory-daemon-oracle.unit.test.ts\",\n \"assertions\": [\n \"unpublished empty inventory keeps resume dispatch at zero with the original daemon session, process id, and writer as the sole live writer\",\n \"an authoritative empty inventory settles the mirror and releases exactly one resume dispatch with zero liveness probes\",\n \"re-enabling unconditional empty hydration makes the identical oracle red with one resume dispatch, two session ids, two process ids, and two writer calls\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-remote-terminal-host-restart-background-sync.spec.ts\",\n \"assertions\": [\n \"preserves daemon PID and target PTY identity across the paired host relaunch\",\n \"foregrounds the daemon-backgrounded target on its first post-relaunch remote observation\",\n \"delivers target and post-relaunch control terminal input and live output\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-remote-terminal-probe-gap-recovery.spec.ts\",\n \"assertions\": [\"replaces a stale paired stream when the PTY snapshot advanced\"]\n },\n {\n \"file\": \"tests/e2e/paired-remote-terminal-stall-recovery.spec.ts\",\n \"assertions\": [\n \"restarts one ACK-starved paired terminal stream without replacing its PTY\"\n ]\n },\n {\n \"file\": \"tests/e2e/headless-paired-remote-terminal-stall-recovery.spec.ts\",\n \"assertions\": [\"recovers an ACK-starved stream from an isolated headless Orca host\"]\n },\n {\n \"file\": \"tests/e2e/paired-remote-terminal-lossy-initial-snapshot.spec.ts\",\n \"assertions\": [\n \"a nonempty lossy initial snapshot paints exactly once on a paired client\",\n \"the authoritative host cursor advances and live output resumes exactly once\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-remote-terminal-truncated-tail-first-paint.spec.ts\",\n \"assertions\": [\n \"paints a paired remote terminal when only its retained text tail overflowed\",\n \"legacy paired hosts retain the lossy hidden-manager budget fallback\"\n ]\n },\n {\n \"file\": \"tests/e2e/paired-remote-terminal-retention-memory.spec.ts\",\n \"assertions\": [\n \"ordinary-parks paired terminals and restores authoritative host scrollback\",\n \"warm-mounted hidden paired streams schedule zero renderer output work under sustained host output\",\n \"six hidden real PTYs publish and apply only exact working and idle title transitions across paired transport\",\n \"client recovery completes while every target terminal remains unmounted in the host renderer\"\n ]\n },\n {\n \"file\": \"tests/e2e/headless-paired-remote-terminal-retention-memory.spec.ts\",\n \"assertions\": [\n \"ordinary-parks paired terminals against an isolated headless Orca host\",\n \"cold-activates only visible paired terminals against an isolated headless host\",\n \"the headless host bounds real-PTY decorative title transport and production store application\",\n \"the headless host shares the zero-hidden-renderer-work and exact-restoration contract\"\n ]\n },\n {\n \"file\": \"tests/e2e/terminal-parked-memory.spec.ts\",\n \"assertions\": [\n \"releases un-parkable hidden worktree buffers only once the retention budget engages\"\n ]\n },\n {\n \"file\": \"src/main/runtime/rpc/terminal/terminal-multiplex-pty-wait-capacity.test.ts\",\n \"assertions\": [\n \"admits 128 active streams, rejects the 129th, and reuses released capacity\",\n \"reserves PTY wait capacity independently from active streams\"\n ]\n },\n {\n \"file\": \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-activation-inventory-fallback.test.ts\",\n \"assertions\": [\n \"keeps a mounted HUB mirror alive when the old stream ends before the replacement snapshot\"\n ]\n },\n {\n \"file\": \"src/renderer/src/web/web-preload-api-runtime-environment.test.ts\",\n \"assertions\": [\n \"keeps pairing while manual disconnect fences passive reconnects\",\n \"returns a disconnect envelope when a queued active runtime call disconnects\",\n \"returns a disconnect envelope when a queued selected environment call disconnects\"\n ]\n }\n ]" ], "demotionRule": "Keep experimental or demote to protection none if decorative title frequency changes paired client-event or session-tabs publication volume after convergence, a semantic fact is dropped, paired first paint is blank, passive work reconnects after manual disconnect, a capable hidden paired manager survives ordinary parking, a legacy hidden pane schedules raw xterm output or bypasses its fallback, reveal loses requested bounded history or live PTY identity, retained buffer cells do not fall, or either headed/headless scenario flakes." }, @@ -9029,19 +9025,18 @@ "providers": ["daemon", "ssh", "remote-runtime"], "coveredPlatforms": ["macos", "linux"], "coveredProviders": ["daemon", "ssh"], - "coverageNotes": "Audit1939 (sources1934/1935): Pruned hidden-view suite retains local rank and age eviction only; its snapshot-capability and paired-owner admission examples are removed. No assertion object maps to this source, so unrelated aliases remain untouched. Existing physical stall selectors and their original dated receipts retain their independent scope; they do not validate removed capability units. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: An Electron main-stall oracle proves capability lookup is asynchronous. Startup prefetch covers restored primary and split-pane PTY identities before cold activation, while unknown providers remain eager. Docker SSH journeys prove remote terminals still remount eagerly and reclaim their authenticated PTY owner after restart. Audit1292: The entire terminal-provider snapshot capability suite is removed. Unchanged-set scan suppression,512 batching/IPC, timeout/unknown state, stale-result fences, success/failure retry signals, unresolved cadence, identical-set retries and closed/reappearing-ID reset alarms are lost. Remaining Electron responsiveness evidence does not establish equivalent unit coverage. Audit1299 removes tests/e2e/terminal-cold-activation-deferral.spec.ts. Private-state/work-budget/assembled-fixture alarms are intentionally lost; retained suites are not equivalent replacement coverage. No new runtime/platform evidence is claimed.", + "coverageNotes": "Audit5772 companion to audit5768: Retire the whole hidden-view parking policy suite. Direct local recency/cap/TTL/last-active retention and activation tie-order alarms are intentionally lost without equivalent replacement. Narrow one compound unit command and remove the parking testFiles entry. Separate renderer snapshot-capability/main-stall assertions remain unchanged at their own exact scope; they are not certified as replacements. Complete dated evidenceRuns and unrelated selectors/assertions are unchanged; none selects these retired suites and none validates the narrowed command. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account preserved verbatim below as historical, including any older then-retained coverage claim: Audit1939 (sources1934/1935): Pruned hidden-view suite retains local rank and age eviction only; its snapshot-capability and paired-owner admission examples are removed. No assertion object maps to this source, so unrelated aliases remain untouched. Existing physical stall selectors and their original dated receipts retain their independent scope; they do not validate removed capability units. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: An Electron main-stall oracle proves capability lookup is asynchronous. Startup prefetch covers restored primary and split-pane PTY identities before cold activation, while unknown providers remain eager. Docker SSH journeys prove remote terminals still remount eagerly and reclaim their authenticated PTY owner after restart. Audit1292: The entire terminal-provider snapshot capability suite is removed. Unchanged-set scan suppression,512 batching/IPC, timeout/unknown state, stale-result fences, success/failure retry signals, unresolved cadence, identical-set retries and closed/reappearing-ID reset alarms are lost. Remaining Electron responsiveness evidence does not establish equivalent unit coverage. Audit1299 removes tests/e2e/terminal-cold-activation-deferral.spec.ts. Private-state/work-budget/assembled-fixture alarms are intentionally lost; retained suites are not equivalent replacement coverage. No new runtime/platform evidence is claimed.", "motivatingLinks": ["https://stablygroup.slack.com/archives/C0BD60A5J85/p1785524559818629"], "invariant": "PTY snapshot capability discovery must never synchronously block renderer JavaScript. Restored daemon capability must be known before workspace readiness enables cold activation; unknown or legacy capability must remain eager. A healthy SSH provider must return definitive false without polling. One unresponsive capability batch must fail open within one second regardless of PTY count, and stale async responses must not update current bindings.", - "oracle": "Audit1939 (sources1934/1935): Pruned hidden-view suite retains local rank and age eviction only; its snapshot-capability and paired-owner admission examples are removed. No assertion object maps to this source, so unrelated aliases remain untouched. Existing physical stall selectors and their original dated receipts retain their independent scope; they do not validate removed capability units. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): During an injected 1.5-second Electron main-thread stall, a renderer-owned 50ms interval must keep a maximum gap below 500ms and each API call must return within 100ms. The production cold-activation journey must still mount at most three of eight daemon tabs after reload, while Docker SSH restoration remains eager.", + "oracle": "Audit5772 companion to audit5768: Retire the whole hidden-view parking policy suite. Direct local recency/cap/TTL/last-active retention and activation tie-order alarms are intentionally lost without equivalent replacement. Narrow one compound unit command and remove the parking testFiles entry. Separate renderer snapshot-capability/main-stall assertions remain unchanged at their own exact scope; they are not certified as replacements. Complete dated evidenceRuns and unrelated selectors/assertions are unchanged; none selects these retired suites and none validates the narrowed command. No fresh execution, current import reachability, replacement coverage or native/platform/remote result is claimed. Complete prior account preserved verbatim below as historical, including any older then-retained coverage claim: Audit1939 (sources1934/1935): Pruned hidden-view suite retains local rank and age eviction only; its snapshot-capability and paired-owner admission examples are removed. No assertion object maps to this source, so unrelated aliases remain untouched. Existing physical stall selectors and their original dated receipts retain their independent scope; they do not validate removed capability units. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): During an injected 1.5-second Electron main-thread stall, a renderer-owned 50ms interval must keep a maximum gap below 500ms and each API call must return within 100ms. The production cold-activation journey must still mount at most three of eight daemon tabs after reload, while Docker SSH restoration remains eager.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/use-terminal-provider-snapshot-capability.test.tsx src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts --reporter=dot", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/use-terminal-provider-snapshot-capability.test.tsx src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts --reporter=dot", "pnpm exec electron-vite build --mode e2e", "SKIP_BUILD=1 pnpm exec playwright test tests/e2e/pty-snapshot-capability-main-stall.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1 --repeat-each=3" ], "testFiles": [ "src/renderer/src/components/terminal/use-terminal-provider-snapshot-capability.test.tsx", "src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts", - "src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts", "tests/e2e/pty-snapshot-capability-main-stall.spec.ts" ], "assertionRefs": [ @@ -9092,7 +9087,10 @@ "This gate proves renderer responsiveness to main stalls; it does not identify the cause of the reported production hard freeze.", "Audit1292: The entire terminal-provider snapshot capability suite is removed. Unchanged-set scan suppression,512 batching/IPC, timeout/unknown state, stale-result fences, success/failure retry signals, unresolved cadence, identical-set retries and closed/reappearing-ID reset alarms are lost. Remaining Electron responsiveness evidence does not establish equivalent unit coverage.", "Audit1299 removes tests/e2e/terminal-cold-activation-deferral.spec.ts. Private-state/work-budget/assembled-fixture alarms are intentionally lost; retained suites are not equivalent replacement coverage. No new runtime/platform evidence is claimed.", - "Audit1939 (sources1934/1935): Pruned hidden-view suite retains local rank and age eviction only; its snapshot-capability and paired-owner admission examples are removed. No assertion object maps to this source, so unrelated aliases remain untouched. Existing physical stall selectors and their original dated receipts retain their independent scope; they do not validate removed capability units. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Exact retired authored alarms: 'selects only reachable hosts advertising the paired parking contract'; 'shares the capability Set across status-only changes and replaces it on membership changes'; 'allows local daemon sessions owned by the worktree'; 'allows folder-workspace sessions owned by the workspace'; 'rejects separator-less local PTY ids that lack a daemon session model'; 'rejects tabs that do not have a PTY yet'; 'rejects daemon sessions owned by another worktree'; 'rejects SSH and remote runtime PTY handles'; 'accepts every snapshot-backed pty regardless of policy'; 'accepts SSH ptys only when the SSH-parking policy is enabled'; 'accepts paired ptys only for the exact snapshot-capable owner'; 'rejects paired, fail-open, foreign, and null ptys without capability evidence'; 'parks hidden local terminal renderers after the idle delay'; 'parks a hidden SSH worktree only under the SSH restore policy'; 'defers preserved-daemon snapshot authority to the watcher coverage gate'; 'never parks when the settings kill switch disables parking'; 'keeps renderers mounted while visible, measuring, portaled, or before the delay'; 'honors a per-call cold-park delay override'; 'holds an otherwise past-deadline candidate out of park until the measure cool-down ends'; 'keeps the renderer mounted when any terminal lacks snapshot-backed restore'; 'keeps renderers mounted while a tab has startup or activation work pending'; 'ignores mirrored activation residue after a capable paired PTY exists'; 'parks an idle hidden local tab and honors the kill switch'; 'ignores mirrored activation residue after a capable paired PTY exists'; 'honors a per-call cold-park delay override'; 'holds an otherwise past-deadline tab out of park until the measure cool-down ends'; 'keeps recent hidden local worktrees hot up to the retain limit'; 'selects nothing when the settings kill switch disables parking'; 'does not cold-park terminals without local snapshot recovery'; 'keeps visible, measuring, portaled, and pending terminals mounted'; 'keeps visible and recent inactive terminal tabs mounted'; 'cold-parks the oldest inactive local tabs beyond the retain limit'; 'selects nothing while the post-measure cool-down is active'; 'cold-parks aged inactive local tabs even when under the retain limit'; 'never cold-parks the single most-recently-hidden (last-active) tab'; 'selects nothing when the settings kill switch disables parking'; 'does not cold-park inactive terminal tabs without local snapshot recovery'; 'keeps portaled, pending-startup, and pending-activation terminal tabs mounted'." + "Audit1939 (sources1934/1935): Pruned hidden-view suite retains local rank and age eviction only; its snapshot-capability and paired-owner admission examples are removed. No assertion object maps to this source, so unrelated aliases remain untouched. Existing physical stall selectors and their original dated receipts retain their independent scope; they do not validate removed capability units. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Exact retired authored alarms: 'selects only reachable hosts advertising the paired parking contract'; 'shares the capability Set across status-only changes and replaces it on membership changes'; 'allows local daemon sessions owned by the worktree'; 'allows folder-workspace sessions owned by the workspace'; 'rejects separator-less local PTY ids that lack a daemon session model'; 'rejects tabs that do not have a PTY yet'; 'rejects daemon sessions owned by another worktree'; 'rejects SSH and remote runtime PTY handles'; 'accepts every snapshot-backed pty regardless of policy'; 'accepts SSH ptys only when the SSH-parking policy is enabled'; 'accepts paired ptys only for the exact snapshot-capable owner'; 'rejects paired, fail-open, foreign, and null ptys without capability evidence'; 'parks hidden local terminal renderers after the idle delay'; 'parks a hidden SSH worktree only under the SSH restore policy'; 'defers preserved-daemon snapshot authority to the watcher coverage gate'; 'never parks when the settings kill switch disables parking'; 'keeps renderers mounted while visible, measuring, portaled, or before the delay'; 'honors a per-call cold-park delay override'; 'holds an otherwise past-deadline candidate out of park until the measure cool-down ends'; 'keeps the renderer mounted when any terminal lacks snapshot-backed restore'; 'keeps renderers mounted while a tab has startup or activation work pending'; 'ignores mirrored activation residue after a capable paired PTY exists'; 'parks an idle hidden local tab and honors the kill switch'; 'ignores mirrored activation residue after a capable paired PTY exists'; 'honors a per-call cold-park delay override'; 'holds an otherwise past-deadline tab out of park until the measure cool-down ends'; 'keeps recent hidden local worktrees hot up to the retain limit'; 'selects nothing when the settings kill switch disables parking'; 'does not cold-park terminals without local snapshot recovery'; 'keeps visible, measuring, portaled, and pending terminals mounted'; 'keeps visible and recent inactive terminal tabs mounted'; 'cold-parks the oldest inactive local tabs beyond the retain limit'; 'selects nothing while the post-measure cool-down is active'; 'cold-parks aged inactive local tabs even when under the retain limit'; 'never cold-parks the single most-recently-hidden (last-active) tab'; 'selects nothing when the settings kill switch disables parking'; 'does not cold-park inactive terminal tabs without local snapshot recovery'; 'keeps portaled, pending-startup, and pending-activation terminal tabs mounted'.", + "Audit5772 exact original complete commands JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/use-terminal-provider-snapshot-capability.test.tsx src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts --reporter=dot\",\n \"pnpm exec electron-vite build --mode e2e\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/pty-snapshot-capability-main-stall.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1 --repeat-each=3\"\n ]", + "Audit5772 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n \"src/renderer/src/components/terminal/use-terminal-provider-snapshot-capability.test.tsx\",\n \"src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts\",\n \"src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts\",\n \"tests/e2e/pty-snapshot-capability-main-stall.spec.ts\"\n ]", + "Audit5772 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; narrowed commands have no new validation:\n[\n {\n \"file\": \"tests/e2e/pty-snapshot-capability-main-stall.spec.ts\",\n \"assertions\": [\n \"a 1.5-second main stall leaves renderer interval gaps below 500ms\",\n \"capability calls return to renderer JavaScript within 100ms\"\n ]\n }\n ]" ], "demotionRule": "Demote if capability discovery reintroduces synchronous renderer IPC, cold daemon tabs mount eagerly despite authoritative snapshots, SSH capability polls after a definitive response, or the renderer gap budget flakes without a product or harness bug." }, @@ -9125,7 +9123,7 @@ "providers": ["ssh", "remote-runtime", "wsl"], "coveredPlatforms": ["linux"], "coveredProviders": ["ssh", "remote-runtime"], - "coverageNotes": "Audit5736 removes whole runtime/SSH IPC test suites from active selectors, accepting fake-window frame/contract/VM/upload cancellation and fake-transport SSH state/forward ownership alarms without equivalent replacement or fresh execution. Remaining dated evidence keeps its exact independent selector scope. Historical prior account (preserved verbatim): Audit5658 integrates source audit5652: retire the whole remote-runtime-pty-recovery-state.test.ts suite and its exact active selectors and assertionRef. Intentionally lose reentrant retry single dispatch; shared owner-refresh caller settlement and per-epoch allowance; deadline registry revival; parked same-epoch retry; actual deadline versus UI disconnected latch alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3554 intentionally removes the whole worktrees-ssh-repo-owner-resolution suite (2 authored cases). Dedicated duplicate-exact/ambiguous-legacy owner refusal and fixed runtime-host/wrong-target/missing-authority/zero-owner/contradictory-owner status alarms are lost. The suite did not exercise an authority transition or actual SSH listing; its no-local-Git spy was also unreachable on an admitted SSH metadata-only route. Remaining suites are not equivalent replacements. Current selectors have no fresh execution from this static packet; historical receipts retain their original scope. No new SSH/provider/native/UI/mobile/mixed-version/cross-platform result is claimed. Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3368 narrows stream-reconnect coverage to the actual ten synthetic transport epochs retaining one PTY identity, accepting and holding detached input for exactly-once later delivery, current decoded output and per-epoch subscription release. Prior rejection wording was inaccurate. Phase/backoff/cutoff/manual reconnect and parser/OSC/pause/retained-image/fatal/latch/claim/early-close alarms are intentionally lost without equivalent replacement. The Linux multi-pane reconnect receipt remains verbatim with its original scope; no fresh live SSH/provider/PTY/UI/mobile/mixed-version/cross-platform evidence is claimed. Audit3359 retires whole host-surface-replacement and create-handoff suites, removing their compound unit command tokens, test-file entries and assertion references. Fake polling/deadline/subscription, supplied stale-handle ownership, close and replacement examples are intentionally lost without equivalent replacement. The unrelated Linux paired multi-pane reconnect receipt stays verbatim with its original scope. No fresh SSH/provider/network/PTY recovery, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit3342 retires the complete client create-outcome identity/options/recovery suite and the malformed-or-contradictory repo-owner response matrix. Client replay identity, options, no-downgrade, quiescence/budget/manual retry, authoritative probe-error and malformed-owner refusal alarms are intentionally lost without equivalent replacement. Remaining repo-owner late catalog and old-host re-adoption boundaries do not replace them. The unrelated Linux paired-reconnect receipt stays verbatim with its original scope. Surviving selectors are unexecuted here; no fresh SSH/provider/process-deduplication, mobile, mixed-version or cross-platform validation is claimed. Audit3329 execution amendment: the reduced one-suite reconnect selector passed on Linux (1 case). Original source-review statements about no fresh execution describe the earlier static review; this new receipt validates only this one local deterministic unit case, not the complete gate or physical/runtime/rendered/provider/platform parity. Historical seven-case macOS and two-case Linux receipts remain archived verbatim. Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: keeps a sidebar row for every still-live pane after a long sleep — Whole suite: 279 lines manually replay renderer ownership registry/status writes, snapshot patch/set, six-pane fixture inventory, and sidebar selectors/builders; expected pane IDs are production-computed. Does not run sleep/wake/transport or actual sidebar entry. Retires reconnect row-preservation assembly alarm.; still retires the regular TUI surface after an explicit terminal exit — Ordinary explicit-exit callback/map cleanup is repeated in the stale/new stream lifecycle case below. Retires separate regular-TUI baseline; keeper is not equivalent process/UI proof.; asks the HUB to recover an expired SSH pane and rebinds the host identity — Expired SSH owner error must ask the owning HUB to recover, then adopt fixed replacement handle, resubscribe and report rebind; actual transport dispatch and handle state prevent wrong-client recovery.; does not recover a pane whose relay reply was an identity mismatch — Identity mismatch means a different live PTY, so actual transport must surface refusal without recover/create, keeping original identity. Prevents destructive duplicate agent recovery.; fails closed when an older HUB cannot recover an expired SSH pane — Old HUB method_not_found is scripted mock refusal/error echo with no actual skewed host; repeats generic recovery failure propagation. Retires old-host recovery fallback refusal example.; names a held recovery's stopped WSL distro in readable copy, not the raw hold code — Pins exact WSL stopped-distro error prose after mock code; translation/copy assertion with no actual held recovery behavior. Retires readable-copy alarm.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces runtime-environment-ssh-state.test.ts, intentionally losing metadata membership-pruning/new-target-only-read and other-environment/local-bucket isolation alarms. Preserve generation/failed-full-refresh assertion and unknown-target authoritative-list reread; these narrower cases are not equivalent replacements. The unchanged active two-case Linux reconnect materialization/sidebar receipt and covered platform retain their exact scope and do not validate the reduced SSH state selector. Preserve unrelated SSH assertions, selectors and archived history. No fresh SSH discovery, provider/PTY/network, rendered, mobile, mixed-version, cross-platform or full-gate execution is claimed. Audit3315 execution amendment: the reduced two-suite reconnect selector passed on Linux (2 cases). Original source-review statements about no fresh execution describe the earlier static review; this new receipt validates only these two local deterministic unit cases, not the complete gate or physical/runtime/rendered/provider/platform parity. Historical seven-case macOS receipt remains archived verbatim. Audit 3312 retires the ordinary six-pane distinct-live-handle reconnect/resubscription alarm from paired-reconnect-multi-pane-materialization.test.ts. The unchanged parked-pane activation/rematerialization case remains narrower and is not an equivalent replacement. The complete prior seven-contract macOS receipt is archived as historical evidence; it does not validate the reduced selector. No fresh socket, PTY, sleep/wake, provider, platform, mobile, mixed-version or rendered execution is claimed. Audit3096: remove the deleted reconnect-banner selector and its two UI aliases. The reduced recovery-state selector retains only the deadline cancelling pending backoff and explicit retry owning a new epoch alias; healthy-replacement stale-schedule and independent caller-cutoff cancellation aliases retire. Other retained state cases cover reentrant retry, owner settlement and same-epoch parked revival, without replacing those removed alarms. Prior admission-selector retirement, archived July 28 receipt, unrelated selectors/claims/receipts and old gaps remain unchanged; no fresh execution is claimed. Audit3086: retire the destroyed fresh-session fallback settlement/non-destructive reattach alias and its direct selector; retain the detach/attach selector and assertion unchanged. The retained admission cases cover adopt-before-data and explicitly buffered-death admission without a new spawn, without replacing fallback retirement. July 28 evidence was already archived by audit3077; no duplicate retirement or new execution is claimed. Audit2709 removes src/renderer/src/runtime/web-session-tabs-sync/inventory/remote-runtime-session-tabs-inflight.test.ts: intentionally retire waiting out an older inventory and sharing a fresh post-operation request among concurrent callers. No equivalent replacement or fresh execution is claimed. Dated receipts remain historical evidence for their unchanged selectors only; they do not validate the reduced commands or full current gate. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/ssh/connection/ssh-connection-manager.test.ts: tears a failed startup down quietly, so its error is not replaced by a disconnect; marks a dial that never reached the host, so setup reports SSH’s reason; removes the registration when bulk teardown fails; leaves a connection whose own reconnect is asking the user alone; clears the pool entry when the closed connection is still the registered one; still reuses a connection that is already up; dials a user's connection test. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Delete the terminal-create idempotency forwarding suite and its prospective selector. Preserve2 unrelated receipts without claiming the lost forwarding alarm was replaced. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the sole supplied public-SSH-state spread/sanitized-error projection and its provider-authority-pair alias. Also delete the complete tiny one-shot split-startup wrapper suite: callback-visible temporary field/reset, sequential payload and thrown-sentinel reset alarms disappear. No SSH provider epoch handoff, connection, process startup or actual terminal split was performed by either deleted suite. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): Audit1645 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1342 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1301 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Deterministic renderer coverage proves retained native and runtime SSH payloads are admitted through production routes only with valid complete authority, stale cleanup cannot unregister a replacement runtime terminal, direct SSH Git and folder panes keep their PTY bindings through disconnect and reconnect, one authority chain stops after two automatic attempts even when each timeout exceeds the rolling window, rejected acknowledgements mutate no store maps, and one shared exact attempt admits every concurrent split-pane spawn and reattach while preserving the first PTY as the tab fallback. A later sibling failure rotates the tab once, stale callbacks from the prior attempt mutate no state, split remount activity suppression is counted per leaf, primary PTY exit promotes a bound survivor or preserves an empty continuation gap for a late sibling, and primary, non-primary, or null-PTY detach preserves exact authority on both resulting tabs. Intentional pane disposal cancels its settlement timer without breaking StrictMode remount timeout ownership. A mounted remote-runtime terminal survives repeated transport partitions without changing PTY identity. A real encrypted-WebSocket oracle proves a successful reachability probe can replace a pre-ready shared-control socket without rejecting or duplicating the waiting RPC. Direct SSH coordinator tests cover immediate terminal finalization, hydration correction, damping, bounded retry, and telemetry non-interference. Client/server heartbeat tests cover timer suspension, socket generations fence stale callbacks, cold restored-terminal attachment retries, cached pixels remain unhealthy until authoritative replay, automatic retries stop after one minute, manual reconnect preserves the PTY, and pane closure releases recovery UI state. Current-transport recovery clears every error that transport surfaced without clearing or displaying a sibling pane's errors, while transport suppression, pane retention, and the rendered surface are independently bounded. Current macOS Electron journeys against an ephemeral Linux Docker SSH target cover exact-authority repo/worktree hydration, live terminal recovery after disconnect/reconnect, and eager six-terminal remount after renderer reload. A Windows remote-runtime smoke covers reachability and PTY round-trip. Multi-target live fanout, paired-close, WSL, and patched live partition journeys remain gaps. The test-value audit narrowed resolved-worktree-execution-host.test.ts to cache reuse and invalidation. Its direct hydrated-worktree, missing-folder, restored-owner, host-stamp and empty-runtime selection alarms are lost. Other routing and recovery suites do not establish equivalent selector coverage; historical run commands and results remain historical. The test-value audit removes standalone unwritten/released renderer-authority and cross-scope request-count examples. The retained synthetic mirror/store/sidebar and pending-inventory checks do not establish real PTY byte ownership, SSH reconnection or equivalent replacement coverage; historical commands and results remain historical. The test-value audit removes direct join/label ledgers, immediate failure and negative-only stale/removal/partial-authority examples, plus the standalone retained/live event projection. Retained synthetic store/hydration compositions do not establish real SSH continuity, remote authority delivery or equivalent replacement alarms. Historical commands and results remain historical. The renderer scheduling fixture retains in-flight coalescing only. Its immediate publication and negative stale-SSH-cleanup call ledgers were removed; the retained SSH recovery evidence does not replace those alarms. The accepted-handle-events observer suite is removed, including its scoped listener and settlement-release assertions. These observer alarms are lost; retained SSH/transport journeys are not equivalent replacement coverage. The test-value audit removed repeated remote-handle rotation inventories and snapshot-first pending-restart migration examples from terminal-pty-identity-replacement.test.ts, plus direct foreground metadata setter, confirmation, evidence-enum, and prefix/worktree cleanup examples. Those rotation, pending-restart, snapshot-first migration, and foreground scalar-update alarms are lost. The retained replacement case observes pane and tab identities in one subscriber publication; it does not establish equivalent migration, process-evidence, or input-routing coverage. Historical commands and results remain historical. The test-value audit narrows terminals-hydration.test.ts to a real reconnect batch with one measured store publication and hydration-seeded history consumed by a subsequent visit/Back check. Direct split-layout, runtime/folder/floating restoration, dead-leaf focus, cold/known-absent SSH deferral, title, default-tab marker, navigation initialization, and hydrationSucceeded scalar examples are removed; those specific alarms are lost. No actual target-removal transition, live SSH connection, session writer, or persisted restart is exercised by the retained cases. The old target-scoped/snapshot assertion references are retired because the current file does not contain those oracles. Other suites and historical runs do not establish equivalent replacement coverage. Audit1299 removes tests/e2e/terminal-cold-activation-deferral.spec.ts. Private-state/work-budget/assembled-fixture alarms are intentionally lost; retained suites are not equivalent replacement coverage. No new runtime/platform evidence is claimed. Audit1301: src/renderer/src/runtime/remote-runtime-session-tabs-inflight.test.ts reduced. Direct dedupe eviction/count and equal receipt-position sample loses authored alarm. No equivalent replacement coverage is claimed. Audit1318: src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts: Retain real local encrypted WebSocket regressions for pre-ready socket replacement preserving a request, close-before-ready logical subscription cleanup, unrelated RPC surviving another deadline, and pending setup abort leaving a sibling pending. Host server is synthetic and uses production crypto; kept scenarios also retain internal diagnostics/memory assertions unchanged. Remove happy routing, authority-envelope, unknown-ID/log, cleanup enum, binary, keepalive/liveness and production-budget/private socket inventories; intentionally lose those alarms, no physical host authorization, independent crypto or remote provider claim. Reduced selectors need fresh validation; historical full-suite receipts do not validate the changed coverage. No equivalent replacement or physical-provider claim. Audit1342: src/renderer/src/hooks/ipc-events/direct-ssh-connect-reply-routing.test.ts removed. Initial and event-triggered partial-authority hydration fixture alarms disappear. src/renderer/src/components/terminal-pane/terminal-error-accumulation.test.ts removed. Multiline dedup/storm bounds, resource classification/collision, scoped clear/reconnect strip and1000-pane map count alarms disappear. No equivalent replacement coverage is claimed. Audit1396: src/renderer/src/components/terminal-pane/pty-connection-pending-spawn.spec.ts reduced. Lose standalone debug-state retention/log silence alarm. React StrictMode is not mounted; bindings manually simulate remount over mocked transport. No equivalent replacement coverage is claimed. The existing primary-selector receipt and its claims remain scoped to their unchanged sources; the broad optional command has no new execution result. Audit1400: src/main/ipc/ssh/ssh.test.ts reduced. Lose trivial missing target and mocked publication inventory. Preexisting unresolved ../ssh/ssh-port-scanner mock is recorded, not fixed. src/renderer/src/runtime/sync-runtime-graph-scheduling.test.ts removed. Removes whole coalescing call-count suite; no newest-state delivery or replacement claim. src/renderer/src/store/slices/terminal-pty-identity-replacement.test.ts reduced. Removes three no-op/work-count registrations; retains externally observed ownership consistency. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1412: src/main/ssh/ssh-provider-authority.test.ts removed. Loses real AbortController revocation/target isolation/reentrancy outcomes, recreated-target generation-floor/session rollover behavior, stale mutation refusal and settled-registration cleanup alarms. These useful alarms are deliberately lost; no equivalent cancellation coverage is claimed. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1743 removes the standalone line-height clamp/default and pane cwd fallback helper tests (5 authored cases). These trivial-helper alarms are intentionally lost, with no equivalent replacement. Only current commands/testFiles lose the deleted selectors; historical receipts and evidenceRuns remain unchanged and do not validate the reduced commands. Audit5043 intentionally deletes the entire remote-runtime-client-error-classification suite (3 authored/9 finite cases): structured-code precedence over contradictory legacy text and7 unstructured-message compatibility alarms are lost. Whole retired-request-ID helper suite (3 cases) also removed outside this selector, losing direct TTL/non-refresh, eviction refresh and backward-clock expiry alarms. No equivalent replacement is claimed. Other selectors and dated evidence retain their original scope; no fresh execution, native/provider/mobile/mixed-version/cross-platform or full-gate result is claimed.", + "coverageNotes": "Audit5779 companion to audit5775: Retire the complete PTY detach/attach handoff suite. Handler-complete durable reattach detachment, buffered state/lifetime preservation and late spawn retain-versus-kill alarms are intentionally lost without replacement. Remove one standalone command, one testFiles entry and its direct obsolete-reattach assertionRef. Complete dated evidenceRuns are unchanged; none selects these retired suites and none validates narrowed selectors. All unrelated remaining assertions and selectors retain their original scope, without replacement certification. No fresh execution or current import reachability result is claimed. Complete prior account preserved verbatim below as historical: Audit5748 companion to audit5744 retires the whole queued-pane-startup.test.ts suite. Its remaining captured-primary split ownership, one-shot repeated-spawn consumption, replacement-before-spawn refusal and permanently spent skipped-consumer alarms are intentionally lost without equivalent replacement. Remove its standalone unit selector or narrow the compound selector and remove its testFiles entry. Existing assertionRefs/evidenceRuns keep only their original scope and are unchanged; no fresh execution, current import reachability, PTY/provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit5736 removes whole runtime/SSH IPC test suites from active selectors, accepting fake-window frame/contract/VM/upload cancellation and fake-transport SSH state/forward ownership alarms without equivalent replacement or fresh execution. Remaining dated evidence keeps its exact independent selector scope. Historical prior account (preserved verbatim): Audit5658 integrates source audit5652: retire the whole remote-runtime-pty-recovery-state.test.ts suite and its exact active selectors and assertionRef. Intentionally lose reentrant retry single dispatch; shared owner-refresh caller settlement and per-epoch allowance; deadline registry revival; parked same-epoch retry; actual deadline versus UI disconnected latch alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3554 intentionally removes the whole worktrees-ssh-repo-owner-resolution suite (2 authored cases). Dedicated duplicate-exact/ambiguous-legacy owner refusal and fixed runtime-host/wrong-target/missing-authority/zero-owner/contradictory-owner status alarms are lost. The suite did not exercise an authority transition or actual SSH listing; its no-local-Git spy was also unreachable on an admitted SSH metadata-only route. Remaining suites are not equivalent replacements. Current selectors have no fresh execution from this static packet; historical receipts retain their original scope. No new SSH/provider/native/UI/mobile/mixed-version/cross-platform result is claimed. Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3368 narrows stream-reconnect coverage to the actual ten synthetic transport epochs retaining one PTY identity, accepting and holding detached input for exactly-once later delivery, current decoded output and per-epoch subscription release. Prior rejection wording was inaccurate. Phase/backoff/cutoff/manual reconnect and parser/OSC/pause/retained-image/fatal/latch/claim/early-close alarms are intentionally lost without equivalent replacement. The Linux multi-pane reconnect receipt remains verbatim with its original scope; no fresh live SSH/provider/PTY/UI/mobile/mixed-version/cross-platform evidence is claimed. Audit3359 retires whole host-surface-replacement and create-handoff suites, removing their compound unit command tokens, test-file entries and assertion references. Fake polling/deadline/subscription, supplied stale-handle ownership, close and replacement examples are intentionally lost without equivalent replacement. The unrelated Linux paired multi-pane reconnect receipt stays verbatim with its original scope. No fresh SSH/provider/network/PTY recovery, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit3342 retires the complete client create-outcome identity/options/recovery suite and the malformed-or-contradictory repo-owner response matrix. Client replay identity, options, no-downgrade, quiescence/budget/manual retry, authoritative probe-error and malformed-owner refusal alarms are intentionally lost without equivalent replacement. Remaining repo-owner late catalog and old-host re-adoption boundaries do not replace them. The unrelated Linux paired-reconnect receipt stays verbatim with its original scope. Surviving selectors are unexecuted here; no fresh SSH/provider/process-deduplication, mobile, mixed-version or cross-platform validation is claimed. Audit3329 execution amendment: the reduced one-suite reconnect selector passed on Linux (1 case). Original source-review statements about no fresh execution describe the earlier static review; this new receipt validates only this one local deterministic unit case, not the complete gate or physical/runtime/rendered/provider/platform parity. Historical seven-case macOS and two-case Linux receipts remain archived verbatim. Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: keeps a sidebar row for every still-live pane after a long sleep — Whole suite: 279 lines manually replay renderer ownership registry/status writes, snapshot patch/set, six-pane fixture inventory, and sidebar selectors/builders; expected pane IDs are production-computed. Does not run sleep/wake/transport or actual sidebar entry. Retires reconnect row-preservation assembly alarm.; still retires the regular TUI surface after an explicit terminal exit — Ordinary explicit-exit callback/map cleanup is repeated in the stale/new stream lifecycle case below. Retires separate regular-TUI baseline; keeper is not equivalent process/UI proof.; asks the HUB to recover an expired SSH pane and rebinds the host identity — Expired SSH owner error must ask the owning HUB to recover, then adopt fixed replacement handle, resubscribe and report rebind; actual transport dispatch and handle state prevent wrong-client recovery.; does not recover a pane whose relay reply was an identity mismatch — Identity mismatch means a different live PTY, so actual transport must surface refusal without recover/create, keeping original identity. Prevents destructive duplicate agent recovery.; fails closed when an older HUB cannot recover an expired SSH pane — Old HUB method_not_found is scripted mock refusal/error echo with no actual skewed host; repeats generic recovery failure propagation. Retires old-host recovery fallback refusal example.; names a held recovery's stopped WSL distro in readable copy, not the raw hold code — Pins exact WSL stopped-distro error prose after mock code; translation/copy assertion with no actual held recovery behavior. Retires readable-copy alarm.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces runtime-environment-ssh-state.test.ts, intentionally losing metadata membership-pruning/new-target-only-read and other-environment/local-bucket isolation alarms. Preserve generation/failed-full-refresh assertion and unknown-target authoritative-list reread; these narrower cases are not equivalent replacements. The unchanged active two-case Linux reconnect materialization/sidebar receipt and covered platform retain their exact scope and do not validate the reduced SSH state selector. Preserve unrelated SSH assertions, selectors and archived history. No fresh SSH discovery, provider/PTY/network, rendered, mobile, mixed-version, cross-platform or full-gate execution is claimed. Audit3315 execution amendment: the reduced two-suite reconnect selector passed on Linux (2 cases). Original source-review statements about no fresh execution describe the earlier static review; this new receipt validates only these two local deterministic unit cases, not the complete gate or physical/runtime/rendered/provider/platform parity. Historical seven-case macOS receipt remains archived verbatim. Audit 3312 retires the ordinary six-pane distinct-live-handle reconnect/resubscription alarm from paired-reconnect-multi-pane-materialization.test.ts. The unchanged parked-pane activation/rematerialization case remains narrower and is not an equivalent replacement. The complete prior seven-contract macOS receipt is archived as historical evidence; it does not validate the reduced selector. No fresh socket, PTY, sleep/wake, provider, platform, mobile, mixed-version or rendered execution is claimed. Audit3096: remove the deleted reconnect-banner selector and its two UI aliases. The reduced recovery-state selector retains only the deadline cancelling pending backoff and explicit retry owning a new epoch alias; healthy-replacement stale-schedule and independent caller-cutoff cancellation aliases retire. Other retained state cases cover reentrant retry, owner settlement and same-epoch parked revival, without replacing those removed alarms. Prior admission-selector retirement, archived July 28 receipt, unrelated selectors/claims/receipts and old gaps remain unchanged; no fresh execution is claimed. Audit3086: retire the destroyed fresh-session fallback settlement/non-destructive reattach alias and its direct selector; retain the detach/attach selector and assertion unchanged. The retained admission cases cover adopt-before-data and explicitly buffered-death admission without a new spawn, without replacing fallback retirement. July 28 evidence was already archived by audit3077; no duplicate retirement or new execution is claimed. Audit2709 removes src/renderer/src/runtime/web-session-tabs-sync/inventory/remote-runtime-session-tabs-inflight.test.ts: intentionally retire waiting out an older inventory and sharing a fresh post-operation request among concurrent callers. No equivalent replacement or fresh execution is claimed. Dated receipts remain historical evidence for their unchanged selectors only; they do not validate the reduced commands or full current gate. Historical prior account (preserved verbatim): Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/ssh/connection/ssh-connection-manager.test.ts: tears a failed startup down quietly, so its error is not replaced by a disconnect; marks a dial that never reached the host, so setup reports SSH’s reason; removes the registration when bulk teardown fails; leaves a connection whose own reconnect is asking the user alone; clears the pool entry when the closed connection is still the registered one; still reuses a connection that is already up; dials a user's connection test. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Delete the terminal-create idempotency forwarding suite and its prospective selector. Preserve2 unrelated receipts without claiming the lost forwarding alarm was replaced. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the sole supplied public-SSH-state spread/sanitized-error projection and its provider-authority-pair alias. Also delete the complete tiny one-shot split-startup wrapper suite: callback-visible temporary field/reset, sequential payload and thrown-sentinel reset alarms disappear. No SSH provider epoch handoff, connection, process startup or actual terminal split was performed by either deleted suite. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): Audit1645 removes low-value test projections, mock wiring, private-state assertions, inventories and duplicate examples without equivalent replacement coverage. Per-source reviews record retained public behavior and refusal boundaries with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1640 removes low-value IPC, SSH, workspace and transcript-watcher tests without equivalent replacement coverage. Per-source reviews record retained public refusal, cancellation, execution-host and real-filesystem outcomes with injected/native/remote limits. Affected historical receipts are retired; gates without active current evidence are downgraded. Historical scope before this audit: Audit1342 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Audit1301 changes referenced sources. Retained unchanged-source receipts apply only to their unchanged commands; the reduced selectors have no new execution result. Historical coverage account (not a current claim for changed sources): Deterministic renderer coverage proves retained native and runtime SSH payloads are admitted through production routes only with valid complete authority, stale cleanup cannot unregister a replacement runtime terminal, direct SSH Git and folder panes keep their PTY bindings through disconnect and reconnect, one authority chain stops after two automatic attempts even when each timeout exceeds the rolling window, rejected acknowledgements mutate no store maps, and one shared exact attempt admits every concurrent split-pane spawn and reattach while preserving the first PTY as the tab fallback. A later sibling failure rotates the tab once, stale callbacks from the prior attempt mutate no state, split remount activity suppression is counted per leaf, primary PTY exit promotes a bound survivor or preserves an empty continuation gap for a late sibling, and primary, non-primary, or null-PTY detach preserves exact authority on both resulting tabs. Intentional pane disposal cancels its settlement timer without breaking StrictMode remount timeout ownership. A mounted remote-runtime terminal survives repeated transport partitions without changing PTY identity. A real encrypted-WebSocket oracle proves a successful reachability probe can replace a pre-ready shared-control socket without rejecting or duplicating the waiting RPC. Direct SSH coordinator tests cover immediate terminal finalization, hydration correction, damping, bounded retry, and telemetry non-interference. Client/server heartbeat tests cover timer suspension, socket generations fence stale callbacks, cold restored-terminal attachment retries, cached pixels remain unhealthy until authoritative replay, automatic retries stop after one minute, manual reconnect preserves the PTY, and pane closure releases recovery UI state. Current-transport recovery clears every error that transport surfaced without clearing or displaying a sibling pane's errors, while transport suppression, pane retention, and the rendered surface are independently bounded. Current macOS Electron journeys against an ephemeral Linux Docker SSH target cover exact-authority repo/worktree hydration, live terminal recovery after disconnect/reconnect, and eager six-terminal remount after renderer reload. A Windows remote-runtime smoke covers reachability and PTY round-trip. Multi-target live fanout, paired-close, WSL, and patched live partition journeys remain gaps. The test-value audit narrowed resolved-worktree-execution-host.test.ts to cache reuse and invalidation. Its direct hydrated-worktree, missing-folder, restored-owner, host-stamp and empty-runtime selection alarms are lost. Other routing and recovery suites do not establish equivalent selector coverage; historical run commands and results remain historical. The test-value audit removes standalone unwritten/released renderer-authority and cross-scope request-count examples. The retained synthetic mirror/store/sidebar and pending-inventory checks do not establish real PTY byte ownership, SSH reconnection or equivalent replacement coverage; historical commands and results remain historical. The test-value audit removes direct join/label ledgers, immediate failure and negative-only stale/removal/partial-authority examples, plus the standalone retained/live event projection. Retained synthetic store/hydration compositions do not establish real SSH continuity, remote authority delivery or equivalent replacement alarms. Historical commands and results remain historical. The renderer scheduling fixture retains in-flight coalescing only. Its immediate publication and negative stale-SSH-cleanup call ledgers were removed; the retained SSH recovery evidence does not replace those alarms. The accepted-handle-events observer suite is removed, including its scoped listener and settlement-release assertions. These observer alarms are lost; retained SSH/transport journeys are not equivalent replacement coverage. The test-value audit removed repeated remote-handle rotation inventories and snapshot-first pending-restart migration examples from terminal-pty-identity-replacement.test.ts, plus direct foreground metadata setter, confirmation, evidence-enum, and prefix/worktree cleanup examples. Those rotation, pending-restart, snapshot-first migration, and foreground scalar-update alarms are lost. The retained replacement case observes pane and tab identities in one subscriber publication; it does not establish equivalent migration, process-evidence, or input-routing coverage. Historical commands and results remain historical. The test-value audit narrows terminals-hydration.test.ts to a real reconnect batch with one measured store publication and hydration-seeded history consumed by a subsequent visit/Back check. Direct split-layout, runtime/folder/floating restoration, dead-leaf focus, cold/known-absent SSH deferral, title, default-tab marker, navigation initialization, and hydrationSucceeded scalar examples are removed; those specific alarms are lost. No actual target-removal transition, live SSH connection, session writer, or persisted restart is exercised by the retained cases. The old target-scoped/snapshot assertion references are retired because the current file does not contain those oracles. Other suites and historical runs do not establish equivalent replacement coverage. Audit1299 removes tests/e2e/terminal-cold-activation-deferral.spec.ts. Private-state/work-budget/assembled-fixture alarms are intentionally lost; retained suites are not equivalent replacement coverage. No new runtime/platform evidence is claimed. Audit1301: src/renderer/src/runtime/remote-runtime-session-tabs-inflight.test.ts reduced. Direct dedupe eviction/count and equal receipt-position sample loses authored alarm. No equivalent replacement coverage is claimed. Audit1318: src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts: Retain real local encrypted WebSocket regressions for pre-ready socket replacement preserving a request, close-before-ready logical subscription cleanup, unrelated RPC surviving another deadline, and pending setup abort leaving a sibling pending. Host server is synthetic and uses production crypto; kept scenarios also retain internal diagnostics/memory assertions unchanged. Remove happy routing, authority-envelope, unknown-ID/log, cleanup enum, binary, keepalive/liveness and production-budget/private socket inventories; intentionally lose those alarms, no physical host authorization, independent crypto or remote provider claim. Reduced selectors need fresh validation; historical full-suite receipts do not validate the changed coverage. No equivalent replacement or physical-provider claim. Audit1342: src/renderer/src/hooks/ipc-events/direct-ssh-connect-reply-routing.test.ts removed. Initial and event-triggered partial-authority hydration fixture alarms disappear. src/renderer/src/components/terminal-pane/terminal-error-accumulation.test.ts removed. Multiline dedup/storm bounds, resource classification/collision, scoped clear/reconnect strip and1000-pane map count alarms disappear. No equivalent replacement coverage is claimed. Audit1396: src/renderer/src/components/terminal-pane/pty-connection-pending-spawn.spec.ts reduced. Lose standalone debug-state retention/log silence alarm. React StrictMode is not mounted; bindings manually simulate remount over mocked transport. No equivalent replacement coverage is claimed. The existing primary-selector receipt and its claims remain scoped to their unchanged sources; the broad optional command has no new execution result. Audit1400: src/main/ipc/ssh/ssh.test.ts reduced. Lose trivial missing target and mocked publication inventory. Preexisting unresolved ../ssh/ssh-port-scanner mock is recorded, not fixed. src/renderer/src/runtime/sync-runtime-graph-scheduling.test.ts removed. Removes whole coalescing call-count suite; no newest-state delivery or replacement claim. src/renderer/src/store/slices/terminal-pty-identity-replacement.test.ts reduced. Removes three no-op/work-count registrations; retains externally observed ownership consistency. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1412: src/main/ssh/ssh-provider-authority.test.ts removed. Loses real AbortController revocation/target isolation/reentrancy outcomes, recreated-target generation-floor/session rollover behavior, stale mutation refusal and settled-registration cleanup alarms. These useful alarms are deliberately lost; no equivalent cancellation coverage is claimed. No equivalent replacement coverage is claimed. Existing exact unaffected receipts remain unchanged and apply only to their unchanged selectors. Changed optional selectors have no new execution result. Audit1743 removes the standalone line-height clamp/default and pane cwd fallback helper tests (5 authored cases). These trivial-helper alarms are intentionally lost, with no equivalent replacement. Only current commands/testFiles lose the deleted selectors; historical receipts and evidenceRuns remain unchanged and do not validate the reduced commands. Audit5043 intentionally deletes the entire remote-runtime-client-error-classification suite (3 authored/9 finite cases): structured-code precedence over contradictory legacy text and7 unstructured-message compatibility alarms are lost. Whole retired-request-ID helper suite (3 cases) also removed outside this selector, losing direct TTL/non-refresh, eviction refresh and backward-clock expiry alarms. No equivalent replacement is claimed. Other selectors and dated evidence retain their original scope; no fresh execution, native/provider/mobile/mixed-version/cross-platform or full-gate result is claimed.", "motivatingLinks": [ "https://linear.app/stably/issue/STA-3107", "https://github.com/stablyai/orca/pull/12664", @@ -9140,11 +9138,10 @@ "https://github.com/stablyai/orca/issues/12902" ], "invariant": "SSH, WSL, and remote-runtime restore paths must treat provider listing failures and unknown liveness as unknown, not dead, while still avoiding duplicate spawn and clearing expired relay leases exactly once. Direct SSH disconnect, reconnect, and wake must keep PTY bindings and relay identity, and target snapshot hydration/reconnect cannot reset sibling SSH, local, WSL, or runtime-owned state. Every restored remote terminal must preserve its provider PTY identity, including the authoritative incarnation returned by a successful session-ID reattach. After a recoverable partition the same authenticated runtime must reattach the same PTY, reject detached input, apply the latest viewport, and report healthy only after authoritative replay. A successful one-shot reachability probe may replace a pre-ready shared-control socket, but waiting RPCs must continue onto the replacement under their original deadline without duplicate host delivery or retained request bytes. Automatic PTY recovery stops after one bounded minute without a fatal terminal error; a manual reconnect starts a newly fenced epoch against the same PTY, and closed panes retain no recovery UI state. Successful current-transport recovery must clear every stale error surfaced for that pane without clearing or displaying a sibling pane's error; a later genuine failure must remain visible. Each transport retains at most eight suppressed messages, each pane retains at most eight distinct messages, and the rendered surface retains at most 24 lines and 4,000 characters. One capability-gated terminal-create mutation must produce at most one host PTY across an unknown response outcome, remain manually retryable after cutoff, and never let a stale completion replace a newer pane lifecycle. Reconnect must alternate exact activation with authoritative inventory so neither a stale activation response nor an activation failure can strand or retire a pane, and activating a parked surface whose persisted binding was already retired must respawn it rather than report a changed owner after signalling its exit.", - "oracle": "Audit5658 integrates source audit5652: retire the whole remote-runtime-pty-recovery-state.test.ts suite and its exact active selectors and assertionRef. Intentionally lose reentrant retry single dispatch; shared owner-refresh caller settlement and per-epoch allowance; deadline registry revival; parked same-epoch retry; actual deadline versus UI disconnected latch alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3368 narrows stream-reconnect coverage to the actual ten synthetic transport epochs retaining one PTY identity, accepting and holding detached input for exactly-once later delivery, current decoded output and per-epoch subscription release. Prior rejection wording was inaccurate. Phase/backoff/cutoff/manual reconnect and parser/OSC/pause/retained-image/fatal/latch/claim/early-close alarms are intentionally lost without equivalent replacement. The Linux multi-pane reconnect receipt remains verbatim with its original scope; no fresh live SSH/provider/PTY/UI/mobile/mixed-version/cross-platform evidence is claimed. Audit3359 retires whole host-surface-replacement and create-handoff suites, removing their compound unit command tokens, test-file entries and assertion references. Fake polling/deadline/subscription, supplied stale-handle ownership, close and replacement examples are intentionally lost without equivalent replacement. The unrelated Linux paired multi-pane reconnect receipt stays verbatim with its original scope. No fresh SSH/provider/network/PTY recovery, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit3342 retires the complete client create-outcome identity/options/recovery suite and the malformed-or-contradictory repo-owner response matrix. Client replay identity, options, no-downgrade, quiescence/budget/manual retry, authoritative probe-error and malformed-owner refusal alarms are intentionally lost without equivalent replacement. Remaining repo-owner late catalog and old-host re-adoption boundaries do not replace them. The unrelated Linux paired-reconnect receipt stays verbatim with its original scope. Surviving selectors are unexecuted here; no fresh SSH/provider/process-deduplication, mobile, mixed-version or cross-platform validation is claimed. Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: keeps a sidebar row for every still-live pane after a long sleep — Whole suite: 279 lines manually replay renderer ownership registry/status writes, snapshot patch/set, six-pane fixture inventory, and sidebar selectors/builders; expected pane IDs are production-computed. Does not run sleep/wake/transport or actual sidebar entry. Retires reconnect row-preservation assembly alarm.; still retires the regular TUI surface after an explicit terminal exit — Ordinary explicit-exit callback/map cleanup is repeated in the stale/new stream lifecycle case below. Retires separate regular-TUI baseline; keeper is not equivalent process/UI proof.; asks the HUB to recover an expired SSH pane and rebinds the host identity — Expired SSH owner error must ask the owning HUB to recover, then adopt fixed replacement handle, resubscribe and report rebind; actual transport dispatch and handle state prevent wrong-client recovery.; does not recover a pane whose relay reply was an identity mismatch — Identity mismatch means a different live PTY, so actual transport must surface refusal without recover/create, keeping original identity. Prevents destructive duplicate agent recovery.; fails closed when an older HUB cannot recover an expired SSH pane — Old HUB method_not_found is scripted mock refusal/error echo with no actual skewed host; repeats generic recovery failure propagation. Retires old-host recovery fallback refusal example.; names a held recovery's stopped WSL distro in readable copy, not the raw hold code — Pins exact WSL stopped-distro error prose after mock code; translation/copy assertion with no actual held recovery behavior. Retires readable-copy alarm.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces runtime-environment-ssh-state.test.ts, intentionally losing metadata membership-pruning/new-target-only-read and other-environment/local-bucket isolation alarms. Preserve generation/failed-full-refresh assertion and unknown-target authoritative-list reread; these narrower cases are not equivalent replacements. The unchanged active two-case Linux reconnect materialization/sidebar receipt and covered platform retain their exact scope and do not validate the reduced SSH state selector. Preserve unrelated SSH assertions, selectors and archived history. No fresh SSH discovery, provider/PTY/network, rendered, mobile, mixed-version, cross-platform or full-gate execution is claimed. Audit 3312 retires the ordinary six-pane distinct-live-handle reconnect/resubscription alarm from paired-reconnect-multi-pane-materialization.test.ts. The unchanged parked-pane activation/rematerialization case remains narrower and is not an equivalent replacement. The complete prior seven-contract macOS receipt is archived as historical evidence; it does not validate the reduced selector. No fresh socket, PTY, sleep/wake, provider, platform, mobile, mixed-version or rendered execution is claimed. Audit3096: remove the deleted reconnect-banner selector and its two UI aliases. The reduced recovery-state selector retains only the deadline cancelling pending backoff and explicit retry owning a new epoch alias; healthy-replacement stale-schedule and independent caller-cutoff cancellation aliases retire. Other retained state cases cover reentrant retry, owner settlement and same-epoch parked revival, without replacing those removed alarms. Prior admission-selector retirement, archived July 28 receipt, unrelated selectors/claims/receipts and old gaps remain unchanged; no fresh execution is claimed. Audit3086: retire the destroyed fresh-session fallback settlement/non-destructive reattach alias and its direct selector; retain the detach/attach selector and assertion unchanged. The retained admission cases cover adopt-before-data and explicitly buffered-death admission without a new spawn, without replacing fallback retirement. July 28 evidence was already archived by audit3077; no duplicate retirement or new execution is claimed. Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/ssh/connection/ssh-connection-manager.test.ts: tears a failed startup down quietly, so its error is not replaced by a disconnect; marks a dial that never reached the host, so setup reports SSH’s reason; removes the registration when bulk teardown fails; leaves a connection whose own reconnect is asking the user alone; clears the pool entry when the closed connection is still the registered one; still reuses a connection that is already up; dials a user's connection test. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Delete the terminal-create idempotency forwarding suite and its prospective selector. Preserve2 unrelated receipts without claiming the lost forwarding alarm was replaced. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the sole supplied public-SSH-state spread/sanitized-error projection and its provider-authority-pair alias. Also delete the complete tiny one-shot split-startup wrapper suite: callback-visible temporary field/reset, sequential payload and thrown-sentinel reset alarms disappear. No SSH provider epoch handoff, connection, process startup or actual terminal split was performed by either deleted suite. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Deterministic tests cover bounded stale-handle replacement, suspended heartbeat clocks, cold and established subscription failure, ten partition/recovery cycles, automatic-recovery cutoff, manual reconnect, and direct SSH binding retention. They assert SSH state changes leave PTY bindings in place, relay identity survives, and another target/local/WSL/runtime panes remain byte-identical through target snapshot hydration and reconnect. Both remount callbacks consume split-count activity suppression, intentional dispose emits no failure/timeout, and a same-attempt StrictMode remount still owns one timeout. Hydration clears an untrusted PTY hint without clearing its current pending owner, healthy current-authority bindings suppress correction, hydration finalizes once, and reconnect emits no paired close lifecycle. A provider-level session-ID reattach returns an incarnation, then a legacy exit without an incarnation must resolve to that returned identity rather than minting a fallback identity. The shared-control oracle withholds the first encrypted ready frame, starts one RPC, triggers the successful-probe refresh, then requires exactly two client connections, one host request, a successful response, zero pending calls, and zero retained request bytes. Tests also assert one unsubscribe per remote-runtime epoch, observable recovery phases, stable PTY identity, resumed snapshot/output/input, no healthy state before replay, no retry or input after cutoff, a new manual epoch against the same PTY, quiet recovery UI with an explicit Reconnect action, pane-close state cleanup, one stable create mutation id, old-runtime no-retry behavior, cross-process PTY adoption, and bounded in-flight coordination. A focused recovery oracle surfaces two distinct failures through one transport, completes authoritative replay, and requires both matching clear callbacks; pane-state tests require only the active pane's error to render, matching-pane recovery to preserve sibling and unrelated errors, dismissal to re-admit later failures, and distinct storms to retain only the newest eight messages within 24 lines and 4,000 characters. The retained store replacement assertion observes one atomic pane/tab subscriber publication; repeated rotations and snapshot-first pending-restart migration no longer have their direct store examples. Preload layout cleanup retires the mock SSH forwarding/type-census suite without replacement: preload wiring alarms are lost; shared authority-admission tests cover narrower behavior. Historical receipts retain their original scope.", + "oracle": "Audit5779 companion to audit5775: Retire the complete PTY detach/attach handoff suite. Handler-complete durable reattach detachment, buffered state/lifetime preservation and late spawn retain-versus-kill alarms are intentionally lost without replacement. Remove one standalone command, one testFiles entry and its direct obsolete-reattach assertionRef. Complete dated evidenceRuns are unchanged; none selects these retired suites and none validates narrowed selectors. All unrelated remaining assertions and selectors retain their original scope, without replacement certification. No fresh execution or current import reachability result is claimed. Complete prior account preserved verbatim below as historical: Audit5748 companion to audit5744 retires the whole queued-pane-startup.test.ts suite. Its remaining captured-primary split ownership, one-shot repeated-spawn consumption, replacement-before-spawn refusal and permanently spent skipped-consumer alarms are intentionally lost without equivalent replacement. Remove its standalone unit selector or narrow the compound selector and remove its testFiles entry. Existing assertionRefs/evidenceRuns keep only their original scope and are unchanged; no fresh execution, current import reachability, PTY/provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit5658 integrates source audit5652: retire the whole remote-runtime-pty-recovery-state.test.ts suite and its exact active selectors and assertionRef. Intentionally lose reentrant retry single dispatch; shared owner-refresh caller settlement and per-epoch allowance; deadline registry revival; parked same-epoch retry; actual deadline versus UI disconnected latch alarms without replacement. Remaining selectors retain only their own scope; no fresh execution, native/platform or remote evidence is claimed. Complete original selector fields are preserved in knownGaps. Historical prior account (preserved verbatim): Audit3390 composes root-adopted3382/independent3383 and3386/independent3387 and3388/independent3389: intentionally retires216 authored registrations/230 expanded cases in42 whole authored suites plus5 zero-case registration drivers, without equivalent replacement. Lost local alarms include fake PTY identity/routing/startup/replay/mode/title/mouse/IME/scroll matrices, broad startup identity and file-open wiring, mock mailbox title recovery, mobile row parity and whole-v-selective save parity. Retained24 registrations/26 expanded cases in22 suites preserve actual xterm Windows buffer/wrap/scroll, typed TOML scalar, real Promise cancellation/settlement, HTTP Codex scanner/projector semantics, durable recovery admission/newer-schema bytes, federation completion/ACK/SQLite atomicity and failed stale-run-write versus imported durable history. Additional retained clock-domain scheduling, durable freeze/ACK/checkpoint ordering, ABA dirty intent, SQL atomicity, folder-domain retier/last-note deletion, scrollback durable no-sync staging, PanelBridge subscriber lifetime and reserved-send publication preserve narrower concrete behaviors. Current finite owner drift assessed in bounded defining bodies; retained callback bytes unchanged. Historical notes and complete dated receipts keep their original exact scopes. No new execution, equivalent replacement, native focus/device/pixel, live remote or global mixed-version guarantee is claimed. Audit3368 narrows stream-reconnect coverage to the actual ten synthetic transport epochs retaining one PTY identity, accepting and holding detached input for exactly-once later delivery, current decoded output and per-epoch subscription release. Prior rejection wording was inaccurate. Phase/backoff/cutoff/manual reconnect and parser/OSC/pause/retained-image/fatal/latch/claim/early-close alarms are intentionally lost without equivalent replacement. The Linux multi-pane reconnect receipt remains verbatim with its original scope; no fresh live SSH/provider/PTY/UI/mobile/mixed-version/cross-platform evidence is claimed. Audit3359 retires whole host-surface-replacement and create-handoff suites, removing their compound unit command tokens, test-file entries and assertion references. Fake polling/deadline/subscription, supplied stale-handle ownership, close and replacement examples are intentionally lost without equivalent replacement. The unrelated Linux paired multi-pane reconnect receipt stays verbatim with its original scope. No fresh SSH/provider/network/PTY recovery, historical-import, mobile, mixed-version or cross-platform validation is claimed. Audit3342 retires the complete client create-outcome identity/options/recovery suite and the malformed-or-contradictory repo-owner response matrix. Client replay identity, options, no-downgrade, quiescence/budget/manual retry, authoritative probe-error and malformed-owner refusal alarms are intentionally lost without equivalent replacement. Remaining repo-owner late catalog and old-host re-adoption boundaries do not replace them. The unrelated Linux paired-reconnect receipt stays verbatim with its original scope. Surviving selectors are unexecuted here; no fresh SSH/provider/process-deduplication, mobile, mixed-version or cross-platform validation is claimed. Audit3326 adopts reconciled source audit3324 and intentionally retires these low-value examples and their regression alarms: keeps a sidebar row for every still-live pane after a long sleep — Whole suite: 279 lines manually replay renderer ownership registry/status writes, snapshot patch/set, six-pane fixture inventory, and sidebar selectors/builders; expected pane IDs are production-computed. Does not run sleep/wake/transport or actual sidebar entry. Retires reconnect row-preservation assembly alarm.; still retires the regular TUI surface after an explicit terminal exit — Ordinary explicit-exit callback/map cleanup is repeated in the stale/new stream lifecycle case below. Retires separate regular-TUI baseline; keeper is not equivalent process/UI proof.; asks the HUB to recover an expired SSH pane and rebinds the host identity — Expired SSH owner error must ask the owning HUB to recover, then adopt fixed replacement handle, resubscribe and report rebind; actual transport dispatch and handle state prevent wrong-client recovery.; does not recover a pane whose relay reply was an identity mismatch — Identity mismatch means a different live PTY, so actual transport must surface refusal without recover/create, keeping original identity. Prevents destructive duplicate agent recovery.; fails closed when an older HUB cannot recover an expired SSH pane — Old HUB method_not_found is scripted mock refusal/error echo with no actual skewed host; repeats generic recovery failure propagation. Retires old-host recovery fallback refusal example.; names a held recovery's stopped WSL distro in readable copy, not the raw hold code — Pins exact WSL stopped-distro error prose after mock code; translation/copy assertion with no actual held recovery behavior. Retires readable-copy alarm.. Retained tests do not replace these alarms. Dated unrelated evidence remains scoped to its original execution; no historical source/import-closure equivalence, fresh execution, real network/provider/SSH, rendered UI, mobile, mixed-version or cross-platform validation is claimed. Audit 3318 reduces runtime-environment-ssh-state.test.ts, intentionally losing metadata membership-pruning/new-target-only-read and other-environment/local-bucket isolation alarms. Preserve generation/failed-full-refresh assertion and unknown-target authoritative-list reread; these narrower cases are not equivalent replacements. The unchanged active two-case Linux reconnect materialization/sidebar receipt and covered platform retain their exact scope and do not validate the reduced SSH state selector. Preserve unrelated SSH assertions, selectors and archived history. No fresh SSH discovery, provider/PTY/network, rendered, mobile, mixed-version, cross-platform or full-gate execution is claimed. Audit 3312 retires the ordinary six-pane distinct-live-handle reconnect/resubscription alarm from paired-reconnect-multi-pane-materialization.test.ts. The unchanged parked-pane activation/rematerialization case remains narrower and is not an equivalent replacement. The complete prior seven-contract macOS receipt is archived as historical evidence; it does not validate the reduced selector. No fresh socket, PTY, sleep/wake, provider, platform, mobile, mixed-version or rendered execution is claimed. Audit3096: remove the deleted reconnect-banner selector and its two UI aliases. The reduced recovery-state selector retains only the deadline cancelling pending backoff and explicit retry owning a new epoch alias; healthy-replacement stale-schedule and independent caller-cutoff cancellation aliases retire. Other retained state cases cover reentrant retry, owner settlement and same-epoch parked revival, without replacing those removed alarms. Prior admission-selector retirement, archived July 28 receipt, unrelated selectors/claims/receipts and old gaps remain unchanged; no fresh execution is claimed. Audit3086: retire the destroyed fresh-session fallback settlement/non-destructive reattach alias and its direct selector; retain the detach/attach selector and assertion unchanged. The retained admission cases cover adopt-before-data and explicitly buffered-death admission without a new spawn, without replacing fallback retirement. July 28 evidence was already archived by audit3077; no duplicate retirement or new execution is claimed. Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Historical prior account (preserved verbatim): Audit2076 (sources2073/2074): Intentionally retire these low-value alarms without replacement: src/main/ssh/connection/ssh-connection-manager.test.ts: tears a failed startup down quietly, so its error is not replaced by a disconnect; marks a dial that never reached the host, so setup reports SSH’s reason; removes the registration when bulk teardown fails; leaves a connection whose own reconnect is asking the user alone; clears the pool entry when the closed connection is still the registered one; still reuses a connection that is already up; dials a user's connection test. Existing unrelated evidenceRuns retain their original scope; unchanged dated receipt objects do not validate changed source bytes or reduced selectors. No fresh gate execution or historical import-closure equivalence is claimed. Frozen current literal-import graph reaches these changed test bytes; unresolved local and computed edges remain debt, and current reachability is not historical execution or equivalent replacement evidence. Historical prior account (preserved verbatim): Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1983: Delete the terminal-create idempotency forwarding suite and its prospective selector. Preserve2 unrelated receipts without claiming the lost forwarding alarm was replaced. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the sole supplied public-SSH-state spread/sanitized-error projection and its provider-authority-pair alias. Also delete the complete tiny one-shot split-startup wrapper suite: callback-visible temporary field/reset, sequential payload and thrown-sentinel reset alarms disappear. No SSH provider epoch handoff, connection, process startup or actual terminal split was performed by either deleted suite. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): Deterministic tests cover bounded stale-handle replacement, suspended heartbeat clocks, cold and established subscription failure, ten partition/recovery cycles, automatic-recovery cutoff, manual reconnect, and direct SSH binding retention. They assert SSH state changes leave PTY bindings in place, relay identity survives, and another target/local/WSL/runtime panes remain byte-identical through target snapshot hydration and reconnect. Both remount callbacks consume split-count activity suppression, intentional dispose emits no failure/timeout, and a same-attempt StrictMode remount still owns one timeout. Hydration clears an untrusted PTY hint without clearing its current pending owner, healthy current-authority bindings suppress correction, hydration finalizes once, and reconnect emits no paired close lifecycle. A provider-level session-ID reattach returns an incarnation, then a legacy exit without an incarnation must resolve to that returned identity rather than minting a fallback identity. The shared-control oracle withholds the first encrypted ready frame, starts one RPC, triggers the successful-probe refresh, then requires exactly two client connections, one host request, a successful response, zero pending calls, and zero retained request bytes. Tests also assert one unsubscribe per remote-runtime epoch, observable recovery phases, stable PTY identity, resumed snapshot/output/input, no healthy state before replay, no retry or input after cutoff, a new manual epoch against the same PTY, quiet recovery UI with an explicit Reconnect action, pane-close state cleanup, one stable create mutation id, old-runtime no-retry behavior, cross-process PTY adoption, and bounded in-flight coordination. A focused recovery oracle surfaces two distinct failures through one transport, completes authoritative replay, and requires both matching clear callbacks; pane-state tests require only the active pane's error to render, matching-pane recovery to preserve sibling and unrelated errors, dismissal to re-admit later failures, and distinct storms to retain only the newest eight messages within 24 lines and 4,000 characters. The retained store replacement assertion observes one atomic pane/tab subscriber publication; repeated rotations and snapshot-first pending-restart migration no longer have their direct store examples. Preload layout cleanup retires the mock SSH forwarding/type-census suite without replacement: preload wiring alarms are lost; shared authority-admission tests cover narrower behavior. Historical receipts retain their original scope.", "commands": [ "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts --reporter=dot", - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts", - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts --reporter=dot", "pnpm exec vitest run --config config/vitest.config.ts src/main/ssh/connection/ssh-connection-manager.test.ts src/main/ssh/connection/ssh-connection.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts --reporter=dot", @@ -9155,8 +9152,6 @@ "testFiles": [ "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts", "src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts", - "src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts", - "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts", "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts", "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts", "src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts", @@ -9233,12 +9228,6 @@ "held replies from an old generation cannot replace a newer generation; failed full refresh preserves live state behind queued metadata", "an unknown target triggers an authoritative list reread" ] - }, - { - "file": "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts", - "assertions": [ - "abandoning an obsolete reattach drops its data, replay, write-unavailable, and exit handlers without killing the durable PTY" - ] } ], "evidenceRuns": [ @@ -9361,7 +9350,12 @@ "Audit5658 exact original complete commands: [\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts --reporter=dot\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/recovery/remote-runtime-pty-recovery-state.test.ts src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts --reporter=dot\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/ssh/ssh.test.ts src/main/ssh/connection/ssh-connection-manager.test.ts src/main/ssh/connection/ssh-connection.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts src/shared/ssh-retained-payload-admission.test.ts --reporter=dot\",\"pnpm exec electron-vite build --mode e2e\",\"pnpm run build:web-from-renderer\",\"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"]", "Audit5658 exact original complete testFiles: [\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\"src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts\",\"src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/recovery/remote-runtime-pty-recovery-state.test.ts\",\"src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\"src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts\",\"src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts\",\"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts\",\"src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts\",\"src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts\",\"src/main/ipc/ssh/ssh.test.ts\",\"src/main/ssh/connection/ssh-connection-manager.test.ts\",\"src/main/ssh/connection/ssh-connection.test.ts\",\"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\"src/shared/ssh-retained-payload-admission.test.ts\"]", "Audit5658 exact original complete assertionRefs: [{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\"assertions\":[\"a pane parked while the client slept is authoritatively activated and rematerialized without leaving any pane handle null\"]},{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\"assertions\":[\"ten synthetic partition cycles retain one PTY identity, deliver each held detached input exactly once and release each epoch subscription exactly once; decoded live input/output remains current\"]},{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/recovery/remote-runtime-pty-recovery-state.test.ts\",\"assertions\":[\"the automatic-recovery deadline cancels pending backoff and a manual retry owns a new epoch\"]},{\"file\":\"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\"assertions\":[\"a suspended client receives a fresh probe deadline after resume and post-resume activity clears it\"]},{\"file\":\"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"assertions\":[\"one authenticated client/worktree mutation derives a stable server-owned terminal handle\",\"an unknown-outcome retry adopts the same provider PTY after runtime-process restart without rerunning startup\",\"retry inventory failure, missing same-worktree identity metadata, or ownership mismatch fails closed without spawning\",\"in-flight mutation coordination is bounded and releases capacity after settlement\"]},{\"file\":\"src/main/ssh/connection/ssh-connection-manager.test.ts\",\"assertions\":[\"disconnect invalidates a pending transport attempt immediately so late rejection or resolution cannot remove the replacement\"]},{\"file\":\"src/main/ssh/connection/ssh-connection.test.ts\",\"assertions\":[\"late ssh2 ready and startup error events after disconnect cannot resurrect or overwrite disconnected state\"]},{\"file\":\"src/shared/ssh-retained-payload-admission.test.ts\",\"assertions\":[\"retained connection states reject partial or malformed authority\",\"only partial compatibility authority can normalize to unknown for bounded direct-SSH reconciliation\",\"shared direct SSH authority admission requires bounded identifiers and a non-negative safe generation\"]},{\"file\":\"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\"assertions\":[\"partial runtime authority is rejected through the captured subscription callback before environment state receives it\"]},{\"file\":\"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\"assertions\":[\"held replies from an old generation cannot replace a newer generation; failed full refresh preserves live state behind queued metadata\",\"an unknown target triggers an authoritative list reread\"]},{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"assertions\":[\"abandoning an obsolete reattach drops its data, replay, write-unavailable, and exit handlers without killing the durable PTY\"]}]", - "Audit5736 exact original active selector fields before whole IPC suite removal (historical, not current coverage): {\"commands\":[\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts --reporter=dot\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts --reporter=dot\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/ssh/ssh.test.ts src/main/ssh/connection/ssh-connection-manager.test.ts src/main/ssh/connection/ssh-connection.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts --reporter=dot\",\"pnpm exec electron-vite build --mode e2e\",\"pnpm run build:web-from-renderer\",\"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"],\"testFiles\":[\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\"src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts\",\"src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts\",\"src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\"src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts\",\"src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts\",\"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts\",\"src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts\",\"src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts\",\"src/main/ipc/ssh/ssh.test.ts\",\"src/main/ssh/connection/ssh-connection-manager.test.ts\",\"src/main/ssh/connection/ssh-connection.test.ts\",\"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\"src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts\"],\"assertionRefs\":[{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\"assertions\":[\"a pane parked while the client slept is authoritatively activated and rematerialized without leaving any pane handle null\"]},{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\"assertions\":[\"ten synthetic partition cycles retain one PTY identity, deliver each held detached input exactly once and release each epoch subscription exactly once; decoded live input/output remains current\"]},{\"file\":\"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\"assertions\":[\"a suspended client receives a fresh probe deadline after resume and post-resume activity clears it\"]},{\"file\":\"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"assertions\":[\"one authenticated client/worktree mutation derives a stable server-owned terminal handle\",\"an unknown-outcome retry adopts the same provider PTY after runtime-process restart without rerunning startup\",\"retry inventory failure, missing same-worktree identity metadata, or ownership mismatch fails closed without spawning\",\"in-flight mutation coordination is bounded and releases capacity after settlement\"]},{\"file\":\"src/main/ssh/connection/ssh-connection-manager.test.ts\",\"assertions\":[\"disconnect invalidates a pending transport attempt immediately so late rejection or resolution cannot remove the replacement\"]},{\"file\":\"src/main/ssh/connection/ssh-connection.test.ts\",\"assertions\":[\"late ssh2 ready and startup error events after disconnect cannot resurrect or overwrite disconnected state\"]},{\"file\":\"src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts\",\"assertions\":[\"retained connection states reject partial or malformed authority\",\"only partial compatibility authority can normalize to unknown for bounded direct-SSH reconciliation\",\"shared direct SSH authority admission requires bounded identifiers and a non-negative safe generation\"]},{\"file\":\"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\"assertions\":[\"partial runtime authority is rejected through the captured subscription callback before environment state receives it\"]},{\"file\":\"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\"assertions\":[\"held replies from an old generation cannot replace a newer generation; failed full refresh preserves live state behind queued metadata\",\"an unknown target triggers an authoritative list reread\"]},{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"assertions\":[\"abandoning an obsolete reattach drops its data, replay, write-unavailable, and exit handlers without killing the durable PTY\"]}]}" + "Audit5736 exact original active selector fields before whole IPC suite removal (historical, not current coverage): {\"commands\":[\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts --reporter=dot\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts --reporter=dot\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/ssh/ssh.test.ts src/main/ssh/connection/ssh-connection-manager.test.ts src/main/ssh/connection/ssh-connection.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts --reporter=dot\",\"pnpm exec electron-vite build --mode e2e\",\"pnpm run build:web-from-renderer\",\"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"],\"testFiles\":[\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\"src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts\",\"src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts\",\"src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\"src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts\",\"src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts\",\"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts\",\"src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts\",\"src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts\",\"src/main/ipc/ssh/ssh.test.ts\",\"src/main/ssh/connection/ssh-connection-manager.test.ts\",\"src/main/ssh/connection/ssh-connection.test.ts\",\"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\"src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts\"],\"assertionRefs\":[{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\"assertions\":[\"a pane parked while the client slept is authoritatively activated and rematerialized without leaving any pane handle null\"]},{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\"assertions\":[\"ten synthetic partition cycles retain one PTY identity, deliver each held detached input exactly once and release each epoch subscription exactly once; decoded live input/output remains current\"]},{\"file\":\"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\"assertions\":[\"a suspended client receives a fresh probe deadline after resume and post-resume activity clears it\"]},{\"file\":\"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\"assertions\":[\"one authenticated client/worktree mutation derives a stable server-owned terminal handle\",\"an unknown-outcome retry adopts the same provider PTY after runtime-process restart without rerunning startup\",\"retry inventory failure, missing same-worktree identity metadata, or ownership mismatch fails closed without spawning\",\"in-flight mutation coordination is bounded and releases capacity after settlement\"]},{\"file\":\"src/main/ssh/connection/ssh-connection-manager.test.ts\",\"assertions\":[\"disconnect invalidates a pending transport attempt immediately so late rejection or resolution cannot remove the replacement\"]},{\"file\":\"src/main/ssh/connection/ssh-connection.test.ts\",\"assertions\":[\"late ssh2 ready and startup error events after disconnect cannot resurrect or overwrite disconnected state\"]},{\"file\":\"src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts\",\"assertions\":[\"retained connection states reject partial or malformed authority\",\"only partial compatibility authority can normalize to unknown for bounded direct-SSH reconciliation\",\"shared direct SSH authority admission requires bounded identifiers and a non-negative safe generation\"]},{\"file\":\"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\"assertions\":[\"partial runtime authority is rejected through the captured subscription callback before environment state receives it\"]},{\"file\":\"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\"assertions\":[\"held replies from an old generation cannot replace a newer generation; failed full refresh preserves live state behind queued metadata\",\"an unknown target triggers an authoritative list reread\"]},{\"file\":\"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\"assertions\":[\"abandoning an obsolete reattach drops its data, replay, write-unavailable, and exit handlers without killing the durable PTY\"]}]}", + "Audit5748 exact original complete commands JSON value, preserved verbatim as historical selector metadata; removed/narrowed selector is not validated by old evidence:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts --reporter=dot\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts --reporter=dot\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/ssh/ssh.test.ts src/main/ssh/connection/ssh-connection-manager.test.ts src/main/ssh/connection/ssh-connection.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts --reporter=dot\",\n \"pnpm exec electron-vite build --mode e2e\",\n \"pnpm run build:web-from-renderer\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"\n ]", + "Audit5748 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; removed/narrowed selector is not validated by old evidence:\n[\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\n \"src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts\",\n \"src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts\",\n \"src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\n \"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\n \"src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts\",\n \"src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts\",\n \"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\n \"tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts\",\n \"src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts\",\n \"src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts\",\n \"src/main/ipc/ssh/ssh.test.ts\",\n \"src/main/ssh/connection/ssh-connection-manager.test.ts\",\n \"src/main/ssh/connection/ssh-connection.test.ts\",\n \"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\n \"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\n \"src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts\"\n ]", + "Audit5779 exact original complete commands JSON value, preserved verbatim as historical selector metadata; changed selectors have no new validation:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts --reporter=dot\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts --reporter=dot\",\n \"pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/ssh/ssh.test.ts src/main/ssh/connection/ssh-connection-manager.test.ts src/main/ssh/connection/ssh-connection.test.ts src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts --reporter=dot\",\n \"pnpm exec electron-vite build --mode e2e\",\n \"pnpm run build:web-from-renderer\",\n \"SKIP_BUILD=1 pnpm exec playwright test tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"\n ]", + "Audit5779 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; changed selectors have no new validation:\n[\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\n \"src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts\",\n \"src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\n \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts\",\n \"src/renderer/src/store/terminals/pty/terminal-pty-identity-replacement.test.ts\",\n \"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\n \"src/shared/remote-runtime/control/remote-runtime-shared-control-connection.test.ts\",\n \"src/shared/remote-runtime/control/remote-runtime-shared-control-socket-generation.test.ts\",\n \"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\n \"tests/e2e/paired-remote-terminal-materialization-reconnect.spec.ts\",\n \"src/renderer/src/store/slices/ui/workspace-navigation-history-hydration.test.ts\",\n \"src/renderer/src/store/repos/repos-ssh-host-reconciliation.test.ts\",\n \"src/main/ipc/ssh/ssh.test.ts\",\n \"src/main/ssh/connection/ssh-connection-manager.test.ts\",\n \"src/main/ssh/connection/ssh-connection.test.ts\",\n \"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\n \"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\n \"src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts\"\n ]", + "Audit5779 exact original complete assertionRefs JSON value, preserved verbatim as historical selector metadata; changed selectors have no new validation:\n[\n {\n \"file\": \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts\",\n \"assertions\": [\n \"a pane parked while the client slept is authoritatively activated and rematerialized without leaving any pane handle null\"\n ]\n },\n {\n \"file\": \"src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts\",\n \"assertions\": [\n \"ten synthetic partition cycles retain one PTY identity, deliver each held detached input exactly once and release each epoch subscription exactly once; decoded live input/output remains current\"\n ]\n },\n {\n \"file\": \"src/shared/remote-runtime/remote-runtime-socket-liveness.test.ts\",\n \"assertions\": [\n \"a suspended client receives a fresh probe deadline after resume and post-resume activity clears it\"\n ]\n },\n {\n \"file\": \"src/main/runtime/terminal/launch/orca-runtime-terminal-create-idempotency.test.ts\",\n \"assertions\": [\n \"one authenticated client/worktree mutation derives a stable server-owned terminal handle\",\n \"an unknown-outcome retry adopts the same provider PTY after runtime-process restart without rerunning startup\",\n \"retry inventory failure, missing same-worktree identity metadata, or ownership mismatch fails closed without spawning\",\n \"in-flight mutation coordination is bounded and releases capacity after settlement\"\n ]\n },\n {\n \"file\": \"src/main/ssh/connection/ssh-connection-manager.test.ts\",\n \"assertions\": [\n \"disconnect invalidates a pending transport attempt immediately so late rejection or resolution cannot remove the replacement\"\n ]\n },\n {\n \"file\": \"src/main/ssh/connection/ssh-connection.test.ts\",\n \"assertions\": [\n \"late ssh2 ready and startup error events after disconnect cannot resurrect or overwrite disconnected state\"\n ]\n },\n {\n \"file\": \"src/shared/remote-runtime/ssh/ssh-retained-payload-admission.test.ts\",\n \"assertions\": [\n \"retained connection states reject partial or malformed authority\",\n \"only partial compatibility authority can normalize to unknown for bounded direct-SSH reconciliation\",\n \"shared direct SSH authority admission requires bounded identifiers and a non-negative safe generation\"\n ]\n },\n {\n \"file\": \"src/renderer/src/runtime/rpc/subscriptions/runtime-client-events.test.ts\",\n \"assertions\": [\n \"partial runtime authority is rejected through the captured subscription callback before environment state receives it\"\n ]\n },\n {\n \"file\": \"src/renderer/src/runtime/hosts/ssh/runtime-environment-ssh-state.test.ts\",\n \"assertions\": [\n \"held replies from an old generation cannot replace a newer generation; failed full refresh preserves live state behind queued metadata\",\n \"an unknown target triggers an authoritative list reread\"\n ]\n },\n {\n \"file\": \"src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts\",\n \"assertions\": [\n \"abandoning an obsolete reattach drops its data, replay, write-unavailable, and exit handlers without killing the durable PTY\"\n ]\n }\n ]" ], "demotionRule": "Cannot promote if provider failure can close panes or if the oracle is screenshot-only." }, @@ -10050,7 +10044,7 @@ "providers": ["local", "daemon", "ssh", "remote-runtime"], "coveredPlatforms": ["macos"], "coveredProviders": [], - "coverageNotes": "Audit4362 intentionally deletes the imported stale-waiter retry and manually assembled OSC9999 mobile-republish cases, plus the mocked missing-worktree cleanup suite (4 authored / 5 finite cases in three suites). Lost alarms include repeated unread worker_done pointers, working-to-waiting mobile status publication, missing-worktree filtering, and scoped daemon shutdown with unrelated duplicate identities. No replacement coverage or new platform proof is claimed. Audit3994 retires two authored callbacks imported by the shared construction test driver: split OSC 9999 carry and rendererless status ownership, plus OpenCode permission text taking priority in status and tui-idle refusal. Remaining imports and selectors keep their scope. No equivalent replacement or fresh gate execution is claimed. Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Audit2095 current-parent preparation2126: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Audit2090 (sources2088/2089): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. NEXT136 retains only unchanged execution receipts at their original scopes. Reduced-source selectors and retained static assertions have no new execution or equivalent replacement credit.", + "coverageNotes": "Audit5743 removes whole identity-scanner/browser retirement/RPC dispatch test suites from active selectors, accepting incremental OSC identity framing, in-memory page retirement generation fencing and spied-runtime SQL dispatch authority/rollback alarms without equivalent replacement or fresh execution. Remaining dated evidence keeps its exact independent selector scope. Historical prior account (preserved verbatim): Audit4362 intentionally deletes the imported stale-waiter retry and manually assembled OSC9999 mobile-republish cases, plus the mocked missing-worktree cleanup suite (4 authored / 5 finite cases in three suites). Lost alarms include repeated unread worker_done pointers, working-to-waiting mobile status publication, missing-worktree filtering, and scoped daemon shutdown with unrelated duplicate identities. No replacement coverage or new platform proof is claimed. Audit3994 retires two authored callbacks imported by the shared construction test driver: split OSC 9999 carry and rendererless status ownership, plus OpenCode permission text taking priority in status and tui-idle refusal. Remaining imports and selectors keep their scope. No equivalent replacement or fresh gate execution is claimed. Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Audit2095 current-parent preparation2126: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Audit2090 (sources2088/2089): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. NEXT136 retains only unchanged execution receipts at their original scopes. Reduced-source selectors and retained static assertions have no new execution or equivalent replacement credit.", "motivatingLinks": [ "https://linear.app/stably/issue/STA-3800", "https://linear.app/stably/issue/STA-3904", @@ -10062,14 +10056,13 @@ "invariant": "Injected orchestration task prompts for recognized agent CLIs must send the prompt body inside one bracketed-paste frame, sanitize embedded ESC bytes, preserve chunk boundaries without losing the frame, and submit exactly once only after the agent can accept Enter. Local worker-start with supported observation must preserve an unobserved turn as start_unknown without revoking authority, closing questions, or triggering a rescue Enter; a worker report during observation must settle normally. Claude and Codex must emit a post-paste composer marker and then settle, or reach the bounded fallback first; every other agent retains the platform delay.", "oracle": "Audit4362 intentionally deletes the imported stale-waiter retry and manually assembled OSC9999 mobile-republish cases, plus the mocked missing-worktree cleanup suite (4 authored / 5 finite cases in three suites). Lost alarms include repeated unread worker_done pointers, working-to-waiting mobile status publication, missing-worktree filtering, and scoped daemon shutdown with unrelated duplicate identities. No replacement coverage or new platform proof is claimed. Audit3832 deliberately retires76 authored/79 finite cases:75 runtime compatibility cases/78 finite cases across14 fragments, plus one localization extractor default-flag case. Three whole runtime fragments are deleted;27 authored/30 finite cases remain across the reviewed sources. This gate retains only its own selected scope; no equivalent replacement or fresh runtime/native/remote evidence is claimed. Runtime component A: Audit3828 composes3822 with independent3824: deliberately retires49 authored/52 finite cases from seven compatibility fragments, leaving15 authored/18 finite cases and deleting two entire fragments. Accepted losses: positive folder-worker recovery/materialization and reveal deadline; persisted-key normalization and legacy split/group/focus projection; fixed stale CAS refusal; occupied/alias/restored/preallocated terminal-handle variants; fixed OpenCode/Cursor/Claude/Codex/Antigravity classification, readiness, title and management examples; direct private-map browser authority projections; browser-focus and OMP title projection; already-aborted claim cleanup. Additional3824 loss: src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts :: does not poll a wrapper foreground for a speculative CLI prompt send :: Speculative retryForegroundWrappers:false check must return false on a wrapper after one foreground read, without polling the supplied later codex response. These real bounded alarms are deliberately retired for low marginal value. Retained callbacks are unchanged and provide only their own bounded scope, not equivalent replacement. Historical receipts do not validate reduced callbacks. No fresh runtime/native/SSH/WSL/phone/browser evidence or full transitive closure is claimed. Runtime component B: Audit3834 deliberately retires26 authored/26 finite cases from seven fresh compatibility fragments, leaving10/10 and deleting the one-case saved-binding reattachment fragment. Original position58 is excluded: its existing substantive3578 KEEP7 review remains historical, with no fresh credit. Accepted losses: fixed hook/provider-session identities and stale metadata refusal; decorative/pre-title foreground ordering variants; saved-binding surface reattachment; saved-row exit ghost removal and silent activation selection; unsupported headless wake; positive pending materialization/group projections; per-caller navigation selection; positive SSH hydration/read partition; laptop mobile publication/buffer and background/pending/status projections; abnormal/unregistered SSH grace, normal-exit refusal, persisted SSH hydration, positive serve reattachment, pending-agent launch arguments and direct seeded running-launch admission guard. These are real bounded alarms deliberately retired for low marginal value. Retained cases preserve their own distinct deferred foreground coalescing, usable handle continuity, stale inventory refresh, concurrent browser snapshot preservation, renderer graph fencing, caller dedup isolation, SSH partition writes, runtime split lifetime, independent relay-ready publication, lease admission/state/expiry. The direct running-launch no-spawn guard alarm is deliberately retired; no remaining owning-launch refusal coverage is claimed. Historical runs do not validate reduced callbacks. No equivalent replacement, runtime/native/SSH/WSL/phone/browser result or full transitive closure is claimed. Additional extractor loss: config/scripts/localization/source-extraction/audit-localization-native-dialogs.test.mjs :: does not change the existing renderer scan by default :: Default options must omit the five native-only fields in this supplied snippet. No equivalent replacement is claimed. Historical prior account (preserved verbatim): Audit3814 deliberately retires60 authored/60 finite cases:53runtime compatibility cases,4native XCTest methods and3Python clipboard methods, including the entire StableElementIndexes suite. Clipboard cuts retire the one-over-cap sample, incoming-offer destruction trace and sequential20-copy replay; actual wire, FD/pipe, startup and Xvfb/GTK boundaries remain without equivalent replacement claims. Accepted losses include narrow terminal-send payload/provider projections, legacy and direct no-op/error permutations, timing/work-count examples, private state/title/activity projections and fixture-driven readiness examples, individually enumerated below. These include real bounded production alarms consciously retired for marginal value; retained failed writes, duplicate submission, stale capture, transcript/ring and allocation fences are not equivalent replacements. No fresh native/remote/browser execution or complete transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3806 deliberately retires40 authored/40 finite runtime compatibility cases, including the terminal-side-effect-facts-part03 headless-snapshots-part02 and agent-status-and-waits-part03 fragments, plus20 scalar Swift precondition sites. Lost runtime alarms include status/title/attention projection examples, simple renderer/headless frame restoration and status waiting outcomes detailed in the accepted-loss ledger. Swift cuts retire duplicate generation-map/schema/navigation/bridge and notification-wrapper assertions; no standalone native program is deleted. These include real bounded production alarms consciously retired for marginal value. Retained races, pending writes/reflow, namespace and waiter ownership are not equivalent replacements. No fresh native/remote/browser execution or full transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3798 deliberately retires21 authored/24 finite compatibility cases, including the entire SSH-worktree-lifecycle and repository-project-operations fragments. Accepted losses include navigation-only settings acknowledgement, browser session cleanup and host preservation projections, window positive/policy-state examples, terminal recovery/reload and no-incarnation remint examples, terminal listing compatibility/malformed IDs, directory browse/sort/Windows path smoke, SSH create refusal/manual lineage, recursive parent-folder creation and fork/origin/avatar/icon projections. Real bounded production alarms are consciously retired for marginal value; retained authority races, cleanup/clone ownership, pending waiters, nested-folder and scan invalidation cases are not equivalent replacements. No fresh native/remote/browser execution or full transitive closure is claimed. Earlier dated receipts and raw selectors remain historical accounts of prior callback sets. Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Audit2133 current-parent preparation: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Audit2095 current-parent preparation2126: Current reduced sources/selectors intentionally retire the alarms listed in knownGaps; prior dated runs and replacement claims do not validate the changed set. Audit2090 (sources2088/2089): Current reduced suites intentionally retire the alarms listed in knownGaps; prior dated execution and replacement claims do not validate changed source bytes or selectors. Retained assertion references and unchanged receipts keep their original scopes; retired callbacks and archived receipts provide no current coverage.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/shared/agent-launch/startup/agent-prompt-injection.test.ts src/main/runtime/construction/orca-runtime.test.ts src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts src/main/runtime/orchestration/coordinator/coordinator.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/shared/agent-launch/startup/agent-prompt-injection.test.ts src/main/runtime/construction/orca-runtime.test.ts src/main/runtime/orchestration/coordinator/coordinator.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/methods/orchestration/worker/start/readiness/worker-start-prompt-contract.test.ts --reporter=dot", "node tests/tools/repro-orchestration-long-prompt.mjs --cli out/bin/orca-dev --mode codex-like --size-kb 32 --timeout-ms 20000" ], "testFiles": [ "src/shared/agent-launch/startup/agent-prompt-injection.test.ts", "src/main/runtime/construction/orca-runtime.test.ts", - "src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts", "src/main/runtime/rpc/methods/orchestration/worker/start/readiness/worker-start-prompt-contract.test.ts", "src/main/runtime/orchestration/coordinator/coordinator.test.ts", "tests/tools/repro-orchestration-long-prompt.mjs" @@ -10084,10 +10077,6 @@ "chunk reconstruction preserves the paste frame" ] }, - { - "file": "src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts", - "assertions": ["failed prompt injection rolls back the active dispatch"] - }, { "file": "src/main/runtime/orchestration/coordinator/coordinator.test.ts", "assertions": [ @@ -10168,7 +10157,8 @@ "Audit2133 current-parent preparation (988 authored removals; independently reviewed2099/2107/2115/2116 decisions; upstream clear-buffer and recovery-image regressions retained): Intentionally retire these low-value alarms without replacement: src/main/runtime/construction/orca-runtime.test.ts: remove only literal registration import/call pairs await import('../orca-runtime-tests/worktree-setup-and-startup.spec'), await import('../orca-runtime-tests/gitlab-and-pr-bases.spec'); no additional authored credit. src/main/runtime/orca-runtime-tests/targeting-and-resilience.spec.ts: routes tab switch and capture start by explicit page id; accepts focus on tab switch without altering bridge args (focus is main-side concern); keeps terminal cwd resolution fail-soft when the provider is unavailable. src/main/runtime/orca-runtime-tests/worktree-removal-and-reconciliation-part-04.spec.ts: drops the bounded scan cache when orphan-cleanup removal completes; clears optimistic reconcile tokens when a CLI worktree removal succeeds; emits drift without mutating when the fetched base fast-forwards created HEAD; emits base_changed without mutation when the fetched base rewrote history; skips stale-token reconciles without mutating or emitting stale status; emits unknown without mutation when fetch fails or the base ref is missing. src/main/runtime/orca-runtime-tests/worktree-removal-and-reconciliation-part-03.spec.ts: routes runtime preserved-branch force-delete through the selected WSL project runtime; replies to a waiting client with the error of a delete that fails after acceptance; treats forced runtime deletion of an already-missing unregistered worktree as cleanup; treats normal runtime deletion of an already-missing unregistered worktree as cleanup. src/main/runtime/orca-runtime-tests/worktree-removal-and-reconciliation-part-02.spec.ts: warns that a missing-repo removal only forgot the workspace; restores runtime watchers when CLI worktree deletion fails after teardown; does not re-spend the drain budget on a removal after a wedged install was abandoned; routes runtime worktree removal through the selected WSL project runtime; force-deletes a branch that was preserved by runtime worktree removal. src/main/runtime/orca-runtime-tests/gitlab-and-pr-bases-part-02.spec.ts: records GitLab pasted-project recents only after successful runtime lookup; threads explicit origin preference through runtime WSL PR base resolution; resolves local GitLab fork MR bases from the target project MR head ref; captures the fork MR head from a dedicated ref, not the shared FETCH_HEAD; keeps the durable MR head when the head fetch fails but the local ref resolves; routes runtime GitLab fork MR base git calls through the selected WSL project runtime. src/main/runtime/orca-runtime-tests/gitlab-and-pr-bases.spec.ts: passes SSH connection ids through GitLab task operations; routes runtime GitLab issue, MR, work-item, and todo actions through the selected WSL project runtime; routes runtime GitLab MR details, review-management, job, and pasted URL actions through the selected WSL project runtime; normalizes runtime GitLab issue list arguments like the desktop IPC path. src/main/runtime/orca-runtime-tests/worktree-setup-and-startup-part-03.spec.ts: does not warn when setup is explicitly skipped for CLI-created worktrees; puts the agent a create starts in the first default tab, as the window does; keeps the 8s main-runtime startup readiness budget for agents without an override; gives OpenCode the 20s main-runtime startup readiness budget; launches explicit startup agents with prompts for CLI-created worktrees. src/main/runtime/orca-runtime-tests/worktree-setup-and-startup.spec.ts: returns a setup launch payload for CLI-created worktrees when hooks are explicitly enabled; does not hand the window a setup main never tried to start; passes the selected Windows setup shell into runtime runner generation; follows normal setup policy for CLI-created worktrees without activating them; uses returned WSL setup shell metadata when runtime spawns setup; uses the shell-aware setup runner for windowless creates without a startup command; reports the in-process setup hook as running when nothing can launch the runner. src/main/runtime/orca-runtime-tests/terminal-sleep-and-teardown-part-02.spec.ts: coalesces two clients sleeping the same host worktree; stops exactly the expected live PTYs for a worktree; explains a refused workspace close instead of throwing the raw refusal enum. src/main/runtime/orca-runtime-tests/mobile-summaries-part-03.spec.ts: marks the desktop-active worktree as isActive; includes SSH-backed worktrees in the mobile worktree summary; caches repeated malformed path misses before normalizing them again. src/main/runtime/orca-runtime-tests/mobile-summaries-part-02.spec.ts: keeps title-only foreground work ahead of monitoring in another pane; keeps a local hook row while a connected PTY still backs its pane; keeps an OSC row via its connected PTY after the pane binding is cleared. src/main/runtime/orca-runtime-tests/mobile-summaries.spec.ts: resolves files through a source-visible linked-checkout worktree; marks saved session tabs with live PTYs as host sidebar activity; attributes live legacy PTYs from saved layout bindings when their panes are hidden; marks saved browser tabs as host sidebar activity like desktop; falls back to the path-keyed GitHub cache entry; includes folder workspaces in compact worktree summaries for mobile; attaches inline agent rows from the latest OSC 9999 status; projects monitoring over a title-derived working status. src/main/runtime/orca-runtime-tests/mobile-creation-and-orchestration-part-03.spec.ts: pushes to an idle pane when the only live waiter filters out the message type; resolves a registered waiter without PTY-injecting when the leaf is already idle; keeps already-idle status after tui-idle wait for immediate message delivery; resolves message waiters when notifyMessageArrived is called; does not resolve type-filtered message waiters for unrelated message types; removes message waiter abort listeners after message arrival; resolves message waiters on timeout when no message arrives. src/main/runtime/orca-runtime-tests/mobile-creation-and-orchestration-part-02.spec.ts: delivers pending mail via notifyMessageArrived when the recipient is already idle; does not keep retrying when every pending row was already pointed; repoints pending rows restored with a live-idle coordinator. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-13.spec.ts: rolls back a half-created terminal whose surface never publishes. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-12.spec.ts: rejects startup prompts for agents that require post-ready stdin; uses portable Unix quoting for mobile agent launch commands in WSL project runtimes; keeps PowerShell quoting for mobile agent launch commands in Windows host runtimes; uses cmd.exe quoting for mobile agent launch commands in local Windows host runtimes; publishes headless mobile session agent identity with synthesized PTY status; rejects disabled mobile session agent launches before spawning; validates mobile terminal insertion anchors before resolving agent launch commands. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-11.spec.ts: coalesces a reconnect close burst onto one authoritative PTY inventory; keeps an explicit user close destructive while the PTY is live; builds mobile session agent launch commands on the runtime host; injects mobile quick-command prompts into the host-built agent startup command. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-10.spec.ts: closes persisted headless terminal parents before any prior list call; tears down a serve-owned headless tab on close while a renderer is attached so it cannot resurrect; defers a renderer-published pending tab to the renderer instead of tearing it down; returns a delegated close outcome with no selection tombstone when the renderer owns the outcome; tears down a runtime pending shell the renderer never adopted on close. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-08.spec.ts: materializes a plain shell when the pending tab has no launch agent; hydrates legacy persisted terminal tabs without layout entries; reads and indexes the full agent-status snapshot once per mobile projection; kills persisted SSH PTYs when closing hydrated headless tabs before pane metadata is restored; materializes hydrated pending headless terminals with the persisted session identity. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-07.spec.ts: hydrates a persisted SSH-owned pane before an attached renderer publishes its graph. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-05.spec.ts: publishes the desktop's tab name over the live agent title, and the live title without one; uses fresh neutral PTY titles over stale mobile snapshot and OSC titles; operates PTY-backed mobile session terminals without a renderer graph; reuses pane close for live PTYs that do not own a renderer tab; lists PTY-backed mobile session terminals without a renderer graph; shows and resolves active PTY-backed mobile session terminals without a renderer graph. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-04.spec.ts: creates mobile session terminals for folder workspaces in a headless runtime server; spawns fresh headless SSH mobile session terminals instead of reattaching synthetic local ids; hydrates headless mobile session terminals from the host workspace session; keeps live headless mobile session terminals when a desktop renderer publishes without them; publishes laptop-created remote runtime split terminals to phone session tabs. src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-02.spec.ts: does not report headless wake degradation without sleeping records; does not wake slept agents for non-mobile session-only activation; does not rewrite unread metadata when a mobile activation finds the worktree already read; returns unread:false from worktree.ps after a mobile activation clears the flag; materializes pending mobile session terminals without focusing desktop clients; closes browser mobile session tabs when addressed by browser workspace id. src/main/runtime/orca-runtime-tests/mobile-session-tabs.spec.ts: resolves mobile terminal surfaces by exact split leaf; closes the matching mobile terminal UUID leaf without closing the whole tab; closes the whole mobile terminal tab when addressed by parent tab id; activates the active split leaf when addressed by parent tab id; clears unread metadata on mobile worktree activation without focusing desktop clients; wakes slept agents on the host renderer when a phone activates a worktree. src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-05.spec.ts: publishes the hook provider session on a headless mobile tab so native chat can address the transcript; recovers the agent type from the hook row when the pane was launched without an agent hint; reads one agent-status snapshot per projection, not one per terminal tab; waits for unknown-launch foreground owner before publishing Pi-compatible mobile status; keeps Pi-compatible mobile session status as Pi for an unknown-launch foreground pi PTY; keeps renderer-vetted mobile agent status for custom-titled terminals. src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-04.spec.ts: publishes terminal surface agent status for paired web clients; preserves authoritative OMP identity for Pi-compatible remote terminal snapshots; normalizes a remote OMP title without republishing omitted launch identity; skips the foreground-process probe when the PTY launch agent is already known; probes the foreground process only on a status transition for unknown launch agents; passes the client signal and the slept-worktree refusal to the spawn. src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-03.spec.ts: does not use stale runtime-created PTY status when a neutral PTY title exists; recognizes runtime-created Codex PTY handles from the ready prompt; recognizes runtime-created Antigravity PTY handles from the ready prompt; recognizes live leaf Antigravity terminals from the ready prompt; recognizes a later Antigravity header with a prompt but no model line; keeps mobile terminal surfaces visible while their leaf handle is pending. src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts: lets Claude agents management titles clear stale runtime-created title status; does not recognize live Claude agents panes from a Claude foreground process; does not let stale tab-level agent titles override current neutral pane titles; lists live terminals with fresh pane titles over stale tab titles; lets adopted neutral pane titles use non-shell foreground fallback; lets adopted neutral pane titles retry wrapper foregrounds until recognized; authorizes settled CLI prompts only after positive %s foreground identity; does not recognize arbitrary foreground TUIs as running agents; lets live neutral pane titles retry wrapper foregrounds until recognized; lets current Claude agents PTY titles override stale runtime-created OSC titles; does not let stale Claude agents OSC titles suppress current PTY title activity. src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status.spec.ts: keeps preallocated terminal handles valid across renderer reloads; preserves runtime-created PTY process identity after graph unavailable; keeps prompt bindings fenced across runtime restarts without provider incarnation; recognizes runtime-created PTY handles with agent launch titles; does not treat a bare Cursor Agent native title as a running agent session; uses stale runtime-created PTY status when there is no title or foreground evidence. src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-07.spec.ts: keeps orphaned list and show writability aligned with the send gate. src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-04.spec.ts: cancels a coalesced SSH worker recovery retry when its provider disconnects. src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-03.spec.ts: retries renderer reveal before clearing an adopted legacy worker sleeping record. src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-02.spec.ts: recovers exported ORCA_TERMINAL_HANDLE from discovered live PTY sessions. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-12.spec.ts: applies ANSI erase-from-start line controls in retained previews; applies ANSI stripping for private or intermediate CSI line controls; applies ANSI stripping for unsupported erase-line modes; reveals an agent terminal under the pane the caller reserved; keeps a fresh %s pane host-owned when a desktop window is available; keeps desktop publication %s separate from the reserved host spawn; mints its own pane when the reserved leaf is malformed, and reports the one it used; starts an agent terminal with the model the caller picked; starts an agent terminal without a model flag when no pick was made; attributes a startup-agent launch named %s as %s; attributes a fresh agent session the host builds as unknown; leaves a bare agent command the user typed out of launch attribution. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-11.spec.ts: trims oversized terminal output bursts without per-line array shifts; builds terminal previews without mapping the full retained tail; keeps recent PTY replay output capped without needing previous data for large chunks; applies terminal redraw controls before retaining previews; applies ANSI terminal redraw controls before retaining previews; retains multi-line ANSI footer redraws instead of appending old frames; keeps the cursor column when erasing full lines in multi-line redraws; applies ANSI split redraw controls without leaking raw params. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-10.spec.ts: returns renderer visible screen lines through terminal.read RPC JSON result; separates composer drafts from provider-owned terminal screens. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-09.spec.ts: reports an in-flight PTY focus as not navigated when its notifier disappears; reports graph-leaf focus as not navigated without a host notifier; grounds the provider mode tracker before a later chunk, in the emulator order; grounds an in-flight provider snapshot capture so it cannot publish the pre-reset screen; waits for terminal exit and resolves with the exit status; keeps terminal read payloads bounded while retained output remains pageable; trims terminal read preview character budget without per-line array shifts. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-08.spec.ts: submits a silent Claude composer once after the bounded render fallback; chunks large terminal.send text before provider writes; yields chunked terminal input through immediates between writes; yields while validating accepted large terminal.send text before provider writes; reveals a background terminal session when focusing its handle; replays captured launch config when focusing a background agent session; reveals background terminal sessions with the freshest PTY title; renames background terminal handles without requiring a visible tab; keeps a background terminal handle stable while reveal adoption is racing. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-07.spec.ts: resolves tui-idle when a stale Codex prompt is followed by Antigravity readiness; returns an agent-neutral blocked wait result for update prompts; returns an agent-neutral blocked wait result for workspace trust prompts; returns an agent-neutral blocked wait result for cwd selection prompts; returns a blocked wait result for Codex model migration prompts; returns a blocked wait result for Codex startup hook review prompts; returns an agent-neutral blocked wait result for generic interactive prompts; splits text and enter writes for background terminal handles; types the lead line for %s: %s; submits through the agent-specific PTY timing policy for %s. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-06.spec.ts: waits for exit on background terminal handles; keeps retained PTY transcript memory when controller refresh fails; resolves tui-idle from an Antigravity ready prompt preview; resolves Antigravity ready prompts with newline-heavy pasted tails without splitting; resolves live-leaf tui-idle from an Antigravity ready prompt preview. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-03.spec.ts: spawns the available Qoder command for a captured same-session resume: %s; does not use the local Windows shell setting for remote Windows bare agent creates; matches canonical bare agent commands when a command override is configured; keeps non-bare agent command terminal creates unchanged; keeps disabled bare agent command terminal creates unchanged; injects runtime hook receiver env into terminal sessions; creates background terminal sessions for a $label; creates background terminal sessions for a $label; enables Claude Agent Teams only for direct Claude launches when configured in-process; reveals Claude Agent Teams launches with the rewritten launch config; preserves Claude Agent Teams for sequenced Claude launches. src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness.spec.ts: creates visible terminal sessions without asking the renderer to focus a tab; asks the pty controller for the requested shell instead of a startup command; knows the agent a flagged launch command names before any process read; retires a flagged command pane identity when the command exits; retires only receipted restored PTY authority on command completion and exit; forgets synthetic handles when disconnected PTY records are pruned. src/main/runtime/orca-runtime-tests/headless-snapshots.spec.ts: returns OSC titles from headless main terminal snapshots; adopts renderer-seeded titles into headless main terminal snapshots; returns cwd metadata from seeded headless main terminal snapshots; adopts OSC7 host metadata from seeded headless terminal scrollback; falls back to the renderer snapshot for hidden-output recovery without headless state; keeps an empty headless snapshot authoritative for hidden-output recovery; advances the absolute output sequence across a daemon stream gap; emits explicit OSC 9999 agent status from runtime PTY data. src/main/runtime/orca-runtime-tests/terminal-side-effect-facts-part-02.spec.ts: falls back to the provider snapshot for a restored PTY with no mounted renderer; falls back to the available mirror when authoritative provider history is unavailable; keeps an empty renderer snapshot when the provider has no retained content; keeps restored provider history authoritative after later live output; uses provider alternate-screen state while a partial model is unsafe; prefers the tracked title over the headless emulator lastTitle; keeps the cursor-agent literal in record-fallback snapshots only without a tracker title; touches mobile snapshots once for decorative spinner ticks, again on idle. src/main/runtime/orca-runtime-tests/local-worktree-creation-part-02.spec.ts: creates a same-repo PR branch override from a resolved head SHA and matching push target; skips broad remote fetch for an existing full-SHA PR base; creates a selected Bitbucket PR branch override from a matching remote branch; suffixes an existing PR when a matching push target lacks selected PR metadata; suffixes a matching push target branch when selected PR metadata has no PR number; suffixes a matching push target branch when the existing PR is different; suffixes a selected PR remote conflict when the PR lookup fails; checks out an unused runtime PR branch only when it is at the resolved head SHA; suffixes only the runtime worktree path when an exact PR branch checkout path exists. src/main/runtime/orca-runtime-tests/local-worktree-creation.spec.ts: returns runtime local base update suggestions from addWorktree; creates a runtime local worktree from a usable persisted local branch base; does not create a runtime local worktree when the refresh fails and no local base ref exists; creates a branchNameOverride worktree from the selected matching remote base ref. Current changed source bytes, wrapper registrations and reduced selectors have no fresh execution or red/green credit. Unrelated surviving receipt objects keep their original narrow scope; current literal graph reachability does not establish historical import closure or equivalent replacement coverage. Current conservative command/import graph reaches src/main/runtime/construction/orca-runtime.test.ts, src/main/runtime/orca-runtime-tests/targeting-and-resilience.spec.ts, src/main/runtime/orca-runtime-tests/worktree-removal-and-reconciliation-part-04.spec.ts, src/main/runtime/orca-runtime-tests/worktree-removal-and-reconciliation-part-03.spec.ts, src/main/runtime/orca-runtime-tests/worktree-removal-and-reconciliation-part-02.spec.ts, src/main/runtime/orca-runtime-tests/gitlab-and-pr-bases-part-02.spec.ts, src/main/runtime/orca-runtime-tests/gitlab-and-pr-bases.spec.ts, src/main/runtime/orca-runtime-tests/worktree-setup-and-startup-part-03.spec.ts, src/main/runtime/orca-runtime-tests/worktree-setup-and-startup.spec.ts, src/main/runtime/orca-runtime-tests/terminal-sleep-and-teardown-part-02.spec.ts, src/main/runtime/orca-runtime-tests/mobile-summaries-part-03.spec.ts, src/main/runtime/orca-runtime-tests/mobile-summaries-part-02.spec.ts, src/main/runtime/orca-runtime-tests/mobile-summaries.spec.ts, src/main/runtime/orca-runtime-tests/mobile-creation-and-orchestration-part-03.spec.ts, src/main/runtime/orca-runtime-tests/mobile-creation-and-orchestration-part-02.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-13.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-12.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-11.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-10.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-08.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-07.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-05.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-04.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs-part-02.spec.ts, src/main/runtime/orca-runtime-tests/mobile-session-tabs.spec.ts, src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-05.spec.ts, src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-04.spec.ts, src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-03.spec.ts, src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts, src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status.spec.ts, src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-07.spec.ts, src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-04.spec.ts, src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-03.spec.ts, src/main/runtime/orca-runtime-tests/terminal-output-and-worker-recovery-part-02.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-12.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-11.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-10.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-09.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-08.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-07.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-06.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness-part-03.spec.ts, src/main/runtime/orca-runtime-tests/terminal-creation-and-readiness.spec.ts, src/main/runtime/orca-runtime-tests/headless-snapshots.spec.ts, src/main/runtime/orca-runtime-tests/terminal-side-effect-facts-part-02.spec.ts, src/main/runtime/orca-runtime-tests/local-worktree-creation-part-02.spec.ts, src/main/runtime/orca-runtime-tests/local-worktree-creation.spec.ts. Unresolved local/computed edges remain explicit debt.", "Audit2145 accepts removal of canned runtime metadata/guard/forwarding, fake in-memory persistence, private work-count and wrapper-duplication tests from the construction/orca-runtime.test.ts aggregate, plus the two automation run-context guards from runtime-workspace-launch-contracts.test.ts. Retained race, framing, physical completion and ownership callbacks remain byte-identical. Existing commands remain valid selectors; historical receipts stay unchanged and provide no fresh validation or replacement coverage for the reduced suites.", "Audit3403 composes root-adopted3393/3394,3400/3401 and3398/3399: intentionally retires167 authored registrations/196 potential expanded cases across93 whole suites without equivalent replacement or fresh execution. Retained65 registrations/79 potential cases include one conditional missing-input failure sentinel; potential counts are not executions. Historical notes and complete dated receipts retain their exact original scopes. The retained runtime registration driver loses three complete imported fragments: changed-working-label title facts and suppressed-frame tracked snapshots; refusing SSH GitLab MR-base lookup before local Git/glab calls; and missing folder-workspace path creation/update refusal before spawn/store mutation. These alarms are intentionally lost. Other imported fragments and separately rooted dated receipts are unchanged; they are not equivalent replacement coverage. Original scope text is retained as the exact suffix of coverageNotes/oracle; historical evidence is unchanged.", - "Audit3832 deliberately retires76 authored/79 finite cases:75 runtime compatibility cases/78 finite cases across14 fragments, plus one localization extractor default-flag case. Three whole runtime fragments are deleted;27 authored/30 finite cases remain across the reviewed sources. This gate retains only its own selected scope; no equivalent replacement or fresh runtime/native/remote evidence is claimed. Runtime component A: Audit3828 composes3822 with independent3824: deliberately retires49 authored/52 finite cases from seven compatibility fragments, leaving15 authored/18 finite cases and deleting two entire fragments. Accepted losses: positive folder-worker recovery/materialization and reveal deadline; persisted-key normalization and legacy split/group/focus projection; fixed stale CAS refusal; occupied/alias/restored/preallocated terminal-handle variants; fixed OpenCode/Cursor/Claude/Codex/Antigravity classification, readiness, title and management examples; direct private-map browser authority projections; browser-focus and OMP title projection; already-aborted claim cleanup. Additional3824 loss: src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts :: does not poll a wrapper foreground for a speculative CLI prompt send :: Speculative retryForegroundWrappers:false check must return false on a wrapper after one foreground read, without polling the supplied later codex response. These real bounded alarms are deliberately retired for low marginal value. Retained callbacks are unchanged and provide only their own bounded scope, not equivalent replacement. Historical receipts do not validate reduced callbacks. No fresh runtime/native/SSH/WSL/phone/browser evidence or full transitive closure is claimed. Runtime component B: Audit3834 deliberately retires26 authored/26 finite cases from seven fresh compatibility fragments, leaving10/10 and deleting the one-case saved-binding reattachment fragment. Original position58 is excluded: its existing substantive3578 KEEP7 review remains historical, with no fresh credit. Accepted losses: fixed hook/provider-session identities and stale metadata refusal; decorative/pre-title foreground ordering variants; saved-binding surface reattachment; saved-row exit ghost removal and silent activation selection; unsupported headless wake; positive pending materialization/group projections; per-caller navigation selection; positive SSH hydration/read partition; laptop mobile publication/buffer and background/pending/status projections; abnormal/unregistered SSH grace, normal-exit refusal, persisted SSH hydration, positive serve reattachment, pending-agent launch arguments and direct seeded running-launch admission guard. These are real bounded alarms deliberately retired for low marginal value. Retained cases preserve their own distinct deferred foreground coalescing, usable handle continuity, stale inventory refresh, concurrent browser snapshot preservation, renderer graph fencing, caller dedup isolation, SSH partition writes, runtime split lifetime, independent relay-ready publication, lease admission/state/expiry. The direct running-launch no-spawn guard alarm is deliberately retired; no remaining owning-launch refusal coverage is claimed. Historical runs do not validate reduced callbacks. No equivalent replacement, runtime/native/SSH/WSL/phone/browser result or full transitive closure is claimed. Additional extractor loss: config/scripts/localization/source-extraction/audit-localization-native-dialogs.test.mjs :: does not change the existing renderer scan by default :: Default options must omit the five native-only fields in this supplied snippet. No equivalent replacement is claimed." + "Audit3832 deliberately retires76 authored/79 finite cases:75 runtime compatibility cases/78 finite cases across14 fragments, plus one localization extractor default-flag case. Three whole runtime fragments are deleted;27 authored/30 finite cases remain across the reviewed sources. This gate retains only its own selected scope; no equivalent replacement or fresh runtime/native/remote evidence is claimed. Runtime component A: Audit3828 composes3822 with independent3824: deliberately retires49 authored/52 finite cases from seven compatibility fragments, leaving15 authored/18 finite cases and deleting two entire fragments. Accepted losses: positive folder-worker recovery/materialization and reveal deadline; persisted-key normalization and legacy split/group/focus projection; fixed stale CAS refusal; occupied/alias/restored/preallocated terminal-handle variants; fixed OpenCode/Cursor/Claude/Codex/Antigravity classification, readiness, title and management examples; direct private-map browser authority projections; browser-focus and OMP title projection; already-aborted claim cleanup. Additional3824 loss: src/main/runtime/orca-runtime-tests/terminal-handles-and-agent-status-part-02.spec.ts :: does not poll a wrapper foreground for a speculative CLI prompt send :: Speculative retryForegroundWrappers:false check must return false on a wrapper after one foreground read, without polling the supplied later codex response. These real bounded alarms are deliberately retired for low marginal value. Retained callbacks are unchanged and provide only their own bounded scope, not equivalent replacement. Historical receipts do not validate reduced callbacks. No fresh runtime/native/SSH/WSL/phone/browser evidence or full transitive closure is claimed. Runtime component B: Audit3834 deliberately retires26 authored/26 finite cases from seven fresh compatibility fragments, leaving10/10 and deleting the one-case saved-binding reattachment fragment. Original position58 is excluded: its existing substantive3578 KEEP7 review remains historical, with no fresh credit. Accepted losses: fixed hook/provider-session identities and stale metadata refusal; decorative/pre-title foreground ordering variants; saved-binding surface reattachment; saved-row exit ghost removal and silent activation selection; unsupported headless wake; positive pending materialization/group projections; per-caller navigation selection; positive SSH hydration/read partition; laptop mobile publication/buffer and background/pending/status projections; abnormal/unregistered SSH grace, normal-exit refusal, persisted SSH hydration, positive serve reattachment, pending-agent launch arguments and direct seeded running-launch admission guard. These are real bounded alarms deliberately retired for low marginal value. Retained cases preserve their own distinct deferred foreground coalescing, usable handle continuity, stale inventory refresh, concurrent browser snapshot preservation, renderer graph fencing, caller dedup isolation, SSH partition writes, runtime split lifetime, independent relay-ready publication, lease admission/state/expiry. The direct running-launch no-spawn guard alarm is deliberately retired; no remaining owning-launch refusal coverage is claimed. Historical runs do not validate reduced callbacks. No equivalent replacement, runtime/native/SSH/WSL/phone/browser result or full transitive closure is claimed. Additional extractor loss: config/scripts/localization/source-extraction/audit-localization-native-dialogs.test.mjs :: does not change the existing renderer scan by default :: Default options must omit the five native-only fields in this supplied snippet. No equivalent replacement is claimed.", + "Audit5743 exact original active selector fields before whole suite removal (historical, not current coverage): {\"commands\":[\"pnpm exec vitest run --config config/vitest.config.ts src/shared/agent-launch/startup/agent-prompt-injection.test.ts src/main/runtime/construction/orca-runtime.test.ts src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts src/main/runtime/orchestration/coordinator/coordinator.test.ts\",\"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/methods/orchestration/worker/start/readiness/worker-start-prompt-contract.test.ts --reporter=dot\",\"node tests/tools/repro-orchestration-long-prompt.mjs --cli out/bin/orca-dev --mode codex-like --size-kb 32 --timeout-ms 20000\"],\"testFiles\":[\"src/shared/agent-launch/startup/agent-prompt-injection.test.ts\",\"src/main/runtime/construction/orca-runtime.test.ts\",\"src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts\",\"src/main/runtime/rpc/methods/orchestration/worker/start/readiness/worker-start-prompt-contract.test.ts\",\"src/main/runtime/orchestration/coordinator/coordinator.test.ts\",\"tests/tools/repro-orchestration-long-prompt.mjs\"],\"assertionRefs\":[{\"file\":\"src/shared/agent-launch/startup/agent-prompt-injection.test.ts\",\"assertions\":[\"agent prompts are always framed as bracketed paste\",\"Deferred unit obligation: OMP joins submit to the paste frame while Claude, Codex and unidentified agents keep submit separate; the direct predicate table was removed. Runtime-writer coverage is unchanged.\",\"embedded ESC bytes are made inert before framing\",\"chunk reconstruction preserves the paste frame\"]},{\"file\":\"src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts\",\"assertions\":[\"failed prompt injection rolls back the active dispatch\"]},{\"file\":\"src/main/runtime/orchestration/coordinator/coordinator.test.ts\",\"assertions\":[\"coordinator dispatch failures from prompt injection circuit-break through the DB\",\"silent-skip paths do not attempt prompt injection\"]},{\"file\":\"tests/tools/repro-orchestration-long-prompt.mjs\",\"assertions\":[\"fake Codex-like worker observes submit after long orchestration dispatch\",\"32KB task marker survives before submit\",\"prompt bytes include a bracketed-paste frame with zero unframed line breaks\"]}]}" ], "demotionRule": "Demote or quarantine if the live harness flakes without a product bug or harness bug filed to the terminal-input owner." }, @@ -13225,22 +13215,18 @@ "providers": ["local"], "coveredPlatforms": ["macos"], "coveredProviders": ["local"], - "coverageNotes": "Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the complete pane-split-startup wrapper suite and selector. Its temporary dependency-field exposure/reset, sequential payload isolation and thrown-sentinel cleanup alarms are lost; no quick command, process or PTY startup was exercised by those callbacks. Remaining queued-startup/ownership sources are not equivalent replacements. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): A forced pre-spawn barrier makes one visible Quick Command cross a recovery remount before its successor PTY binds. Lifecycle contracts retain lower-layer ownership; the Electron sentinel adds the rendered affordance, real PTY, exact-once terminal marker, staged identity file, and unrelated sibling canary. The test-value audit removed the store examples for retaining an undelivered queued startup command across remount, distinct queued ownership, sibling-bind preservation, unspawned close, and sibling queue isolation. The remaining store cases exercise recovery admission/settlement and non-replay after consumption; neither covers an undelivered command. The store suite is retired from this gate. Retained lifecycle and historical Electron evidence do not establish equivalent replacement coverage; historical commands and results remain historical. Audit1743 removes the standalone line-height clamp/default and pane cwd fallback helper tests (5 authored cases). These trivial-helper alarms are intentionally lost, with no equivalent replacement. Only current commands/testFiles lose the deleted selectors; historical receipts and evidenceRuns remain unchanged and do not validate the reduced commands.", + "coverageNotes": "Audit5748 companion to audit5744 retires the whole queued-pane-startup.test.ts suite. Its remaining captured-primary split ownership, one-shot repeated-spawn consumption, replacement-before-spawn refusal and permanently spent skipped-consumer alarms are intentionally lost without equivalent replacement. Remove its standalone unit selector or narrow the compound selector and remove its testFiles entry. Existing assertionRefs/evidenceRuns keep only their original scope and are unchanged; no fresh execution, current import reachability, PTY/provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the complete pane-split-startup wrapper suite and selector. Its temporary dependency-field exposure/reset, sequential payload isolation and thrown-sentinel cleanup alarms are lost; no quick command, process or PTY startup was exercised by those callbacks. Remaining queued-startup/ownership sources are not equivalent replacements. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): A forced pre-spawn barrier makes one visible Quick Command cross a recovery remount before its successor PTY binds. Lifecycle contracts retain lower-layer ownership; the Electron sentinel adds the rendered affordance, real PTY, exact-once terminal marker, staged identity file, and unrelated sibling canary. The test-value audit removed the store examples for retaining an undelivered queued startup command across remount, distinct queued ownership, sibling-bind preservation, unspawned close, and sibling queue isolation. The remaining store cases exercise recovery admission/settlement and non-replay after consumption; neither covers an undelivered command. The store suite is retired from this gate. Retained lifecycle and historical Electron evidence do not establish equivalent replacement coverage; historical commands and results remain historical. Audit1743 removes the standalone line-height clamp/default and pane cwd fallback helper tests (5 authored cases). These trivial-helper alarms are intentionally lost, with no equivalent replacement. Only current commands/testFiles lose the deleted selectors; historical receipts and evidenceRuns remain unchanged and do not validate the reduced commands.", "motivatingLinks": [ "https://linear.app/stably/issue/STA-4876", "https://github.com/stablyai/orca/pull/15630" ], "invariant": "A Quick Command selected for a new terminal remains owned by that tab through a recovery remount, executes exactly once only after the successor PTY binds, and never reaches an unrelated terminal.", - "oracle": "Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the complete pane-split-startup wrapper suite and selector. Its temporary dependency-field exposure/reset, sequential payload isolation and thrown-sentinel cleanup alarms are lost; no quick command, process or PTY startup was exercised by those callbacks. Remaining queued-startup/ownership sources are not equivalent replacements. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): Arm the E2E-only pre-spawn barrier, click the visible Quick Command, force one recovery generation while the original spawn is blocked, and release it. Require one exact semantic xterm marker, an independently written pane/tab identity file matching the bound live PTY, queue consumption only after bind, and a live interactive sibling canary.", + "oracle": "Audit5748 companion to audit5744 retires the whole queued-pane-startup.test.ts suite. Its remaining captured-primary split ownership, one-shot repeated-spawn consumption, replacement-before-spawn refusal and permanently spent skipped-consumer alarms are intentionally lost without equivalent replacement. Remove its standalone unit selector or narrow the compound selector and remove its testFiles entry. Existing assertionRefs/evidenceRuns keep only their original scope and are unchanged; no fresh execution, current import reachability, PTY/provider/native/platform or replacement coverage is claimed. Complete prior account preserved verbatim: Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1925 (sources1922/1923): Delete the complete pane-split-startup wrapper suite and selector. Its temporary dependency-field exposure/reset, sequential payload isolation and thrown-sentinel cleanup alarms are lost; no quick command, process or PTY startup was exercised by those callbacks. Remaining queued-startup/ownership sources are not equivalent replacements. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Historical prior account (preserved verbatim): Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Historical prior account (preserved verbatim): Arm the E2E-only pre-spawn barrier, click the visible Quick Command, force one recovery generation while the original spawn is blocked, and release it. Require one exact semantic xterm marker, an independently written pane/tab identity file matching the bound live PTY, queue consumption only after bind, and a live interactive sibling canary.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts --reporter=dot", "pnpm exec playwright test tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", "ORCA_E2E_FORCE_HEADFUL=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1" ], - "testFiles": [ - "src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts", - "tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts" - ], + "testFiles": ["tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts"], "assertionRefs": [ { "file": "tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts", @@ -13302,7 +13288,9 @@ "Audit1903 removes whole mocked detach, supplied geometry and/or close-request suites selected by this gate. Their pending-CWD/PTY-binding argument/order, fabricated hit-test and close bookkeeping alarms are intentionally lost without replacement. Valid remaining selectors/assertions and unchanged-selector execution receipts retain their original scope. Reduced unit selections have no fresh broad gate, real PTY/provider, rendered focus, or measured-budget validation. Exact lost direct alarms: 'detaches a rolled-back split surface without closing its PTY'; \"closes a tab through its last pane with the requester's reason, never an implied user close\"; 'uses non-destructive tab close semantics for the last rolled-back pane'; 'ignores a delayed rollback after the pane PTY identity changed'; 'retires a mounted rollback pane without detaching it as a movable surface'; 'retires mounted authority and binding while preserving the process and sleeping fence'; 'suppresses the pane PTY exit before intentional close teardown destroys the transport'; 'does not suppress natural PTY exits that already cleared the transport id'.", "Audit1925 (sources1922/1923): Delete the complete pane-split-startup wrapper suite and selector. Its temporary dependency-field exposure/reset, sequential payload isolation and thrown-sentinel cleanup alarms are lost; no quick command, process or PTY startup was exercised by those callbacks. Remaining queued-startup/ownership sources are not equivalent replacements. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Exact retired authored alarms: 'only exposes startup to the intentional split and clears it afterwards'; 'isolates startup payloads across sequential calls (setup then issue)'; 'clears startup even when splitPane throws'.", "Audit1931 (sources1928/1929): Delete complete transport-unmount and queued-initial-CWD helper suites: despite lifecycle-shaped fixtures, the unmount owner returns a Boolean PTY-id predicate, while CWD cases check nullish field selection and callback counts. Lose their detach/destroy/teardown and one-shot-CWD supplied examples. Partial queued-pane-startup loses three identical/empty/nonowner identity examples, retaining four exact one-shot/replacement ownership callbacks. No assertion object maps to these three sources, so unrelated alias objects remain byte-exact. Preserve the current81ed prior removal of pane-split-startup; stale bd948 source metadata snapshots are not replayed. No actual process/PTY startup, transport shutdown, live SSH or rendered recovery is proven by this metadata change. Preserve meaningful remaining selectors/assertions and unchanged dated receipts within their original scope. Reduced selectors have no fresh gate execution evidence in this metadata packet. No equivalent replacement, physical watcher/PTY/provider, live SSH/remote/mobile, rendered, cross-platform, soak or measured-budget result is claimed. Exact retired authored alarms: 'detaches when the tab still owns the transport PTY'; 'detaches when a mirrored replacement tab owns the same PTY'; 'detaches when closeTab already owns provider shutdown for the removed tab'; 'destroys an ID-less transport so a pending spawn cannot outlive unmount'; 'detaches a removed automation pane after closeTab takes teardown authority'; 'consumes the queued initial cwd once when the ref is unset'; 'reuses the existing queued state without re-reading the store'; 'clears the one-shot cwd and restores the default cwd after the first pane'; 'leaves the cwd unchanged when no one-shot override is queued'; 'denies ownership to a split payload structurally identical to the queued command'; 'denies ownership when the tab queued nothing, so an unrelated pane cannot spend a slot'; 'withholds the consumer from a pane that does not own the queued command'.", - "Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed." + "Audit2052 (sources2049/2050/2051): Remove complete low-value restored-pane-title and pane-visibility-identity suites and their current selectors. Their supplied snapshot/title and nullable identity-comparison alarms are intentionally lost without replacement. Unrelated dated evidenceRuns remain unchanged and do not validate the reduced commands. No fresh gate execution, actual PTY/provider, rendered, remote/mobile or cross-platform result is claimed.", + "Audit5748 exact original complete commands JSON value, preserved verbatim as historical selector metadata; removed/narrowed selector is not validated by old evidence:\n[\n \"pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts --reporter=dot\",\n \"pnpm exec playwright test tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\",\n \"ORCA_E2E_FORCE_HEADFUL=1 SKIP_BUILD=1 pnpm exec playwright test tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1\"\n ]", + "Audit5748 exact original complete testFiles JSON value, preserved verbatim as historical selector metadata; removed/narrowed selector is not validated by old evidence:\n[\n \"src/renderer/src/components/terminal-pane/mounting/queued-pane-startup.test.ts\",\n \"tests/e2e/terminal-quick-command-pre-bind-recovery.spec.ts\"\n ]" ], "demotionRule": "Demote if the barrier can be bypassed nondeterministically, either independent oracle is removed, the sibling canary is no longer isolated, or one unexplained flake occurs." }, diff --git a/config/scripts/ci/sharding/ci-shard-timings.json b/config/scripts/ci/sharding/ci-shard-timings.json index 404552418d1..07ed4c30925 100644 --- a/config/scripts/ci/sharding/ci-shard-timings.json +++ b/config/scripts/ci/sharding/ci-shard-timings.json @@ -396,33 +396,25 @@ "src/main/acp/history/acp-history-scaling.test.ts": 24879, "src/main/persistence/preferences/active-view-persistence-boundary.test.ts": 2119, "src/main/persistence/preferences/active-view-preference-sync-flush-veto.test.ts": 781, - "src/main/providers/accounts/agent-auth-restart-preservation.test.ts": 55, "src/main/agent-hooks/tool-events/agent-tool-plugin-hooks.test.ts": 202, "src/main/agent-hooks/installation/scripts/cursor-replay-guard.test.ts": 403, "src/main/agent-hooks/server/testing/reconciliation/ended-process-reconciliation.test.ts": 775, "src/main/agent-hooks/first-work/first-work-branch-rename-wsl-move.test.ts": 831, "src/main/agent-hooks/first-work/first-work-branch-rename.test.ts": 857, - "src/main/agent-hooks/installation/scripts/grok-replay-guard.test.ts": 533, "src/main/agent-hooks/installation/scripts/hook-process-capture.test.ts": 118, "src/main/agent-hooks/installation/scripts/hook-script-outside-orca.test.ts": 171, "src/main/agent-hooks/installation/testing/installer-contract.test.ts": 264, - "src/main/agent-hooks/installation/local-agent-cli-presence.test.ts": 153, - "src/main/agent-hooks/observations/local-tmux-managed-pty.test.ts": 50, "src/main/agent-hooks/installation/scripts/locked-executable-rename.test.ts": 69, "src/main/agent-hooks/installation/managed-agent-hook-controls.test.ts": 250, "src/main/agent-hooks/installation/locking/managed-hook-install-lock.test.ts": 226, "src/main/agent-hooks/installation/scripts/managed-hook-script-refresh-main-thread.test.ts": 567, - "src/main/agent-hooks/installation/scripts/managed-hook-script-refresh.test.ts": 1637, "src/main/agent-hooks/installation/scripts/managed-hook-stdin-lifecycle.test.ts": 1989, "src/main/agent-hooks/installation/scripts/managed-hook-timeout.test.ts": 2987, "src/main/agent-hooks/installation/scripts/posix-hook-json-stdin-reader.test.ts": 3479, "src/main/agent-hooks/server/testing/presence/server-agent-presence.test.ts": 1257, - "src/main/agent-hooks/server/testing/identity/server-ai-vault-liveness.test.ts": 643, "src/main/agent-hooks/server/testing/providers/antigravity/server-antigravity-resume-identity.test.ts": 820, - "src/main/agent-hooks/server/testing/permissions/server-claude-child-permission-lifecycle.test.ts": 681, "src/main/agent-hooks/server/testing/interruptions/server-claude-helper-kill.test.ts": 10279, "src/main/agent-hooks/server/testing/identity/server-claude-session-continuation.test.ts": 675, - "src/main/agent-hooks/server/testing/http/server-claude-statusline.test.ts": 679, "src/main/agent-hooks/server/testing/task-wakeup/server-claude-task-wakeup-lifecycle.test.ts": 5451, "src/main/agent-hooks/server/testing/interruptions/server-claude-terminal-interrupt.test.ts": 802, "src/main/agent-hooks/server/testing/authority/server-closed-tab-suppression.test.ts": 895, @@ -437,7 +429,6 @@ "src/main/agent-hooks/server/testing/providers/grok/server-grok-background-status.test.ts": 723, "src/main/agent-hooks/server/testing/providers/grok/server-grok-discovery.test.ts": 723, "src/main/agent-hooks/server/testing/identity/server-hermes-resume-identity.test.ts": 941, - "src/main/agent-hooks/server/testing/http/server-hook-http-ingest.test.ts": 719, "src/main/agent-hooks/server/testing/identity/server-hook-session-binding.test.ts": 2674, "src/main/agent-hooks/server/testing/presence/server-http-owner-probe-lifecycle.test.ts": 1088, "src/main/agent-hooks/server/testing/presence/server-idle-process-owner.test.ts": 1014, @@ -445,28 +436,16 @@ "src/main/agent-hooks/server/testing/structured-ingress/server-ingest-structured-state-clock.test.ts": 723, "src/main/agent-hooks/server/testing/structured-ingress/server-ingest-structured-status.test.ts": 697, "src/main/agent-hooks/server/testing/terminal-ingress/server-ingest-terminal-status.test.ts": 673, - "src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-guards.test.ts": 685, - "src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-resurrection.test.ts": 759, - "src/main/agent-hooks/server/testing/persistence/server-last-status-child-held-main-agent.test.ts": 937, "src/main/agent-hooks/server/testing/persistence/server-last-status-main-agent-fact.test.ts": 813, - "src/main/agent-hooks/server/testing/persistence/server-last-status-restored-children.test.ts": 818, "src/main/agent-hooks/server/testing/persistence/server-last-status-write.test.ts": 745, - "src/main/agent-hooks/server/testing/identity/server-launch-resume-identity.test.ts": 735, - "src/main/agent-hooks/server/testing/main-agent/server-main-agent-turn-verdicts.test.ts": 1716, "src/main/agent-hooks/server/testing/providers/muse/server-muse-session-log-poll.test.ts": 2772, - "src/main/agent-hooks/server/testing/identity/server-nested-agent-boundaries.test.ts": 657, - "src/main/agent-hooks/server/testing/identity/server-nested-agent-model.test.ts": 665, - "src/main/agent-hooks/server/testing/identity/server-nested-same-provider-owner.test.ts": 708, - "src/main/agent-hooks/server/testing/authority/server-omp-retired-ingress.test.ts": 641, "src/main/agent-hooks/server/testing/authority/server-omp-retirement-ack.test.ts": 676, "src/main/agent-hooks/server/testing/identity/server-opencode-writer-observation.test.ts": 681, "src/main/agent-hooks/server/testing/authority/server-pane-authority.test.ts": 762, "src/main/agent-hooks/server/testing/telemetry/server-prompt-sent-telemetry.test.ts": 701, "src/main/agent-hooks/server/testing/interruptions/server-relayed-claude-cancel.test.ts": 901, "src/main/agent-hooks/server/testing/replay/server-relayed-claude-permission-replay.test.ts": 758, - "src/main/agent-hooks/server/testing/authority/server-reminted-pane-key.test.ts": 688, "src/main/agent-hooks/server/testing/authority/server-removed-worktree-foreign-authority.test.ts": 764, - "src/main/agent-hooks/server/testing/authority/server-removed-worktree-status.test.ts": 687, "src/main/agent-hooks/server/testing/replay/server-replay-evidence-clock.test.ts": 643, "src/main/agent-hooks/server/testing/http/server-startup-lifecycle.test.ts": 718, "src/main/agent-hooks/server/testing/http/server-startup-prompt-control.test.ts": 697, @@ -477,12 +456,10 @@ "src/main/agent-hooks/server/testing/tmux/server-tmux-wire.test.ts": 564, "src/main/agent-hooks/server/testing/http/server-transport-interference.test.ts": 1814, "src/main/agent-hooks/server/testing/main-agent/server-turn-ended-at.test.ts": 990, - "src/main/agent-hooks/server/testing/main-agent/server-turn-started-at.test.ts": 898, "src/main/agent-hooks/server/testing/replay/spool.test.ts": 999, "src/main/agent-hooks/server/testing/identity/terminal-handle-row-identity.test.ts": 669, "src/main/agent-hooks/installation/commands/windows-batch-hook-launcher.test.ts": 108, "src/main/agent-hooks/installation/commands/windows-cmd-hook-command-unicode.test.ts": 141, - "src/main/agent-hooks/installation/commands/windows-hook-payload-delivery.test.ts": 345, "src/main/agent-hooks/installation/commands/windows-native-hook-exe-hosts.test.ts": 262, "src/main/agent-hooks/installation/commands/windows-powershell-hook-launcher.test.ts": 44, "src/main/agent-hooks/wsl-relay/testing/wsl-hook-relay-live.integration.test.ts": 2231, @@ -584,7 +561,6 @@ "src/main/ai-vault/scanners/opencode2/session-scanner-opencode2-message.test.ts": 138, "src/main/ai-vault/scanners/opencode2/session-scanner-opencode2-sqlite.test.ts": 306, "src/main/ai-vault/parse-cache/session-scanner-parse-cache-agents.test.ts": 544, - "src/main/ai-vault/session-scanner-parse-wsl-stall.test.ts": 296, "src/main/ai-vault/session-scanner-parser-stream-cleanup.test.ts": 184, "src/main/ai-vault/scanners/pi/session-scanner-pi-omp-shared-root.test.ts": 505, "src/main/ai-vault/scanners/pi/session-scanner-pi-scope.test.ts": 501, @@ -593,7 +569,6 @@ "src/main/ai-vault/session-scanner-roots.test.ts": 203, "src/main/ai-vault/session-scanner-scope-cwd-facts.test.ts": 797, "src/main/ai-vault/session-scanner-scope-walk.test.ts": 5362, - "src/main/ai-vault/session-scanner-scope.test.ts": 550, "src/main/ai-vault/scan-service/session-scanner-service-cancellation.test.ts": 391, "src/main/ai-vault/scan-service/session-scanner-service-entry.test.ts": 909, "src/main/ai-vault/scan-service/session-scanner-service-request-deadline.test.ts": 122, @@ -652,13 +627,11 @@ "src/main/automations/automation-wsl-move-refusal.test.ts": 2285, "src/main/automations/automation-zero-grace-tick-latency.test.ts": 2108, "src/main/automations/dispatch/dispatch-refusal-wsl-move.test.ts": 577, - "src/main/automations/external-managers/external-automation-manager-cache.test.ts": 70, "src/main/automations/external-managers/scoped-external-automations.test.ts": 391, "src/main/automations/run-terminal-retention.test.ts": 112, "src/main/automations/automation-workspace-create.test.ts": 50, "src/main/automations/hook-review-blocked-run-terminals.test.ts": 4564, "src/main/automations/dispatch/precheck-runner.test.ts": 1132, - "src/main/automations/observation/retained-run-reconciliation.test.ts": 1940, "src/main/automations/ownership/run-target-resolution.test.ts": 367, "src/main/automations/runtime-terminal-run-observer-evidence.test.ts": 230, "src/main/automations/service-precheck.test.ts": 2057, @@ -846,7 +819,6 @@ "src/main/claude-accounts/profiles/claude-profile-paths.test.ts": 82, "src/main/claude-accounts/profiles/setup/claude-profile-provisioning.test.ts": 854, "src/main/claude-accounts/profiles/routing/claude-profile-router.test.ts": 1091, - "src/main/claude-accounts/profiles/setup/claude-profile-setup-worker.test.ts": 410, "src/main/claude-accounts/profiles/setup/claude-profile-setup.test.ts": 405, "src/main/claude-accounts/profiles/wsl/claude-profile-wsl-router.test.ts": 919, "src/main/claude-accounts/sign-in/claude-sign-in-browser.test.ts": 314, @@ -873,9 +845,7 @@ "src/main/claude/claude-background-task-turn-resumption.test.ts": 325, "src/main/claude/claude-background-wake-retention.test.ts": 1652, "src/main/claude/claude-close-turn-end.test.ts": 970, - "src/main/claude/structured/turns/claude-command-lifecycle-frames.test.ts": 268, "src/main/claude/structured/turns/claude-command-lifecycle.test.ts": 1107, - "src/main/claude/structured/turns/claude-command-turn.test.ts": 292, "src/main/claude/claude-context-model-switch.test.ts": 422, "src/main/claude/claude-context-usage-restart.test.ts": 925, "src/main/claude/claude-context-usage-unloaded-turn.test.ts": 4910, @@ -883,20 +853,16 @@ "src/main/claude/claude-fold-steer-receipt.test.ts": 1019, "src/main/claude/configuration/claude-folder-trust-file.test.ts": 762, "src/main/claude/claude-informational-row.test.ts": 811, - "src/main/claude/structured/journal/claude-journal-turn-scope.test.ts": 254, "src/main/claude/claude-naming-invocation.test.ts": 334, "src/main/claude/claude-plan-approval-mode.test.ts": 905, "src/main/claude/hooks/claude-profile-hooks.test.ts": 371, "src/main/claude/transcripts/claude-provider-session-rename.test.ts": 597, - "src/main/claude/subagents/claude-provisional-row-corrections.test.ts": 67, - "src/main/claude/structured/turns/claude-request-end-wait.test.ts": 53, "src/main/claude/claude-settings-schema-install.test.ts": 410, "src/main/claude/hooks/claude-status-line-install.test.ts": 342, "src/main/claude/claude-status-line-windows.test.ts": 273, "src/main/claude/claude-stop-ack-race.test.ts": 1301, "src/main/claude/claude-stream-json-connection-close.test.ts": 621, "src/main/claude/sdk-transport/claude-stream-json-connection.test.ts": 8687, - "src/main/claude/structured/journal/claude-streamed-text-checkpoints.test.ts": 59, "src/main/claude/claude-structured-launch-home-perf.test.ts": 401, "src/main/claude/claude-structured-result-control-overlap.test.ts": 1136, "src/main/claude/claude-subagent-permission-request.test.ts": 3776, @@ -905,9 +871,7 @@ "src/main/claude/claude-supervised-stop.integration.test.ts": 3821, "src/main/claude/transcripts/claude-transcript-catch-up.test.ts": 4017, "src/main/claude/claude-transcript-duration.test.ts": 1411, - "src/main/claude/hooks/hook-service.test.ts": 329, "src/main/claude/hooks/post-compact-hook-command.test.ts": 314, - "src/main/claude/hooks/statusline-script.test.ts": 257, "src/main/claude/structured/claude-structured-conversation-stop.test.ts": 884, "src/main/claude/structured/claude-structured-dispatch-admission.test.ts": 426, "src/main/claude/structured/claude-structured-dispatch-content.test.ts": 176, @@ -922,7 +886,6 @@ "src/main/claude/structured/claude-structured-real-cli-stop-task.test.ts": 888, "src/main/claude/structured/claude-structured-real-cli-visuals.test.ts": 945, "src/main/claude/structured/claude-structured-real-cli.test.ts": 918, - "src/main/claude/structured/claude-structured-reasoning.test.ts": 265, "src/main/claude/structured/claude-structured-requested-stop.test.ts": 925, "src/main/claude/structured/claude-structured-resume-point.test.ts": 1713, "src/main/claude/structured/claude-structured-session-acquisition-processless.test.ts": 778, @@ -936,7 +899,6 @@ "src/main/claude/structured/journal/claude-structured-journal-translation-turn-timing.test.ts": 827, "src/main/claude/structured/journal/claude-structured-journal-translation.test.ts": 771, "src/main/claude/structured/journal/claude-structured-prompt-ownership.test.ts": 944, - "src/main/claude/structured/launch/claude-structured-applied-options.test.ts": 956, "src/main/claude/structured/launch/claude-structured-child-env.test.ts": 126, "src/main/claude/structured/launch/claude-structured-launch-resolution.test.ts": 672, "src/main/claude/structured/launch/claude-structured-launch-visuals.test.ts": 565, @@ -947,7 +909,6 @@ "src/main/claude/structured/launch/claude-structured-provider-fallback.test.ts": 670, "src/main/claude/structured/launch/claude-structured-real-cli-options.test.ts": 902, "src/main/claude/windows-native-hook-registration.test.ts": 246, - "src/main/cli/appimage/appimage-copy-pre-extraction.test.ts": 328, "src/main/cli/appimage/appimage-extraction-pruning-namespace.test.ts": 106, "src/main/cli/appimage/appimage-extraction-pruning.test.ts": 117, "src/main/cli/appimage/appimage-stable-launcher.test.ts": 135, @@ -968,7 +929,6 @@ "src/main/cli/wsl/wsl-cli-registration-reconciliation.test.ts": 386, "src/main/cli/wsl/wsl-cli-registration-registry.test.ts": 150, "src/main/cli/wsl/wsl-managed-cli.wsl.test.ts": 115, - "src/main/codebuddy/hook-service.test.ts": 272, "src/main/filesystem/async-file-rename.test.ts": 1065, "src/main/filesystem/atomic-file-publication.test.ts": 127, "src/main/codex-accounts/managed-homes/guest-codex-account-homes.test.ts": 86, @@ -977,7 +937,6 @@ "src/main/codex-accounts/runtime-home/legacy-host/legacy-shared-config-compatibility.test.ts": 151, "src/main/codex-accounts/legacy-wsl-auth-drain/legacy-wsl-runtime-auth-drain-apply-script.test.ts": 5936, "src/main/codex-accounts/legacy-wsl-auth-drain/legacy-wsl-runtime-auth-drain-rollback-script.test.ts": 558, - "src/main/codex-accounts/credentials/managed-codex-auth-readiness.test.ts": 86, "src/main/codex-accounts/runtime-home/legacy-host/runtime-home-legacy-migration.test.ts": 1147, "src/main/codex-accounts/runtime-home/credentials/runtime-home-managed-auth-recovery.test.ts": 658, "src/main/codex-accounts/runtime-home/credentials/runtime-home-mirror-login-copy.test.ts": 1012, @@ -1056,7 +1015,6 @@ "src/main/codex/history/index/codex-session-index-heal.test.ts": 2722, "src/main/codex/history/resume/codex-session-resume-home.test.ts": 110, "src/main/codex/history/resume/codex-session-resume-preparation.test.ts": 66, - "src/main/codex/history/resume/codex-session-resume-windows.test.ts": 57, "src/main/codex/history/resume/codex-session-resume-wrong-account.test.ts": 82, "src/main/codex/configuration/shared-server/codex-shared-server-probe.test.ts": 181, "src/main/codex/configuration/homes/codex-stale-pane-accounts.test.ts": 146, @@ -1099,7 +1057,6 @@ "src/main/codex/structured/session-lifecycle/codex-structured-session-exit-blame.test.ts": 548, "src/main/codex/structured/session-lifecycle/codex-structured-session-prompts.test.ts": 609, "src/main/codex/structured/session-lifecycle/codex-structured-session-shutdown.test.ts": 635, - "src/main/codex/structured/catalog/codex-structured-skill-report.test.ts": 651, "src/main/codex/structured/threads/codex-structured-thread-catch-up.test.ts": 1170, "src/main/codex/structured/threads/codex-structured-thread-goal.test.ts": 737, "src/main/codex/structured/threads/codex-structured-thread-open.test.ts": 469, @@ -1156,7 +1113,6 @@ "src/main/crash-reporting/breadcrumbs/crash-breadcrumb-store-orphan-cleanup.test.ts": 81, "src/main/crash-reporting/reports/crash-report-store.test.ts": 438, "src/main/crash-reporting/minidumps/minidump-crash-signature.test.ts": 87, - "src/main/crash-reporting/minidumps/minidump-fault-context.test.ts": 57, "src/main/crash-reporting/minidumps/minidump-file-source.test.ts": 199, "src/main/crash-reporting/memory/renderer-heap-allocation-sites.test.ts": 62, "src/main/credentials/saved-credential-readability.test.ts": 56, @@ -1368,7 +1324,6 @@ "src/main/ephemeral-vm/recipe-runner.test.ts": 460, "src/main/ephemeral-vm/runtime-service.test.ts": 870, "src/main/ephemeral-vm/runtime-ssh-cleanup.test.ts": 188, - "src/main/runtime/events/event-listener-fanout.test.ts": 52, "src/main/agent-launch/trust/execution-host-workspace-trust.test.ts": 232, "src/main/external-conversations/external-conversation-cancel-settlement.test.ts": 1601, "src/main/external-conversations/external-conversation-cancel.test.ts": 1605, @@ -1394,7 +1349,6 @@ "src/main/git/command-runner/exec-file-capture-stdin.test.ts": 287, "src/main/git/command-runner/gh-exec-file-lifetime.test.ts": 229, "src/main/git/command-runner/git-admission-storm-measurement.test.ts": 264, - "src/main/git/command-runner/git-command-resolution-windows-checkout.test.ts": 133, "src/main/git/command-runner/git-exec-admission-lifetime.test.ts": 718, "src/main/git/command-runner/git-spawn-wsl-admission.test.ts": 153, "src/main/git/command-runner/missing-git-spawn-cwd.test.ts": 218, @@ -1412,14 +1366,11 @@ "src/main/git/refs/maintenance/local-repo-ref-maintenance.test.ts": 339, "src/main/git/objects/merge-tree-object-quarantine-real-git.test.ts": 2561, "src/main/git/refs/maintenance/pack-refs-lock-ownership.test.ts": 59, - "src/main/git/source-control/status/porcelain-v1-records.test.ts": 138, "src/main/git/remotes/remote-ref-probe-cache.test.ts": 414, "src/main/git/remotes/remote.test.ts": 352, "src/main/git/worktrees/removal/remove-worktree-branch-cleanup.test.ts": 409, "src/main/git/worktrees/removal/remove-worktree-clean-preflight.test.ts": 248, "src/main/git/worktrees/removal/remove-worktree.test.ts": 310, - "src/main/git/refs/resolution/repo-branch-conflict-real-git.test.ts": 348, - "src/main/git/repositories/discovery/repo-detection-async.test.ts": 612, "src/main/git/repositories/discovery/repo-detection-batching.test.ts": 494, "src/main/git/repositories/discovery/repo-detection.test.ts": 842, "src/main/git/refs/maintenance/repo-maintenance-admission.test.ts": 757, @@ -1430,10 +1381,7 @@ "src/main/git/repo-search-ref-compat.test.ts": 125, "src/main/git/repo-username.test.ts": 303, "src/main/git/refs/resolution/repo.test.ts": 2318, - "src/main/git/command-runner/runner-buffer-cancellation.test.ts": 318, "src/main/git/command-runner/runner-buffer-stdin.test.ts": 229, - "src/main/git/command-runner/hosted-cli/runner-gh-rate-limit-breaker.test.ts": 261, - "src/main/git/command-runner/host-routing/runner-windows-host-environment.test.ts": 322, "src/main/git/command-runner/host-routing/runner-wsl-direct-read.test.ts": 413, "src/main/git/command-runner/hosted-cli/runner-wsl-gh-fallback.test.ts": 1093, "src/main/git/runner-wsl-linked-gitdir-timeout.test.ts": 266, @@ -1452,13 +1400,10 @@ "src/main/git/source-control/submodules/submodule-restore-recurse-real-git.test.ts": 398, "src/main/git/source-control/comparisons/status-branch-compare-real-ref.test.ts": 593, "src/main/git/source-control/status-branch-compare.test.ts": 251, - "src/main/git/source-control/status/status-branch-line-total-exec-contract.test.ts": 1033, "src/main/git/source-control/status/status-branch-line-total-real-git.test.ts": 785, "src/main/git/source-control/status/status-branch-line-total-untracked-base.test.ts": 700, - "src/main/git/source-control/diffs/status-diff.test.ts": 327, "src/main/git/source-control/status-discard-and-bulk-staging.test.ts": 289, "src/main/git/source-control/mutations/status-discard-symlink.test.ts": 456, - "src/main/git/source-control/status/status-line-stats-host-paths.test.ts": 77, "src/main/git/source-control/status/status-line-stats-renames-real-git.test.ts": 631, "src/main/git/source-control/mutations/status-pathspec-literals.test.ts": 442, "src/shared/git/status/git-status-porcelain-parser.test.ts": 52, @@ -1466,7 +1411,6 @@ "src/main/git/source-control/status/status-read-failure-real-git.test.ts": 307, "src/main/git/source-control/status/status-shared-symlinks.test.ts": 746, "src/main/git/source-control/submodules/status-submodule.test.ts": 306, - "src/main/git/source-control/upstream/upstream-deferred-fork-remote-real.test.ts": 319, "src/main/git/worktrees/creation/worktree-add-local-base-refresh.test.ts": 362, "src/main/git/worktrees/creation/worktree-add-pending-removal.test.ts": 346, "src/main/git/worktrees/creation/worktree-add-remote-branch-upstream-real-git.test.ts": 786, @@ -1500,7 +1444,6 @@ "src/main/git/worktrees/content-paths/worktree-shared-directories.test.ts": 1045, "src/main/git/worktrees/content-paths/worktree-symlink-detection.test.ts": 51, "src/main/git/command-runner/wsl-linked-worktree-git-route-invalidation.test.ts": 48, - "src/main/git/command-runner/host-routing/wsl-windows-checkout-git-probe.test.ts": 273, "src/main/git/wsl-windows-checkout-sample-script.test.ts": 165, "src/main/gitea/client-scan-invalidation.test.ts": 474, "src/main/github/auth-diagnose.test.ts": 43, @@ -1533,21 +1476,15 @@ "src/main/github/gh-utils-concurrency.test.ts": 530, "src/main/github/gh-utils.test.ts": 570, "src/main/github/github-enterprise-repository.test.ts": 479, - "src/main/github/github-pr-stack.test.ts": 495, "src/main/github/github-project-account.test.ts": 547, "src/main/github/github-repository-identity.fork-owner-repo.test.ts": 478, - "src/main/github/github-repository-identity.signed-cache.test.ts": 479, - "src/main/github/issue-work-item-details-fresh.test.ts": 490, "src/main/github/issues.test.ts": 569, - "src/main/github/pr-refresh-coordinator-active-visible-priority.test.ts": 643, "src/main/github/pr-refresh-coordinator-alias-coalescing.test.ts": 1020, - "src/main/github/pr-refresh-coordinator-completion-order.test.ts": 914, "src/main/github/pr-refresh-coordinator-foreground-pacing.test.ts": 650, "src/main/github/pr-refresh-coordinator-refresh-events.test.ts": 617, "src/main/github/pr-refresh-coordinator-visibility-policy.test.ts": 1371, "src/main/github/pr-refresh-coordinator-visible-follow-up.test.ts": 1096, "src/main/github/pr-refresh-coordinator-wsl-stopped-distro.test.ts": 510, - "src/main/github/pr-refresh-queue-growth-bound.test.ts": 1021, "src/main/github/pr-refresh-validation-backoff.test.ts": 55, "src/main/github/pr-review-comment-lines.test.ts": 41, "src/main/github/pr-start-point.test.ts": 525, @@ -1558,15 +1495,11 @@ "src/main/github/project-view/project-view-config.test.ts": 556, "src/main/github/pull-request-sidebar-query.test.ts": 492, "src/main/github/rate-limit.test.ts": 78, - "src/main/github/repository-merge-metadata-reuse.test.ts": 546, "src/main/github/work-item-details-enterprise-host.test.ts": 574, - "src/main/github/work-item-details-pr-files.test.ts": 591, "src/main/github/work-item-details-query-reuse.test.ts": 592, - "src/main/github/work-item-details.test.ts": 613, "src/main/github/work-item-pr-cursor-page.test.ts": 2179, "src/main/github/work-item-search-freshness.test.ts": 1425, "src/main/github/work-item-search-pagination.test.ts": 618, - "src/main/gitlab/projects/gitlab-known-host-probe.test.ts": 389, "src/main/gitlab/requests/glab-request-admission.test.ts": 493, "src/main/gitlab/projects/task-project-eligibility.test.ts": 362, "src/main/gitlab/work-items/work-item-details.test.ts": 115, @@ -1662,7 +1595,6 @@ "src/main/ipc/filesystem/watcher-process/parcel-watcher-process-dispose.test.ts": 51, "src/main/ipc/filesystem/watcher-process/parcel-watcher-process.test.ts": 519, "src/main/ipc/filesystem/watcher-process/root-paths/parcel-watcher-root-path-rewrite.test.ts": 135, - "src/main/ipc/filesystem/watcher-process/native-subscriptions/parcel-watcher-shallow-subscription.test.ts": 241, "src/main/ipc/filesystem/watcher-process/supervision/parcel-watcher-supervisor-capacity.test.ts": 235, "src/main/ipc/filesystem/watchers/filesystem-watcher-event-batch.test.ts": 59, "src/main/ipc/filesystem/watchers/filesystem-watcher-ignore-real.test.ts": 707, @@ -1693,7 +1625,6 @@ "src/main/ipc/notifications-subject-retirement.test.ts": 304, "src/main/ipc/profiles/orca-profiles-switch-persistence.test.ts": 2761, "src/main/ipc/filesystem/watcher-process/supervision/parcel-watcher-crash-fuse-recovery.test.ts": 128, - "src/main/ipc/filesystem/watcher-process/event-delivery/parcel-watcher-delivery-health.test.ts": 110, "src/main/ipc/pets/pet-bundle.test.ts": 48, "src/main/ipc/pets/pet.test.ts": 268, "src/main/ipc/plugin-marketplaces.test.ts": 430, @@ -2273,14 +2204,12 @@ "src/main/plugins/workers/plugin-host-runtime.test.ts": 274, "src/main/plugins/workers/plugin-worker-controller.test.ts": 394, "src/main/plugins/workers/plugin-worker-dev-restart-storage.integration.test.ts": 754, - "src/main/plugins/workers/plugin-worker-manager.test.ts": 231, "src/main/plugins/workers/plugin-worker-output-retention.test.ts": 296, "src/main/plugins/workers/plugin-worker-refresh-admission.test.ts": 6941, "src/main/plugins/workers/plugin-worker-reviewed-content.test.ts": 760, "src/main/plugins/workers/plugin-worker-supervision.integration.test.ts": 8561, "src/main/plugins/workers/plugin-worker-typescript-entry.integration.test.ts": 516, "src/main/ports/advertised-url-retention.test.ts": 167, - "src/main/ports/advertised-url-watcher.test.ts": 99, "src/main/ports/darwin-port-scan-lifetime.test.ts": 63, "src/main/ports/darwin-process-metadata.test.ts": 404, "src/main/ports/local-workspace-port-scanner.test.ts": 328, @@ -2296,13 +2225,11 @@ "src/main/workspaces/execution-host/project-runtime-git-router-store.test.ts": 1818, "src/main/credentials/protected-secret-persistence.test.ts": 53, "src/main/provider-process/managed-provider-process-fallback-tree.test.ts": 150, - "src/main/provider-process/managed-provider-process.test.ts": 185, "src/main/provider-process/managed-provider-writer-close.test.ts": 162, "src/main/provider-process/provider-group-orphan-guard.integration.test.ts": 3432, "src/main/provider-process/provider-group-orphan-guard.test.ts": 220, "src/main/provider-process/provider-process-row-read.test.ts": 87, "src/main/provider-process/provider-process-supervisor.integration.test.ts": 7485, - "src/main/provider-process/provider-process-teardown.test.ts": 146, "src/main/daemon/pty-subprocess/testing/agent-foreground-process-git-bash.win32.test.ts": 361, "src/main/providers/local-pty/local-pty-provider-shutdown.test.ts": 731, "src/main/providers/local-pty/local-pty-provider-spawn-session.test.ts": 856, @@ -2327,7 +2254,6 @@ "src/main/pty/process-retirement/posix-pty-foreground-group-libproc.test.ts": 46, "src/main/pty/process-retirement/posix-pty-foreground-group.test.ts": 89, "src/main/pty/process-retirement/posix-pty-process-groups.integration.test.ts": 215, - "src/main/pty/process-retirement/posix-pty-process-groups.test.ts": 134, "src/main/pty/process-retirement/posix-pty-process-table-event-loop.test.ts": 1212, "src/main/pty/process-retirement/pty-master-foreground-native.test.ts": 112, "src/main/pty/process-retirement/pty-master-foreground-observation.test.ts": 120, @@ -2343,7 +2269,6 @@ "src/main/rate-limits/codex-rate-limit-wsl-home-gate.test.ts": 105, "src/main/rate-limits/codex-rpc-worker-backpressure.test.ts": 615, "src/main/rate-limits/gemini-oauth-sources.test.ts": 97, - "src/main/rate-limits/grok-auth.test.ts": 105, "src/main/rate-limits/opencode-go-api-key-source.test.ts": 418, "src/main/rate-limits/opencode-go-status-parsing.test.ts": 57, "src/main/rate-limits/service-antigravity-usage.test.ts": 212, @@ -2395,7 +2320,6 @@ "src/main/runtime/agent-session/ownership/agent-session-reservation-admission.test.ts": 276, "src/main/runtime/agent-session/ownership/agent-session-surface-release-transition.test.ts": 144, "src/main/runtime/agent-session/ownership/structured-agent-session-spawn-token-descendants.test.ts": 2446, - "src/main/runtime/agent-session/records/agent-session-conversation-name-store.test.ts": 743, "src/main/runtime/agent-session/records/agent-session-record-store-slot.test.ts": 2353, "src/main/runtime/agent-session/records/agent-session-record-store-tab-table.test.ts": 808, "src/main/runtime/agent-session/records/agent-session-record-store.test.ts": 2452, @@ -2425,7 +2349,6 @@ "src/main/runtime/browser-host/leases/browser-host-lease-registry.test.ts": 184, "src/main/runtime/browser-host/reconciliation/browser-host-page-placement.test.ts": 169, "src/main/runtime/browser-host/reconciliation/browser-host-page-reconciliation-preconditions.test.ts": 129, - "src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts": 59, "src/main/runtime/browser/network/browser-network-tunnel-paired-runtime.integration.test.ts": 5293, "src/main/runtime/browser/screencast/browser-screencast-renderer-throttle-lease.test.ts": 5665, "src/main/runtime/browser/tabs/browser-session-tab-selection-snapshot.test.ts": 45, @@ -2631,7 +2554,6 @@ "src/main/runtime/orchestration/db/worker-dispatch/orchestration-worker-dispatch-db.test.ts": 804, "src/main/runtime/orchestration/db/schema/run-coordinator-handle-migration.test.ts": 675, "src/main/runtime/orchestration/db/runs/run-coordinator-orca-session-address.test.ts": 760, - "src/main/runtime/orchestration/turn-delivery/send-agent-turn-host.test.ts": 2586, "src/main/runtime/orchestration/workers/launch/setup-completion-signal.test.ts": 48, "src/main/runtime/orchestration/mailbox/structured-mail/structured-mail-source.test.ts": 693, "src/main/runtime/orchestration/structured-pointer-operation-id.test.ts": 61, @@ -2657,7 +2579,6 @@ "src/main/runtime/terminal/query/pty-shell-ownership-mirror.test.ts": 860, "src/main/runtime/push/desktop-push-service-unreadable-outbox.test.ts": 265, "src/main/runtime/push/desktop-push-service.test.ts": 317, - "src/main/runtime/push/push-delivery-policy.test.ts": 74, "src/main/runtime/push/push-gateway-client.test.ts": 280, "src/main/runtime/push/push-gateway-session.test.ts": 224, "src/main/runtime/push/push-host-proof-vector.test.ts": 65, @@ -2775,7 +2696,6 @@ "src/main/runtime/rpc/methods/orchestration/runs/migration-behavior.test.ts": 5762, "src/main/runtime/rpc/methods/orchestration/runs/multi-run-coordinator.test.ts": 4218, "src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts": 4589, - "src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts": 4854, "src/main/runtime/rpc/methods/orchestration/worker-start-card.test.ts": 7003, "src/main/runtime/rpc/methods/orchestration/worker/start/worker-start-composition.test.ts": 4775, "src/main/runtime/rpc/methods/orchestration/worker/observation/fleet-status-observed-identity.test.ts": 3493, @@ -2825,7 +2745,6 @@ "src/main/runtime/rpc/methods/structured-sessions/subscriptions/structured-agent-session-unsubscribe.test.ts": 5518, "src/main/runtime/rpc/methods/structured-sessions/attachments/structured-agent-session-visual.test.ts": 5180, "src/main/runtime/rpc/methods/session-tabs/structured-chat-tab-table.test.ts": 18947, - "src/main/runtime/rpc/methods/orchestration/structured-workers/structured-worker-read-cursor.test.ts": 1097, "src/main/runtime/rpc/methods/orchestration/structured-workers/structured-worker-stop-receipt.test.ts": 5349, "src/main/runtime/rpc/methods/orchestration/structured-workers/structured-worker-tab-retirement.test.ts": 4714, "src/main/runtime/rpc/methods/terminal/terminal-quick-command-client-capabilities.test.ts": 3556, @@ -2992,7 +2911,6 @@ "src/main/runtime/workspaces/lineage/runtime-worktree-lineage-controller.test.ts": 1027, "src/main/runtime/workspaces/startup/runtime-worktree-startup-readiness.test.ts": 289, "src/main/runtime/workspaces/process-listing/runtime-worktree-structured-agent-rows-liveness.test.ts": 1412, - "src/main/runtime/session-lifecycle/close/close-mobile-row-in-main-layout.test.ts": 4514, "src/main/runtime/session-lifecycle/projection/pane-sleeping-record.test.ts": 76, "src/main/runtime/session-lifecycle/projection/sleep-record-pane-claim.test.ts": 48, "src/main/runtime/session-tabs/session-tab-close-force.test.ts": 7089, @@ -3004,7 +2922,6 @@ "src/main/runtime/session-tabs/session-tabs-phone-layout-moves.test.ts": 4153, "src/main/runtime/session-tabs/session-tabs-windowed-main-change.test.ts": 4444, "src/main/runtime/orchestration/terminal-authority/settled-worker-process-replacement.test.ts": 5013, - "src/main/runtime/sidebar-inputs/cached-scan.test.ts": 106, "src/main/runtime/sidebar-inputs/catalog/desktop-sidebar-facts.test.ts": 378, "src/main/runtime/sidebar-inputs/temporal/orca-runtime-closed-tab-retention.test.ts": 5233, "src/main/runtime/sidebar-inputs/catalog/orca-runtime-project-catalog.test.ts": 4975, @@ -3081,7 +2998,6 @@ "src/main/runtime/terminal/identity/main-pane-record-arrival.test.ts": 5024, "src/main/runtime/terminal/identity/terminal-identity-placement-schedules.test.ts": 4255, "src/main/runtime/terminal/identity/terminal-identity-schedules.test.ts": 4334, - "src/main/runtime/terminal/input/agent-prompt-permission-hold.test.ts": 48, "src/main/runtime/terminal/launch/mobile-terminal-chat-fork.test.ts": 3900, "src/main/runtime/terminal/layout/agent-generated-tab-titles.test.ts": 5572, "src/main/runtime/terminal/lifecycle/main-pane-liveness.test.ts": 4871, @@ -3120,7 +3036,6 @@ "src/main/runtime/workspaces/catalog/wsl-moved-project-chat-runtime.test.ts": 5094, "src/main/updater/serve-update-handoff.test.ts": 62, "src/main/server/serve-readiness.test.ts": 52, - "src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts": 39, "src/main/pty/shell-startup/shell-wrapper-content-address.test.ts": 49, "src/main/source-control/hosted-review-azure-devops.integration.test.ts": 818, "src/main/source-control/hosted-review-base-ref-suffix.test.ts": 474, @@ -3558,13 +3473,11 @@ "src/renderer/src/components/activity/activity-portal-readiness-decay.react185.test.tsx": 228, "src/renderer/src/components/activity/activity-portal-readiness-loop.react185.test.tsx": 377, "src/renderer/src/components/activity/activity-portal-readiness-subscription-churn.react185.test.tsx": 315, - "src/renderer/src/components/activity/activity-search-query.test.tsx": 2286, "src/renderer/src/components/activity/activity-thread-list-pane.multi-select.test.tsx": 4699, "src/renderer/src/components/activity/useActivityUnreadCount.freshness.test.tsx": 1990, "src/renderer/src/components/activity/useActivityUnreadCount.test.ts": 1633, "src/renderer/src/components/agent-tab-shortcut-launch.test.ts": 369, "src/renderer/src/components/agent/AgentLaunchPickerMenu.search.test.tsx": 2090, - "src/renderer/src/components/artifacts/ArtifactCollection.test.tsx": 1833, "src/renderer/src/components/artifacts/ArtifactPublishButton.test.tsx": 706, "src/renderer/src/components/artifacts/ArtifactsPage.test.tsx": 2052, "src/renderer/src/components/artifacts/artifact-publish-flow.test.ts": 114, @@ -3619,13 +3532,10 @@ "src/renderer/src/components/browser-pane/restored-client-hosted-recovery-window.test.tsx": 6205, "src/renderer/src/components/browser-pane/stream-remote/remote-browser-page-input-model.test.ts": 45, "src/renderer/src/components/browser-pane/stream-remote/remote-browser-page-pane.address-bar.test.tsx": 2987, - "src/renderer/src/components/browser-pane/stream-remote/remote-browser-page-session.test.ts": 390, "src/renderer/src/components/browser-pane/stream-remote/remote-browser-service-failure.test.ts": 465, "src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-lifecycle.test.ts": 643, - "src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts": 54, "src/renderer/src/components/browser-pane/stream-remote/use-remote-browser-page-keyboard.test.tsx": 910, "src/renderer/src/components/browser-pane/stream-remote/use-remote-browser-page-navigation.test.ts": 2179, - "src/renderer/src/components/browser-pane/stream-remote/use-remote-browser-stream-activation.test.ts": 304, "src/renderer/src/components/browser-pane/use-ssh-workspace-browser-route.host-connection.test.tsx": 4005, "src/renderer/src/components/browser-pane/workspace-doc/HtmlDocPreview.failure-message.test.tsx": 3251, "src/renderer/src/components/browser-pane/workspace-doc/HtmlDocPreview.toolbar.test.tsx": 4357, @@ -3638,7 +3548,6 @@ "src/renderer/src/components/connect-dialog-outside-dismiss.test.tsx": 1125, "src/renderer/src/components/contextual-tours/ContextualTourOverlay.visibility.test.tsx": 2101, "src/renderer/src/components/crash-report/crash-report-submit-notice.test.ts": 208, - "src/renderer/src/components/crash-report/use-crash-report-copy.test.tsx": 425, "src/renderer/src/components/dashboard-popout/AgentKanbanBoard.test.tsx": 1004, "src/renderer/src/components/dashboard-popout/AgentTerminalDialog.test.tsx": 935, "src/renderer/src/components/dashboard-popout/AgentTerminalPreview.clipboard-routes.test.tsx": 2983, @@ -3656,9 +3565,7 @@ "src/renderer/src/components/dashboard/build-dashboard-bucket-counts.equivalence.test.ts": 722, "src/renderer/src/components/dashboard/build-dashboard-snapshot.test.ts": 2121, "src/renderer/src/components/dashboard/useRetainedAgents.test.ts": 2028, - "src/renderer/src/components/dictation/dictation-insertion-target.test.ts": 323, "src/renderer/src/components/dictation/use-hold-dictation-gesture.test.tsx": 249, - "src/renderer/src/components/diff-comments/DiffCommentDraftCard.test.tsx": 1988, "src/renderer/src/components/diff-comments/diff-comment-draft-zone.test.tsx": 2633, "src/renderer/src/components/diff-comments/diff-comment-line-range.test.ts": 49, "src/renderer/src/components/editor/check-details/panel/CheckRunDetailsPanel.copy.test.tsx": 3108, @@ -3675,7 +3582,6 @@ "src/renderer/src/components/editor/model-lifetime/retention/closed-editor-model-lifetime.test.ts": 7921, "src/renderer/src/components/editor/model-lifetime/retention/closed-editor-view-state-retention.test.ts": 9012, "src/renderer/src/components/editor/combined-diff/load-sections/combined-diff-metadata-retention.test.tsx": 1151, - "src/renderer/src/components/editor/combined-diff/remember-view/combined-diff-view-cache.test.ts": 45, "src/renderer/src/components/editor/combined-diff/review-controls/use-combined-diff-section-actions.disk-precondition.test.tsx": 2383, "src/renderer/src/components/editor/conflict-review-file-tree-windowing.test.tsx": 1487, "src/renderer/src/components/editor/csv/CsvViewer.editing.test.tsx": 3583, @@ -3732,7 +3638,6 @@ "src/renderer/src/components/editor/monaco-content-sync.undo-history.test.ts": 1108, "src/renderer/src/components/editor/monaco-editor-input-bindings.paste-capture.test.ts": 342, "src/renderer/src/components/editor/monaco-large-text-paste.crlf.test.ts": 2297, - "src/renderer/src/components/editor/markdown-source-tools/monaco/monaco-markdown-doc-completions-retention.test.ts": 1243, "src/renderer/src/components/editor/pdf-viewer-zoom-ownership.test.tsx": 789, "src/renderer/src/components/editor/plugin-custom-editor-host.test.ts": 480, "src/renderer/src/components/editor/rich-markdown/raw-source/raw-markdown-html-line-break.test.ts": 2188, @@ -3750,11 +3655,9 @@ "src/renderer/src/components/editor/rich-markdown/details/rich-markdown-details-keyboard.test.ts": 7747, "src/renderer/src/components/editor/rich-markdown/instance/rich-markdown-editor-config.test.ts": 2794, "src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-empty-paragraph-delete.test.ts": 224, - "src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-escape-fidelity.test.ts": 2650, "src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-extension-retention.test.ts": 6690, "src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-extension.test.ts": 282, "src/renderer/src/components/editor/rich-markdown/citations/rich-markdown-html-superscript-link.test.ts": 3769, - "src/renderer/src/components/editor/rich-markdown/images/rich-markdown-image-attributes.test.ts": 2412, "src/renderer/src/components/editor/rich-markdown/images/rich-markdown-image-context.test.ts": 676, "src/renderer/src/components/editor/rich-markdown/images/rich-markdown-image-cut.test.ts": 2685, "src/renderer/src/components/editor/rich-markdown/images/rich-markdown-image-insert-code-block.test.ts": 1078, @@ -3786,7 +3689,6 @@ "src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-trailing-paragraph.test.ts": 2437, "src/renderer/src/components/editor/use-custom-editor-outside-merge.test.tsx": 2069, "src/renderer/src/components/editor/model-lifetime/buffer-text/use-editor-content-change-handler.test.tsx": 2031, - "src/renderer/src/components/editor/markdown-preview/document-worker/use-markdown-preview-document.test.tsx": 326, "src/renderer/src/components/editor/markdown-preview/search/use-markdown-preview-search-reveal.test.tsx": 390, "src/renderer/src/components/editor/use-monaco-editor-mount.cursor-owner.test.tsx": 1332, "src/renderer/src/components/editor/use-monaco-editor-mount.stale-cache.test.tsx": 877, @@ -3822,7 +3724,6 @@ "src/renderer/src/components/github/github-work-item-mutation-target.test.ts": 348, "src/renderer/src/components/github/use-image-input.test.ts": 2619, "src/renderer/src/components/gitlab-item-dialog/use-gitlab-primary-actions.test.ts": 2141, - "src/renderer/src/components/jira-attachment-image.test.tsx": 2117, "src/renderer/src/components/jira-connect-scoped-token.test.tsx": 1047, "src/renderer/src/components/jira-issue-assignee-control.test.tsx": 2875, "src/renderer/src/components/jira-issue-transition-control.test.tsx": 1293, @@ -3836,13 +3737,10 @@ "src/renderer/src/components/mobile/WindowsFirewallNotice.test.tsx": 691, "src/renderer/src/components/mobile/use-mobile-page-paired-devices.test.ts": 475, "src/renderer/src/components/native-chat/markdown/code/NativeChatCodeBlock.test.tsx": 2775, - "src/renderer/src/components/native-chat/usage/NativeChatContextUsageRing.test.tsx": 781, - "src/renderer/src/components/native-chat/media/visuals/NativeChatInlineVisual.link-placement.test.tsx": 2477, "src/renderer/src/components/native-chat/prompts/NativeChatInteractiveCard.test.tsx": 2881, "src/renderer/src/components/native-chat/viewport/scroll/NativeChatJumpToLatest.test.tsx": 477, "src/renderer/src/components/native-chat/markdown/code/NativeChatMarkdown.code-wrap.test.tsx": 3123, "src/renderer/src/components/native-chat/markdown/NativeChatMarkdown.mermaid.test.tsx": 2372, - "src/renderer/src/components/native-chat/media/visuals/NativeChatMarkdown.visual.test.tsx": 2860, "src/renderer/src/components/native-chat/messages/reasoning/NativeChatMessageList.live-reasoning.test.tsx": 20337, "src/renderer/src/components/native-chat/NativeChatMessageList.new-rows-marker.test.tsx": 4304, "src/renderer/src/components/native-chat/viewport/scroll/NativeChatMessageList.scroll-behavior.test.tsx": 14260, @@ -3851,9 +3749,7 @@ "src/renderer/src/components/native-chat/usage/NativeChatNoticeRow.test.tsx": 3399, "src/renderer/src/components/native-chat/composer/editor/NativeChatPromptEditor.paragraph-selection.test.tsx": 652, "src/renderer/src/components/native-chat/composer/editor/NativeChatPromptEditor.test.tsx": 1110, - "src/renderer/src/components/native-chat/prompts/NativeChatQuestionCard.test.tsx": 762, "src/renderer/src/components/native-chat/queue/NativeChatQueuedMessageRows.test.tsx": 2691, - "src/renderer/src/components/native-chat/prompts/NativeChatResolutionReceipt.test.tsx": 912, "src/renderer/src/components/native-chat/media/images/NativeChatResolvedView.context-menu.test.tsx": 4025, "src/renderer/src/components/native-chat/surfaces/integration/NativeChatResolvedView.prompt-card-composer.test.tsx": 7151, "src/renderer/src/components/native-chat/prompts/NativeChatResolvedView.prompt-card-input.test.tsx": 3594, @@ -3864,7 +3760,6 @@ "src/renderer/src/components/native-chat/surfaces/integration/NativeChatStructuredSession.refusal-notices.test.tsx": 3014, "src/renderer/src/components/native-chat/surfaces/integration/NativeChatStructuredSession.test.tsx": 4459, "src/renderer/src/components/native-chat/tools/lines/NativeChatToolLine.test.tsx": 3544, - "src/renderer/src/components/native-chat/tools/lines/NativeChatToolOutput.test.tsx": 410, "src/renderer/src/components/native-chat/tools/runs/NativeChatToolRun.identity.test.tsx": 3269, "src/renderer/src/components/native-chat/tools/runs/NativeChatToolRun.test.tsx": 2988, "src/renderer/src/components/native-chat/tools/runs/NativeChatToolRunCallCounts.test.tsx": 2846, @@ -3878,7 +3773,6 @@ "src/renderer/src/components/native-chat/session/options/terminal/claude-model-switch-confirmation.test.ts": 1969, "src/renderer/src/components/native-chat/paste/inline-deferred-input.test.tsx": 2562, "src/renderer/src/components/native-chat/queue/editing/inline-queued-edit-lease.test.tsx": 2401, - "src/renderer/src/components/native-chat/viewport/rail/native-chat-active-rail-item.test.ts": 62, "src/renderer/src/components/native-chat/messages/agent-senders/native-chat-agent-message-sender-host.test.tsx": 8140, "src/renderer/src/components/native-chat/attachments/uploads/native-chat-attachment-upload.test.ts": 1614, "src/renderer/src/components/native-chat/conversation/slots/native-chat-compaction-visibility.test.ts": 363, @@ -3904,7 +3798,6 @@ "src/renderer/src/components/native-chat/composer/editor/native-chat-prompt-document-text.test.ts": 219, "src/renderer/src/components/native-chat/composer/editor/native-chat-prompt-document.test.ts": 459, "src/renderer/src/components/native-chat/queue/editing/native-chat-queued-edit-draft.test.ts": 649, - "src/renderer/src/components/native-chat/viewport/rail/native-chat-rail-outline-parity.test.ts": 497, "src/renderer/src/components/native-chat/attachments/uploads/native-chat-resolved-path-ownership.test.ts": 1749, "src/renderer/src/components/native-chat/session/terminal/assembly/native-chat-session-assembler.test.ts": 221, "src/renderer/src/components/native-chat/session/terminal/read/native-chat-session-transport.test.ts": 381, @@ -3922,18 +3815,12 @@ "src/renderer/src/components/native-chat/conversation/projection/structured-agent-session-transcript-order.test.ts": 294, "src/renderer/src/components/native-chat/session/attention/structured-attention-dispatch.test.ts": 1974, "src/renderer/src/components/native-chat/session/status/structured-chat-sleep-startup.test.tsx": 2285, - "src/renderer/src/components/native-chat/session/options/catalog/use-host-model-catalog-upgrade.test.tsx": 1968, - "src/renderer/src/components/native-chat/composer/focus/use-native-chat-composer-app-menu-selection.test.tsx": 313, "src/renderer/src/components/native-chat/attachments/chips/use-native-chat-composer-attachments.test.tsx": 2467, - "src/renderer/src/components/native-chat/attachments/chips/use-native-chat-composer-preview-lifetime.test.tsx": 1926, "src/renderer/src/components/native-chat/attachments/intake/use-native-chat-external-attachments.test.tsx": 797, - "src/renderer/src/components/native-chat/host-access/use-native-chat-host-outage.test.tsx": 2131, - "src/renderer/src/components/native-chat/drafts/use-native-chat-launch-draft-adoption.test.tsx": 319, "src/renderer/src/components/native-chat/session/terminal/read/use-native-chat-live-session-pending.test.ts": 2063, "src/renderer/src/components/native-chat/session/terminal/read/use-native-chat-live-session-visibility.test.ts": 2047, "src/renderer/src/components/native-chat/session/terminal/read/use-native-chat-live-session.test.ts": 2218, "src/renderer/src/components/native-chat/composer/pickers/use-native-chat-mention-files.test.tsx": 2162, - "src/renderer/src/components/native-chat/paste/use-native-chat-paste-lifetime.test.tsx": 567, "src/renderer/src/components/native-chat/paste/use-native-chat-pasted-text-file.test.tsx": 2385, "src/renderer/src/components/native-chat/session/terminal/delivery/use-native-chat-pending-delivery.test.tsx": 457, "src/renderer/src/components/native-chat/composer/pickers/use-native-chat-picker-state.test.tsx": 315, @@ -3942,12 +3829,9 @@ "src/renderer/src/components/native-chat/session/terminal/send/use-native-chat-send-lifecycle.test.tsx": 281, "src/renderer/src/components/native-chat/session/options/terminal/use-native-chat-session-options.test.ts": 1068, "src/renderer/src/components/native-chat/usage/use-structured-agent-session-context-usage.test.tsx": 2766, - "src/renderer/src/components/native-chat/session/options/structured/use-structured-agent-session-options.preloaded-agents.test.tsx": 1971, "src/renderer/src/components/native-chat/session/options/structured/use-structured-agent-session-options.recovery.test.tsx": 2874, - "src/renderer/src/components/native-chat/session/options/structured/use-structured-agent-session-options.test.tsx": 6047, "src/renderer/src/components/native-chat/prompts/use-structured-agent-session-question-answers.test.tsx": 2264, "src/renderer/src/components/native-chat/queue/editing/use-structured-agent-session-queued-edit.test.tsx": 3369, - "src/renderer/src/components/native-chat/queue/use-structured-agent-session-queued-reorder.test.tsx": 1795, "src/renderer/src/components/native-chat/session/structured/read/use-structured-agent-session-read.test.tsx": 3081, "src/renderer/src/components/native-chat/session/structured/use-structured-agent-session.clear-send.test.tsx": 2804, "src/renderer/src/components/native-chat/pane/actions/use-structured-native-chat-submit-reveal.test.ts": 2304, @@ -3964,30 +3848,22 @@ "src/renderer/src/components/plugins/declarative/PluginDeclarativeView.test.tsx": 2804, "src/renderer/src/components/plugins/dialogs/PluginUpdateAllDialog.test.tsx": 2313, "src/renderer/src/components/plugins/list/plugin-list-entries.test.ts": 231, - "src/renderer/src/components/plugins/page/PluginAddsSection.test.tsx": 2043, "src/renderer/src/components/plugins/page/PluginDetailPage.test.tsx": 3367, - "src/renderer/src/components/plugins/state/use-plugin-install-link.test.tsx": 518, "src/renderer/src/components/plugins/view/plugin-view-acts.test.tsx": 3241, "src/renderer/src/components/plugins/view/plugin-view-editor-shot-cleanup.test.ts": 59, "src/renderer/src/components/ports/WorkspacePortScanner.test.tsx": 2474, "src/renderer/src/components/pull-request-page/actions/merge-actions.test.ts": 383, "src/renderer/src/components/pull-request-page/cache/file-content.test.ts": 344, "src/renderer/src/components/pull-request-page/page/use-details.test.tsx": 745, - "src/renderer/src/components/quick-open-file-history.test.ts": 1716, "src/renderer/src/components/quick-open-file-list-host-name-filter.react.test.tsx": 1941, "src/renderer/src/components/quick-open-file-list.test.ts": 54, - "src/renderer/src/components/quick-open-recent-validation.test.ts": 213, - "src/renderer/src/components/render-phase-adjustment-discarded-render.test.tsx": 2577, "src/renderer/src/components/right-sidebar/ai-vault/session-list/AiVaultSessionHistoryDialog.test.tsx": 2796, "src/renderer/src/components/right-sidebar/ai-vault/session-list/AiVaultSessionVirtualList.measurement.test.tsx": 3117, "src/renderer/src/components/right-sidebar/FolderWorkspaceWorktreesPanel.test.tsx": 461, "src/renderer/src/components/right-sidebar/plugin-panels/PluginPanel.test.tsx": 2710, "src/renderer/src/components/right-sidebar/PortsPanel.test.tsx": 1618, "src/renderer/src/components/right-sidebar/source-control/ai/SourceControlAgentActionDialog.test.tsx": 2772, - "src/renderer/src/components/right-sidebar/ai-vault/accounts/ai-vault-account-native.test.tsx": 2785, "src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane.test.ts": 64, - "src/renderer/src/components/right-sidebar/ai-vault/scanning/ai-vault-panel-session-list-request.test.tsx": 3044, - "src/renderer/src/components/right-sidebar/ai-vault/session-list/ai-vault-session-filters.test.ts": 105, "src/renderer/src/components/right-sidebar/ai-vault/scope/ai-vault-session-projects.test.ts": 117, "src/renderer/src/components/right-sidebar/ai-vault/scanning/ai-vault-session-refresh.test.ts": 2034, "src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-resume-in-chat-workspace.test.ts": 746, @@ -3997,10 +3873,8 @@ "src/renderer/src/components/right-sidebar/file-explorer/mutations/file-explorer-delete-undo-precondition.test.tsx": 2023, "src/renderer/src/components/right-sidebar/file-explorer/watching/file-explorer-expanded-dirs-refresh.test.ts": 1962, "src/renderer/src/components/right-sidebar/file-explorer/mutations/file-explorer-inline-input-ime-enter.test.tsx": 479, - "src/renderer/src/components/right-sidebar/file-explorer/watching/file-explorer-linked-recovery.test.tsx": 2158, "src/renderer/src/components/right-sidebar/file-explorer/watching/file-explorer-linked-watch.test.ts": 1831, "src/renderer/src/components/right-sidebar/folder-workspace-attached-worktrees.test.ts": 70, - "src/renderer/src/components/right-sidebar/source-control/sync/git-status-refresh.test.ts": 553, "src/renderer/src/components/right-sidebar/hosted-review/folder-checks/parent-pr-checks-rows.test.ts": 374, "src/renderer/src/components/plugins/frames/plugin-frame-host-declarative.test.ts": 439, "src/renderer/src/components/right-sidebar/checks-panel/comments/pr-comments-ai-launch-ack.test.ts": 118, @@ -4011,15 +3885,12 @@ "src/renderer/src/components/right-sidebar/source-control/commit/use-commit-message-generation.cancel.test.ts": 1992, "src/renderer/src/components/right-sidebar/source-control/listing/open-uncommitted-entry.test.ts": 900, "src/renderer/src/components/right-sidebar/source-control/review/create-pr-intent-operation-target.test.ts": 1735, - "src/renderer/src/components/right-sidebar/ai-vault/search/use-ai-vault-search.test.tsx": 688, "src/renderer/src/components/right-sidebar/checks-panel/refresh/use-checks-panel-terminal-worktree.test.ts": 2116, "src/renderer/src/components/right-sidebar/source-control/sync/use-source-control-git-history.test.tsx": 1951, "src/renderer/src/components/right-sidebar/file-explorer/mutations/useFileDeletion.save-refusal.test.tsx": 840, "src/renderer/src/components/right-sidebar/file-explorer/mutations/useFileDeletion.trash-failure.test.tsx": 774, "src/renderer/src/components/right-sidebar/file-explorer/mutations/useFileExplorerImport.committed-scope.test.tsx": 588, - "src/renderer/src/components/right-sidebar/file-explorer/watching/useFileExplorerTree.stale-dirs.test.tsx": 1958, "src/renderer/src/components/right-sidebar/file-explorer/content-search/useFileSearchPanel.lifecycle.test.tsx": 2249, - "src/renderer/src/components/right-sidebar/source-control/listing/useSourceControlSubmoduleStatus.test.tsx": 2076, "src/renderer/src/components/settings/accounts/AccountsPane.owner-scope.test.tsx": 4057, "src/renderer/src/components/settings/agents/AgentsPane.test.tsx": 3230, "src/renderer/src/components/settings/browser/profiles/BrowserProfileRow.google-cookie-clear.test.tsx": 27636, @@ -4036,7 +3907,6 @@ "src/renderer/src/components/settings/appearance/fonts/FontAutocomplete.test.tsx": 1202, "src/renderer/src/components/settings/shortcuts/ShortcutsPane.provenance.test.tsx": 2302, "src/renderer/src/components/settings/repository/worktrees/SparsePresetSettingsSection.test.tsx": 744, - "src/renderer/src/components/settings/ssh/server-actions/SshHostDeltaMoveDialog.test.tsx": 438, "src/renderer/src/components/settings/tasks/TaskSourceSimpleSetup.test.tsx": 527, "src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts": 549, "src/renderer/src/components/settings/terminal/session-management/TerminalLimitSetting.test.tsx": 1015, @@ -4045,13 +3915,11 @@ "src/renderer/src/components/settings/accounts/usage/accounts-pane-opencode-credentials.test.ts": 519, "src/renderer/src/lib/agent-session/launch/agent-settings-update-queue.test.ts": 249, "src/renderer/src/components/agent/launch-settings/agent-default-env-draft.test.ts": 54, - "src/renderer/src/components/integrations/source-control/bitbucket-integration-card.test.tsx": 619, "src/renderer/src/components/settings/developer-permissions/developer-permissions-search.test.ts": 308, "src/renderer/src/components/settings/shortcuts/keybinding-diagnostic-text.test.ts": 522, "src/renderer/src/components/settings/shortcuts/keybinding-title-copy.test.ts": 227, "src/renderer/src/components/settings/notifications/notification-host-pending-save.test.tsx": 2029, "src/renderer/src/components/settings/repository/RepositoryJiraProjectSection.test.tsx": 463, - "src/renderer/src/components/settings/repository/hosts/RepositoryHostSetupsSection.settings-entry.test.tsx": 2007, "src/renderer/src/components/settings/repository/worktrees/RepositoryWorktreeDefaultsSection.test.tsx": 495, "src/renderer/src/components/settings/repository/identity/RepositoryIconPicker.github-avatar-refresh.test.tsx": 615, "src/renderer/src/components/settings/source-control/source-control-action-card-layout.test.tsx": 4551, @@ -4062,8 +3930,6 @@ "src/renderer/src/components/session-search/use-session-search-status.test.tsx": 477, "src/renderer/src/components/settings/accounts/usage/use-zcode-plan-credentials.test.tsx": 880, "src/renderer/src/components/shared/kill-all-terminal-surfaces.test.ts": 1925, - "src/renderer/src/components/sidebar/host-admission/ssh/AddRemoteHostDialog.config-picker.test.tsx": 1178, - "src/renderer/src/components/sidebar/project-admission/dialog/AddRepoDialogChrome.test.tsx": 714, "src/renderer/src/components/sidebar/workspace-card/identity/AutoRenameFailedDialog.test.tsx": 2254, "src/renderer/src/components/sidebar/CommentMarkdown.code-block-renderer.test.tsx": 2109, "src/renderer/src/components/sidebar/CommentMarkdown.math-loading.test.tsx": 2249, @@ -4075,39 +3941,26 @@ "src/renderer/src/components/sidebar/host-path-browser/RemoteFileBrowser.keyboard.test.tsx": 825, "src/renderer/src/components/sidebar/Sidebar.test.tsx": 833, "src/renderer/src/components/sidebar/SidebarAgentsList.test.tsx": 2985, - "src/renderer/src/components/sidebar/StalledTerminalDaemonBanner.test.tsx": 320, "src/renderer/src/components/sidebar/workspace-card/surface/WorktreeCard.single-reference-details.test.tsx": 2032, "src/renderer/src/components/sidebar/workspace-actions/context-menu/WorktreeContextMenu.closed-menu-work.test.tsx": 1753, "src/renderer/src/components/sidebar/worktree-list/listing/WorktreeList.lineage-agent-expansion-coupling.test.tsx": 5388, - "src/renderer/src/components/sidebar/workspace-card/metadata/WorktreeMetaDialog.test.tsx": 7694, "src/renderer/src/components/sidebar/workspace-visibility/dialog/WorktreeVisibilityDialog.test.tsx": 2602, "src/renderer/src/components/sidebar/chat-markdown-math-typeset.test.ts": 1336, - "src/renderer/src/components/sidebar/workspace-actions/deletion/delete-worktree-flow.test.ts": 1014, "src/renderer/src/components/sidebar/workspace-actions/deletion/delete-worktree-parallel-flow.test.ts": 938, "src/renderer/src/components/sidebar/workspace-card/review/folder-workspace-card-pr-display.test.ts": 377, "src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-expiry.test.tsx": 2558, "src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit-host-platform.test.ts": 2264, "src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit.test.ts": 2665, "src/renderer/src/components/sidebar/project-move-pause-follower.test.ts": 938, - "src/renderer/src/components/sidebar/worktree-list/listing/rendered-sidebar-worktree-order.test.ts": 1873, "src/renderer/src/components/sidebar/workspace-board/projection/use-workspace-board-task-status-sync.queued.test.ts": 1022, - "src/renderer/src/components/sidebar/workspace-board/selection/use-workspace-kanban-selection.test.tsx": 243, "src/renderer/src/components/sidebar/workspace-card/review/use-workspace-reference-details.test.tsx": 1335, "src/renderer/src/components/sidebar/workspace-card/activity/use-worktree-agent-rows-subscriptions.test.tsx": 3635, "src/renderer/src/components/sidebar/useRenderedSetupScriptPromptState.test.ts": 623, - "src/renderer/src/components/sidebar/workspace-card/activity/useWorktreeAgentRows.test.ts": 450, "src/renderer/src/components/sidebar/workspace-board/projection/workspace-board-task-status-sync.test.ts": 378, "src/renderer/src/components/sidebar/workspace-actions/deletion/workspace-delete-lineage.test.ts": 51, "src/renderer/src/components/sidebar/workspace-board/search/workspace-kanban-search.test.ts": 176, - "src/renderer/src/components/sidebar/workspace-card/review/workspace-reference-detail-read.test.ts": 662, "src/renderer/src/components/sidebar/workspace-card/review/workspace-reference-refresh-targets.test.ts": 945, - "src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-activity-summary.test.ts": 577, - "src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-orchestration-index.test.ts": 443, - "src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-row-selectors.test.ts": 376, "src/renderer/src/components/sidebar/worktree-list/drag/worktree-lineage-drag-drop.test.ts": 200, - "src/renderer/src/components/sidebar/worktree-list/grouping/worktree-list-groups-lineage-nesting.test.ts": 241, - "src/renderer/src/components/sidebar/worktree-list/grouping/worktree-list-groups-project-host-setups.test.ts": 280, - "src/renderer/src/components/sidebar/worktree-list/grouping/worktree-list-groups-project-order.test.ts": 1861, "src/renderer/src/components/sidebar/worktree-list/drag/pointer-flush.test.ts": 517, "src/renderer/src/components/sidebar/worktree-list/listing/host-status-isolation.test.tsx": 3404, "src/renderer/src/components/sidebar/worktree-list/listing/pending-worktree-creation-keys.test.ts": 42, @@ -4116,8 +3969,6 @@ "src/renderer/src/components/sidebar/worktree-list/navigation/use-keyboard.reveal.test.tsx": 1691, "src/renderer/src/components/sidebar/worktree-list/rows/repo-header-ssh-isolation.test.tsx": 2945, "src/renderer/src/components/sidebar/worktree-list/rows/section-header-create-host.test.tsx": 2393, - "src/renderer/src/components/sidebar/worktree-list/drag/worktree-manual-order-store-write.test.ts": 2144, - "src/renderer/src/components/sidebar/workspace-actions/parenting/worktree-parent-eligibility.test.ts": 68, "src/renderer/src/components/skills/sharing/SkillSharedLinkRow.test.tsx": 817, "src/renderer/src/components/skills/SkillsPage.test.tsx": 3822, "src/renderer/src/components/status-bar/ClaudeSwitcherMenu.owner-lifetime.test.tsx": 2317, @@ -4137,7 +3988,6 @@ "src/renderer/src/components/status-bar/use-resource-pty-actions.test.tsx": 879, "src/renderer/src/components/tab-bar/CopyTabIdMenuItem.test.tsx": 428, "src/renderer/src/components/tab-bar/TabBarCreateEntry.search.test.tsx": 3224, - "src/renderer/src/components/tab-bar/TabBarQuickCommandItem.test.tsx": 384, "src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.virtualization.test.tsx": 1644, "src/renderer/src/components/tab-bar/cli-chat-resume-close-terminal.test.ts": 598, "src/renderer/src/components/tab-bar/cli-chat-resume-run-close.test.ts": 3079, @@ -4151,7 +4001,6 @@ "src/renderer/src/components/tab-bar/tab-strip-pointer-activation.test.tsx": 2047, "src/renderer/src/components/tab-bar/use-agent-picker-refused-wake.test.tsx": 271, "src/renderer/src/components/tab-bar/use-new-tab-agent-menu-host-preferences.test.tsx": 3234, - "src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows-owner.test.tsx": 1828, "src/renderer/src/components/tab-bar/use-sortable-tab-context-menu.test.ts": 261, "src/renderer/src/components/tab-bar/use-tab-bar-quick-command-search-input.test.tsx": 536, "src/renderer/src/components/tab-group/RetainedPaneHost.test.tsx": 340, @@ -4164,7 +4013,6 @@ "src/renderer/src/components/task-page/github/task-page-github-work-item-mutation-regressions.test.ts": 140, "src/renderer/src/components/task-page/github/task-page-github-work-item-mutations.test.ts": 169, "src/renderer/src/components/task-page/github/use-task-page-github-issue-creation.test.tsx": 1769, - "src/renderer/src/components/task-page/gitlab/use-task-page-gitlab-loading.test.tsx": 1504, "src/renderer/src/components/task-page/jira/Content.board-owner.test.tsx": 2582, "src/renderer/src/components/task-page/jira/task-page-jira-board-detail-integration.test.tsx": 2192, "src/renderer/src/components/task-page/jira/task-page-jira-board-view.test.tsx": 2287, @@ -4176,9 +4024,7 @@ "src/renderer/src/components/task-page/task-page-work-item-pagination.test.ts": 63, "src/renderer/src/components/terminal-pane/layout/close/RunningTerminalCloseDialog.test.tsx": 2303, "src/renderer/src/components/terminal-pane/account-restart/detached/account-restart-queue-progress.test.ts": 1988, - "src/renderer/src/components/terminal-pane/agent-completion/agent-completion-coordinator-attention-dispatch.test.ts": 301, "src/renderer/src/components/terminal-pane/agent-completion/agent-completion-coordinator-completion-replay-guard.test.ts": 318, - "src/renderer/src/components/terminal-pane/agent-completion/agent-completion-coordinator-hook-done-quiet-window.test.ts": 328, "src/renderer/src/components/terminal-pane/agent-completion/agent-completion-coordinator-hook-title-precedence.test.ts": 280, "src/renderer/src/components/terminal-pane/agent-completion/agent-completion-coordinator-process-cadence.test.ts": 326, "src/renderer/src/components/terminal-pane/agent-completion/agent-completion-coordinator-process-exit-turn-boundary.test.ts": 284, @@ -4189,7 +4035,6 @@ "src/renderer/src/components/terminal-pane/agent-status/input-inference/agent-interrupt-inference.test.ts": 146, "src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.test.ts": 1195, "src/renderer/src/components/terminal-pane/account-restart/detached/claude-detached-pane-restart.test.ts": 1938, - "src/renderer/src/components/terminal-pane/provider-notices/claude-diff-panel/claude-diff-panel-notice-banner.test.tsx": 1986, "src/renderer/src/components/terminal-pane/notifications/claude-side-question-completion.test.ts": 2305, "src/renderer/src/components/terminal-pane/provider-notices/codex-server-isolation/codex-shared-server-banner.test.tsx": 2766, "src/renderer/src/components/terminal-pane/pty-connection/output/deferred-reattach-live-data-queue.test.ts": 184, @@ -4208,7 +4053,6 @@ "src/renderer/src/components/terminal-pane/pty-transport/legacy-relay/legacy-relay-bridge-transport.test.ts": 358, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/paired-reconnect-multi-pane-materialization.test.ts": 1040, "src/renderer/src/components/terminal-pane/pty-connection/agent-identity/foreground-process/pane-foreground-agent-tracker.test.ts": 486, - "src/renderer/src/components/terminal-pane/pty-connection/agent-identity/foreground-process/pane-foreground-inspect-observation-identity.test.ts": 226, "src/renderer/src/components/terminal-pane/pty-connection/agent-identity/foreground-process/pane-foreground-process-exit-retire.test.ts": 329, "src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.test.ts": 352, "src/renderer/src/components/terminal-pane/layout/close/pending-pane-close-confirmation.test.ts": 4695, @@ -4233,14 +4077,11 @@ "src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-restored-baseline-shortfall.test.ts": 1902, "src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-visible-pane-output-pause-latch.test.ts": 1639, "src/renderer/src/components/terminal-pane/pty-connection/reattach/deferred-session-reattach-startup-snapshot.test.ts": 1830, - "src/renderer/src/components/terminal-pane/pty-connection/reattach/deferred-session-reattach-wsl-distro-stopped-hold.test.ts": 2517, "src/shared/terminal/protocol/escape/terminal-synchronized-output-socket-splits.test.ts": 92, "src/renderer/src/components/terminal-pane/pty-connection/startup/main-pane-resume-banner.test.ts": 59, "src/renderer/src/components/terminal-pane/pty-connection/spawn/main-pane-start-wait.test.ts": 76, "src/renderer/src/components/terminal-pane/pty-connection/serialization/pane-serializer-register.test.ts": 123, "src/renderer/src/components/terminal-pane/pty-connection/output-restore/snapshot-covered-terminal-queries.test.ts": 150, - "src/renderer/src/components/terminal-pane/pty-connection/host-ownership/unserved-ssh-pane-bridge.test.ts": 70, - "src/renderer/src/components/terminal-pane/pty-transport/delivery/pty-dispatcher-delivery-resync.test.ts": 85, "src/renderer/src/components/terminal-pane/pty-transport/delivery/pty-dispatcher-pi-routing.test.ts": 1362, "src/renderer/src/components/terminal-pane/pty-transport/input/pty-input-write-queue.test.ts": 787, "src/renderer/src/components/terminal-pane/pty-transport/output/pty-output-processor-program-activity.test.ts": 160, @@ -4250,21 +4091,17 @@ "src/renderer/src/components/terminal-pane/pty-transport/input/pty-preconnect-input-retention.test.ts": 86, "src/renderer/src/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-suspension.test.ts": 60, "src/renderer/src/components/terminal-pane/pty-transport/shutdown/pty-shutdown-exit-deferral.test.ts": 121, - "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-detach-attach-handoff.test.ts": 1199, "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-eager-buffer-replay.test.ts": 1636, "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-handler-suspension.test.ts": 1243, "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-input-write.test.ts": 3927, "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-output-side-effects.test.ts": 1128, "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-reattach-admission.test.ts": 1636, "src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-recycled-pty-incarnation.test.ts": 787, - "src/renderer/src/components/terminal-pane/input/focus/regular-terminal-focus-ownership.test.ts": 208, - "src/renderer/src/components/terminal-pane/layout/persistence/remote-pane-layout-push.test.ts": 77, "src/renderer/src/components/terminal-pane/pty-connection/output-restore/remote-park-reveal-unverifiable-retry.test.ts": 1546, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-disconnected-input-grace-retry.test.ts": 1366, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/output/remote-runtime-pty-batching.test.ts": 108, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-query-reply-immediate.test.ts": 1556, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-activation-inventory-fallback.test.ts": 1311, - "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-end-verdict.test.ts": 942, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-expired-pane-recovery.test.ts": 1763, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-input-coalescing.test.ts": 2777, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-input-replay.test.ts": 7130, @@ -4274,7 +4111,6 @@ "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-snapshot-replay.test.ts": 1717, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stale-handle-recovery.test.ts": 1882, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-stream-reconnect.test.ts": 4148, - "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-unmounted-host-pane.test.ts": 626, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport-unpublished-host-graph.test.ts": 1435, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/input/remote-runtime-recovery-input-hold.test.ts": 342, "src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-saved-result-consumer.test.ts": 3650, @@ -4283,19 +4119,14 @@ "src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-replay.test.ts": 3010, "src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-history-seam.test.ts": 2093, "src/renderer/src/components/terminal-pane/layout/split/resolve-split-cwd.test.ts": 56, - "src/renderer/src/components/terminal-pane/viewport/split-right-white-screen.test.ts": 53, - "src/renderer/src/components/terminal-pane/viewport/visibility/stale-document-visibility.test.ts": 88, "src/renderer/src/components/terminal-pane/input/paste/terminal-agent-paste-bracketing.test.ts": 329, "src/renderer/src/components/terminal-pane/input/paste/terminal-bracketed-paste.test.ts": 57, "src/renderer/src/components/terminal-pane/emulation/terminal-capability-replies.test.ts": 131, "src/renderer/src/components/terminal-pane/clipboard/terminal-clipboard-paste.test.ts": 76, "src/renderer/src/components/terminal-pane/input/file-drop/terminal-drop-runtime-catalog-owner.test.ts": 872, - "src/renderer/src/components/terminal-pane/viewport/terminal-fit-restore.test.ts": 59, "src/renderer/src/components/terminal-pane/links/handles/terminal-handle-links.test.ts": 527, - "src/renderer/src/components/terminal-pane/parking/retention/terminal-hidden-view-parking.test.ts": 325, "src/renderer/src/components/terminal-pane/emulation/terminal-idle-cursor-reset.test.ts": 190, "src/renderer/src/components/terminal-pane/input/ime/terminal-ime-composer-placeholder-mask.test.ts": 871, - "src/renderer/src/components/terminal-pane/input/ime/terminal-ime-deferred-newline.test.ts": 244, "src/renderer/src/components/terminal-pane/input/ime/terminal-ime-forwarder-space-claim.test.ts": 257, "src/renderer/src/components/terminal-pane/input/ime/terminal-ime-hangul-syllable-flush.test.ts": 877, "src/renderer/src/components/terminal-pane/input/ime/terminal-ime-hangul-terminating-digit.test.ts": 545, @@ -4325,7 +4156,6 @@ "src/renderer/src/components/terminal-pane/links/files/terminal-link-provider-link-detection.test.ts": 951, "src/renderer/src/components/terminal-pane/links/files/terminal-link-provider-markdown.test.ts": 1480, "src/renderer/src/components/terminal-pane/links/gestures/terminal-link-pty-mouse-suppression.test.ts": 574, - "src/renderer/src/components/terminal-pane/links/files/terminal-link-same-id-ssh-file-host.test.ts": 879, "src/renderer/src/components/terminal-pane/input/keyboard/terminal-option-kitty-release.test.ts": 52, "src/renderer/src/components/terminal-pane/input/file-drop/terminal-pane-element-file-drop.test.tsx": 1748, "src/renderer/src/components/terminal-pane/layout/reconciliation/terminal-pane-frame-reconciliation.test.ts": 903, @@ -4333,7 +4163,6 @@ "src/renderer/src/components/terminal-pane/layout/detach/terminal-pane-tab-detach-main-commit.test.ts": 2090, "src/renderer/src/components/terminal-pane/layout/detach/terminal-pane-tab-detach-main-move.test.ts": 2147, "src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-tab-watchers.test.ts": 473, - "src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-watcher-sleep-preserved-exit.test.ts": 399, "src/renderer/src/components/terminal-pane/parking/output-watchers/terminal-parked-watcher-sole-newborn-exit.test.ts": 402, "src/renderer/src/components/terminal-pane/emulation/terminal-parser-handler-guard.test.ts": 55, "src/renderer/src/components/terminal-pane/input/paste/terminal-paste-coordinator.test.ts": 155, @@ -4354,14 +4183,11 @@ "src/renderer/src/components/terminal-quick-commands/TerminalQuickCommandDialog.test.tsx": 1916, "src/renderer/src/components/terminal-search-long-wrapped-line.test.ts": 4708, "src/renderer/src/components/terminal-search-safe-find.test.ts": 45, - "src/renderer/src/components/terminal-startup-hold-placeholder.test.tsx": 952, "src/renderer/src/components/terminal-workspace-keydown.test.ts": 2213, - "src/renderer/src/components/terminal/activation-deferred-tab-admission.test.ts": 1761, "src/renderer/src/components/terminal/active-terminal-repair-loop.react185.test.tsx": 1998, "src/renderer/src/components/terminal/background-terminal-worktree-mount.test.ts": 1707, "src/renderer/src/components/terminal/initial-terminal-structured-launch.test.tsx": 786, "src/renderer/src/components/terminal/running-terminal-close-guard.test.ts": 99, - "src/renderer/src/components/terminal/startup-terminal-tab-hold.test.ts": 2118, "src/renderer/src/components/terminal/terminal-close-incarnation.test.ts": 42, "src/renderer/src/components/terminal/terminal-tab-actions-unified-close.test.ts": 1831, "src/renderer/src/components/terminal/terminal-tab-actions-unrouted-close.test.ts": 589, @@ -4369,7 +4195,6 @@ "src/renderer/src/components/terminal/use-terminal-provider-snapshot-capability.test.tsx": 573, "src/renderer/src/components/terminal/window-close-running-work.test.ts": 97, "src/renderer/src/components/ui/menu-pointer-highlight.test.tsx": 350, - "src/renderer/src/components/ui/menu-pointer-submenu-handoff.test.tsx": 514, "src/renderer/src/components/ui/popover-wheel-scroll.test.tsx": 501, "src/renderer/src/components/use-github-task-search-commit.test.ts": 255, "src/renderer/src/components/use-jira-create-assignee.test.tsx": 271, @@ -4390,7 +4215,6 @@ "src/renderer/src/components/worktree-jump/WorktreeJumpPalette.recent-tabs.behavior.test.tsx": 4445, "src/renderer/src/components/worktree-jump/WorktreeJumpPalette.test.tsx": 4442, "src/renderer/src/components/worktree-jump/worktree-jump-palette-browser-navigation.test.tsx": 4470, - "src/renderer/src/components/wsl-move/wsl-move-dialog-store.test.ts": 2011, "src/renderer/src/components/wsl-move/wsl-move-scope-rows.test.ts": 156, "src/renderer/src/hooks/agent-hook-completion-grok-notifications.test.ts": 679, "src/renderer/src/hooks/agent-hook-completion-notifications.test.ts": 1131, @@ -4409,7 +4233,6 @@ "src/renderer/src/hooks/editor-external-watch-background-trim.test.ts": 363, "src/renderer/src/hooks/editor-external-watch-dirty-resync.test.ts": 973, "src/renderer/src/hooks/editor-external-watch-overflow.test.ts": 1023, - "src/renderer/src/hooks/editor-external-watch-selected-host.test.ts": 1988, "src/renderer/src/hooks/editor-runtime-file-watch.test.ts": 58, "src/renderer/src/hooks/ipc-events/agent-status-pane-routing-index-retention.test.ts": 4878, "src/renderer/src/hooks/ipc-events/agent-status-terminal-title-tab-write.test.ts": 2247, @@ -4431,14 +4254,10 @@ "src/renderer/src/hooks/ipc-events/worktree-event-lineage-refresh.test.ts": 2309, "src/renderer/src/hooks/ipc-events/worktree-event-runtime-activation.test.ts": 1934, "src/renderer/src/hooks/ipc-events/wsl-host-ipc-bridge-capability.test.ts": 1917, - "src/renderer/src/hooks/ipc-tab-switch-group-order-hydration.test.ts": 797, - "src/renderer/src/hooks/macos-tcc-prompt-notice-subscription.test.ts": 52, "src/renderer/src/hooks/metadata-request-cache.test.ts": 144, "src/renderer/src/hooks/runtime-client-events-sync-ownership.test.ts": 59, "src/renderer/src/hooks/runtime-project-refresh-scheduler.test.ts": 65, "src/renderer/src/hooks/unpaired-device-auth-notification.test.ts": 41, - "src/renderer/src/hooks/use-list-multi-selection.test.tsx": 545, - "src/renderer/src/hooks/use-now.test.ts": 270, "src/renderer/src/hooks/use-os-file-drop-owner.test.tsx": 401, "src/renderer/src/hooks/use-window-stream-visibility.test.ts": 289, "src/renderer/src/hooks/useAutomationDispatchEvents.test.ts": 788, @@ -4446,9 +4265,7 @@ "src/renderer/src/hooks/useDetectedAgents.host-reconnect.test.tsx": 2044, "src/renderer/src/hooks/useDetectedAgents.local-invalidation.test.tsx": 2246, "src/renderer/src/hooks/useDetectedAgents.re-pair.test.tsx": 1959, - "src/renderer/src/hooks/useDetectedAgents.ssh-reconnect.test.tsx": 2194, "src/renderer/src/hooks/useDetectedAgents.test.tsx": 1907, - "src/renderer/src/hooks/useEditorExternalWatch-background-trim.test.tsx": 238, "src/renderer/src/hooks/useEditorExternalWatch-self-move.test.ts": 2029, "src/renderer/src/hooks/useEditorExternalWatch-shared-root.test.tsx": 872, "src/renderer/src/hooks/useEditorExternalWatch-subscriptions.test.tsx": 266, @@ -4456,7 +4273,6 @@ "src/renderer/src/hooks/useEditorExternalWatch-targets.test.ts": 599, "src/renderer/src/hooks/useEditorExternalWatch.test.ts": 2099, "src/renderer/src/hooks/useEphemeralVmRecipeOptions.test.tsx": 415, - "src/renderer/src/hooks/useGitHubSlugMetadata.assignee-reuse.test.tsx": 233, "src/renderer/src/hooks/useImmediateMutation.test.ts": 618, "src/renderer/src/hooks/skills/discovery/useInstalledAgentSkills.react.test.tsx": 2093, "src/renderer/src/hooks/useIpcEvents-agent-status-connection-attribution.test.ts": 5510, @@ -4469,12 +4285,8 @@ "src/renderer/src/hooks/useIssueMetadata.test.tsx": 344, "src/renderer/src/hooks/clipboard/primary-selection/usePrimarySelectionPaste.terminal-native-paste.test.tsx": 388, "src/renderer/src/hooks/clipboard/primary-selection/usePrimarySelectionPaste.test.tsx": 411, - "src/renderer/src/hooks/useReadOnScreenAttention.away.test.ts": 2420, - "src/renderer/src/hooks/useReadOnScreenAttention.clock-skew.test.ts": 2093, "src/renderer/src/hooks/useReadOnScreenAttention.floating-panel.test.ts": 2157, - "src/renderer/src/hooks/useReadOnScreenAttention.focus-group.test.ts": 2090, "src/renderer/src/hooks/useReadOnScreenAttention.mixed-workspace.test.ts": 1725, - "src/renderer/src/hooks/virtualized-hidden-row-measurement.test.ts": 199, "src/renderer/src/hooks/worktree-change-refresh-queue.test.ts": 59, "src/renderer/src/i18n/I18nProvider.test.tsx": 2101, "src/renderer/src/i18n/language-catalog-timeout.test.tsx": 2025, @@ -4499,21 +4311,17 @@ "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-exited-owner.test.ts": 1289, "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-options.test.ts": 991, "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-persistence.test.ts": 386, - "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-probe-outage.test.ts": 1891, "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-record.test.ts": 151, "src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery-perf.test.ts": 1708, "src/shared/agent-status/contracts/agent-status-evidence-clock.test.ts": 88, "src/shared/agent-status/title/agent-title-tracker.test.ts": 172, "src/renderer/src/lib/agent-session/resume/history/ai-vault-antigravity-reference-host.test.ts": 678, "src/renderer/src/lib/agent-session/resume/history/ai-vault-session-drag.test.ts": 68, - "src/renderer/src/lib/agent-session/resume/history/ai-vault-session-resume-preparation.test.ts": 408, "src/renderer/src/lib/agent-session/history/title-sync/ai-vault-tab-title-sync-inputs.test.ts": 476, "src/renderer/src/lib/clipboard/menu/app-menu-paste.test.ts": 229, "src/renderer/src/lib/automation-terminal-ownership.test.ts": 1795, - "src/renderer/src/lib/browser/navigation/browser-link-destination.test.ts": 1839, "src/renderer/src/lib/browser/navigation/browser-link-open.test.ts": 2215, "src/renderer/src/lib/browser/navigation/browser-link-profile-isolation.test.ts": 2511, - "src/renderer/src/lib/browser/palette/browser-page-palette-activation.test.ts": 1983, "src/renderer/src/lib/browser/palette/browser-palette-page-entries.test.ts": 480, "src/renderer/src/lib/skills/runtime/bundled-skill-target.test.ts": 54, "src/renderer/src/lib/source-control/checks/check-run-details-log-normalization-performance.test.ts": 846, @@ -4524,7 +4332,6 @@ "src/renderer/src/lib/composer-submit-cancellation.test.ts": 41, "src/renderer/src/lib/workspace/ownership/connection-context.test.ts": 1817, "src/renderer/src/lib/create-untitled-markdown.test.ts": 566, - "src/renderer/src/lib/workspace/ownership/direct-ssh-target-scope.test.ts": 48, "src/renderer/src/lib/editor/file-operations/editor-file-operation-owner.test.ts": 2848, "src/renderer/src/lib/emulator-error-copy.test.ts": 415, "src/renderer/src/lib/text-input/ime/ime-composition-keyboard-event.test.ts": 274, @@ -4545,7 +4352,6 @@ "src/renderer/src/lib/simulator/launch/open-mobile-emulator-tab.test.ts": 545, "src/renderer/src/lib/pane-manager/pane-drag-window-blur.test.ts": 618, "src/renderer/src/lib/pane-manager/pane-layout-geometry-apply.test.ts": 897, - "src/renderer/src/lib/pane-manager/pane-manager-registry.test.ts": 69, "src/renderer/src/lib/pane-manager/pane-manager-spawn-placement.test.ts": 766, "src/renderer/src/lib/pane-manager/terminal-output/pane-terminal-output-queue-chunks.test.ts": 44, "src/renderer/src/lib/pane-manager/pane-tree-match-moves.test.ts": 662, @@ -4566,7 +4372,6 @@ "src/renderer/src/lib/review-owner.test.ts": 238, "src/renderer/src/lib/runtime-host-copy.test.ts": 317, "src/renderer/src/lib/simulator/launch/simulator-launch-coordination.test.ts": 43, - "src/renderer/src/lib/simulator/search/simulator-palette-search.test.ts": 515, "src/renderer/src/lib/simulator/tabs/simulator-pane-shutdown-scheduler.test.ts": 1679, "src/renderer/src/lib/simulator/tabs/simulator-tab-layout-owner.test.ts": 2398, "src/renderer/src/lib/simulator/tabs/simulator-tab-palette-activation.test.ts": 1903, @@ -4577,7 +4382,6 @@ "src/renderer/src/lib/task-provider-error-copy.test.ts": 363, "src/renderer/src/lib/text-input/paste/text-control-paste.test.ts": 222, "src/renderer/src/lib/text-generation-error-copy.test.ts": 466, - "src/renderer/src/lib/workspace/activation/workspace-activation-path-gate.test.ts": 2107, "src/renderer/src/lib/browser/workspace/workspace-browser-tab-open-placement.test.ts": 1996, "src/renderer/src/lib/workspace/persistence/workspace-session-host-emptied-fields.test.ts": 279, "src/renderer/src/lib/workspace/persistence/workspace-session-ssh-partition-ownership.test.ts": 309, @@ -4628,15 +4432,10 @@ "src/renderer/src/runtime/workspace-layout/server/server-layout-editor-handover.test.ts": 5075, "src/renderer/src/runtime/workspace-layout/server/server-layout-frames-handover.test.ts": 1991, "src/renderer/src/runtime/workspace-layout/server/server-layout-frames.test.ts": 2053, - "src/renderer/src/runtime/native-chat/host-capabilities/structured-chat-host-permission.test.ts": 523, - "src/renderer/src/runtime/web-session-tabs-sync/placement/structured-conversation-tab-replacement.test.ts": 2029, "src/renderer/src/runtime/sync-runtime-graph/sync-runtime-graph-chat-tab-order.test.ts": 529, "src/renderer/src/runtime/sync-runtime-graph/sync-runtime-graph-conversion-publish.test.ts": 1608, "src/renderer/src/runtime/sync-runtime-graph/sync-runtime-graph-workspace-publication.test.ts": 513, - "src/renderer/src/runtime/sync-runtime-graph/mirrored-editor-tab-republication.test.ts": 1025, - "src/renderer/src/runtime/sync-runtime-graph/terminal-group-grid-sizes.test.ts": 194, "src/renderer/src/runtime/browser/creation/web-runtime-browser-link-open.test.ts": 2217, - "src/renderer/src/runtime/web-session-tabs-sync/tracking/web-session-tabs-removed-frame-retires-live-publisher.test.ts": 854, "src/renderer/src/runtime/web-session-tabs-sync/subscriptions/web-session-tabs-stream-end-resubscribe.test.tsx": 2282, "src/renderer/src/runtime/web-session-tabs-sync/navigation/web-session-tabs-sync-focus-intent.test.ts": 892, "src/renderer/src/runtime/web-session-tabs-sync/agent-status/web-session-tabs-sync-host-tab-retraction-ghost-rows.test.ts": 1956, @@ -4647,13 +4446,11 @@ "src/renderer/src/runtime/web-session-tabs-sync/subscriptions/web-session-tabs-sync-worktree-switch.test.tsx": 2625, "src/renderer/src/runtime/web-session-tabs-sync/navigation/web-session-tabs-sync.test.ts": 1006, "src/renderer/src/runtime/web-session-tabs-sync/frame-drawn-server-workspaces.test.ts": 956, - "src/renderer/src/runtime/hosted-terminals/recovery/inventory/web-session-terminal-orphan-absence-across-republication.test.ts": 678, "src/renderer/src/runtime/hosted-terminals/recovery/web-session-terminal-orphan-mixed-version.test.ts": 923, "src/renderer/src/runtime/hosted-terminals/recovery/panes/web-session-terminal-pending-handle-recovery.test.ts": 723, "src/renderer/src/runtime/hosted-terminals/recovery/evidence/web-session-terminal-retirement-proof-ledger.test.ts": 685, "src/renderer/src/runtime/rpc/subscriptions/window-visibility-subscription-parking-stream-end.test.ts": 225, "src/renderer/src/startup/startup-degraded-recovery.test.ts": 574, - "src/renderer/src/startup/startup-ssh-connection-restore.test.ts": 71, "src/renderer/src/store/slices/editor/buffers/editor-buffer-record-lifecycle.test.ts": 1794, "src/renderer/src/store/github/checks/check-details-failure-mapping.test.ts": 887, "src/renderer/src/store/github/projects/project-field-mutations.test.ts": 2100, @@ -4664,14 +4461,11 @@ "src/renderer/src/store/repos/dropped-repo-worktree-rows.test.ts": 1738, "src/renderer/src/store/repos/repo-removal.test.ts": 799, "src/renderer/src/store/repos/wsl-moved-local-session-rows.test.ts": 319, - "src/renderer/src/store/repos/wsl-moved-repo-ui-retention.test.ts": 2920, - "src/renderer/src/store/slices/editor/focus/active-selection-owner-scoping.test.ts": 1909, "src/renderer/src/store/slices/agent-status/agent-status-pane-owner-reclaim.test.ts": 1899, "src/renderer/src/store/slices/agent-status/agent-status-ack-cleanup.test.ts": 1776, "src/renderer/src/store/slices/agent-status/agent-status-batch.test.ts": 1933, "src/renderer/src/store/slices/agent-status/agent-status-drop-ipc.test.ts": 2205, "src/renderer/src/store/slices/agent-status/agent-status-entry-contracts.test.ts": 1875, - "src/renderer/src/store/slices/agent-status/agent-status-freshness-scheduler.test.ts": 58, "src/renderer/src/store/slices/agent-status/agent-status-live-map-leak.test.ts": 4389, "src/renderer/src/store/slices/agent-status/agent-status-manual-sleep-capture.test.ts": 1756, "src/renderer/src/store/slices/agent-status/agent-status-provider-session.test.ts": 1874, @@ -4696,11 +4490,9 @@ "src/renderer/src/store/slices/editor/closing/editor-close-background-file.test.ts": 893, "src/renderer/src/store/slices/editor/closing/editor-close-document-siblings.test.ts": 1317, "src/renderer/src/store/slices/editor/closing/editor-close-file-stale-active.test.ts": 1806, - "src/renderer/src/store/slices/editor/closing/editor-close-workspace-selection.test.ts": 1850, "src/renderer/src/store/slices/editor/file-ids/editor-file-rename-twin-layout-owner.test.ts": 2090, "src/renderer/src/store/slices/editor/tabs/editor-layout-owner-records.test.ts": 2006, "src/renderer/src/store/slices/editor/markdown/editor-markdown-link-activation.test.ts": 953, - "src/renderer/src/store/slices/editor/tabs/editor-preview-tab-setting.test.ts": 1952, "src/renderer/src/store/slices/editor/opening/editor-read-only-tabs.test.ts": 901, "src/renderer/src/store/slices/editor/focus/editor-set-active-file-guard.test.ts": 895, "src/renderer/src/store/slices/editor/buffers/editor-buffer-reconcile-identity.test.ts": 1775, @@ -4739,7 +4531,6 @@ "src/renderer/src/store/slices/worktrees/session/selected-host-active-workspace-identity.test.ts": 1661, "src/renderer/src/store/slices/runtime-status/set-runtime-environments-purge-wiring.test.ts": 1683, "src/renderer/src/store/slices/settings/settings-terminal-quick-commands.test.ts": 1734, - "src/renderer/src/lib/workspace/activation/active-worktree-removal-successor.test.ts": 1867, "src/renderer/src/store/terminals/store-create-tab-start-in-main.test.ts": 1801, "src/renderer/src/store/slices/tabs/store-open-to-side-layout-owner.test.ts": 1919, "src/renderer/src/store/terminals/store-sleep-exact-runtime-stop.test.ts": 1842, @@ -4747,7 +4538,6 @@ "src/renderer/src/store/slices/worktrees/teardown/tab-worktree-orphan-map-purge-leak.test.ts": 1936, "src/renderer/src/store/slices/tabs/tabs-close-dangling-group.test.ts": 1849, "src/renderer/src/store/slices/tabs/tabs-hydration-group-validation.test.ts": 249, - "src/renderer/src/store/slices/tabs/structured-chat-close-owner.test.ts": 1866, "src/renderer/src/store/slices/tabs/tabs-reconciliation-empty-groups.test.ts": 1703, "src/renderer/src/store/terminals/terminal-pty-identity-replacement.test.ts": 1751, "src/renderer/src/store/terminals/terminal-quick-command-hosts.test.ts": 1759, @@ -4757,18 +4547,14 @@ "src/renderer/src/store/slices/ui/ui-modal-slot-dismissal.test.ts": 662, "src/renderer/src/store/slices/workspace-attention/workspace-unread-flag-host-raises.test.ts": 1914, "src/renderer/src/store/slices/workspace-attention/workspace-unread-on-screen-characterization.test.ts": 1780, - "src/renderer/src/store/slices/workspace-attention/workspace-unread-screen-moves-characterization.test.ts": 1884, "src/renderer/src/store/slices/worktrees/teardown/workspace-chat-draft-removal.test.ts": 1896, "src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-browse.test.ts": 69, - "src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-enrichment-performance.test.ts": 995, "src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-removal-preflight.test.ts": 750, - "src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-scan-progress.test.ts": 1207, "src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-unverified-removal-consent.test.ts": 639, "src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-wrong-host-removal-guard.test.ts": 1800, "src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-wrong-host-removal.test.ts": 1909, "src/renderer/src/store/slices/ui/workspace-document-title-refresh.test.ts": 1630, "src/renderer/src/store/terminals/worktree-sleep-intent-lifecycle.test.ts": 1764, - "src/renderer/src/store/slices/settings/worktree-visibility-settings-write.test.ts": 307, "src/renderer/src/store/slices/worktrees/teardown/worktrees-always-force-delete.test.ts": 1611, "src/renderer/src/store/slices/worktrees/create/worktrees-create-captured-host.test.ts": 1148, "src/renderer/src/store/slices/worktrees/listing/worktrees-fetch-refresh-coalescing.test.ts": 1226, @@ -4777,7 +4563,6 @@ "src/renderer/src/store/slices/worktrees/listing/worktrees-fetch-stale-catalog-version.test.ts": 1337, "src/renderer/src/store/slices/worktrees/metadata/worktrees-git-identity-branch-title.test.ts": 1181, "src/renderer/src/store/slices/worktrees/listing/worktrees-hydration-purge.test.ts": 1274, - "src/renderer/src/store/slices/worktrees/listing/worktrees-runtime-connection-generation-fence.test.ts": 1240, "src/renderer/src/store/slices/worktrees/session/worktrees-terminal-reference-source-race.test.ts": 1063, "src/renderer/src/store/slices/worktrees/host-scoped-row-merges.test.ts": 1805, "src/renderer/src/store/slices/worktrees/listing/stale-listing-purges-created-worktree.test.ts": 1828, @@ -4788,7 +4573,6 @@ "src/renderer/src/store/terminals/structured-chat-tab-rename.test.ts": 3154, "src/renderer/src/store/terminals/terminal-no-op-subscriber.test.ts": 1763, "src/renderer/src/store/terminals/terminal-startup-queue-restart.test.ts": 1895, - "src/renderer/src/store/slices/runtime-status/views/use-runtime-status-view.test.tsx": 1979, "src/renderer/src/store/workspace-layout/workspace-layout-cache.test.ts": 63, "src/renderer/src/store/slices/worktrees/listing/worktree-host-collision-index.test.ts": 1875, "src/renderer/src/web/preload-api/web-agent-session-attachment-upload.test.ts": 1588, @@ -4796,7 +4580,6 @@ "src/renderer/src/web/preload-api/web-runtime-calls-connection-pin.test.ts": 51, "src/renderer/src/web/preload-api/web-ui-compact-notice.test.ts": 1192, "src/renderer/src/web/preload-api/web-ui-explorer-root.test.ts": 880, - "src/renderer/src/web/web-clipboard-copy-terminal-selection.test.ts": 176, "src/renderer/src/web/web-device-key.test.ts": 74, "src/renderer/src/web/web-file-mutation-methods.test.ts": 462, "src/renderer/src/web/web-file-write-disk-precondition.test.ts": 555, @@ -5005,17 +4788,14 @@ "src/shared/git/diff/git-change-list.test.ts": 133, "src/shared/git/remotes/git-clone-failure-message.test.ts": 63, "src/shared/git/commands/git-config-snapshot-runner.test.ts": 59, - "src/shared/git/remotes/git-configured-branch-target.test.ts": 58, "src/shared/git/diff/git-diff-transport-budget.test.ts": 479, "src/shared/git/paths/git-discard-path-safety.test.ts": 58, "src/shared/git/fetch/git-fetch-head-lock-key-derivation.test.ts": 128, "src/shared/git/fetch/git-fetch-head-lock.test.ts": 72, - "src/shared/git/history/git-history-graph.test.ts": 111, "src/shared/git/history/git-history-real-repository.test.ts": 758, "src/shared/git/history/git-history.test.ts": 92, "src/shared/git/metadata/git-metadata-path.test.ts": 63, "src/shared/git/objects/git-object-quarantine.test.ts": 89, - "src/shared/git/commands/git-progress-records.test.ts": 168, "src/shared/git/remotes/git-remote-error.test.ts": 88, "src/shared/git/remotes/git-remote-identity.test.ts": 56, "src/shared/git/remotes/git-remote-url-index.test.ts": 47, @@ -5073,7 +4853,6 @@ "src/shared/linear/issue-attribute-filter.test.ts": 49, "src/shared/linear/issue-view-resume-state.test.ts": 80, "src/shared/linear/links.test.ts": 58, - "src/shared/linear/workspace-types.test.ts": 47, "src/shared/linux-wayland-session.test.ts": 46, "src/shared/local-build-compatibility.test.ts": 46, "src/shared/local-windows-terminal-runtime.test.ts": 41, @@ -5134,7 +4913,6 @@ "src/shared/network/manual-address.test.ts": 68, "src/shared/new-workspace-dialog-repo.test.ts": 50, "src/shared/new-workspace/smart-workspace-url-source-results.test.ts": 67, - "src/shared/new-workspace/workspace-source.test.ts": 68, "src/shared/node-bounded-file-reader-sync.test.ts": 56, "src/shared/node-bounded-file-reader-window.test.ts": 63, "src/shared/node-bounded-file-reader.test.ts": 67, @@ -5222,7 +5000,6 @@ "src/shared/plugins/manifest/plugin-manifest.test.ts": 234, "src/shared/plugins/view/plugin-editor-shot-acts.test.ts": 112, "src/shared/plugins/workers/plugin-hook-chain.test.ts": 182, - "src/shared/posix-wait-status.test.ts": 40, "src/shared/powershell-native-argument.test.ts": 34, "src/shared/powershell-native-argument.windows.test.ts": 67, "src/shared/source-control/checks/pr-checks-fix-prompt.test.ts": 93, @@ -5263,7 +5040,6 @@ "src/shared/quick-open-transport-budget.test.ts": 42, "src/shared/raster-image-dimensions.test.ts": 50, "src/shared/raster-image-preview-limits.test.ts": 44, - "src/shared/relay-frame-buffer.test.ts": 295, "src/shared/relay-version-marker.test.ts": 52, "src/shared/release-channel.test.ts": 63, "src/shared/remote-execution-host-pty-id.test.ts": 49, @@ -5288,7 +5064,6 @@ "src/shared/remote-runtime/requests/remote-runtime-request-connection-stale.test.ts": 228, "src/shared/remote-runtime/requests/remote-runtime-request-connection.test.ts": 10491, "src/shared/remote-runtime/requests/remote-runtime-request-frames.test.ts": 127, - "src/shared/remote-runtime/requests/remote-runtime-request-websocket.test.ts": 237, "src/shared/remote-runtime/requests/remote-runtime-shared-control-subscription-start.test.ts": 122, "src/shared/remote-runtime/requests/remote-runtime-shared-control-subscriptions.test.ts": 115, "src/shared/remote-runtime/requests/remote-runtime-subscription-connect-bound.test.ts": 556, @@ -5433,7 +5208,6 @@ "src/shared/windows-transient-lock-removal.test.ts": 198, "src/shared/work-item-empty-page.test.ts": 70, "src/shared/worker-auto-close.test.ts": 60, - "src/shared/worker-transcript-background-task-text.test.ts": 46, "src/shared/workspace-attachments/workspace-attachment-mutation.test.ts": 101, "src/shared/workspace-attachments/workspace-attachment-normalization.test.ts": 76, "src/shared/workspace-attachments/workspace-attachment-origins.test.ts": 42, diff --git a/config/scripts/desktop-distribution/runtime-verification/electron-builder-config.test.mjs b/config/scripts/desktop-distribution/runtime-verification/electron-builder-config.test.mjs index 0bdb3207208..4e2683a31ed 100644 --- a/config/scripts/desktop-distribution/runtime-verification/electron-builder-config.test.mjs +++ b/config/scripts/desktop-distribution/runtime-verification/electron-builder-config.test.mjs @@ -5,8 +5,7 @@ import { createRequire } from 'node:module' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { promisify } from 'node:util' -import { afterAll, beforeAll, describe, expect, it } from 'vitest' -import { writeMobileWebBundleFixtureTree } from '../../build/mobile-web-app/mobile-web-bundle-fixture-tree.mjs' +import { describe, expect, it } from 'vitest' const REPO_ROOT = join(import.meta.dirname, '../../..', '..') @@ -71,12 +70,6 @@ describe('electron-builder config', () => { } }) - // All-negation lists implicitly include **/*; missing examples exclusion shipped hostile-panel in 1.4.160-rc.3. Exercise real matcher, not pattern spelling. - - // CI never creates ~270MB/branch out/electron-dev caches; only local packages exposed this bloat. - - // Duplicated relay.js added 14MB to asar and AV quarantine gutted the entire archive (#20966); packaged app uses resources/relay. - // Bundled agent-browser answered "No skills found" because only its binary shipped (#17705). const hostBuilderPlatform = { darwin: 'mac', linux: 'linux', win32: 'win' }[process.platform] it.runIf(hostBuilderPlatform)( @@ -114,84 +107,4 @@ describe('electron-builder config', () => { } } ) - - // CLI Node mode cannot read asar; packed entry sends orca serve to Electron (#27307). - - // Swept one-time /tmp asar extracts cause web-client 500s and phone bundle failures until restart (#27976). - - it('validates each AppImage before electron-builder publishes it', async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-electron-builder-appimage-')) - try { - const appImage = join(root, 'orca-linux.AppImage') - await writeFile(appImage, 'not an ELF') - await chmod(appImage, 0o755) - - expect(() => - electronBuilderConfig.artifactBuildCompleted({ file: appImage, arch: 1 }) - ).toThrow(/ELF header is outside/) - expect(() => - electronBuilderConfig.artifactBuildCompleted({ file: join(root, 'orca-ide.deb') }) - ).not.toThrow() - } finally { - await rm(root, { recursive: true, force: true }) - } - }) -}) - -describe('arch-aware packaging guard', () => { - // electron-builder Arch enum: ia32=0, x64=1, armv7l=2, arm64=3. - const HOST_ARCH = process.arch === 'arm64' ? 3 : 1 - - // Native tests need valid mobile bundle for beforePack; use temp build, leaving bundle verification to its own suite. - let scratch - let bundleDir - beforeAll(async () => { - scratch = await mkdtemp(join(tmpdir(), 'orca-electron-builder-guard-')) - bundleDir = join(scratch, 'mobile-web') - await writeMobileWebBundleFixtureTree({ outDir: bundleDir }) - }) - afterAll(async () => { - await rm(scratch, { recursive: true, force: true }) - }) - - const packHost = (arch) => - electronBuilderConfig.beforePack( - { electronPlatformName: process.platform, arch }, - bundleDir, - () => undefined - ) - - it('refuses to package a dark layout-owner build', () => { - const previous = process.env.ORCA_LAYOUT_OWNER - process.env.ORCA_LAYOUT_OWNER = 'main' - try { - expect(() => packHost(HOST_ARCH)).toThrow('ORCA_LAYOUT_OWNER=main') - } finally { - if (previous === undefined) { - delete process.env.ORCA_LAYOUT_OWNER - } else { - process.env.ORCA_LAYOUT_OWNER = previous - } - } - }) - - it('refuses to package an orcad template marked by a dark test build', async () => { - const templateDir = join(scratch, 'orcad-template') - await mkdir(templateDir, { recursive: true }) - await writeFile(join(templateDir, 'ORCA_LAYOUT_OWNER_MAIN'), 'dark\n') - try { - expect(() => - electronBuilderConfig.beforePack( - { electronPlatformName: process.platform, arch: HOST_ARCH }, - bundleDir, - () => undefined, - templateDir - ) - ).toThrow(`${templateDir} holds an ORCA_LAYOUT_OWNER=main build`) - } finally { - await rm(templateDir, { recursive: true, force: true }) - } - }) - - // The host's own build is the foreign-arch case: a Windows checkout compiles these for its CPU only. }) diff --git a/config/scripts/release/publication/create-draft-release.test.mjs b/config/scripts/release/publication/create-draft-release.test.mjs index f58ff25bc79..776d68d6ee4 100644 --- a/config/scripts/release/publication/create-draft-release.test.mjs +++ b/config/scripts/release/publication/create-draft-release.test.mjs @@ -15,7 +15,6 @@ const draft = { id: 259, draft: true, tag_name: tag, body: 'original notes' } function fixture(options = {}) { const writes = [] - const reads = [] let wrote = false const response = (body, status = 200) => ({ ok: status === 200, @@ -27,7 +26,6 @@ function fixture(options = {}) { const fetchImpl = async (url, request = {}) => { const route = url.replace('https://api.github.com/repos/test/repo', '') const method = request.method ?? 'GET' - reads.push(route) if (route === `/git/ref/tags/${tag}`) { if (options.missing || (wrote && options.deleted)) { return response({}, 404) @@ -72,7 +70,6 @@ function fixture(options = {}) { } return { writes, - reads, run: () => createDraftRelease({ repo: 'test/repo', @@ -114,14 +111,6 @@ describe('release draft source and uploader contract', () => { } ) - it('peels the captured tag object ID instead of re-dereferencing the tag name', async () => { - const f = fixture({ annotated: true }) - await f.run() - expect(f.reads).toContain(`/git/tags/${tagObject}`) - expect(f.reads).toContain(`/git/commits/${checkout}`) - expect(f.reads.some((route) => route.startsWith('/commits/'))).toBe(false) - }) - it.each([ { missing: true }, { annotated: true, commit: 'e'.repeat(40) }, @@ -187,31 +176,10 @@ describe('release draft source and uploader contract', () => { const workflow = parse(readFileSync('.github/workflows/release-cut.yml', 'utf8')) describe('release-cut draft wiring', () => { - it('passes the approved source and only the job token to the helper', () => { - const job = workflow.jobs['create-release'] - const step = job.steps.find((s) => s.id === 'draft') - expect(step.env).toMatchObject({ - SOURCE_SHA: '${{ needs.cut.outputs.source_sha }}', - GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}' - }) - expect(job.outputs.tag_object).toBe('${{ steps.draft.outputs.tag_object }}') - }) - - it('isolates both real-process skill release suites', () => { - for (const name of ['skill-sharing-release-gate', 'skill-sharing-linux-floor-release-gate']) { - const step = workflow.jobs[name].steps.find((s) => s.name?.startsWith('Run skill package')) - expect(step.env.ORCA_VITEST_ISOLATE_EVERY_FILE).toBe('1') - } - }) - const steps = workflow.jobs['publish-release'].steps const guardIndex = steps.findIndex( (s) => s.name === 'Verify release tag still matches the drafted source' ) - it('re-checks the tag immediately before undrafting', () => { - expect(steps[guardIndex + 1].name).toBe('Publish release') - expect(workflow.jobs['publish-release'].needs).toContain('create-release') - }) it.skipIf(process.platform === 'win32').each([ ['lightweight tag unchanged', { type: 'commit', sha: checkout }, checkout, 0], diff --git a/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs b/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs index eb9221657a8..4588ca9e003 100644 --- a/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs +++ b/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs @@ -110,14 +110,11 @@ const NODE_RUNTIME_INCLUDE = [ 'src/main/pty/process-retirement/posix-pty-process-groups.integration.test.ts', 'src/shared/remote-runtime/ephemeral-vm-recipes/ephemeral-vm-recipe-output-capture.test.ts', 'src/main/native-chat/agent-session-journal/**/*.test.ts', - 'src/main/runtime/agent-session/records/agent-session-conversation-name-store.test.ts', 'src/main/runtime/rpc/methods/structured-sessions/attachments/structured-agent-session-visual.test.ts', // Bun resolves 'ws' to its built-in client, which bypasses the patched package. 'src/main/runtime/rpc/transports/websocket/ws-empty-payload-frame-write.test.ts', 'src/shared/remote-runtime/remote-runtime-client.test.ts', 'src/shared/remote-runtime/remote-runtime-connect-bound.test.ts', - // Bun's built-in ws client ignores maxPayload; the product opener only runs on Node. - 'src/shared/remote-runtime/requests/remote-runtime-request-websocket.test.ts', 'src/shared/remote-runtime/requests/remote-runtime-subscription-connect-bound.test.ts', 'src/main/codex/configuration/shared-server/codex-shared-server-probe.test.ts', 'src/main/opencode/model-launch/opencode-launch-model-context-supervision.test.ts', diff --git a/config/scripts/workflow/source-routing/pr-package-test-paths.mjs b/config/scripts/workflow/source-routing/pr-package-test-paths.mjs index 026151e55a8..16b9fac7b1f 100644 --- a/config/scripts/workflow/source-routing/pr-package-test-paths.mjs +++ b/config/scripts/workflow/source-routing/pr-package-test-paths.mjs @@ -166,7 +166,6 @@ export const WINDOWS_BOUNDARY_TESTS = [ 'src/shared/agent-launch/startup/omp-fresh-launch-cmd.win32.test.ts', 'src/shared/windows-batch-spawn.win32.test.ts', 'src/main/claude/structured/launch/claude-structured-child-env.test.ts', - 'src/main/agent-hooks/installation/commands/windows-hook-payload-delivery.test.ts', 'src/main/jcode/hook-gate-script.test.ts', 'src/main/agent-hooks/installation/commands/windows-native-hook-exe-hosts.test.ts', 'src/main/agent-hooks/installation/commands/windows-batch-hook-launcher.test.ts', diff --git a/mobile/src/components/bottom-drawer/use-bottom-drawer-follow-up.test.tsx b/mobile/src/components/bottom-drawer/use-bottom-drawer-follow-up.test.tsx deleted file mode 100644 index a6cb1b1fe64..00000000000 --- a/mobile/src/components/bottom-drawer/use-bottom-drawer-follow-up.test.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { createElement, useState } from 'react' -import { act, create, type ReactTestRenderer } from 'react-test-renderer' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { BottomDrawer } from './BottomDrawer' -import { MountedBottomDrawer } from './mounted-bottom-drawer' -import { useBottomDrawerFollowUp } from './use-bottom-drawer-follow-up' - -// BottomDrawer also carries the option pager, which loads these at import. -vi.mock('react-native', () => ({ StyleSheet: { create: (sheet: T) => sheet }, View: 'View' })) -vi.mock('react-native-reanimated', async () => - (await import('../../test-support/reanimated-pager-stub')).reanimatedPagerStub() -) -vi.mock('./mounted-bottom-drawer', () => ({ MountedBottomDrawer: 'MountedBottomDrawer' })) - -describe('drawer handoff', () => { - let renderer: ReactTestRenderer | undefined - let handoff: ReturnType | undefined - function Harness() { - const [visible, setVisible] = useState(true) - handoff = useBottomDrawerFollowUp(() => setVisible(false)) - return ( - - Source - - ) - } - function mount() { - act(() => { - renderer = create(createElement(Harness)) - }) - } - afterEach(() => act(() => renderer?.unmount())) - - it('opens the next surface once, after the source drawer has unmounted', () => { - mount() - const next = vi.fn(() => expect(renderer?.toJSON()).toBeNull()) - act(() => handoff?.closeThen(next)) - expect(next).not.toHaveBeenCalled() - expect(renderer?.toJSON()).not.toBeNull() - const onHidden = renderer?.root.findByType(MountedBottomDrawer).props.onHidden - act(() => onHidden()) - act(() => onHidden()) - expect(next).toHaveBeenCalledTimes(1) - }) - - it('drops queued work when its screen unmounts', () => { - mount() - const next = vi.fn() - const afterClose = handoff?.drawerProps.onAfterClose - act(() => handoff?.closeThen(next)) - act(() => renderer?.unmount()) - act(() => afterClose?.()) - expect(next).not.toHaveBeenCalled() - }) -}) diff --git a/mobile/src/diagnostics/connection-diagnostics-submission.test.ts b/mobile/src/diagnostics/connection-diagnostics-submission.test.ts deleted file mode 100644 index d0bac63d1d6..00000000000 --- a/mobile/src/diagnostics/connection-diagnostics-submission.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { boundConnectionDiagnosticsReport } from './connection-diagnostics-submission' - -describe('submitConnectionDiagnostics', () => { - it('preserves the newest complete events when bounding a UTF-8 report', () => { - const report = [ - 'Orca Mobile connection diagnostics', - 'State: reconnecting', - '', - 'Recent connection history (3 events, oldest first):', - `oldest ${'😀'.repeat(20)}`, - `middle ${'😀'.repeat(20)}`, - `newest ${'😀'.repeat(20)}` - ].join('\n') - - const bounded = boundConnectionDiagnosticsReport(report, 180) - - expect(new TextEncoder().encode(bounded).byteLength).toBeLessThanOrEqual(180) - expect(bounded).toContain('newest') - expect(bounded).not.toContain('oldest') - expect(bounded).toMatch(/older omitted/) - }) - - it('retains a bounded form of the newest event when that event exceeds the budget', () => { - const report = [ - 'Orca Mobile connection diagnostics', - 'State: reconnecting', - '', - 'Recent connection history (2 events, oldest first):', - 'old event', - `newest oversized ${'😀'.repeat(1_000)}` - ].join('\n') - - const bounded = boundConnectionDiagnosticsReport(report, 220) - - expect(new TextEncoder().encode(bounded).byteLength).toBeLessThanOrEqual(220) - expect(bounded).toContain('newest oversized') - expect(bounded).toContain('[truncated]') - }) -}) diff --git a/mobile/src/home/tabs/home-usage-cards.test.ts b/mobile/src/home/tabs/home-usage-cards.test.ts deleted file mode 100644 index 2c5d9145d90..00000000000 --- a/mobile/src/home/tabs/home-usage-cards.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { AccountProviderRateLimits, AccountsSnapshot } from '../../accounts/accounts-snapshot' -import { selectHomeUsageCards } from './home-usage-cards' - -function limits( - provider: 'claude' | 'codex', - usedPercent: number, - overrides: Partial = {} -): AccountProviderRateLimits { - return { - provider, - session: { usedPercent, windowMinutes: 300, resetsAt: null, resetDescription: null }, - weekly: null, - updatedAt: 1_000, - error: null, - status: 'ok', - ...overrides - } -} - -function snapshot(overrides: { - claude?: Partial - codex?: Partial - rateLimits?: Partial -}): AccountsSnapshot { - return { - claude: { accounts: [], activeAccountId: null, ...overrides.claude }, - codex: { accounts: [], activeAccountId: null, ...overrides.codex }, - rateLimits: { - claude: null, - codex: null, - claudeTarget: { runtime: 'host', wslDistro: null }, - codexTarget: { runtime: 'host', wslDistro: null }, - inactiveClaudeAccounts: [], - inactiveCodexAccounts: [], - ...overrides.rateLimits - } - } -} - -describe('selectHomeUsageCards', () => { - it('lists the active managed account first, with no System default, and inactive usage from its own fetch', () => { - const cards = selectHomeUsageCards( - snapshot({ - claude: { - accounts: [ - { id: 'a', email: 'a@example.com', organizationName: 'Acme' }, - { id: 'b', email: 'b@example.com' } - ], - activeAccountId: 'b' - }, - rateLimits: { - claude: limits('claude', 70), - inactiveClaudeAccounts: [ - { accountId: 'a', rateLimits: limits('claude', 10), updatedAt: 1, isFetching: true } - ] - } - }), - 'claude' - ) - expect( - cards.map((card) => [ - card.email, - card.subtitle, - card.active, - card.limits?.session?.usedPercent, - card.fetching - ]) - ).toEqual([ - ['b@example.com', null, true, 70, false], - ['a@example.com', 'Acme', false, 10, true] - ]) - }) - - it('reads the Codex active account for the rate-limit runtime target', () => { - const cards = selectHomeUsageCards( - snapshot({ - codex: { - accounts: [ - { id: 'host', email: 'host@example.com', updatedAt: 1, workspaceLabel: 'Team' }, - { id: 'wsl', email: 'wsl@example.com', updatedAt: 1 } - ], - activeAccountId: 'host', - activeAccountIdsByRuntime: { host: 'host', wsl: { Ubuntu: 'wsl' } } - }, - rateLimits: { codexTarget: { runtime: 'wsl', wslDistro: 'Ubuntu' } } - }), - 'codex' - ) - expect(cards.map((card) => [card.accountId, card.subtitle, card.active])).toEqual([ - ['wsl', null, true], - ['host', 'Team', false] - ]) - }) -}) diff --git a/mobile/src/hooks/use-active-worktree-scroll.test.tsx b/mobile/src/hooks/use-active-worktree-scroll.test.tsx deleted file mode 100644 index db0c9b00076..00000000000 --- a/mobile/src/hooks/use-active-worktree-scroll.test.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { createElement } from 'react' -import { act, create, type ReactTestRenderer } from 'react-test-renderer' -import { describe, expect, it, vi } from 'vitest' -import { useActiveWorktreeScroll } from './use-active-worktree-scroll' - -type Row = { row: { worktreeId: string; isActive?: boolean } } -type Sections = { key: string; data: Row[] }[] - -const listOf = (active: string | null, folded = false): Sections => [ - { - key: 'all', - data: folded - ? [] - : ['a', 'b', 'c'].map((worktreeId) => ({ - row: { worktreeId, isActive: worktreeId === active } - })) - } -] - -const NONE = new Set() -const FOLDED = new Set(['all']) - -function mount(sections: Sections, collapsedGroups: ReadonlySet = NONE) { - const scrollToLocation = vi.fn() - function Probe(props: { sections: Sections; collapsedGroups: ReadonlySet }): null { - const { sectionListRef } = useActiveWorktreeScroll(props.sections, props.collapsedGroups) - Object.assign(sectionListRef, { current: { scrollToLocation } }) - return null - } - let renderer: ReactTestRenderer | null = null - act(() => { - renderer = create(createElement(Probe, { sections, collapsedGroups })) - }) - const update = (next: Sections, nextCollapsed: ReadonlySet = NONE) => - act(() => { - renderer?.update(createElement(Probe, { sections: next, collapsedGroups: nextCollapsed })) - }) - return { scrollToLocation, update } -} - -describe('useActiveWorktreeScroll', () => { - it('scrolls to the highlighted row, and again when another workspace is highlighted', () => { - const list = mount(listOf('b')) - expect(list.scrollToLocation).toHaveBeenLastCalledWith( - expect.objectContaining({ sectionIndex: 0, itemIndex: 1 }) - ) - list.update(listOf('c')) - expect(list.scrollToLocation).toHaveBeenLastCalledWith( - expect.objectContaining({ itemIndex: 2 }) - ) - expect(list.scrollToLocation).toHaveBeenCalledTimes(2) - }) - - it('never scrolls when a fold or search hides the row and it comes back', () => { - const list = mount(listOf('b')) - list.update(listOf('b', true), FOLDED) - list.update(listOf('b'), NONE) - list.update(listOf(null)) - list.update(listOf('b')) - expect(list.scrollToLocation).toHaveBeenCalledTimes(1) - }) - - it('never scrolls to a highlight an unfold first reveals', () => { - const list = mount(listOf('b', true), FOLDED) - list.update(listOf('b'), NONE) - expect(list.scrollToLocation).not.toHaveBeenCalled() - list.update(listOf('c'), NONE) - expect(list.scrollToLocation).toHaveBeenCalledTimes(1) - }) -}) diff --git a/mobile/src/mobile-release/prepare-android-release-script.test.ts b/mobile/src/mobile-release/prepare-android-release-script.test.ts deleted file mode 100644 index ac3822684e8..00000000000 --- a/mobile/src/mobile-release/prepare-android-release-script.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { spawnSync } from 'node:child_process' -import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { fileURLToPath } from 'node:url' -import { afterEach, describe, expect, it } from 'vitest' - -const scriptPath = fileURLToPath( - new URL('../../scripts/prepare-android-release.mjs', import.meta.url) -) - -const appConfig = { - expo: { - version: '0.0.22', - android: { - versionCode: 4 - } - } -} - -let tempDirs: string[] = [] - -function createAppConfig() { - const dir = mkdtempSync(join(tmpdir(), 'orca-android-release-')) - tempDirs.push(dir) - const configPath = join(dir, 'app.json') - const contents = `${JSON.stringify(appConfig, null, 2)}\n` - writeFileSync(configPath, contents) - const outputPath = join(dir, 'github-output') - writeFileSync(outputPath, '') - return { configPath, contents, outputPath } -} - -function scenarioEnv(configPath: string, outputPath: string, inputs: Record) { - const env = { ...process.env } - for (const key of Object.keys(env)) { - if (key.startsWith('MOBILE_ANDROID_') || key === 'GITHUB_REF' || key === 'GITHUB_OUTPUT') { - delete env[key] - } - } - return { ...env, MOBILE_APP_CONFIG_PATH: configPath, GITHUB_OUTPUT: outputPath, ...inputs } -} - -describe('prepare Android release script', () => { - afterEach(() => { - for (const dir of tempDirs) { - rmSync(dir, { force: true, recursive: true }) - } - tempDirs = [] - }) - - it('rejects release-only Android versionCode bumps', () => { - const { configPath, contents, outputPath } = createAppConfig() - - const result = spawnSync(process.execPath, [scriptPath], { - encoding: 'utf8', - env: scenarioEnv(configPath, outputPath, { MOBILE_ANDROID_BUMP_VERSION_CODE: 'true' }) - }) - - expect(result.status).toBe(1) - expect(readFileSync(configPath, 'utf8')).toBe(contents) - expect(readFileSync(outputPath, 'utf8')).toBe('') - expect(result.stderr).toContain( - 'Android versionCode changes must be committed in mobile/app.json before release' - ) - }) - - it('rejects release versions that do not match committed app config', () => { - const { configPath, contents, outputPath } = createAppConfig() - - const result = spawnSync(process.execPath, [scriptPath], { - encoding: 'utf8', - env: scenarioEnv(configPath, outputPath, { MOBILE_ANDROID_RELEASE_VERSION: '0.0.23' }) - }) - - expect(result.status).toBe(1) - expect(readFileSync(configPath, 'utf8')).toBe(contents) - expect(readFileSync(outputPath, 'utf8')).toBe('') - expect(result.stderr).toContain( - 'MOBILE_ANDROID_RELEASE_VERSION must match the committed mobile app version' - ) - }) -}) diff --git a/src/main/agent-hooks/installation/commands/windows-hook-payload-delivery.test.ts b/src/main/agent-hooks/installation/commands/windows-hook-payload-delivery.test.ts deleted file mode 100644 index cb385db6666..00000000000 --- a/src/main/agent-hooks/installation/commands/windows-hook-payload-delivery.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest' -import { runProcess } from '@orca/process-host' -import { lstatSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs' -import { removeTreeSync } from '../../../../shared/windows-transient-lock-removal' -import { tmpdir } from 'node:os' -import { basename, join } from 'node:path' -import type * as osModule from 'node:os' - -const { homedirMock } = vi.hoisted(() => ({ homedirMock: vi.fn<() => string>() })) - -vi.mock('electron', () => ({ - app: { - getPath: () => '/tmp/orca-user-data' - } -})) - -vi.mock('os', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - homedir: homedirMock.mockImplementation(actual.homedir) - } -}) -import { CopilotHookService } from '../../../copilot/hook-service' -import { - WINDOWS_POWERSHELL_WARM_UP_TIMEOUT_MS, - warmWindowsEncodedPowerShell -} from './testing/windows-powershell-warm-up.test-fixture' -// Multiple chunks and non-ASCII expose pipe truncation and code-page conversion. -const PAYLOAD = JSON.stringify({ - session_id: 'a3f9c1e0-payload-delivery', - hook_event_name: 'PreToolUse', - tool_name: 'Bash', - tool_input: { command: 'echo "café 日本語 😀" & echo %PATH% | more' }, - transcript: 'y'.repeat(4096) -}) - -type Runner = { - name: string - program: () => string - args: (command: string) => string[] - verbatim?: boolean -} - -const SYSTEM32 = join(process.env.SystemRoot ?? 'C:\\Windows', 'System32') -const CMD = join(SYSTEM32, 'cmd.exe') -const POWERSHELL = join(SYSTEM32, 'WindowsPowerShell', 'v1.0', 'powershell.exe') -function findPwsh(): string | undefined { - const candidates = [ - join(process.env.ProgramFiles ?? 'C:\\Program Files', 'PowerShell', '7', 'pwsh.exe'), - join(process.env.LOCALAPPDATA ?? '', 'Microsoft', 'WindowsApps', 'pwsh.exe') - ] - // lstat: the Store install is an app-execution alias that existsSync cannot follow. - return candidates.find((candidate) => lstatSync(candidate, { throwIfNoEntry: false })) -} -// Copilot's ` -nop -nol -c `; pwsh only where it is installed. -const COPILOT_RUNNERS: Runner[] = [POWERSHELL, findPwsh()].flatMap((program) => - program - ? [ - { - name: `${basename(program)} (Copilot)`, - program: () => program, - args: (c: string) => ['-nop', '-nol', '-c', c] - } - ] - : [] -) - -type Entry = { command?: string; powershell?: string; hooks?: { command?: string }[] } -const commandsOf = (entries: Entry[] | undefined): (string | undefined)[] => - (entries ?? []).flatMap((entry) => - entry.hooks ? entry.hooks.map((h) => h.command) : (entry.command ?? entry.powershell) - ) - -function readEvent(path: string, event: string): (string | undefined)[] { - return commandsOf(JSON.parse(readFileSync(path, 'utf8')).hooks?.[event]) -} - -// Inherited Orca endpoints must not redirect test payloads away from this listener. -function hookEnvironment(extra: NodeJS.ProcessEnv): NodeJS.ProcessEnv { - const base = Object.fromEntries( - Object.entries(process.env).filter(([key]) => !key.toUpperCase().startsWith('ORCA_')) - ) - return { ...base, ORCA_BACKGROUND_LAUNCH: '1', ...extra } -} - -describe.skipIf(process.platform !== 'win32')('Windows managed hook payload delivery', () => { - let root = '' - - beforeAll( - () => warmWindowsEncodedPowerShell(hookEnvironment({})), - WINDOWS_POWERSHELL_WARM_UP_TIMEOUT_MS - ) - - afterEach(() => { - vi.unstubAllEnvs() - homedirMock.mockImplementation(() => process.env.HOME ?? tmpdir()) - if (root) { - removeTreeSync(root) - root = '' - } - }) - - // The control verifies profile-based AutoRun ran; printing it must not corrupt Copilot gate JSON. - it('Copilot answers exactly {} when the cmd AutoRun prints', async () => { - root = mkdtempSync(join(tmpdir(), 'orca-hook-autorun-')) - const home = join(root, 'user') - mkdirSync(home) - homedirMock.mockReturnValue(home) - for (const name of ['USERPROFILE', 'HOME']) { - vi.stubEnv(name, home) - } - vi.stubEnv('COPILOT_HOME', undefined) - writeFileSync(join(home, '.cmd_aliases.cmd'), '@echo autorun-noise\r\n', 'utf8') - expect(new CopilotHookService().install().state).toBe('installed') - const [command] = readEvent(join(home, '.copilot', 'hooks', 'orca.json'), 'PreToolUse') - if (!command) { - throw new Error('Missing managed Copilot PreToolUse command') - } - const env = hookEnvironment({ USERPROFILE: home, HOME: home }) - - const autoRun = await runProcess({ program: CMD, args: ['/c', 'rem'], env, timeoutMs: 15_000 }) - for (const runner of COPILOT_RUNNERS) { - const result = await runProcess({ - program: runner.program(), - args: runner.args(command), - env, - input: PAYLOAD, - timeoutMs: 15_000 - }) - expect(result.code, `${runner.name} exit code`).toBe(0) - expect(result.stdout, `${runner.name} stdout`).toBe('{}\r\n') - } - if (autoRun.stdout.includes('autorun-noise')) { - const bare = command.replace(/^\S+\/cmd\.exe \/d \/c /, '') - const control = await runProcess({ - program: POWERSHELL, - args: ['-nop', '-nol', '-c', bare], - env, - input: PAYLOAD, - timeoutMs: 15_000 - }) - expect(control.stdout, 'without /d the AutoRun prints first').toContain('autorun-noise') - } - }, 60_000) -}) diff --git a/src/main/agent-hooks/installation/local-agent-cli-presence.test.ts b/src/main/agent-hooks/installation/local-agent-cli-presence.test.ts deleted file mode 100644 index 222211d5ea6..00000000000 --- a/src/main/agent-hooks/installation/local-agent-cli-presence.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { chmodSync, mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { ManagedAgentHookTarget } from '../../../shared/managed-agent-hook-targets' -import { detectLocalManagedAgentCliPresence } from './local-agent-cli-presence' - -const { mergePersistedWindowsPathAsyncMock } = vi.hoisted(() => ({ - mergePersistedWindowsPathAsyncMock: vi.fn(async (_env: NodeJS.ProcessEnv) => undefined) -})) -vi.mock('../../pty/environment/windows-environment-path', () => ({ - mergePersistedWindowsPathAsync: mergePersistedWindowsPathAsyncMock -})) - -const codexTarget: ManagedAgentHookTarget = { - agent: 'codex', - tuiAgent: 'codex', - executableCandidates: ['codex'] -} - -const claudeTarget: ManagedAgentHookTarget = { - agent: 'claude', - tuiAgent: 'claude', - executableCandidates: ['claude'] -} - -describe('detectLocalManagedAgentCliPresence', () => { - let tmpDir: string | null = null - - afterEach(() => { - if (tmpDir) { - rmSync(tmpDir, { recursive: true, force: true }) - tmpDir = null - } - }) - - it.runIf(process.platform !== 'win32')( - 'accepts executable symlinks and rejects broken symlinks', - async () => { - tmpDir = mkdtempSync(join(tmpdir(), 'orca-cli-presence-')) - const binDir = join(tmpDir, 'bin') - mkdirSync(binDir) - const targetPath = join(tmpDir, 'codex-real') - writeFileSync(targetPath, '#!/bin/sh\n') - chmodSync(targetPath, 0o755) - symlinkSync(targetPath, join(binDir, 'codex')) - symlinkSync(join(tmpDir, 'missing'), join(binDir, 'claude')) - - const result = await detectLocalManagedAgentCliPresence( - [codexTarget, claudeTarget], - { agentCmdOverrides: {} }, - { pathEnv: binDir, pathDelimiter: ':', platform: process.platform } - ) - - expect(result.codex?.state).toBe('found') - expect(result.claude?.state).toBe('missing') - } - ) -}) diff --git a/src/main/agent-hooks/installation/scripts/grok-replay-guard.test.ts b/src/main/agent-hooks/installation/scripts/grok-replay-guard.test.ts deleted file mode 100644 index 7e318f07e41..00000000000 --- a/src/main/agent-hooks/installation/scripts/grok-replay-guard.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' - -vi.mock('electron', () => ({ app: { getPath: () => '/tmp/userData' } })) - -import { getManagedScript as getClaudeManagedScript } from '../../../claude/hooks/hook-script' -import { getManagedScript as getCursorManagedScript } from '../../../cursor/hook-script' -import { runVendorHook } from './testing/vendor-hook-delivery.test-fixture' - -const CLAUDE_SCRIPT_OPTIONS = { - skipWhenDevinImportsClaude: true, - skipWhenGrokImportsClaude: true -} - -describe('Grok vendor hook replay guard', () => { - it('drops Grok-replayed hooks without suppressing their protocol response', async () => { - for (const script of [ - getClaudeManagedScript('local', CLAUDE_SCRIPT_OPTIONS), - getCursorManagedScript('local') - ]) { - expect((await runVendorHook(script, { GROK_HOOK_EVENT: 'Stop' })).requests).toEqual([]) - } - }) - - it.skipIf(process.platform === 'win32')( - 'keeps Grok-replayed hooks out of the spool', - async () => { - for (const [source, script] of [ - ['claude', getClaudeManagedScript('posix', CLAUDE_SCRIPT_OPTIONS)], - ['cursor', getCursorManagedScript('posix')] - ]) { - const ordinary = await runVendorHook(script, { GROK_HOOK_EVENT: '' }, 'spool') - expect(ordinary.requests).toEqual([]) - expect(ordinary.spooled).toHaveLength(1) - expect(JSON.parse(ordinary.spooled[0])).toMatchObject({ - source, - paneKey: 'tab:leaf', - payload: { hook_event_name: 'Stop' } - }) - const replayed = await runVendorHook(script, { GROK_HOOK_EVENT: 'Stop' }, 'spool') - expect(replayed.requests).toEqual([]) - expect(replayed.spooled).toEqual([]) - } - } - ) -}) diff --git a/src/main/agent-hooks/installation/scripts/managed-hook-script-refresh.test.ts b/src/main/agent-hooks/installation/scripts/managed-hook-script-refresh.test.ts deleted file mode 100644 index 067f10062fc..00000000000 --- a/src/main/agent-hooks/installation/scripts/managed-hook-script-refresh.test.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as CodexHookHashLookup from '../../../codex/trust/hooks/codex-hook-hash-lookup' -import { - existsSync, - chmodSync, - mkdirSync, - mkdtempSync, - readdirSync, - readFileSync, - rmSync, - statSync, - utimesSync, - writeFileSync -} from 'node:fs' -import { tmpdir } from 'node:os' -import { spawnSync } from 'node:child_process' -import { join } from 'node:path' -import type * as osModule from 'node:os' - -let isolatedUserDataDir = '' -let previousUserDataPath: string | undefined - -beforeEach(() => { - vi.stubEnv('GROK_HOME', undefined) - vi.stubEnv('KIMI_CODE_HOME', undefined) - vi.stubEnv('COPILOT_HOME', undefined) - vi.stubEnv('KIRO_HOME', undefined) - vi.stubEnv('XDG_CONFIG_HOME', undefined) - previousUserDataPath = process.env.ORCA_USER_DATA_PATH - isolatedUserDataDir = mkdtempSync(join(tmpdir(), 'orca-hook-refresh-user-data-')) - process.env.ORCA_USER_DATA_PATH = isolatedUserDataDir -}) - -afterEach(() => { - if (previousUserDataPath === undefined) { - delete process.env.ORCA_USER_DATA_PATH - } else { - process.env.ORCA_USER_DATA_PATH = previousUserDataPath - } - rmSync(isolatedUserDataDir, { recursive: true, force: true }) - vi.unstubAllEnvs() -}) - -const { homedirMock } = vi.hoisted(() => ({ - homedirMock: vi.fn<() => string>() -})) - -vi.mock('../../../codex/trust/hooks/codex-hook-hash-lookup', async (importOriginal) => ({ - ...(await importOriginal()), - resolveCodexHookAnswerForLaunch: async () => - ( - await import('../../../codex/hooks/installation/hook-service-test-harness') - ).codexHookAnswerForTests() -})) - -vi.mock('electron', () => ({ - app: { - getPath: () => '/tmp/orca-user-data' - } -})) - -vi.mock('os', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - homedir: homedirMock.mockImplementation(actual.homedir) - } -}) - -import { refreshManagedScriptIfPresent } from './managed-hook-script-refresh' -import { ClaudeHookService } from '../../../claude/hook-service' - -describe('refreshManagedScriptIfPresent', () => { - it('rewrites an existing script and refuses to create a missing one', async () => { - const dir = mkdtempSync(join(tmpdir(), 'orca-hook-refresh-unit-')) - try { - const present = join(dir, 'present.cmd') - writeFileSync(present, 'stale') - expect(await refreshManagedScriptIfPresent(present, 'fresh')).toBe(true) - expect(readFileSync(present, 'utf8')).toBe('fresh') - - if (process.platform !== 'win32') { - chmodSync(present, 0o600) - } - const fixedTime = new Date(1_000) - utimesSync(present, fixedTime, fixedTime) - expect(await refreshManagedScriptIfPresent(present, 'fresh')).toBe(true) - expect(statSync(present).mtimeMs).toBe(fixedTime.getTime()) - if (process.platform !== 'win32') { - expect(statSync(present).mode & 0o777).toBe(0o755) - } - - const missing = join(dir, 'missing.cmd') - expect(await refreshManagedScriptIfPresent(missing, 'fresh')).toBe(false) - expect(existsSync(missing)).toBe(false) - } finally { - rmSync(dir, { recursive: true, force: true }) - } - }) -}) - -describe('managed hook script refresh', () => { - it.skipIf(process.platform === 'win32')( - 'refreshes existing POSIX hook and statusline locale handling without a CLI config', - async () => { - const home = mkdtempSync(join(tmpdir(), 'orca-hook-locale-refresh-')) - homedirMock.mockReturnValue(home) - try { - const hooksDir = join(home, '.orca', 'agent-hooks') - mkdirSync(hooksDir, { recursive: true }) - for (const name of ['claude-hook.sh', 'claude-statusline.sh']) { - writeFileSync(join(hooksDir, name), '#!/bin/sh\ncurl --connect-timeout 0.5\n') - } - await new ClaudeHookService().refreshManagedScripts() - for (const name of ['claude-hook.sh', 'claude-statusline.sh']) { - const observed = join(home, `${name}.locale`) - const result = spawnSync( - '/bin/sh', - [ - '-c', - 'curl() { printf "%s|%s" "$LC_ALL" "$LC_NUMERIC" > "$ORCA_TEST_CURL_LOCALE"; command -p cat >/dev/null; }; . "$1"', - 'hook', - join(hooksDir, name) - ], - { - input: '{"hook_event_name":"Stop","rate_limits":{},"total_duration_ms":1000}', - encoding: 'utf8', - timeout: 5_000, - env: { - ...process.env, - LC_ALL: 'de_DE.UTF-8', - LC_NUMERIC: 'de_DE.UTF-8', - TMPDIR: home, - CLAUDE_JOB_DIR: '', - ORCA_AGENT_HOOK_ENDPOINT: '', - ORCA_AGENT_HOOK_PORT: '1', - ORCA_AGENT_HOOK_TOKEN: 'test-token', - ORCA_PANE_KEY: 'pane-1', - ORCA_TEST_CURL_LOCALE: observed - } - } - ) - expect(result.error, name).toBeUndefined() - expect(result.status, name).toBe(0) - expect(existsSync(observed), `${name} delivered to curl`).toBe(true) - expect(readFileSync(observed, 'utf8'), name).toBe('|C') - expect(statSync(join(hooksDir, name)).mode & 0o777).toBe(0o755) - } - expect(existsSync(join(home, '.claude'))).toBe(false) - expect(readdirSync(hooksDir).sort()).toEqual(['claude-hook.sh', 'claude-statusline.sh']) - } finally { - homedirMock.mockImplementation(() => process.env.HOME ?? tmpdir()) - rmSync(home, { recursive: true, force: true }) - } - } - ) -}) diff --git a/src/main/agent-hooks/observations/local-tmux-managed-pty.test.ts b/src/main/agent-hooks/observations/local-tmux-managed-pty.test.ts deleted file mode 100644 index 4b676205c19..00000000000 --- a/src/main/agent-hooks/observations/local-tmux-managed-pty.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { - createLocalPtyInventoryReader, - createLocalTmuxManagedPtyResolver -} from './local-tmux-managed-pty' -import type { PtyProcessInfo } from '../../providers/pty/process-info' - -const row: PtyProcessInfo = { - id: 'pty', - incarnationId: 'generation', - rootProcessId: 123, - cwd: '/workspace', - title: 'shell', - worktreeId: 'folder:workspace' -} -describe.skipIf(process.platform === 'win32')('authenticated local tmux root resolution', () => { - it('refuses a binding changed during capture and excludes WSL roots from a native probe', async () => { - let binding = 'pty' - const resolve = createLocalTmuxManagedPtyResolver( - createLocalPtyInventoryReader({ - getPtyId: () => binding, - listProcesses: async () => { - binding = 'replacement' - return [row] - } - }) - ) - expect(await resolve('pane')).toBeNull() - const wsl = createLocalTmuxManagedPtyResolver( - createLocalPtyInventoryReader({ - getPtyId: () => 'pty', - listProcesses: async () => [{ ...row, wslDistro: 'Ubuntu-24.04' }] - }) - ) - expect(await wsl('pane')).toBeNull() - }) -}) diff --git a/src/main/agent-hooks/server/testing/authority/server-omp-retired-ingress.test.ts b/src/main/agent-hooks/server/testing/authority/server-omp-retired-ingress.test.ts deleted file mode 100644 index 2746269d8a1..00000000000 --- a/src/main/agent-hooks/server/testing/authority/server-omp-retired-ingress.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer } from '../../agent-hook-server' -import { PANE } from '../server.test-fixtures' - -vi.mock('../../../../telemetry/client', () => ({ track: vi.fn() })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ getCohortAtEmit: vi.fn() })) -afterEach(() => vi.restoreAllMocks()) - -const working = { agentType: 'omp', state: 'working', prompt: 'new turn' } - -describe('OMP retired-pane remote ingress', () => { - it('recovers a legacy source-less OMP new turn using validated payload identity', () => { - const server = new AgentHookServer() - server.retirePaneAuthority(PANE) - server.ingestRemote( - { paneKey: PANE, hookEventName: 'before_agent_start', payload: working }, - 'ssh' - ) - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - paneKey: PANE, - observation: expect.objectContaining({ boundary: true }) - }) - ]) - }) - - it.each([ - { payload: { ...working, state: 'invalid' } }, - { payload: { ...working, agentType: 'claude' } }, - { isReplay: 'true' }, - { isReplay: null }, - { launchToken: 42 }, - { providerSessionOnly: true } - ])('rejected metadata leaves retirement intact: %j', (invalid) => { - const server = new AgentHookServer() - server.retirePaneAuthority(PANE) - const input = { - paneKey: PANE, - source: 'omp', - hookEventName: 'before_agent_start', - payload: working, - ...invalid - } - // Exercise raw JSON ingress, including malformed fields a typed caller cannot create. - server.ingestRemote(JSON.parse(JSON.stringify(input)), 'ssh') - expect(server.getStatusSnapshot()).toEqual([]) - server.ingestRemote( - { - paneKey: PANE, - source: 'omp', - hookEventName: 'agent_end', - payload: { ...working, state: 'done' } - }, - 'ssh' - ) - expect(server.getStatusSnapshot()).toEqual([]) - server.ingestRemote( - { paneKey: PANE, source: 'omp', hookEventName: 'before_agent_start', payload: working }, - 'ssh' - ) - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ paneKey: PANE, state: 'working' }) - ]) - }) - - it('a replay cannot restore a retired OMP pane', () => { - const server = new AgentHookServer() - server.retirePaneAuthority(PANE) - server.ingestRemote( - { paneKey: PANE, hookEventName: 'before_agent_start', isReplay: true, payload: working }, - 'ssh' - ) - expect(server.getStatusSnapshot()).toEqual([]) - server.ingestRemote( - { paneKey: PANE, source: 'omp', hookEventName: 'before_agent_start', payload: working }, - 'ssh' - ) - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ paneKey: PANE, state: 'working' }) - ]) - }) -}) diff --git a/src/main/agent-hooks/server/testing/authority/server-reminted-pane-key.test.ts b/src/main/agent-hooks/server/testing/authority/server-reminted-pane-key.test.ts deleted file mode 100644 index 3a46caacfc6..00000000000 --- a/src/main/agent-hooks/server/testing/authority/server-reminted-pane-key.test.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { readSavedStatus, hasSavedStatus } from '../persistence/last-status.test-fixtures' -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, GOOD_PANE, postHookEvent, PANE } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ - track: trackMock -})) - -vi.mock('../../../../telemetry/cohort-classifier', () => ({ - getCohortAtEmit: getCohortAtEmitMock -})) - -const REMINTED = '$$MFRGGZDFMY:L$$' -const FOREIGN = '$$ONXW2ZJAON:L$$' - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -describe('reminted $$ pane keys on the OMP hook pipeline', () => { - let userDataPath: string - - beforeEach(() => { - userDataPath = mkdtempSync(join(tmpdir(), 'orca-reminted-pane-')) - }) - - afterEach(() => { - rmSync(userDataPath, { recursive: true, force: true }) - }) - - function lastStatusPath(): string { - return join(userDataPath, 'agent-hooks', 'last-status.json') - } - - it('routes a reminted $$ key to its canonical pane and settles at done', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production', userDataPath }) - try { - server.registerPaneKeyAlias(REMINTED, PANE, 'pty-remint') - const start = await postHookEvent( - server, - buildBody( - { hook_event_name: 'before_agent_start', prompt: 'finish the reminted pane' }, - { paneKey: REMINTED, launchToken: 'launch-remint' } - ), - '/hook/omp' - ) - const end = await postHookEvent( - server, - buildBody( - { hook_event_name: 'agent_end' }, - { paneKey: REMINTED, launchToken: 'launch-remint' } - ), - '/hook/omp' - ) - expect(start.status).toBe(204) - expect(end.status).toBe(204) - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - paneKey: PANE, - tabId: 'tab-1', - state: 'done', - prompt: 'finish the reminted pane', - agentType: 'omp' - }) - ]) - server.flushStatusPersistSync() - expect(hasSavedStatus(lastStatusPath())).toBe(true) - const file: { - entries: Record - } = JSON.parse(readSavedStatus(lastStatusPath())) - expect(file.entries[PANE]?.payload.state).toBe('done') - expect(file.entries[REMINTED]).toBeUndefined() - } finally { - server.stop() - } - }) - - it('does not let a foreign reminted key stamp another pane', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - try { - server.registerPaneKeyAlias(REMINTED, PANE, 'pty-remint') - await postHookEvent( - server, - buildBody( - { hook_event_name: 'before_agent_start', prompt: 'owned turn' }, - { paneKey: REMINTED } - ), - '/hook/omp' - ) - const foreign = await postHookEvent( - server, - buildBody( - { hook_event_name: 'agent_end', prompt: 'stolen done' }, - { paneKey: FOREIGN, tabId: 'tab-1' } - ), - '/hook/omp' - ) - expect(foreign.status).toBe(204) - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - paneKey: PANE, - state: 'working', - prompt: 'owned turn', - agentType: 'omp' - }) - ]) - } finally { - server.stop() - } - }) - - it('does not rebind a reminted token onto a different pane', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - try { - // Different spawns can share $$ tokens; stale remints must not overwrite the newer pane owner. - server.registerPaneKeyAlias(REMINTED, PANE, 'pty-a', 10, { authorityVerified: true }) - server.registerPaneKeyAlias(REMINTED, GOOD_PANE, 'pty-b', 20, { authorityVerified: true }) - const start = await postHookEvent( - server, - buildBody( - { hook_event_name: 'before_agent_start', prompt: 'owned remint turn' }, - { paneKey: REMINTED, tabId: 'tab-good' } - ), - '/hook/omp' - ) - expect(start.status).toBe(204) - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - paneKey: PANE, - tabId: 'tab-1', - state: 'working', - prompt: 'owned remint turn', - agentType: 'omp' - }) - ]) - } finally { - server.stop() - } - }) -}) diff --git a/src/main/agent-hooks/server/testing/authority/server-removed-worktree-status.test.ts b/src/main/agent-hooks/server/testing/authority/server-removed-worktree-status.test.ts deleted file mode 100644 index 25f7c5d74f4..00000000000 --- a/src/main/agent-hooks/server/testing/authority/server-removed-worktree-status.test.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { readSavedStatus } from '../persistence/last-status.test-fixtures' -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' -import { LEAF_1, LEAF_2, LEAF_3, LEAF_4, LEAF_5, recentTs } from '../server.test-fixtures' - -const REMOVED = 'repo-1::/workspace/removed' -const KEPT = 'repo-1::/workspace/kept' -const LOCAL_PANE = makePaneKey('tab-local', LEAF_1) -const WSL_PANE = makePaneKey('tab-wsl', LEAF_2) -const SSH_PANE = makePaneKey('tab-ssh', LEAF_3) -const SSH_COMMITMENT_PANE = makePaneKey('tab-ssh-idle', LEAF_4) -const OTHER_PANE = makePaneKey('tab-other', LEAF_5) - -function row(paneKey: string, worktreeId: string, connectionId: string | null) { - const receivedAt = recentTs() - return { - paneKey, - tabId: paneKey.split(':')[0], - worktreeId, - connectionId, - receivedAt, - stateStartedAt: receivedAt, - payload: { state: 'working', prompt: 'stranded', agentType: 'codex' } - } -} - -describe('AgentHookServer removed-worktree retirement', () => { - let userDataPath: string - const lastStatusPath = () => join(userDataPath, 'agent-hooks', 'last-status.json') - - beforeEach(() => { - _internals.resetCachesForTests() - userDataPath = mkdtempSync(join(tmpdir(), 'orca-removed-worktree-')) - mkdirSync(join(userDataPath, 'agent-hooks'), { recursive: true }) - writeFileSync( - lastStatusPath(), - JSON.stringify({ - version: 2, - entries: { - [LOCAL_PANE]: row(LOCAL_PANE, REMOVED, null), - [WSL_PANE]: row(WSL_PANE, REMOVED, 'wsl:Ubuntu'), - [SSH_PANE]: row(SSH_PANE, REMOVED, 'user@box'), - [OTHER_PANE]: row(OTHER_PANE, KEPT, null) - } - }), - 'utf8' - ) - }) - - afterEach(() => { - rmSync(userDataPath, { recursive: true, force: true }) - }) - - it('retires only the removing host rows and commitments, then persists the pruned map', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production', userDataPath }) - try { - // An SSH commitment recorded this session outlives its row across a disconnect clear. - server.ingestRemote( - { - paneKey: SSH_COMMITMENT_PANE, - tabId: 'tab-ssh-idle', - worktreeId: REMOVED, - launchToken: 'idle-launch', - payload: { state: 'working', prompt: 'idle', agentType: 'codex' } - }, - 'idle@box' - ) - server.clearStatusEntriesForConnection('idle@box') - const persisted = () => { - server.flushStatusPersistSync() - const file = JSON.parse(readSavedStatus(lastStatusPath())) - return { - entries: Object.keys(file.entries).sort(), - commitments: Object.keys(file.authorityCommitments ?? {}) - } - } - - server.dropStatusEntriesForRemovedWorktree(REMOVED, 'runtime:env-1') - expect(persisted().entries).toHaveLength(4) - - server.dropStatusEntriesForRemovedWorktree(REMOVED, 'local') - expect(persisted()).toEqual({ - entries: [OTHER_PANE, SSH_PANE].sort(), - commitments: [SSH_COMMITMENT_PANE] - }) - - server.dropStatusEntriesForRemovedWorktree(REMOVED, 'ssh:user%40box') - expect(persisted()).toEqual({ entries: [OTHER_PANE], commitments: [SSH_COMMITMENT_PANE] }) - - server.dropStatusEntriesForRemovedWorktree(REMOVED, 'ssh:idle%40box') - expect(persisted().commitments).toEqual([]) - } finally { - server.stop() - } - }) - - it('fences only the retired pane, so its kept tab still reports a new agent', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production', userDataPath }) - try { - server.dropStatusEntriesForRemovedWorktree(REMOVED, 'local') - const newPane = makePaneKey('tab-local', '66666666-6666-4666-8666-666666666666') - const done = { state: 'done', prompt: 'late', agentType: 'codex' } as const - server.ingestTerminalStatus({ paneKey: LOCAL_PANE, connectionId: null, payload: done }) - server.ingestTerminalStatus({ paneKey: newPane, connectionId: null, payload: done }) - - const panes = server.getStatusSnapshot().map((entry) => entry.paneKey) - expect(panes).toContain(newPane) - expect(panes).not.toContain(LOCAL_PANE) - } finally { - server.stop() - } - }) - - it.each([ - { occupant: 'the removed worktree', sshWorktree: KEPT, localWorktree: REMOVED, host: 'local' }, - { - occupant: 'another owner', - sshWorktree: REMOVED, - localWorktree: KEPT, - host: 'ssh:user%40box' - } - ] as const)( - 'decides a reused pane by its occupant: $occupant', - async ({ sshWorktree, localWorktree, host }) => { - const server = new AgentHookServer() - await server.start({ env: 'production', userDataPath }) - try { - const pane = makePaneKey('tab-reused', '77777777-7777-4777-8777-777777777777') - const working = { state: 'working', prompt: 'live', agentType: 'codex' } as const - const reportLocally = (state: 'working' | 'done') => - server.ingestTerminalStatus({ - paneKey: pane, - worktreeId: localWorktree, - connectionId: null, - payload: { ...working, state } - }) - server.ingestRemote( - { - paneKey: pane, - tabId: 'tab-reused', - worktreeId: sshWorktree, - launchToken: 'ssh', - payload: working - }, - 'user@box' - ) - server.clearStatusEntriesForConnection('user@box') - reportLocally('working') - - server.dropStatusEntriesForRemovedWorktree(REMOVED, host) - reportLocally('done') - - server.flushStatusPersistSync() - const file = JSON.parse(readSavedStatus(lastStatusPath())) - if (localWorktree === REMOVED) { - expect(file.authorityCommitments?.[pane]).toMatchObject({ worktreeId: KEPT }) - expect(file.entries[pane]).toBeUndefined() - } else { - expect(file.authorityCommitments?.[pane]).toBeUndefined() - expect(file.entries[pane]).toMatchObject({ worktreeId: KEPT, payload: { state: 'done' } }) - expect(file.entries[pane].launchTokenHash).toBeUndefined() - } - } finally { - server.stop() - } - } - ) -}) diff --git a/src/main/agent-hooks/server/testing/http/server-claude-statusline.test.ts b/src/main/agent-hooks/server/testing/http/server-claude-statusline.test.ts deleted file mode 100644 index 0f5132ad5ca..00000000000 --- a/src/main/agent-hooks/server/testing/http/server-claude-statusline.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { AgentHookServer } from '../../agent-hook-server' -import type { ClaudeStatusLineRateLimits } from '../../../../../shared/claude-statusline-rate-limits' - -describe('AgentHookServer /statusline/claude', () => { - let server: AgentHookServer - - beforeEach(async () => { - server = new AgentHookServer() - await server.start({ env: 'production' }) - }) - - afterEach(() => { - server.stop() - }) - - function post(body: string, token?: string): Promise { - const env = server.buildPtyEnv() - return fetch(`http://127.0.0.1:${env.ORCA_AGENT_HOOK_PORT}/statusline/claude`, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'X-Orca-Agent-Hook-Token': token ?? env.ORCA_AGENT_HOOK_TOKEN - }, - body - }) - } - - it('forwards parsed rate limits to the statusline listener', async () => { - const events: ClaudeStatusLineRateLimits[] = [] - server.setClaudeStatusLineListener((event) => { - events.push(event) - }) - - const payload = JSON.stringify({ - rate_limits: { - five_hour: { used_percentage: 12.5, resets_at: 1738425600 }, - seven_day: { used_percentage: 40, resets_at: 1712059200 } - } - }) - const body = new URLSearchParams({ - paneKey: 'pane-1', - configDir: '/home/dev/managed', - payload - }).toString() - - await expect(post(body)).resolves.toMatchObject({ status: 204 }) - expect(events).toEqual([ - { - configDir: '/home/dev/managed', - fiveHour: { used_percentage: 12.5, resets_at: 1738425600 }, - sevenDay: { used_percentage: 40, resets_at: 1712059200 } - } - ]) - }) - - it('rejects posts with a bad token and ignores payloads without rate limits', async () => { - const events: ClaudeStatusLineRateLimits[] = [] - server.setClaudeStatusLineListener((event) => { - events.push(event) - }) - - await expect(post('payload={}', 'wrong-token')).resolves.toMatchObject({ status: 403 }) - - const noLimits = new URLSearchParams({ - paneKey: 'pane-1', - payload: JSON.stringify({ context_window: { used_percentage: 8 } }) - }).toString() - await expect(post(noLimits)).resolves.toMatchObject({ status: 204 }) - - await expect(post('payload=not-json')).resolves.toMatchObject({ status: 204 }) - - expect(events).toEqual([]) - }) -}) diff --git a/src/main/agent-hooks/server/testing/http/server-hook-http-ingest.test.ts b/src/main/agent-hooks/server/testing/http/server-hook-http-ingest.test.ts deleted file mode 100644 index 55bfc705f66..00000000000 --- a/src/main/agent-hooks/server/testing/http/server-hook-http-ingest.test.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, PANE } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ - track: trackMock -})) - -vi.mock('../../../../telemetry/cohort-classifier', () => ({ - getCohortAtEmit: getCohortAtEmitMock -})) - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -describe('AgentHookServer listener replay', () => { - it('accepts raw JSON hook bodies with base64 metadata headers', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - try { - const env = server.buildPtyEnv() - const response = await fetch(`http://127.0.0.1:${env.ORCA_AGENT_HOOK_PORT}/hook/claude`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Orca-Agent-Hook-Token': env.ORCA_AGENT_HOOK_TOKEN, - 'X-Orca-Agent-Hook-Meta-Encoding': 'base64', - 'X-Orca-Agent-Hook-Meta': Buffer.from( - [PANE, 'tab-1', '', 'wt-1', 'production', ''].join('\x1f') - ).toString('base64') - }, - body: JSON.stringify({ hook_event_name: 'UserPromptSubmit', prompt: 'raw JSON' }) - }) - - expect(response.status).toBe(204) - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - paneKey: PANE, - worktreeId: 'wt-1', - state: 'working', - prompt: 'raw JSON' - }) - ]) - } finally { - server.stop() - } - }) - - it('ignores local nested Claude Stop while a parent Codex hook status is active', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - try { - const env = server.buildPtyEnv() - const listener = vi.fn() - server.setListener(listener) - const postHook = async ( - source: 'codex' | 'claude', - payload: Record - ): Promise => { - const response = await fetch( - `http://127.0.0.1:${env.ORCA_AGENT_HOOK_PORT}/hook/${source}`, - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Orca-Agent-Hook-Token': env.ORCA_AGENT_HOOK_TOKEN - }, - body: JSON.stringify(buildBody(payload)) - } - ) - expect(response.status).toBe(204) - } - - await postHook('codex', { - hook_event_name: 'UserPromptSubmit', - prompt: 'parent codex' - }) - await postHook('claude', { - hook_event_name: 'Stop', - last_assistant_message: 'child finished' - }) - - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - paneKey: PANE, - state: 'working', - prompt: 'parent codex', - agentType: 'codex' - }) - ]) - const snapshot = server.getStatusSnapshot()[0] - expect(snapshot.lastAssistantMessage).toBeUndefined() - expect(listener).toHaveBeenCalledTimes(1) - expect(listener).toHaveBeenLastCalledWith( - expect.objectContaining({ - payload: expect.objectContaining({ - state: 'working', - prompt: 'parent codex', - agentType: 'codex' - }) - }) - ) - } finally { - server.stop() - } - }) - - it('accepts form-encoded hook posts from Unix managed scripts', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - try { - const env = server.buildPtyEnv() - const params = new URLSearchParams({ - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'repo::/tmp/worktree with "quotes"', - env: 'production', - version: env.ORCA_AGENT_HOOK_VERSION ?? '', - payload: JSON.stringify({ - hook_event_name: 'UserPromptSubmit', - prompt: 'form encoded' - }) - }) - - const response = await fetch(`http://127.0.0.1:${env.ORCA_AGENT_HOOK_PORT}/hook/claude`, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'X-Orca-Agent-Hook-Token': env.ORCA_AGENT_HOOK_TOKEN - }, - body: params - }) - expect(response.status).toBe(204) - - const listener = vi.fn() - server.setListener(listener) - - expect(listener).toHaveBeenCalledWith( - expect.objectContaining({ - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'repo::/tmp/worktree with "quotes"', - connectionId: null, - receivedAt: expect.any(Number), - stateStartedAt: expect.any(Number), - payload: expect.objectContaining({ - state: 'working', - prompt: 'form encoded', - agentType: 'claude' - }) - }) - ) - } finally { - server.stop() - } - }) -}) diff --git a/src/main/agent-hooks/server/testing/identity/server-ai-vault-liveness.test.ts b/src/main/agent-hooks/server/testing/identity/server-ai-vault-liveness.test.ts deleted file mode 100644 index 9608bb152df..00000000000 --- a/src/main/agent-hooks/server/testing/identity/server-ai-vault-liveness.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import '../memory-agent-identity-store.test-fixture' -import { mkdtemp, rm } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { describe, expect, it } from 'vitest' -import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' -import { AgentHookServer } from '../../agent-hook-server' - -const PANE = makePaneKey('external-live', '11111111-1111-4111-8111-111111111111') -const PROVIDER_SESSION = { key: 'session_id' as const, id: 'session-live' } - -function seedLocalIdentity(server: AgentHookServer): void { - server.ingestRemote( - { - paneKey: PANE, - providerSession: PROVIDER_SESSION, - payload: { state: 'working', prompt: 'test', agentType: 'gemini' } - }, - 'seed-connection' - ) - server.ingestTerminalStatus({ - paneKey: PANE, - connectionId: null, - payload: { state: 'working', prompt: 'test', agentType: 'gemini' } - }) -} - -describe('AgentHookServer AI Vault liveness identity', () => { - it('hydrates dismissed provider identity without reviving visible status', async () => { - const userDataPath = await mkdtemp(join(tmpdir(), 'orca-ai-vault-liveness-')) - const first = new AgentHookServer() - try { - await first.start({ env: 'production', userDataPath }) - seedLocalIdentity(first) - first.dropStatusEntry(PANE) - first.flushStatusPersistSync() - first.stop() - - const second = new AgentHookServer() - await second.start({ env: 'production', userDataPath }) - try { - expect(second.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - providerSession: PROVIDER_SESSION, - providerSessionOnly: true, - restoredUnconfirmed: true - }) - ]) - expect(second.getStatusChangeSnapshot()).toEqual([]) - } finally { - second.stop() - } - } finally { - first.stop() - await rm(userDataPath, { recursive: true, force: true }) - } - }) -}) diff --git a/src/main/agent-hooks/server/testing/identity/server-claude-resume-record-continuity.test.ts b/src/main/agent-hooks/server/testing/identity/server-claude-resume-record-continuity.test.ts deleted file mode 100644 index 35b2bdc1a6e..00000000000 --- a/src/main/agent-hooks/server/testing/identity/server-claude-resume-record-continuity.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, beforeEach, expect, it, vi } from 'vitest' -import { AgentHookServer } from '../../agent-hook-server' -import { HOOK_SILENCE_BEFORE_PROGRAM_STATUS_FALLBACK_MS } from '../../program-status/hook-precedence' -import { buildBody, ingestProgramStatusOsc, PANE, postHookEvent } from '../server.test-fixtures' - -const SESSION = '70efcb3f-ae17-4863-9318-649f5469408b' - -let dir: string -let server: AgentHookServer - -beforeEach(async () => { - dir = mkdtempSync(join(tmpdir(), 'orca-claude-continuation-')) - server = new AgentHookServer() - await server.start({ env: 'production', userDataPath: dir }) -}) - -afterEach(() => { - vi.useRealTimers() - server.stop() - rmSync(dir, { recursive: true, force: true }) -}) - -async function claudeHook(payload: Record): Promise { - const response = await postHookEvent(server, buildBody({ session_id: SESSION, ...payload })) - expect(response.status).toBe(204) -} - -function recordedSession() { - return server.getStatusSnapshot()[0]?.providerSession -} - -function seedResume(providerSession: { cwd?: string; effort?: string }): void { - server.recordLaunchResumeIdentity({ - paneKey: PANE, - worktreeId: 'wt-1', - agentType: 'claude', - providerSession: { key: 'session_id', id: SESSION, ...providerSession }, - launchedAt: Date.now() - }) -} - -it('keeps the start folder and effort when a terminal status row precedes the next hook', async () => { - await claudeHook({ hook_event_name: 'SessionStart', source: 'startup', cwd: '/repo' }) - await claudeHook({ - hook_event_name: 'PostToolUse', - tool_name: 'Bash', - cwd: '/repo/sub', - effort: { level: 'max' } - }) - await claudeHook({ hook_event_name: 'Stop', cwd: '/repo/sub', effort: { level: 'max' } }) - vi.useFakeTimers({ toFake: ['Date'] }) - vi.setSystemTime(Date.now() + HOOK_SILENCE_BEFORE_PROGRAM_STATUS_FALLBACK_MS) - // Claude reports OSC 7501 `working` just before UserPromptSubmit. - ingestProgramStatusOsc(server, '\x1b]7501;state=working:app=claude-code\x1b\\') - await claudeHook({ hook_event_name: 'UserPromptSubmit', prompt: 'next', cwd: '/repo/sub' }) - - expect(recordedSession()).toMatchObject({ id: SESSION, cwd: '/repo', effort: 'max' }) -}) - -it('records where a resumed process really started over the folder its seed named', async () => { - seedResume({ cwd: '/repo' }) - await claudeHook({ hook_event_name: 'SessionStart', source: 'resume', cwd: '/elsewhere' }) - - expect(recordedSession()?.cwd).toBe('/elsewhere') -}) - -it('names the pane session from a --fork-session start, which Claude 2.1.214+ reports as fork', async () => { - // Captured from Claude 2.1.321 `claude --resume --fork-session` before any message. - await claudeHook({ - session_id: 'b47ec7fc-07e4-4012-8b28-1d5daa938f52', - transcript_path: - '/Users/u/.claude/projects/-private-tmp-w39942fork/b47ec7fc-07e4-4012-8b28-1d5daa938f52.jsonl', - cwd: '/private/tmp/w39942fork', - hook_event_name: 'SessionStart', - source: 'fork' - }) - - expect(recordedSession()).toMatchObject({ - id: 'b47ec7fc-07e4-4012-8b28-1d5daa938f52', - cwd: '/private/tmp/w39942fork' - }) -}) diff --git a/src/main/agent-hooks/server/testing/identity/server-launch-resume-identity.test.ts b/src/main/agent-hooks/server/testing/identity/server-launch-resume-identity.test.ts deleted file mode 100644 index 396f7741356..00000000000 --- a/src/main/agent-hooks/server/testing/identity/server-launch-resume-identity.test.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, postHookEvent, PANE } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ track: trackMock })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ getCohortAtEmit: getCohortAtEmitMock })) - -const RESUMED = { key: 'session_id' as const, id: 'resumed-session' } - -// Codex may stay silent until the resumed pane's first turn; seed identity at launch for every reader. -describe('a resume launch seeds the pane identity', () => { - const servers: AgentHookServer[] = [] - let userDataPath: string - - beforeEach(() => { - _internals.resetCachesForTests() - getCohortAtEmitMock.mockReturnValue({}) - userDataPath = mkdtempSync(join(tmpdir(), 'orca-launch-resume-identity-')) - }) - - afterEach(() => { - for (const server of servers) { - server.stop() - } - servers.length = 0 - rmSync(userDataPath, { recursive: true, force: true }) - vi.restoreAllMocks() - }) - - async function startServer(): Promise { - const server = new AgentHookServer() - servers.push(server) - await server.start({ env: 'production', userDataPath }) - return server - } - - it('yields to a newer agent report', async () => { - const server = await startServer() - const launchedAt = Date.now() - 1_000 - const response = await postHookEvent( - server, - buildBody({ hook_event_name: 'SessionStart', session_id: 'agent-reported' }), - '/hook/codex' - ) - expect(response.status).toBe(204) - server.recordLaunchResumeIdentity({ - paneKey: PANE, - agentType: 'codex', - providerSession: RESUMED, - launchedAt - }) - expect(server.getStatusSnapshotForPane(PANE)[0]?.providerSession?.id).toBe('agent-reported') - }) - - it("replaces a row left by the pane's previous process", async () => { - const server = await startServer() - const response = await postHookEvent( - server, - buildBody({ hook_event_name: 'Stop', session_id: 'previous-run' }), - '/hook/codex' - ) - expect(response.status).toBe(204) - server.recordLaunchResumeIdentity({ - paneKey: PANE, - agentType: 'codex', - providerSession: RESUMED, - launchedAt: Date.now() + 1_000 - }) - expect(server.getStatusSnapshotForPane(PANE)[0]).toMatchObject({ - providerSession: RESUMED, - providerSessionOnly: true - }) - - await postHookEvent( - server, - buildBody({ hook_event_name: 'UserPromptSubmit', session_id: RESUMED.id, prompt: 'go on' }), - '/hook/codex' - ) - const [row] = server.getStatusSnapshotForPane(PANE) - expect(row?.providerSessionOnly).toBeUndefined() - expect(row).toMatchObject({ state: 'working', providerSession: RESUMED }) - }) - - it('keeps the seeded identity when terminal evidence starts the first turn', async () => { - const server = await startServer() - server.recordLaunchResumeIdentity({ - paneKey: PANE, - agentType: 'opencode2', - providerSession: RESUMED, - launchedAt: Date.now() - }) - server.ingestTerminalStatus({ - paneKey: PANE, - origin: 'process', - payload: { state: 'working', prompt: '', agentType: 'opencode2' } - }) - expect(server.getStatusSnapshotForPane(PANE)[0]).toMatchObject({ - state: 'working', - providerSession: RESUMED - }) - }) - - it('keeps the seeded identity across a host restart', async () => { - const server = await startServer() - server.recordLaunchResumeIdentity({ - paneKey: PANE, - worktreeId: 'wt-1', - agentType: 'codex', - providerSession: RESUMED, - launchedAt: Date.now() - }) - server.stop() - servers.length = 0 - const restarted = await startServer() - expect(restarted.getStatusSnapshotForPane(PANE)).toEqual([ - expect.objectContaining({ - agentType: 'codex', - providerSession: RESUMED, - providerSessionOnly: true - }) - ]) - }) -}) diff --git a/src/main/agent-hooks/server/testing/identity/server-nested-agent-boundaries.test.ts b/src/main/agent-hooks/server/testing/identity/server-nested-agent-boundaries.test.ts deleted file mode 100644 index 3721d72103f..00000000000 --- a/src/main/agent-hooks/server/testing/identity/server-nested-agent-boundaries.test.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer } from '../../agent-hook-server' -import { buildBody, PANE, postHookEvent } from '../server.test-fixtures' - -vi.mock('../../../../telemetry/client', () => ({ track: vi.fn() })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ - getCohortAtEmit: vi.fn(() => ({ nth_repo_added: 2 })) -})) - -const route = { paneKey: PANE, tabId: 'tab-1', worktreeId: 'wt-1' } - -afterEach(() => { - vi.useRealTimers() - vi.restoreAllMocks() -}) - -describe('nested provider ownership boundaries', () => { - it.each([ - ['ssh-b', 'wt-1', 'codex'], - ['conn-1', 'wt-2', 'codex'], - ['conn-1', 'wt-1', 'claude'] - ] as const)( - 'scopes ownership to host %s and workspace %s', - (connectionId, worktreeId, agentType) => { - const server = new AgentHookServer() - server.ingestRemote( - { ...route, payload: { state: 'working', prompt: 'Parent', agentType: 'claude' } }, - 'conn-1' - ) - server.ingestRemote( - { - ...route, - worktreeId, - payload: { state: 'working', prompt: 'Other', agentType: 'codex' } - }, - connectionId - ) - expect(server.getStatusSnapshot()[0]).toMatchObject({ agentType, connectionId, worktreeId }) - } - ) - - it.each([ - [null, 'wsl:Ubuntu'], - ['wsl:Ubuntu', null] - ] as const)('retains WSL ownership across %s to %s transport', (before, after) => { - const server = new AgentHookServer() - const worktreeId = 'repo:://wsl.localhost/Ubuntu/home/user/project' - server.ingestRemote( - { - ...route, - worktreeId, - payload: { state: 'working', prompt: 'Parent', agentType: 'claude' } - }, - before - ) - server.ingestRemote( - { ...route, worktreeId, payload: { state: 'working', prompt: 'Nested', agentType: 'codex' } }, - after - ) - expect(server.getStatusSnapshot()[0]).toMatchObject({ agentType: 'claude', prompt: 'Parent' }) - }) - - it('admits a local HTTP owner despite a remote pane-key collision', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - try { - server.ingestRemote( - { ...route, payload: { state: 'working', prompt: 'Remote', agentType: 'claude' } }, - 'ssh-a' - ) - const response = await postHookEvent( - server, - buildBody({ - hook_event_name: 'UserPromptSubmit', - session_id: 'local-codex', - prompt: 'Local' - }), - '/hook/codex' - ) - expect(response.status).toBe(204) - expect(server.getStatusSnapshot()[0]).toMatchObject({ - connectionId: null, - agentType: 'codex', - prompt: 'Local', - providerSession: { id: 'local-codex' } - }) - } finally { - server.stop() - } - }) - - it('keeps nested Pi identity-only metadata off an active owner and permits it after completion', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - const server = new AgentHookServer() - server.ingestRemote( - { - ...route, - payload: { state: 'working', prompt: 'Parent work', agentType: 'claude' }, - providerSession: { key: 'session_id', id: 'claude-parent' } - }, - 'conn-1' - ) - const before = server.getStatusSnapshot() - const pi = { - ...route, - providerSessionOnly: true, - providerSession: { - key: 'session_id' as const, - id: 'pi-child', - transcriptPath: '/tmp/pi-child.jsonl' - }, - payload: { state: 'done' as const, prompt: '', agentType: 'pi' as const } - } - server.ingestRemote(pi, 'conn-1') - expect(server.getStatusSnapshot()).toEqual(before) - server.ingestRemote( - { ...route, payload: { state: 'done', prompt: 'Parent work', agentType: 'claude' } }, - 'conn-1' - ) - server.ingestRemote(pi, 'conn-1') - expect(server.getStatusSnapshot()[0]).toMatchObject({ - agentType: 'pi', - providerSessionOnly: true, - providerSession: { id: 'pi-child' } - }) - }) -}) diff --git a/src/main/agent-hooks/server/testing/identity/server-nested-agent-model.test.ts b/src/main/agent-hooks/server/testing/identity/server-nested-agent-model.test.ts deleted file mode 100644 index 6691b0afd49..00000000000 --- a/src/main/agent-hooks/server/testing/identity/server-nested-agent-model.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, postHookEvent } from '../server.test-fixtures' - -vi.mock('../../../../telemetry/client', () => ({ - track: vi.fn() -})) - -vi.mock('../../../../telemetry/cohort-classifier', () => ({ - getCohortAtEmit: vi.fn(() => ({ nth_repo_added: 2 })) -})) - -beforeEach(() => { - _internals.resetCachesForTests() - vi.useFakeTimers() -}) - -afterEach(() => { - vi.useRealTimers() - vi.restoreAllMocks() -}) - -describe('AgentHookServer nested agent model fence', () => { - // Readers retain sparse model labels, so a transient child label could remain on the parent. - it('never pushes a nested codex model to the renderer from real hook bodies', async () => { - vi.useRealTimers() - const server = new AgentHookServer() - await server.start({ env: 'production' }) - const pushed: { agentType?: string; model?: string }[] = [] - server.setListener((event) => pushed.push(event.payload)) - try { - const steps: [string, Record][] = [ - ['/hook/claude', { hook_event_name: 'UserPromptSubmit', session_id: 'c-1', prompt: 'p' }], - [ - '/hook/codex', - { - hook_event_name: 'SessionStart', - session_id: 'x-1', - model: 'gpt-6-astra', - source: 'startup' - } - ], - [ - '/hook/codex', - { - hook_event_name: 'UserPromptSubmit', - session_id: 'x-1', - prompt: 'n', - model: 'gpt-6-astra' - } - ], - [ - '/hook/codex', - { - hook_event_name: 'PreToolUse', - session_id: 'x-1', - model: 'gpt-6-astra', - tool_name: 'shell' - } - ], - [ - '/hook/codex', - { - hook_event_name: 'Stop', - session_id: 'x-1', - model: 'gpt-6-astra', - stop_hook_active: false - } - ], - ['/hook/claude', { hook_event_name: 'Stop', session_id: 'c-1' }] - ] - for (const [path, body] of steps) { - expect((await postHookEvent(server, buildBody(body), path)).status).toBe(204) - } - const [row] = server.getStatusSnapshot() - expect(row).toMatchObject({ agentType: 'claude', state: 'done' }) - expect(row?.model).toBeUndefined() - } finally { - server.stop() - } - - expect(pushed).toHaveLength(2) - expect(pushed.every((payload) => payload.agentType === 'claude')).toBe(true) - expect(pushed.map((payload) => payload.model)).not.toContain('gpt-6-astra') - }) -}) diff --git a/src/main/agent-hooks/server/testing/identity/server-nested-same-provider-owner.test.ts b/src/main/agent-hooks/server/testing/identity/server-nested-same-provider-owner.test.ts deleted file mode 100644 index 7dbc60dff96..00000000000 --- a/src/main/agent-hooks/server/testing/identity/server-nested-same-provider-owner.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer } from '../../agent-hook-server' -import { buildBody, PANE, postHookEvent } from '../server.test-fixtures' -import type { probeAgentProcessPresence } from '../../../../../shared/agent-status/process/agent-process-presence-probe' - -vi.mock('../../../../telemetry/client', () => ({ track: vi.fn() })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ getCohortAtEmit: () => ({}) })) -const probe = vi.hoisted(() => vi.fn(async () => 'live')) -vi.mock('../../../../../shared/agent-status/process/agent-process-presence-probe', () => ({ - probeAgentProcessPresence: probe -})) -const servers: AgentHookServer[] = [] -const parent = { pid: 4001, platform: 'linux', startTime: 'birth-4001' } -const child = { pid: 4002, platform: 'linux', startTime: 'birth-4002' } - -afterEach(() => { - for (const server of servers.splice(0)) { - server.stop() - } - probe.mockReset().mockResolvedValue('live') -}) - -async function claudeHook( - server: AgentHookServer, - process: typeof parent, - payload: Record -): Promise { - await postHookEvent(server, buildBody(payload, { agentProcess: JSON.stringify(process) })) -} - -async function parentWorking(): Promise { - const server = new AgentHookServer() - servers.push(server) - await server.start({ env: 'production' }) - await claudeHook(server, parent, { - hook_event_name: 'UserPromptSubmit', - session_id: 'claude-parent', - prompt: 'Parent task' - }) - return server -} - -describe('a second Claude process in the same pane', () => { - it('does not replace the live owner row when a nested claude -p fails', async () => { - const server = await parentWorking() - const emitted = vi.fn() - server.setListener(emitted) - await claudeHook(server, child, { - hook_event_name: 'UserPromptSubmit', - session_id: 'claude-child', - prompt: 'Child task' - }) - await claudeHook(server, child, { - hook_event_name: 'StopFailure', - session_id: 'claude-child', - error: 'rate_limit' - }) - const row = server.getStatusSnapshot().find((entry) => entry.paneKey === PANE) - expect(row).toMatchObject({ - state: 'working', - prompt: 'Parent task', - providerSession: { id: 'claude-parent' } - }) - expect(emitted.mock.calls.some(([event]) => event.payload.state === 'done')).toBe(false) - }) - - it('lets a new Claude take the pane once the old owner process exited', async () => { - const server = await parentWorking() - probe.mockResolvedValue('exited') - await claudeHook(server, child, { - hook_event_name: 'UserPromptSubmit', - session_id: 'claude-next', - prompt: 'Next task' - }) - const row = server.getStatusSnapshot().find((entry) => entry.paneKey === PANE) - expect(row).toMatchObject({ - state: 'working', - prompt: 'Next task', - providerSession: { id: 'claude-next' } - }) - }) -}) diff --git a/src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-guards.test.ts b/src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-guards.test.ts deleted file mode 100644 index e69358a1ab7..00000000000 --- a/src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-guards.test.ts +++ /dev/null @@ -1,410 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, PANE, RUNNING_SHELL } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ - track: trackMock -})) - -vi.mock('../../../../telemetry/cohort-classifier', () => ({ - getCohortAtEmit: getCohortAtEmitMock -})) - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -describe('AgentHookServer listener replay', () => { - it('infers a cancel of a live Claude main agent turn and keeps the shell it leaves running as monitoring', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - claudeRunningNonAgentTask: true, - payload: { - state: 'working', - prompt: 'run in background', - agentType: 'claude', - mainAgent: { state: 'working', stateStartedAt: 900 } - } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'run in background', - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - ).toBe(true) - // Cancel the main agent without discarding live shell inventory or marking the working row interrupted. - const inferred = server.getStatusSnapshot()[0] - expect(inferred).toMatchObject({ - state: 'working', - workingMode: 'monitoring', - mainAgent: { state: 'done', outcome: 'cancellation', stateStartedAt: 1_500 } - }) - expect(inferred.interrupted).toBeUndefined() - expect(server._getStateForTests().claudeRunningNonAgentTaskPaneKeys.has(PANE)).toBe(true) - } finally { - vi.useRealTimers() - } - }) - - it("starts a relayed Claude pane's cancel clock at each cancel, not at an earlier one", () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - const relayTurn = (prompt: string, startedAt: number): void => - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { - state: 'working', - prompt, - agentType: 'claude', - mainAgent: { state: 'working', stateStartedAt: startedAt } - } - }, - 'conn-1' - ) - const cancel = (prompt: string): boolean => { - const baseline = server.getStatusSnapshot()[0] - return server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: prompt, - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - } - relayTurn('first', 900) - vi.setSystemTime(1_500) - expect(cancel('first')).toBe(true) - - // Relay-owned turns must not inherit the local record's earlier cancellation clock. - vi.setSystemTime(5_000) - relayTurn('second', 5_000) - vi.setSystemTime(6_000) - expect(cancel('second')).toBe(true) - expect(server.getStatusSnapshot()[0]).toMatchObject({ - state: 'done', - mainAgent: { state: 'done', outcome: 'cancellation', stateStartedAt: 6_000 } - }) - } finally { - vi.useRealTimers() - } - }) - - it('infers a cancel of a live Claude main agent turn beside a working subagent and keeps the row working', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { - state: 'working', - prompt: 'delegate', - agentType: 'claude', - subagents: [{ id: 'a1', state: 'working', startedAt: 900 }], - mainAgent: { state: 'working', stateStartedAt: 900 } - } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'delegate', - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - ).toBe(true) - // Relayed rows carry their own child evidence; main-agent cancellation must preserve it. - expect(server.getStatusSnapshot()[0]).toMatchObject({ - state: 'working', - subagents: [{ id: 'a1', state: 'working' }], - mainAgent: { state: 'done', outcome: 'cancellation' } - }) - expect(server.getStatusSnapshot()[0].workingMode).toBeUndefined() - } finally { - vi.useRealTimers() - } - }) - - it('does not infer a cancel at the idle prompt of a Claude row held open by child work', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - claudeRunningNonAgentTask: true, - payload: { - state: 'working', - workingMode: 'monitoring', - prompt: 'run in background', - agentType: 'claude', - mainAgent: { state: 'done', stateStartedAt: 900 } - } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - // Ctrl+C at an idle lead's prompt stops none of the child work shown. - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'run in background', - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - ).toBe(false) - expect(server.getStatusSnapshot()[0]).toMatchObject({ - state: 'working', - workingMode: 'monitoring', - mainAgent: { state: 'done' } - }) - } finally { - vi.useRealTimers() - } - }) - - it('blocks local HTTP interrupt inference for provider-owned work without exposing transport metadata', async () => { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - try { - const env = server.buildPtyEnv() - const postHook = (payload: Record): Promise => - fetch(`http://127.0.0.1:${env.ORCA_AGENT_HOOK_PORT}/hook/claude`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Orca-Agent-Hook-Token': env.ORCA_AGENT_HOOK_TOKEN - }, - body: JSON.stringify(buildBody(payload)) - }) - - await expect( - postHook({ hook_event_name: 'UserPromptSubmit', prompt: 'run in background' }) - ).resolves.toMatchObject({ status: 204 }) - await expect( - postHook({ hook_event_name: 'Stop', background_tasks: [RUNNING_SHELL] }) - ).resolves.toMatchObject({ status: 204 }) - const baseline = server.getStatusSnapshot()[0] - - expect(baseline).not.toHaveProperty('claudeRunningNonAgentTask') - expect(baseline).toMatchObject({ state: 'working', workingMode: 'monitoring' }) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'run in background', - baselineAgentType: 'claude', - intent: 'plain-escape' - }) - ).toBe(false) - - await expect( - postHook({ - hook_event_name: 'Stop', - background_tasks: [], - session_crons: [{ id: 'cron-1' }] - }) - ).resolves.toMatchObject({ status: 204 }) - const cronBaseline = server.getStatusSnapshot()[0] - expect(server._getStateForTests().claudeActiveSessionCronPaneKeys.has(PANE)).toBe(true) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: cronBaseline.receivedAt, - baselineStateStartedAt: cronBaseline.stateStartedAt, - baselinePrompt: 'run in background', - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - ).toBe(false) - } finally { - server.stop() - } - }) - - it('uses replayed Claude background metadata only before a live observation', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - isReplay: true, - claudeRunningNonAgentTask: true, - payload: { state: 'working', prompt: 'stale replay', agentType: 'claude' } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'stale replay', - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - ).toBe(false) - - vi.setSystemTime(1_500) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - claudeRunningNonAgentTask: false, - payload: { state: 'working', prompt: 'stale replay', agentType: 'claude' } - }, - 'conn-1' - ) - vi.setSystemTime(2_000) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - isReplay: true, - claudeRunningNonAgentTask: true, - payload: { state: 'working', prompt: 'stale replay', agentType: 'claude' } - }, - 'conn-1' - ) - const liveBaseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(2_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: liveBaseline.receivedAt, - baselineStateStartedAt: liveBaseline.stateStartedAt, - baselinePrompt: 'stale replay', - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - ).toBe(true) - } finally { - vi.useRealTimers() - } - }) - - it('preserves an inferred interrupted row when OpenCode immediately reports SessionIdle', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - const listener = vi.fn() - server.setListener(listener) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { state: 'working', prompt: 'long task', agentType: 'opencode' } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'long task', - baselineAgentType: 'opencode', - intent: 'plain-escape', - inputCount: 2 - }) - ).toBe(true) - - vi.setSystemTime(1_501) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { state: 'done', prompt: 'long task', agentType: 'opencode' } - }, - 'conn-1' - ) - - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - paneKey: PANE, - state: 'done', - prompt: 'long task', - agentType: 'opencode', - interrupted: true, - receivedAt: 1_500, - stateStartedAt: 1_500 - }) - ]) - expect(listener).toHaveBeenLastCalledWith( - expect.objectContaining({ - paneKey: PANE, - payload: expect.objectContaining({ state: 'done', interrupted: true }) - }) - ) - } finally { - vi.useRealTimers() - } - }) -}) diff --git a/src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-resurrection.test.ts b/src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-resurrection.test.ts deleted file mode 100644 index 8e7022748c9..00000000000 --- a/src/main/agent-hooks/server/testing/interruptions/server-interrupt-inference-resurrection.test.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { PANE } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ - track: trackMock -})) - -vi.mock('../../../../telemetry/cohort-classifier', () => ({ - getCohortAtEmit: getCohortAtEmitMock -})) - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -describe('AgentHookServer listener replay', () => { - it('does not let late same-turn working hooks resurrect an inferred interrupt', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { state: 'working', prompt: 'long task', agentType: 'pi' } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'long task', - baselineAgentType: 'pi', - intent: 'ctrl-c' - }) - ).toBe(true) - - vi.setSystemTime(6_000) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { - state: 'working', - prompt: 'long task', - agentType: 'pi', - toolName: 'bash', - toolInput: '/bin/sleep 90' - } - }, - 'conn-1' - ) - - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - state: 'done', - prompt: 'long task', - agentType: 'pi', - interrupted: true, - receivedAt: 1_500, - stateStartedAt: 1_500 - }) - ]) - } finally { - vi.useRealTimers() - } - }) - - it('allows an immediate same-prompt retry after an inferred interrupt', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - hasExplicitPrompt: true, - payload: { state: 'working', prompt: 'retryable task', agentType: 'pi' } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'retryable task', - baselineAgentType: 'pi', - intent: 'ctrl-c' - }) - ).toBe(true) - - vi.setSystemTime(2_000) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - hasExplicitPrompt: true, - payload: { state: 'working', prompt: 'retryable task', agentType: 'pi' } - }, - 'conn-1' - ) - - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - state: 'working', - prompt: 'retryable task', - agentType: 'pi', - receivedAt: 2_000, - stateStartedAt: 2_000 - }) - ]) - } finally { - vi.useRealTimers() - } - }) - - it('suppresses same-turn Claude tool progress after the stale suppression window', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - hasExplicitPrompt: true, - hookEventName: 'UserPromptSubmit', - payload: { state: 'working', prompt: 'repeat task', agentType: 'claude' } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'repeat task', - baselineAgentType: 'claude', - intent: 'ctrl-c' - }) - ).toBe(true) - - vi.setSystemTime(16_501) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - hasExplicitPrompt: true, - hookEventName: 'PostToolUse', - payload: { - state: 'working', - prompt: 'repeat task', - agentType: 'claude', - toolName: 'bash', - toolInput: '/bin/sleep 90' - } - }, - 'conn-1' - ) - - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - state: 'done', - prompt: 'repeat task', - agentType: 'claude', - interrupted: true, - receivedAt: 1_500, - stateStartedAt: 1_500 - }) - ]) - } finally { - vi.useRealTimers() - } - }) - - it('allows generic non-explicit same-prompt working after the stale suppression window', () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - try { - const server = new AgentHookServer() - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { state: 'working', prompt: 'repeat task', agentType: 'pi' } - }, - 'conn-1' - ) - const baseline = server.getStatusSnapshot()[0] - - vi.setSystemTime(1_500) - expect( - server.inferInterrupt({ - paneKey: PANE, - baselineUpdatedAt: baseline.receivedAt, - baselineStateStartedAt: baseline.stateStartedAt, - baselinePrompt: 'repeat task', - baselineAgentType: 'pi', - intent: 'ctrl-c' - }) - ).toBe(true) - - vi.setSystemTime(16_501) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { state: 'working', prompt: 'repeat task', agentType: 'pi' } - }, - 'conn-1' - ) - - expect(server.getStatusSnapshot()).toEqual([ - expect.objectContaining({ - state: 'working', - prompt: 'repeat task', - agentType: 'pi', - interrupted: undefined, - receivedAt: 16_501, - stateStartedAt: 16_501 - }) - ]) - } finally { - vi.useRealTimers() - } - }) -}) diff --git a/src/main/agent-hooks/server/testing/main-agent/server-main-agent-turn-verdicts.test.ts b/src/main/agent-hooks/server/testing/main-agent/server-main-agent-turn-verdicts.test.ts deleted file mode 100644 index f711a261ae2..00000000000 --- a/src/main/agent-hooks/server/testing/main-agent/server-main-agent-turn-verdicts.test.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { appendFileSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, postHookEvent, PANE } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ track: trackMock })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ getCohortAtEmit: getCohortAtEmitMock })) - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) - // Fake only Date so real hook sockets keep working. - vi.useFakeTimers({ toFake: ['Date'] }) - vi.setSystemTime(1_000_000) -}) - -afterEach(() => { - vi.useRealTimers() - vi.restoreAllMocks() -}) - -describe('main agent turn verdicts and clocks', () => { - let server: AgentHookServer - - beforeEach(async () => { - server = new AgentHookServer() - await server.start({ env: 'production' }) - }) - - afterEach(() => { - server.stop() - }) - - async function post(path: string, payload: Record): Promise { - const response = await postHookEvent(server, buildBody(payload), path) - expect(response.status).toBe(204) - } - - it.each(['idle_prompt notification', 'session end'] as const)( - 'keeps a cancelled Grok turn verdict when a %s restates done', - async (restatement) => { - const turn = { sessionId: 'session-1', promptId: 'prompt-1' } - await post('/hook/grok', { hookEventName: 'user_prompt_submit', ...turn, prompt: 'go' }) - await post('/hook/grok', { hookEventName: 'stop_cancelled', ...turn }) - const cancelled = server.getStatusSnapshot()[0]?.mainAgent - expect(cancelled).toMatchObject({ state: 'done', outcome: 'cancellation' }) - - // Advance past late-event suppression so the restatement is published. - vi.setSystemTime(1_030_000) - await post( - '/hook/grok', - restatement === 'session end' - ? { hookEventName: 'session_end', ...turn } - : { hookEventName: 'notification', ...turn, notificationType: 'idle_prompt' } - ) - - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'done', mainAgent: cancelled }) - } - ) - - it('keeps a recorded Codex cancellation across a late root Stop', async () => { - const directory = mkdtempSync(join(tmpdir(), 'codex-turn-verdict-')) - const transcriptPath = join(directory, 'rollout.jsonl') - try { - writeFileSync( - transcriptPath, - '{"type":"event_msg","payload":{"type":"task_started","turn_id":"turn-1"}}\n' - ) - await post('/hook/codex', { - hook_event_name: 'UserPromptSubmit', - prompt: 'long task', - transcript_path: transcriptPath - }) - vi.setSystemTime(1_001_000) - appendFileSync( - transcriptPath, - '{"type":"event_msg","payload":{"type":"turn_aborted","turn_id":"turn-1","reason":"interrupted"}}\n' - ) - await vi.waitFor( - () => expect(server.getStatusSnapshot()[0]?.mainAgent?.outcome).toBe('cancellation'), - { timeout: 2_000 } - ) - } finally { - rmSync(directory, { recursive: true, force: true }) - } - const cancelled = server.getStatusSnapshot()[0]?.mainAgent - expect(cancelled).toMatchObject({ state: 'done', outcome: 'cancellation' }) - - vi.setSystemTime(1_002_000) - await post('/hook/codex', { hook_event_name: 'Stop' }) - // Older readers need interrupted even when they cannot read mainAgent. - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'done', interrupted: true }) - // Advance past suppression before child activity republishes the main agent. - vi.setSystemTime(1_060_000) - await post('/hook/codex', { hook_event_name: 'SubagentStart', agent_id: 'child-1' }) - - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'working', mainAgent: cancelled }) - }) - - it('keeps a host-confirmed Codex cancellation across a late relayed root Stop', () => { - const relayed = ( - hookEventName: string, - payload: Record, - extra: Record = {} - ) => - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - hookEventName, - ...extra, - payload: { prompt: 'long task', agentType: 'codex', ...payload } - }, - 'conn-1' - ) - relayed('UserPromptSubmit', { state: 'working' }, { hasExplicitPrompt: true }) - vi.setSystemTime(1_001_000) - server.ingestRemote( - { - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { - prompt: 'long task', - agentType: 'codex', - state: 'done', - interrupted: true, - mainAgent: { state: 'done', outcome: 'cancellation', stateStartedAt: 1_001_000 } - } - }, - 'conn-1' - ) - const cancelled = server.getStatusSnapshot()[0]?.mainAgent - expect(cancelled).toMatchObject({ state: 'done', outcome: 'cancellation' }) - - vi.setSystemTime(1_002_000) - relayed('Stop', { state: 'done' }) - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'done', interrupted: true }) - vi.setSystemTime(1_060_000) - relayed( - 'SubagentStart', - { - state: 'working', - subagents: [{ id: 'child-1', state: 'working', startedAt: 1_060_000 }] - }, - { toolAgentId: 'child-1' } - ) - - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'working', mainAgent: cancelled }) - }) -}) diff --git a/src/main/agent-hooks/server/testing/main-agent/server-turn-started-at.test.ts b/src/main/agent-hooks/server/testing/main-agent/server-turn-started-at.test.ts deleted file mode 100644 index c315a61c31f..00000000000 --- a/src/main/agent-hooks/server/testing/main-agent/server-turn-started-at.test.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { readSavedStatus } from '../persistence/last-status.test-fixtures' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, postHookEvent, PANE } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ track: trackMock })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ getCohortAtEmit: getCohortAtEmitMock })) - -beforeEach(() => { - _internals.resetCachesForTests() - getCohortAtEmitMock.mockReturnValue({}) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -// Separate host timestamps by advancing real time between events. -async function nextMillisecond(): Promise { - await new Promise((resolve) => setTimeout(resolve, 5)) -} - -// Host-stamped turn starts survive reader reloads without reconstructing state history. -describe('the host-stamped turn start', () => { - const servers: AgentHookServer[] = [] - let userDataPath: string - - beforeEach(() => { - userDataPath = mkdtempSync(join(tmpdir(), 'orca-turn-started-at-')) - }) - - afterEach(() => { - for (const server of servers) { - server.stop() - } - servers.length = 0 - rmSync(userDataPath, { recursive: true, force: true }) - }) - - async function startServer(): Promise { - const server = new AgentHookServer() - servers.push(server) - await server.start({ env: 'production', userDataPath }) - return server - } - - async function post(server: AgentHookServer, payload: Record): Promise { - const response = await postHookEvent(server, buildBody(payload)) - expect(response.status).toBe(204) - await nextMillisecond() - } - - function turnStartedAt(server: AgentHookServer): number | undefined { - return server.getStatusSnapshot()[0]?.turnStartedAt - } - - it('is not stamped by a child agent, and the same prompt sent again is a new turn', async () => { - const server = await startServer() - await post(server, { hook_event_name: 'UserPromptSubmit', prompt: 'Rename the module' }) - const started = turnStartedAt(server) - - await post(server, { - hook_event_name: 'UserPromptSubmit', - prompt: 'child task', - agent_id: 'child-1' - }) - expect(turnStartedAt(server)).toBe(started) - - // Esc at a permission prompt fires no hook, so the resend follows the stale wait directly. - await post(server, { hook_event_name: 'PermissionRequest', tool_name: 'Bash', tool_input: {} }) - await post(server, { hook_event_name: 'UserPromptSubmit', prompt: 'Rename the module' }) - expect(turnStartedAt(server)).toBeGreaterThan(started!) - }) - - it('is not stamped by a relayed replay', async () => { - const server = await startServer() - const envelope = { - paneKey: PANE, - tabId: 'tab-1', - source: 'claude' as const, - hookEventName: 'UserPromptSubmit', - payload: { state: 'working' as const, prompt: 'relayed', agentType: 'claude' as const } - } - server.ingestRemote(envelope, 'ssh-turn') - const started = turnStartedAt(server) - expect(started).toEqual(expect.any(Number)) - await nextMillisecond() - - server.ingestRemote({ ...envelope, isReplay: true }, 'ssh-turn') - expect(turnStartedAt(server)).toBe(started) - }) - - // An OSC repaint can land before the prompt hook; it must not count from the finished turn. - it('drops the stamp when a finished main agent runs again with no turn-opening event', async () => { - const server = await startServer() - await post(server, { hook_event_name: 'UserPromptSubmit', prompt: 'Rename the module' }) - await post(server, { hook_event_name: 'Stop' }) - expect(turnStartedAt(server)).toEqual(expect.any(Number)) - - server.ingestTerminalStatus({ - paneKey: PANE, - tabId: 'tab-1', - worktreeId: 'wt-1', - payload: { state: 'working', prompt: 'Rename the module', agentType: 'claude' } - }) - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'working' }) - expect(server.getStatusSnapshot()[0]).not.toHaveProperty('turnStartedAt') - }) - - it('reaches the live push and survives a restart through the status file', async () => { - const server = await startServer() - const pushed: (number | undefined)[] = [] - server.setListener((status) => pushed.push(status.turnStartedAt)) - await post(server, { hook_event_name: 'UserPromptSubmit', prompt: 'Rename the module' }) - await post(server, { hook_event_name: 'PreToolUse', tool_name: 'Bash', tool_input: {} }) - const started = turnStartedAt(server) - expect(pushed.at(-1)).toBe(started) - server.flushStatusPersistSync() - server.stop() - const file = JSON.parse(readSavedStatus(join(userDataPath, 'agent-hooks', 'last-status.json'))) - expect(file.entries[PANE].turnStartedAt).toBe(started) - - const restarted = await startServer() - expect(restarted.getStatusSnapshot()[0]).toMatchObject({ - restoredUnconfirmed: true, - turnStartedAt: started - }) - await post(restarted, { hook_event_name: 'PostToolUse', tool_name: 'Bash', tool_input: {} }) - expect(turnStartedAt(restarted)).toBe(started) - }) -}) diff --git a/src/main/agent-hooks/server/testing/permissions/server-claude-child-permission-lifecycle.test.ts b/src/main/agent-hooks/server/testing/permissions/server-claude-child-permission-lifecycle.test.ts deleted file mode 100644 index e24d6cae7df..00000000000 --- a/src/main/agent-hooks/server/testing/permissions/server-claude-child-permission-lifecycle.test.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, PANE } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ track: trackMock })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ getCohortAtEmit: getCohortAtEmitMock })) - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -describe('Claude child permission lifecycle', () => { - async function createServer(): Promise<{ - server: AgentHookServer - postClaudeHook: (payload: Record) => Promise - }> { - const server = new AgentHookServer() - await server.start({ env: 'production' }) - const env = server.buildPtyEnv() - return { - server, - postClaudeHook: (payload) => - fetch(`http://127.0.0.1:${env.ORCA_AGENT_HOOK_PORT}/hook/claude`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Orca-Agent-Hook-Token': env.ORCA_AGENT_HOOK_TOKEN - }, - body: JSON.stringify(buildBody(payload)) - }) - } - } - - it('clears a child permission when an API error ends that child', async () => { - const { server, postClaudeHook } = await createServer() - try { - await postClaudeHook({ hook_event_name: 'UserPromptSubmit', prompt: 'guarded task' }) - await postClaudeHook({ - hook_event_name: 'PermissionRequest', - agent_id: 'a-blocked', - agent_type: 'general-purpose', - tool_name: 'Bash', - tool_input: { command: 'false' } - }) - // Lead progress replaces the listener wait slot; the server must retain the child prompt. - await postClaudeHook({ hook_event_name: 'PreToolUse', tool_name: 'Read' }) - await postClaudeHook({ - hook_event_name: 'StopFailure', - agent_id: 'a-other', - error: 'rate_limit' - }) - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'waiting', toolName: 'Bash' }) - - await postClaudeHook({ - hook_event_name: 'StopFailure', - agent_id: 'a-blocked', - agent_type: 'general-purpose', - error: 'rate_limit' - }) - - const status = server.getStatusSnapshot()[0] - expect(status).toMatchObject({ paneKey: PANE, state: 'working', agentType: 'claude' }) - expect(status?.toolName).toBe('Read') - expect(status?.interactivePrompt).toBeUndefined() - expect(status?.subagents).toBeUndefined() - } finally { - server.stop() - } - }) - - it('settles a finished lead when its background child fails on a pending permission', async () => { - const { server, postClaudeHook } = await createServer() - try { - await postClaudeHook({ - hook_event_name: 'UserPromptSubmit', - prompt: 'research in background' - }) - await postClaudeHook({ - hook_event_name: 'SubagentStart', - agent_id: 'a6324370b7bede0c7', - agent_type: 'general-purpose' - }) - await postClaudeHook({ - hook_event_name: 'Stop', - last_assistant_message: 'Started the research.', - background_tasks: [{ id: 'a6324370b7bede0c7', type: 'subagent', status: 'running' }] - }) - await postClaudeHook({ - hook_event_name: 'PermissionRequest', - agent_id: 'a6324370b7bede0c7', - agent_type: 'general-purpose', - tool_name: 'Bash', - tool_input: { command: 'false' } - }) - expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'waiting', toolName: 'Bash' }) - - await postClaudeHook({ - hook_event_name: 'StopFailure', - agent_id: 'a6324370b7bede0c7', - agent_type: 'general-purpose', - error: 'rate_limit' - }) - - const status = server.getStatusSnapshot()[0] - expect(status).toMatchObject({ paneKey: PANE, state: 'done', agentType: 'claude' }) - expect(status?.interactivePrompt).toBeUndefined() - expect(status?.subagents).toBeUndefined() - } finally { - server.stop() - } - }) -}) diff --git a/src/main/agent-hooks/server/testing/persistence/server-last-status-child-held-main-agent.test.ts b/src/main/agent-hooks/server/testing/persistence/server-last-status-child-held-main-agent.test.ts deleted file mode 100644 index 34ada9e3b43..00000000000 --- a/src/main/agent-hooks/server/testing/persistence/server-last-status-child-held-main-agent.test.ts +++ /dev/null @@ -1,212 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, postHookEvent, PANE, RUNNING_SHELL } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ track: trackMock })) -vi.mock('../../../../telemetry/cohort-classifier', () => ({ getCohortAtEmit: getCohortAtEmitMock })) - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -const CHILD_PERMISSION = { - hook_event_name: 'PermissionRequest', - agent_id: 'achild-a', - tool_name: 'Bash', - tool_input: { command: 'rm scratch' } -} - -// Persist the settled main-agent fact so child lifecycle hooks, rather than OSC, can settle the restored row. -describe('Claude rows held open by child agents', () => { - let userDataPath: string - - beforeEach(() => { - userDataPath = mkdtempSync(join(tmpdir(), 'orca-child-held-main-agent-')) - }) - - afterEach(() => { - rmSync(userDataPath, { recursive: true, force: true }) - }) - - async function startServer(): Promise { - const server = new AgentHookServer() - await server.start({ env: 'production', userDataPath }) - return server - } - - async function restart(server: AgentHookServer): Promise { - server.flushStatusPersistSync() - server.stop() - return startServer() - } - - async function post(server: AgentHookServer, payload: Record): Promise { - await postHookEvent(server, buildBody(payload)) - } - - async function settleMainAgentBeside(server: AgentHookServer, childIds: string[]): Promise { - await post(server, { hook_event_name: 'UserPromptSubmit', prompt: 'delegate' }) - for (const id of childIds) { - await post(server, { hook_event_name: 'SubagentStart', agent_id: id }) - } - await post(server, { hook_event_name: 'Stop' }) - } - - function row(server: AgentHookServer) { - return server.getStatusSnapshot()[0] - } - - it('settles a restored child permission wait once the child is approved and stops', async () => { - let server = await startServer() - await settleMainAgentBeside(server, ['achild-a']) - await post(server, CHILD_PERMISSION) - server = await restart(server) - try { - await post(server, { - hook_event_name: 'PreToolUse', - agent_id: 'achild-a', - tool_name: 'Bash', - tool_input: { command: 'rm scratch' }, - tool_use_id: 'toolu-approved' - }) - expect(row(server)?.state).toBe('working') - await post(server, { hook_event_name: 'SubagentStop', agent_id: 'achild-a' }) - - expect(row(server)).toMatchObject({ state: 'done', mainAgent: { state: 'done' } }) - expect(row(server)?.restoredUnconfirmed).toBeUndefined() - } finally { - server.stop() - } - }) - - it('does not settle a restored row whose main agent resumed behind a child permission', async () => { - let server = await startServer() - await settleMainAgentBeside(server, ['achild-a', 'achild-b']) - await post(server, CHILD_PERMISSION) - await post(server, { hook_event_name: 'PreToolUse', tool_name: 'Read' }) - expect(row(server)).toMatchObject({ - state: 'waiting', - toolName: 'Bash', - mainAgent: { state: 'working' } - }) - server = await restart(server) - try { - await post(server, { hook_event_name: 'SubagentStop', agent_id: 'achild-a' }) - await post(server, { hook_event_name: 'SubagentStop', agent_id: 'achild-b' }) - - expect(row(server)).toMatchObject({ state: 'working', restoredUnconfirmed: true }) - } finally { - server.stop() - } - }) - - it('settles a restored row after an inferred child answer when no shell ran', async () => { - let server = await startServer() - await settleMainAgentBeside(server, ['achild-a']) - await post(server, { - hook_event_name: 'PreToolUse', - agent_id: 'achild-a', - tool_name: 'AskUserQuestion', - tool_use_id: 'toolu-question' - }) - const waiting = row(server) - expect( - server.inferQuestionAnswered({ - paneKey: PANE, - baselineUpdatedAt: waiting?.receivedAt ?? 0, - baselineStateStartedAt: waiting?.stateStartedAt ?? 0, - baselinePrompt: waiting?.prompt ?? '', - baselineAgentType: 'claude' - }) - ).toBe(true) - server = await restart(server) - try { - await post(server, { hook_event_name: 'SubagentStop', agent_id: 'achild-a' }) - - expect(row(server)).toMatchObject({ state: 'done', mainAgent: { state: 'done' } }) - } finally { - server.stop() - } - }) - - // Preserve shell evidence beside mainAgent so restart cannot mistake the row for shell-free. - async function expectShellHeldRowStaysOpenAfterRestart( - server: AgentHookServer, - childEvents: Record[] - ): Promise { - const restarted = await restart(server) - try { - for (const event of childEvents) { - await post(restarted, event) - } - - expect(row(restarted)?.state).toBe('working') - } finally { - restarted.stop() - } - } - - it('keeps the shell fact when OSC repaints a shell-held row', async () => { - const server = await startServer() - await post(server, { hook_event_name: 'UserPromptSubmit', prompt: 'build in background' }) - await post(server, { hook_event_name: 'Stop', background_tasks: [RUNNING_SHELL] }) - server.ingestTerminalStatus({ - paneKey: PANE, - connectionId: null, - payload: { state: 'working', prompt: 'title text', agentType: 'claude' } - }) - expect(row(server)).toMatchObject({ state: 'working', prompt: 'title text' }) - - await expectShellHeldRowStaysOpenAfterRestart(server, [ - { hook_event_name: 'SubagentStart', agent_id: 'achild-b' }, - { hook_event_name: 'SubagentStop', agent_id: 'achild-b' } - ]) - }) - - it('keeps the shell fact when an answered child question is inferred', async () => { - const server = await startServer() - await post(server, { hook_event_name: 'UserPromptSubmit', prompt: 'delegate' }) - await post(server, { hook_event_name: 'SubagentStart', agent_id: 'achild-a' }) - await post(server, { - hook_event_name: 'Stop', - background_tasks: [{ id: 'achild-a', type: 'subagent', status: 'running' }, RUNNING_SHELL] - }) - await post(server, { - hook_event_name: 'PreToolUse', - agent_id: 'achild-a', - tool_name: 'AskUserQuestion', - tool_use_id: 'toolu-question' - }) - const waiting = row(server) - expect(waiting).toMatchObject({ state: 'waiting', toolName: 'AskUserQuestion' }) - expect( - server.inferQuestionAnswered({ - paneKey: PANE, - baselineUpdatedAt: waiting?.receivedAt ?? 0, - baselineStateStartedAt: waiting?.stateStartedAt ?? 0, - baselinePrompt: waiting?.prompt ?? '', - baselineAgentType: 'claude' - }) - ).toBe(true) - expect(row(server)).toMatchObject({ state: 'working', mainAgent: { state: 'done' } }) - - await expectShellHeldRowStaysOpenAfterRestart(server, [ - { hook_event_name: 'SubagentStop', agent_id: 'achild-a' } - ]) - }) -}) diff --git a/src/main/agent-hooks/server/testing/persistence/server-last-status-restored-children.test.ts b/src/main/agent-hooks/server/testing/persistence/server-last-status-restored-children.test.ts deleted file mode 100644 index bb42bc4e671..00000000000 --- a/src/main/agent-hooks/server/testing/persistence/server-last-status-restored-children.test.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { AgentHookServer, _internals } from '../../agent-hook-server' -import { buildBody, postHookEvent } from '../server.test-fixtures' - -const { getCohortAtEmitMock, trackMock } = vi.hoisted(() => ({ - getCohortAtEmitMock: vi.fn(), - trackMock: vi.fn() -})) - -vi.mock('../../../../telemetry/client', () => ({ - track: trackMock -})) - -vi.mock('../../../../telemetry/cohort-classifier', () => ({ - getCohortAtEmit: getCohortAtEmitMock -})) - -beforeEach(() => { - _internals.resetCachesForTests() - trackMock.mockReset() - getCohortAtEmitMock.mockReset() - getCohortAtEmitMock.mockReturnValue({ nth_repo_added: 2 }) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -describe('Last-status persistence', () => { - let userDataPath: string - - beforeEach(() => { - userDataPath = mkdtempSync(join(tmpdir(), 'orca-laststatus-')) - }) - - afterEach(() => { - rmSync(userDataPath, { recursive: true, force: true }) - }) - - it('keeps a legacy Stop unconfirmed when only a restored child gates it', async () => { - const firstServer = new AgentHookServer() - await firstServer.start({ env: 'production', userDataPath }) - await postHookEvent( - firstServer, - buildBody({ - hook_event_name: 'SubagentStart', - agent_id: 'a0000000000000013', - agent_type: 'reviewer' - }) - ) - firstServer.flushStatusPersistSync() - firstServer.stop() - - const server = new AgentHookServer() - await server.start({ env: 'production', userDataPath }) - try { - await postHookEvent(server, buildBody({ hook_event_name: 'Stop' })) - - expect(server.getStatusSnapshot()[0]).toMatchObject({ - state: 'working', - restoredUnconfirmed: true, - subagents: [expect.objectContaining({ id: 'a0000000000000013' })] - }) - expect(server.getStatusChangeSnapshot()[0]?.observedInCurrentRuntime).toBe(false) - } finally { - server.stop() - } - }) - - it('waits for a lead boundary after a post-restart idle matches a restored teammate', async () => { - const firstServer = new AgentHookServer() - await firstServer.start({ env: 'production', userDataPath }) - await postHookEvent( - firstServer, - buildBody({ - hook_event_name: 'SubagentStart', - agent_id: 'areviewer-6d3cb5b5', - agent_type: 'reviewer' - }) - ) - firstServer.flushStatusPersistSync() - firstServer.stop() - - const server = new AgentHookServer() - await server.start({ env: 'production', userDataPath }) - try { - const restored = server.getStatusSnapshot()[0] - expect(restored).toMatchObject({ - state: 'working', - restoredUnconfirmed: true, - subagents: [expect.objectContaining({ id: 'areviewer-6d3cb5b5' })] - }) - - await postHookEvent( - server, - buildBody({ hook_event_name: 'TeammateIdle', teammate_name: 'reviewer' }) - ) - - expect(server.getStatusSnapshot()[0]).toMatchObject({ - state: 'working', - restoredUnconfirmed: true, - subagents: [expect.objectContaining({ id: 'areviewer-6d3cb5b5', state: 'idle' })] - }) - expect(server.getStatusChangeSnapshot()[0]?.observedInCurrentRuntime).toBe(false) - - await postHookEvent( - server, - buildBody({ - hook_event_name: 'Stop', - background_tasks: [{ id: 'treviewer', type: 'teammate', status: 'running' }] - }) - ) - - expect(server.getStatusSnapshot()[0]).toMatchObject({ - state: 'done', - subagents: [expect.objectContaining({ id: 'areviewer-6d3cb5b5', state: 'idle' })] - }) - expect(server.getStatusSnapshot()[0]?.restoredUnconfirmed).toBeUndefined() - } finally { - server.stop() - } - }) -}) diff --git a/src/main/ai-vault/parsing/session-scanner-parse-wsl-stall.test.ts b/src/main/ai-vault/parsing/session-scanner-parse-wsl-stall.test.ts deleted file mode 100644 index c134fb0c3a3..00000000000 --- a/src/main/ai-vault/parsing/session-scanner-parse-wsl-stall.test.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as NodeFsPromisesModule from 'node:fs/promises' -import type { SessionFileCandidate } from '../session-scanner-types' - -const STALLED_PATH = '\\\\wsl.localhost\\Ubuntu\\home\\ada\\.claude\\projects\\p\\a.jsonl' - -const mocks = vi.hoisted(() => ({ open: vi.fn(), readdir: vi.fn() })) - -// Claude also counts sibling subagents; mock readdir to avoid real UNC access under fake timers. -vi.mock('node:fs/promises', async (importOriginal) => ({ - ...(await importOriginal()), - open: mocks.open, - readdir: mocks.readdir -})) - -import * as transcriptFs from '../../native-chat/transcript-filesystem/wsl-transcript-fs-access' -import { parseAgentSessionFileCached } from '../parse-cache/session-scanner-parse-cache' -import { - registerTranscriptConsumer, - resetTranscriptConsumersForTests -} from '../transcripts/session-transcript-consumers' -import { resetSessionParseCacheForTests } from '../parse-cache/session-parse-cache-store' -import { - resetWslTranscriptFsGateForTests, - WSL_TRANSCRIPT_FS_SCAN_TIMEOUT_MS -} from '../../native-chat/transcript-filesystem/wsl-transcript-fs-gate' -import { WSL_TRANSCRIPT_FS_ROUTE_QUARANTINE_BASE_MS } from '../../native-chat/transcript-filesystem/wsl-transcript-fs-route-quarantine' -import { WslTranscriptFsError } from '../../native-chat/transcript-filesystem/wsl-transcript-fs-error' - -type ReadResult = { bytesRead: number; buffer: Buffer } - -// Settle stalled calls between cases to release their scan permits. -let releaseStall: (() => void) | undefined - -function stalls(): Promise { - return new Promise((resolve) => { - releaseStall = () => resolve({ bytesRead: 0, buffer: Buffer.alloc(0) }) - }) -} - -function servingHandle(body: Buffer) { - return { - read: vi.fn(async (buffer: Buffer, offset: number, length: number, position: number) => { - const slice = body.subarray(position, Math.min(position + length, body.length)) - slice.copy(buffer, offset) - return { bytesRead: slice.length, buffer } - }), - close: vi.fn(async () => {}) - } -} - -function record(index: number, text: string): string { - return JSON.stringify({ - type: 'user', - sessionId: 'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee', - timestamp: new Date(1740000000000 + index * 60_000).toISOString(), - cwd: '/repo/app', - gitBranch: 'main', - message: { role: 'user', content: text } - }) -} - -function body(count: number): Buffer { - return Buffer.from( - Array.from({ length: count }, (_, index) => `${record(index, `line ${index}`)}\n`).join('') - ) -} - -function candidate(path: string, bytes: Buffer, mtimeMs: number): SessionFileCandidate { - return { - agent: 'claude', - file: { - path, - mtimeMs, - modifiedAt: new Date(mtimeMs).toISOString(), - sizeBytes: bytes.length - }, - codexHome: null - } -} - -// Late results cannot clear quarantine; advance through backoff before retrying. -async function releaseAndSettle(): Promise { - releaseStall?.() - releaseStall = undefined - await vi.advanceTimersByTimeAsync(WSL_TRANSCRIPT_FS_ROUTE_QUARANTINE_BASE_MS) -} - -beforeEach(() => { - resetWslTranscriptFsGateForTests() - resetSessionParseCacheForTests() - resetTranscriptConsumersForTests() - mocks.open.mockReset() - mocks.readdir.mockReset() - mocks.readdir.mockResolvedValue([]) - releaseStall = undefined - // performance.now drives the route quarantine clock, so it must be faked too. - vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout', 'Date', 'performance'] }) -}) - -afterEach(async () => { - await releaseAndSettle() - resetTranscriptConsumersForTests() - vi.restoreAllMocks() - vi.useRealTimers() -}) - -describe('AI Vault session parse with a stalled WSL transcript body read', () => { - it('cancels stalled EOF finalization, cleans up, and admits the next read', async () => { - const bytes = body(2) - const file = candidate(STALLED_PATH.replace('a.jsonl', 'finalization.jsonl'), bytes, 1) - mocks.open.mockResolvedValue(servingHandle(bytes)) - let entered!: () => void - const finalizing = new Promise((resolve) => { - entered = resolve - }) - const readdir = vi.spyOn(transcriptFs, 'wslGatedReaddir').mockImplementationOnce(() => { - entered() - return new Promise(() => {}) - }) - const finishes = vi.fn() - registerTranscriptConsumer({ - beginRead: () => ({ message: () => {}, finish: finishes }) - }) - const controller = new AbortController() - const first = parseAgentSessionFileCached( - file, - 'linux', - undefined, - undefined, - controller.signal - ) - const cancelled = first.catch((error) => { - expect(error).toMatchObject({ - name: 'AbortError', - message: 'Agent Session History scan was cancelled' - }) - return 'cancelled' - }) - await finalizing - let nextMessageCount: number | undefined - const next = parseAgentSessionFileCached(file, 'linux').then((session) => { - nextMessageCount = session?.messageCount - return session - }) - let result: string | undefined - void cancelled.then((value) => { - result = typeof value === 'string' ? value : 'completed' - }) - controller.abort() - await vi.advanceTimersByTimeAsync(100) - expect(result).toBe('cancelled') - expect(finishes).toHaveBeenNthCalledWith(1, expect.objectContaining({ cancelled: true })) - expect(nextMessageCount).toBe(2) - await next - expect(finishes).toHaveBeenCalledTimes(2) - readdir.mockRestore() - }) - - it('caches no resume point when the newline probe is refused mid-append', async () => { - const first = body(2) - mocks.open.mockResolvedValue(servingHandle(first)) - const seeded = await parseAgentSessionFileCached(candidate(STALLED_PATH, first, 1), 'linux') - expect(seeded?.messageCount).toBe(2) - - const grown = body(3) - const serving = servingHandle(grown) - mocks.open.mockResolvedValue({ - // Only the 1-byte resume probe stalls; the body read stays healthy. - read: vi.fn((buffer: Buffer, offset: number, length: number, position: number) => - length === 1 ? stalls() : serving.read(buffer, offset, length, position) - ), - close: vi.fn(async () => {}) - }) - const refused = expect( - parseAgentSessionFileCached(candidate(STALLED_PATH, grown, 2), 'linux') - ).rejects.toBeInstanceOf(WslTranscriptFsError) - await vi.advanceTimersByTimeAsync(WSL_TRANSCRIPT_FS_SCAN_TIMEOUT_MS + 1) - await refused - - await releaseAndSettle() - mocks.open.mockResolvedValue(servingHandle(grown)) - const recovered = await parseAgentSessionFileCached(candidate(STALLED_PATH, grown, 2), 'linux') - - resetSessionParseCacheForTests() - const cold = await parseAgentSessionFileCached(candidate(STALLED_PATH, grown, 2), 'linux') - expect(recovered).toEqual(cold) - expect(recovered?.messageCount).toBe(3) - }) -}) diff --git a/src/main/ai-vault/scope/session-scanner-scope.test.ts b/src/main/ai-vault/scope/session-scanner-scope.test.ts deleted file mode 100644 index e6a73a50cad..00000000000 --- a/src/main/ai-vault/scope/session-scanner-scope.test.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { chmod, mkdtemp, mkdir, rm, utimes, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it } from 'vitest' -import { scanAiVaultSessions } from '../session-scanner' -import { isolatedScanRoots } from '../scanner-fixtures/session-scanner-test-fixtures' -import type { AiVaultScanOptions } from '../session-scanner-types' - -let tempRoots: string[] = [] - -afterEach(async () => { - await Promise.all(tempRoots.map((root) => rm(root, { recursive: true, force: true }))) - tempRoots = [] -}) - -function scopedScanOptions(claudeProjectsDir: string, extra: Partial) { - return { - ...isolatedScanRoots(claudeProjectsDir), - claudeProjectsDir, - ...extra - } satisfies AiVaultScanOptions -} - -// Recent out-of-scope sessions fill the recency pass, so the old session can only come from the scope pass. -async function writeOldClaudeSessionBehindRecentOnes( - claudeRoot: string, - old: { dirName: string; cwd: string } -): Promise { - await writeClaudeSession({ - claudeRoot, - ...old, - sessionId: 'old-in-scope', - iso: '2026-01-01T00:00:00.000Z' - }) - for (let index = 0; index < 4; index++) { - await writeClaudeSession({ - claudeRoot, - dirName: `-other-${index}`, - sessionId: `recent-${index}`, - cwd: `/other/${index}`, - iso: `2026-06-2${index}T00:00:00.000Z` - }) - } -} - -const LONG_PATH = `/repo/${'nested-folder/'.repeat(16)}app` - -async function writeClaudeSession(args: { - claudeRoot: string - dirName: string - sessionId: string - cwd: string - iso: string - leadingCwdlessLine?: boolean -}): Promise { - const dir = join(args.claudeRoot, args.dirName) - await mkdir(dir, { recursive: true }) - const records: unknown[] = [] - if (args.leadingCwdlessLine) { - records.push({ type: 'last-prompt', sessionId: args.sessionId }) - } - records.push({ - type: 'user', - sessionId: args.sessionId, - timestamp: args.iso, - cwd: args.cwd, - message: { role: 'user', content: `work in ${args.cwd}` } - }) - const filePath = join(dir, `${args.sessionId}.jsonl`) - await writeFile(filePath, records.map((record) => JSON.stringify(record)).join('\n')) - const time = new Date(args.iso) - await utimes(filePath, time, time) -} - -describe('scanAiVaultSessions scope inclusion', () => { - it('surfaces in-scope sessions older than the global recency cap', async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-ai-vault-scope-')) - tempRoots.push(root) - const claudeRoot = join(root, 'claude-projects') - - await writeClaudeSession({ - claudeRoot, - dirName: '-repo-app', - sessionId: 'old-in-scope', - cwd: '/repo/app', - iso: '2026-01-01T00:00:00.000Z', - leadingCwdlessLine: true - }) - await writeClaudeSession({ - claudeRoot, - dirName: '-repo-app-packages-ui', - sessionId: 'old-in-scope-subdir', - cwd: '/repo/app/packages/ui', - iso: '2026-01-02T00:00:00.000Z' - }) - for (let index = 0; index < 4; index++) { - await writeClaudeSession({ - claudeRoot, - dirName: `-other-${index}`, - sessionId: `recent-${index}`, - cwd: `/other/${index}`, - iso: `2026-06-2${index}T00:00:00.000Z` - }) - } - - const withoutScope = await scanAiVaultSessions(scopedScanOptions(claudeRoot, { limit: 2 })) - const withScope = await scanAiVaultSessions( - scopedScanOptions(claudeRoot, { limit: 2, scopePaths: ['/repo/app'] }) - ) - - const ids = (result: { sessions: { sessionId: string }[] }) => - result.sessions.map((session) => session.sessionId) - - expect(ids(withoutScope)).not.toContain('old-in-scope') - expect(ids(withoutScope)).not.toContain('old-in-scope-subdir') - expect(ids(withScope)).toContain('old-in-scope') - expect(ids(withScope)).toContain('old-in-scope-subdir') - }) - - it('does not assign a native transcript to a WSL distro from cwd alone', async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-ai-vault-scope-')) - tempRoots.push(root) - const claudeRoot = join(root, 'claude-projects') - - await writeClaudeSession({ - claudeRoot, - dirName: '-home-ada-repo', - sessionId: 'old-wsl-in-scope', - cwd: '/home/ada/repo', - iso: '2026-01-01T00:00:00.000Z' - }) - for (let index = 0; index < 4; index++) { - await writeClaudeSession({ - claudeRoot, - dirName: `-other-wsl-${index}`, - sessionId: `recent-wsl-${index}`, - cwd: `/other/wsl/${index}`, - iso: `2026-06-2${index}T00:00:00.000Z` - }) - } - - const result = await scanAiVaultSessions( - scopedScanOptions(claudeRoot, { - limit: 2, - scopePaths: ['\\\\wsl.localhost\\Ubuntu\\home\\ada\\repo'] - }) - ) - - expect(result.sessions.map((session) => session.sessionId)).not.toContain('old-wsl-in-scope') - }) - - it.each([ - { layout: 'a drive root', scopePath: 'C:\\', dirName: 'C--repo', cwd: 'C:\\repo' }, - { - layout: 'a Windows path in another case', - scopePath: 'c:\\users\\ada\\repo', - dirName: 'C--Users-Ada-repo', - cwd: 'C:\\Users\\Ada\\repo' - }, - { - layout: 'the other WSL share spelling', - scopePath: '\\\\wsl.localhost\\Ubuntu\\home\\ada\\repo', - dirName: '--wsl--Ubuntu-home-ada-repo', - cwd: '\\\\wsl$\\Ubuntu\\home\\ada\\repo' - }, - { - // Claude Code names a bucket over 200 characters `-`. - layout: 'a long path', - scopePath: LONG_PATH, - dirName: `${LONG_PATH.replace(/[^a-zA-Z0-9]/g, '-').slice(0, 200)}-1a2b3c`, - cwd: LONG_PATH - } - ])('finds older in-scope Claude sessions for $layout', async ({ scopePath, dirName, cwd }) => { - const root = await mkdtemp(join(tmpdir(), 'orca-ai-vault-scope-')) - tempRoots.push(root) - const claudeRoot = join(root, 'claude-projects') - await writeOldClaudeSessionBehindRecentOnes(claudeRoot, { dirName, cwd }) - - const result = await scanAiVaultSessions( - scopedScanOptions(claudeRoot, { limit: 2, scopePaths: [scopePath] }) - ) - - expect(result.sessions.map((session) => session.sessionId)).toContain('old-in-scope') - }) - - // chmod cannot lock out root, and Windows ignores the mode bits. - it.skipIf(process.platform === 'win32' || process.getuid?.() === 0)( - 'reports an unreadable in-scope folder instead of listing it as empty', - async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-ai-vault-scope-')) - tempRoots.push(root) - const claudeRoot = join(root, 'claude-projects') - await writeOldClaudeSessionBehindRecentOnes(claudeRoot, { - dirName: '-repo-app', - cwd: '/repo/app' - }) - const bucket = join(claudeRoot, '-repo-app') - await chmod(bucket, 0o000) - try { - const result = await scanAiVaultSessions( - scopedScanOptions(claudeRoot, { limit: 2, scopePaths: ['/repo/app'] }) - ) - - expect(result.issues.map((issue) => issue.path)).toContain(bucket) - } finally { - await chmod(bucket, 0o755) - } - } - ) -}) diff --git a/src/main/automations/automation-wake-settle.test.ts b/src/main/automations/automation-wake-settle.test.ts deleted file mode 100644 index 4db46f98032..00000000000 --- a/src/main/automations/automation-wake-settle.test.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { closeTestStores, createStore, testState } from '../persistence/persistence-test-harness' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { mkdtempSync, rmSync } from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import type { Repo } from '../../shared/repo-types' -import { AutomationService } from './automation-service' -import { TICK_MS } from './testing/automation-service-tick.test-fixture' -import { createAwakeClock, type AwakeClock } from '../power/awake-clock' -import { - AUTOMATION_WAKE_SETTLE_MS, - automationSystemSettled -} from './dispatch/automation-wake-settle' - -vi.mock('electron', () => ({ - app: { - getPath: () => testState.dir - }, - safeStorage: { - isEncryptionAvailable: () => true, - encryptString: (plaintext: string) => Buffer.from(`encrypted:${plaintext}`, 'utf-8'), - decryptString: (ciphertext: Buffer) => ciphertext.toString('utf-8').slice('encrypted:'.length) - } -})) - -const makeRepo = (): Repo => ({ - id: 'r1', - path: '/repo', - displayName: 'test', - badgeColor: '#fff', - addedAt: 1 -}) - -type CounterModel = 'counts sleep (macOS/Windows Node)' | 'stops in sleep (Linux)' - -describe.each(['counts sleep (macOS/Windows Node)', 'stops in sleep (Linux)'])( - 'scheduled catch-up after a wake, on a monotonic counter that %s', - (model) => { - let clock: AwakeClock - /** Sleep the fake monotonic counter missed: fake performance only moves with timers. */ - let countedSleep = 0 - - beforeEach(() => { - testState.dir = mkdtempSync(join(tmpdir(), 'orca-automations-wake-test-')) - vi.useFakeTimers({ - toFake: [ - 'Date', - 'performance', - 'setTimeout', - 'clearTimeout', - 'setInterval', - 'clearInterval', - 'setImmediate', - 'clearImmediate' - ] - }) - // Why: offset-less times are local, matching the schedule's local BYHOUR in any CI TZ. - vi.setSystemTime(new Date('2026-11-09T08:00:00')) - countedSleep = 0 - clock = createAwakeClock({ - wallNow: () => Date.now(), - monotonicNow: () => performance.now() + countedSleep, - after: (beat, ms) => { - setTimeout(beat, ms) - } - }) - }) - - afterEach(async () => { - await closeTestStores() - vi.useRealTimers() - rmSync(testState.dir, { recursive: true, force: true }) - }) - - async function awakeFor(ms: number): Promise { - await vi.advanceTimersByTimeAsync(ms) - } - - /** Asleep: no timers run; the wall clock moves on, and so does the counter if it counts sleep. */ - function asleepUntil(when: string): void { - const ms = new Date(when).getTime() - Date.now() - vi.setSystemTime(Date.now() + ms) - if (model === 'counts sleep (macOS/Windows Node)') { - countedSleep += ms - } - } - - async function scheduledService(opts: { tickMs?: number; graceMinutes?: number } = {}) { - const tickMs = opts.tickMs ?? TICK_MS - const store = await createStore() - store.addRepo(makeRepo()) - const automation = store.createAutomation({ - name: 'GitHub i18n issue and PR scan', - prompt: 'Scan', - agentId: 'codex', - projectId: 'r1', - workspaceMode: 'existing', - workspaceId: 'r1::wt1', - timezone: 'America/Los_Angeles', - rrule: 'FREQ=DAILY;BYHOUR=9;BYMINUTE=0', - dtstart: new Date('2026-11-08T00:00:00').getTime(), - missedRunGraceMinutes: opts.graceMinutes ?? 720 - }) - const launch = vi.fn(async () => ({ workspaceId: 'wt-1', terminalSessionId: 'tab-1' })) - const service = new AutomationService(store, { - tickMs, - terminalLauncher: { launch, available: () => true } - }) - service.wakeGate.settled = () => automationSystemSettled(clock) - service.start() - await awakeFor(tickMs) - const statuses = () => store.listAutomationRuns(automation.id).map((run) => run.status) - return { store, automation, launch, service, statuses } - } - - it('does not start a missed run during a dark wake, then catches it up once awake and stable', async () => { - // A one-second tick runs the scheduler inside the two-second dark wake. - const { store, automation, launch, service, statuses } = await scheduledService({ - tickMs: 1_000 - }) - - // The machine sleeps through 09:00 and dark-wakes at 09:08:30 with no resume event. - clock.suspend() - asleepUntil('2026-11-09T09:08:30') - await awakeFor(2_000) - expect(statuses()).toEqual([]) - - // Back to sleep, then a full wake at 09:19:37. - asleepUntil('2026-11-09T09:19:37') - clock.resume() - await awakeFor(AUTOMATION_WAKE_SETTLE_MS - 1_000) - expect(statuses()).toEqual([]) - expect(launch).not.toHaveBeenCalled() - - await awakeFor(2_000) - await vi.waitFor(() => expect(statuses()).toEqual(['dispatched'])) - expect(store.listAutomationRuns(automation.id)[0]!.scheduledFor).toBe( - new Date('2026-11-09T09:00:00').getTime() - ) - expect(launch).toHaveBeenCalledOnce() - service.stop() - }) - } -) diff --git a/src/main/automations/external-managers/external-automation-manager-cache.test.ts b/src/main/automations/external-managers/external-automation-manager-cache.test.ts deleted file mode 100644 index efb26c1f169..00000000000 --- a/src/main/automations/external-managers/external-automation-manager-cache.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { ExternalAutomationManagerCache } from './external-automation-manager-cache' -import { ExternalAutomationProbeCancelledError } from './external-automation-probe-scheduler' -import type { ExternalAutomationManager } from '../../../shared/automations/external/external-automation' - -function manager(id: string): ExternalAutomationManager { - return { - id, - provider: 'openclaw', - label: id, - targetLabel: 'this computer', - target: { type: 'local' }, - status: 'available', - error: null, - canManage: true, - jobs: [] - } -} - -const sshOwner = 'owner:desktop:ssh:target-a:3' - -describe('ExternalAutomationManagerCache', () => { - it('propagates cancellation and leaves the previous entry untouched', async () => { - const cache = new ExternalAutomationManagerCache() - const key = { ownerKey: sshOwner, provider: 'openclaw' } - cache.write(key, manager('openclaw:ssh:target-a')) - - await expect( - cache.resolve(key, () => Promise.reject(new ExternalAutomationProbeCancelledError()), { - refresh: true - }) - ).rejects.toBeInstanceOf(ExternalAutomationProbeCancelledError) - expect(cache.read(key)?.manager?.id).toBe('openclaw:ssh:target-a') - }) -}) diff --git a/src/main/automations/observation/retained-run-reconciliation.test.ts b/src/main/automations/observation/retained-run-reconciliation.test.ts deleted file mode 100644 index 4f9a93e2695..00000000000 --- a/src/main/automations/observation/retained-run-reconciliation.test.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { closeTestStores, createStore, testState } from '../../persistence/persistence-test-harness' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { mkdtempSync, rmSync } from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import type { Repo } from '../../../shared/repo-types' -import type { Automation } from '../../../shared/automations/automation-definition' -import type { AutomationRun } from '../../../shared/automations/history/automation-run' -import { AutomationService } from '../automation-service' -import type { - AutomationRunCompletionObservation, - AutomationRunTerminalObserver -} from './run-completion-watcher' - -vi.mock('electron', () => ({ - app: { getPath: () => testState.dir }, - ipcMain: { handle: () => {} }, - safeStorage: { - isEncryptionAvailable: () => true, - encryptString: (plaintext: string) => Buffer.from(`encrypted:${plaintext}`, 'utf-8'), - decryptString: (ciphertext: Buffer) => ciphertext.toString('utf-8').slice('encrypted:'.length) - } -})) - -type TestStore = Awaited> - -const makeRepo = (): Repo => ({ - id: 'r1', - path: '/repo', - displayName: 'test', - badgeColor: '#fff', - addedAt: 1 -}) - -const LAUNCH_TARGET = { - workspaceId: 'wt1', - terminalSessionId: 'tab-1', - terminalPaneKey: 'tab-1:11111111-2222-4333-8444-555555555555', - terminalPtyId: 'pty-1' -} - -const OPEN_LAUNCHER = { launch: async () => ({ ...LAUNCH_TARGET }), available: () => true } - -function createAutomation(store: TestStore): Automation { - store.addRepo(makeRepo()) - return store.createAutomation({ - name: 'Nightly check', - prompt: 'Check the repo', - agentId: 'claude', - projectId: 'r1', - workspaceMode: 'existing', - workspaceId: 'wt1', - timezone: 'UTC', - rrule: 'FREQ=DAILY;BYHOUR=9;BYMINUTE=0', - dtstart: new Date('2026-05-12T00:00:00Z').getTime() - }) -} - -function retainDispatchedRun(store: TestStore, automation: Automation): AutomationRun { - const run = store.createAutomationRun(automation, Date.now() - 60_000, 'manual') - return store.updateAutomationRun({ - runId: run.id, - status: 'dispatched', - ...LAUNCH_TARGET, - error: null - }) -} - -function readRun(store: TestStore, automationId: string, runId: string): AutomationRun { - const run = store.listAutomationRuns(automationId).find((entry) => entry.id === runId) - if (!run) { - throw new Error('run missing') - } - return run -} - -function createPaneSurface(): { - observer: AutomationRunTerminalObserver - mountPane: () => void - settleObservation: (value: AutomationRunCompletionObservation) => void - observedHandles: string[] -} { - const state = { mounted: false } - const observedHandles: string[] = [] - let resolveObservation: ((value: AutomationRunCompletionObservation) => void) | null = null - return { - observer: { - resolveRunTerminal: (run) => (state.mounted && run.terminalPaneKey ? 'handle-1' : null), - observeCompletion: (handle) => { - observedHandles.push(handle) - return new Promise((resolve) => { - resolveObservation = resolve - }) - } - }, - mountPane: () => { - state.mounted = true - }, - settleObservation: (value) => resolveObservation?.(value), - observedHandles - } -} - -describe('reconciling retained runs against a graph that has not published yet', () => { - beforeEach(() => { - testState.dir = mkdtempSync(join(tmpdir(), 'orca-retained-run-')) - vi.useFakeTimers() - // Away from the automation's 09:00 UTC occurrence so timer advances stay inert. - vi.setSystemTime(new Date('2026-06-01T12:00:00Z')) - }) - - afterEach(async () => { - await closeTestStores() - vi.useRealTimers() - rmSync(testState.dir, { recursive: true, force: true }) - }) - - it('re-attaches to the run once the restored pane mounts seconds later', async () => { - const store = await createStore() - const automation = createAutomation(store) - const retained = retainDispatchedRun(store, automation) - const surface = createPaneSurface() - const service = new AutomationService(store, { - terminalObserver: surface.observer, - terminalLauncher: OPEN_LAUNCHER - }) - - service.start() - await vi.advanceTimersByTimeAsync(5_000) - expect(surface.observedHandles).toEqual([]) - - surface.mountPane() - await vi.advanceTimersByTimeAsync(5_000) - expect(surface.observedHandles).toEqual(['handle-1']) - - surface.settleObservation({ status: 'completed', error: null }) - await vi.advanceTimersByTimeAsync(0) - expect(readRun(store, automation.id, retained.id).status).toBe('completed') - service.stop() - }) -}) diff --git a/src/main/browser/extensions/tabs-and-windows/browser-extension-agent-caller.test.ts b/src/main/browser/extensions/tabs-and-windows/browser-extension-agent-caller.test.ts deleted file mode 100644 index 05e31b9ba44..00000000000 --- a/src/main/browser/extensions/tabs-and-windows/browser-extension-agent-caller.test.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const browserMocks = vi.hoisted(() => ({ - appGetPathMock: vi.fn(() => '/downloads'), - shellOpenExternalMock: vi.fn(), - browserWindowFromWebContentsMock: vi.fn(), - menuBuildFromTemplateMock: vi.fn(), - guestOffMock: vi.fn(), - guestOnMock: vi.fn(), - guestSetBackgroundThrottlingMock: vi.fn(), - guestSetWindowOpenHandlerMock: vi.fn(), - guestOpenDevToolsMock: vi.fn(), - webContentsFromIdMock: vi.fn(), - screenGetCursorScreenPointMock: vi.fn(() => ({ x: 0, y: 0 })), - openPopupWithOriginBarMock: vi.fn() -})) - -vi.mock('electron', () => ({ - app: { prependListener: vi.fn(), off: vi.fn(), getPath: browserMocks.appGetPathMock }, - BrowserWindow: { fromWebContents: browserMocks.browserWindowFromWebContentsMock }, - clipboard: { writeText: vi.fn() }, - shell: { openExternal: browserMocks.shellOpenExternalMock }, - Menu: { buildFromTemplate: browserMocks.menuBuildFromTemplateMock }, - screen: { getCursorScreenPoint: browserMocks.screenGetCursorScreenPointMock }, - webContents: { fromId: browserMocks.webContentsFromIdMock } -})) - -import { browserManager } from '../../guest-lifecycle/manager/browser-manager' -import { runWithActiveRpcCaller } from '../../../runtime/rpc/callers/active-call' -import { withAgentInputInjection } from '../../cdp/input/agent-input-injection' -import { - guestNavigationMethods, - rendererWebContentsId, - resetBrowserManagerMocks, - resetBrowserManagerState -} from '../../guest-lifecycle/manager/browser-manager-test-harness' -import type { BrowserExtensionCaller } from '../api-runtime/browser-extension-namespace-registry' -import { placeBrowserExtensionCallerTab } from './browser-extension-agent-caller' - -const workSession = { name: 'work' } -const otherSession = { name: 'other' } - -/** Registers a guest page; `click` delivers an activating input to it. */ -function registerPage(browserPageId: string, id: number, worktreeId: string) { - const on = vi.fn() - const guest = { - ...guestNavigationMethods(), - id, - session: workSession, - isDestroyed: vi.fn(() => false), - isCurrentlyAudible: vi.fn(() => false), - getType: vi.fn(() => 'webview'), - setBackgroundThrottling: vi.fn(), - setWindowOpenHandler: vi.fn(), - setIgnoreMenuShortcuts: vi.fn(), - on, - prependListener: vi.fn(), - off: vi.fn(), - openDevTools: vi.fn() - } - const previous = browserMocks.webContentsFromIdMock.getMockImplementation() - browserMocks.webContentsFromIdMock.mockImplementation((lookup: number) => - lookup === id ? guest : previous?.(lookup) - ) - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the manager and input tracker call only the methods stubbed above. - const contents = guest as unknown as Electron.WebContents - browserManager.attachGuestPolicies(contents) - browserManager.registerGuest({ - browserPageId, - worktreeId, - webContentsId: id, - rendererWebContentsId - }) - const onInput = on.mock.calls.find(([event]) => event === 'input-event')?.[1] - return { contents, click: () => onInput({}, { type: 'mouseUp' }) } -} - -function caller(session: typeof workSession, extra: Partial = {}) { - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: placement reads session, webContents and userGesture only. - return { session, browserProfileId: 'work', fromWorker: true, ...extra } as BrowserExtensionCaller -} - -beforeEach(() => { - resetBrowserManagerMocks(browserMocks) - resetBrowserManagerState() - browserMocks.webContentsFromIdMock.mockImplementation(() => null) -}) - -describe('an extension tab set off while an agent drives a page in its profile', () => { - it("opens in the background in the agent's workspace, unless the user set it off", async () => { - const userPage = registerPage('user-page', 11, 'wt-user') - const agentPage = registerPage('agent-page', 12, 'wt-agent') - const command = runWithActiveRpcCaller({ kind: 'local-cli' }, () => - browserManager.beginAgentCommand('agent-page') - ) - const placeFromWorker = () => placeBrowserExtensionCallerTab(caller(workSession), true) - const agentPlacement = { active: false, worktreeId: 'wt-agent' } - - expect(placeFromWorker()).toEqual(agentPlacement) - expect(placeBrowserExtensionCallerTab(caller(otherSession), true)).toEqual({ active: true }) - expect( - placeBrowserExtensionCallerTab(caller(workSession, { userGesture: true }), true) - ).toEqual({ active: true }) - - userPage.click() - expect(placeFromWorker()).toEqual({ active: true }) - await withAgentInputInjection(agentPage.contents, async () => agentPage.click()) - expect(placeFromWorker()).toEqual(agentPlacement) - - command.end() - }) -}) diff --git a/src/main/claude-accounts/profiles/setup/claude-profile-setup-worker.test.ts b/src/main/claude-accounts/profiles/setup/claude-profile-setup-worker.test.ts deleted file mode 100644 index 5b9cfc035e6..00000000000 --- a/src/main/claude-accounts/profiles/setup/claude-profile-setup-worker.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { existsSync, mkdirSync, mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join, resolve } from 'node:path' -import { build } from 'esbuild' -import { afterEach, expect, it } from 'vitest' -import { JSONC_PARSER_ESM_ALIAS } from '../../../../../config/build-plugins/jsonc-parser-esm' -import { describeClaudeProfile } from '../claude-profile-paths' -import { runClaudeProfileSetupInWorker } from './claude-profile-setup-worker' - -const roots: string[] = [] -afterEach(() => roots.splice(0).forEach((root) => rmSync(root, { recursive: true, force: true }))) - -it('runs account setup in the built worker entry, off the calling thread', async () => { - const root = mkdtempSync(join(tmpdir(), 'claude-setup-worker-')) - roots.push(root) - const userHome = join(root, 'personal') - const dataRoot = join(root, 'data') - mkdirSync(join(userHome, '.claude'), { recursive: true }) - const profile = describeClaudeProfile(dataRoot, 'a', { - executionHostId: 'local', - runtime: 'host' - }) - mkdirSync(profile.home, { recursive: true }) - const entry = join(root, 'claude-profile-setup-worker-entry.js') - await build({ - entryPoints: [ - resolve('src/main/claude-accounts/profiles/setup/claude-profile-setup-worker-entry.ts') - ], - outfile: entry, - bundle: true, - alias: JSONC_PARSER_ESM_ALIAS, - platform: 'node', - format: 'cjs', - external: ['electron'], - logLevel: 'silent' - }) - - const report = await runClaudeProfileSetupInWorker( - { - dataRoot, - profile, - userHome, - userConfigDir: undefined, - hooks: false, - claudeVersion: undefined - }, - entry - ) - - expect(report.outcome).toBe('prepared') - expect(existsSync(join(dataRoot, 'claude-profiles', 'a', 'profile.json'))).toBe(true) - await expect( - runClaudeProfileSetupInWorker( - { - dataRoot, - profile, - userHome, - userConfigDir: undefined, - hooks: false, - claudeVersion: undefined - }, - join(root, 'missing-entry.js') - ) - ).rejects.toThrow() -}) diff --git a/src/main/claude/hooks/hook-service.test.ts b/src/main/claude/hooks/hook-service.test.ts deleted file mode 100644 index de9d7bdc01c..00000000000 --- a/src/main/claude/hooks/hook-service.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { vi, describe, expect, it } from 'vitest' -import type * as GitBashModule from '../../pty/shell-startup/git-bash' - -vi.mock('electron', () => ({ - app: { - getPath: () => '/tmp/userData' - } -})) - -const { gitBashAvailableMock } = vi.hoisted(() => ({ gitBashAvailableMock: { value: true } })) -vi.mock('../../pty/shell-startup/git-bash', async (importOriginal) => ({ - ...(await importOriginal()), - isGitBashAvailable: () => gitBashAvailableMock.value -})) - -import { ClaudeHookService } from '../hook-service' - -describe('ClaudeHookService.install', () => { - it('does not re-install a managed statusLine the user deleted, until remove() resets the opt-out', () => { - const tmpHome = mkdtempSync(join(tmpdir(), 'orca-claude-statusline-optout-')) - vi.stubEnv('HOME', tmpHome) - vi.stubEnv('USERPROFILE', tmpHome) - try { - const settingsPath = join(tmpHome, '.claude', 'settings.json') - new ClaudeHookService().install() - expect(JSON.parse(readFileSync(settingsPath, 'utf-8')).statusLine).toBeTruthy() - - const settings = JSON.parse(readFileSync(settingsPath, 'utf-8')) - delete settings.statusLine - writeFileSync(settingsPath, JSON.stringify(settings)) - - new ClaudeHookService().install() - expect(JSON.parse(readFileSync(settingsPath, 'utf-8')).statusLine).toBeUndefined() - - new ClaudeHookService().remove() - new ClaudeHookService().install() - expect(JSON.parse(readFileSync(settingsPath, 'utf-8')).statusLine).toBeTruthy() - } finally { - vi.unstubAllEnvs() - rmSync(tmpHome, { recursive: true, force: true }) - } - }) -}) diff --git a/src/main/claude/hooks/statusline-script.test.ts b/src/main/claude/hooks/statusline-script.test.ts deleted file mode 100644 index 9c71c6fdad6..00000000000 --- a/src/main/claude/hooks/statusline-script.test.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { spawn } from 'node:child_process' -import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it } from 'vitest' -import { getManagedStatusLineScript } from './statusline-script' - -const ORIGINAL_PLATFORM = process.platform - -afterEach(() => { - Object.defineProperty(process, 'platform', { configurable: true, value: ORIGINAL_PLATFORM }) -}) - -describe.skipIf(process.platform === 'win32')('statusline curl throttle (posix behavioral)', () => { - const PANE_KEY = 'tab-1:00000000-0000-4000-8000-000000000000' - const dirs: string[] = [] - - afterEach(() => { - for (const dir of dirs.splice(0)) { - rmSync(dir, { recursive: true, force: true }) - } - }) - - function rateLimitPayload(durationMs: number): string { - return JSON.stringify({ - cost: { total_duration_ms: durationMs }, - rate_limits: { five_hour: { used_percentage: 12 } } - }) - } - - function makeHarness(): { - scriptPath: string - dir: string - curlLog: string - payloadLog: string - dateLog: string - catLog: string - } { - const dir = mkdtempSync(join(tmpdir(), 'orca-statusline-throttle-')) - dirs.push(dir) - const curlLog = join(dir, 'curl.log') - const payloadLog = join(dir, 'payload.log') - const dateLog = join(dir, 'date.log') - const catLog = join(dir, 'cat.log') - const scriptPath = join(dir, 'statusline.sh') - writeFileSync(scriptPath, getManagedStatusLineScript('posix')) - const binDir = join(dir, 'stub-bin') - mkdirSync(binDir, { recursive: true }) - writeFileSync( - join(binDir, 'curl'), - `#!/bin/sh\n/bin/cat > "${payloadLog}"\nprintf 'x\\n' >> "${curlLog}"\nexit 0\n`, - { mode: 0o755 } - ) - writeFileSync( - join(binDir, 'date'), - `#!/bin/sh\nprintf 'x\\n' >> "${dateLog}"\nprintf '2000000000\\n'\n`, - { mode: 0o755 } - ) - writeFileSync(join(binDir, 'cat'), `#!/bin/sh\nprintf 'x\\n' >> "${catLog}"\n/bin/cat "$@"\n`, { - mode: 0o755 - }) - return { scriptPath, dir, curlLog, payloadLog, dateLog, catLog } - } - - function runScript( - scriptPath: string, - dir: string, - payload: string, - paneKey = PANE_KEY - ): Promise { - return new Promise((resolve, reject) => { - const child = spawn('sh', [scriptPath], { - env: { - PATH: `${join(dir, 'stub-bin')}:${process.env.PATH ?? ''}`, - TMPDIR: dir, - ORCA_AGENT_HOOK_PORT: '65535', - ORCA_AGENT_HOOK_TOKEN: 'test-token', - ORCA_PANE_KEY: paneKey - }, - stdio: ['pipe', 'ignore', 'pipe'] - }) - let stderr = '' - child.stderr.on('data', (chunk: Buffer) => { - stderr += chunk.toString() - }) - child.on('error', reject) - child.on('close', (code) => { - if (code === 0) { - resolve() - } else { - reject(new Error(`statusline script exited ${code}: ${stderr}`)) - } - }) - child.stdin.write(payload) - child.stdin.end() - }) - } - - it('preserves multiline payloads while capturing stdin with shell builtins', async () => { - const { scriptPath, dir, payloadLog } = makeHarness() - const payload = JSON.stringify(JSON.parse(rateLimitPayload(1_000)), null, 2) - await runScript(scriptPath, dir, payload) - expect(readFileSync(payloadLog, 'utf8')).toBe(payload) - }) -}) diff --git a/src/main/claude/structured/claude-structured-reasoning.test.ts b/src/main/claude/structured/claude-structured-reasoning.test.ts deleted file mode 100644 index e175f783d87..00000000000 --- a/src/main/claude/structured/claude-structured-reasoning.test.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { AgentJournalItemBody } from '../../../shared/agent-session/journal/agent-session-journal-types' -import { agentJournalItemKey } from '../../../shared/agent-session/journal/agent-session-journal-item-key' -import { createClaudeJournalTranslator } from './journal/claude-structured-journal-translation' - -function setup() { - const rows = new Map() - const translator = createClaudeJournalTranslator({ - sink: { - appendItem: (identity, body) => { - if (body.kind !== 'turn') { - rows.set(agentJournalItemKey(identity), body) - } - }, - appendTombstone: vi.fn(), - publish: vi.fn() - } - }) - const frame = (message: Record, observedAt?: number): void => - translator.handle({ - type: 'message', - sessionId: 'orca-session', - ...(observedAt === undefined ? {} : { observedAt }), - message: { - session_id: 'session', - parent_tool_use_id: null, - ...message - } - }) - const stream = (uuid: string, event: Record, observedAt?: number): void => - frame({ type: 'stream_event', uuid, event }, observedAt) - const final = (uuid: string, content: unknown[], observedAt?: number): void => - frame( - { - type: 'assistant', - uuid, - message: { id: 'message-1', role: 'assistant', content } - }, - observedAt - ) - return { rows, translator, frame, stream, final } -} - -function reasoning(text: string, lifecycle: Record): AgentJournalItemBody { - return { - kind: 'message', - role: 'reasoning', - blocks: [{ type: 'text', text }], - ...lifecycle - } -} - -afterEach(() => vi.useRealTimers()) - -describe('structured Claude reasoning', () => { - it('writes final-only thinking closed, with no span it never saw', () => { - const { rows, final, translator } = setup() - final('final-only', [{ type: 'thinking', thinking: 'Inspecting the request' }], 5_000) - expect([...rows.values()]).toEqual([ - reasoning('Inspecting the request', { state: 'completed' }) - ]) - translator.dispose() - }) - - it('streams a running row and closes that same row on its final frame', () => { - vi.useFakeTimers() - const { rows, stream, final, translator } = setup() - stream('start', { type: 'message_start', message: { id: 'message-1' } }, 1_000) - stream( - 'thinking-start', - { type: 'content_block_start', index: 0, content_block: { type: 'thinking', thinking: '' } }, - 1_000 - ) - stream( - 'delta-1', - { - type: 'content_block_delta', - index: 0, - delta: { type: 'thinking_delta', thinking: 'Inspecting ' } - }, - 3_000 - ) - translator.flush() - const firstKey = [...rows.keys()][0] - expect(rows.get(firstKey!)).toEqual(reasoning('Inspecting ', { state: 'running' })) - stream( - 'delta-2', - { - type: 'content_block_delta', - index: 0, - delta: { type: 'thinking_delta', thinking: 'the request' } - }, - 4_000 - ) - translator.flush() - expect([...rows.keys()]).toEqual([firstKey]) - final('thinking-final', [{ type: 'thinking', thinking: 'Inspecting the request' }], 9_000) - expect([...rows.keys()]).toEqual([firstKey]) - expect(rows.get(firstKey!)).toEqual( - reasoning('Inspecting the request', { state: 'completed', completedAt: 9_000 }) - ) - - stream('text-start', { - type: 'content_block_start', - index: 1, - content_block: { type: 'text', text: '' } - }) - stream('text-delta', { - type: 'content_block_delta', - index: 1, - delta: { type: 'text_delta', text: 'Here is the answer' } - }) - translator.flush() - final('text-final', [{ type: 'text', text: 'Here is the answer' }]) - expect([...rows.values()].map((body) => body.kind === 'message' && body.role)).toEqual([ - 'reasoning', - 'assistant' - ]) - expect(translator.pendingStreamedBlocks).toBe(0) - translator.dispose() - }) - - it('closes a streamed row with its streamed text when the final frame carries none', () => { - vi.useFakeTimers() - const { rows, stream, final, translator } = setup() - stream( - 'delta', - { - type: 'content_block_delta', - index: 0, - delta: { type: 'thinking_delta', thinking: 'Summary' } - }, - 1_000 - ) - final('thinking-final', [{ type: 'thinking', thinking: '', signature: 'sig' }], 2_000) - expect([...rows.values()]).toEqual([ - reasoning('Summary', { state: 'completed', completedAt: 2_000 }) - ]) - expect(translator.pendingStreamedBlocks).toBe(0) - translator.dispose() - }) - - it('reconciles an empty final block before the next thinking block', () => { - const { rows, stream, final, translator } = setup() - stream('empty-start', { - type: 'content_block_start', - index: 0, - content_block: { type: 'thinking', thinking: '' } - }) - final('empty-final', [{ type: 'thinking', thinking: '' }]) - stream('next-start', { - type: 'content_block_start', - index: 1, - content_block: { type: 'thinking', thinking: 'Next thought' } - }) - translator.flush() - const key = [...rows.keys()][0] - final('next-final', [{ type: 'thinking', thinking: 'Next thought' }]) - expect([...rows.keys()]).toEqual([key]) - expect(translator.pendingStreamedBlocks).toBe(0) - translator.dispose() - }) - - it('writes streamed thinking into the turn its first delta opened', () => { - vi.useFakeTimers() - const scopes: unknown[] = [] - const translator = createClaudeJournalTranslator({ - sink: { - appendItem: (_identity, body, options) => { - if (body.kind === 'message' && body.role === 'reasoning') { - scopes.push(options.turnScope) - } - }, - appendTombstone: vi.fn(), - publish: vi.fn() - } - }) - translator.handle({ - type: 'message', - sessionId: 'orca-session', - message: { - type: 'stream_event', - session_id: 'session', - parent_tool_use_id: null, - uuid: 'delta', - event: { - type: 'content_block_delta', - index: 0, - delta: { type: 'thinking_delta', thinking: 'Considering' } - } - } - }) - translator.flush() - expect(scopes).toEqual([{ kind: 'turn', turnItemId: expect.stringContaining('turn') }]) - translator.dispose() - }) -}) diff --git a/src/main/claude/structured/journal/claude-journal-turn-scope.test.ts b/src/main/claude/structured/journal/claude-journal-turn-scope.test.ts deleted file mode 100644 index bf5ec650614..00000000000 --- a/src/main/claude/structured/journal/claude-journal-turn-scope.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { expect, it, vi } from 'vitest' -import type { AgentJournalItemBody } from '../../../../shared/agent-session/journal/agent-session-journal-types' -import type { AgentJournalItemIdentity } from '../../../../shared/agent-session/journal/agent-session-journal-identity' -import type { - StructuredAgentSessionEventSink, - StructuredAgentSessionItemAppendOptions -} from '../../../native-chat/agent-session-wire/journal-ingress/structured-agent-session-event-sink' -import { createClaudeJournalTranslator } from './claude-structured-journal-translation' - -function recorder() { - const writes: { - identity: AgentJournalItemIdentity - body: AgentJournalItemBody - options: StructuredAgentSessionItemAppendOptions - }[] = [] - const sink: StructuredAgentSessionEventSink = { - appendItem: (identity, body, options) => writes.push({ identity, body, options }), - appendTombstone: vi.fn(), - publish: vi.fn() - } - const scopeOfProse = (text: string) => - writes.findLast( - (write) => - write.body.kind === 'message' && - write.body.blocks.some((block) => block.type === 'text' && block.text === text) - )?.options.turnScope - return { sink, writes, scopeOfProse } -} - -function frame(message: Record, startsTurn = false) { - return { - type: 'message' as const, - sessionId: 'orca-session', - ...(startsTurn ? { startsTurn: true as const } : {}), - message: { session_id: 'claude-session', ...message } - } -} - -function prose(uuid: string, text: string, parentToolUseId: string | null = null) { - return frame({ - type: 'assistant', - uuid, - parent_tool_use_id: parentToolUseId, - message: { role: 'assistant', content: [{ type: 'text', text }] } - }) -} - -it("scopes the session's and a subagent's rows to the open turn, and a late one to none", () => { - const { sink, writes, scopeOfProse } = recorder() - const translator = createClaudeJournalTranslator({ sink, fallbackIdPrefix: 'test' }) - translator.handle( - frame( - { - type: 'user', - uuid: 'user-1', - parent_tool_use_id: null, - message: { role: 'user', content: [{ type: 'text', text: 'go' }] } - }, - true - ) - ) - translator.handle(prose('assistant-1', 'Working on it')) - translator.handle(prose('child-1', 'Child mid-turn', 'toolu_1')) - translator.handle(frame({ type: 'result', subtype: 'success', uuid: 'result-1', result: 'ok' })) - translator.handle(prose('child-2', 'Child after the turn', 'toolu_1')) - - const turnRecord = writes.find((write) => write.body.kind === 'turn') - expect(turnRecord?.options.turnScope).toEqual({ kind: 'thread' }) - const turnKey = expect.stringContaining('turn-lifecycle') - expect(scopeOfProse('Working on it')).toEqual({ kind: 'turn', turnItemId: turnKey }) - expect(scopeOfProse('Child mid-turn')).toEqual({ kind: 'turn', turnItemId: turnKey }) - expect(scopeOfProse('Child after the turn')).toEqual({ kind: 'thread' }) -}) diff --git a/src/main/claude/structured/journal/claude-plugin-ui-frames.test.ts b/src/main/claude/structured/journal/claude-plugin-ui-frames.test.ts deleted file mode 100644 index 357a0ff6b13..00000000000 --- a/src/main/claude/structured/journal/claude-plugin-ui-frames.test.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import type { AgentJournalItemBody } from '../../../../shared/agent-session/journal/agent-session-journal-types' -import type { AgentJournalItemIdentity } from '../../../../shared/agent-session/journal/agent-session-journal-identity' -import type { StructuredAgentSessionEventSink } from '../../../native-chat/agent-session-wire/journal-ingress/structured-agent-session-event-sink' -import { createClaudeJournalTranslator } from './claude-structured-journal-translation' - -function sinkState() { - const items: { identity: AgentJournalItemIdentity; body: AgentJournalItemBody }[] = [] - const sink: StructuredAgentSessionEventSink = { - appendItem: (identity, body) => items.push({ identity, body }), - appendTombstone: () => {}, - publish: vi.fn() - } - return { sink, items } -} - -function providerFrameKinds(items: { body: AgentJournalItemBody }[]): string[] { - return items.flatMap((item) => - item.body.kind === 'status' && item.body.providerFrame ? [item.body.providerFrame.kind] : [] - ) -} - -/** Shape reported from Claude Code 2.1.316; UUIDs are test identities. */ -function pluginUi(subtype: string | undefined, uuid: string, fields: Record) { - return { - type: 'message' as const, - sessionId: 'orca-session', - message: { - type: 'system', - subtype, - plugin: 'fos-skills', - ...fields, - uuid, - session_id: 'claude-session' - } - } -} - -function userTurn(uuid: string, text: string) { - return { - type: 'message' as const, - sessionId: 'orca-session', - startsTurn: true as const, - message: { - type: 'user', - uuid, - session_id: 'claude-session', - parent_tool_use_id: null, - isReplay: true, - message: { role: 'user', content: text } - } - } -} - -function assistantReply(uuid: string, text: string) { - return { - type: 'message' as const, - sessionId: 'orca-session', - message: { - type: 'assistant', - uuid, - session_id: 'claude-session', - parent_tool_use_id: null, - message: { role: 'assistant', content: [{ type: 'text', text }] } - } - } -} - -describe('Claude plugin UI frames', () => { - it('keeps plugin status lines and toasts off the transcript for a whole turn', () => { - const state = sinkState() - const translator = createClaudeJournalTranslator({ sink: state.sink }) - - translator.handle(userTurn('user-1', 'Reply with exactly PROBE_OK and nothing else.')) - translator.handle(pluginUi('ui_status', 'ui-1', { text: 'PR 6 · 진행 13 · 대기 6 /board' })) - translator.handle(assistantReply('assistant-1', 'PROBE_OK')) - // Captured from Claude Code 2.1.316 with an isolated test plugin. - translator.handle( - pluginUi('ui_toast', 'ui-2', { - plugin: 'qa-plugin-ui', - text: 'QA plugin toast: prompt seen', - timeout_ms: 4000 - }) - ) - translator.handle(pluginUi('ui_status', 'ui-3', { text: null })) - translator.handle({ - type: 'message', - sessionId: 'orca-session', - message: { - type: 'result', - subtype: 'success', - uuid: 'result-1', - session_id: 'claude-session', - is_error: false, - result: 'PROBE_OK', - terminal_reason: 'completed' - } - }) - - expect(providerFrameKinds(state.items)).toEqual([]) - expect( - state.items.flatMap((item) => - item.body.kind === 'message' && item.body.role === 'assistant' ? [item.body.blocks] : [] - ) - ).toEqual([[{ type: 'text', text: 'PROBE_OK' }]]) - }) -}) diff --git a/src/main/claude/structured/journal/claude-streamed-text-checkpoints.test.ts b/src/main/claude/structured/journal/claude-streamed-text-checkpoints.test.ts deleted file mode 100644 index 2220f57d102..00000000000 --- a/src/main/claude/structured/journal/claude-streamed-text-checkpoints.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { AgentJournalItemIdentity } from '../../../../shared/agent-session/journal/agent-session-journal-identity' -import type { AgentJournalProducerLinkage } from '../../../../shared/agent-session/journal/agent-session-journal-types' -import type { StructuredAgentSessionAppendOptions } from '../../../native-chat/agent-session-wire/journal-ingress/structured-agent-session-event-sink' -import { createClaudeStreamedTextCheckpoints } from './claude-streamed-text-checkpoints' -import type { - ClaudeSubagentLinkageSource, - ClaudeSubagentLinkageVerdict -} from '../../subagents/claude-subagent-linkage' - -function identityOf(uuid: string): AgentJournalItemIdentity { - return { provider: 'claude', sessionId: 'claude-session', uuid } -} - -/** Scopeless blocks are root-owned and must never consult the child resolver. */ -const unconsultedProducer: ClaudeSubagentLinkageSource = { - linkageFor: () => { - throw new Error('resolver consulted for a block with no scope') - }, - settledLinkageFor: () => { - throw new Error('resolver consulted for a block with no scope') - } -} - -const CHILD_LINKAGE: AgentJournalProducerLinkage = { - agentId: 'task-1', - providerParentRef: 'toolu_1', - producerKind: 'agent' -} - -/** Resolve announcements mid-stream; use the raw reference if no announcement arrives. */ -function scriptedProducer() { - let verdict: ClaudeSubagentLinkageVerdict = { kind: 'pending' } - const settledFallback: Extract = { - kind: 'linked', - linkage: { agentId: 'toolu_1', providerParentRef: 'toolu_1', producerKind: 'agent' } - } - return { - source: { - linkageFor: () => verdict, - settledLinkageFor: () => (verdict.kind === 'pending' ? settledFallback : verdict) - } satisfies ClaudeSubagentLinkageSource, - resolve: (linkage: AgentJournalProducerLinkage) => { - verdict = { kind: 'linked', linkage } - } - } -} - -function checkpoints(producer: ClaudeSubagentLinkageSource = unconsultedProducer) { - const rows: { uuid: string; text: string }[] = [] - const stamps: StructuredAgentSessionAppendOptions[] = [] - let scheduled: (() => void) | null = null - const store = createClaudeStreamedTextCheckpoints({ - producer, - persist: (identity, text, options) => { - rows.push({ uuid: 'uuid' in identity ? identity.uuid : '', text }) - stamps.push(options) - }, - schedule: (run) => { - scheduled = run - return () => { - scheduled = null - } - } - }) - return { - store, - rows, - stamps, - runWindow: () => { - const run = scheduled as (() => void) | null - run?.() - } - } -} - -describe('claude streamed text checkpoints', () => { - it('writes a checkpoint at once while the producing agent is provisional', () => { - const producer = scriptedProducer() - const { store, rows, stamps, runWindow } = checkpoints(producer.source) - - store.append(identityOf('block-1'), 'partial', 'toolu_1') - runWindow() - expect(rows).toEqual([{ uuid: 'block-1', text: 'partial' }]) - expect(stamps.at(-1)).toMatchObject({ agentId: 'toolu_1' }) - - // Flush advances text; reattribute corrects linkage even when text is unchanged. - producer.resolve(CHILD_LINKAGE) - store.flush() - expect(stamps.at(-1)).toMatchObject({ agentId: 'toolu_1' }) - - store.reattribute() - - expect(rows.at(-1)).toEqual({ uuid: 'block-1', text: 'partial' }) - expect(stamps.at(-1)).toEqual(CHILD_LINKAGE) - }) -}) diff --git a/src/main/claude/structured/launch/claude-structured-applied-options.test.ts b/src/main/claude/structured/launch/claude-structured-applied-options.test.ts deleted file mode 100644 index 07b4c3e57a3..00000000000 --- a/src/main/claude/structured/launch/claude-structured-applied-options.test.ts +++ /dev/null @@ -1,216 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import type { ClaudeStructuredSessionEvent } from '../claude-structured-session-state' -import { - PROVIDER_SESSION_ID, - acquired, - adapterFor, - fakeClaude, - identityFor -} from '../claude-structured-session-test-support' -import { claudeOpened } from '../claude-structured-startup-settled-test-support' - -/** Claude Code 2.1.280 list_models fixture; default and opus[1m] resolve to the same model. */ -const CATALOG = [ - { - value: 'default', - resolvedModel: 'claude-opus-5-5[1m]', - displayName: 'Default (recommended)', - supportsEffort: true, - supportedEffortLevels: ['low', 'medium', 'high', 'xhigh', 'max'] - }, - { - value: 'opus[1m]', - resolvedModel: 'claude-opus-5-5[1m]', - displayName: 'Opus (1M context)', - supportsEffort: true, - supportedEffortLevels: ['low', 'medium', 'high', 'xhigh', 'max'] - }, - { - value: 'sonnet', - resolvedModel: 'claude-sonnet-5', - displayName: 'Sonnet', - supportsEffort: true, - supportedEffortLevels: ['low', 'medium', 'high', 'xhigh', 'max'] - }, - { value: 'haiku', resolvedModel: 'claude-haiku-4-5-20251001', displayName: 'Haiku' } -] - -/** Claude Code 2.1.280 scratch-config responses: applied includes env resolution; effective reflects settings. */ -const SETTINGS = { - noOverride: { - effective: {}, - sources: [], - applied: { model: 'claude-opus-5-5[1m]', effort: 'medium', advisor: null, ultracode: false } - }, - settingsHaiku: { - effective: { model: 'haiku' }, - sources: [{ source: 'userSettings', settings: { model: 'haiku' } }], - applied: { model: 'claude-haiku-4-5-20251001', effort: null, advisor: null, ultracode: false } - } -} - -function startedWithoutATurn(settings: unknown) { - // The real startup proof before any turn is the SessionStart hook frame, which names no model. - return fakeClaude({ - initProof: 'session-start', - initModels: CATALOG, - settings, - routes: { list_models: () => CATALOG } - }) -} - -describe('Claude model before the first turn', () => { - it('uses native applied effort despite settings High, before and after a reply', async () => { - // Claude Code 2.1.318: no flag applies Medium; --effort low applies Low. - const claude = startedWithoutATurn({ - effective: { effortLevel: 'high' }, - applied: { model: 'claude-opus-5-5', effort: 'medium', ultracode: false } - }) - const events: ClaudeStructuredSessionEvent[] = [] - const adapter = await acquired(claude, {}, events) - const current = async () => - (await adapter.readOptions({ sessionId: 'session-1', fence: 7 })).current - expect((await current()).effort).toBe('medium') - expect((await current()).confirmed ?? []).not.toContain('effort') - const connection = claude.connections[0]! - connection.getSettings = async () => ({ - effective: { effortLevel: 'high' }, - applied: { model: 'claude-opus-5-5', effort: 'low', ultracode: false } - }) - connection.handlers.onMessage?.({ - type: 'result', - subtype: 'success', - uuid: 'finished', - session_id: PROVIDER_SESSION_ID, - is_error: false - }) - await vi.waitFor(async () => expect((await current()).effort).toBe('low')) - expect((await current()).confirmed ?? []).not.toContain('effort') - const started = await claudeOpened(adapter, 'session-1') - expect(started.reportedOptions).not.toHaveProperty('effort') - const reported = events.find((event) => event.type === 'options-reported') - expect(reported).toMatchObject({ - reportedOptions: expect.not.objectContaining({ effort: expect.anything() }) - }) - await adapter.closeAll() - }) - - it('clears inferred effort when native settings explicitly report none', async () => { - const claude = startedWithoutATurn({ - effective: { effortLevel: 'high' }, - applied: { model: 'claude-opus-5-5', effort: 'medium', ultracode: false } - }) - const adapter = await acquired(claude) - expect((await adapter.readOptions({ sessionId: 'session-1', fence: 7 })).current.effort).toBe( - 'medium' - ) - // The recorded Haiku response explicitly names no effort parameter. - claude.connections[0]!.getSettings = async () => ({ - ...SETTINGS.settingsHaiku, - effective: { model: 'haiku', effortLevel: 'high' } - }) - claude.connections[0]!.handlers.onMessage?.({ - type: 'result', - subtype: 'success', - uuid: 'haiku-finished', - session_id: PROVIDER_SESSION_ID, - is_error: false - }) - await vi.waitFor(async () => - expect( - (await adapter.readOptions({ sessionId: 'session-1', fence: 7 })).current.effort - ).toBeUndefined() - ) - await adapter.closeAll() - }) - - it('lets the first turn confirm or correct it', async () => { - const claude = startedWithoutATurn(SETTINGS.settingsHaiku) - const adapter = await acquired(claude) - - claude.connections[0]!.handlers.onMessage?.({ - type: 'system', - subtype: 'init', - session_id: PROVIDER_SESSION_ID, - uuid: 'turn-init-uuid', - model: 'claude-sonnet-5', - apiKeySource: 'none' - }) - - const { current } = await adapter.readOptions({ sessionId: 'session-1', fence: 7 }) - expect(current.model).toBe('claude-sonnet-5') - expect(current.confirmed).toContain('model') - }) - - it('starts a new chat on the model Claude will apply, which is what the session persists', async () => { - const events: ClaudeStructuredSessionEvent[] = [] - await acquired(startedWithoutATurn(SETTINGS.settingsHaiku), {}, events) - - const reported = events.find((event) => event.type === 'options-reported') - expect(reported).toMatchObject({ reportedOptions: { model: 'claude-haiku-4-5-20251001' } }) - }) - - it('shows the applied effort but never persists it as the session options', async () => { - const events: ClaudeStructuredSessionEvent[] = [] - const adapter = await acquired(startedWithoutATurn(SETTINGS.noOverride), {}, events) - - const started = await claudeOpened(adapter, 'session-1') - expect(started.reportedOptions).not.toHaveProperty('model') - // Saved, it would be restored on every reopen past a later settings.json change. - expect(started.reportedOptions).not.toHaveProperty('effort') - const reported = events.find((event) => event.type === 'options-reported') - expect( - reported?.type === 'options-reported' ? reported.reportedOptions : null - ).not.toHaveProperty('effort') - const { current } = await adapter.readOptions({ sessionId: 'session-1', fence: 7 }) - expect(current.effort).toBe('medium') - }) - - it('refreshes what Claude applies at turn completion, without work on an options read', async () => { - const settings = structuredClone(SETTINGS.settingsHaiku) - const claude = startedWithoutATurn(settings) - const adapter = await acquired(claude) - - await adapter.setOption({ sessionId: 'session-1', fence: 7, key: 'model', value: 'sonnet' }) - Object.assign(settings.applied, { model: 'claude-sonnet-5', effort: 'high' }) - - const reads = claude.connections[0]!.calls.filter( - (call) => call.subtype === 'get_settings' - ).length - const { current } = await adapter.readOptions({ sessionId: 'session-1', fence: 7 }) - expect(current.model).toBe('sonnet') - expect(current.effort).toBeUndefined() - expect( - claude.connections[0]!.calls.filter((call) => call.subtype === 'get_settings') - ).toHaveLength(reads) - claude.connections[0]!.handlers.onMessage?.({ - type: 'result', - subtype: 'success', - uuid: 'finished', - session_id: PROVIDER_SESSION_ID, - is_error: false - }) - await vi.waitFor(async () => { - expect( - (await adapter.readOptions({ sessionId: 'session-1', fence: 7 })).current - ).toMatchObject({ model: 'sonnet', effort: 'high' }) - }) - }) - - it('drops the applied effort once a restored model replaces the model it described', async () => { - const claude = startedWithoutATurn(SETTINGS.noOverride) - const events: ClaudeStructuredSessionEvent[] = [] - const adapter = adapterFor(claude, { resumesTranscript: true, continuesChain: true }, events) - - await adapter.acquire({ - identity: identityFor(), - fence: 7, - spawnToken: 'spawn-9', - options: { model: 'haiku' } - }) - - const started = await claudeOpened(adapter, 'session-1') - expect(started.reportedOptions).not.toHaveProperty('model') - expect(started.reportedOptions.effort).toBeUndefined() - }) -}) diff --git a/src/main/claude/structured/turns/claude-command-lifecycle-frames.test.ts b/src/main/claude/structured/turns/claude-command-lifecycle-frames.test.ts deleted file mode 100644 index 4a5761ed64a..00000000000 --- a/src/main/claude/structured/turns/claude-command-lifecycle-frames.test.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import type { AgentJournalItemBody } from '../../../../shared/agent-session/journal/agent-session-journal-types' -import type { AgentJournalItemIdentity } from '../../../../shared/agent-session/journal/agent-session-journal-identity' -import type { StructuredAgentSessionEventSink } from '../../../native-chat/agent-session-wire/journal-ingress/structured-agent-session-event-sink' -import { createClaudeJournalTranslator } from '../journal/claude-structured-journal-translation' - -function sinkState() { - const items: { identity: AgentJournalItemIdentity; body: AgentJournalItemBody }[] = [] - const sink: StructuredAgentSessionEventSink = { - appendItem: (identity, body) => items.push({ identity, body }), - appendTombstone: () => {}, - publish: vi.fn() - } - return { sink, items } -} - -function providerFrameKinds(items: { body: AgentJournalItemBody }[]): string[] { - return items.flatMap((item) => - item.body.kind === 'status' && item.body.providerFrame ? [item.body.providerFrame.kind] : [] - ) -} - -/** Queue-bookkeeping shape captured from CLI 2.1.258 emission sites. */ -function commandLifecycle(state: 'started' | 'completed' | 'cancelled', uuid: string) { - return { - type: 'message' as const, - sessionId: 'orca-session', - message: { - type: 'command_lifecycle', - command_uuid: 'command-1', - state, - uuid, - session_id: 'claude-session' - } - } -} - -function userTurn(uuid: string, text: string) { - return { - type: 'message' as const, - sessionId: 'orca-session', - startsTurn: true as const, - message: { - type: 'user', - uuid, - session_id: 'claude-session', - parent_tool_use_id: null, - isReplay: true, - message: { role: 'user', content: text } - } - } -} - -function assistantReply(uuid: string, text: string) { - return { - type: 'message' as const, - sessionId: 'orca-session', - message: { - type: 'assistant', - uuid, - session_id: 'claude-session', - parent_tool_use_id: null, - message: { role: 'assistant', content: [{ type: 'text', text }] } - } - } -} - -describe('Claude command_lifecycle frames', () => { - it('keeps queue bookkeeping off the transcript for a whole turn', () => { - const state = sinkState() - const translator = createClaudeJournalTranslator({ sink: state.sink }) - - translator.handle(userTurn('user-1', 'Reply with exactly PROBE_OK and nothing else.')) - translator.handle(commandLifecycle('started', 'lifecycle-1')) - translator.handle(assistantReply('assistant-1', 'PROBE_OK')) - translator.handle(commandLifecycle('completed', 'lifecycle-2')) - translator.handle(commandLifecycle('completed', 'lifecycle-3')) - translator.handle({ - type: 'message', - sessionId: 'orca-session', - message: { - type: 'result', - subtype: 'success', - uuid: 'result-1', - session_id: 'claude-session', - is_error: false, - result: 'PROBE_OK', - terminal_reason: 'completed' - } - }) - - expect(providerFrameKinds(state.items)).toEqual([]) - expect( - state.items.flatMap((item) => - item.body.kind === 'message' && item.body.role === 'assistant' ? [item.body.blocks] : [] - ) - ).toEqual([[{ type: 'text', text: 'PROBE_OK' }]]) - }) -}) diff --git a/src/main/claude/structured/turns/claude-command-turn.test.ts b/src/main/claude/structured/turns/claude-command-turn.test.ts deleted file mode 100644 index d9b5debde25..00000000000 --- a/src/main/claude/structured/turns/claude-command-turn.test.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { agentJournalItemKey } from '../../../../shared/agent-session/journal/agent-session-journal-item-key' -import type { AgentJournalItemBody } from '../../../../shared/agent-session/journal/agent-session-journal-types' -import type { AgentJournalItemIdentity } from '../../../../shared/agent-session/journal/agent-session-journal-identity' -import type { AgentJournalTurnScope } from '../../../../shared/agent-session/journal/agent-session-journal-turn-scope' -import { readAgentJournalTurn } from '../../../../shared/agent-session/lifecycle/records/agent-session-turn-record' -import type { StructuredAgentSessionEventSink } from '../../../native-chat/agent-session-wire/journal-ingress/structured-agent-session-event-sink' -import { journalTimelineItemsView } from '../../../native-chat/agent-session-journal/writing/journal-timeline-view' -import { resolveJournalTimelineItem } from '../../../native-chat/agent-session-journal/writing/journal-timeline-resolution' -import { - CAPTURED_COMPACT_SESSION_ID, - type CapturedCompactEvent -} from '../../fixtures/claude-captured-compact-frames.test-fixture' -import { createClaudeJournalTranslator } from '../journal/claude-structured-journal-translation' - -const COMMAND_IDENTITY: AgentJournalItemIdentity = { - provider: 'orca', - clientMessageId: 'command-turn:cmd-1' -} -const COMMAND_KEY = agentJournalItemKey(COMMAND_IDENTITY) -const NOW = 1_800_000_000_000 - -const RUNNING = { - kind: 'turn' as const, - turnId: 'compact:cmd-1', - state: 'running' as const, - userItemId: 'orca:submission:cmd-1', - requestedAt: 900, - startedAt: 1_000 -} - -// Usage limits expire by the system clock; pin it so the quota reset stays an hour ahead. -beforeEach(() => { - vi.useFakeTimers({ toFake: ['Date'] }) - vi.setSystemTime(NOW) -}) -afterEach(() => { - vi.useRealTimers() -}) - -type Row = { key: string; body: AgentJournalItemBody; turnScope?: AgentJournalTurnScope } - -function harness() { - const rows = new Map([[COMMAND_KEY, { key: COMMAND_KEY, body: RUNNING }]]) - const writes: Row[] = [] - const write = ( - identity: AgentJournalItemIdentity, - body: AgentJournalItemBody, - turnScope?: AgentJournalTurnScope - ) => { - const row = { key: agentJournalItemKey(identity), body, ...(turnScope ? { turnScope } : {}) } - rows.set(row.key, row) - writes.push(row) - } - const view = { - ...journalTimelineItemsView( - () => null, - () => - [...rows.values()].map(({ key, body, turnScope }, sequence) => ({ - itemId: key, - body, - ...(turnScope ? { turnScope } : {}), - revision: 1, - sequence, - observedAt: 0 - })) - ), - itemBody: (itemId: string) => rows.get(itemId)?.body ?? null - } - const revise: NonNullable = ( - bytes, - resolution, - options - ) => { - const resolved = resolveJournalTimelineItem(view, resolution, options.turnScope, bytes) - if (resolved.kind === 'resolved') { - write(resolved.item.identity, resolved.item.body, options.turnScope) - } - return { accepted: true } - } - const sink: StructuredAgentSessionEventSink = { - appendItem: (identity, body, options) => write(identity, body, options.turnScope), - appendTombstone: vi.fn(), - publish: vi.fn(), - tryReviseResolvedItem: revise, - tryReviseResolvedItemAndPublish: revise - } - const translator = createClaudeJournalTranslator({ sink, fallbackIdPrefix: 'test' }) - const frame = (message: Record, extra: Record = {}) => - translator.handle({ - type: 'message', - sessionId: 'orca-session', - message: { session_id: CAPTURED_COMPACT_SESSION_ID, ...message }, - observedAt: 5_000, - ...extra - }) - const begin = (sentUuid: string) => - translator.beginCommand({ - clientMessageId: 'cmd-1', - turnId: RUNNING.turnId, - identity: COMMAND_IDENTITY, - resultIdentity: { provider: 'orca', clientMessageId: 'command-result:cmd-1' }, - running: RUNNING, - providerSessionId: CAPTURED_COMPACT_SESSION_ID, - sentUuid - }) - const replay = (events: readonly CapturedCompactEvent[]) => { - for (const event of events) { - if ('sent' in event) { - if (event.sent.text === '/compact') { - begin(event.sent.uuid) - } - } else if ('interrupt' in event) { - translator.commandInterruptRequested(RUNNING.turnId) - } else { - frame(event.frame) - } - } - } - const commandTurn = () => readAgentJournalTurn(rows.get(COMMAND_KEY)?.body) - const drawn = () => - [...rows.values()].filter((row) => row.key !== COMMAND_KEY && row.body.kind !== 'turn') - return { translator, rows, writes, frame, begin, replay, commandTurn, drawn } -} - -describe('a captured /compact as the open Claude turn', () => { - it('leaves the command running at a result that names another input', () => { - const { begin, frame, commandTurn, translator } = harness() - begin('compact-input') - frame({ type: 'system', subtype: 'compact_boundary', uuid: 'boundary' }) - frame({ type: 'result', subtype: 'success', is_error: false, user_message_uuid: 'earlier' }) - expect(commandTurn()?.state).toBe('running') - expect(translator.commandTurnId).toBe(RUNNING.turnId) - - frame({ - type: 'result', - subtype: 'success', - is_error: false, - user_message_uuid: 'compact-input' - }) - expect(commandTurn()).toMatchObject({ state: 'completed', outcome: 'success' }) - }) -}) diff --git a/src/main/claude/structured/turns/claude-request-end-wait.test.ts b/src/main/claude/structured/turns/claude-request-end-wait.test.ts deleted file mode 100644 index f88c771841d..00000000000 --- a/src/main/claude/structured/turns/claude-request-end-wait.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { - awaitClaudeRequestEnd, - CLAUDE_STOP_GRACE_MS, - settleClaudeTurnEndWaiters -} from './claude-request-end-wait' -import type { ClaudeSession } from '../claude-structured-session-state' - -type InFlight = { translator: { currentTurnId: string | null }; dispatchWaiters: unknown[] } - -function claudeWith( - currentTurnId: string | null = 'turn-1', - unanswered = 0 -): { claude: ClaudeSession; state: InFlight } { - const state: InFlight = { - translator: { currentTurnId }, - dispatchWaiters: Array.from({ length: unanswered }, () => ({})) - } - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the wait reads only `translator.currentTurnId` and `dispatchWaiters`, and keys its waiters by the session's identity. - return { claude: state as unknown as ClaudeSession, state } -} - -async function settledWithin(promise: Promise, ms: number): Promise { - let settled = false - void promise.then(() => { - settled = true - }) - await vi.advanceTimersByTimeAsync(ms) - return settled -} - -describe("a Stop's wait for Claude to wind down what it has in flight", () => { - beforeEach(() => { - vi.useFakeTimers() - }) - afterEach(() => { - vi.useRealTimers() - }) - - it('waits on a send Claude has not echoed, through its turn, to that turn’s end', async () => { - const { claude, state } = claudeWith(null, 1) - const waiting = awaitClaudeRequestEnd(claude, CLAUDE_STOP_GRACE_MS) - state.dispatchWaiters.length = 0 - state.translator.currentTurnId = 'turn-1' - settleClaudeTurnEndWaiters(claude) - expect(await settledWithin(waiting, 0)).toBe(false) - - state.translator.currentTurnId = null - settleClaudeTurnEndWaiters(claude) - expect(await settledWithin(waiting, 0)).toBe(true) - }) -}) diff --git a/src/main/claude/subagents/claude-provisional-row-corrections.test.ts b/src/main/claude/subagents/claude-provisional-row-corrections.test.ts deleted file mode 100644 index c9ff7f239a3..00000000000 --- a/src/main/claude/subagents/claude-provisional-row-corrections.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { AGENT_JOURNAL_THREAD_SCOPE } from '../../../shared/agent-session/journal/agent-session-journal-types' -import { describe, expect, it } from 'vitest' -import type { AgentJournalItemBody } from '../../../shared/agent-session/journal/agent-session-journal-types' -import type { AgentJournalItemIdentity } from '../../../shared/agent-session/journal/agent-session-journal-identity' -import type { StructuredAgentSessionAppendOptions } from '../../native-chat/agent-session-wire/journal-ingress/structured-agent-session-event-sink' -import { ClaudeProvisionalRowCorrections } from './claude-provisional-row-corrections' -import type { ClaudeSubagentLinkageVerdict } from './claude-subagent-linkage' - -function identityOf(toolUseId: string): AgentJournalItemIdentity { - return { provider: 'orca', clientMessageId: `claude-tool:claude-session:${toolUseId}` } -} - -const RUNNING: AgentJournalItemBody = { - kind: 'tool-call', - callId: 'toolu_2', - name: 'Task', - input: null, - state: 'running' -} -const COMPLETED: AgentJournalItemBody = { ...RUNNING, state: 'completed' } - -function ledger(initial: Record = {}) { - const verdicts = new Map(Object.entries(initial)) - const rewrites: { - identity: AgentJournalItemIdentity - body: AgentJournalItemBody - options: StructuredAgentSessionAppendOptions - }[] = [] - let published = 0 - let refuse = false - const settledFor = (ref: string): ClaudeSubagentLinkageVerdict => { - const verdict = verdicts.get(ref) - return verdict && verdict.kind !== 'pending' - ? verdict - : { kind: 'linked', linkage: { agentId: ref, providerParentRef: ref, producerKind: 'agent' } } - } - const corrections = new ClaudeProvisionalRowCorrections({ - turnScope: () => AGENT_JOURNAL_THREAD_SCOPE, - linkageFor: (ref) => verdicts.get(ref) ?? { kind: 'pending' }, - settledLinkageFor: (ref) => { - const verdict = settledFor(ref) - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: `settledFor` returns only the linked arm, never `pending`. - return verdict as Exclude - }, - rewrite: (identity, body, options) => { - if (refuse) { - return false - } - rewrites.push({ identity, body, options }) - return true - }, - publish: () => { - published += 1 - } - }) - return { - corrections, - rewrites, - announce: (ref: string, agentId: string) => - verdicts.set(ref, { - kind: 'linked', - linkage: { agentId, providerParentRef: ref, producerKind: 'agent' } - }), - publishes: () => published, - setRefusing: (value: boolean) => { - refuse = value - } - } -} - -describe('ClaudeProvisionalRowCorrections', () => { - it('carries the NEWEST body when a row is written provisionally twice', () => { - const { corrections, rewrites, announce } = ledger() - const stamp = corrections.stampFor('toolu_1') - stamp(identityOf('toolu_2'), RUNNING) - stamp(identityOf('toolu_2'), COMPLETED) - - announce('toolu_1', 'task-1') - corrections.retry() - - expect(rewrites).toHaveLength(1) - expect(rewrites[0]?.body).toEqual(COMPLETED) - }) -}) diff --git a/src/main/cli/appimage/appimage-copy-pre-extraction.test.ts b/src/main/cli/appimage/appimage-copy-pre-extraction.test.ts deleted file mode 100644 index fc149b5215c..00000000000 --- a/src/main/cli/appimage/appimage-copy-pre-extraction.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { existsSync } from 'node:fs' -import { mkdir, mkdtemp, rename, rm, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { resolveAppImageExtractedRoot } from './appimage-extracted-root' -import { resolveAppImageLauncherEndpointPath } from './appimage-stable-launcher' -import type * as PreExtractionModule from './appimage-copy-pre-extraction' - -type PreExtraction = typeof PreExtractionModule - -const created: string[] = [] -let preExtraction: PreExtraction - -beforeEach(async () => { - // Why: the module holds this launch's in-flight copy, so every test starts a fresh launch. - vi.resetModules() - preExtraction = await import('./appimage-copy-pre-extraction') -}) - -afterEach(async () => { - await Promise.all(created.splice(0).map((path) => rm(path, { recursive: true, force: true }))) -}) - -async function makeFixture() { - const root = await mkdtemp(join(tmpdir(), 'orca-appimage-pre-extract-')) - created.push(root) - const appImagePath = join(root, 'apps', 'Orca.AppImage') - await mkdir(join(root, 'apps'), { recursive: true }) - await writeFile(appImagePath, 'release 1.0.0', { mode: 0o755 }) - return { root, appImagePath, cacheRootPath: join(root, 'cache') } -} - -async function writePayload(cwd: string): Promise { - const launcherDir = join(cwd, 'squashfs-root', 'resources', 'bin') - await mkdir(launcherDir, { recursive: true }) - await writeFile(join(launcherDir, 'orca-ide'), '', { mode: 0o755 }) -} - -const acceptCache = async (): Promise => null - -describe('preExtractDownloadedAppImageUpdate', () => { - it('unpacks the download into the copy its install will run from', async () => { - const { root, appImagePath, cacheRootPath } = await makeFixture() - const downloadedFile = join(root, 'apps', '.pending-Orca.AppImage') - await writeFile(downloadedFile, 'release 2.0.0', { mode: 0o755 }) - - const staged = await preExtraction.preExtractDownloadedAppImageUpdate( - downloadedFile, - async () => true, - { - appImagePath, - cacheRootPath, - probeCache: acceptCache, - runExtract: async (path, cwd) => { - expect(path).toBe(downloadedFile) - await writePayload(cwd) - }, - log: () => {} - } - ) - expect(staged).toBe(true) - - // What the updater's install does on one filesystem: a rename, which keeps the file identity. - await rename(downloadedFile, appImagePath) - const installed = resolveAppImageExtractedRoot({ appImagePath, cacheRootPath })! - expect(existsSync(installed.payloadLauncherPath)).toBe(true) - expect(existsSync(resolveAppImageLauncherEndpointPath(cacheRootPath, 'installed'))).toBe(false) - }) -}) diff --git a/src/main/codex-accounts/credentials/managed-codex-auth-readiness.test.ts b/src/main/codex-accounts/credentials/managed-codex-auth-readiness.test.ts deleted file mode 100644 index 3b2de38b2d5..00000000000 --- a/src/main/codex-accounts/credentials/managed-codex-auth-readiness.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it, vi } from 'vitest' - -import type { GlobalSettings } from '../../../shared/global-settings-types' -import type { CodexManagedAccount } from '../../../shared/managed-account-types' -import { - readStoredCodexCredentialState, - waitForManagedCodexAuthReady -} from './managed-codex-auth-readiness' - -const roots: string[] = [] -const testIdToken = 'e30.eyJlbWFpbCI6InVzZXJAZXhhbXBsZS5jb20ifQ.sig' -const testChatGptAuth = { - auth_mode: 'chatgpt', - tokens: { - access_token: 'access', - id_token: testIdToken, - refresh_token: 'refresh', - account_id: 'account' - }, - last_refresh: '2026-07-31T00:00:00Z' -} - -afterEach(() => { - vi.useRealTimers() - for (const root of roots.splice(0)) { - rmSync(root, { recursive: true, force: true }) - } -}) - -describe('waitForManagedCodexAuthReady', () => { - it('waits for a partial managed ChatGPT credential to become complete', async () => { - vi.useFakeTimers() - const fixture = createFixture() - writeAuth(fixture.home, { - tokens: { access_token: 'access', id_token: testIdToken } - }) - expect(readStoredCodexCredentialState(join(fixture.home, 'auth.json'))).toBe('incomplete') - let resolved = false - const readiness = waitForManagedCodexAuthReady(fixture.args) - void readiness?.then(() => { - resolved = true - }) - - await vi.advanceTimersByTimeAsync(50) - expect(resolved).toBe(false) - writeAuth(fixture.home, testChatGptAuth) - await vi.advanceTimersByTimeAsync(25) - - await expect(readiness).resolves.toBe(true) - }) -}) - -function createFixture(): { - root: string - home: string - args: Parameters[0] -} { - const root = mkdtempSync(join(tmpdir(), 'orca-managed-codex-auth-')) - roots.push(root) - const home = join(root, 'account', 'home') - mkdirSync(home, { recursive: true }) - const account = { - id: 'account-1', - managedHomePath: home, - managedHomeRuntime: 'host' - } as CodexManagedAccount - return { - root, - home, - args: { - codexHomePath: home, - settings: { codexManagedAccounts: [account] } as GlobalSettings, - target: { runtime: 'host' } - } - } -} - -function writeAuth(home: string, auth: Record): void { - writeFileSync(join(home, 'auth.json'), JSON.stringify(auth), { mode: 0o600 }) -} diff --git a/src/main/codex/history/resume/codex-session-resume-windows.test.ts b/src/main/codex/history/resume/codex-session-resume-windows.test.ts deleted file mode 100644 index 1f5e1d88c47..00000000000 --- a/src/main/codex/history/resume/codex-session-resume-windows.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { dirname, join, toNamespacedPath } from 'node:path' -import { tmpdir } from 'node:os' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { prepareCodexSessionResume } from './codex-session-resume-preparation' - -const windowsIt = process.platform === 'win32' ? it : it.skip -const cleanupPaths: string[] = [] - -afterEach(() => { - for (const cleanupPath of cleanupPaths.splice(0)) { - rmSync(cleanupPath, { recursive: true, force: true }) - } -}) - -describe('Codex session resume on native Windows', () => { - windowsIt('resumes an extended-length rollout from its ordinary trusted home', async () => { - const homePath = mkdtempSync(join(tmpdir(), 'orca-codex-resume-')) - cleanupPaths.push(homePath) - const rolloutPath = join( - homePath, - 'sessions', - '2026', - '07', - '20', - 'rollout-019f81b9-19a9-7651-a8d1-352d9420bd11.jsonl' - ) - mkdirSync(dirname(rolloutPath), { recursive: true }) - writeFileSync(rolloutPath, '{"type":"session_meta"}\n') - const transcriptPath = toNamespacedPath(rolloutPath) - const resolveVerifiedResumeHome = vi.fn(async () => homePath) - - await expect( - prepareCodexSessionResume({ - sessionId: '019f81b9-19a9-7651-a8d1-352d9420bd11', - transcriptPath, - trustedCodexHomes: [homePath], - getSelectedAccountCodexHome: () => null, - systemCodexHomePath: homePath, - sharedRuntimeCodexHomePath: null, - resolveVerifiedResumeHome - }) - ).resolves.toEqual({ outcome: 'resume', codexHomePath: homePath }) - expect(resolveVerifiedResumeHome).toHaveBeenCalledWith({ homePath, transcriptPath }) - }) -}) diff --git a/src/main/codex/structured/catalog/codex-structured-skill-report.test.ts b/src/main/codex/structured/catalog/codex-structured-skill-report.test.ts deleted file mode 100644 index 72a134cfe31..00000000000 --- a/src/main/codex/structured/catalog/codex-structured-skill-report.test.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { assert, describe, expect, it } from 'vitest' -import { acquired, fakeCodex } from '../session-lifecycle/codex-structured-session-adapter-fixture' -import type { AgentJournalMessageItem } from '../../../../shared/agent-session/journal/agent-session-journal-types' -import { - queuedMessageWithEdit, - type QueuedMessageEdit -} from '../../../../shared/queued-message-edit' - -function skill(name: string, path: string, enabled = true) { - return { name, path, description: `${name} skill`, scope: 'user', enabled } -} - -const PERSONAL_REVIEW = '/home/me/.agents/skills/review/SKILL.md' -const REPO_REVIEW = '/work/repo/.agents/skills/review/SKILL.md' -const PET = '/home/me/.codex/plugins/cache/work/pets/skills/create-pet/SKILL.md' - -async function settle(): Promise { - for (let turn = 0; turn < 5; turn += 1) { - await Promise.resolve() - } -} - -describe('a running Codex chat lists and runs the skills Codex loaded', () => { - it('reports Codex names and files, re-lists on change, and sends a pick by its file', async () => { - let listed = [ - skill('review', PERSONAL_REVIEW), - skill('review', REPO_REVIEW), - skill('work-pets:create-pet', PET), - skill('old', '/home/me/.agents/skills/old/SKILL.md', false) - ] - const codex = fakeCodex({ - 'skills/list': () => ({ data: [{ cwd: '/work/repo', skills: listed, errors: [] }] }), - 'turn/start': () => ({ turn: { id: 'turn-1' } }) - }) - const adapter = await acquired(codex) - await settle() - - const reported = adapter.readCommands('session-1') ?? [] - expect(reported.filter((row) => row.kind === 'command').map((row) => row.name)).toEqual( - expect.arrayContaining(['model', 'clear', 'compact', 'goal']) - ) - expect(reported.filter((row) => row.kind === 'skill')).toEqual( - listed - .filter(({ enabled }) => enabled) - .map(({ name, path, description }) => ({ - name, - path, - description, - kind: 'skill' - })) - ) - - listed = [...listed, skill('fresh', '/home/me/.agents/skills/fresh/SKILL.md')] - codex.connections[0].handlers.onNotification?.('skills/changed', {}) - await settle() - expect( - codex.connections[0].calls.findLast((call) => call.method === 'skills/list') - ).toMatchObject({ params: { cwds: ['/work/repo'], forceReload: true } }) - expect(adapter.readCommands('session-1')?.some((row) => row.name === 'fresh')).toBe(true) - - await adapter.dispatch({ - sessionId: 'session-1', - clientMessageId: 'pick-1', - fence: 7, - body: { - kind: 'message', - role: 'user', - blocks: [{ type: 'text', text: '$review this, then $gone' }], - skills: [ - { name: 'review', path: REPO_REVIEW }, - // Removed from the text after selection. - { name: 'work-pets:create-pet', path: PET }, - // Unloaded paths remain plain $name text. - { name: 'gone', path: '/elsewhere/gone/SKILL.md' } - ] - } - }) - expect( - codex.connections[0].calls.findLast((call) => call.method === 'turn/start')?.params?.input - ).toEqual([ - { type: 'text', text: '$review this, then $gone' }, - { type: 'skill', name: 'review', path: REPO_REVIEW } - ]) - - const text = 'project: $review personal: $review' - const skills = [ - { name: 'review', path: REPO_REVIEW }, - { name: 'review', path: PERSONAL_REVIEW } - ] - const body: AgentJournalMessageItem = { - kind: 'message', - role: 'user', - blocks: [ - { type: 'text', text }, - { type: 'image-ref', path: '/work/repo/example.png' } - ], - sentAs: 'goal', - from: { kind: 'agent', senders: [], orchestration: null }, - skills - } - const { blocks: _blocks, skills: _picks, ...retainedFields } = body - const edit = (body: AgentJournalMessageItem, input: QueuedMessageEdit) => { - const result = queuedMessageWithEdit(body, input) - assert(result.ok) - return result.body - } - const unchanged = edit(body, { text }) - expect(unchanged).toBe(body) - expect(unchanged.skills).toBe(skills) - const deleted = edit(body, { text: 'later' }) - const retyped = edit(deleted, { text }) - for (const [edited, expectedSkills] of [ - [unchanged, skills], - [edit(body, { text: 'project: $review' }), []], - [edit(body, { text: `${text} please` }), []], - [ - edit(body, { - text, - images: [{ type: 'image-ref', path: '/work/repo/example.png', alt: 'edited' }] - }), - [] - ], - [retyped, []], - [edit(body, { text: '/review', skills: [{ name: 'review', path: REPO_REVIEW }] }), []] - ] as const) { - expect(edited).toMatchObject(retainedFields) - const adapter = await acquired(codex) - await settle() - const connection = codex.connections.at(-1)! - await adapter.dispatch({ - sessionId: 'session-1', - clientMessageId: 'queued-pick', - fence: 7, - body: edited - }) - expect(connection.calls.find((call) => call.method === 'turn/start')?.params?.input).toEqual([ - ...edited.blocks.filter((block) => block.type === 'text'), - { type: 'localImage', path: '/work/repo/example.png' }, - ...expectedSkills.map((s) => ({ type: 'skill', ...s })) - ]) - } - }) -}) diff --git a/src/main/codex/structured/items/codex-generated-image-answer.test.ts b/src/main/codex/structured/items/codex-generated-image-answer.test.ts deleted file mode 100644 index cf66b6c4205..00000000000 --- a/src/main/codex/structured/items/codex-generated-image-answer.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { expect, it } from 'vitest' -import { chat, SESSION, THREAD, turn } from '../threads/codex-thread-catch-up-contract-test-fixture' -import { codexNonMessageIdentity } from './codex-thread-item-identity' -import { codexTurnLifecycleIdentity } from '../journal/codex-structured-journal-translation-turns' -import { agentJournalItemKey } from '../../../../shared/agent-session/journal/agent-session-journal-item-key' -import { projectStructuredItemsToNativeChat } from '../../../../shared/agent-session/view/structured-agent-session-projection' -import { nativeChatGeneratedImageAnswers } from '../../../../shared/native-chat/transcript/images/native-chat-generated-image-answers' -import { readTestJournalItems } from '../../../native-chat/agent-session-journal/journal-observation.test-support' - -it.each(['complete', 'sparse'])( - 'enriches %s authoritative saved generation once and preserves the result through replay', - async (shape) => { - const c = await chat({ now: 1000 }) - const identity = codexNonMessageIdentity(THREAD, 'turn-1', 'image-1') - const key = agentJournalItemKey(identity) - const turnIdentity = codexTurnLifecycleIdentity(SESSION, 'turn-1') - await c.journal.appendItem( - turnIdentity, - { kind: 'turn', turnId: 'turn-1', state: 'completed', outcome: 'success' }, - { fence: 1, turnScope: { kind: 'thread' } } - ) - await c.journal.appendItem( - identity, - { - kind: 'message', - role: 'assistant', - blocks: [ - { type: 'text', text: 'Generated image' }, - { type: 'image-ref', path: '/tmp/elephant.png' } - ] - }, - { fence: 1, turnScope: { kind: 'turn', turnItemId: agentJournalItemKey(turnIdentity) } } - ) - const supplied = { - ...turn(1), - items: [ - { - type: 'imageGeneration', - id: 'image-1', - ...(shape === 'complete' ? { status: 'completed', savedPath: '/tmp/elephant.png' } : {}) - }, - { type: 'agentMessage', id: 'answer', text: 'Here is your elephant.' } - ] - } - await c.open([], { returnedTurns: [supplied], paginate: false }) - const saved = (await c.journal.reads.item(key))! - expect(saved.body).toEqual({ - kind: 'message', - role: 'assistant', - blocks: [ - { type: 'text', text: 'Generated image', presentation: 'generated-image' }, - { type: 'image-ref', path: '/tmp/elephant.png' } - ] - }) - const messages = projectStructuredItemsToNativeChat(await readTestJournalItems(c.journal)) - const projected = nativeChatGeneratedImageAnswers( - messages, - messages.map(() => 'turn-1'), - new Set(['turn-1']), - () => [] - ) - expect( - projected.find((row) => - row.blocks.some((block) => block.type === 'text' && block.text === 'Here is your elephant.') - )?.blocks - ).toEqual([ - { type: 'text', text: 'Here is your elephant.' }, - { type: 'image-ref', path: '/tmp/elephant.png' } - ]) - await c.open([], { returnedTurns: [supplied], paginate: false }) - expect(await c.journal.reads.item(key)).toEqual(saved) - } -) diff --git a/src/main/codex/structured/journal/codex-turn-failures.test.ts b/src/main/codex/structured/journal/codex-turn-failures.test.ts deleted file mode 100644 index 96bf3377025..00000000000 --- a/src/main/codex/structured/journal/codex-turn-failures.test.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { readFileSync } from 'node:fs' -import { join } from 'node:path' -import { describe, expect, it } from 'vitest' -import { createCodexJournalTranslator } from './codex-structured-journal-translation' -import { - LIFECYCLE_KEY, - THREAD_ID, - TURN_ID, - notification, - recorder, - reduced, - translatorFor -} from './codex-turn-lifecycle-contract-test-fixture' - -const DIAGNOSTIC = 'Provider diagnostic: internal request failure' - -function error(code: unknown, extra: Record = {}) { - return { - threadId: THREAD_ID, - turnId: TURN_ID, - willRetry: false, - error: { message: DIAGNOSTIC, codexErrorInfo: code }, - ...extra - } -} - -function statuses(tap: ReturnType) { - return reduced(tap.rows).flatMap((row) => - row.body.kind === 'status' && row.body.failure?.kind !== 'providerRetrying' ? [row.body] : [] - ) -} - -describe('Codex terminal failure categories', () => { - it('ends a recorded-shape failed completion carrying an unknown future code', () => { - const frames: { - case: string - method: string - params: { - threadId: string - turn?: { id: string; status: string; error?: Record } - } - }[] = readFileSync( - join(__dirname, '../../__fixtures__/codex-app-server-turn-endings.jsonl'), - 'utf8' - ) - .trim() - .split('\n') - .map((line) => JSON.parse(line)) - const captured = frames.find( - (frame) => frame.case === '0.141.0-conn-refused' && frame.method === 'turn/completed' - ) - if (!captured?.params.turn) { - throw new Error('Missing captured failed completion') - } - const tap = recorder() - const translator = createCodexJournalTranslator({ - sink: tap.sink, - sessionId: 'session-1', - primaryThreadId: () => captured.params.threadId - }) - const on = (method: string, params: unknown) => - translator.handle({ - type: 'notification', - sessionId: 'session-1', - threadId: captured.params.threadId, - method, - params - }) - on('turn/started', { turn: { id: captured.params.turn.id } }) - expect(reduced(tap.rows).map((row) => row.body)).toMatchObject([ - { kind: 'turn', state: 'running' } - ]) - expect( - on('turn/completed', { - ...captured.params, - turn: { - ...captured.params.turn, - error: { ...captured.params.turn.error, codexErrorInfo: 'futureFailureAfter0167' } - } - }) - ).toEqual({ accepted: true }) - expect(reduced(tap.rows).map((row) => row.body)).toMatchObject([ - { kind: 'turn', state: 'completed', outcome: 'failure' }, - { kind: 'status', failure: { kind: 'providerResponseFailed' } } - ]) - }) - - it('shows a completion-only safety stop while preserving an ordinary Stop', () => { - for (const error of [{ message: DIAGNOSTIC, codexErrorInfo: 'tooManyDenials' }, null]) { - const tap = recorder() - const translator = translatorFor(tap) - translator.handle(notification('turn/started', { turn: { id: TURN_ID } })) - translator.handle( - notification('turn/completed', { turn: { id: TURN_ID, status: 'interrupted', error } }) - ) - expect(reduced(tap.rows).find((row) => row.key === LIFECYCLE_KEY)?.body).toMatchObject({ - kind: 'turn', - state: 'interrupted', - outcome: 'cancellation' - }) - expect(statuses(tap)).toMatchObject( - error ? [{ failure: { kind: 'providerSafetyStopped' } }] : [] - ) - } - }) - - it('keeps completion-only sign-in diagnostics behind Details', () => { - const tap = recorder() - const translator = translatorFor(tap) - translator.handle(notification('turn/started', { turn: { id: TURN_ID } })) - translator.handle( - notification('turn/completed', { - turn: { - id: TURN_ID, - status: 'failed', - error: error({ responseStreamDisconnected: { httpStatusCode: 401 } }).error - } - }) - ) - expect(statuses(tap)).toMatchObject([{ failure: { kind: 'notSignedIn' } }]) - expect(statuses(tap)[0]?.text).not.toContain(DIAGNOSTIC) - expect(statuses(tap)[0]?.providerFrame?.payload.head).toContain(DIAGNOSTIC) - }) - - it('keeps recovered sign-in advice through completion backpressure without another failure row', () => { - const tap = recorder() - let rejectCompletion = true - tap.sink.tryAppendItem = (identity, body, options) => { - if (body.kind === 'turn' && body.state === 'completed' && rejectCompletion) { - rejectCompletion = false - return { accepted: false, reason: 'backpressure' } - } - tap.sink.appendItem(identity, body, options) - return { accepted: true } - } - const translator = translatorFor(tap) - translator.handle(notification('turn/started', { turn: { id: TURN_ID } })) - translator.handle( - notification('error', { - ...error({ responseStreamDisconnected: { httpStatusCode: 401 } }, { willRetry: true }), - error: { - message: 'Reconnecting... 1/2', - codexErrorInfo: { responseStreamDisconnected: { httpStatusCode: 401 } }, - additionalDetails: DIAGNOSTIC - } - }) - ) - translator.handle(notification('error', error('other'))) - const completion = notification('turn/completed', { - turn: { id: TURN_ID, status: 'failed', error: error('other').error } - }) - expect(translator.handle(completion)).toEqual({ accepted: false, reason: 'backpressure' }) - expect(translator.handle(completion)).toEqual({ accepted: true }) - const terminal = tap.rows.filter( - (row) => row.body.kind === 'status' && row.body.failure?.kind !== 'providerRetrying' - ) - expect(terminal.map((row) => row.body)).toMatchObject([{ failure: { kind: 'notSignedIn' } }]) - expect(statuses(tap)[0]?.text).not.toContain(DIAGNOSTIC) - expect(statuses(tap)[0]?.providerFrame?.payload.head).toContain(DIAGNOSTIC) - expect(reduced(tap.rows).find((row) => row.key === LIFECYCLE_KEY)?.body).toMatchObject({ - state: 'completed', - outcome: 'failure' - }) - }) - - it('uses the last non-other retry only for matching text and scope, including empty details', () => { - const tap = recorder() - const translator = translatorFor(tap) - const retry = (code: unknown, details: string) => - notification('error', { - ...error(code, { willRetry: true }), - error: { message: DIAGNOSTIC, codexErrorInfo: code, additionalDetails: details } - }) - translator.handle(retry({ responseStreamDisconnected: { httpStatusCode: 401 } }, '')) - translator.handle(notification('error', error('other'))) - expect(statuses(tap).at(-1)?.failure?.kind).toBe('providerResponseFailed') - translator.handle(retry({ responseStreamDisconnected: { httpStatusCode: 401 } }, DIAGNOSTIC)) - translator.handle(retry('futureRetryCode', DIAGNOSTIC)) - translator.handle(notification('error', error('other'))) - expect(statuses(tap).at(-1)?.failure?.kind).toBe('providerResponseFailed') - translator.handle(retry({ responseStreamDisconnected: { httpStatusCode: 401 } }, DIAGNOSTIC)) - translator.handle(notification('error', error('other', { turnId: 'another-turn' }))) - expect(statuses(tap).at(-1)?.failure?.kind).toBe('providerResponseFailed') - }) -}) diff --git a/src/main/crash-reporting/minidumps/minidump-fault-context.test.ts b/src/main/crash-reporting/minidumps/minidump-fault-context.test.ts deleted file mode 100644 index 766f194ef6c..00000000000 --- a/src/main/crash-reporting/minidumps/minidump-fault-context.test.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { parseMinidumpCrashSignature } from './minidump-crash-signature' - -const STREAM_TYPE_MODULE_LIST = 4 -const STREAM_TYPE_MEMORY_LIST = 5 -const STREAM_TYPE_SYSTEM_INFO = 7 -const VER_PLATFORM_WIN32_NT = 2 - -const STREAM_TYPE_EXCEPTION = 6 -const CONTEXT_SIZE = 0x4d0 -// Electron 43.7.8 x64 bytes at electron.exe+0x23d3f88 for comparison with dump capture. - -type FaultDump = { - code: number - rip: bigint - params?: bigint[] - rsp?: bigint - contextFlags?: number - memory?: { start: bigint; bytes: Buffer }[] - modules?: { base: bigint; size: number; name: string }[] - platformId?: number -} - -function buildFaultDump(options: FaultDump): Buffer { - const streamCount = - 1 + - (options.memory ? 1 : 0) + - (options.modules ? 1 : 0) + - (options.platformId === undefined ? 0 : 1) - let cursor = 32 + streamCount * 12 - const regions: Buffer[] = [] - const append = (buf: Buffer): number => { - const rva = cursor - regions.push(buf) - cursor += buf.length - return rva - } - - const context = Buffer.alloc(CONTEXT_SIZE) - context.writeUInt32LE(options.contextFlags ?? 0x0010001f, 0x30) - context.writeBigUInt64LE(options.rsp ?? 0n, 0x98) - const contextRva = append(context) - - const exception = Buffer.alloc(168) - exception.writeUInt32LE(7, 0) - exception.writeUInt32LE(options.code, 8) - exception.writeBigUInt64LE(options.rip, 24) - const params = options.params ?? [] - exception.writeUInt32LE(params.length, 32) - params.forEach((value, index) => exception.writeBigUInt64LE(value, 40 + index * 8)) - exception.writeUInt32LE(CONTEXT_SIZE, 160) - exception.writeUInt32LE(contextRva, 164) - const streams = [{ type: STREAM_TYPE_EXCEPTION, size: 168, rva: append(exception) }] - - if (options.memory) { - const dataRvas = options.memory.map((range) => append(range.bytes)) - const list = Buffer.alloc(4 + options.memory.length * 16) - list.writeUInt32LE(options.memory.length, 0) - options.memory.forEach((range, index) => { - list.writeBigUInt64LE(range.start, 4 + index * 16) - list.writeUInt32LE(range.bytes.length, 12 + index * 16) - list.writeUInt32LE(dataRvas[index], 16 + index * 16) - }) - streams.push({ type: STREAM_TYPE_MEMORY_LIST, size: list.length, rva: append(list) }) - } - - if (options.modules) { - const nameRvas = options.modules.map((module) => { - const name = Buffer.from(module.name, 'utf16le') - const length = Buffer.alloc(4) - length.writeUInt32LE(name.length, 0) - return append(Buffer.concat([length, name])) - }) - const list = Buffer.alloc(4 + options.modules.length * 108) - list.writeUInt32LE(options.modules.length, 0) - options.modules.forEach((module, index) => { - list.writeBigUInt64LE(module.base, 4 + index * 108) - list.writeUInt32LE(module.size, 12 + index * 108) - list.writeUInt32LE(nameRvas[index], 24 + index * 108) - }) - streams.push({ type: STREAM_TYPE_MODULE_LIST, size: list.length, rva: append(list) }) - } - - if (options.platformId !== undefined) { - const systemInfo = Buffer.alloc(56) - systemInfo.writeUInt32LE(options.platformId, 20) - streams.push({ type: STREAM_TYPE_SYSTEM_INFO, size: 56, rva: append(systemInfo) }) - } - - const header = Buffer.alloc(32 + streamCount * 12) - header.writeUInt32LE(0x504d444d, 0) - header.writeUInt32LE(streamCount, 8) - header.writeUInt32LE(32, 12) - streams.forEach((stream, index) => { - header.writeUInt32LE(stream.type, 32 + index * 12) - header.writeUInt32LE(stream.size, 36 + index * 12) - header.writeUInt32LE(stream.rva, 40 + index * 12) - }) - return Buffer.concat([header, ...regions]) -} - -describe('minidump fault context', () => { - it('keeps only code bytes for non-AV exceptions and truncates at the captured range', async () => { - const signature = await parseMinidumpCrashSignature( - buildFaultDump({ - code: 0x80000003, - rip: 0x5000n, - params: [1n, 0x20n], - memory: [ - { start: 0x100n, bytes: Buffer.from('aa', 'hex') }, - { start: 0x4ffen, bytes: Buffer.from('9090cc0f0b', 'hex') } - ], - platformId: VER_PLATFORM_WIN32_NT, - modules: [{ base: 0x4000n, size: 0x2000, name: 'Orca.exe' }] - }) - ) - expect(signature?.fault).toEqual({ codeBytes: 'cc0f0b' }) - }) -}) diff --git a/src/main/emulator/avcc-frame-parser.test.ts b/src/main/emulator/avcc-frame-parser.test.ts deleted file mode 100644 index 63e20233814..00000000000 --- a/src/main/emulator/avcc-frame-parser.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { AvccFrameParser, type AvccFrame } from './avcc-frame-parser' - -function packet(tag: number, payload: number[]): number[] { - const length = payload.length + 1 - return [ - length >>> 24, - (length >>> 16) & 0xff, - (length >>> 8) & 0xff, - length & 0xff, - tag, - ...payload - ] -} - -function parse(chunks: number[][]): { frame: AvccFrame; bytes: number[] }[] { - const frames: { frame: AvccFrame; bytes: number[] }[] = [] - const parser = new AvccFrameParser((frame) => - frames.push({ frame, bytes: [...new Uint8Array(frame.bytes)] }) - ) - for (const chunk of chunks) { - parser.push(Uint8Array.from(chunk)) - } - return frames -} - -describe('AvccFrameParser', () => { - it('reassembles description, IDR and delta packets split anywhere across chunks', () => { - const wire = [...packet(1, [1, 0x64, 0, 0x33]), ...packet(2, [9, 9, 9]), ...packet(3, [7])] - const frames = parse([wire.slice(0, 3), wire.slice(3, 11), wire.slice(11, 12), wire.slice(12)]) - - expect(frames.map(({ frame, bytes }) => [frame.config, frame.keyFrame, bytes])).toEqual([ - [true, false, [1, 0x64, 0, 0x33]], - [false, true, [9, 9, 9]], - [false, false, [7]] - ]) - }) -}) diff --git a/src/main/environment-doctor/environment-doctor.test.ts b/src/main/environment-doctor/environment-doctor.test.ts deleted file mode 100644 index 09e2b2bfe38..00000000000 --- a/src/main/environment-doctor/environment-doctor.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { - runEnvironmentDoctor, - type EnvironmentDoctorCommandResult, - type EnvironmentDoctorDeps -} from './environment-doctor' - -const ROOT = '/work/repo' -const ok = (stdout = ''): EnvironmentDoctorCommandResult => ({ - code: 0, - stdout, - stderr: '', - timedOut: false -}) -const failed = (stderr: string, code = 128): EnvironmentDoctorCommandResult => ({ - code, - stdout: '', - stderr, - timedOut: false -}) - -function makeDeps(options: { - files?: Record - installed?: string[] - agents?: string[] - git?: (args: readonly string[]) => EnvironmentDoctorCommandResult - agentStatus?: Record - freeBytes?: number - setup?: EnvironmentDoctorCommandResult -}): EnvironmentDoctorDeps { - const files = options.files ?? {} - return { - platform: 'linux', - prepare: async () => {}, - run: async (program, args) => { - if (program === 'git') { - return options.git?.(args) ?? failed('not a git repository') - } - return options.agentStatus?.[program] ?? ok() - }, - findCommands: async (commands) => - new Set(commands.filter((command) => (options.installed ?? ['git']).includes(command))), - detectAgents: async () => options.agents ?? [], - readFile: async (path) => files[path.replace(`${ROOT}/`, '')] ?? null, - exists: async (path) => path.replace(`${ROOT}/`, '') in files, - isDirectory: async (path) => path === ROOT || path.startsWith(`${ROOT}/`), - freeBytes: async () => options.freeBytes ?? 50 * 1024 ** 3, - runSetupScript: vi.fn(async () => options.setup ?? ok()) - } -} - -function gitRepo(overrides: Record = {}) { - return (args: readonly string[]): EnvironmentDoctorCommandResult => { - const key = args.join(' ') - for (const [prefix, result] of Object.entries(overrides)) { - if (key.startsWith(prefix)) { - return result - } - } - if (key.startsWith('rev-parse --is-inside-work-tree')) { - return ok(`true\n${ROOT}\n/work/main/.git\n`) - } - if (key === 'symbolic-ref --quiet --short HEAD') { - return ok('feature\n') - } - if (key === 'remote') { - return ok('origin\n') - } - return ok() - } -} - -function statuses(result: Awaited>) { - return Object.fromEntries(result.checks.map((check) => [check.id, check.status])) -} - -describe('runEnvironmentDoctor', () => { - it('fails on a missing repo-implied CLI but only warns on a signed-out agent', async () => { - const result = await runEnvironmentDoctor( - { worktreePath: ROOT }, - makeDeps({ - files: { 'package.json': '{"packageManager":"pnpm@10.0.0"}' }, - installed: ['git', 'node', 'claude', 'codex'], - agents: ['claude', 'codex', 'gemini'], - agentStatus: { claude: failed('', 1) }, - git: gitRepo() - }) - ) - - expect(result.ok).toBe(false) - expect(statuses(result)).toMatchObject({ - 'tool.git': 'pass', - 'tool.node': 'pass', - 'tool.pnpm': 'fail', - 'agent.claude': 'warn', - 'agent.codex': 'pass', - 'agent.cli': 'pass', - 'git.fetch': 'pass', - 'git.push': 'pass', - 'setup.script': 'warn', - 'disk.free': 'pass' - }) - expect(result.checks.find((check) => check.id === 'agent.claude')?.remediation).toContain( - 'claude auth login' - ) - }) - - it('reports an unreachable remote without leaking the credential in its URL', async () => { - const result = await runEnvironmentDoctor( - { worktreePath: ROOT }, - makeDeps({ - git: gitRepo({ - 'ls-remote': failed( - "fatal: unable to access 'https://x-access-token:ghp_secret123@github.com/o/r.git/': 403" - ) - }) - }) - ) - - expect(statuses(result)['git.fetch']).toBe('fail') - expect(statuses(result)['git.push']).toBeUndefined() - expect(JSON.stringify(result)).not.toContain('ghp_secret123') - }) - - it('probes push with a dry run that skips hooks and targets a probe ref', async () => { - const calls: string[] = [] - const deps = makeDeps({ - git: (args) => { - calls.push(args.join(' ')) - return gitRepo({ push: failed('remote: Permission denied', 1) })(args) - } - }) - const result = await runEnvironmentDoctor({ worktreePath: ROOT }, deps) - - expect(statuses(result)['git.push']).toBe('fail') - expect(calls).toContain( - 'push --dry-run --no-verify --porcelain origin HEAD:refs/heads/orca-env-doctor-push-probe' - ) - }) - - it('runs the setup script only when asked and gates on its exit code', async () => { - const files = { 'orca.yaml': 'scripts:\n setup: pnpm install\n' } - const passive = makeDeps({ files, git: gitRepo() }) - const passiveResult = await runEnvironmentDoctor({ worktreePath: ROOT }, passive) - expect(passive.runSetupScript).not.toHaveBeenCalled() - expect(statuses(passiveResult)['setup.run']).toBe('warn') - - const active = makeDeps({ files, git: gitRepo(), setup: failed('ERR_PNPM_NO_LOCKFILE', 1) }) - const activeResult = await runEnvironmentDoctor({ worktreePath: ROOT, runSetup: true }, active) - expect(active.runSetupScript).toHaveBeenCalledWith({ - worktreePath: ROOT, - rootPath: '/work/main', - script: 'pnpm install' - }) - expect(activeResult.ok).toBe(false) - expect(activeResult.checks.find((check) => check.id === 'setup.run')).toMatchObject({ - status: 'fail', - message: 'Setup script exited with code 1.' - }) - expect(activeResult.checks.find((check) => check.id === 'setup.run')?.remediation).toContain( - 'ERR_PNPM_NO_LOCKFILE' - ) - }) - - it('reads the repo root when started in a subfolder, and fails on an unreadable checkout', async () => { - const files = { 'package.json': '{"packageManager":"pnpm@10.0.0"}' } - const fromSubfolder = await runEnvironmentDoctor( - { worktreePath: `${ROOT}/src` }, - makeDeps({ files, installed: ['git', 'node', 'pnpm'], git: gitRepo() }) - ) - expect(fromSubfolder.worktreePath).toBe(ROOT) - expect(statuses(fromSubfolder)['tool.pnpm']).toBe('pass') - - const dubious = await runEnvironmentDoctor( - { worktreePath: ROOT }, - makeDeps({ - git: gitRepo({ - 'rev-parse --is-inside-work-tree': failed( - "fatal: detected dubious ownership in repository at '/work/repo'" - ) - }) - }) - ) - expect(statuses(dubious)['git.repo']).toBe('fail') - expect(dubious.ok).toBe(false) - }) - - it('skips Git checks for a folder workspace and fails on a nearly full disk', async () => { - const result = await runEnvironmentDoctor( - { worktreePath: ROOT }, - makeDeps({ freeBytes: 512 * 1024 ** 2 }) - ) - - expect(statuses(result)).toMatchObject({ - 'git.repo': 'pass', - 'agent.cli': 'warn', - 'disk.free': 'fail' - }) - expect(statuses(result)['git.fetch']).toBeUndefined() - expect(result.ok).toBe(false) - }) -}) diff --git a/src/main/external-editors/default-app-location-open.test.ts b/src/main/external-editors/default-app-location-open.test.ts deleted file mode 100644 index e795b277d6c..00000000000 --- a/src/main/external-editors/default-app-location-open.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' - -const { applicationInfo, openPath, runProcess } = vi.hoisted(() => ({ - applicationInfo: vi.fn(), - openPath: vi.fn(), - runProcess: vi.fn() -})) -vi.mock('electron', () => ({ - app: { getApplicationInfoForProtocol: applicationInfo }, - shell: { openPath } -})) -vi.mock('@orca/process-host', () => ({ runProcess })) - -import { openPathInDefaultApp } from './default-app-location-open' -import type { RuntimeFileOpenPosition } from '../../shared/file-access/runtime-editor-file-open' - -const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform')! -const filePath = '/tmp/project with spaces/main #1.json' - -function setPlatform(value: NodeJS.Platform): void { - Object.defineProperty(process, 'platform', { configurable: true, value }) -} - -describe('openPathInDefaultApp', () => { - beforeEach(() => { - vi.resetAllMocks() - setPlatform('darwin') - applicationInfo.mockResolvedValue({ path: '/Applications/Cursor.app' }) - runProcess.mockResolvedValue({ code: 0, timedOut: false }) - openPath.mockResolvedValue('') - }) - afterEach(() => { - Object.defineProperty(process, 'platform', originalPlatform) - }) - - it.each([ - ['Cursor.app', { line: 551, column: 7 }, '551:7'], - ['Visual Studio Code.app', { line: 551 }, '551'], - ['Visual Studio Code - Insiders.app', { line: 551, column: 7 }, '551:7'] - ])( - 'hands the line to a default %s instead of the OS opener', - async (bundle, location, suffix) => { - const appPath = `/Users/ada/Applications/${bundle}` - applicationInfo.mockResolvedValue({ path: appPath }) - - await expect(openPathInDefaultApp(filePath, location)).resolves.toBe('') - - expect(applicationInfo).toHaveBeenCalledWith( - 'file:///tmp/project%20with%20spaces/main%20%231.json' - ) - expect(runProcess).toHaveBeenCalledWith( - expect.objectContaining({ - program: '/usr/bin/open', - args: ['-n', '-g', '-a', appPath, '--args', '--goto', `${filePath}:${suffix}`], - env: {}, - timeoutMs: null - }) - ) - expect(openPath).not.toHaveBeenCalled() - } - ) - - it.each<[string, () => void]>([ - ['another default app', () => applicationInfo.mockResolvedValue({ path: '/A/Zed.app' })], - ['a failed association lookup', () => applicationInfo.mockRejectedValue(new Error('none'))], - ['an open that exits non-zero', () => runProcess.mockResolvedValue({ code: 1 })], - ['an open that cannot spawn', () => runProcess.mockRejectedValue(new Error('ENOENT'))] - ])('opens once with the OS opener on %s', async (_name, arrange) => { - arrange() - openPath.mockResolvedValue('no app') - - await expect(openPathInDefaultApp(filePath, { line: 551 })).resolves.toBe('no app') - expect(openPath).toHaveBeenCalledTimes(1) - expect(openPath).toHaveBeenCalledWith(filePath) - }) - - it.each<[string, NodeJS.Platform, RuntimeFileOpenPosition | undefined]>([ - ['links without a line', 'darwin', undefined], - ['a zero line', 'darwin', { line: 0 }], - ['a fractional line', 'darwin', { line: 1.5 }], - ['a zero column', 'darwin', { line: 551, column: 0 }], - ['Linux', 'linux', { line: 551 }], - ['Windows', 'win32', { line: 551 }] - ])('leaves %s to the OS opener', async (_name, platform, location) => { - setPlatform(platform) - - await expect(openPathInDefaultApp(filePath, location)).resolves.toBe('') - expect(applicationInfo).not.toHaveBeenCalled() - expect(runProcess).not.toHaveBeenCalled() - expect(openPath).toHaveBeenCalledWith(filePath) - }) -}) diff --git a/src/main/git/command-runner/host-routing/git-command-resolution-windows-checkout.test.ts b/src/main/git/command-runner/host-routing/git-command-resolution-windows-checkout.test.ts deleted file mode 100644 index f79e5926cca..00000000000 --- a/src/main/git/command-runner/host-routing/git-command-resolution-windows-checkout.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { resolveGitCommandWithoutProbe } from './git-command-resolution' -import { - recordHostAutocrlf, - recordLineEndingSample, - resetWslWindowsCheckoutGitConfigForTests, - wslWindowsCheckoutKey -} from './wsl-windows-checkout-git-config' -import { resetWslLinkedWorktreeGitRoutingForTests } from './wsl-linked-worktree-git-routing' - -const originalPlatform = process.platform -const DRIVE_REPO = String.raw`C:\Users\dev\repo` - -function detectWindowsCheckout(): void { - const key = wslWindowsCheckoutKey(DRIVE_REPO, 'Ubuntu') - recordHostAutocrlf(key, 'true', Date.now()) - recordLineEndingSample(key, 'windows', 'clone', Date.now()) -} - -describe('WSL git on a Windows Git checkout', () => { - beforeEach(() => { - Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) - }) - - afterEach(() => { - Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) - resetWslWindowsCheckoutGitConfigForTests() - resetWslLinkedWorktreeGitRoutingForTests() - }) - - it('runs WSL git with Windows Git line-ending and stat settings once detected', () => { - detectWindowsCheckout() - - const resolved = resolveGitCommandWithoutProbe(['add', '--', 'a.ts'], { - cwd: DRIVE_REPO, - wslDistro: 'Ubuntu' - }) - - expect(resolved.binary).toBe('wsl.exe') - expect(resolved.args.join(' ')).toMatch(/core\.autocrlf=true.+core\.checkStat=minimal.+add/) - expect(resolved.args.join(' ')).not.toContain('trustctime') - }) -}) diff --git a/src/main/git/command-runner/host-routing/runner-windows-host-environment.test.ts b/src/main/git/command-runner/host-routing/runner-windows-host-environment.test.ts deleted file mode 100644 index 5d0e226d386..00000000000 --- a/src/main/git/command-runner/host-routing/runner-windows-host-environment.test.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { EventEmitter } from 'node:events' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' - -const { execFileMock, spawnMock } = vi.hoisted(() => ({ - execFileMock: vi.fn(), - spawnMock: vi.fn() -})) - -vi.mock('node:child_process', () => ({ - execFile: execFileMock, - execFileSync: vi.fn(), - spawn: spawnMock -})) - -import { - awaitWindowsHostGitEnvironmentReady, - configureWindowsHostGitEnvironmentReadiness -} from './windows-host-git-environment' -import { gitExecFileAsync, gitExecFileAsyncBuffer } from '../git-exec-file' -import { gitSpawnAfterWindowsEnvironmentReady } from '../git-spawn' -import { gitStreamStdout } from '../git-stream-stdout' -import { _resetGitAdmissionForTests } from '../admission/git-subprocess-admission' - -type MockChildProcess = EventEmitter & { - stdout: EventEmitter - stderr: EventEmitter - pid: number - kill: ReturnType -} - -function createMockChildProcess(pid: number): MockChildProcess { - const child = new EventEmitter() as MockChildProcess - child.stdout = new EventEmitter() - child.stderr = new EventEmitter() - child.pid = pid - child.kill = vi.fn() - return child -} - -function deferred(): { promise: Promise; resolve: () => void } { - let resolve!: () => void - const promise = new Promise((next) => { - resolve = next - }) - return { promise, resolve } -} - -async function withPlatform(platform: NodeJS.Platform, fn: () => Promise): Promise { - const original = process.platform - Object.defineProperty(process, 'platform', { configurable: true, value: platform }) - try { - return await fn() - } finally { - Object.defineProperty(process, 'platform', { configurable: true, value: original }) - } -} - -describe('Windows host Git environment readiness', () => { - const originalPath = process.env.Path - - beforeEach(() => { - execFileMock.mockReset() - spawnMock.mockReset() - }) - - afterEach(() => { - _resetGitAdmissionForTests() - configureWindowsHostGitEnvironmentReadiness(null) - if (originalPath === undefined) { - delete process.env.Path - } else { - process.env.Path = originalPath - } - }) - - it('does not gate spawned Git routed through WSL on the Windows host profile', async () => { - await withPlatform('win32', async () => { - const waitUntilReady = vi.fn(() => new Promise(() => {})) - const child = createMockChildProcess(1234) - spawnMock.mockReturnValue(child) - execFileMock.mockImplementation((_cmd, _args, _options, callback) => { - callback(Object.assign(new Error('missing SSH config'), { code: 1 }), '', '') - return child - }) - configureWindowsHostGitEnvironmentReadiness(waitUntilReady) - - await expect( - gitSpawnAfterWindowsEnvironmentReady(['clone', 'url', 'repo'], { - cwd: String.raw`C:\repo`, - wslDistro: 'Ubuntu', - stdio: ['ignore', 'ignore', 'pipe'] - }) - ).resolves.toBe(child) - - expect(waitUntilReady).not.toHaveBeenCalled() - expect(spawnMock).toHaveBeenCalled() - }) - }) - - it('does not spawn Git when canceled during Windows environment readiness', async () => { - await withPlatform('win32', async () => { - const ready = deferred() - const controller = new AbortController() - configureWindowsHostGitEnvironmentReadiness(() => ready.promise) - - const spawned = gitSpawnAfterWindowsEnvironmentReady(['status'], { - cwd: String.raw`C:\repo`, - signal: controller.signal, - stdio: ['ignore', 'ignore', 'pipe'] - }) - controller.abort() - - await expect(spawned).rejects.toMatchObject({ name: 'AbortError' }) - expect(spawnMock).not.toHaveBeenCalled() - ready.resolve() - }) - }) - - it('cancels async Git immediately while Windows environment readiness is pending', async () => { - await withPlatform('win32', async () => { - const ready = deferred() - const controller = new AbortController() - configureWindowsHostGitEnvironmentReadiness(() => ready.promise) - - const operation = gitExecFileAsync(['status'], { - cwd: String.raw`C:\repo`, - signal: controller.signal - }) - controller.abort() - - await expect(operation).rejects.toMatchObject({ name: 'AbortError' }) - expect(execFileMock).not.toHaveBeenCalled() - ready.resolve() - }) - }) - - it('does not gate WSL paths at a synchronous Git consumer boundary', async () => { - await withPlatform('win32', async () => { - const waitUntilReady = vi.fn(() => new Promise(() => {})) - configureWindowsHostGitEnvironmentReadiness(waitUntilReady) - - await expect( - awaitWindowsHostGitEnvironmentReady({ - cwd: String.raw`\\wsl.localhost\Ubuntu\home\me\repo` - }) - ).resolves.toBeUndefined() - - expect(waitUntilReady).not.toHaveBeenCalled() - }) - }) - - it('does not gate Git routed through WSL on the Windows host profile', async () => { - await withPlatform('win32', async () => { - const waitUntilReady = vi.fn(() => new Promise(() => {})) - const child = createMockChildProcess(1234) - execFileMock.mockImplementation((_cmd, _args, _options, callback) => { - callback(null, 'ok', '') - return child - }) - configureWindowsHostGitEnvironmentReadiness(waitUntilReady) - - await expect( - gitExecFileAsync(['status'], { - cwd: String.raw`C:\repo`, - wslDistro: 'Ubuntu' - }) - ).resolves.toEqual({ stdout: 'ok', stderr: '' }) - - expect(waitUntilReady).not.toHaveBeenCalled() - expect(execFileMock).toHaveBeenCalled() - }) - }) - - it('gates buffered native Git reads on the current generation', async () => { - await withPlatform('win32', async () => { - const ready = deferred() - const child = createMockChildProcess(1234) - execFileMock.mockImplementation((_cmd, _args, _options, callback) => { - callback(null, Buffer.from('blob'), Buffer.alloc(0)) - return child - }) - configureWindowsHostGitEnvironmentReadiness(() => ready.promise) - - const read = gitExecFileAsyncBuffer(['show', 'HEAD:file'], { cwd: String.raw`C:\repo` }) - expect(execFileMock).not.toHaveBeenCalled() - ready.resolve() - - await expect(read).resolves.toEqual({ stdout: Buffer.from('blob') }) - }) - }) - - it('gates native Git streams and refreshes their snapshotted PATH', async () => { - await withPlatform('win32', async () => { - const ready = deferred() - const child = createMockChildProcess(1234) - spawnMock.mockReturnValue(child) - configureWindowsHostGitEnvironmentReadiness(() => ready.promise) - process.env.Path = 'hydrated-stream-path' - - const stream = gitStreamStdout(['status'], { - cwd: String.raw`C:\repo`, - env: { Path: 'stale-stream-path' }, - onStdout: () => {} - }) - expect(spawnMock).not.toHaveBeenCalled() - ready.resolve() - await vi.waitFor(() => expect(spawnMock).toHaveBeenCalledOnce()) - expect(spawnMock.mock.calls[0]?.[2]?.env?.Path).toBe('hydrated-stream-path') - child.emit('close', 0) - - await expect(stream).resolves.toEqual({ stoppedEarly: false }) - }) - }) -}) diff --git a/src/main/git/command-runner/host-routing/wsl-windows-checkout-git-probe.test.ts b/src/main/git/command-runner/host-routing/wsl-windows-checkout-git-probe.test.ts deleted file mode 100644 index dc3ac59ca94..00000000000 --- a/src/main/git/command-runner/host-routing/wsl-windows-checkout-git-probe.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { WslResult } from '../../../wsl/execution/wsl-runner' -import { - pendingWslWindowsCheckoutGitConfig, - resetWslWindowsCheckoutProbesForTests, - type HostGitResult, - type WslWindowsCheckoutProbeDeps -} from './wsl-windows-checkout-git-probe' -import { - resetWslWindowsCheckoutGitConfigForTests, - withWslWindowsCheckoutGitConfig -} from './wsl-windows-checkout-git-config' -import { - HOST_CONFIG_SYSTEM_AUTOCRLF, - PLAIN_WINDOWS_CLONE_SAMPLE -} from './wsl-windows-checkout-line-endings.test-fixture' - -afterEach(() => { - resetWslWindowsCheckoutGitConfigForTests() - resetWslWindowsCheckoutProbesForTests() -}) - -const CWD = String.raw`C:\Users\dev\repo` -const READ = ['status', '--porcelain=v2'] - -function host(overrides: Partial = {}): HostGitResult { - return { code: 0, stdout: HOST_CONFIG_SYSTEM_AUTOCRLF, stderr: '', timedOut: false, ...overrides } -} - -function wsl(overrides: Partial = {}): WslResult { - return { - environmentResolved: true, - code: 0, - stdout: PLAIN_WINDOWS_CLONE_SAMPLE, - stderr: '', - timedOut: false, - outputTruncated: false, - ...overrides - } -} - -type HostRunner = NonNullable -type WslRunner = NonNullable -type IdentityReader = NonNullable - -function harness( - overrides: { runHostGit?: HostRunner; runWsl?: WslRunner; checkoutIdentity?: IdentityReader } = {} -) { - const clock = { now: 1_000_000 } - const deps = { - platform: 'win32' as const, - now: () => clock.now, - runHostGit: vi.fn(overrides.runHostGit ?? (async () => host())), - runWsl: vi.fn(overrides.runWsl ?? (async () => wsl())), - checkoutIdentity: vi.fn(overrides.checkoutIdentity ?? (async () => 'clone-1')), - admit: vi.fn(async () => ({ queueWaitMs: 0, release: vi.fn() })) - } - const run = (args: string[], signal?: AbortSignal) => - pendingWslWindowsCheckoutGitConfig(args, { cwd: CWD, wslDistro: 'Ubuntu', signal }, deps) - const flagged = (args: string[]) => - withWslWindowsCheckoutGitConfig(args, CWD, 'Ubuntu', 'win32', clock.now).includes( - 'core.autocrlf=true' - ) - return { clock, deps, run, flagged } -} - -describe('pendingWslWindowsCheckoutGitConfig', () => { - it('stops waiting when the command aborts', async () => { - const { run } = harness({ runHostGit: vi.fn(() => new Promise(() => {})) }) - const controller = new AbortController() - const waiting = run(READ, controller.signal) - controller.abort() - await expect(waiting).resolves.toBeUndefined() - }) -}) diff --git a/src/main/git/command-runner/hosted-cli/runner-gh-rate-limit-breaker.test.ts b/src/main/git/command-runner/hosted-cli/runner-gh-rate-limit-breaker.test.ts deleted file mode 100644 index 3018550b00a..00000000000 --- a/src/main/git/command-runner/hosted-cli/runner-gh-rate-limit-breaker.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' - -const { execFileMock, execFileSyncMock, spawnMock } = vi.hoisted(() => ({ - execFileMock: vi.fn(), - execFileSyncMock: vi.fn(), - spawnMock: vi.fn() -})) - -vi.mock('child_process', () => ({ - execFile: execFileMock, - execFileSync: execFileSyncMock, - spawn: spawnMock -})) - -import { fakeSpawnReturning } from '../../../../shared/__fixtures__/fake-spawned-child' -import { ghExecFileAsync } from './gh-exec-file' -import { _resetGhRateLimitBreaker } from './gh-rate-limit-breaker' - -const PRIMARY_RATE_LIMIT_STDERR = - 'gh: API rate limit exceeded for user ID 1775218. Please wait. (HTTP 403)' - -function mockGhFailure(stderr: string): void { - spawnMock.mockImplementation(fakeSpawnReturning({ stderr, code: 1 })) -} - -beforeEach(() => { - execFileMock.mockReset() - spawnMock.mockReset() -}) - -afterEach(() => { - _resetGhRateLimitBreaker() -}) - -describe('ghExecFileAsync rate-limit breaker', () => { - it('spawns once for a primary 403, then short-circuits same-bucket calls', async () => { - mockGhFailure(PRIMARY_RATE_LIMIT_STDERR) - await expect( - ghExecFileAsync(['api', '--cache', '120s', 'search/issues?q=repo:a/b&per_page=1']) - ).rejects.toThrow('rate limit') - expect(spawnMock).toHaveBeenCalledTimes(1) - - await expect( - ghExecFileAsync(['api', '--cache', '120s', 'search/issues?q=repo:c/d&per_page=1']) - ).rejects.toMatchObject({ ghRateLimitBlocked: true }) - expect(spawnMock).toHaveBeenCalledTimes(1) - }) -}) diff --git a/src/main/git/command-runner/runner-buffer-cancellation.test.ts b/src/main/git/command-runner/runner-buffer-cancellation.test.ts deleted file mode 100644 index 7ab47ac11e7..00000000000 --- a/src/main/git/command-runner/runner-buffer-cancellation.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' - -const { execFileMock } = vi.hoisted(() => ({ execFileMock: vi.fn() })) -vi.mock('node:child_process', () => ({ - execFile: execFileMock, - execFileSync: vi.fn(), - spawn: vi.fn() -})) - -import { gitExecFileAsyncBuffer } from './git-exec-file' - -import { _resetGitAdmissionForTests } from './admission/git-subprocess-admission' -import { configureWindowsHostGitEnvironmentReadiness } from './host-routing/windows-host-git-environment' - -beforeEach(() => execFileMock.mockReset()) -afterEach(() => { - _resetGitAdmissionForTests() - configureWindowsHostGitEnvironmentReadiness(null) -}) - -describe('buffered Git cancellation', () => { - it('cancels Windows environment readiness without launching Git', async () => { - const platform = process.platform - Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) - try { - configureWindowsHostGitEnvironmentReadiness(() => new Promise(() => {})) - const controller = new AbortController() - const read = gitExecFileAsyncBuffer(['show', 'HEAD:file'], { - cwd: String.raw`C:\repo`, - signal: controller.signal - }) - const rejected = expect(read).rejects.toMatchObject({ name: 'AbortError' }) - controller.abort() - await rejected - expect(execFileMock).not.toHaveBeenCalled() - } finally { - Object.defineProperty(process, 'platform', { configurable: true, value: platform }) - } - }) -}) diff --git a/src/main/git/refs/resolution/repo-branch-conflict-real-git.test.ts b/src/main/git/refs/resolution/repo-branch-conflict-real-git.test.ts deleted file mode 100644 index 1aad351a523..00000000000 --- a/src/main/git/refs/resolution/repo-branch-conflict-real-git.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { execFileSync } from 'node:child_process' -import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it } from 'vitest' -import { getBranchConflictKind } from './repo-branch-conflict' - -describe('branch conflict real Git contract', () => { - const tempPaths: string[] = [] - - afterEach(() => { - for (const path of tempPaths.splice(0)) { - rmSync(path, { recursive: true, force: true }) - } - }) - - it('decides remote conflicts from one batched probe across many remotes', async () => { - const repoPath = mkdtempSync(join(tmpdir(), 'orca-branch-conflict-')) - tempPaths.push(repoPath) - const git = (...args: string[]): string => - execFileSync('git', args, { cwd: repoPath, encoding: 'utf8' }) - - git('init', '--quiet') - git('config', 'user.name', 'Orca Test') - git('config', 'user.email', 'orca@example.test') - git('config', 'commit.gpgSign', 'false') - git('config', 'core.hooksPath', '.git/no-hooks') - writeFileSync(join(repoPath, 'fixture.txt'), 'base\n') - git('add', 'fixture.txt') - git('commit', '--quiet', '-m', 'base') - const head = git('rev-parse', 'HEAD').trim() - - for (let index = 0; index < 12; index += 1) { - git('remote', 'add', `remote${index}`, 'https://example.test/repo.git') - } - git('update-ref', 'refs/remotes/remote7/taken', head) - - await expect(getBranchConflictKind(repoPath, 'taken')).resolves.toBe('remote') - await expect(getBranchConflictKind(repoPath, 'free')).resolves.toBeNull() - await expect( - getBranchConflictKind(repoPath, 'taken', 'refs/remotes/remote7/taken') - ).resolves.toBeNull() - - git('branch', 'local-only', head) - await expect(getBranchConflictKind(repoPath, 'local-only')).resolves.toBe('local') - }) -}) diff --git a/src/main/git/refs/snapshot/branch-ref-snapshot-read.test.ts b/src/main/git/refs/snapshot/branch-ref-snapshot-read.test.ts deleted file mode 100644 index 419d56412a1..00000000000 --- a/src/main/git/refs/snapshot/branch-ref-snapshot-read.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { afterEach, expect, it, vi } from 'vitest' -const stream = vi.hoisted(() => vi.fn()) -vi.mock('../../command-runner/git-stream-stdout', () => ({ gitStreamStdout: stream })) -import { readBranchRefSnapshot } from './branch-ref-snapshot-read' - -afterEach(() => stream.mockReset()) - -it('keeps raw output complete under aggregate pressure and distinguishes an intrinsic bound', async () => { - stream.mockImplementation(async (_args, options) => { - for (const name of ['first', 'second']) { - if (options.onStdout(`refs/heads/${name}\0${'a'.repeat(40)}\u00001\0\n`) === true) { - return { stoppedEarly: true } - } - } - return { stoppedEarly: false } - }) - const page: string[] = [] - const pressured = await readBranchRefSnapshot( - '/repo', - {}, - (ref) => { - page.push(ref.refName) - return page.length === 2 - }, - undefined, - { reserve: () => false, release: () => {} } - ) - expect(page).toEqual(['refs/heads/first', 'refs/heads/second']) - expect(pressured).toEqual({ snapshot: null, oversized: false }) - expect(await readBranchRefSnapshot('/repo', {}, () => true, 100)).toEqual({ - snapshot: null, - oversized: true - }) - const recovered = await readBranchRefSnapshot('/repo', {}, () => true) - expect(recovered.snapshot?.refs.map((ref) => ref.refName)).toEqual([ - 'refs/heads/first', - 'refs/heads/second' - ]) -}) diff --git a/src/main/git/refs/snapshot/branch-ref-snapshot-routing.test.ts b/src/main/git/refs/snapshot/branch-ref-snapshot-routing.test.ts deleted file mode 100644 index f4947725675..00000000000 --- a/src/main/git/refs/snapshot/branch-ref-snapshot-routing.test.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { afterEach, expect, it, vi } from 'vitest' -import type * as FsPromises from 'node:fs/promises' -import type * as SnapshotReader from './branch-ref-snapshot-read' -import type * as DistroCatalog from '../../../wsl/discovery/distro-catalog' - -const cwd = String.raw`C:\repo-linked` -const commonDir = String.raw`C:\repo-main\.git` -const gitDir = String.raw`C:\repo-main\.git\worktrees\linked` -const io = vi.hoisted(() => ({ remote: vi.fn(), refs: vi.fn() })) -vi.mock('../../../wsl/discovery/distro-catalog', async (original) => ({ - ...(await original()), - listRunningWslDistrosAsync: async () => ['Ubuntu'] -})) -vi.mock('node:fs/promises', async (original) => ({ - ...(await original()), - realpath: async (path: string) => path, - stat: async (path: string) => ({ - isFile: () => path.endsWith('.git'), - isDirectory: () => !path.endsWith('.git'), - dev: 1n, - ino: 2n, - birthtimeNs: 3n - }), - readFile: async () => String.raw`gitdir: C:\repo-main\.git\worktrees\linked` -})) -vi.mock('../../../../shared/git/metadata/git-common-directory', () => ({ - resolveGitCommonDirectory: async () => String.raw`C:\repo-main\.git` -})) -vi.mock('../../source-control/resolve-git-dir', () => ({ - resolveGitDir: async () => String.raw`C:\repo-main\.git\worktrees\linked` -})) -vi.mock('./branch-ref-snapshot-read', async (original) => ({ - ...(await original()), - readBranchRemoteNames: io.remote, - readBranchRefSnapshot: io.refs -})) -import { searchBranchRefSnapshot, _resetBranchRefSnapshotsForTests } from './branch-ref-snapshot' -import { - prepareWslLinkedWorktreeGitRouting, - resetWslLinkedWorktreeGitRoutingForTests -} from '../../command-runner/host-routing/wsl-linked-worktree-git-routing' -import { resolveBranchSnapshotIdentity } from './branch-ref-snapshot-identity' -import { trackGitRefMutation } from '../../command-runner/git-ref-mutation-state' -import { subscribeGitRefChanges } from '../git-ref-change-signal' -import { _resetWslBackgroundDistroGateForTests } from '../../../wsl/discovery/wsl-background-distro-gate' - -const platform = process.platform -afterEach(() => { - _resetBranchRefSnapshotsForTests() - resetWslLinkedWorktreeGitRoutingForTests() - _resetWslBackgroundDistroGateForTests() - Object.defineProperty(process, 'platform', { configurable: true, value: platform }) - vi.restoreAllMocks() - io.remote.mockReset() - io.refs.mockReset() -}) - -it('keeps a live host snapshot across expiry of the filesystem-only linked-route proof', async () => { - Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) - const clock = vi.spyOn(Date, 'now').mockReturnValue(10_000) - // The reader boundary models execution's existing route settlement; it is not a real WSL benchmark. - io.remote.mockImplementation(async () => { - await prepareWslLinkedWorktreeGitRouting(cwd, 'Ubuntu') - return [] - }) - io.refs.mockResolvedValue({ - snapshot: { - refs: [ - { - refName: 'refs/heads/topic', - label: 'topic', - searchName: 'topic', - oid: 'a'.repeat(40), - committedAt: 0, - symref: '' - } - ] - }, - oversized: false - }) - expect(await searchBranchRefSnapshot(cwd, 'topic', 20, { wslDistro: 'Ubuntu' })).toEqual([ - { refName: 'refs/heads/topic', localBranchName: 'topic' } - ]) - clock.mockReturnValue(40_001) - expect(await resolveBranchSnapshotIdentity(cwd, { wslDistro: 'Ubuntu' })).toMatchObject({ - commonDir, - gitDir - }) - expect(await searchBranchRefSnapshot(cwd, 'topic', 20, { wslDistro: 'Ubuntu' })).toEqual([ - { refName: 'refs/heads/topic', localBranchName: 'topic' } - ]) - expect(io.remote).toHaveBeenCalledTimes(1) - expect(io.refs).toHaveBeenCalledTimes(1) - clock.mockReturnValue(70_002) - const events: string[] = [] - const offOwner = subscribeGitRefChanges(commonDir, () => events.push('owner')) - const offOther = subscribeGitRefChanges(String.raw`C:\other\.git`, () => events.push('other')) - try { - trackGitRefMutation(['commit'])() - expect(events).toEqual(['owner', 'other', 'owner', 'other']) - } finally { - offOwner() - offOther() - } -}) diff --git a/src/main/git/repositories/discovery/repo-detection-async.test.ts b/src/main/git/repositories/discovery/repo-detection-async.test.ts deleted file mode 100644 index bd86f02fa8f..00000000000 --- a/src/main/git/repositories/discovery/repo-detection-async.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { mkdirSync, mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import * as gitExecFileModule from '../../command-runner/git-exec-file' -import { runProcess } from '@orca/process-host' -import { getGitRepoRootAsync, isGitRepoAsync } from './repo-detection' - -let fixture: string -async function git(cwd: string, args: string[]): Promise { - const result = await runProcess({ program: 'git', args, cwd, timeoutMs: 15_000 }) - if (result.code !== 0) { - throw new Error(result.stderr) - } -} - -beforeEach(() => { - fixture = mkdtempSync(join(tmpdir(), 'orca-repo-async-')) -}) -afterEach(() => { - vi.restoreAllMocks() - rmSync(fixture, { recursive: true, force: true }) -}) - -describe('asynchronous repository detection with real Git', () => { - it('preserves genuine metadata fallback when asynchronous Git cannot answer', async () => { - const repo = join(fixture, 'fallback repo') - const nested = join(repo, 'packages') - mkdirSync(nested, { recursive: true }) - await git(repo, ['init', '--quiet']) - vi.spyOn(gitExecFileModule, 'gitExecFileAsync').mockRejectedValue(new Error('Git unavailable')) - expect(await isGitRepoAsync(nested)).toBe(true) - expect(await getGitRepoRootAsync(nested)).toBe(repo.replaceAll('\\', '/')) - expect(await isGitRepoAsync(join(repo, '.git'))).toBe(false) - }) -}) diff --git a/src/main/git/source-control/diffs/status-diff.test.ts b/src/main/git/source-control/diffs/status-diff.test.ts deleted file mode 100644 index 6ff2d0d7c95..00000000000 --- a/src/main/git/source-control/diffs/status-diff.test.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type * as GitExecFileModule from '../../command-runner/git-exec-file' -import type * as GitStreamStdoutModule from '../../command-runner/git-stream-stdout' -import type * as GitProcessEnvModule from '../../command-runner/git-environment/git-process-env' -import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as BoundedFileReader from '../../../../shared/file-content/node-bounded-file-reader' -import path from 'node:path' - -import { - createBoundedFileReaderModuleMock, - createFsPromisesModuleMock, - createGitExecFileModuleMock, - createGitStreamStdoutModuleMock, - createGitProcessEnvModuleMock -} from './status-test-harness' - -const { - gitExecFileAsyncMock, - gitExecFileAsyncBufferMock, - gitStreamOptionsMock, - lstatMock, - realpathMock, - readFileMock, - statMock, - rmMock, - existsSyncMock -} = vi.hoisted(() => ({ - gitExecFileAsyncMock: vi.fn(), - gitExecFileAsyncBufferMock: vi.fn(), - gitStreamOptionsMock: vi.fn(), - lstatMock: vi.fn(), - realpathMock: vi.fn(), - readFileMock: vi.fn(), - statMock: vi.fn(), - rmMock: vi.fn(), - existsSyncMock: vi.fn() -})) - -vi.mock('../../command-runner/git-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - ...createGitExecFileModuleMock({ gitExecFileAsyncMock, gitExecFileAsyncBufferMock }) -})) - -vi.mock('../../command-runner/git-stream-stdout', async (importOriginal) => ({ - ...(await importOriginal()), - ...createGitStreamStdoutModuleMock({ gitExecFileAsyncMock, gitStreamOptionsMock }) -})) - -vi.mock('../../command-runner/git-environment/git-process-env', async (importOriginal) => ({ - ...(await importOriginal()), - ...createGitProcessEnvModuleMock() -})) - -vi.mock('fs/promises', () => - createFsPromisesModuleMock({ lstatMock, realpathMock, readFileMock, statMock, rmMock }) -) - -vi.mock('fs', () => ({ - existsSync: existsSyncMock -})) - -vi.mock('../../../../shared/file-content/node-bounded-file-reader', async (importOriginal) => - createBoundedFileReaderModuleMock(await importOriginal(), { - readFileMock, - statMock - }) -) -import { getDiff } from './file-diff' -describe('getDiff', () => { - beforeEach(() => { - gitExecFileAsyncMock.mockReset() - gitExecFileAsyncBufferMock.mockReset() - lstatMock.mockReset() - readFileMock.mockReset() - statMock.mockReset() - existsSyncMock.mockReset() - statMock.mockResolvedValue({ - isFile: () => true, - size: 12 - }) - }) - - it('does not treat an unreadable working-tree image as a deletion', async () => { - const pngBuffer = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x00]) - const workingTreePath = path.join('/repo', 'assets/unreadable.png') - gitExecFileAsyncBufferMock.mockResolvedValueOnce({ stdout: pngBuffer }) - statMock.mockImplementation(async () => ({ isFile: () => true, size: 5 })) - readFileMock.mockImplementation(async (target: string) => { - if (target === workingTreePath) { - throw new Error('EIO') - } - return Buffer.from('') - }) - - const result = await getDiff('/repo', 'assets/unreadable.png', false) - - expect(result.kind).toBe('binary') - if (result.kind !== 'binary') { - throw new Error('expected binary diff result') - } - expect(result.modifiedDeleted).toBeUndefined() - }) -}) diff --git a/src/main/git/source-control/status/porcelain-v1-records.test.ts b/src/main/git/source-control/status/porcelain-v1-records.test.ts deleted file mode 100644 index f0d1cf82468..00000000000 --- a/src/main/git/source-control/status/porcelain-v1-records.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { execFileSync } from 'node:child_process' -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it } from 'vitest' -import { parsePorcelainV1Records } from './porcelain-v1-records' - -const tempRoots: string[] = [] - -const git = (args: string[], cwd: string): string => - execFileSync('git', args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }) - -function createRepo(): string { - const repo = mkdtempSync(join(tmpdir(), 'orca-porcelain-v1-')) - tempRoots.push(repo) - git(['init', '-q', '-b', 'main'], repo) - git(['config', 'user.email', 'test@example.com'], repo) - git(['config', 'user.name', 'Test'], repo) - return repo -} - -afterEach(() => { - for (const root of tempRoots.splice(0)) { - rmSync(root, { recursive: true, force: true }) - } -}) - -describe('parsePorcelainV1Records', () => { - it('reports a rename alongside a later untracked entry', () => { - const repo = createRepo() - writeFileSync(join(repo, 'original.txt'), 'content\n') - git(['add', '-A'], repo) - git(['commit', '-qm', 'init'], repo) - git(['mv', 'original.txt', 'renamed.txt'], repo) - mkdirSync(join(repo, 'node_modules')) - writeFileSync(join(repo, 'node_modules', 'pkg.js'), 'x') - - const records = parsePorcelainV1Records(git(['status', '--porcelain', '-z'], repo)) - - expect(records).toEqual([ - { xy: 'R ', path: 'renamed.txt' }, - { xy: '??', path: 'node_modules/' } - ]) - }) -}) diff --git a/src/main/git/source-control/status/status-branch-line-total-exec-contract.test.ts b/src/main/git/source-control/status/status-branch-line-total-exec-contract.test.ts deleted file mode 100644 index 4811d84928f..00000000000 --- a/src/main/git/source-control/status/status-branch-line-total-exec-contract.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { execFileSync } from 'node:child_process' -import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import * as path from 'node:path' -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { invalidateGitBranchLineTotalInFlight } from '../../../../shared/git/status/git-branch-line-total' - -import { clearEffectiveUpstreamStatusCacheForTests } from '../upstream/effective-upstream-status-cache' -import { clearSubmodulePathsCacheForTests } from '../submodules/submodule-paths' -import { getStatus } from './status-read' -import { invalidateGitReadCaches } from '../git-read-cache-invalidation' - -const tempRoots: string[] = [] - -function git(repo: string, args: string[]): string { - return execFileSync('git', args, { - cwd: repo, - encoding: 'utf8', - stdio: ['ignore', 'pipe', 'pipe'] - }).trim() -} - -async function createFixtureRepo(): Promise<{ repo: string; mergeBase: string }> { - const root = await mkdtemp(path.join(tmpdir(), 'orca-branch-line-total-exec-')) - tempRoots.push(root) - const repo = path.join(root, 'repo') - execFileSync('git', ['init', '-q', repo]) - git(repo, ['config', 'user.email', 'test@example.com']) - git(repo, ['config', 'user.name', 'Test User']) - git(repo, ['config', 'commit.gpgSign', 'false']) - await write(repo, 'f.txt', 'a\nb\n') - git(repo, ['add', '-A']) - git(repo, ['commit', '-q', '-m', 'base']) - await write(repo, 'f.txt', 'a\nb\nc\n') - return { repo, mergeBase: git(repo, ['rev-parse', 'HEAD']) } -} - -async function write(repo: string, relativePath: string, contents: string): Promise { - const target = path.join(repo, relativePath) - await mkdir(path.dirname(target), { recursive: true }) - await writeFile(target, contents) -} - -function resetGitReadCaches(): void { - clearEffectiveUpstreamStatusCacheForTests() - clearSubmodulePathsCacheForTests() - invalidateGitReadCaches() - invalidateGitBranchLineTotalInFlight() -} - -beforeEach(() => { - resetGitReadCaches() -}) - -afterEach(async () => { - resetGitReadCaches() - await Promise.all(tempRoots.splice(0).map((root) => rm(root, { recursive: true, force: true }))) -}) - -describe('branch line total completeness', () => { - it('omits the total when the status listing hit its limit', async () => { - const { repo, mergeBase } = await createFixtureRepo() - await write(repo, 'u1.txt', 'a\n') - await write(repo, 'u2.txt', 'b\n') - await write(repo, 'u3.txt', 'c\n') - - const result = await getStatus(repo, { branchLineTotalMergeBase: mergeBase, limit: 1 }) - - expect(result.didHitLimit).toBe(true) - expect(result.branchLineTotal).toBeUndefined() - expect(result.branchLineTotalUnavailable).toBeUndefined() - }) -}) diff --git a/src/main/git/source-control/status/status-line-stats-host-paths.test.ts b/src/main/git/source-control/status/status-line-stats-host-paths.test.ts deleted file mode 100644 index e9be6d37fdd..00000000000 --- a/src/main/git/source-control/status/status-line-stats-host-paths.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -// Untracked line counts use Node I/O, so WSL guest paths need Win32 spelling while host paths stay literal. -import * as path from 'node:path' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as FsPromises from 'node:fs/promises' -import type * as BoundedFileReader from '../../../../shared/file-content/node-bounded-file-reader' -import type { GitStatusEntry } from '../../../../shared/git/status/git-status-types' - -const { lstatPaths, untrackedFiles } = vi.hoisted(() => ({ - lstatPaths: [] as string[], - untrackedFiles: new Map() -})) - -vi.mock('node:fs/promises', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - lstat: async (target: string) => { - lstatPaths.push(target) - const contents = untrackedFiles.get(target) - if (contents === undefined) { - throw Object.assign(new Error(`ENOENT: ${target}`), { code: 'ENOENT' }) - } - return { - size: Buffer.byteLength(contents), - // Distinct per read so the stat-keyed untracked cache never serves another case's entry. - mtimeMs: lstatPaths.length, - ctimeMs: lstatPaths.length, - isSymbolicLink: () => false, - isFile: () => true - } - } - } -}) - -vi.mock('../../../../shared/file-content/node-bounded-file-reader', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - readNodeFileWithinLimit: async (target: string) => { - const contents = untrackedFiles.get(target) - if (contents === undefined) { - throw Object.assign(new Error(`ENOENT: ${target}`), { code: 'ENOENT' }) - } - return { buffer: Buffer.from(contents) } - } - } -}) - -import { attachLineStats } from './status-line-stats' - -const GUEST_WORKTREE = '/home/me/repo' -const UNC_WORKTREE = String.raw`\\wsl.localhost\Ubuntu\home\me\repo` - -function untrackedEntry(entryPath: string): GitStatusEntry { - return { path: entryPath, area: 'untracked', status: 'added' } -} - -describe('untracked line stats on a WSL worktree read by a Windows host', () => { - beforeEach(() => { - lstatPaths.length = 0 - untrackedFiles.clear() - vi.spyOn(process, 'platform', 'get').mockReturnValue('win32') - }) - - afterEach(() => { - vi.restoreAllMocks() - }) - - it('re-spells the guest form only, leaving every host-openable spelling byte-identical', async () => { - const cases: { worktree: string; expected: string }[] = [ - { worktree: GUEST_WORKTREE, expected: UNC_WORKTREE }, - { worktree: UNC_WORKTREE, expected: UNC_WORKTREE }, - { - worktree: '//wsl.localhost/Ubuntu/home/me/repo', - expected: '//wsl.localhost/Ubuntu/home/me/repo' - }, - { worktree: '/home/me/my repo ', expected: '/home/me/my repo ' } - ] - - for (const { worktree, expected } of cases) { - lstatPaths.length = 0 - untrackedFiles.clear() - const target = path.join(expected, 'fresh.txt') - untrackedFiles.set(target, 'one\ntwo\n') - const entries = [untrackedEntry('fresh.txt')] - - await attachLineStats(worktree, entries, { wslDistro: 'Ubuntu' }) - - expect(entries[0].added, worktree).toBe(2) - } - }) -}) diff --git a/src/main/git/source-control/upstream/upstream-deferred-fork-remote-real.test.ts b/src/main/git/source-control/upstream/upstream-deferred-fork-remote-real.test.ts deleted file mode 100644 index 09ccaeb33e7..00000000000 --- a/src/main/git/source-control/upstream/upstream-deferred-fork-remote-real.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { execFileSync } from 'node:child_process' -import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it } from 'vitest' -import type { GitPushTarget } from '../../../../shared/worktree/types' -import { getUpstreamStatus } from './upstream' - -// Real Git verifies missing-ref exit/stderr handling before a fork remote is materialized. -describe('getUpstreamStatus with a deferred (not-yet-materialized) fork remote', () => { - const tempPaths: string[] = [] - - afterEach(() => { - for (const path of tempPaths.splice(0)) { - rmSync(path, { recursive: true, force: true }) - } - }) - - it('reports the graceful "publish" state instead of 0 ahead/0 behind', async () => { - const repoPath = mkdtempSync(join(tmpdir(), 'orca-deferred-fork-remote-')) - tempPaths.push(repoPath) - const git = (...args: string[]): string => - execFileSync('git', args, { cwd: repoPath, encoding: 'utf8' }) - - git('init', '--quiet') - git('config', 'user.name', 'Orca Test') - git('config', 'user.email', 'orca@example.test') - git('config', 'commit.gpgSign', 'false') - git('config', 'core.hooksPath', '.git/no-hooks') - writeFileSync(join(repoPath, 'fixture.txt'), 'base\n') - git('add', 'fixture.txt') - git('commit', '-m', 'base') - git('branch', '-M', 'contributor/fix') - - // Persist a push target without adding its deferred remote. - const pushTarget: GitPushTarget = { - remoteName: 'pr-contributor-orca', - branchName: 'contributor/fix', - remoteUrl: 'git@github.com:contributor/orca.git' - } - - const status = await getUpstreamStatus(repoPath, pushTarget) - - expect(status).toEqual({ - hasUpstream: false, - upstreamName: 'pr-contributor-orca/contributor/fix', - ahead: 0, - behind: 0, - hasConfiguredPushTarget: true - }) - }) -}) diff --git a/src/main/github/client/create/create-github-pull-request.test.ts b/src/main/github/client/create/create-github-pull-request.test.ts deleted file mode 100644 index fb232381e88..00000000000 --- a/src/main/github/client/create/create-github-pull-request.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../../repositories/github-repository-identity' -import type * as GitExecFileModule from '../../../git/command-runner/git-exec-file' -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const { - ghExecFileAsyncMock, - getOwnerRepoMock, - getOwnerRepoForRemoteMock, - getEnterpriseGitHubRepoSlugMock, - extractExecErrorMock, - acquireMock, - releaseMock -} = vi.hoisted(() => ({ - ghExecFileAsyncMock: vi.fn(), - getOwnerRepoMock: vi.fn(), - getOwnerRepoForRemoteMock: vi.fn(), - getEnterpriseGitHubRepoSlugMock: vi.fn(), - extractExecErrorMock: vi.fn((error: unknown) => { - const value = error as { stderr?: string; stdout?: string; message?: string } - return { - stderr: value?.stderr ?? value?.message ?? '', - stdout: value?.stdout ?? '' - } - }), - acquireMock: vi.fn(), - releaseMock: vi.fn() -})) - -vi.mock('../../execution/github-legacy-command', () => ({ - execFileAsync: vi.fn() -})) - -vi.mock('../../../git/command-runner/hosted-cli/gh-exec-file', () => ({ - ghExecFileAsync: ghExecFileAsyncMock -})) - -vi.mock('../../repositories/github-owner-repo-selection', () => ({ - getOwnerRepo: getOwnerRepoMock -})) - -vi.mock('../../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - getOwnerRepoForRemote: getOwnerRepoForRemoteMock, - githubRepoContext: vi.fn((repoPath: string, connectionId?: string | null, options = {}) => ({ - ...options, - repoPath, - connectionId: connectionId ?? null - })), - ghRepoExecOptions: vi.fn( - (context: { repoPath: string; connectionId?: string | null; wslDistro?: string }) => - context.connectionId - ? {} - : { cwd: context.repoPath, ...(context.wslDistro ? { wslDistro: context.wslDistro } : {}) } - ), - _resetOwnerRepoCache: vi.fn() -})) - -vi.mock('../../../git/command-runner/git-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - gitExecFileAsync: vi.fn() -})) - -vi.mock('../../execution/github-operation-slots', () => ({ - acquire: acquireMock, - release: releaseMock -})) - -vi.mock('../../repositories/github-enterprise-repository', () => ({ - getEnterpriseGitHubRepoSlug: getEnterpriseGitHubRepoSlugMock, - isGitHubHostAuthenticated: vi.fn().mockResolvedValue(true) -})) - -import { createGitHubPullRequest } from './create-github-pull-request' - -import { _resetOriginGitHubApiRepositoryCache } from '../../repositories/github-api-repository-remote-probe' - -beforeEach(() => { - _resetOriginGitHubApiRepositoryCache() -}) - -describe('createGitHubPullRequest', () => { - beforeEach(() => { - ghExecFileAsyncMock.mockReset() - getOwnerRepoMock.mockReset() - getOwnerRepoForRemoteMock.mockReset() - // Bridge explicit-origin creation to the fixtures that define getOwnerRepoMock. - getOwnerRepoForRemoteMock.mockImplementation( - async (repoPath: string, remoteName: string, connectionId?: string | null, opts = {}) => - remoteName === 'origin' ? getOwnerRepoMock(repoPath, connectionId, opts) : null - ) - getEnterpriseGitHubRepoSlugMock.mockReset() - getEnterpriseGitHubRepoSlugMock.mockResolvedValue(null) - extractExecErrorMock.mockClear() - acquireMock.mockReset() - releaseMock.mockReset() - acquireMock.mockResolvedValue(undefined) - }) - - it('returns the existing PR when gh reports an already-open pull request', async () => { - getOwnerRepoMock.mockResolvedValueOnce({ owner: 'acme', repo: 'widgets' }) - ghExecFileAsyncMock - .mockRejectedValueOnce({ stderr: 'a pull request already exists for feature/existing' }) - .mockResolvedValueOnce({ - stdout: JSON.stringify([ - { - number: 44, - url: 'https://github.com/acme/widgets/pull/44' - } - ]) - }) - - await expect( - createGitHubPullRequest( - '/repo-root', - { - provider: 'github', - base: 'main', - head: 'refs/remotes/origin/feature/existing', - title: 'Existing' - }, - 'local' - ) - ).resolves.toEqual({ - ok: false, - code: 'already_exists', - error: 'A pull request already exists for this branch.', - reason: 'existing_review', - existingReview: { - number: 44, - url: 'https://github.com/acme/widgets/pull/44' - } - }) - - expect(ghExecFileAsyncMock.mock.calls[1]).toEqual([ - [ - 'pr', - 'list', - '--repo', - 'acme/widgets', - '--head', - 'feature/existing', - '--base', - 'main', - '--state', - 'open', - '--limit', - '2', - '--json', - 'number,url' - ], - // Pin dotcom against process-level GH_HOST. - { cwd: '/repo-root', host: 'github.com' } - ]) - }) -}) diff --git a/src/main/github/client/detect/repository-merge-metadata-reuse.test.ts b/src/main/github/client/detect/repository-merge-metadata-reuse.test.ts deleted file mode 100644 index a7b8e56d7a8..00000000000 --- a/src/main/github/client/detect/repository-merge-metadata-reuse.test.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' - -const { exec, guard, spend } = vi.hoisted(() => ({ exec: vi.fn(), guard: vi.fn(), spend: vi.fn() })) -vi.mock('../../../git/command-runner/hosted-cli/gh-exec-file', () => ({ - ghExecFileAsync: exec -})) -vi.mock('../../api/rate-limit', () => ({ - repositoryRateLimitGuard: guard, - noteRepositoryRateLimitSpend: spend -})) - -import { detectRepositoryMergeMetadata } from './repository-merge-metadata' -import { _resetMergeQueueCacheForTests } from './repository-merge-metadata-cache' - -const repository = { owner: 'acme', repo: 'widgets', host: 'github.com' } -const options = { cwd: '/repo' } - -function response(autoMergeAllowed: boolean): { stdout: string } { - return { - stdout: JSON.stringify({ - data: { repository: { autoMergeAllowed, mergeQueue: null, ref: { rules: { nodes: [] } } } } - }) - } -} - -beforeEach(() => { - vi.resetAllMocks() - vi.stubEnv('GH_CONFIG_DIR', undefined) - vi.stubEnv('XDG_CONFIG_HOME', undefined) - _resetMergeQueueCacheForTests() - guard.mockReturnValue({ blocked: false }) -}) -afterEach(() => { - vi.useRealTimers() - vi.unstubAllEnvs() -}) - -describe('repository merge metadata reuse', () => { - it.each([true, false])( - 'retains a successful concurrent read when a newer read fails (failure first: %s)', - async (failureFirst) => { - const older = Promise.withResolvers<{ stdout: string }>() - const newer = Promise.withResolvers<{ stdout: string }>() - exec.mockReturnValueOnce(older.promise).mockReturnValueOnce(newer.promise) - const first = detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - const second = detectRepositoryMergeMetadata( - repository, - 'main', - { cwd: '/another-worktree' }, - 'local:host' - ) - if (failureFirst) { - newer.reject(new Error('ECONNRESET')) - await second - older.resolve(response(true)) - await first - } else { - older.resolve(response(true)) - await first - newer.reject(new Error('ECONNRESET')) - await second - } - await expect( - detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - ).resolves.toMatchObject({ autoMergeAllowed: true }) - expect(exec).toHaveBeenCalledTimes(2) - } - ) - - it('does not couple independent abort signals or cache an aborted result', async () => { - const canceled = Promise.withResolvers<{ stdout: string }>() - const surviving = Promise.withResolvers<{ stdout: string }>() - const firstController = new AbortController() - const secondController = new AbortController() - exec.mockReturnValueOnce(canceled.promise).mockReturnValueOnce(surviving.promise) - const first = detectRepositoryMergeMetadata( - repository, - 'main', - { ...options, signal: firstController.signal }, - 'local:host' - ) - const second = detectRepositoryMergeMetadata( - repository, - 'main', - { ...options, signal: secondController.signal }, - 'local:host' - ) - expect(exec).toHaveBeenCalledTimes(2) - firstController.abort() - canceled.reject(firstController.signal.reason) - await expect(first).resolves.toMatchObject({ autoMergeAllowed: null }) - surviving.resolve(response(false)) - await expect(second).resolves.toMatchObject({ autoMergeAllowed: false }) - await expect( - detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - ).resolves.toMatchObject({ autoMergeAllowed: false }) - expect(exec).toHaveBeenCalledTimes(2) - }) - - it('retries immediately with a new signal after the only probe aborts', async () => { - const canceled = Promise.withResolvers<{ stdout: string }>() - const controller = new AbortController() - exec.mockReturnValueOnce(canceled.promise).mockResolvedValueOnce(response(true)) - const first = detectRepositoryMergeMetadata( - repository, - 'main', - { ...options, signal: controller.signal }, - 'local:host' - ) - controller.abort() - canceled.reject(controller.signal.reason) - await first - - await expect( - detectRepositoryMergeMetadata( - repository, - 'main', - { ...options, signal: new AbortController().signal }, - 'local:host' - ) - ).resolves.toMatchObject({ autoMergeAllowed: true }) - expect(exec).toHaveBeenCalledTimes(2) - }) - - it('retains a surviving cache writer when a newer independent probe aborts', async () => { - const older = Promise.withResolvers<{ stdout: string }>() - const canceled = Promise.withResolvers<{ stdout: string }>() - const controller = new AbortController() - exec.mockReturnValueOnce(older.promise).mockReturnValueOnce(canceled.promise) - const first = detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - const second = detectRepositoryMergeMetadata( - repository, - 'main', - { ...options, signal: controller.signal }, - 'local:host' - ) - controller.abort() - canceled.reject(controller.signal.reason) - await second - older.resolve(response(false)) - await first - - await expect( - detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - ).resolves.toMatchObject({ autoMergeAllowed: false }) - expect(exec).toHaveBeenCalledTimes(2) - }) - - it('does not spend quota for an already aborted probe', async () => { - const controller = new AbortController() - controller.abort() - exec.mockResolvedValue(response(true)) - - await expect( - detectRepositoryMergeMetadata( - repository, - 'main', - { ...options, signal: controller.signal }, - 'local:host' - ) - ).resolves.toMatchObject({ autoMergeAllowed: null }) - expect(exec).not.toHaveBeenCalled() - expect(spend).not.toHaveBeenCalled() - }) - - it('keeps newer worktree settings when an older directory probe completes later', async () => { - const older = Promise.withResolvers<{ stdout: string }>() - const newer = Promise.withResolvers<{ stdout: string }>() - exec.mockReturnValueOnce(older.promise).mockReturnValueOnce(newer.promise) - const first = detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - const second = detectRepositoryMergeMetadata( - repository, - 'main', - { cwd: '/another-worktree' }, - 'local:host' - ) - - newer.resolve(response(false)) - await expect(second).resolves.toMatchObject({ autoMergeAllowed: false }) - older.resolve(response(true)) - await expect(first).resolves.toMatchObject({ autoMergeAllowed: true }) - await expect( - detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - ).resolves.toMatchObject({ autoMergeAllowed: false }) - expect(exec).toHaveBeenCalledTimes(2) - }) - - it('allows a stale successor without letting the older completion replace its cache', async () => { - vi.useFakeTimers() - const older = Promise.withResolvers<{ stdout: string }>() - const newer = Promise.withResolvers<{ stdout: string }>() - exec.mockReturnValueOnce(older.promise).mockReturnValueOnce(newer.promise) - const first = detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - vi.advanceTimersByTime(60_000) - const second = detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - - newer.resolve(response(false)) - await expect(second).resolves.toMatchObject({ autoMergeAllowed: false }) - older.resolve(response(true)) - await expect(first).resolves.toMatchObject({ autoMergeAllowed: true }) - await expect( - detectRepositoryMergeMetadata(repository, 'main', options, 'local:host') - ).resolves.toMatchObject({ autoMergeAllowed: false }) - expect(exec).toHaveBeenCalledTimes(2) - }) -}) diff --git a/src/main/github/client/fetch/get-work-item-check-summary.test.ts b/src/main/github/client/fetch/get-work-item-check-summary.test.ts deleted file mode 100644 index c130d488fe1..00000000000 --- a/src/main/github/client/fetch/get-work-item-check-summary.test.ts +++ /dev/null @@ -1,167 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../../repositories/github-repository-identity' -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const { ghExecFileAsyncMock, getOwnerRepoMock, rateLimitGuardMock } = vi.hoisted(() => ({ - ghExecFileAsyncMock: vi.fn(), - getOwnerRepoMock: vi.fn(), - rateLimitGuardMock: vi.fn(() => ({ blocked: false })) -})) - -vi.mock('../../execution/github-legacy-command', () => ({ - execFileAsync: vi.fn() -})) - -vi.mock('../../../git/command-runner/hosted-cli/gh-exec-file', () => ({ - ghExecFileAsync: ghExecFileAsyncMock -})) - -vi.mock('../../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - githubRepoContext: (repoPath: string, connectionId?: string | null) => ({ - repoPath, - connectionId: connectionId ?? null - }), - ghRepoExecOptions: (context: { repoPath: string }) => ({ cwd: context.repoPath }), - getOwnerRepoForRemote: ( - repoPath: string, - remoteName: string, - connectionId?: string | null, - localGitOptions?: unknown - ) => - remoteName === 'origin' - ? getOwnerRepoMock(repoPath, connectionId, localGitOptions) - : Promise.resolve(null), - _resetOwnerRepoCache: vi.fn() -})) - -vi.mock('../../repositories/github-owner-repo-selection', () => ({ - getOwnerRepo: getOwnerRepoMock, - resolveIssueSource: vi.fn() -})) - -vi.mock('../../../git/command-runner/process-capture/exec-error', async (importOriginal) => ({ - ...(await importOriginal>()), - extractExecError: vi.fn((err: unknown) => ({ stderr: String(err), stdout: '' })) -})) - -vi.mock('../../execution/github-operation-slots', () => ({ - acquire: vi.fn(), - release: vi.fn() -})) - -vi.mock('../../api/gh-error-classification', () => ({ - classifyGhError: (stderr: string) => ({ type: 'unknown', message: stderr }), - classifyListIssuesError: (stderr: string) => ({ type: 'unknown', message: stderr }) -})) - -vi.mock('../../../git/command-runner/git-exec-file', async (importOriginal) => ({ - ...(await importOriginal>()), - gitExecFileAsync: vi.fn() -})) - -vi.mock('../../api/rate-limit', () => ({ - rateLimitGuard: rateLimitGuardMock, - noteRateLimitSpend: vi.fn(), - getRateLimit: vi.fn(async () => ({ ok: false, error: 'not probed in tests' })), - repositoryRateLimitGuard: vi.fn(() => ({ blocked: false })), - noteRepositoryRateLimitSpend: vi.fn(), - spendsSharedGitHubComQuota: vi.fn(() => true) -})) - -import { getWorkItem } from './get-work-item' -import { _resetMergeQueueCacheForTests } from '../detect/repository-merge-metadata-cache' -import { _resetOwnerRepoCache } from '../../repositories/github-repository-identity' -import { _resetOriginGitHubApiRepositoryCache } from '../../repositories/github-api-repository-remote-probe' - -// Metadata and complete checks are independent provider responses. -function mockPullRequestDetail(payload: Record): void { - const head = 'a'.repeat(40) - ghExecFileAsyncMock.mockImplementation(async (args: string[]) => { - if (args[0] === 'pr' && args[1] === 'view') { - return { stdout: JSON.stringify({ ...payload, headRefOid: head }) } - } - if (args.includes('graphql') && args.some((arg) => arg.includes('statusCheckRollup'))) { - return { - stdout: JSON.stringify({ - data: { - repository: { - pullRequest: { - number: payload.number, - headRefOid: head, - commits: { - nodes: [ - { - commit: { - oid: head, - statusCheckRollup: { - contexts: { - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: these test payloads contain object rollup rows only. - nodes: (payload.statusCheckRollup as Record[]).map( - (raw) => ({ - ...raw, - __typename: - raw.__typename ?? (raw.state ? 'StatusContext' : 'CheckRun'), - ...(!raw.state ? { checkSuite: { databaseId: 7 } } : {}) - }) - ), - pageInfo: { hasNextPage: false, endCursor: null } - } - }, - checkSuites: { - nodes: [], - pageInfo: { hasNextPage: false, endCursor: null } - } - } - } - ] - } - } - } - } - }) - } - } - throw new Error('unexpected gh call') - }) -} - -describe('work item checksSummary', () => { - beforeEach(() => { - ghExecFileAsyncMock.mockReset() - getOwnerRepoMock.mockReset() - rateLimitGuardMock.mockReset() - rateLimitGuardMock.mockReturnValue({ blocked: false }) - _resetOwnerRepoCache() - _resetOriginGitHubApiRepositoryCache() - _resetMergeQueueCacheForTests() - getOwnerRepoMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' }) - }) - - it('counts a skipped run as passing and reads a StatusContext state as its conclusion', async () => { - mockPullRequestDetail({ - number: 42, - title: 'Add feature', - state: 'OPEN', - url: 'https://github.com/acme/widgets/pull/42', - updatedAt: '2026-04-01T00:00:00Z', - statusCheckRollup: [ - { __typename: 'CheckRun', status: 'COMPLETED', conclusion: 'SKIPPED' }, - // StatusContext supplies state instead of CheckRun's status/conclusion. - { __typename: 'StatusContext', state: 'SUCCESS' }, - { __typename: 'CheckRun', status: 'COMPLETED', conclusion: 'NEUTRAL' } - ] - }) - - const item = await getWorkItem('/repo-root', 42, 'pr', null, {}, 'origin') - - expect(item?.checksSummary).toEqual({ - state: 'success', - total: 3, - passed: 2, - failed: 0, - cancelled: 0, - pending: 0, - neutral: 1 - }) - }) -}) diff --git a/src/main/github/client/fetch/get-work-item-origin-preference.test.ts b/src/main/github/client/fetch/get-work-item-origin-preference.test.ts deleted file mode 100644 index 3112a829da6..00000000000 --- a/src/main/github/client/fetch/get-work-item-origin-preference.test.ts +++ /dev/null @@ -1,203 +0,0 @@ -import type * as GithubLegacyCommandModule from '../../execution/github-legacy-command' -import type * as GhExecFileModule from '../../../git/command-runner/hosted-cli/gh-exec-file' -import type * as GithubOwnerRepoSelectionModule from '../../repositories/github-owner-repo-selection' -import type * as GithubRepositoryIdentityModule from '../../repositories/github-repository-identity' -import type * as GithubOperationSlotsModule from '../../execution/github-operation-slots' -import type * as GithubApiRepositoryModule from '../../repositories/github-api-repository' -import type * as GithubApiRepositoryRemoteProbeModule from '../../repositories/github-api-repository-remote-probe' -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const { - ghExecFileAsyncMock, - getOwnerRepoMock, - getIssueOwnerRepoMock, - getOwnerRepoForRemoteMock, - resolvePRRepositoryCandidatesMock, - resolveIssueSourceMock, - rateLimitGuardMock, - noteRateLimitSpendMock, - acquireMock, - releaseMock -} = vi.hoisted(() => ({ - ghExecFileAsyncMock: vi.fn(), - getOwnerRepoMock: vi.fn(), - getIssueOwnerRepoMock: vi.fn(), - getOwnerRepoForRemoteMock: vi.fn(), - resolvePRRepositoryCandidatesMock: vi.fn(), - resolveIssueSourceMock: vi.fn(), - rateLimitGuardMock: vi.fn(() => ({ blocked: false })), - noteRateLimitSpendMock: vi.fn(), - acquireMock: vi.fn(), - releaseMock: vi.fn() -})) - -vi.mock('../../execution/github-legacy-command', async () => { - const actual = await vi.importActual( - '../../execution/github-legacy-command' - ) - return { - ...actual, - execFileAsync: vi.fn() - } -}) - -vi.mock('../../../git/command-runner/hosted-cli/gh-exec-file', async () => { - const actual = await vi.importActual( - '../../../git/command-runner/hosted-cli/gh-exec-file' - ) - return { - ...actual, - ghExecFileAsync: ghExecFileAsyncMock - } -}) - -vi.mock('../../repositories/github-owner-repo-selection', async () => { - const actual = await vi.importActual( - '../../repositories/github-owner-repo-selection' - ) - return { - ...actual, - getOwnerRepo: getOwnerRepoMock, - resolveIssueSource: resolveIssueSourceMock - } -}) - -vi.mock('../../repositories/github-repository-identity', async () => { - const actual = await vi.importActual( - '../../repositories/github-repository-identity' - ) - return { - ...actual, - getOwnerRepoForRemote: getOwnerRepoForRemoteMock, - _resetOwnerRepoCache: vi.fn() - } -}) - -vi.mock('../../execution/github-operation-slots', async () => { - const actual = await vi.importActual( - '../../execution/github-operation-slots' - ) - return { - ...actual, - acquire: acquireMock, - release: releaseMock - } -}) - -vi.mock('../../api/rate-limit', () => ({ - rateLimitGuard: rateLimitGuardMock, - noteRateLimitSpend: noteRateLimitSpendMock, - getRateLimit: vi.fn(async () => ({ ok: false, error: 'not probed in tests' })), - repositoryRateLimitGuard: vi.fn(() => ({ blocked: false })), - noteRepositoryRateLimitSpend: vi.fn(), - spendsSharedGitHubComQuota: () => true -})) - -vi.mock('../../repositories/github-api-repository', async (importOriginal) => { - return { - ...(await importOriginal()), - resolveIssueGitHubApiRepositorySource: ( - repoPath: string, - preference: unknown, - connectionId?: string | null, - localGitOptions?: unknown - ) => resolveIssueSourceMock(repoPath, preference, connectionId, localGitOptions), - getIssueGitHubApiRepository: (repoPath: string, connectionId?: string | null) => - getIssueOwnerRepoMock(repoPath, connectionId), - resolveGitHubApiRepositoryCandidates: ( - repoPath: string, - connectionId?: string | null, - localGitOptions?: unknown - ) => resolvePRRepositoryCandidatesMock(repoPath, connectionId, localGitOptions) - } -}) - -vi.mock('../../repositories/github-api-repository-remote-probe', async (importOriginal) => { - return { - ...(await importOriginal()), - getOriginGitHubApiRepository: ( - repoPath: string, - connectionId?: string | null, - localGitOptions?: unknown - ) => getOwnerRepoMock(repoPath, connectionId, localGitOptions), - getGitHubApiRepositoryForRemote: ( - repoPath: string, - remoteName: string, - connectionId?: string | null, - localGitOptions?: unknown - ) => - remoteName === 'origin' - ? getOwnerRepoMock(repoPath, connectionId, localGitOptions) - : getOwnerRepoForRemoteMock(repoPath, remoteName, connectionId, localGitOptions) - } -}) - -import { getWorkItem } from './get-work-item' -import { _resetOwnerRepoCache } from '../../repositories/github-repository-identity' - -describe('GitHub issue open-by-number origin preference', () => { - beforeEach(() => { - ghExecFileAsyncMock.mockReset() - getOwnerRepoMock.mockReset() - getIssueOwnerRepoMock.mockReset() - getOwnerRepoForRemoteMock.mockReset() - resolvePRRepositoryCandidatesMock.mockReset() - resolveIssueSourceMock.mockReset() - rateLimitGuardMock.mockReset() - rateLimitGuardMock.mockReturnValue({ blocked: false }) - noteRateLimitSpendMock.mockReset() - acquireMock.mockReset() - releaseMock.mockReset() - acquireMock.mockResolvedValue(undefined) - getOwnerRepoForRemoteMock.mockImplementation( - async (repoPath: string, remoteName: string, connectionId?: string | null, opts = {}) => - remoteName === 'origin' ? getOwnerRepoMock(repoPath, connectionId, opts) : null - ) - resolvePRRepositoryCandidatesMock.mockImplementation(async (repoPath, connectionId) => { - const origin = await getOwnerRepoMock(repoPath, connectionId) - const repository = origin ? { host: 'github.com', ...origin } : null - return { candidates: repository ? [repository] : [], headRepo: repository } - }) - _resetOwnerRepoCache() - }) - - it('does not run a bare issue lookup when explicit origin identity is unresolved', async () => { - resolveIssueSourceMock.mockResolvedValueOnce({ source: null, fellBack: false }) - - await expect(getWorkItem('/repo-root', 7, 'issue', null, {}, 'origin')).resolves.toBeNull() - - expect(resolveIssueSourceMock).toHaveBeenCalledWith('/repo-root', 'origin', null, {}) - expect(getIssueOwnerRepoMock).not.toHaveBeenCalled() - expect(ghExecFileAsyncMock).not.toHaveBeenCalled() - }) - - it('skips the issue probe on untyped open when origin identity is unresolved', async () => { - const origin = { owner: 'fork', repo: 'orca', host: 'github.com' } - resolveIssueSourceMock.mockResolvedValueOnce({ source: null, fellBack: false }) - getOwnerRepoMock.mockResolvedValue(origin) - resolvePRRepositoryCandidatesMock.mockResolvedValue({ candidates: [origin], headRepo: origin }) - ghExecFileAsyncMock.mockResolvedValueOnce({ - stdout: JSON.stringify({ - number: 7, - title: 'Origin PR', - state: 'open', - labels: [], - isDraft: false, - url: 'https://github.com/fork/orca/pull/7', - baseRefName: 'main', - headRefName: 'origin/fix', - updatedAt: '2026-04-02T00:00:00Z', - author: { login: 'octocat' } - }) - }) - - const item = await getWorkItem('/repo-root', 7, undefined, null, {}, 'origin') - - expect(resolveIssueSourceMock).toHaveBeenCalledWith('/repo-root', 'origin', null, {}) - expect(getIssueOwnerRepoMock).not.toHaveBeenCalled() - expect(ghExecFileAsyncMock.mock.calls[0]?.[0]).toEqual( - expect.arrayContaining(['pr', 'view', '--repo', 'fork/orca']) - ) - expect(item).toMatchObject({ number: 7, type: 'pr' }) - }) -}) diff --git a/src/main/github/client/lookup/get-pr-for-branch-host-scope.test.ts b/src/main/github/client/lookup/get-pr-for-branch-host-scope.test.ts deleted file mode 100644 index b35dd255cf2..00000000000 --- a/src/main/github/client/lookup/get-pr-for-branch-host-scope.test.ts +++ /dev/null @@ -1,215 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../../repositories/github-repository-identity' -import type * as GhExecFileModule from '../../../git/command-runner/hosted-cli/gh-exec-file' -import type * as GithubApiRepositoryModule from '../../repositories/github-api-repository' -import type * as GithubApiRepositoryRemoteProbeModule from '../../repositories/github-api-repository-remote-probe' -import type * as GitExecFileModule from '../../../git/command-runner/git-exec-file' - -import { beforeEach, describe, expect, it, vi } from 'vitest' - -import type * as GitHubEnterpriseRepositoryModule from '../../repositories/github-enterprise-repository' - -const { clientMocks, moduleMocks } = await vi.hoisted(async () => { - const moduleMocks = await import('../client-test-mocks') - return { clientMocks: moduleMocks.createGitHubClientMocks(), moduleMocks } -}) - -vi.mock('../../execution/github-legacy-command', () => - moduleMocks.githubLegacyCommandModuleMock(clientMocks) -) - -vi.mock('../../repositories/github-owner-repo-selection', () => - moduleMocks.githubOwnerSelectionModuleMock(clientMocks) -) - -vi.mock('../../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - ...moduleMocks.githubRepositoryIdentityModuleMock(clientMocks) -})) - -vi.mock('../../api/gh-error-classification', () => - moduleMocks.githubErrorClassificationModuleMock() -) - -vi.mock('../../execution/github-operation-slots', () => - moduleMocks.githubOperationSlotsModuleMock(clientMocks) -) - -vi.mock('../../../git/command-runner/git-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - gitExecFileAsync: clientMocks.gitExecFileAsyncMock -})) - -vi.mock('../../../git/command-runner/hosted-cli/gh-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - ...moduleMocks.githubHostedCliModuleMock(clientMocks) -})) -vi.mock('../../repositories/local-git-config-signature', () => - moduleMocks.localGitConfigSignatureModuleMock(clientMocks) -) -vi.mock('../../repositories/github-enterprise-repository', async (importOriginal) => - moduleMocks.githubEnterpriseRepositoryModuleMock( - await importOriginal() - ) -) -vi.mock('../../api/rate-limit', () => moduleMocks.rateLimitModuleMock(clientMocks)) -vi.mock('../../repositories/github-api-repository', async (importOriginal) => - moduleMocks.githubApiRepositoryModuleMock( - clientMocks, - await importOriginal() - ) -) - -vi.mock('../../repositories/github-api-repository-remote-probe', async (importOriginal) => - moduleMocks.githubApiRepositoryRemoteProbeModuleMock( - clientMocks, - await importOriginal() - ) -) - -import { getPRForBranch } from './get-pr-for-branch' -import { resetPRForBranchMocks } from '../client-test-harness' -import type { RestPullRequest } from './pull-request-lookup-data' -import type { GitHubRepositoryIdentity as OwnerRepo } from '../../../../shared/github/repositories/repository-identity' - -const { - ghExecFileAsyncMock, - getOwnerRepoMock, - resolvePRRepositoryCandidatesMock, - gitExecFileAsyncMock -} = clientMocks - -const ACME = { owner: 'acme', repo: 'widgets' } - -function primeGit( - trackedUpstream: string, - remoteHeads: Record = { origin: 'develop' } -): void { - gitExecFileAsyncMock.mockImplementation(async (args: string[]) => { - if (args[0] === 'for-each-ref' && args.includes('--format=%(refname)%00%(upstream)')) { - return { stdout: `refs/heads/feature/my-change\0${trackedUpstream}\n`, stderr: '' } - } - if (args[0] === 'for-each-ref' && args.includes('--format=%(refname)%00%(symref)')) { - const stdout = Object.entries(remoteHeads) - .filter(([remote]) => args.includes(`refs/remotes/${remote}/HEA[D]`)) - .map( - ([remote, branch]) => `refs/remotes/${remote}/HEAD\0refs/remotes/${remote}/${branch}\n` - ) - .join('') - return { stdout, stderr: '' } - } - if (args[0] === 'rev-parse' && args[1] === 'HEAD') { - return { stdout: 'feature-head-oid\n', stderr: '' } - } - throw new Error(`unexpected git call: ${args.join(' ')}`) - }) -} - -function restPR( - headRefName = 'develop', - headRepo: OwnerRepo = ACME, - prRepo: OwnerRepo = ACME -): RestPullRequest { - return { - number: 7, - title: 'Release develop', - state: 'closed', - merged_at: null, - html_url: `https://${prRepo.host ?? 'github.com'}/${prRepo.owner}/${prRepo.repo}/pull/7`, - updated_at: '2025-01-01T00:00:00Z', - draft: false, - mergeable: null, - base: { ref: 'release', sha: 'release-oid' }, - head: { - ref: headRefName, - sha: 'old-develop-oid', - repo: { name: headRepo.repo, owner: { login: headRepo.owner } } - } - } -} - -function primeGh( - listsByHead: Record, - exactPR: RestPullRequest | RestPullRequest[] = Object.values(listsByHead).flat()[0] ?? restPR() -): void { - const repositorySlug = (pr: RestPullRequest): string => - new URL(pr.html_url ?? '').pathname.split('/').slice(1, 3).join('/') - const repositoryHost = (pr: RestPullRequest): string => new URL(pr.html_url ?? '').host - const exactPRs = Array.isArray(exactPR) ? exactPR : [exactPR] - const prsByRepositoryAndNumber = new Map( - [...Object.values(listsByHead).flat(), ...exactPRs].map((pr) => [ - `${repositoryHost(pr)}/${repositorySlug(pr)}#${pr.number}`, - pr - ]) - ) - ghExecFileAsyncMock.mockImplementation( - async (args: string[], options: { host?: string } = {}) => { - const host = options.host ?? 'github.com' - const match = args[1]?.match(/^repos\/([^/]+\/[^/]+)\/pulls\?head=([^&]+)/) - if (args[0] === 'api' && match) { - const list = (listsByHead[decodeURIComponent(match[2])] ?? []).filter( - (pr) => repositoryHost(pr) === host && repositorySlug(pr) === match[1] - ) - return { stdout: JSON.stringify(list) } - } - const exactRestMatch = args[1]?.match(/^repos\/([^/]+\/[^/]+)\/pulls\/(\d+)$/) - if (args[0] === 'api' && exactRestMatch) { - const pr = prsByRepositoryAndNumber.get(`${host}/${exactRestMatch[1]}#${exactRestMatch[2]}`) - if (pr) { - return { stdout: JSON.stringify(pr) } - } - throw new Error('HTTP 404 Not Found') - } - const repoIndex = args.indexOf('--repo') - const exact = prsByRepositoryAndNumber.get(`${host}/${args[repoIndex + 1]}#${args[2]}`) - if (args[0] === 'pr' && args[1] === 'view') { - if (!exact) { - throw new Error('HTTP 404 Not Found') - } - return { - stdout: JSON.stringify({ - number: exact.number, - title: exact.title, - state: exact.merged_at ? 'MERGED' : exact.state.toUpperCase(), - url: exact.html_url, - statusCheckRollup: [], - updatedAt: exact.updated_at, - isDraft: exact.draft, - mergeable: 'UNKNOWN', - baseRefName: exact.base?.ref, - headRefName: exact.head?.ref, - baseRefOid: exact.base?.sha, - headRefOid: exact.head?.sha, - headRepositoryOwner: exact.head?.repo?.owner, - headRepository: exact.head?.repo ? { name: exact.head.repo.name } : null - }) - } - } - throw new Error(`gh unavailable: ${args.join(' ')}`) - } - ) -} - -describe('issue #26948: a branch tracking the default branch', () => { - beforeEach(() => { - resetPRForBranchMocks(clientMocks) - getOwnerRepoMock.mockResolvedValue(ACME) - }) - - it('does not query another GitHub server for a known public GitHub head', async () => { - const enterprise = { ...ACME, host: 'ghe.example' } - resolvePRRepositoryCandidatesMock.mockResolvedValue({ - candidates: [enterprise, ACME], - headRepo: ACME - }) - primeGit('') - primeGh({ - 'acme:feature/my-change': [ - { ...restPR('feature/my-change', enterprise, enterprise), state: 'open' } - ] - }) - expect(await getPRForBranch('/repo-root', 'feature/my-change')).toBeNull() - expect( - ghExecFileAsyncMock.mock.calls.some(([, options]) => options?.host === 'ghe.example') - ).toBe(false) - }) -}) diff --git a/src/main/github/client/lookup/pr-branch-lookup-revalidation.test.ts b/src/main/github/client/lookup/pr-branch-lookup-revalidation.test.ts deleted file mode 100644 index 7e241c67528..00000000000 --- a/src/main/github/client/lookup/pr-branch-lookup-revalidation.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../../repositories/github-repository-identity' -import type * as GhExecFileModule from '../../../git/command-runner/hosted-cli/gh-exec-file' -import type * as GithubApiRepositoryModule from '../../repositories/github-api-repository' -import type * as GithubApiRepositoryRemoteProbeModule from '../../repositories/github-api-repository-remote-probe' -import type * as GitExecFileModule from '../../../git/command-runner/git-exec-file' - -import { beforeEach, describe, expect, it, vi } from 'vitest' - -import type * as GitHubEnterpriseRepositoryModule from '../../repositories/github-enterprise-repository' - -const { clientMocks, moduleMocks } = await vi.hoisted(async () => { - const moduleMocks = await import('../client-test-mocks') - return { clientMocks: moduleMocks.createGitHubClientMocks(), moduleMocks } -}) - -vi.mock('../../execution/github-legacy-command', () => - moduleMocks.githubLegacyCommandModuleMock(clientMocks) -) - -vi.mock('../../repositories/github-owner-repo-selection', () => - moduleMocks.githubOwnerSelectionModuleMock(clientMocks) -) - -vi.mock('../../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - ...moduleMocks.githubRepositoryIdentityModuleMock(clientMocks) -})) - -vi.mock('../../api/gh-error-classification', () => - moduleMocks.githubErrorClassificationModuleMock() -) - -vi.mock('../../execution/github-operation-slots', () => - moduleMocks.githubOperationSlotsModuleMock(clientMocks) -) - -vi.mock('../../../git/command-runner/git-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - gitExecFileAsync: clientMocks.gitExecFileAsyncMock -})) - -vi.mock('../../../git/command-runner/hosted-cli/gh-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - ...moduleMocks.githubHostedCliModuleMock(clientMocks) -})) -vi.mock('../../repositories/local-git-config-signature', () => - moduleMocks.localGitConfigSignatureModuleMock(clientMocks) -) -vi.mock('../../repositories/github-enterprise-repository', async (importOriginal) => - moduleMocks.githubEnterpriseRepositoryModuleMock( - await importOriginal() - ) -) -vi.mock('../../api/rate-limit', () => moduleMocks.rateLimitModuleMock(clientMocks)) -vi.mock('../../repositories/github-api-repository', async (importOriginal) => - moduleMocks.githubApiRepositoryModuleMock( - clientMocks, - await importOriginal() - ) -) - -vi.mock('../../repositories/github-api-repository-remote-probe', async (importOriginal) => - moduleMocks.githubApiRepositoryRemoteProbeModuleMock( - clientMocks, - await importOriginal() - ) -) - -import { getRestPRForBranch } from './pr-branch-lookup' - -import { resetPRForBranchMocks } from '../client-test-harness' - -const { ghExecFileAsyncMock } = clientMocks - -describe('PR lookup conditional REST reads', () => { - beforeEach(() => resetPRForBranchMocks(clientMocks)) - - it('revalidates both mixed and active discovery responses before falling back to history', async () => { - const repo = { owner: 'acme', repo: 'widgets', host: 'github.com' } - const old = Array.from({ length: 10 }, (_, i) => ({ - number: i + 1, - state: 'closed', - title: 'Old', - head: { ref: 'feature' } - })) - const open = { number: 11, state: 'open', title: 'Active', head: { ref: 'feature' } } - const http = (data: unknown, etag: string) => ({ - stdout: `HTTP/2.0 200 OK\nEtag: "${etag}"\r\n\r\n${JSON.stringify(data)}` - }) - ghExecFileAsyncMock - .mockResolvedValueOnce(http(old, 'recent')) - .mockResolvedValueOnce(http([open], 'active')) - .mockRejectedValueOnce( - Object.assign(new Error('304'), { stdout: 'HTTP/2.0 304 Not Modified\n\n' }) - ) - .mockRejectedValueOnce( - Object.assign(new Error('304'), { stdout: 'HTTP/2.0 304 Not Modified\n\n' }) - ) - await expect( - getRestPRForBranch(repo, 'acme', 'feature', { cwd: '/repo' }) - ).resolves.toMatchObject({ number: 11 }) - await expect( - getRestPRForBranch(repo, 'acme', 'feature', { cwd: '/repo' }) - ).resolves.toMatchObject({ number: 11 }) - expect(ghExecFileAsyncMock.mock.calls[2][0]).toContain('If-None-Match: "recent"') - expect(ghExecFileAsyncMock.mock.calls[3][0]).toContain('If-None-Match: "active"') - }) -}) diff --git a/src/main/github/client/lookup/pr-for-branch-outcome-coalescing.test.ts b/src/main/github/client/lookup/pr-for-branch-outcome-coalescing.test.ts deleted file mode 100644 index 06e499b401e..00000000000 --- a/src/main/github/client/lookup/pr-for-branch-outcome-coalescing.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../../repositories/github-repository-identity' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type { PRRefreshOutcome } from '../../../../shared/github/pull-requests/refresh/pull-request-refresh-types' -import type { - GitHubRepoContext, - LocalGitExecOptions -} from '../../repositories/github-repository-identity' - -import { __resetHostedReviewBranchCacheForTests } from '../../../source-control/hosted-review-branch-cache' - -const mocks = vi.hoisted(() => ({ resolve: vi.fn(), acquire: vi.fn(), release: vi.fn() })) -vi.mock('../../execution/github-operation-slots', () => ({ - acquire: mocks.acquire, - release: mocks.release -})) - -vi.mock('../../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - githubRepoContext: ( - repoPath: string, - connectionId: string | null, - options: LocalGitExecOptions - ) => ({ - repoPath, - connectionId, - ...options - }), - ghRepoExecOptions: (context: GitHubRepoContext) => context -})) -vi.mock('./branch-lookup-resolution', () => ({ - resolvePRForBranchOutcome: mocks.resolve -})) -vi.mock('./pr-for-branch-outcome', async () => ({ - getPRForBranchOutcome: (await import('./pr-for-branch-outcome')).getPRForBranchOutcome -})) - -vi.mock('../fetch/repo-slug-upstream', async () => ({ - getRepoSlug: vi.fn(async () => ({ owner: 'acme', repo: 'orca' })) -})) - -vi.mock('./pr-lookup-rate-limit', async () => ({ - getGitHubPRLookupRateLimitBlock: vi.fn(async () => null) -})) - -vi.mock('../create/create-github-pull-request', async () => ({ - createGitHubPullRequest: vi.fn() -})) -vi.mock('../../../gitlab/merge-requests/merge-request-lookup', () => ({ - getProjectSlug: vi.fn(async () => null) -})) -import { getPRForBranchOutcome } from './pr-for-branch-outcome' - -const outcome: PRRefreshOutcome = { kind: 'no-pr', fetchedAt: 1 } -beforeEach(() => { - vi.clearAllMocks() - mocks.resolve.mockReset() - __resetHostedReviewBranchCacheForTests() - mocks.acquire.mockResolvedValue(undefined) -}) -afterEach(() => { - vi.unstubAllEnvs() - vi.useRealTimers() -}) - -describe('PR lookup coalescing', () => { - it('cleans up errors so later reads can recover', async () => { - mocks.resolve.mockRejectedValueOnce(new Error('network down')).mockResolvedValue(outcome) - const results = await Promise.all([ - getPRForBranchOutcome('/repo', 'topic'), - getPRForBranchOutcome('/repo', 'topic') - ]) - expect(results.every((result) => result.kind === 'upstream-error')).toBe(true) - expect(mocks.resolve).toHaveBeenCalledTimes(1) - await expect(getPRForBranchOutcome('/repo', 'topic')).resolves.toEqual(outcome) - expect(mocks.resolve).toHaveBeenCalledTimes(2) - }) -}) diff --git a/src/main/github/issues/issue-work-item-details-fresh.test.ts b/src/main/github/issues/issue-work-item-details-fresh.test.ts deleted file mode 100644 index 6a66462e75d..00000000000 --- a/src/main/github/issues/issue-work-item-details-fresh.test.ts +++ /dev/null @@ -1,209 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../repositories/github-repository-identity' -import { beforeEach, describe, expect, it, vi } from 'vitest' -const mocks = vi.hoisted(() => ({ exec: vi.fn(), guard: vi.fn() })) -vi.mock('../../git/command-runner/hosted-cli/gh-exec-file', () => ({ - ghExecFileAsync: mocks.exec -})) - -vi.mock('../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - ghRepoExecOptions: () => ({}), - githubRepoContext: () => ({}) -})) -vi.mock('../api/rate-limit', () => ({ - repositoryRateLimitGuard: mocks.guard, - noteRepositoryRateLimitSpend: vi.fn() -})) -import { getIssueBodyAndComments, getIssueDetailsViaGraphQL } from './issue-work-item-details' -const repository = { owner: 'acme', repo: 'widgets' } - -describe('explicit task refresh conversation reads', () => { - beforeEach(() => { - mocks.exec.mockReset() - mocks.guard.mockReset() - mocks.guard.mockReturnValue({ blocked: false }) - }) - it('bypasses body, comments and timeline caches and reads every comments page', async () => { - mocks.exec.mockImplementation(async (args: string[]) => ({ - stdout: args.some((arg) => arg.includes('/comments?')) - ? JSON.stringify([ - [{ id: 1, user: null, body: 'first', created_at: '', html_url: '' }], - [{ id: 2, user: null, body: 'second', created_at: '', html_url: '' }] - ]) - : args.some((arg) => arg.includes('/timeline?')) - ? '' - : JSON.stringify({ body: 'current', assignees: [] }) - })) - const result = await getIssueBodyAndComments('/repo', 42, repository, null, {}, true) - expect(result.body).toBe('current') - expect(result.comments.map((comment) => comment.body)).toEqual(['first', 'second']) - for (const [args] of mocks.exec.mock.calls.filter(([args]) => - args.some((arg: string) => arg.startsWith('repos/')) - )) { - expect(args).not.toContain('--cache') - } - expect( - mocks.exec.mock.calls.find(([args]) => - args.some((arg: string) => arg.includes('/comments?')) - )?.[0] - ).toEqual(expect.arrayContaining(['--paginate', '--slurp'])) - }) - it('marks only the comments the reading gh account wrote', async () => { - const comment = (id: number, login: string) => ({ - id, - user: { login, avatar_url: '' }, - body: 'LGTM', - created_at: '', - html_url: '' - }) - mocks.exec.mockImplementation(async (args: string[]) => ({ - stdout: args.includes('user') - ? 'Me\n' - : args.some((arg) => arg.includes('/comments?')) - ? JSON.stringify([[comment(1, 'alice')], [comment(2, 'me')]]) - : args.some((arg) => arg.includes('/timeline?')) - ? '' - : JSON.stringify({ body: 'current' }) - })) - const result = await getIssueBodyAndComments('/repo', 42, repository, null, {}, true) - expect(result.comments.map((c) => [c.author, c.viewerDidAuthor])).toEqual([ - ['alice', undefined], - ['me', true] - ]) - }) - - it('retains ordinary fallback behavior but does not report an explicit rate-limited read as success', async () => { - mocks.guard.mockReturnValue({ blocked: true }) - expect(await getIssueBodyAndComments('/repo', 42, repository)).toEqual({ - body: '', - comments: [], - assignees: [], - timelineItems: [] - }) - await expect(getIssueBodyAndComments('/repo', 42, repository, null, {}, true)).rejects.toThrow() - expect(mocks.exec).not.toHaveBeenCalled() - }) - it('falls back from incomplete GraphQL conversations and malformed timelines', async () => { - mocks.exec.mockResolvedValueOnce({ - stdout: JSON.stringify({ - data: { - repository: { - issue: { body: 'new', comments: { nodes: [], pageInfo: { hasNextPage: true } } } - } - } - }) - }) - expect( - await getIssueDetailsViaGraphQL('/repo', 42, repository, null, {}, false, true) - ).toBeNull() - mocks.exec.mockImplementation(async (args: string[]) => ({ - stdout: args.some((arg) => arg.includes('/timeline?')) - ? 'not-json' - : args.some((arg) => arg.includes('/comments?')) - ? '[]' - : '{"body":"new"}' - })) - await expect(getIssueBodyAndComments('/repo', 42, repository, null, {}, true)).rejects.toThrow() - }) -}) - -it('pairs issue and comment image sources through collapsed and REST detail reads', async () => { - mocks.exec.mockReset() - mocks.guard.mockReturnValue({ blocked: false }) - const body = - '![shot](https://github.com/user-attachments/assets/ce11040a-fb66-4289-927f-547b16dfc488)' - const html = - '' - mocks.exec.mockImplementation(async (args: string[]) => ({ - stdout: JSON.stringify( - args.includes('graphql') - ? { - data: { - repository: { - issue: { - body, - bodyHTML: html, - comments: { nodes: [{ databaseId: 1, body, bodyHTML: html }] } - } - } - } - } - : args.some((arg) => arg.includes('/timeline?')) - ? [] - : args.some((arg) => arg.includes('/comments?')) - ? [{ id: 1, user: null, body, body_html: html }] - : { body, body_html: html } - ) - })) - const collapsed = await getIssueDetailsViaGraphQL('/repo', 42, repository) - const rest = await getIssueBodyAndComments('/repo', 42, repository) - for (const details of [collapsed!, rest]) { - expect(details.body).toBe(body) - expect(details.bodyImageUrls).toEqual({ - 'https://github.com/user-attachments/assets/ce11040a-fb66-4289-927f-547b16dfc488': - 'https://private-user-images.githubusercontent.com/1/ce11040a-fb66-4289-927f-547b16dfc488.png?jwt=TEST' - }) - expect(details.comments[0].bodyImageUrls).toEqual(details.bodyImageUrls) - } - for (const [args] of mocks.exec.mock.calls.filter(([args]) => - args.some((arg: string) => /\/issues\/42(?:$|\/comments)/.test(arg)) - )) { - expect(args).toContain('Accept: application/vnd.github.full+json') - expect(args).not.toContain('--cache') - } -}) - -it.each(['optional HTML', 'required body', 'pathless', 'rejection without errors'] as const)( - 'admits rejected issue stdout only for available optional HTML failures (%s)', - async (input) => { - mocks.exec.mockReset() - mocks.guard.mockReturnValue({ blocked: false }) - const body = - '![shot](https://github.com/user-attachments/assets/ce11040a-fb66-4289-927f-547b16dfc488)' - const html = - '' - mocks.exec.mockRejectedValueOnce( - Object.assign(new Error('GraphQL failed'), { - stdout: JSON.stringify({ - data: { - repository: { - issue: { - body, - bodyHTML: html, - comments: { - pageInfo: { hasNextPage: false }, - nodes: [{ databaseId: 1, body, bodyHTML: html }] - } - } - } - }, - errors: - input === 'rejection without errors' - ? undefined - : [ - { - path: - input === 'pathless' - ? undefined - : ['repository', 'issue', input === 'required body' ? 'body' : 'bodyHTML'] - } - ] - }) - }) - ) - mocks.exec.mockResolvedValueOnce({ stdout: '[]' }) - const result = await getIssueDetailsViaGraphQL('/repo', 42, repository, null, {}, false, true) - if (input !== 'optional HTML') { - expect(result).toBeNull() - expect(mocks.exec).toHaveBeenCalledTimes(1) - return - } - expect(result?.body).toBe(body) - expect(result?.bodyImageUrls).toBeUndefined() - expect(result?.comments[0].bodyImageUrls).toEqual({ - 'https://github.com/user-attachments/assets/ce11040a-fb66-4289-927f-547b16dfc488': - 'https://private-user-images.githubusercontent.com/1/ce11040a-fb66-4289-927f-547b16dfc488.png?jwt=TEST' - }) - expect(mocks.exec).toHaveBeenCalledTimes(2) - } -) diff --git a/src/main/github/pr-watch/pr-earlier-head-jobs-cadence.test.ts b/src/main/github/pr-watch/pr-earlier-head-jobs-cadence.test.ts deleted file mode 100644 index fd204672616..00000000000 --- a/src/main/github/pr-watch/pr-earlier-head-jobs-cadence.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { afterEach, expect, it, vi } from 'vitest' -import { setPRAutoRefreshCadence } from '../../../shared/review-refresh-policy' - -const mocks = vi.hoisted(() => ({ - read: vi.fn(async () => []), - pending: vi.fn(() => [{ headSha: 'old-head', movedAt: 1, expiresAt: null }]) -})) -vi.mock('../pull-requests/refresh/pr-refresh-coordinator', () => ({ schedulePRWatchRead: vi.fn() })) -vi.mock('./pr-head-check-read', () => ({ readPRHeadCheckRollup: mocks.read })) - -import { PREarlierHeadJobs } from './pr-earlier-head-jobs' -import { prWatchPlanDueAt } from '../pull-requests/refresh/pr-refresh-watch-jobs' - -afterEach(() => setPRAutoRefreshCadence('default')) - -it.each([ - ['default', 120_000], - ['reduced', 10 * 60_000], - ['minimal', 20 * 60_000], - // A chat is waiting for the result, so off slows to minimal instead of stopping. - ['off', 20 * 60_000] -] as const)( - 'an earlier head’s next read follows the %s watch cadence', - async (cadence, interval) => { - setPRAutoRefreshCadence(cadence) - const jobs = new PREarlierHeadJobs({ - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: this read-only probe only requests pending heads. - database: { read: async () => mocks.pending() } as never, - apply: async () => false, - logger: { warn: vi.fn() }, - now: () => 1_000 - }) - const readAt = await jobs.read( - { prKey: 'github.com/acme/repo#7', headSha: 'old-head' }, - { repoId: 'r', repoPath: '/repo', branch: 'topic', repoKind: 'git', cacheKey: 'k' } - ) - expect(readAt).toBe(1_000) - expect(prWatchPlanDueAt({ kind: 'head', at: readAt! })).toBe(1_000 + interval) - } -) diff --git a/src/main/github/pull-requests/refresh/pr-refresh-candidate-policy-cadence.test.ts b/src/main/github/pull-requests/refresh/pr-refresh-candidate-policy-cadence.test.ts deleted file mode 100644 index 0342c73f736..00000000000 --- a/src/main/github/pull-requests/refresh/pr-refresh-candidate-policy-cadence.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { expect, it, vi } from 'vitest' -import { makeCandidate, makePR } from './pr-refresh-coordinator-test-harness' -import { getPRForBranchOutcome } from '../../client/lookup/pr-for-branch-outcome' -import { runHostedPRRead } from './pr-refresh-coordinator' -import { refreshIntervalForCandidate } from './pr-refresh-candidate-policy' - -vi.mock('../../client/lookup/branch-lookup-resolution', () => ({ - resolvePRForBranchOutcome: async () => ({ - kind: 'found', - fetchedAt: Date.now(), - pr: makePR({ - headSha: 'head', - checksStatus: 'success', - checksReadComplete: true, - checksFinal: true, - autoMergeEnabled: false, - mergeQueueRequired: false - }) - }) -})) -vi.mock('../../execution/github-operation-slots', () => ({ - acquire: async () => {}, - release: () => {} -})) - -it('stretches a confirmed quiet PR’s interval by the cadence, as it does every other interval', async () => { - const candidate = makeCandidate({ - branch: 'branch', - currentHeadOid: 'head', - cachedHeadOid: 'head', - cachedFetchedAt: 2_000, - cachedPRState: 'open', - cachedChecksStatus: 'success', - cachedHasPR: true - }) - const read = () => - runHostedPRRead(candidate, () => - getPRForBranchOutcome('/repo', 'branch', null, null, null, { currentHeadOid: 'head' }) - ) - vi.useFakeTimers() - vi.setSystemTime(1_000) - await read() - vi.setSystemTime(2_000) - await read() - const unconfirmed = { ...candidate, fallbackPRNumber: 9 } - expect( - (['default', 'reduced', 'minimal', 'off'] as const).map((cadence) => [ - refreshIntervalForCandidate(candidate, cadence), - refreshIntervalForCandidate(unconfirmed, cadence) - ]) - ).toEqual([ - [300_000, 120_000], - [1_500_000, 600_000], - [3_000_000, 1_200_000], - [Infinity, Infinity] - ]) - vi.useRealTimers() -}) diff --git a/src/main/github/pull-requests/refresh/pr-refresh-coordinator-active-visible-priority.test.ts b/src/main/github/pull-requests/refresh/pr-refresh-coordinator-active-visible-priority.test.ts deleted file mode 100644 index ae51e200e43..00000000000 --- a/src/main/github/pull-requests/refresh/pr-refresh-coordinator-active-visible-priority.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' -import type { PRInfo } from '../../../../shared/github/pull-requests/pull-request-types' - -const { coordinatorMocks, moduleMocks } = await vi.hoisted(async () => { - const moduleMocks = await import('./pr-refresh-coordinator-test-mocks') - return { coordinatorMocks: moduleMocks.createPRRefreshCoordinatorMocks(), moduleMocks } -}) - -vi.mock('./pr-refresh-renderer-port', () => moduleMocks.rendererPortModuleMock(coordinatorMocks)) -vi.mock('../../client/lookup/pr-for-branch-outcome', () => { - return moduleMocks.clientModuleMock(coordinatorMocks) -}) -vi.mock('../../repositories/github-api-repository-remote-probe', () => { - return { - getOriginGitHubApiRepository: coordinatorMocks.getOriginGitHubApiRepositoryMock - } -}) -vi.mock('../../api/rate-limit', () => moduleMocks.rateLimitModuleMock(coordinatorMocks)) - -import { makeCandidate, makePR } from './pr-refresh-coordinator-test-harness' - -const { sendMock, getPRForBranchOutcomeMock } = coordinatorMocks - -function deferred(): { - promise: Promise - resolve: (value: T) => void - reject: (error: unknown) => void -} { - let resolve!: (value: T) => void - let reject!: (error: unknown) => void - const promise = new Promise((res, rej) => { - resolve = res - reject = rej - }) - return { promise, resolve, reject } -} - -describe('pr-refresh-coordinator', () => { - beforeEach(() => { - moduleMocks.resetPRRefreshCoordinatorMocks(coordinatorMocks) - }) - - // Transforming the coordinator's module graph is the slow first step on a loaded machine: do it - // once under the hook limit, so each test still imports its own fresh instance, quickly. - beforeAll(async () => { - await import('./pr-refresh-coordinator') - }) - - afterEach(() => { - // A body that failed must not leave its timers to run on the next test's clock. - vi.clearAllTimers() - vi.useRealTimers() - }) - - it('preserves an active refresh queued while a visible refresh is in flight', async () => { - const { enqueuePRRefresh, reportVisiblePRRefreshCandidates } = - await import('./pr-refresh-coordinator') - const visibleOutcome = deferred<{ - kind: 'found' - pr: PRInfo - fetchedAt: number - }>() - getPRForBranchOutcomeMock.mockReturnValueOnce(visibleOutcome.promise).mockResolvedValueOnce({ - kind: 'found', - pr: makePR({ checksStatus: 'success', state: 'merged' }), - fetchedAt: Date.now() - }) - - const candidate = makeCandidate() - reportVisiblePRRefreshCandidates([candidate], 1, 1) - await vi.advanceTimersByTimeAsync(0) - - enqueuePRRefresh({ ...candidate, cachedFetchedAt: Date.now() }, 'active', 80, 1) - visibleOutcome.resolve({ - kind: 'found', - pr: makePR({ checksStatus: 'pending', mergeable: 'MERGEABLE' }), - fetchedAt: Date.now() - }) - await vi.advanceTimersByTimeAsync(0) - - const inFlightEvents = sendMock.mock.calls - .map(([, event]) => event) - .filter((event) => event.status === 'in-flight') - - expect(inFlightEvents.map((event) => event.reason)).toEqual(['visible', 'active']) - expect(getPRForBranchOutcomeMock).toHaveBeenCalledTimes(2) - }) -}) diff --git a/src/main/github/pull-requests/refresh/pr-refresh-coordinator-completion-order.test.ts b/src/main/github/pull-requests/refresh/pr-refresh-coordinator-completion-order.test.ts deleted file mode 100644 index fd787cc66fe..00000000000 --- a/src/main/github/pull-requests/refresh/pr-refresh-coordinator-completion-order.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type { PRRefreshOutcome } from '../../../../shared/github/pull-requests/refresh/pull-request-refresh-types' - -import { makeCandidate, makePR } from './pr-refresh-coordinator-test-harness' - -const { coordinatorMocks, moduleMocks } = await vi.hoisted(async () => { - const moduleMocks = await import('./pr-refresh-coordinator-test-mocks') - return { coordinatorMocks: moduleMocks.createPRRefreshCoordinatorMocks(), moduleMocks } -}) -vi.mock('./pr-refresh-renderer-port', () => moduleMocks.rendererPortModuleMock(coordinatorMocks)) -vi.mock('../../client/lookup/pr-for-branch-outcome', () => { - return moduleMocks.clientModuleMock(coordinatorMocks) -}) -vi.mock('../../repositories/github-api-repository-remote-probe', () => { - return { - getOriginGitHubApiRepository: coordinatorMocks.getOriginGitHubApiRepositoryMock - } -}) -vi.mock('../../api/rate-limit', () => moduleMocks.rateLimitModuleMock(coordinatorMocks)) - -const { getPRForBranchOutcomeMock } = coordinatorMocks - -function found(state: 'open' | 'closed' | 'merged'): PRRefreshOutcome { - return { kind: 'found', pr: makePR({ state, checksStatus: 'success' }), fetchedAt: Date.now() } -} - -describe('main refresh completion ordering', () => { - beforeEach(() => moduleMocks.resetPRRefreshCoordinatorMocks(coordinatorMocks)) - afterEach(() => vi.useRealTimers()) - - it('preserves a newer failure gate when an older successful lookup completes', async () => { - let finishOlder: (outcome: PRRefreshOutcome) => void = () => {} - getPRForBranchOutcomeMock - .mockImplementationOnce( - () => new Promise((resolve) => (finishOlder = resolve)) - ) - .mockImplementation(async () => ({ - kind: 'upstream-error', - errorType: 'rate_limited', - message: 'wait', - fetchedAt: Date.now(), - retryDisabledUntil: Date.now() + 300_000 - })) - const { reportVisiblePRRefreshCandidates, refreshPRNow } = - await import('./pr-refresh-coordinator') - const candidate = makeCandidate({ isSelected: true }) - reportVisiblePRRefreshCandidates([candidate], 1, 1) - await vi.advanceTimersByTimeAsync(0) - await refreshPRNow(candidate) - finishOlder(found('open')) - await vi.advanceTimersByTimeAsync(60_000) - expect(getPRForBranchOutcomeMock).toHaveBeenCalledTimes(2) - await expect(refreshPRNow(candidate)).resolves.toMatchObject({ errorType: 'rate_limited' }) - expect(getPRForBranchOutcomeMock).toHaveBeenCalledTimes(2) - }) -}) diff --git a/src/main/github/pull-requests/refresh/pr-refresh-queue-growth-bound.test.ts b/src/main/github/pull-requests/refresh/pr-refresh-queue-growth-bound.test.ts deleted file mode 100644 index 2a2323a7209..00000000000 --- a/src/main/github/pull-requests/refresh/pr-refresh-queue-growth-bound.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type { GitHubPRRefreshCandidate } from '../../../../shared/github/pull-requests/refresh/pull-request-refresh-types' - -const { coordinatorMocks, moduleMocks } = await vi.hoisted(async () => { - const moduleMocks = await import('./pr-refresh-coordinator-test-mocks') - return { coordinatorMocks: moduleMocks.createPRRefreshCoordinatorMocks(), moduleMocks } -}) - -vi.mock('./pr-refresh-renderer-port', () => moduleMocks.rendererPortModuleMock(coordinatorMocks)) -vi.mock('../../client/lookup/pr-for-branch-outcome', () => { - return moduleMocks.clientModuleMock(coordinatorMocks) -}) -vi.mock('../../repositories/github-api-repository-remote-probe', () => { - return { - getOriginGitHubApiRepository: coordinatorMocks.getOriginGitHubApiRepositoryMock - } -}) -vi.mock('../../api/rate-limit', () => moduleMocks.rateLimitModuleMock(coordinatorMocks)) - -import { makeCandidate, makePR } from './pr-refresh-coordinator-test-harness' - -const { getPRForBranchOutcomeMock } = coordinatorMocks -const LINKED_PR_KEY = 'local::runtime:host::/repo::pr::42' - -describe('pr-refresh queue growth bounds', () => { - beforeEach(() => { - moduleMocks.resetPRRefreshCoordinatorMocks(coordinatorMocks) - getPRForBranchOutcomeMock.mockImplementation(async () => ({ - kind: 'found' as const, - pr: makePR({ checksStatus: 'pending' as const }), - fetchedAt: Date.now() - })) - }) - - afterEach(() => { - vi.useRealTimers() - }) - - it('keeps the newer alias when a branch switch lands mid-request', async () => { - const { reportVisiblePRRefreshCandidates, _getPRRefreshAliasCountForTests } = - await import('./pr-refresh-coordinator') - - const churnCandidate = (index: number): GitHubPRRefreshCandidate => - makeCandidate({ - cacheKey: `/repo::churn/${index}`, - branch: `churn/${index}`, - worktreeId: 'wt-churn', - linkedPRNumber: 42, - cachedFetchedAt: null - }) - - let switched = false - getPRForBranchOutcomeMock.mockImplementation(async () => { - if (!switched) { - switched = true - // Re-enqueue after dequeue so the older in-flight snapshot merges into a newer queued entry. - reportVisiblePRRefreshCandidates([churnCandidate(2)], 2, 1) - } - return { - kind: 'found' as const, - pr: makePR({ checksStatus: 'pending' as const }), - fetchedAt: Date.now() - } - }) - - reportVisiblePRRefreshCandidates([churnCandidate(1)], 1, 1) - await vi.advanceTimersByTimeAsync(120_000) - - expect(_getPRRefreshAliasCountForTests(LINKED_PR_KEY)).toBe(1) - const broadcasts = coordinatorMocks.sendMock.mock.calls.filter( - (call) => call[0] === 'gh:prRefreshEvent' - ) as [string, { aliases: { cacheKey: string }[] }][] - const lastBroadcast = broadcasts.at(-1) - expect(lastBroadcast?.[1].aliases.map((alias) => alias.cacheKey)).toEqual(['/repo::churn/2']) - }) -}) diff --git a/src/main/github/pull-requests/refresh/pr-refresh-watch-derived-data.test.ts b/src/main/github/pull-requests/refresh/pr-refresh-watch-derived-data.test.ts deleted file mode 100644 index 9d47254c3bc..00000000000 --- a/src/main/github/pull-requests/refresh/pr-refresh-watch-derived-data.test.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { afterEach, expect, it, vi } from 'vitest' -import type { PRRefreshOutcome } from '../../../../shared/github/pull-requests/refresh/pull-request-refresh-types' -import type { PullRequestLookupData } from '../../client/lookup/pull-request-lookup-data' -import { makeCandidate } from './pr-refresh-coordinator-test-harness' - -const fixture = vi.hoisted(() => ({ - lookup: vi.fn(), - conflict: vi.fn(), - stack: { number: 2, position: 1, size: 2, baseRefName: 'main', baseSha: 'base-sha' } -})) -vi.mock('../../repositories/github-api-repository', () => ({ - resolveGitHubApiRepositoryCandidates: async () => ({ - candidates: [{ owner: 'acme', repo: 'widgets' }], - headRepo: { owner: 'acme', repo: 'widgets' } - }) -})) - -vi.mock('../../repositories/github-api-repository-remote-probe', () => ({ - getOriginGitHubApiRepository: async () => ({ owner: 'acme', repo: 'widgets' }) -})) -vi.mock('../../api/rate-limit', () => ({ - repositoryRateLimitGuard: () => ({ blocked: false }), - spendsSharedGitHubComQuota: () => false -})) -vi.mock('../../client/lookup/pr-number-lookup', () => ({ lookupPRByNumber: fixture.lookup })) -vi.mock('../../client/lookup/pr-stack-summary-cache', () => ({ - getCachedGitHubPRStackSummary: async () => fixture.stack -})) -vi.mock('../stacks/github-pr-stack', () => ({ - hydrateGitHubPRStack: async () => fixture.stack -})) -vi.mock('../../client/detect/repository-merge-metadata', () => ({ - detectRepositoryMergeMetadata: async () => ({ mergeQueueRequired: true }) -})) -vi.mock('../conflicts/conflict-summary', () => ({ - getPRConflictSummary: fixture.conflict -})) - -const data: PullRequestLookupData = { - number: 12, - title: 'Conflicting change', - state: 'OPEN', - url: 'https://github.com/acme/widgets/pull/12', - updatedAt: '2026-11-11T00:00:00Z', - mergeable: 'CONFLICTING', - baseRefName: 'main', - baseRefOid: 'base-sha', - headRefName: 'topic', - headRefOid: 'head-sha', - checksUnavailable: false, - statusCheckRollup: [{ __typename: 'CheckRun', name: 'build', status: 'IN_PROGRESS' }] -} -const summary = { baseRef: 'main', baseCommit: 'base-sh', commitsBehind: 1, files: ['a.ts'] } - -afterEach(() => vi.useRealTimers()) - -it('watches preserve provider checks while full and phone reads retain derived details', async () => { - vi.useFakeTimers() - vi.setSystemTime(1_000) - fixture.lookup.mockImplementation(async () => ({ - data: { ...data }, - dataRepo: { owner: 'acme', repo: 'widgets' } - })) - fixture.conflict.mockResolvedValue(summary) - const { addPRRefreshOutcomeObserver, schedulePRWatchRead } = - await import('./pr-refresh-coordinator') - const { getPRForBranchOutcome, readRecentPhonePROutcome } = - await import('../../client/lookup/pr-for-branch-outcome') - const candidate = makeCandidate({ branch: 'topic', linkedPRNumber: 12 }) - const watched = Promise.withResolvers() - const unsubscribe = addPRRefreshOutcomeObserver((_, outcome) => watched.resolve(outcome)) - schedulePRWatchRead({ prKey: 'github.com/acme/widgets#12' }, candidate, Date.now()) - await vi.advanceTimersByTimeAsync(0) - const watch = await watched.promise - unsubscribe() - expect(watch).toMatchObject({ - kind: 'found', - pr: { number: 12, headSha: 'head-sha', state: 'open', checksStatus: 'pending' } - }) - if (watch.kind !== 'found') { - throw new Error('watch did not find the PR') - } - expect(watch.pr.conflictSummary).toBeUndefined() - expect(watch.pr.stack).toBeUndefined() - expect(watch.pr.mergeQueueRequired).toBeUndefined() - - // An uncapped partial read must also stay separate from a concurrent full read. - const provider = Promise.withResolvers() - const entered = Promise.withResolvers() - const conflict = Promise.withResolvers() - fixture.lookup.mockImplementation(async () => { - entered.resolve() - await provider.promise - return { data: { ...data }, dataRepo: { owner: 'acme', repo: 'widgets' } } - }) - fixture.conflict.mockReturnValue(conflict.promise) - const partial = getPRForBranchOutcome('/repo', 'topic', 12, null, null, { - includeDerivedData: false - }) - await entered.promise - const full = getPRForBranchOutcome('/repo', 'topic', 12, null, null) - provider.resolve() - try { - expect(await partial).toMatchObject({ kind: 'found', pr: { conflictSummary: undefined } }) - expect( - await readRecentPhonePROutcome('/repo', 'topic', 12, null, null, { - currentHeadOid: 'head-sha' - }) - ).toBeNull() - } finally { - conflict.resolve(summary) - } - const complete = await full - expect(complete).toMatchObject({ - kind: 'found', - pr: { - number: 12, - headSha: 'head-sha', - checksStatus: 'pending', - conflictSummary: { files: ['a.ts'], commitsBehind: 1 }, - stack: { number: 2, baseRefName: 'main' }, - mergeQueueRequired: true - } - }) - expect( - await readRecentPhonePROutcome('/repo', 'topic', 12, null, null, { currentHeadOid: 'head-sha' }) - ).toEqual(complete) -}) diff --git a/src/main/github/pull-requests/stacks/github-pr-stack.test.ts b/src/main/github/pull-requests/stacks/github-pr-stack.test.ts deleted file mode 100644 index 402fca60bf5..00000000000 --- a/src/main/github/pull-requests/stacks/github-pr-stack.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const { ghExecFileAsyncMock, rateLimitGuardMock, noteRateLimitSpendMock } = vi.hoisted(() => ({ - ghExecFileAsyncMock: vi.fn(), - rateLimitGuardMock: vi.fn(() => ({ blocked: false })), - noteRateLimitSpendMock: vi.fn() -})) - -vi.mock('../../../git/command-runner/hosted-cli/gh-exec-file', async (importOriginal) => ({ - ...(await importOriginal>()), - ghExecFileAsync: ghExecFileAsyncMock -})) -vi.mock('../../api/rate-limit', () => ({ - repositoryRateLimitGuard: rateLimitGuardMock, - noteRepositoryRateLimitSpend: noteRateLimitSpendMock -})) -import { _resetGitHubPRStackCacheForTests } from './github-pr-stack' -import { mergeGitHubPRStack } from './github-pr-stack-async-merge' - -const repository = { owner: 'stablyai', repo: 'orca', host: 'github.com' } - -beforeEach(() => { - vi.useRealTimers() - ghExecFileAsyncMock.mockReset() - rateLimitGuardMock.mockReset() - rateLimitGuardMock.mockReturnValue({ blocked: false }) - noteRateLimitSpendMock.mockReset() - _resetGitHubPRStackCacheForTests() -}) - -describe('mergeGitHubPRStack', () => { - it('reports an in-progress merge after polling is exhausted', async () => { - vi.useFakeTimers() - ghExecFileAsyncMock.mockResolvedValue({ - stdout: JSON.stringify({ status: 'pending', details: { uuid: 'merge-uuid' } }) - }) - - const result = mergeGitHubPRStack({ - repository, - prNumber: 202, - method: 'squash', - mergeAction: 'direct_merge', - ghOptions: { cwd: '/repo' } - }) - await vi.advanceTimersByTimeAsync(180_000) - - await expect(result).resolves.toMatchObject({ - ok: false, - error: 'GitHub is still merging this stack. Refresh to check its status.' - }) - expect(ghExecFileAsyncMock).toHaveBeenCalledTimes(181) - }) -}) diff --git a/src/main/github/repositories/github-api-repository-remote-probe.test.ts b/src/main/github/repositories/github-api-repository-remote-probe.test.ts deleted file mode 100644 index fe39dadd3a9..00000000000 --- a/src/main/github/repositories/github-api-repository-remote-probe.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as GitExecFileModule from '../../git/command-runner/git-exec-file' - -const { gitExecFileAsyncMock } = vi.hoisted(() => ({ - gitExecFileAsyncMock: vi.fn<(args: string[]) => Promise<{ stdout: string; stderr: string }>>() -})) - -vi.mock('../../git/command-runner/git-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - gitExecFileAsync: gitExecFileAsyncMock -})) - -import { _resetOwnerRepoCache } from './github-repository-identity' -import { _resetRemoteNameListingCache } from '../../git/remotes/remote-name-listing' -import { - _resetOriginGitHubApiRepositoryCache, - getGitHubApiRepositoryForRemote -} from './github-api-repository-remote-probe' - -// Why: no real .git config means no config signature, so caches use their short unsigned TTLs. -const REPO_PATH = '/does-not-exist/orca-remote-probe-fixture' - -function mockRemotes(remotes: Record): void { - gitExecFileAsyncMock.mockImplementation((args) => { - if (args[0] === 'remote' && args.length === 1) { - return Promise.resolve({ stdout: Object.keys(remotes).join('\n'), stderr: '' }) - } - if (args[0] === 'remote' && args[1] === 'get-url') { - const url = remotes[args[2]] - if (url) { - return Promise.resolve({ stdout: `${url}\n`, stderr: '' }) - } - return Promise.reject( - Object.assign(new Error(`git remote get-url ${args[2]}`), { - stderr: `error: No such remote '${args[2]}'` - }) - ) - } - return Promise.reject(new Error(`unexpected git exec: ${JSON.stringify(args)}`)) - }) -} - -beforeEach(() => { - vi.useFakeTimers() - gitExecFileAsyncMock.mockReset() - _resetOriginGitHubApiRepositoryCache() - _resetOwnerRepoCache() - _resetRemoteNameListingCache() -}) - -afterEach(() => { - vi.useRealTimers() -}) - -describe('getGitHubApiRepositoryForRemote', () => { - it('still resolves a configured upstream remote', async () => { - mockRemotes({ - origin: 'https://github.com/acme/orca.git', - upstream: 'https://github.com/stablyai/orca.git' - }) - - await expect(getGitHubApiRepositoryForRemote(REPO_PATH, 'upstream')).resolves.toEqual({ - owner: 'stablyai', - repo: 'orca', - host: 'github.com' - }) - }) -}) diff --git a/src/main/github/repositories/github-repository-identity.signed-cache.test.ts b/src/main/github/repositories/github-repository-identity.signed-cache.test.ts deleted file mode 100644 index adc4d5e20dd..00000000000 --- a/src/main/github/repositories/github-repository-identity.signed-cache.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as GitRunner from '../../git/command-runner/git-exec-file' - -const { gitExecFileAsyncMock, readLocalGitConfigSignatureMock } = vi.hoisted(() => ({ - gitExecFileAsyncMock: vi.fn(), - readLocalGitConfigSignatureMock: vi.fn<() => Promise>(async () => 'sig-1') -})) - -vi.mock('../../git/command-runner/git-exec-file', async (importOriginal) => ({ - ...(await importOriginal()), - gitExecFileAsync: gitExecFileAsyncMock -})) - -vi.mock('./local-git-config-signature', () => ({ - readLocalGitConfigSignature: readLocalGitConfigSignatureMock -})) - -import { getOwnerRepoForRemote, _resetOwnerRepoCache } from './github-repository-identity' - -const REPO = '/tmp/signed-cache-repo' -const THIRTY_SECONDS = 30_000 - -let remoteUrl = 'https://github.com/stablyai/orca.git' - -const remoteGetUrlCalls = (): number => - gitExecFileAsyncMock.mock.calls.filter(([args]) => (args as string[])[1] === 'get-url').length - -beforeEach(() => { - _resetOwnerRepoCache() - vi.useRealTimers() - gitExecFileAsyncMock.mockReset() - remoteUrl = 'https://github.com/stablyai/orca.git' - readLocalGitConfigSignatureMock.mockReset() - readLocalGitConfigSignatureMock.mockImplementation(async () => 'sig-1') - gitExecFileAsyncMock.mockImplementation(async () => ({ stdout: remoteUrl })) -}) - -describe('owner/repo identity cache', () => { - it('re-probes as soon as the git config signature changes', async () => { - vi.useFakeTimers() - await getOwnerRepoForRemote(REPO, 'origin') - expect(remoteGetUrlCalls()).toBe(1) - - remoteUrl = 'https://github.com/other-org/orca.git' - readLocalGitConfigSignatureMock.mockImplementation(async () => 'sig-2') - vi.setSystemTime(Date.now() + THIRTY_SECONDS) - - await expect(getOwnerRepoForRemote(REPO, 'origin')).resolves.toEqual({ - owner: 'other-org', - repo: 'orca' - }) - expect(remoteGetUrlCalls()).toBe(2) - vi.useRealTimers() - }) -}) diff --git a/src/main/github/work-items/work-item-details-pr-files.test.ts b/src/main/github/work-items/work-item-details-pr-files.test.ts deleted file mode 100644 index 485054a2f4d..00000000000 --- a/src/main/github/work-items/work-item-details-pr-files.test.ts +++ /dev/null @@ -1,218 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../repositories/github-repository-identity' -import type * as WorkItemDetailsTestLookup from './work-item-details-test-lookup' -import { beforeEach, describe, expect, it, vi } from 'vitest' - -type RateLimitGuardResult = - | { blocked: false } - | { blocked: true; remaining: number; limit: number; resetAt: number } - -const { - ghExecFileAsyncMock, - getEnterpriseGitHubRepoSlugMock, - getOwnerRepoMock, - getWorkItemMock, - getPRChecksMock, - getPRCommentsMock, - noteRepositoryRateLimitSpendMock, - repositoryRateLimitGuardMock -} = vi.hoisted(() => ({ - ghExecFileAsyncMock: vi.fn(), - getEnterpriseGitHubRepoSlugMock: vi.fn(), - getOwnerRepoMock: vi.fn(), - getWorkItemMock: vi.fn(), - getPRChecksMock: vi.fn(), - getPRCommentsMock: vi.fn(), - noteRepositoryRateLimitSpendMock: - vi.fn< - ( - repository: { host?: string } | null | undefined, - bucket: string, - cost?: number, - options?: { cwd?: string; host?: string } - ) => void - >(), - repositoryRateLimitGuardMock: vi.fn< - ( - repository: { host?: string } | null | undefined, - bucket: string, - options?: { cwd?: string; host?: string } - ) => RateLimitGuardResult - >(() => ({ blocked: false })) -})) - -vi.mock('../../git/command-runner/hosted-cli/gh-exec-file', () => ({ - ghExecFileAsync: ghExecFileAsyncMock -})) - -vi.mock('../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - getOwnerRepoForRemote: getOwnerRepoMock, - ghRepoExecOptions: vi.fn((context) => ({ cwd: context.repoPath })), - githubRepoContext: vi.fn((repoPath, connectionId, localGitOptions) => ({ - repoPath, - connectionId: connectionId ?? null, - ...localGitOptions - })) -})) - -vi.mock('../repositories/github-owner-repo-selection', () => ({ - getOwnerRepo: vi.fn() -})) - -vi.mock('../execution/github-operation-slots', () => ({ - acquire: vi.fn(), - release: vi.fn() -})) - -vi.mock('../client/fetch/get-work-item', async () => ({ - getWorkItem: getWorkItemMock, - getWorkItemWithRepository: ( - await vi.importActual('./work-item-details-test-lookup') - ).makeWorkItemDetailsLookupMock(getWorkItemMock), - getWorkItemByOwnerRepo: vi.fn() -})) - -vi.mock('../client/check/get-pr-checks', async () => ({ - getPRChecks: getPRChecksMock -})) - -vi.mock('../client/fetch/get-pr-comments', async () => ({ - getPRComments: getPRCommentsMock -})) - -vi.mock('../repositories/github-enterprise-repository', () => ({ - getEnterpriseGitHubRepoSlug: getEnterpriseGitHubRepoSlugMock, - isGitHubHostAuthenticated: vi.fn().mockResolvedValue(true) -})) - -vi.mock('../api/rate-limit', () => ({ - rateLimitGuard: vi.fn(() => ({ blocked: false })), - noteRateLimitSpend: vi.fn(), - repositoryRateLimitGuard: repositoryRateLimitGuardMock, - noteRepositoryRateLimitSpend: noteRepositoryRateLimitSpendMock -})) -import { getWorkItemDetails } from './work-item-details' - -import { _resetOriginGitHubApiRepositoryCache } from '../repositories/github-api-repository-remote-probe' - -beforeEach(() => { - _resetOriginGitHubApiRepositoryCache() -}) - -function pullRequestItem(number: number, title: string): Record { - return { - id: `pr:${number}`, - type: 'pr', - number, - title, - state: 'open', - url: `https://github.com/acme/widgets/pull/${number}`, - labels: [], - updatedAt: '2026-07-16T00:00:00Z', - author: 'pr-author' - } -} - -function auxiliaryPRResponse(args: string[]): { stdout: string } { - const query = args.find((arg) => arg.startsWith('query=')) ?? '' - if (query.includes('viewerViewedState')) { - return { - stdout: JSON.stringify({ - data: { - repository: { - viewedPullRequest: { - id: 'PR_file_list', - files: { pageInfo: { hasNextPage: false }, nodes: [] } - } - } - } - }) - } - } - if (query.includes('participants(first: 100)')) { - return { - stdout: JSON.stringify({ - data: { repository: { pullRequest: { participants: { nodes: [] } } } } - }) - } - } - return { stdout: JSON.stringify({ data: {} }) } -} - -describe('getWorkItemDetails PR file listing', () => { - beforeEach(() => { - ghExecFileAsyncMock.mockReset() - getOwnerRepoMock.mockReset() - getOwnerRepoMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' }) - getEnterpriseGitHubRepoSlugMock.mockReset() - getEnterpriseGitHubRepoSlugMock.mockResolvedValue(null) - getWorkItemMock.mockReset() - getPRChecksMock.mockReset() - getPRChecksMock.mockResolvedValue([]) - getPRCommentsMock.mockReset() - getPRCommentsMock.mockResolvedValue([]) - noteRepositoryRateLimitSpendMock.mockReset() - repositoryRateLimitGuardMock.mockReset() - repositoryRateLimitGuardMock.mockReturnValue({ blocked: false }) - }) - - it('loads files beyond the first 100-result REST page', async () => { - getWorkItemMock.mockResolvedValueOnce(pullRequestItem(108, 'Large PR')) - const restFile = (index: number) => ({ - filename: `src/file-${index}.ts`, - status: 'modified', - additions: 1, - deletions: 0, - changes: 1, - patch: '@@ -1 +1 @@' - }) - ghExecFileAsyncMock.mockImplementation(async (args: string[]) => { - const endpoint = args.find((arg) => arg.startsWith('repos/')) ?? '' - if (endpoint === 'repos/acme/widgets/pulls/108') { - return { stdout: JSON.stringify({ head: { sha: 'head' }, base: { sha: 'base' } }) } - } - if (endpoint === 'repos/acme/widgets/pulls/108/files?per_page=100') { - return { - stdout: JSON.stringify(Array.from({ length: 100 }, (_, index) => restFile(index))) - } - } - if (endpoint === 'repos/acme/widgets/pulls/108/files?per_page=100&page=2') { - return { stdout: JSON.stringify([restFile(100)]) } - } - return auxiliaryPRResponse(args) - }) - - const details = await getWorkItemDetails('/repo-root', 108, 'pr') - - expect(details?.files).toHaveLength(101) - expect(details?.files?.at(-1)?.path).toBe('src/file-100.ts') - const fileEndpoints = ghExecFileAsyncMock.mock.calls - .map(([args]) => (args as string[]).find((arg) => arg.includes('/files?'))) - .filter(Boolean) - expect(fileEndpoints).toEqual([ - 'repos/acme/widgets/pulls/108/files?per_page=100', - 'repos/acme/widgets/pulls/108/files?per_page=100&page=2' - ]) - expect( - noteRepositoryRateLimitSpendMock.mock.calls.filter(([, bucket]) => bucket === 'core') - ).toHaveLength(3) - expect( - repositoryRateLimitGuardMock.mock.calls.filter(([, bucket]) => bucket === 'core') - ).toHaveLength(3) - }) - - it('does not run bare PR detail commands when local host resolution fails', async () => { - getWorkItemMock.mockResolvedValueOnce({ - ...pullRequestItem(9, 'Unresolved PR'), - prRepo: { owner: 'team', repo: 'orca' } - }) - getOwnerRepoMock.mockResolvedValue(null) - - const details = await getWorkItemDetails('/repo-root', 9, 'pr') - - expect(details).toMatchObject({ body: '', comments: [], checks: [], filesUnavailable: true }) - expect(getPRCommentsMock).not.toHaveBeenCalled() - expect(getPRChecksMock).not.toHaveBeenCalled() - expect(ghExecFileAsyncMock).not.toHaveBeenCalled() - }) -}) diff --git a/src/main/github/work-items/work-item-details.test.ts b/src/main/github/work-items/work-item-details.test.ts deleted file mode 100644 index b500e0db06c..00000000000 --- a/src/main/github/work-items/work-item-details.test.ts +++ /dev/null @@ -1,212 +0,0 @@ -import type * as GithubRepositoryIdentityModule from '../repositories/github-repository-identity' -import type * as WorkItemDetailsTestLookup from './work-item-details-test-lookup' -import { beforeEach, describe, expect, it, vi } from 'vitest' - -type RateLimitGuardResult = - | { blocked: false } - | { blocked: true; remaining: number; limit: number; resetAt: number } - -const { - ghExecFileAsyncMock, - getOwnerRepoMock, - getOwnerRepoForRemoteMock, - getEnterpriseGitHubRepoSlugMock, - getEnterpriseGitHubRepoSlugForRemoteMock, - getWorkItemMock, - getWorkItemByOwnerRepoMock, - getPRChecksMock, - getPRCommentsMock, - repositoryRateLimitGuardMock, - noteRepositoryRateLimitSpendMock, - ghRepoExecOptionsMock, - githubRepoContextMock, - acquireMock, - releaseMock -} = vi.hoisted(() => ({ - ghExecFileAsyncMock: vi.fn(), - getOwnerRepoMock: vi.fn(), - getOwnerRepoForRemoteMock: vi.fn(), - getEnterpriseGitHubRepoSlugMock: vi.fn(), - getEnterpriseGitHubRepoSlugForRemoteMock: vi.fn(), - getWorkItemMock: vi.fn(), - getWorkItemByOwnerRepoMock: vi.fn(), - getPRChecksMock: vi.fn(), - getPRCommentsMock: vi.fn(), - repositoryRateLimitGuardMock: vi.fn< - ( - repository: { host?: string } | null | undefined, - bucket: 'core' | 'graphql' | 'search', - options?: { cwd?: string; wslDistro?: string } - ) => RateLimitGuardResult - >(() => ({ blocked: false })), - noteRepositoryRateLimitSpendMock: vi.fn(), - ghRepoExecOptionsMock: vi.fn((context) => - context.connectionId - ? {} - : { cwd: context.repoPath, ...(context.wslDistro ? { wslDistro: context.wslDistro } : {}) } - ), - githubRepoContextMock: vi.fn((repoPath, connectionId, localGitOptions) => ({ - repoPath, - connectionId: connectionId ?? null, - ...localGitOptions - })), - acquireMock: vi.fn(), - releaseMock: vi.fn() -})) - -vi.mock('../../git/command-runner/hosted-cli/gh-exec-file', () => ({ - ghExecFileAsync: ghExecFileAsyncMock -})) - -vi.mock('../repositories/github-owner-repo-selection', () => ({ - getOwnerRepo: getOwnerRepoMock -})) - -vi.mock('../repositories/github-repository-identity', async (importOriginal) => ({ - ...(await importOriginal()), - getOwnerRepoForRemote: getOwnerRepoForRemoteMock, - ghRepoExecOptions: ghRepoExecOptionsMock, - githubRepoContext: githubRepoContextMock -})) - -vi.mock('../execution/github-operation-slots', () => ({ - acquire: acquireMock, - release: releaseMock -})) - -vi.mock('../client/fetch/get-work-item', async () => ({ - getWorkItem: getWorkItemMock, - getWorkItemWithRepository: ( - await vi.importActual('./work-item-details-test-lookup') - ).makeWorkItemDetailsLookupMock(getWorkItemMock), - getWorkItemByOwnerRepo: getWorkItemByOwnerRepoMock -})) - -vi.mock('../client/check/get-pr-checks', async () => ({ - getPRChecks: getPRChecksMock -})) - -vi.mock('../client/fetch/get-pr-comments', async () => ({ - getPRComments: getPRCommentsMock -})) - -vi.mock('../repositories/github-enterprise-repository', () => ({ - getEnterpriseGitHubRepoSlug: getEnterpriseGitHubRepoSlugMock, - getEnterpriseGitHubRepoSlugForRemote: getEnterpriseGitHubRepoSlugForRemoteMock, - isGitHubHostAuthenticated: vi.fn().mockResolvedValue(true) -})) - -vi.mock('../api/rate-limit', () => ({ - repositoryRateLimitGuard: repositoryRateLimitGuardMock, - noteRepositoryRateLimitSpend: noteRepositoryRateLimitSpendMock -})) - -import { getWorkItemDetails } from './work-item-details' - -import { _resetOriginGitHubApiRepositoryCache } from '../repositories/github-api-repository-remote-probe' - -beforeEach(() => { - _resetOriginGitHubApiRepositoryCache() -}) - -describe('getWorkItemDetails', () => { - beforeEach(() => { - ghExecFileAsyncMock.mockReset() - getOwnerRepoMock.mockReset() - getOwnerRepoForRemoteMock.mockReset() - getEnterpriseGitHubRepoSlugMock.mockReset() - getEnterpriseGitHubRepoSlugMock.mockResolvedValue(null) - getEnterpriseGitHubRepoSlugForRemoteMock.mockReset() - getEnterpriseGitHubRepoSlugForRemoteMock.mockResolvedValue(null) - getWorkItemMock.mockReset() - getWorkItemByOwnerRepoMock.mockReset() - getPRChecksMock.mockReset() - getPRCommentsMock.mockReset() - repositoryRateLimitGuardMock.mockReset() - repositoryRateLimitGuardMock.mockReturnValue({ blocked: false }) - noteRepositoryRateLimitSpendMock.mockReset() - ghRepoExecOptionsMock.mockClear() - githubRepoContextMock.mockClear() - acquireMock.mockReset() - releaseMock.mockReset() - acquireMock.mockResolvedValue(undefined) - }) - - it('caps issue timeline pagination by supported activity items', async () => { - getWorkItemMock.mockResolvedValueOnce({ - id: 'issue:923', - type: 'issue', - number: 923, - title: 'Use upstream issues', - state: 'open', - url: 'https://github.com/acme/widgets/issues/923', - labels: [], - updatedAt: '2026-04-01T00:00:00Z', - author: 'issue-author' - }) - getOwnerRepoForRemoteMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' }) - const makeTimelineEvent = (page: number, index: number, event: string): string => - JSON.stringify({ - id: `${page}:${index}`, - event, - actor: { login: 'issue-author', avatar_url: 'https://x/y' }, - assignee: { login: `assignee-${page}-${index}` }, - created_at: '2026-04-01T00:00:00Z' - }) - const makeTimelinePage = (page: number, supportedCount: number): string => - Array.from({ length: 100 }, (_, index) => - makeTimelineEvent(page, index, index < supportedCount ? 'assigned' : 'subscribed') - ).join('\n') - ghExecFileAsyncMock - .mockResolvedValueOnce({ - stdout: JSON.stringify({ - data: { - repository: { - issue: { - body: 'Issue body', - assignees: { nodes: [] }, - participants: { nodes: [] }, - comments: { nodes: [] } - } - } - } - }) - }) - .mockResolvedValueOnce({ stdout: makeTimelinePage(1, 0) }) - .mockResolvedValueOnce({ stdout: makeTimelinePage(2, 0) }) - .mockResolvedValueOnce({ stdout: makeTimelinePage(3, 10) }) - .mockResolvedValueOnce({ stdout: makeTimelinePage(4, 100) }) - .mockResolvedValueOnce({ stdout: makeTimelinePage(5, 100) }) - .mockResolvedValueOnce({ stdout: makeTimelinePage(6, 100) }) - - const details = await getWorkItemDetails('/repo-root', 923, 'issue') - - expect(ghExecFileAsyncMock).toHaveBeenCalledTimes(7) - expect(ghExecFileAsyncMock.mock.calls[1][0]).toContain( - 'repos/acme/widgets/issues/923/timeline?per_page=100&page=1' - ) - expect(ghExecFileAsyncMock.mock.calls[2][0]).toContain( - 'repos/acme/widgets/issues/923/timeline?per_page=100&page=2' - ) - expect(ghExecFileAsyncMock.mock.calls[3][0]).toContain( - 'repos/acme/widgets/issues/923/timeline?per_page=100&page=3' - ) - expect(ghExecFileAsyncMock.mock.calls[6][0]).toContain( - 'repos/acme/widgets/issues/923/timeline?per_page=100&page=6' - ) - expect( - ghExecFileAsyncMock.mock.calls.some((call) => - call[0].includes('repos/acme/widgets/issues/923/timeline?per_page=100&page=7') - ) - ).toBe(false) - const timelineItems = details?.timelineItems - if (!timelineItems) { - throw new Error('Expected timeline items to be present') - } - expect(timelineItems).toHaveLength(300) - expect(timelineItems.at(0)).toMatchObject({ assignee: 'assignee-3-0' }) - expect(timelineItems.at(-1)).toMatchObject({ assignee: 'assignee-6-89' }) - }) - - // Number-based detail lookups must retain the list's source, avoiding same-number fork/upstream collisions. -}) diff --git a/src/main/gitlab/projects/gitlab-known-host-probe.test.ts b/src/main/gitlab/projects/gitlab-known-host-probe.test.ts deleted file mode 100644 index e5fcfa29c8f..00000000000 --- a/src/main/gitlab/projects/gitlab-known-host-probe.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' - -const { glabExecFileAsyncMock } = vi.hoisted(() => ({ glabExecFileAsyncMock: vi.fn() })) - -vi.mock('../../git/command-runner/hosted-cli/glab-exec-file', async (importOriginal) => ({ - ...(await importOriginal>()), - glabExecFileAsync: glabExecFileAsyncMock -})) -import { - _resetKnownHostsCache, - getGlabKnownHosts, - rememberGlabKnownHost -} from './gitlab-known-host-probe' - -describe('getGlabKnownHosts', () => { - afterEach(() => vi.restoreAllMocks()) - - beforeEach(() => { - glabExecFileAsyncMock.mockReset() - _resetKnownHostsCache() - }) - - it('preserves a native auth refresh while an older native probe is in flight', async () => { - let resolveProbe!: (value: { stdout: string; stderr: string }) => void - glabExecFileAsyncMock.mockImplementationOnce( - () => - new Promise((resolve) => { - resolveProbe = resolve - }) - ) - - const staleProbe = getGlabKnownHosts() - rememberGlabKnownHost('gitlab.refreshed.test') - resolveProbe({ stdout: 'Logged in to gitlab.com as user\n', stderr: '' }) - - await expect(staleProbe).resolves.toEqual(['gitlab.com', 'gitlab.refreshed.test']) - await expect(getGlabKnownHosts()).resolves.toEqual(['gitlab.com', 'gitlab.refreshed.test']) - }) -}) diff --git a/src/main/ipc/filesystem/git-remote/rebase-fetch-error.test.ts b/src/main/ipc/filesystem/git-remote/rebase-fetch-error.test.ts deleted file mode 100644 index a4032513370..00000000000 --- a/src/main/ipc/filesystem/git-remote/rebase-fetch-error.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { afterEach, expect, it, vi } from 'vitest' - -type RebaseHandler = ( - event: unknown, - args: { worktreePath: string; baseRef: string } -) => Promise - -const { handlers, capture } = vi.hoisted(() => ({ - handlers: new Map(), - capture: vi.fn() -})) -vi.mock('electron', () => ({ - ipcMain: { handle: (channel: string, handler: RebaseHandler) => handlers.set(channel, handler) } -})) -vi.mock('../../../git/command-runner/process-capture/exec-file-capture', () => ({ - execFileCapture: capture, - execFileCaptureToTermination: capture -})) -vi.mock('../../../../shared/git/fetch/git-fetch-head-lock', async (importOriginal) => ({ - ...(await importOriginal>()), - runWithGitFetchHeadLock: (_cwd: string, _signal: AbortSignal | undefined, run: () => unknown) => - run() -})) -vi.mock('../../../../shared/git/worktrees/git-worktree-operation-lock', () => ({ - runWithGitWorktreeOperationLock: ( - _cwd: string, - _signal: AbortSignal | undefined, - run: () => unknown - ) => run() -})) - -import { registerGitRemoteBranchMutationHandlers } from './branch-mutation-handlers' - -afterEach(() => { - vi.useRealTimers() - vi.unstubAllEnvs() -}) - -it('surfaces the fetch diagnostic and retry guidance through the rebase IPC handler', async () => { - vi.useFakeTimers() - vi.stubEnv('GIT_SSH_COMMAND', 'ssh') - const original = Object.assign( - new Error('error: fetching ref refs/remotes/origin/main failed: incorrect old value provided'), - { - code: 1, - stderr: 'error: fetching ref refs/remotes/origin/main failed: incorrect old value provided' - } - ) - capture.mockImplementation((_command, args, options) => { - options.onChildTerminated() - if (args[0] === 'fetch') { - return Promise.reject(original) - } - return Promise.resolve({ stdout: args[0] === 'remote' ? 'origin\n' : '', stderr: '' }) - }) - const store = { - getRepos: () => [{ id: 'repo', path: '/repo', displayName: 'repo', badgeColor: '', addedAt: 0 }] - } - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: This handler only reads getRepos and checks optional runtime accessors. - registerGitRemoteBranchMutationHandlers({ store } as never) - const result = handlers.get('git:rebaseFromBase')!(null, { - worktreePath: '/repo', - baseRef: 'origin/main' - }) - const rejection = expect(result).rejects.toMatchObject({ - message: expect.stringMatching( - /fetching ref refs\/remotes\/origin\/main failed: incorrect old value provided[\s\S]+Another Git process updated remote references\. Try again\./ - ), - cause: expect.objectContaining({ cause: original }) - }) - await vi.runAllTimersAsync() - await rejection -}) diff --git a/src/main/ipc/filesystem/watcher-process/event-delivery/parcel-watcher-delivery-health.test.ts b/src/main/ipc/filesystem/watcher-process/event-delivery/parcel-watcher-delivery-health.test.ts deleted file mode 100644 index f8ac493a621..00000000000 --- a/src/main/ipc/filesystem/watcher-process/event-delivery/parcel-watcher-delivery-health.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { - acknowledgeWatcherSubscribe as ackSubscribe, - currentWatcherChild, - FakeWatcherChild as FakeChild -} from '../supervision/parcel-watcher-process-test-child' - -const { forkMock, existsSyncMock } = vi.hoisted(() => ({ - forkMock: vi.fn(), - existsSyncMock: vi.fn() -})) - -vi.mock('node:child_process', () => ({ fork: forkMock })) -vi.mock('node:fs', () => ({ - existsSync: existsSyncMock, - mkdtempSync: vi.fn(() => '/tmp/orca-watcher-canary-health-test'), - rmSync: vi.fn() -})) - -import { - CANARY_STALL_BACKOFF_INITIAL_MS, - CANARY_STALL_BACKOFF_MAX_MS -} from './parcel-watcher-delivery-canary' - -import { createWatcherProcessSupervisor } from '../parcel-watcher-process' - -describe('watcher delivery stall reporting', () => { - beforeEach(() => { - vi.useFakeTimers() - vi.stubEnv('VITEST', '') - vi.spyOn(console, 'error').mockImplementation(() => undefined) - existsSyncMock.mockReturnValue(true) - forkMock.mockImplementation(() => new FakeChild()) - }) - - afterEach(() => { - vi.useRealTimers() - vi.unstubAllEnvs() - vi.restoreAllMocks() - vi.clearAllMocks() - }) - - it('asks callers to rescan during a long stall and once more on recovery', async () => { - const supervisor = createWatcherProcessSupervisor() - const onOverflow = vi.fn() - const subscription = supervisor.subscribe('/repo', vi.fn(), {}, { onOverflow }) - const child = currentWatcherChild(forkMock) - ackSubscribe(child) - await subscription - - child.emit('message', { op: 'delivery-health', state: 'stalled' }) - // A stall shorter than one backoff period is ordinary latency. - await vi.advanceTimersByTimeAsync(CANARY_STALL_BACKOFF_INITIAL_MS - 1) - expect(onOverflow).not.toHaveBeenCalled() - - // Rescans back off with the canary: 30 s, then 60, 120, 240, capped at 300. - const rescanTimes: number[] = [] - onOverflow.mockImplementation(() => rescanTimes.push(Date.now())) - const stalledAt = Date.now() - (CANARY_STALL_BACKOFF_INITIAL_MS - 1) - await vi.advanceTimersByTimeAsync(20 * 60_000) - expect(rescanTimes.map((time) => (time - stalledAt) / 1000)).toEqual([ - 30, 90, 210, 450, 750, 1050 - ]) - - child.emit('message', { op: 'delivery-health', state: 'healthy' }) - expect(onOverflow).toHaveBeenCalledTimes(7) - await vi.advanceTimersByTimeAsync(CANARY_STALL_BACKOFF_MAX_MS * 2) - expect(onOverflow).toHaveBeenCalledTimes(7) - supervisor.dispose() - }) -}) diff --git a/src/main/ipc/filesystem/watcher-process/native-subscriptions/parcel-watcher-shallow-subscription.test.ts b/src/main/ipc/filesystem/watcher-process/native-subscriptions/parcel-watcher-shallow-subscription.test.ts deleted file mode 100644 index fb844005957..00000000000 --- a/src/main/ipc/filesystem/watcher-process/native-subscriptions/parcel-watcher-shallow-subscription.test.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { EventEmitter } from 'node:events' -import { statSync, watch } from 'node:fs' -import type * as Fs from 'node:fs' -import { mkdir, mkdtemp, rm, stat } from 'node:fs/promises' -import type * as FsPromises from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const { watcherState } = vi.hoisted(() => ({ - watcherState: new Map< - string, - { - callback: (eventType: string, fileName: string | Buffer | null) => void - watcher: EventEmitter & { close: () => void } - } - >() -})) - -vi.mock('node:fs', async () => { - const actual = await vi.importActual('node:fs') - return { - ...actual, - statSync: vi.fn(actual.statSync), - watch: vi.fn( - ( - path: string, - _options: unknown, - callback: (eventType: string, fileName: string | Buffer | null) => void - ) => { - const watcher = new EventEmitter() as EventEmitter & { close: () => void } - watcher.close = () => watcher.emit('close') - watcherState.set(path, { callback, watcher }) - return watcher - } - ) - } -}) -vi.mock('node:fs/promises', async () => { - const actual = await vi.importActual('node:fs/promises') - return { ...actual, stat: vi.fn(actual.stat) } -}) - -import { startShallowDirectoryWatcher } from './parcel-watcher-shallow-subscription' - -function emit(path: string, fileName: string): void { - watcherState.get(path)?.callback('change', fileName) -} - -describe('shallow watcher subscription', () => { - beforeEach(() => { - watcherState.clear() - vi.mocked(statSync).mockReset() - vi.mocked(stat).mockReset() - }) - - it('emits only included primary files, including an existing nested directory', async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-shallow-watcher-')) - try { - await mkdir(join(root, 'logs')) - const events: string[] = [] - const { promise, resolve } = Promise.withResolvers() - const subscription = startShallowDirectoryWatcher( - root, - ['HEAD', 'config', 'logs/HEAD'], - (nextEvents) => { - events.push(...nextEvents.map((event) => event.path)) - if ( - events.includes(join(root, 'config')) && - events.includes(join(root, 'logs', 'HEAD')) - ) { - resolve() - } - }, - (error) => { - throw error - } - ) - - emit(root, 'unrelated') - emit(join(root, 'logs'), 'unrelated') - emit(root, 'config') - emit(join(root, 'logs'), 'HEAD') - await promise - - expect(events).toContain(join(root, 'config')) - expect(events).toContain(join(root, 'logs', 'HEAD')) - expect(events).not.toContain(join(root, 'unrelated')) - expect(events).not.toContain(join(root, 'logs', 'unrelated')) - await subscription.unsubscribe() - } finally { - await rm(root, { recursive: true, force: true }) - } - }) - - it('does not forward events after unsubscribe', async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-shallow-watcher-')) - try { - const events: string[] = [] - const subscription = startShallowDirectoryWatcher( - root, - ['HEAD'], - (nextEvents) => events.push(...nextEvents.map((event) => event.path)), - (error) => { - throw error - } - ) - await subscription.unsubscribe() - emit(root, 'HEAD') - const { promise, resolve } = Promise.withResolvers() - setImmediate(resolve) - await promise - expect(events).toEqual([]) - } finally { - await rm(root, { recursive: true, force: true }) - } - }) - - it.skipIf(process.platform === 'win32')( - 'preserves a literal backslash in an included filename', - async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-shallow-watcher-')) - const events: string[] = [] - const subscription = startShallowDirectoryWatcher( - root, - ['plugin\\name'], - (nextEvents) => events.push(...nextEvents.map((event) => event.path)), - (error) => { - throw error - } - ) - try { - emit(root, 'plugin\\name') - expect(events).toEqual([join(root, 'plugin\\name')]) - } finally { - await subscription.unsubscribe() - await rm(root, { recursive: true, force: true }) - } - } - ) - - it('rebinds a nested directory that is replaced, which leaves fs.watch deaf', async () => { - const root = await mkdtemp(join(tmpdir(), 'orca-shallow-watcher-')) - try { - await mkdir(join(root, 'logs')) - const events: string[] = [] - const subscription = startShallowDirectoryWatcher( - root, - ['HEAD', 'logs/HEAD'], - (nextEvents) => events.push(...nextEvents.map((event) => event.path)), - (error) => { - throw error - } - ) - const firstNested = watcherState.get(join(root, 'logs'))?.watcher - - // A 'rename' for the nested dir means the inode was swapped, so the old - // binding is dead and must be replaced rather than reused. - watcherState.get(root)?.callback('rename', 'logs') - - expect(watcherState.get(join(root, 'logs'))?.watcher).not.toBe(firstNested) - events.length = 0 - emit(join(root, 'logs'), 'HEAD') - expect(events).toContain(join(root, 'logs', 'HEAD')) - await subscription.unsubscribe() - } finally { - await rm(root, { recursive: true, force: true }) - } - }) - - it('resyncs included files when an initially missing directory becomes watchable', async () => { - vi.useFakeTimers() - const root = await mkdtemp(join(tmpdir(), 'orca-shallow-watcher-')) - let subscription: ReturnType | undefined - try { - const defaultWatch = vi.mocked(watch).getMockImplementation() - if (!defaultWatch) { - throw new Error('Missing watcher test implementation') - } - vi.mocked(watch) - .mockImplementationOnce(defaultWatch) - .mockImplementationOnce(() => { - throw new Error('ENOENT: logs directory does not exist') - }) - const events: string[] = [] - subscription = startShallowDirectoryWatcher( - root, - ['HEAD', 'logs/HEAD'], - (nextEvents) => events.push(...nextEvents.map((event) => event.path)), - (error) => { - throw error - } - ) - const logs = join(root, 'logs') - await mkdir(logs) - await vi.advanceTimersByTimeAsync(30_000) - await vi.waitFor(() => expect(watcherState.has(logs)).toBe(true)) - - expect(events).toContain(join(logs, 'HEAD')) - } finally { - await subscription?.unsubscribe() - vi.useRealTimers() - await rm(root, { recursive: true, force: true }) - } - }) -}) diff --git a/src/main/kiro/hook-service.test.ts b/src/main/kiro/hook-service.test.ts index 89e5e79092d..b06991538c7 100644 --- a/src/main/kiro/hook-service.test.ts +++ b/src/main/kiro/hook-service.test.ts @@ -208,6 +208,4 @@ describe('KiroHookService', () => { expect(Object.keys(remote.hooks).sort()).toEqual([...KIRO_HOOK_EVENTS].sort()) expect(readAgent('stale').hooks).toBeUndefined() }) - - // Check command shapes everywhere; windows-hook-payload-delivery.test.ts executes them under Kiro's shells. }) diff --git a/src/main/plugins/workers/plugin-worker-manager.test.ts b/src/main/plugins/workers/plugin-worker-manager.test.ts deleted file mode 100644 index 3407dee86fa..00000000000 --- a/src/main/plugins/workers/plugin-worker-manager.test.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { PluginWorkerHandle } from './parent-process/plugin-host-process-types' -import { PluginWorkerManager } from './plugin-worker-manager' -import type { - PluginWorkerFactory, - PluginWorkerSpawnSpec -} from './worker-supervision/plugin-worker-startup' - -type TestWorker = PluginWorkerHandle & { - exit(code?: number | null): void - dispose: ReturnType Promise>> -} - -function worker(lastActivity = 1_000): TestWorker { - const exitCallbacks: ((code: number | null) => void)[] = [] - return { - commands: ['run'], - invokeCommand: vi.fn(async () => null), - deliverEvent: vi.fn(), - requestFromPanel: vi.fn(), - runHook: vi.fn(), - notifyDataChanged: vi.fn(), - lastActivityAt: () => lastActivity, - inFlightCount: () => 0, - dispose: vi.fn(async () => undefined), - kill: vi.fn(), - onExit: (callback) => exitCallbacks.push(callback), - exit: (code = 1) => { - for (const callback of exitCallbacks) { - callback(code) - } - } - } -} - -function spec(pluginKey: string): PluginWorkerSpawnSpec { - return { - pluginKey, - rootDir: `/plugins/${pluginKey}`, - mainEntry: 'worker.js', - grantedCapabilities: [] - } -} - -function manager( - factory: PluginWorkerFactory, - options: { maxActive?: number; idleReapMs?: number } = {} -): PluginWorkerManager { - return new PluginWorkerManager({ - entryPath: '/host.js', - workerFactory: factory, - maxActive: options.maxActive, - idleReapMs: options.idleReapMs, - executeHostCall: async () => ({ ok: true, value: null }), - log: () => vi.fn(), - onWorkerStateChange: vi.fn() - }) -} - -async function flush(): Promise { - await Promise.resolve() - await Promise.resolve() - await Promise.resolve() -} - -describe('PluginWorkerManager capacity', () => { - it('cancels an in-flight start without allowing its generation to land', async () => { - let finishStart!: (handle: PluginWorkerHandle) => void - const pendingStart = new Promise((resolve) => { - finishStart = resolve - }) - const factory = vi.fn(() => pendingStart) - const subject = manager(factory) - const lateWorker = worker() - const activation = subject.ensureActive(spec('starting')) - await flush() - - try { - const deactivation = subject.deactivate('starting') - finishStart(lateWorker) - await deactivation - - await expect(activation).rejects.toThrow('cancelled') - expect(lateWorker.dispose).toHaveBeenCalledOnce() - expect(subject.runState('starting')).toBe('inactive') - expect(subject.trackedSpecs().has('starting')).toBe(false) - } finally { - finishStart(lateWorker) - await subject.disposeAll() - } - }) -}) - -describe('PluginWorkerManager idle reap', () => { - afterEach(() => { - vi.useRealTimers() - }) - - it('does not count time the machine slept as idle time', async () => { - const minute = 60_000 - const busy = worker(2 * minute) - const subject = manager(vi.fn().mockResolvedValue(busy), { - idleReapMs: 5 * minute - }) - await subject.ensureActive(spec('demo')) - subject.reapIdle(2 * minute) - subject.reapIdle(3 * minute) - - // Lid closed for an hour: the next sweep is the first one after wake. - subject.reapIdle(63 * minute) - await flush() - - expect(busy.dispose).not.toHaveBeenCalled() - expect(subject.runState('demo')).toBe('running') - await subject.disposeAll() - }) - - it('does not count a sleep before the first sweep as idle time', async () => { - const minute = 60_000 - vi.useFakeTimers({ now: 0 }) - const busy = worker(0) - const subject = manager(vi.fn().mockResolvedValue(busy), { - idleReapMs: 5 * minute - }) - await subject.ensureActive(spec('demo')) - - // Lid closed before the reaper's first sweep, opened an hour later. - subject.reapIdle(60 * minute) - await flush() - - expect(busy.dispose).not.toHaveBeenCalled() - expect(subject.runState('demo')).toBe('running') - await subject.disposeAll() - }) - - it('still reaps a worker that stays idle for a full window after waking', async () => { - const minute = 60_000 - const idle = worker(2 * minute) - const subject = manager(vi.fn().mockResolvedValue(idle), { - idleReapMs: 5 * minute - }) - await subject.ensureActive(spec('demo')) - subject.reapIdle(3 * minute) - subject.reapIdle(63 * minute) - for (let at = 64; at <= 69; at++) { - subject.reapIdle(at * minute) - } - await flush() - - expect(idle.dispose).toHaveBeenCalledOnce() - expect(subject.runState('demo')).toBe('inactive') - await subject.disposeAll() - }) - - it('waits for an in-progress idle shutdown during manager disposal', async () => { - let finishShutdown!: () => void - const idle = worker(100) - idle.dispose.mockImplementation( - () => - new Promise((resolve) => { - finishShutdown = resolve - }) - ) - const subject = manager(vi.fn().mockResolvedValue(idle), { - idleReapMs: 100 - }) - await subject.ensureActive(spec('demo')) - subject.reapIdle(201) - let disposed = false - const disposal = subject.disposeAll().then(() => { - disposed = true - }) - await flush() - expect(disposed).toBe(false) - - finishShutdown() - await disposal - expect(disposed).toBe(true) - }) -}) diff --git a/src/main/ports/advertised-url-watcher.test.ts b/src/main/ports/advertised-url-watcher.test.ts deleted file mode 100644 index 1722ee7e9f3..00000000000 --- a/src/main/ports/advertised-url-watcher.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { AdvertisedUrlWatcher } from './advertised-url-watcher' - -const WORKTREE = 'repo::/repo' -const PTY = 'pty-1' - -function bindFresh(now = 1_000): AdvertisedUrlWatcher { - const watcher = new AdvertisedUrlWatcher({ now: () => now }) - watcher.bindPty(PTY, WORKTREE) - return watcher -} - -describe('extractUrlCandidates', () => { - it('does not cache a partial default-port URL from a cursor-skip redraw', () => { - const watcher = bindFresh() - watcher.ingest(PTY, 'Local: http://localh\x1b[1Cst/\n') - expect(watcher.lookup(WORKTREE, 80)).toBeUndefined() - }) -}) - -describe('AdvertisedUrlWatcher.ingest', () => { - it('reassembles a URL split across two chunks', () => { - const watcher = bindFresh() - watcher.ingest(PTY, ' Network: https://local.getmontecarlo') - expect(watcher.lookup(WORKTREE, 3001)).toBeUndefined() - watcher.ingest(PTY, '.com:3001/\n') - expect(watcher.lookup(WORKTREE, 3001)?.origin).toBe('https://local.getmontecarlo.com:3001') - }) - - it('sanitizes to origin (drops path, query, fragment, userinfo)', () => { - const watcher = bindFresh() - watcher.ingest(PTY, 'go to https://user:pass@example.com:3001/callback?token=secret#x\n') - expect(watcher.lookup(WORKTREE, 3001)?.origin).toBe('https://example.com:3001') - }) - - it('unbindPty drops buffered state for the PTY', () => { - const watcher = bindFresh() - watcher.ingest(PTY, 'cached https://cached.example.com:3002/\n') - watcher.ingest(PTY, 'partial https://example.com:3001') - const events: { worktreeId: string; port: number }[] = [] - watcher.onDidChange((event) => events.push(event)) - watcher.unbindPty(PTY) - watcher.bindPty(PTY, WORKTREE) - watcher.ingest(PTY, '/now\n') - expect(watcher.lookup(WORKTREE, 3001)).toBeUndefined() - expect(watcher.lookupBest([WORKTREE], 3002)).toBeUndefined() - expect(events).toContainEqual({ worktreeId: WORKTREE, port: 3002 }) - }) - - it('different worktrees on the same port are tracked independently', () => { - const watcher = bindFresh() - watcher.bindPty('pty-2', 'repo::/other') - watcher.ingest(PTY, 'A: https://a.example.com:3001/\n') - watcher.ingest('pty-2', 'B: https://b.example.com:3001/\n') - expect(watcher.lookup(WORKTREE, 3001)?.host).toBe('a.example.com') - expect(watcher.lookup('repo::/other', 3001)?.host).toBe('b.example.com') - }) -}) diff --git a/src/main/provider-process/managed-provider-process.test.ts b/src/main/provider-process/managed-provider-process.test.ts deleted file mode 100644 index e0a5adcd123..00000000000 --- a/src/main/provider-process/managed-provider-process.test.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { basename, dirname, join } from 'node:path' -import { PassThrough } from 'node:stream' -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { PipedProcessSpawner } from '@orca/process-host/process-spec' -import { createFakePipedChild } from '../../shared/__fixtures__/fake-spawned-child' -import { PROVIDER_SUPERVISOR_MAX_STOP_MS } from './provider-process-supervisor' -import { spawnManagedProviderProcess } from './managed-provider-process' - -const mocks = vi.hoisted(() => ({ - capture: vi.fn(async () => null), - windowsTree: vi.fn(async () => {}) -})) -vi.mock('../pty/process-retirement/pty-descendant-termination', () => ({ - captureDescendantSnapshot: mocks.capture -})) -vi.mock('../pty/process-retirement/windows-process-tree-kill', () => ({ - terminateWindowsProcessTree: mocks.windowsTree -})) - -afterEach(() => { - vi.useRealTimers() - vi.clearAllMocks() -}) - -function fakeChild(pid: number | null = 9_999_999) { - const child = Object.assign(createFakePipedChild(), { - pid: pid ?? undefined, - stdin: new PassThrough(), - stdout: new PassThrough(), - stderr: new PassThrough(), - kill: vi.fn(() => true) - }) - const spawn = vi.fn(() => { - return child - }) - return { child, spawn } -} - -function launch(fixture: ReturnType, platform: NodeJS.Platform = 'win32') { - return spawnManagedProviderProcess( - { command: 'fixture-provider', args: ['serve'], cwd: tmpdir() }, - { - spawnImpl: fixture.spawn, - platform, - site: 'fixture-provider-teardown', - acceptClose: (result) => result.root === 'exited', - policy: () => ({ gracefulExitMs: 100, forcedExitMs: 50 }) - } - ) -} - -describe('managed provider process', () => { - it('joins a close, keeps root live after the kill deadline, and retries on the same child', async () => { - vi.useFakeTimers() - const fixture = fakeChild() - const managed = launch(fixture) - const first = managed.close() - expect(managed.close()).toBe(first) - await vi.advanceTimersByTimeAsync(150) - await expect(first).resolves.toMatchObject({ root: 'live' }) - expect(fixture.child.kill).toHaveBeenCalledWith('SIGKILL') - expect(managed.rootVerdict).toBe('live') - fixture.child.kill.mockImplementation(() => { - fixture.child.emit('exit', null, 'SIGKILL') - return true - }) - const second = managed.close() - await vi.advanceTimersByTimeAsync(150) - await expect(second).resolves.toMatchObject({ root: 'exited' }) - expect(fixture.spawn).toHaveBeenCalledOnce() - expect(vi.getTimerCount()).toBe(0) - }) - - it('requires error then close for a processless spawn to settle', async () => { - const fixture = fakeChild(null) - const managed = launch(fixture) - expect(managed.rootVerdict).toBe('unverifiable') - fixture.child.emit('close', -2, null) - expect(managed.rootVerdict).toBe('unverifiable') - fixture.child.emit('error', new Error('ENOENT')) - expect(managed.rootVerdict).toBe('unverifiable') - fixture.child.emit('close', null, null) - expect(managed.processless).toBe(true) - expect(managed.rootVerdict).toBe('exited') - await expect(managed.close()).resolves.toMatchObject({ root: 'exited' }) - }) - - // Direct (Windows) and supervised (POSIX) spawns: Node names what it spawned, never the folder. - it.each(['win32', 'linux'] as const)( - 'names a deleted working folder, not the CLI, when a real %s spawn fails there', - async (platform) => { - const parent = mkdtempSync(join(tmpdir(), 'orca-provider-cwd-')) - try { - // Found on PATH, so only the missing folder can fail the spawn. - const managed = spawnManagedProviderProcess( - { command: basename(process.execPath), args: ['-e', ''], cwd: join(parent, 'deleted') }, - { - platform, - policy: () => ({ gracefulExitMs: PROVIDER_SUPERVISOR_MAX_STOP_MS, forcedExitMs: 50 }), - inheritedEnv: { PATH: dirname(process.execPath) }, - site: 'fixture-provider-missing-cwd' - } - ) - await managed.exitPromise - expect(managed.executableMissing).toBe(false) - expect(managed.spawnAbsence).toBe('launchFolder') - } finally { - rmSync(parent, { recursive: true, force: true }) - } - } - ) - - it('keeps the agent session that launched Orca out of a provider child', () => { - vi.stubEnv('CODEX_THREAD_ID', 'parent-thread') - vi.stubEnv('CODEX_WINDOWS_REGISTERED_CORE', '1') - vi.stubEnv('CODEX_HOME', '/home/user/.codex') - try { - const fixture = fakeChild() - launch(fixture) - const env = fixture.spawn.mock.calls[0][0].env - expect(env?.CODEX_THREAD_ID).toBeUndefined() - expect(env?.CODEX_WINDOWS_REGISTERED_CORE).toBeUndefined() - expect(env?.CODEX_HOME).toBe('/home/user/.codex') - } finally { - vi.unstubAllEnvs() - } - }) - - it('does not turn a transport close with an existing pid into Claude exit proof', () => { - const fixture = fakeChild() - const managed = launch(fixture) - fixture.child.emit('error', new Error('EPIPE')) - fixture.child.emit('close', 0, null) - expect(managed.rootVerdict).toBe('live') - expect(managed.processless).toBe(false) - }) -}) diff --git a/src/main/provider-process/provider-process-teardown.test.ts b/src/main/provider-process/provider-process-teardown.test.ts deleted file mode 100644 index 4555695ec7e..00000000000 --- a/src/main/provider-process/provider-process-teardown.test.ts +++ /dev/null @@ -1,151 +0,0 @@ -import type { ChildProcess } from 'node:child_process' -import { beforeEach, describe, expect, it, vi } from 'vitest' -import { resetSelfInitiatedTreeKillLogForTest } from '../crash-reporting/process-exits/self-initiated-tree-kill-log' -import type { DescendantTreeVerdict } from '../pty/process-retirement/pty-descendant-exit-verification' -import { terminateProviderProcessTree as terminateWithEvidence } from './provider-process-teardown' - -async function terminateProviderProcessTree(...args: Parameters) { - const verdict = await terminateWithEvidence(...args) - return typeof verdict === 'object' && verdict ? verdict.tree : verdict -} - -function child() { - return { - pid: 1234, - kill: vi.fn(() => true) - } -} - -describe('terminateProviderProcessTree', () => { - beforeEach(() => { - resetSelfInitiatedTreeKillLogForTest() - }) - - it('waits for the Windows tree kill before releasing the wrapper, and reports what taskkill reported', async () => { - const target = child() - const release = Promise.withResolvers() - const terminateWindowsTree = vi.fn(() => release.promise) - - const teardown = terminateWithEvidence(target, { - site: 'codex-app-server-teardown', - platform: 'win32', - terminateWindowsTree - }) - expect(target.kill).not.toHaveBeenCalled() - release.resolve(true) - await expect(teardown).resolves.toEqual({ tree: 'exited', killDelivered: true }) - - expect(terminateWindowsTree).toHaveBeenCalledWith(1234, { site: 'codex-app-server-teardown' }) - expect(target.kill).toHaveBeenCalledWith('SIGKILL') - }) - - it('waits for an owned POSIX snapshot before killing the wrapper', async () => { - const target = child() - const signalProcessGroup = vi.fn() - const snapshot = { rootPgid: 1234, descendants: [], capturedAtMs: 1 } - const release = Promise.withResolvers() - - const teardown = terminateProviderProcessTree(target, { - site: 'codex-app-server-teardown', - platform: 'darwin', - captureDescendants: async () => snapshot, - terminateDescendants: () => release.promise, - signalProcessGroup - }) - await vi.waitFor(() => expect(target.kill).toHaveBeenCalledWith('SIGSTOP')) - expect(target.kill).not.toHaveBeenCalledWith('SIGKILL') - release.resolve('exited') - await expect(teardown).resolves.toBe('exited') - - expect(target.kill).toHaveBeenLastCalledWith('SIGKILL') - expect(signalProcessGroup).toHaveBeenCalledWith(1234, 'SIGKILL') - }) - - // An intercepted ESRCH must exercise the default signal path without creating a false kill breadcrumb. - - it.each([ - ['live', 'live'], - ['unverifiable', 'unverifiable'] - ] as const)( - 'reports a %s descendant snapshot after killing anchored child groups and the held root', - async (observed, verdict) => { - const target = child() - const signalProcessGroup = vi.fn() - const signalProcess = vi.fn() - await expect( - terminateProviderProcessTree(target, { - site: 'codex-app-server-teardown', - platform: 'darwin', - captureDescendants: async () => ({ - rootPgid: 1234, - descendants: [ - { pid: 2000, ppid: 1234, pgid: 2000, startedAt: 'now' }, - { pid: 3000, ppid: 2000, pgid: 2000, startedAt: 'now' } - ], - capturedAtMs: 1 - }), - terminateDescendants: async () => observed, - signalProcessGroup, - signalProcess - }) - ).resolves.toBe(verdict) - expect(signalProcessGroup).toHaveBeenCalledWith(2000, 'SIGKILL') - expect(signalProcess).toHaveBeenCalledWith(2000, 'SIGKILL') - expect(signalProcess).not.toHaveBeenCalledWith(3000, 'SIGKILL') - expect(target.kill).toHaveBeenLastCalledWith('SIGKILL') - expect(signalProcess.mock.invocationCallOrder[0]).toBeLessThan( - target.kill.mock.invocationCallOrder.at(-1)! - ) - } - ) -}) - -it('counts the writer group kill, but never a supervisor-only kill, without an exit report', async () => { - const target = child() - const snapshot = { - rootPgid: 1234, - capturedAtMs: 1, - descendants: [{ pid: 5678, ppid: 1234, pgid: 5678, startedAt: 'now' }] - } - const deps = { - site: 'writer-kill-proof', - platform: 'linux' as const, - supervised: true, - captureDescendants: async () => snapshot, - terminateDescendants: async () => 'unverifiable' as const, - signalProcessGroup: vi.fn(), - signalProcess: vi.fn() - } - await expect(terminateWithEvidence(target, deps)).resolves.toEqual({ - tree: 'unverifiable', - killDelivered: true - }) - await expect( - terminateWithEvidence(child(), { ...deps, captureDescendants: async () => null }) - ).resolves.toBeNull() - await expect( - terminateWithEvidence(child(), { - ...deps, - signalProcessGroup: () => { - throw new Error('denied') - } - }) - ).resolves.toBe('unverifiable') -}) - -it.each([true, false])( - 'preserves taskkill=%s when exact-root cleanup throws', - async (delivered) => { - const target = child() - target.kill.mockImplementation(() => { - throw new Error('held root cleanup failed') - }) - await expect( - terminateWithEvidence(target, { - site: 'fixture-cleanup', - platform: 'win32', - terminateWindowsTree: async () => delivered - }) - ).resolves.toEqual(delivered ? { tree: 'exited', killDelivered: true } : 'unverifiable') - } -) diff --git a/src/main/providers/accounts/agent-auth-restart-preservation.test.ts b/src/main/providers/accounts/agent-auth-restart-preservation.test.ts deleted file mode 100644 index bea7a1ca5a3..00000000000 --- a/src/main/providers/accounts/agent-auth-restart-preservation.test.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' - -import { preserveAgentAuthBeforeRestart } from './agent-auth-restart-preservation' - -describe('preserveAgentAuthBeforeRestart', () => { - afterEach(() => { - vi.useRealTimers() - vi.restoreAllMocks() - }) - - it('does not release restart while the bounded WSL drain is still running', async () => { - vi.useFakeTimers() - let finishWslDrain!: () => void - let settled = false - const flushPendingOrThrowAsync = vi.fn() - - const preservation = preserveAgentAuthBeforeRestart({ - codexRuntimeHome: { - syncForCurrentSelection: vi.fn(), - syncActiveWslSelectionsBeforeRestart: vi.fn( - () => - new Promise((resolve) => { - finishWslDrain = resolve - }) - ) - }, - store: { flushPendingOrThrowAsync } - }).then(() => { - settled = true - }) - - await vi.advanceTimersByTimeAsync(2_000) - await vi.advanceTimersByTimeAsync(1) - expect(flushPendingOrThrowAsync).toHaveBeenCalledTimes(1) - expect(settled).toBe(false) - - finishWslDrain() - await preservation - expect(settled).toBe(true) - }) - - it('continues after the bounded WSL drain fails without logging secrets', async () => { - const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) - const flushPendingOrThrowAsync = vi.fn() - - await preserveAgentAuthBeforeRestart({ - codexRuntimeHome: { - syncForCurrentSelection: vi.fn(), - syncActiveWslSelectionsBeforeRestart: vi.fn(async () => { - throw new Error('wsl-token-secret') - }) - }, - store: { flushPendingOrThrowAsync } - }) - - expect(flushPendingOrThrowAsync).toHaveBeenCalledTimes(1) - expect(warn).toHaveBeenCalledWith( - '[agent-auth-restart] Codex auth preservation failed (Error); continuing restart/update' - ) - expect(JSON.stringify(warn.mock.calls)).not.toContain('token-secret') - }) - - it('checkpoints admitted state without waiting for ongoing edits when auth services are missing', async () => { - const flushPendingOrThrowAsync = vi.fn() - - await preserveAgentAuthBeforeRestart({ store: { flushPendingOrThrowAsync } }) - - expect(flushPendingOrThrowAsync).toHaveBeenCalledExactlyOnceWith({ - drainToStableGeneration: false - }) - }) - - it('logs secret-free warnings and does not throw when sync fails', async () => { - const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) - const flushPendingOrThrowAsync = vi.fn() - - await expect( - preserveAgentAuthBeforeRestart({ - codexRuntimeHome: { - syncForCurrentSelection: vi.fn(() => { - throw new Error('codex-token-secret') - }) - }, - store: { flushPendingOrThrowAsync } - }) - ).resolves.toBeUndefined() - - expect(flushPendingOrThrowAsync).toHaveBeenCalledTimes(1) - expect(warn).toHaveBeenCalledTimes(1) - expect(JSON.stringify(warn.mock.calls)).not.toContain('token-secret') - }) - - it('bounds a store flush that never settles', async () => { - vi.useFakeTimers() - const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) - const preservation = preserveAgentAuthBeforeRestart({ - store: { flushPendingOrThrowAsync: vi.fn(() => new Promise(() => {})) } - }) - - let settled = false - void preservation.then(() => { - settled = true - }) - await vi.advanceTimersByTimeAsync(1_999) - expect(settled).toBe(false) - expect(warn).not.toHaveBeenCalled() - await vi.advanceTimersByTimeAsync(1) - await preservation - - expect(warn).toHaveBeenCalledWith( - '[agent-auth-restart] Store persistence exceeded 2000ms; continuing restart/update' - ) - }) -}) diff --git a/src/main/pty/process-retirement/posix-pty-process-groups.test.ts b/src/main/pty/process-retirement/posix-pty-process-groups.test.ts deleted file mode 100644 index 02f3821dc41..00000000000 --- a/src/main/pty/process-retirement/posix-pty-process-groups.test.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' - -import type * as NodeFs from 'node:fs' -import type * as NodeFsPromises from 'node:fs/promises' - -const { - readFileMock, - readFileSyncMock, - recordSelfInitiatedTreeKillMock, - runProcessMock, - runProcessSyncMock -} = vi.hoisted(() => ({ - readFileMock: vi.fn(), - readFileSyncMock: vi.fn(), - recordSelfInitiatedTreeKillMock: vi.fn(), - runProcessMock: vi.fn(), - runProcessSyncMock: vi.fn() -})) -vi.mock('node:fs', async (importOriginal) => ({ - ...(await importOriginal()), - readFileSync: readFileSyncMock -})) -vi.mock('node:fs/promises', async (importOriginal) => ({ - ...(await importOriginal()), - readFile: readFileMock -})) -vi.mock('../../crash-reporting/process-exits/self-initiated-tree-kill-log', () => ({ - recordSelfInitiatedTreeKill: recordSelfInitiatedTreeKillMock -})) -vi.mock('@orca/process-host', () => ({ - runProcess: runProcessMock, - runProcessSync: runProcessSyncMock -})) -import { - forceKillPosixPtyProcessGroups, - getPosixPtyProcessGroups, - signalPosixPtyProcessGroups -} from './posix-pty-process-groups' -import { resetPosixPtyProcessTableDialectForTests } from './posix-pty-process-table' - -// `/proc//stat` fixture: fields after comm are state, ppid, pgrp, session, tty_nr, ... -const procStat = (pid: number, session: number, comm = 'bash'): string => - `${pid} (${comm}) S 1 ${pid} ${session} 34822 ${pid} 4194560 1 0 0 0 0 0 0 0 20 0 1 0 98765 0 0\n` -const procSessions = new Map() - -beforeEach(() => { - procSessions.clear() - readFileSyncMock.mockReset() - readFileMock.mockReset() - // Default fixture: each hundred-block of pids is one terminal session led by its round pid. - readFileSyncMock.mockImplementation((path: string) => { - const pid = Number(/^\/proc\/(\d+)\/stat$/.exec(path)?.[1]) - if (!pid) { - throw Object.assign(new Error('ENOENT'), { code: 'ENOENT' }) - } - return procStat(pid, procSessions.get(pid) ?? Math.floor(pid / 100) * 100) - }) - readFileMock.mockImplementation(async (path: string) => readFileSyncMock(path)) - recordSelfInitiatedTreeKillMock.mockReset() - runProcessMock.mockReset() - runProcessSyncMock.mockReset() - resetPosixPtyProcessTableDialectForTests() -}) - -const TABLE = ` - 100 100 ttys001 - 101 101 ttys001 - 102 101 ttys001 - 103 103 ttys001 - 200 200 ttys002 - 300 300 ?? -` -const BUSYBOX_TABLE = ` -PROCESS_ID PROCESS_GID TERMINAL_DEVICE_NUMBER -100 100 136,100 -101 101 136,100 -200 200 136,10 -201 201 136,10 -999 999 ? -` - -describe('ps selection compatibility', () => { - it('preserves full numeric terminal identity and the daemon terminal guard', () => { - expect(getPosixPtyProcessGroups(BUSYBOX_TABLE, 100, 999)).toEqual([101, 100]) - expect(getPosixPtyProcessGroups(BUSYBOX_TABLE, 200, 999)).toEqual([201, 200]) - expect(getPosixPtyProcessGroups(BUSYBOX_TABLE, 100, 101)).toBeNull() - }) -}) - -describe('POSIX PTY process-group termination', () => { - it.each([ - ['SIGSTOP', [99, 101, 103]], - ['SIGCONT', [101, 103, 99]] - ] as const)('orders shell and job groups safely for %s', async (signal, expected) => { - const signalProcessGroup = vi.fn() - await signalPosixPtyProcessGroups(100, signal, vi.fn(), { - platform: 'linux', - currentPid: 999, - readProcessTable: async () => TABLE.replace('100 100', '100 99'), - signalProcessGroup - }) - expect(signalProcessGroup.mock.calls.map(([pgid]) => pgid)).toEqual(expected) - }) - - it.each(['EPERM', 'ESRCH'])( - 'does not stop jobs when stopping the shell fails with %s', - async (code) => { - const error = Object.assign(new Error('stop failed'), { code }) - const signalProcessGroup = vi.fn(() => { - throw error - }) - const stop = signalPosixPtyProcessGroups(100, 'SIGSTOP', vi.fn(), { - platform: 'linux', - currentPid: 999, - readProcessTable: async () => TABLE, - signalProcessGroup - }) - await (code === 'ESRCH' - ? expect(stop).resolves.toBeUndefined() - : expect(stop).rejects.toThrow(error)) - expect(signalProcessGroup.mock.calls).toEqual([[100]]) - } - ) - - it('signals nothing when the root exits while the table is read', async () => { - // A reaped root frees its pid and TTY, so the table may now describe another terminal. - let rootExited = false - const fallback = vi.fn() - const signalProcessGroup = vi.fn() - - await forceKillPosixPtyProcessGroups(100, fallback, { - platform: 'darwin', - currentPid: 999, - readProcessTable: async () => { - rootExited = true - return TABLE - }, - ownsRoot: () => !rootExited, - signalProcessGroup - }) - - expect(signalProcessGroup).not.toHaveBeenCalled() - expect(fallback).not.toHaveBeenCalled() - }) -}) - -describe('Linux terminal session identity (#27337)', () => { - // Container devpts instances reuse pts numbers: tty alone cannot tell host pts/6 from a container's. - const COLLIDING_TABLE = ` -100 100 pts/6 Ss -101 101 pts/6 S+ -500 500 pts/6 Ss -501 500 pts/6 S -600 600 pts/6 Ss -` - - it('force-kills only groups in the shell session, not container processes on the same pts', async () => { - procSessions.set(500, 500).set(501, 500).set(600, 600) - const signalProcessGroup = vi.fn() - const fallback = vi.fn() - await forceKillPosixPtyProcessGroups(100, fallback, { - platform: 'linux', - currentPid: 999, - readProcessTable: async () => COLLIDING_TABLE, - signalProcessGroup - }) - expect(signalProcessGroup.mock.calls).toEqual([[101], [100]]) - expect(fallback).not.toHaveBeenCalled() - expect(readFileMock).toHaveBeenCalledWith('/proc/500/stat', 'utf8') - }) -}) diff --git a/src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts b/src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts deleted file mode 100644 index 2b1607c23e6..00000000000 --- a/src/main/pty/shell-startup/shell-startup-identity-scanner.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { - createShellStartupIdentityScanState, - drainShellStartupIdentityHeldBytes, - scanForShellStartupIdentity -} from './shell-startup-identity-scanner' - -describe('shell startup identity scanner', () => { - it('strips a split identity marker and returns its shell pid', () => { - const state = createShellStartupIdentityScanState() - expect(scanForShellStartupIdentity(state, 'before\x1b]777;orca-shell-st')).toEqual({ - output: 'before', - shellPid: null - }) - expect(scanForShellStartupIdentity(state, 'art:12345\x07after')).toEqual({ - output: 'after', - shellPid: 12345 - }) - }) - - it('forwards lookalikes unchanged', () => { - const state = createShellStartupIdentityScanState() - const input = 'a\x1b]777;orca-shell-start:nope\x07b' - expect(scanForShellStartupIdentity(state, input)).toEqual({ output: input, shellPid: null }) - }) - - it('forwards an unrelated OSC ending in digits', () => { - const state = createShellStartupIdentityScanState() - const input = '\x1b]1337;remote-session:12345' - expect(scanForShellStartupIdentity(state, input)).toEqual({ output: input, shellPid: null }) - expect(state.heldBytes).toBe('') - }) - - it('releases an incomplete marker on teardown', () => { - const state = createShellStartupIdentityScanState() - scanForShellStartupIdentity(state, '\x1b]777;orca-shell-start:12') - expect(drainShellStartupIdentityHeldBytes(state)).toBe('\x1b]777;orca-shell-start:12') - }) - - it('does not retain an unbounded digit stream', () => { - const state = createShellStartupIdentityScanState() - const input = `\x1b]777;orca-shell-start:${'1'.repeat(100)}` - expect(scanForShellStartupIdentity(state, input).output).toBe(input) - expect(state.heldBytes).toBe('') - }) -}) diff --git a/src/main/rate-limits/providers/grok/grok-auth.test.ts b/src/main/rate-limits/providers/grok/grok-auth.test.ts deleted file mode 100644 index 646519c9f54..00000000000 --- a/src/main/rate-limits/providers/grok/grok-auth.test.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' - -describe('readGrokAuthSession', () => { - afterEach(() => { - vi.resetModules() - vi.doUnmock('node:fs') - }) - - it('redacts filesystem paths from auth read failures', async () => { - vi.doMock('node:fs', () => ({ - existsSync: vi.fn(() => true), - readFileSync: vi.fn(() => { - throw new Error( - 'EACCES: permission denied, open /Users/brennanbenson/private/.grok/auth.json' - ) - }) - })) - const { readGrokAuthSession } = await import('./grok-auth') - - expect(readGrokAuthSession()).toEqual({ - status: 'error', - error: 'Unable to read Grok auth file' - }) - }) - - it('reports malformed auth JSON without parser details', async () => { - vi.doMock('node:fs', () => ({ - existsSync: vi.fn(() => true), - readFileSync: vi.fn(() => '{') - })) - const { readGrokAuthSession } = await import('./grok-auth') - - expect(readGrokAuthSession()).toEqual({ - status: 'error', - error: 'Grok auth file is invalid' - }) - }) - - it.each(['https://auth.x.ai', 'https://auth.x.ai::client'])( - 'prefers the %s issuer entry over an earlier alternate issuer', - async (preferredIssuer) => { - vi.doMock('node:fs', () => ({ - existsSync: vi.fn(() => true), - readFileSync: vi.fn(() => - JSON.stringify({ - 'https://stale.example.com::client': { - key: 'stale-token', - user_id: 'stale-user', - email: 'stale@example.com', - expires_at: '2099-01-01T00:00:00.000Z' - }, - [preferredIssuer]: { - key: 'live-token', - user_id: 'live-user', - email: 'live@example.com', - team_id: 'team-1', - expires_at: '2099-06-01T00:00:00.000Z', - oidc_client_id: 'client-1' - } - }) - ) - })) - const { readGrokAuthSession } = await import('./grok-auth') - - expect(readGrokAuthSession()).toEqual({ - status: 'ok', - session: { - accessToken: 'live-token', - userId: 'live-user', - email: 'live@example.com', - teamId: 'team-1', - expiresAtMs: Date.parse('2099-06-01T00:00:00.000Z'), - oidcClientId: 'client-1' - } - }) - } - ) - - it('skips an expired auth.x.ai client entry when a fresh one follows it', async () => { - vi.doMock('node:fs', () => ({ - existsSync: vi.fn(() => true), - readFileSync: vi.fn(() => - JSON.stringify({ - 'https://auth.x.ai::old-client': { - key: 'expired-token', - expires_at: '2020-01-01T00:00:00.000Z' - }, - 'https://auth.x.ai::current-client': { - key: 'fresh-token', - expires_at: '2099-01-01T00:00:00.000Z' - } - }) - ) - })) - const { readGrokAuthSession } = await import('./grok-auth') - - expect(readGrokAuthSession()).toMatchObject({ - status: 'ok', - session: { accessToken: 'fresh-token' } - }) - }) - - it('does not resurrect an alternate issuer when an auth.x.ai entry is tokenless', async () => { - vi.doMock('node:fs', () => ({ - existsSync: vi.fn(() => true), - readFileSync: vi.fn(() => - JSON.stringify({ - 'https://alternate.example.com::client': { key: 'stale-token' }, - 'https://auth.x.ai::client': { user_id: 'signed-out-user' } - }) - ) - })) - const { readGrokAuthSession } = await import('./grok-auth') - - expect(readGrokAuthSession()).toEqual({ status: 'missing' }) - }) -}) diff --git a/src/main/runtime/agent-session/records/agent-session-conversation-name-store.test.ts b/src/main/runtime/agent-session/records/agent-session-conversation-name-store.test.ts deleted file mode 100644 index cc66992c1bd..00000000000 --- a/src/main/runtime/agent-session/records/agent-session-conversation-name-store.test.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { mkdtemp, rm } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import type { AgentSessionExecutionLocation } from '../../../../shared/agent-session/lifecycle/agent-session-record' -import type { AgentSessionRecordStore } from './agent-session-record-store' -import { - closeTestAgentSessionRecordStores, - openTestAgentSessionRecordStore -} from './agent-session-record-store-test-harness' -import type { AgentSessionReserveRequest } from '../ownership/agent-session-reservation-admission' - -const NOW = 1_800_000_000_000 -const SESSION = 'session-alpha' -const NATIVE: AgentSessionExecutionLocation = { - executionHostId: 'local', - wslDistro: null, - workspaceId: 'workspace-1', - workspaceKind: 'git-worktree' -} - -let counter = 0 -function operationId(): string { - counter += 1 - return `${NOW}-${String(counter) - .padStart(32, '0') - .replaceAll(/[^0-9a-f]/g, '0')}` -} - -const reserveRequest = (): AgentSessionReserveRequest => ({ - sessionId: SESSION, - location: NATIVE, - provider: 'claude', - accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude-work' }, - expectedFence: null, - spawnToken: 'spawn-a', - claimKeyId: 'key-1', - handoffOperationId: null, - probe: { outcome: 'indeterminate', reason: 'no answer' }, - operation: { callerKey: 'client-1', operationId: operationId(), fingerprint: 'fp-1' }, - now: NOW -}) - -let directory: string - -beforeEach(async () => { - directory = await mkdtemp(join(tmpdir(), 'orca-conversation-name-store-')) -}) -afterEach(async () => { - await closeTestAgentSessionRecordStores() - await rm(directory, { recursive: true, force: true }) -}) - -async function reservedStore(): Promise { - const store = await openTestAgentSessionRecordStore(directory) - await store.reserveOwner(reserveRequest()) - return store -} - -describe('AgentSessionRecordStore.setConversationName', () => { - it('stores the name and survives a reload, so the record is where it lives', async () => { - const store = await reservedStore() - - await store.setConversationName(SESSION, 'Fix the lease probe') - - const reloaded = await openTestAgentSessionRecordStore(directory, { mode: 'observe' }) - expect(reloaded.getRecord(SESSION)?.conversationName).toBe('Fix the lease probe') - }) - - it('normalizes at the boundary, so no caller can persist an invalid record', async () => { - const store = await reservedStore() - - await store.setConversationName(SESSION, `Fix\nthe ${'x'.repeat(400)}`) - - const name = store.getRecord(SESSION)?.conversationName ?? '' - expect(name).toHaveLength(200) - expect(name.startsWith('Fix the ')).toBe(true) - // Reload validates rows; oversized names must not make the record unreadable. - const reloaded = await openTestAgentSessionRecordStore(directory, { mode: 'observe' }) - expect(reloaded.getRecord(SESSION)?.conversationName).toBe(name) - }) - - it('compares against the committed name before applying a generated title', async () => { - const store = await reservedStore() - await store.compareAndSetConversationName(SESSION, 'First prompt', null) - await store.setConversationName(SESSION, 'Manual name') - const stale = await store.compareAndSetConversationName( - SESSION, - 'Late generated name', - 'First prompt' - ) - expect(stale).toBeNull() - expect(store.getRecord(SESSION)?.conversationName).toBe('Manual name') - await store.compareAndSetConversationName(SESSION, 'Generated name', 'Manual name') - expect(store.getRecord(SESSION)?.conversationName).toBe('Generated name') - const stillNamed = await store.compareAndSetConversationName( - SESSION, - 'Another placeholder', - null - ) - expect(stillNamed).toBeNull() - }) - - it('reports a failed seed even when another writer stored the same placeholder', async () => { - const store = await reservedStore() - const placeholder = 'First prompt' - expect(await store.compareAndSetConversationName(SESSION, placeholder, null)).toMatchObject({ - conversationName: placeholder - }) - expect(await store.compareAndSetConversationName(SESSION, placeholder, null)).toBeNull() - expect( - await store.compareAndSetConversationName(SESSION, 'Generated name', placeholder) - ).toMatchObject({ conversationName: 'Generated name' }) - expect( - await store.compareAndSetConversationName(SESSION, 'Stale generation', placeholder) - ).toBeNull() - }) - - it('checks a stale generation against the saved user name before writing', async () => { - const store = await reservedStore() - await store.compareAndSetConversationName(SESSION, 'First prompt', null) - const stale = await openTestAgentSessionRecordStore(directory, { mode: 'observe' }) - await store.setUserConversationName(SESSION, 'First prompt', 'rename') - - expect( - await stale.compareAndSetConversationName(SESSION, 'Late generated name', 'First prompt') - ).toBeNull() - await stale.pinLaunchDirectory(SESSION, '/workspace/current') - expect( - (await openTestAgentSessionRecordStore(directory, { mode: 'observe' })).getRecord(SESSION) - ).toMatchObject({ - conversationName: 'First prompt', - conversationNameSource: 'user', - launchDirectory: '/workspace/current' - }) - }) -}) diff --git a/src/main/runtime/browser-host/leases/browser-host-request-registry.test.ts b/src/main/runtime/browser-host/leases/browser-host-request-registry.test.ts deleted file mode 100644 index 51eefb4ce6e..00000000000 --- a/src/main/runtime/browser-host/leases/browser-host-request-registry.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { BrowserClientHostRequestEvent } from '../../../../shared/browser/client-hosting/browser-client-host-request-protocol' -import { BrowserHostRequestRegistry } from './browser-host-request-registry' - -function desktop(requests: BrowserHostRequestRegistry, pairedDeviceId: string) { - const asked: BrowserClientHostRequestEvent[] = [] - const unregister = requests.register({ pairedDeviceId, emit: (event) => asked.push(event) }) - const answer = (browserHostClientId?: string) => { - const request = asked.at(-1) - if (!request) { - throw new Error(`${pairedDeviceId} was not asked`) - } - return requests.settle( - { pairedDeviceId }, - { requestId: request.requestId, ...(browserHostClientId ? { browserHostClientId } : {}) } - ) - } - return { asked, answer, unregister } -} - -const flush = () => new Promise((resolve) => setTimeout(resolve, 0)) - -afterEach(() => { - vi.useRealTimers() -}) - -describe('BrowserHostRequestRegistry with two paired desktops', () => { - it('asks only the newest desktop, so one lease answers concurrent pages', async () => { - const requests = new BrowserHostRequestRegistry() - const older = desktop(requests, 'device-a') - const newer = desktop(requests, 'device-b') - - const first = requests.request() - const second = requests.request() - // A device cannot answer a request sent to another. - const sentToNewer = { - requestId: newer.asked[0]?.requestId ?? '', - browserHostClientId: 'host-a' - } - expect(requests.settle({ pairedDeviceId: 'device-a' }, sentToNewer)).toBe(false) - expect(newer.answer('host-b')).toBe(true) - - const expected = { browserHostClientId: 'host-b', pairedDeviceId: 'device-b' } - await expect(first).resolves.toEqual(expected) - await expect(second).resolves.toEqual(expected) - expect(newer.asked).toHaveLength(1) - expect(older.asked).toHaveLength(0) - }) - - it('asks the other desktop when the newest declines', async () => { - const requests = new BrowserHostRequestRegistry() - const older = desktop(requests, 'device-a') - const newer = desktop(requests, 'device-b') - - const hosted = requests.request() - newer.answer() - await flush() - older.answer('host-a') - - await expect(hosted).resolves.toEqual({ - browserHostClientId: 'host-a', - pairedDeviceId: 'device-a' - }) - }) - - // A silent desktop may still take its lease; asking another would leave two and make selection ambiguous. - it('never asks a second desktop after the first goes silent', async () => { - vi.useFakeTimers() - const requests = new BrowserHostRequestRegistry({ desktopTimeoutMs: 1_000 }) - const older = desktop(requests, 'device-a') - desktop(requests, 'device-b') - - const timedOut = requests.request() - const rejected = expect(timedOut).rejects.toThrow('browser_host_unavailable') - await vi.advanceTimersByTimeAsync(1_000) - - await rejected - expect(older.asked).toHaveLength(0) - }) -}) - -describe('BrowserHostRequestRegistry with a sleeping desktop', () => { - it('fails at once on a desktop that missed its last ask, until it answers again', async () => { - vi.useFakeTimers() - const requests = new BrowserHostRequestRegistry({ desktopTimeoutMs: 1_000 }) - const sleeping = desktop(requests, 'device-a') - - const timedOut = expect(requests.request()).rejects.toThrow('browser_host_unavailable') - await vi.advanceTimersByTimeAsync(1_000) - await timedOut - - const again = requests.request() - expect(sleeping.asked).toHaveLength(1) - await expect(again).rejects.toThrow('browser_host_unavailable') - - // Its late answer to the missed ask shows it is awake. - expect(sleeping.answer()).toBe(false) - const hosted = requests.request() - expect(sleeping.asked).toHaveLength(2) - sleeping.answer('host-a') - await expect(hosted).resolves.toEqual({ - browserHostClientId: 'host-a', - pairedDeviceId: 'device-a' - }) - }) - - it('hands a pending ask to the subscription a waking desktop opens', async () => { - const requests = new BrowserHostRequestRegistry() - const halfOpen = desktop(requests, 'device-a') - const hosted = requests.request() - expect(halfOpen.asked).toHaveLength(1) - - const reconnected = desktop(requests, 'device-a') - expect(reconnected.answer('host-a')).toBe(true) - - await expect(hosted).resolves.toEqual({ - browserHostClientId: 'host-a', - pairedDeviceId: 'device-a' - }) - }) -}) diff --git a/src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts b/src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts deleted file mode 100644 index 796ee0f44ee..00000000000 --- a/src/main/runtime/browser-host/reconciliation/browser-host-page-retirement.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { BrowserHostPagePlacementRegistry } from './browser-host-page-placement' - -const host = { - browserHostClientId: 'host-a', - browserHostGeneration: 1 -} - -const registry = (maxPagePlacements = 256): BrowserHostPagePlacementRegistry => - new BrowserHostPagePlacementRegistry( - { authorityRuntimeId: 'runtime-a', authorityEpoch: 'epoch-a' }, - { maxPagePlacements } - ) - -const authority = (pageHostGeneration: number) => ({ - authorityRuntimeId: 'runtime-a', - authorityEpoch: 'epoch-a', - browserPageId: 'page-a', - browserHostClientId: 'host-a', - browserHostGeneration: 1, - pageHostGeneration -}) - -describe('browser page retirement settlement', () => { - it('fences a live client page while retirement is pending', () => { - const pages = registry() - const placement = pages.placeClientPage('page-a', host) - const retirement = pages.beginPageRetirement('page-a', placement) - - expect(pages.beginPageRetirement('page-a', placement)).toBe(retirement) - expect(() => pages.requireClientPage(authority(1))).toThrow('browser_page_retirement_pending') - expect(() => pages.requireClientPage(authority(2))).toThrow('browser_page_placement_stale') - expect(() => pages.placeClientPage('page-a', host)).toThrow( - 'browser_page_replacement_requires_retirement' - ) - expect(() => pages.placeServerPage('page-a')).toThrow( - 'browser_page_replacement_requires_retirement' - ) - expect(pages.getPlacement('page-a')).toBe(placement) - }) - - it('cancels exact retirement and rejects its delayed settlement', () => { - const pages = registry() - const placement = pages.placeClientPage('page-a', host) - const first = pages.beginPageRetirement('page-a', placement) - - expect(pages.cancelPageRetirement(first)).toBe(true) - expect(pages.requireClientPage(authority(1))).toBe(placement) - expect(pages.cancelPageRetirement(first)).toBe(false) - expect(pages.completePageRetirement(first)).toBe(false) - - const replacement = pages.beginPageRetirement('page-a', placement) - expect(replacement).not.toBe(first) - expect(pages.completePageRetirement(first)).toBe(false) - expect(pages.getPlacement('page-a')).toBe(placement) - expect(pages.cancelPageRetirement(replacement)).toBe(true) - expect(pages.requireClientPage(authority(1))).toBe(placement) - }) - - it('completes only exact retirement and preserves page generations', () => { - const pages = registry() - const placement = pages.placeClientPage('page-a', host) - const retirement = pages.beginPageRetirement('page-a', placement) - - expect(pages.completePageRetirement(retirement)).toBe(true) - expect(pages.getPlacement('page-a')).toBeUndefined() - expect(pages.completePageRetirement(retirement)).toBe(false) - - const replacement = pages.placeClientPage('page-a', host) - expect(replacement.pageHostGeneration).toBe(placement.pageHostGeneration + 1) - expect(() => pages.beginPageRetirement('page-a', placement)).toThrow( - 'browser_page_placement_stale' - ) - expect(pages.getPlacement('page-a')).toBe(replacement) - }) - - it('serializes completion against cancellation and recursive completion', () => { - const pages = registry() - const placement = pages.placeClientPage('page-a', host) - const retirement = pages.beginPageRetirement('page-a', placement) - let cancellationAccepted = true - - expect( - pages.completePageRetirement(retirement, () => { - cancellationAccepted = pages.cancelPageRetirement(retirement) - expect(() => pages.completePageRetirement(retirement)).toThrow( - 'browser_page_retirement_completion_pending' - ) - }) - ).toBe(true) - expect(cancellationAccepted).toBe(false) - expect(pages.getPlacement('page-a')).toBeUndefined() - }) - - it('leaves failed completion pending and retryable', () => { - const pages = registry() - const placement = pages.placeClientPage('page-a', host) - const retirement = pages.beginPageRetirement('page-a', placement) - - expect(() => - pages.completePageRetirement(retirement, () => { - throw new Error('destroy failed') - }) - ).toThrow('destroy failed') - expect(() => pages.requireClientPage(authority(1))).toThrow('browser_page_retirement_pending') - expect(pages.completePageRetirement(retirement)).toBe(true) - }) -}) diff --git a/src/main/runtime/construction/orca-runtime.test.ts b/src/main/runtime/construction/orca-runtime.test.ts index fa08c434067..c4c74c98e1e 100644 --- a/src/main/runtime/construction/orca-runtime.test.ts +++ b/src/main/runtime/construction/orca-runtime.test.ts @@ -25,7 +25,6 @@ await import('../orca-runtime-tests/local-worktree-creation-part-02.spec') await import('../orca-runtime-tests/hooks-and-hosted-review-part-02.spec') await import('../orca-runtime-tests/repository-project-operations-part-02.spec') await import('../orca-runtime-tests/project-setup-folder-remote-identity.spec') -await import('../orca-runtime-tests/terminal-side-effect-facts.spec') await import('../orca-runtime-tests/terminal-side-effect-facts-part-02.spec') await import('../orca-runtime-tests/headless-snapshots.spec') await import('../orca-runtime-tests/agent-status-and-waits-part-02.spec') diff --git a/src/main/runtime/events/event-listener-fanout.test.ts b/src/main/runtime/events/event-listener-fanout.test.ts deleted file mode 100644 index 8fc6717aab5..00000000000 --- a/src/main/runtime/events/event-listener-fanout.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { EventEmitter } from 'node:events' -import { describe, expect, it, vi } from 'vitest' -import { addFanoutListener, addFanoutListeners } from './event-listener-fanout' - -describe('addFanoutListener', () => { - it('shares one native listener across overlapping subscribers and returns to baseline', () => { - const source = new EventEmitter() - const callbacks = Array.from({ length: 25 }, () => vi.fn()) - const releases = callbacks.map((callback) => addFanoutListener(source, 'destroyed', callback)) - - expect(source.listenerCount('destroyed')).toBe(1) - source.emit('destroyed', 'arg') - for (const callback of callbacks) { - expect(callback).toHaveBeenCalledWith('arg') - } - - for (const release of releases.slice(1)) { - release() - } - expect(source.listenerCount('destroyed')).toBe(1) - releases[0]() - releases[0]() - expect(source.eventNames()).toEqual([]) - }) - - it('lets the same callback subscribe twice without one release dropping the other', () => { - const source = new EventEmitter() - const callback = vi.fn() - const releaseFirst = addFanoutListener(source, 'closed', callback) - addFanoutListener(source, 'closed', callback) - - releaseFirst() - source.emit('closed') - - expect(callback).toHaveBeenCalledTimes(1) - }) - - it('skips subscribers released by an earlier callback in the same dispatch', () => { - const source = new EventEmitter() - const second = vi.fn() - let releaseSecond = (): void => {} - addFanoutListener(source, 'destroyed', () => releaseSecond()) - releaseSecond = addFanoutListener(source, 'destroyed', second) - - source.emit('destroyed') - - expect(second).not.toHaveBeenCalled() - }) - - it('reattaches a fresh native listener after the last subscriber left', () => { - const source = new EventEmitter() - addFanoutListener(source, 'destroyed', vi.fn())() - const callback = vi.fn() - addFanoutListener(source, 'destroyed', callback) - - source.emit('destroyed') - - expect(source.listenerCount('destroyed')).toBe(1) - expect(callback).toHaveBeenCalledOnce() - }) -}) - -describe('addFanoutListeners', () => { - it('releases every event with one call', () => { - const source = new EventEmitter() - const release = addFanoutListeners(source, ['destroyed', 'render-process-gone'], vi.fn()) - - expect(source.eventNames().sort()).toEqual(['destroyed', 'render-process-gone']) - release() - release() - - expect(source.eventNames()).toEqual([]) - }) -}) diff --git a/src/main/runtime/orca-runtime-tests/terminal-side-effect-facts.spec.ts b/src/main/runtime/orca-runtime-tests/terminal-side-effect-facts.spec.ts deleted file mode 100644 index 6e3554404ed..00000000000 --- a/src/main/runtime/orca-runtime-tests/terminal-side-effect-facts.spec.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import './bind-first-pane.test-fixture' -import './runtime-test-module-registration.spec' -import '../orca-runtime' -import type { RuntimeClientEvent } from '../../../shared/remote-runtime/session-graph/runtime-client-events' -import { syncSinglePty } from './orca-runtime-test-fixtures.spec' -import { createSideEffectRuntime } from './orca-runtime-test-scenario-builders.spec' -import { DECORATIVE_TITLE_FACT_HEARTBEAT_MS } from '../terminal/output/decorative-title-fact-emission' - -describe('terminal side-effect fact channel', () => { - it('bounds decorative title delivery per paired client below the local heartbeat', () => { - // Clear the local heartbeat each round so only the per-client gate can collapse repeats. - vi.useFakeTimers({ toFake: ['Date'] }) - try { - const { runtime, batches } = createSideEffectRuntime() - const firstClientEvents: RuntimeClientEvent[] = [] - runtime.attachWindow(1) - runtime.syncWindowGraph(1, { tabs: [], leaves: [] }) - runtime.onClientEvent((event) => firstClientEvents.push(event)) - - const ptyIds = Array.from({ length: 64 }, (_, index) => `pty-remote-${index}`) - const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] - const stepPastHeartbeat = (): void => { - vi.setSystemTime(new Date(Date.now() + DECORATIVE_TITLE_FACT_HEARTBEAT_MS)) - } - for (const ptyId of ptyIds) { - runtime.ingestSyntheticTitleFrame(ptyId, `\x1b]0;${frames[0]} Cursor Agent\x07`) - } - firstClientEvents.length = 0 - - for (const frame of frames.slice(1)) { - stepPastHeartbeat() - for (const ptyId of ptyIds) { - runtime.ingestSyntheticTitleFrame(ptyId, `\x1b]0;${frame} Cursor Agent\x07`) - } - } - - expect(firstClientEvents).toEqual([]) - expect(batches).toHaveLength(ptyIds.length * frames.length) - - const bellChunk = `\x1b]0;${frames.at(-1)} Cursor Agent\x07\x07` - runtime.onPtyData(ptyIds[0], bellChunk, 1) - expect(firstClientEvents).toEqual([ - expect.objectContaining({ - type: 'terminalSideEffects', - batch: expect.objectContaining({ facts: [{ kind: 'bell' }] }) - }) - ]) - firstClientEvents.length = 0 - - const secondClientEvents: RuntimeClientEvent[] = [] - runtime.onClientEvent((event) => secondClientEvents.push(event)) - stepPastHeartbeat() - for (const ptyId of ptyIds) { - runtime.ingestSyntheticTitleFrame(ptyId, `\x1b]0;${frames[0]} Cursor Agent\x07`) - } - - expect(firstClientEvents).toEqual([]) - expect(secondClientEvents).toHaveLength(ptyIds.length) - - for (const ptyId of ptyIds) { - runtime.ingestSyntheticTitleFrame(ptyId, '\x1b]0;Cursor ready\x07') - } - expect(firstClientEvents).toHaveLength(ptyIds.length) - expect(secondClientEvents).toHaveLength(ptyIds.length * 2) - } finally { - vi.useRealTimers() - } - }) - - it('does not confirm an agent exit from a foreground read predating its title', async () => { - const { runtime, batches } = createSideEffectRuntime() - syncSinglePty(runtime) - let resolveStaleRead!: (process: string) => void - const staleRead = new Promise((resolve) => { - resolveStaleRead = resolve - }) - const getForegroundProcess = vi.fn().mockReturnValueOnce(staleRead).mockResolvedValueOnce('zsh') - runtime.setPtyController({ - write: () => true, - kill: () => true, - getForegroundProcess - }) - - runtime.ingestSyntheticTitleFrame('pty-1', '\x1b]0;Codex ready\x07') - runtime.onPtyData('pty-1', '\x1b]0;bichir\x07', 100) - expect(getForegroundProcess).toHaveBeenCalledOnce() - - resolveStaleRead('codex') - - await vi.waitFor(() => expect(getForegroundProcess).toHaveBeenCalledTimes(2)) - await vi.waitFor(() => - expect(batches.flatMap((batch) => batch.facts)).toContainEqual({ kind: 'agent-exited' }) - ) - }) - - it('aligns a restored session and pre-response bytes to the provider sequence', async () => { - const { runtime } = createSideEffectRuntime() - - // Simulate a stream-socket byte winning the race with the spawn response. - runtime.onPtyData('pty-restored', 'queued', 100) - expect( - runtime.synchronizePtyOutputSequenceFromProvider( - 'pty-restored', - { value: 900, generation: 'continued' }, - 0 - ) - ).toBe(906) - runtime.onPtyData('pty-restored', 'fresh', 101) - - expect(runtime.getPtyOutputSequence('pty-restored')).toBe(911) - await expect(runtime.serializeMainTerminalBuffer('pty-restored')).resolves.toMatchObject({ - data: expect.stringContaining('queuedfresh'), - seq: 911, - source: 'headless' - }) - }) - - it('drops stale headless state without rewinding the runtime sequence', async () => { - const { runtime } = createSideEffectRuntime() - runtime.synchronizePtyOutputSequenceFromProvider( - 'pty-restarted', - { value: 0, generation: 'reset' }, - 0 - ) - runtime.onPtyData('pty-restarted', 'old generation', 100) - const sequenceBeforeRespawn = runtime.getPtyOutputSequence('pty-restarted') - - expect( - runtime.synchronizePtyOutputSequenceFromProvider( - 'pty-restarted', - { value: 0, generation: 'reset' }, - sequenceBeforeRespawn - ) - ).toBe(sequenceBeforeRespawn) - runtime.onPtyData('pty-restarted', 'new generation', 101) - - await expect(runtime.serializeMainTerminalBuffer('pty-restarted')).resolves.toMatchObject({ - data: expect.not.stringContaining('old generation'), - seq: sequenceBeforeRespawn + 'new generation'.length - }) - }) - - it('keeps active listener sequences monotonic across a daemon reset', () => { - const { runtime } = createSideEffectRuntime() - runtime.synchronizePtyOutputSequenceFromProvider( - 'pty-reset', - { value: 0, generation: 'reset' }, - 0 - ) - runtime.onPtyData('pty-reset', 'old', 100) - const sequenceBeforeRespawn = runtime.getPtyOutputSequence('pty-reset') - const observedSequences: number[] = [] - runtime.subscribeToTerminalData('pty-reset', (_data, meta) => { - if (typeof meta?.seq === 'number') { - observedSequences.push(meta.seq) - } - }) - - runtime.onPtyData('pty-reset', 'early', 101) - runtime.synchronizePtyOutputSequenceFromProvider( - 'pty-reset', - { value: 0, generation: 'reset' }, - sequenceBeforeRespawn - ) - runtime.onPtyData('pty-reset', 'later', 102) - - expect(observedSequences).toEqual([ - sequenceBeforeRespawn + 'early'.length, - sequenceBeforeRespawn + 'early'.length + 'later'.length - ]) - }) -}) diff --git a/src/main/runtime/orchestration/turn-delivery/send-agent-turn-host.test.ts b/src/main/runtime/orchestration/turn-delivery/send-agent-turn-host.test.ts deleted file mode 100644 index 409487fc250..00000000000 --- a/src/main/runtime/orchestration/turn-delivery/send-agent-turn-host.test.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { readTestHostJournal } from '../../../native-chat/agent-session-journal/journal-observation.test-support' -// Use the real host's fingerprint admission to reject envelopes derived from different fields. - -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import type { AgentMessageSource } from '../../../../shared/agent-session/agent-session-message-source' -import { agentJournalSubmissionKey } from '../../../../shared/agent-session/journal/agent-session-journal-item-key' -import { createQueuedMessageTestRig } from '../../../native-chat/agent-session-wire/host/testing/structured-agent-session-queued-message-rig.test-fixture' - -import { eventually } from '../../../native-chat/agent-session-wire/host/testing/structured-agent-session-queued-message-rig-provider.test-fixture' -import type { QueuedMessageTestRig } from '../../../native-chat/agent-session-wire/host/testing/structured-agent-session-queued-message-rig.test-fixture' -import { - HOST_TEST_SESSION as SESSION, - hostTestMessage, - hostTestOperationId -} from '../../../native-chat/agent-session-wire/host/testing/structured-agent-session-host-test-data.test-fixture' -import { openRigTurnFor } from '../../../native-chat/agent-session-wire/host/testing/structured-agent-session-queued-rig-turn.test-fixture' -import { - sendAgentTurn, - type AgentTurnDelivery, - type StructuredAgentTurnHost -} from './send-agent-turn' - -let rig: QueuedMessageTestRig - -const MAIL_SOURCE: AgentMessageSource = { - kind: 'agent', - senders: [ - { - party: { - address: 'term_peer', - terminalHandle: 'term_peer', - orcaSessionId: null - }, - name: 'Claude' - } - ], - orchestration: { - message: 'mail-notice', - mailbox: 'dispatch:d1', - dispatchId: 'd1', - messages: [{ messageId: 'm1', runId: 'r1', from: 'term_peer' }] - } -} - -beforeEach(async () => { - rig = await createQueuedMessageTestRig() -}) - -afterEach(() => rig.dispose()) - -function sendTurn( - delivery: AgentTurnDelivery, - operationId = hostTestOperationId(), - host: StructuredAgentTurnHost = rig.host -) { - return sendAgentTurn({ - kind: 'structured-session', - host, - sessionId: SESSION, - callerKey: 'trusted-local:orchestration:d1', - turn: { - body: { ...hostTestMessage('mail'), from: MAIL_SOURCE }, - operationId, - expectedRuntimeFence: 1, - delivery - } - }) -} - -async function sentMessage(clientMessageId: string) { - const snapshot = await readTestHostJournal(rig.host, SESSION) - return snapshot.items.find((item) => item.itemId === agentJournalSubmissionKey(clientMessageId)) -} - -describe('sendAgentTurn through the real host', () => { - it('keeps the sender on the turn the queue sends', async () => { - const working = await rig.workingSend() - const operationId = hostTestOperationId() - await sendTurn('queue', operationId) - await rig.settleAccepted(working, 'work') - await eventually(async () => expect(await rig.handoff(operationId)).toBeDefined()) - const item = await sentMessage(await rig.handoffId(operationId)) - expect(item?.body).toMatchObject({ from: MAIL_SOURCE }) - }) - - it('replays a retried `queue` send instead of refusing it', async () => { - await rig.workingSend() - const operationId = hostTestOperationId() - const first = await sendTurn('queue', operationId) - await expect(sendTurn('queue', operationId)).resolves.toEqual(first) - expect(await rig.drafts()).toHaveLength(1) - }) - - it('waits on the hand-off when a retried `queue` turn was already sent from the queue', async () => { - const working = await rig.workingSend() - const operationId = hostTestOperationId() - await sendTurn('queue', operationId) - await rig.settleAccepted(working, 'work') - await eventually(async () => expect(await rig.handoff(operationId)).toBeDefined()) - const handoffId = await rig.handoffId(operationId) - const waitedOn: string[] = [] - const host: StructuredAgentTurnHost = { - send: rig.host.send.bind(rig.host), - waitForSendSettlement: (sessionId, clientMessageId, options) => { - waitedOn.push(clientMessageId) - return rig.host.waitForSendSettlement(sessionId, clientMessageId, options) - } - } - let returned = false - const replay = sendTurn('queue', operationId, host).finally(() => { - returned = true - }) - await eventually(async () => expect(waitedOn).toHaveLength(1)) - await eventually(async () => - expect((await rig.submission(handoffId))?.handedOverAt).toBeDefined() - ) - expect(returned).toBe(false) - await rig.settleAccepted(handoffId, 'mail') - await expect(replay).resolves.toMatchObject({ - kind: 'sent', - submission: { clientMessageId: handoffId, dispatchState: 'accepted' } - }) - expect(waitedOn).toEqual([handoffId]) - }) - - /** Settles a handed-over send as the provider taking it; the turn's wait ends on that. */ - async function sendTurnAccepted( - delivery: AgentTurnDelivery, - operationId = hostTestOperationId() - ) { - const outcome = sendTurn(delivery, operationId) - let handedOverId = operationId - await eventually(async () => { - const submission = (await rig.handoff(operationId)) ?? (await rig.submission(operationId)) - expect(submission?.handedOverAt).toBeDefined() - handedOverId = submission!.clientMessageId - }) - await rig.settleAccepted(handedOverId, 'mail') - return outcome - } - - it.each(['now', 'queue'] as const)('sends a `%s` turn to an idle agent', async (delivery) => { - const outcome = await sendTurnAccepted(delivery) - expect(outcome).toMatchObject({ kind: 'sent', submission: { dispatchState: 'accepted' } }) - expect(await rig.drafts()).toEqual([]) - const sent = outcome.kind === 'sent' ? outcome.clientMessageId : '' - expect((await sentMessage(sent))?.body).toMatchObject({ from: MAIL_SOURCE }) - }) - - it('has a `now` send join the running turn through its row', async () => { - const working = await rig.workingSend() - await rig.settleAccepted(working, 'work') - await openRigTurnFor(rig, working) - await expect(sendTurnAccepted('now')).resolves.toMatchObject({ kind: 'queued' }) - expect(await rig.drafts()).toEqual([]) - }) -}) diff --git a/src/main/runtime/push/push-delivery-policy.test.ts b/src/main/runtime/push/push-delivery-policy.test.ts deleted file mode 100644 index ef17a699c01..00000000000 --- a/src/main/runtime/push/push-delivery-policy.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { afterEach, expect, it, vi } from 'vitest' -import { createHarness, flush, notification, registration } from './push-dispatcher.test-fixture' -import { parseMobilePushRegistration } from '../../../shared/mobile-push-contract' - -afterEach(() => vi.useRealTimers()) - -it('does not send or consume cooldown while the desktop is active', async () => { - const reg = registration() - reg.filter = { ...reg.filter, onlyWhenDesktopAway: true } - const { dispatcher, sends } = createHarness({ - devices: [{ deviceId: 'phone', pushRegistration: reg }] - }) - dispatcher.enqueue(notification({ desktopAway: false, emittedAt: 10_000 })) - dispatcher.enqueue(notification({ desktopAway: true, emittedAt: 10_001 })) - await flush() - expect(sends).toHaveLength(1) -}) - -it('drops finished-agent alerts for a phone that asked only for agent questions', async () => { - const reg = registration() - reg.filter = { ...reg.filter, onlyWhenAgentNeedsInput: true } - const { dispatcher, sends } = createHarness({ - devices: [{ deviceId: 'phone', pushRegistration: reg }] - }) - dispatcher.enqueue(notification({ agentState: 'done', emittedAt: 10_000 })) - dispatcher.enqueue(notification({ source: 'terminal-bell', worktreeId: 'b', emittedAt: 10_001 })) - dispatcher.enqueue(notification({ agentState: 'blocked', worktreeId: 'c', emittedAt: 10_002 })) - await flush() - expect(sends.map((send) => send.notification.agentState)).toEqual([null, 'needs-input']) -}) - -it('expires per phone at the boundary, preserves leases across persistence, and permits renewal', async () => { - vi.useFakeTimers({ toFake: ['Date'] }) - vi.setSystemTime(50_000) - const expired = parseMobilePushRegistration(registration({ expiresAt: 50_000 }))! - const devices = [{ deviceId: 'phone', pushRegistration: expired }] - const { dispatcher, sends } = createHarness({ devices }) - dispatcher.enqueue(notification()) - await flush() - expect(sends).toHaveLength(0) - devices[0].pushRegistration = registration({ expiresAt: 50_001 }) - dispatcher.enqueue(notification()) - await flush() - expect(sends).toHaveLength(1) -}) - -it('rechecks expiry before a retry', async () => { - vi.useFakeTimers({ toFake: ['Date'] }) - vi.setSystemTime(10) - const { dispatcher, sends, runRetry } = createHarness({ - devices: [{ deviceId: 'phone', pushRegistration: registration({ expiresAt: 20 }) }], - sendImpl: async () => ({ ok: false, reason: 'unreachable' }) as never - }) - dispatcher.enqueue(notification()) - await flush() - vi.setSystemTime(20) - runRetry() - await flush() - expect(sends).toHaveLength(1) - expect(parseMobilePushRegistration({ ...registration(), expiresAt: undefined })).toBeUndefined() -}) - -it('never lets the workspace window swallow distinct keyed news, but still collapses its repeat', async () => { - const { dispatcher, sends } = createHarness({ - devices: [{ deviceId: 'phone', pushRegistration: registration() }] - }) - dispatcher.enqueue(notification({ emittedAt: 10_000 })) - dispatcher.enqueue(notification({ emittedAt: 10_001, agentState: 'blocked', attentionKey: 'p1' })) - dispatcher.enqueue(notification({ emittedAt: 10_002, agentState: 'blocked', attentionKey: 'p2' })) - dispatcher.enqueue(notification({ emittedAt: 10_003, agentState: 'blocked', attentionKey: 'p2' })) - dispatcher.enqueue(notification({ emittedAt: 10_004 })) - await flush() - expect(sends.map((send) => send.notification.agentState)).toEqual([ - 'finished', - 'needs-input', - 'needs-input' - ]) -}) diff --git a/src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts b/src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts deleted file mode 100644 index ea46f3a979d..00000000000 --- a/src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { RpcContext } from '../../../core' -import { createOrchestrationRpcHarness } from '../rpc-test-harness' -import type { OrchestrationDb } from '../../../../orchestration/db/orchestration-db' -import type { OrcaRuntimeService } from '../../../../orca-runtime' -import '../../../../../../shared/orchestration/orchestration-dispatch-refusal-contract' -import { createRootDispatch } from '../../../../orchestration/db/root-dispatch-test-fixture' -import '../../../../orchestration/workers/launch/worker-dispatch-preamble' - -describe('orchestration RPC methods', () => { - const h = createOrchestrationRpcHarness() - const { coordinatorPaneKey } = h - let db: OrchestrationDb - let runtime: OrcaRuntimeService - let ctx: RpcContext - - function setup(withBoundRun = true): void { - ;({ db, runtime, ctx } = h.setup(withBoundRun)) - } - - afterEach(() => { - h.cleanup() - }) - - async function call(name: string, params: Record) { - return h.call(name, params, ctx) - } - - describe('orchestration.taskCreate', () => { - it('records the caller pane, process, and Run generation when creating a task', async () => { - setup() - vi.spyOn(runtime, 'getTerminalPaneKey').mockImplementation((handle) => - handle === 'term_creator' ? coordinatorPaneKey : null - ) - vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockReturnValue({ - terminalHandle: 'term_creator', - paneKey: coordinatorPaneKey, - processIncarnation: 'pty-creator:incarnation-a' - } as never) - const result = (await call('orchestration.taskCreate', { - spec: 'spawn related workspace', - callerTerminalHandle: 'term_creator' - })) as { task: { id: string } } - - expect(db.getTask(result.task.id)).toMatchObject({ - created_by_terminal_handle: 'term_creator', - created_by_pane_key: coordinatorPaneKey, - created_by_process_incarnation: 'pty-creator:incarnation-a', - created_by_run_generation: 1 - }) - }) - }) - - describe('orchestration.dispatch', () => { - function provideInjectIdentity(handle = 'term_a'): void { - vi.mocked(runtime.getTerminalPaneKey).mockImplementation((candidate) => - candidate === handle ? `tab_worker:${handle}` : coordinatorPaneKey - ) - vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockImplementation((candidate) => - candidate === handle - ? ({ - terminalHandle: handle, - paneKey: `tab_worker:${handle}`, - processIncarnation: `runtime_test:${handle}:1`, - launchTokenHash: null - } as never) - : null - ) - } - - it('commits authenticated process authority on a manual dispatch', async () => { - setup() - vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockReturnValue({ - runtimeId: runtime.getRuntimeId(), - terminalHandle: 'term_a', - ptyId: 'pty_a', - worktreeId: 'repo::worktree', - paneKey: 'tab_w:leaf_w', - processIncarnation: 'runtime_test:term_a:1', - launchTokenHash: 'launch-token-hash', - hostScope: { kind: 'local', hostId: 'local' } - }) - const task = db.createTask({ spec: 'work' }) - - const result = (await call('orchestration.dispatch', { - task: task.id, - to: 'term_a' - })) as { dispatch: { id: string } } - - expect(db.getDispatchContextById(result.dispatch.id)).toMatchObject({ - assignee_pane_key: 'tab_w:leaf_w', - process_incarnation: 'runtime_test:term_a:1', - launch_token_hash: 'launch-token-hash' - }) - }) - - it('does not infer manual process authority from an unauthenticated handle', async () => { - setup() - const task = db.createTask({ spec: 'work' }) - - const result = (await call('orchestration.dispatch', { - task: task.id, - to: 'term_a' - })) as { dispatch: { id: string } } - - expect(runtime.getTerminalProcessIncarnation('term_a')).toBe('runtime_test:term_a:1') - expect(db.getDispatchContextById(result.dispatch.id)?.process_incarnation).toBeNull() - }) - - it('rolls back active dispatch when injection fails', async () => { - setup() - provideInjectIdentity() - const task = db.createTask({ spec: 'work' }) - vi.spyOn(runtime, 'isTerminalRunningAgent').mockResolvedValue(true) - vi.spyOn(runtime, 'sendTerminalAgentPrompt').mockRejectedValue( - new Error('terminal_not_writable') - ) - - await expect( - call('orchestration.dispatch', { - task: task.id, - to: 'term_a', - inject: true - }) - ).rejects.toThrow('terminal_not_writable') - - expect(db.getTask(task.id)?.status).toBe('ready') - expect(db.getActiveDispatchForTerminal('term_a')).toBeUndefined() - }) - - it('rejects dispatch to occupied terminal', async () => { - setup() - const t1 = db.createTask({ spec: 'first' }) - const t2 = db.createTask({ spec: 'second' }) - createRootDispatch(db, t1.id, 'term_a') - - await expect(call('orchestration.dispatch', { task: t2.id, to: 'term_a' })).rejects.toThrow( - /already has an active dispatch/ - ) - }) - }) -}) diff --git a/src/main/runtime/rpc/methods/orchestration/structured-workers/structured-worker-read-cursor.test.ts b/src/main/runtime/rpc/methods/orchestration/structured-workers/structured-worker-read-cursor.test.ts deleted file mode 100644 index da4cbd5d628..00000000000 --- a/src/main/runtime/rpc/methods/orchestration/structured-workers/structured-worker-read-cursor.test.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { - agentSessionLeaseFixture, - agentSessionRecordFixture -} from '../../../../../../shared/agent-session/lifecycle/records/agent-session-record.test-fixture' -import { agentSessionConversationView } from '../../../../../../shared/agent-session/lifecycle/leases/agent-session-conversation-view' -/** Mutate journals between reads to catch in-place revisions and mid-array insertions missed by oldest-item-only cursor identity; both can silently omit or duplicate output. */ - -import { beforeEach, describe, expect, it, vi } from 'vitest' -import { boundStructuredJournalTail } from '../../../../orchestration/workers/archives/structured-worker-journal-archive' -import { projectSavedChatContextItems } from '../../../../../native-chat/conversation-context/agent-session-saved-prompt-text' -import { formatWorkerTranscriptMessage } from '../../../../../../shared/worker-transcript-text' -import type { AgentJournalRenderItem } from '../../../../../../shared/agent-session/journal/agent-session-journal-types' -import type { StructuredWorkerIdentity } from '../../../../orchestration/terminal-authority/structured-sessions/structured-worker-identity' - -const hostRef: { current: unknown } = { current: null } - -vi.mock( - '../../../../../native-chat/agent-session-wire/host/structured-agent-session-registry', - () => ({ - getStructuredAgentSessionHost: () => hostRef.current - }) -) - -const { readStructuredWorkerJournal } = await import('./orchestration-structured-worker-lifecycle') - -const IDENTITY: StructuredWorkerIdentity = { - handle: 'structworker_1', - sessionId: 'session-1', - agent: 'claude', - paneKey: 'structured-agent-session-session-1:11111111-1111-4111-a111-111111111111', - processIncarnation: 'structured:session-1', - worktreeId: 'wt_1', - hostScope: { kind: 'local', hostId: 'local' } -} - -function message(itemId: string, text: string, revision = 1): AgentJournalRenderItem { - return { - itemId, - revision, - sequence: Number(itemId.slice(1)), - observedAt: 1, - body: { kind: 'message', role: 'assistant', blocks: [{ type: 'text', text }] } - } as unknown as AgentJournalRenderItem -} - -/** Projects to null while pending, and to a system message once resolved — mid-array. */ -function approval(itemId: string, resolved: boolean, revision = 1): AgentJournalRenderItem { - return { - itemId, - revision, - sequence: Number(itemId.slice(1)), - observedAt: 1, - body: { - kind: 'approval', - title: 'run it?', - detail: null, - resolution: { state: resolved ? 'approved' : 'pending' } - } - } as unknown as AgentJournalRenderItem -} - -function installJournal(items: AgentJournalRenderItem[]): void { - hostRef.current = { - deps: { - store: { - getConversation: () => - agentSessionConversationView( - agentSessionRecordFixture(agentSessionLeaseFixture({ sessionId: IDENTITY.sessionId })) - ) - } - }, - hasSession: () => true, - history: () => ({ page: { items, hasOlder: false } }) - } -} - -function read(cursor?: string, limit?: number) { - return readStructuredWorkerJournal({ - identity: IDENTITY, - dispatchId: 'd1', - workerState: 'ready', - liveness: 'live', - agent: 'claude', - ...(cursor === undefined ? {} : { cursor }), - ...(limit === undefined ? {} : { limit }) - }) -} - -function textsOf(result: Awaited>): string[] { - return result.transcript.messages.map((entry) => - entry.blocks.map((block) => ('text' in block ? block.text : '')).join('') - ) -} - -describe('the structured worker-read cursor over a mutating journal', () => { - beforeEach(() => { - hostRef.current = null - }) - - it('omits creation facts from worker output, consumed prefixes, saved context and terminal views', async () => { - const start: AgentJournalRenderItem = { - itemId: 'i2', - revision: 1, - sequence: 2, - observedAt: 1, - body: { - kind: 'agent-start', - dispatchId: 'dispatch', - task: 'Private worker assignment', - worker: { - party: { address: 'term_worker', terminalHandle: 'term_worker', orcaSessionId: null }, - name: 'Worker' - } - } - } - const items = [message('i1', 'first'), start, message('i3', 'answer')] - installJournal(items) - const first = await read(undefined, 1) - expect(textsOf(first)).toEqual(['first']) - installJournal([ - items[0], - { - ...start, - revision: 2, - body: - start.body.kind === 'agent-start' - ? { ...start.body, task: 'Revised display fact' } - : start.body - }, - items[2] - ]) - expect(textsOf(await read(first.cursor))).toEqual(['answer']) - const saved = projectSavedChatContextItems(items).map(formatWorkerTranscriptMessage).join('\n') - expect(saved).toBe('[assistant] first\n[assistant] answer') - expect(boundStructuredJournalTail(items).messages.map(formatWorkerTranscriptMessage)).toEqual([ - '[assistant] first', - '[assistant] answer' - ]) - }) - - it('refuses to resume when an already-delivered item was revised in place', async () => { - // Revise an already-read item in place; old oldest-item identity silently skipped the revised text. - installJournal([message('i1', 'hel'), message('i2', 'second')]) - const first = await read(undefined, 1) - expect(textsOf(first)).toEqual(['hel']) - - installJournal([message('i1', 'hello world', 2), message('i2', 'second')]) - await expect(read(first.cursor)).rejects.toThrow(/source changed/i) - }) - - it('refuses to resume when a resolved prompt inserts ahead of the caller position', async () => { - // Resolving an approval inserts a message mid-array; the old cursor accepted a stale index and duplicated content. - installJournal([message('i1', 'first'), approval('i2', false), message('i3', 'second')]) - const first = await read(undefined, 2) - expect(textsOf(first)).toEqual(['first', 'second']) - - installJournal([message('i1', 'first'), approval('i2', true, 2), message('i3', 'second')]) - await expect(read(first.cursor)).rejects.toThrow(/source changed/i) - }) - - it('still resumes across a page boundary when only unread tail items change', async () => { - // Hash only consumed prefix: whole-page hashing would invalidate on every streaming revision (~60ms). - installJournal([message('i1', 'first'), message('i2', 'streaming')]) - const first = await read(undefined, 1) - expect(textsOf(first)).toEqual(['first']) - - installJournal([message('i1', 'first'), message('i2', 'streaming more', 7)]) - const second = await read(first.cursor) - expect(textsOf(second)).toEqual(['streaming more']) - }) - - it('still refuses when the window slides off the front', async () => { - // Keep detecting window slides, which shift every message index. - installJournal([message('i1', 'a'), message('i2', 'b')]) - const first = await read(undefined, 1) - installJournal([message('i2', 'b'), message('i3', 'c')]) - await expect(read(first.cursor)).rejects.toThrow(/source changed/i) - }) -}) diff --git a/src/main/runtime/session-lifecycle/close/close-mobile-row-in-main-layout.test.ts b/src/main/runtime/session-lifecycle/close/close-mobile-row-in-main-layout.test.ts deleted file mode 100644 index b3106315b4d..00000000000 --- a/src/main/runtime/session-lifecycle/close/close-mobile-row-in-main-layout.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -// Layout-owner build: a phone's close of a terminal row main owns, with no window, is main's own -// layout close; a pinned tab stays unless the phone forces the close, as the window-era close did. -import { afterEach, describe, expect, it, vi } from 'vitest' -import { - resetAgentLaunchPanesForTests, - resolveAgentLaunchPaneVerdict, - trackRunningAgentLaunchPane -} from '../../../agent-launch/agent-launch-pane-attachment' -import { makePaneKey } from '../../../../shared/workspace-layout/stable-pane-id' -import { - LEAF_A, - LEAF_B, - PTY_A, - PTY_B, - TAB_ID, - WORKTREE_ID, - setupMainOwnedWorkspace -} from '../../terminal/layout/main-owned-workspace-runtime-fixture' - -vi.mock('../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) - -const tabsOf = (fixture: ReturnType) => - fixture.session().tabsByWorktree[WORKTREE_ID] ?? [] - -describe("a phone's terminal close in a workspace main owns, with no window", () => { - afterEach(() => resetAgentLaunchPanesForTests()) - - it('closes the tab in main, records the close, and stops its terminal', async () => { - const fixture = setupMainOwnedWorkspace() - - await fixture.runtime.closeMobileSessionTab(`id:${WORKTREE_ID}`, TAB_ID, { reason: 'user' }) - - expect(tabsOf(fixture)).toHaveLength(0) - expect(fixture.session().closedTerminalTabTombstonesByTabId?.[TAB_ID]).toMatchObject({ - reason: 'user' - }) - expect(fixture.stopped).toEqual([PTY_A]) - }) - - it('closes one pane of a split and stops only its terminal', async () => { - const fixture = setupMainOwnedWorkspace({ split: true }) - - await fixture.runtime.closeMobileSessionTab(`id:${WORKTREE_ID}`, `${TAB_ID}::${LEAF_B}`) - - expect(tabsOf(fixture)).toHaveLength(1) - expect(fixture.session().terminalLayoutsByTabId[TAB_ID]?.root).toEqual({ - type: 'leaf', - leafId: LEAF_A - }) - expect(fixture.stopped).toEqual([PTY_B]) - }) - - it('refuses a pinned tab and keeps it and its terminal', async () => { - const fixture = setupMainOwnedWorkspace({ pinned: true }) - - await expect( - fixture.runtime.closeMobileSessionTab(`id:${WORKTREE_ID}`, TAB_ID, { reason: 'user' }) - ).rejects.toThrow('terminal_tab_pinned') - - expect(tabsOf(fixture)).toHaveLength(1) - expect(fixture.stopped).toEqual([]) - }) - - it('leaves a launch running in a pinned tab it refused to close to finish into the tab', async () => { - const fixture = setupMainOwnedWorkspace({ pinned: true }) - const pane = { worktreeId: WORKTREE_ID, paneKey: makePaneKey(TAB_ID, LEAF_A) } - const launch = trackRunningAgentLaunchPane(pane) - - await expect( - fixture.runtime.closeMobileSessionTab(`id:${WORKTREE_ID}`, TAB_ID, { reason: 'user' }) - ).rejects.toThrow('terminal_tab_pinned') - - // The launch is not told its tab closed, so it does not take its pane back... - expect(launch.closedByUser()).toBe(false) - launch.finish({ kind: 'not-started', code: 'agent_exited' }) - // ...and its failure stays for the pane, which is still there, to show. - await expect(resolveAgentLaunchPaneVerdict(pane, () => false)).resolves.toEqual({ - kind: 'not-started', - code: 'agent_exited' - }) - expect(tabsOf(fixture)).toHaveLength(1) - }) - - it('closes a pinned tab the phone forces', async () => { - const fixture = setupMainOwnedWorkspace({ pinned: true }) - - await fixture.runtime.closeMobileSessionTab(`id:${WORKTREE_ID}`, TAB_ID, { - reason: 'user', - force: true - }) - - expect(tabsOf(fixture)).toHaveLength(0) - expect(fixture.stopped).toEqual([PTY_A]) - }) -}) diff --git a/src/main/runtime/sidebar-inputs/cached-scan.test.ts b/src/main/runtime/sidebar-inputs/cached-scan.test.ts deleted file mode 100644 index 651c2493d4a..00000000000 --- a/src/main/runtime/sidebar-inputs/cached-scan.test.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { CachedScan } from './cached-scan' - -function scanner(demand = true) { - const pending: { value: number; resolve: () => void }[] = [] - const applied: number[] = [] - let next = 0 - const cache = new CachedScan({ - label: 'test', - demand: () => demand, - applied: (value) => applied.push(value), - scan: () => { - const value = ++next - return new Promise((resolve) => { - pending.push({ value, resolve: () => resolve(value) }) - }) - } - }) - const finish = async (): Promise => { - pending.shift()?.resolve() - await vi.waitFor(() => {}) - await new Promise((resolve) => setImmediate(resolve)) - } - return { cache, pending, applied, finish } -} - -describe('CachedScan', () => { - it('runs one scan at a time and one more for every request made during it', async () => { - const { cache, pending, applied, finish } = scanner() - cache.request() - cache.request() - cache.request() - expect(pending).toHaveLength(1) - await finish() - expect(applied).toEqual([1]) - expect(pending).toHaveLength(1) - await finish() - expect(applied).toEqual([1, 2]) - expect(cache.current).toBe(2) - expect(pending).toHaveLength(0) - }) - - it('runs no scan without demand, but makes the next reader scan again', async () => { - const { cache, pending, finish } = scanner(false) - const first = cache.ready() - await finish() - await first - cache.request() - expect(pending).toHaveLength(0) - const second = cache.ready() - expect(pending).toHaveLength(1) - await finish() - await second - expect(cache.current).toBe(2) - }) - - it('keeps the last result when a scan fails', async () => { - vi.spyOn(console, 'warn').mockImplementation(() => {}) - let fail = false - const cache = new CachedScan({ - label: 'test', - demand: () => true, - applied: () => {}, - scan: async () => { - if (fail) { - throw new Error('git failed') - } - return 1 - } - }) - await cache.ready() - fail = true - cache.request() - await cache.settled() - expect(cache.current).toBe(1) - vi.restoreAllMocks() - }) - - it('calls a fresh waiter right after a scan started after it applies, not an older one', async () => { - const { cache, pending, applied, finish } = scanner() - cache.request() - const seen: number[][] = [] - // A scan already in flight started before the wait, so it cannot satisfy it. - cache.afterFresh(() => seen.push([...applied])) - await finish() - expect(applied).toEqual([1]) - expect(seen).toEqual([]) - expect(pending).toHaveLength(1) - await finish() - // Called synchronously after the apply, so its change publishes in the same revision. - expect(seen).toEqual([[1, 2]]) - }) - - it('calls a fresh waiter at once with no demand, and after a failed scan', async () => { - const idle = scanner(false) - const calls: string[] = [] - idle.cache.afterFresh(() => calls.push('idle')) - expect(calls).toEqual(['idle']) - vi.spyOn(console, 'warn').mockImplementation(() => {}) - const failing = new CachedScan({ - label: 'test', - demand: () => true, - applied: () => {}, - scan: () => Promise.reject(new Error('git failed')) - }) - failing.afterFresh(() => calls.push('failed')) - await vi.waitFor(() => expect(calls).toEqual(['idle', 'failed'])) - vi.restoreAllMocks() - }) -}) diff --git a/src/main/runtime/terminal/input/agent-prompt-permission-hold.test.ts b/src/main/runtime/terminal/input/agent-prompt-permission-hold.test.ts deleted file mode 100644 index 7d5e01cb061..00000000000 --- a/src/main/runtime/terminal/input/agent-prompt-permission-hold.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { - AGENT_PROMPT_PERMISSION_RECHECK_MS, - waitWhileAgentPromptBlocked -} from './agent-prompt-permission-hold' - -function hold(initiallyBlocked: boolean) { - const state = { blocked: initiallyBlocked, stale: false } - let wake: (() => void) | null = null - let exit: (() => void) | null = null - const released = { status: 0, exit: 0 } - return { - state, - released, - wake: () => wake?.(), - exit: () => exit?.(), - deps: { - isBlocked: () => { - if (state.stale) { - throw new Error('terminal_handle_stale') - } - return state.blocked - }, - subscribeStatus: (listener: () => void) => { - wake = listener - return () => { - released.status += 1 - } - }, - subscribeExit: (listener: () => void) => { - exit = listener - return () => { - released.exit += 1 - } - } - } - } -} - -describe('waitWhileAgentPromptBlocked', () => { - afterEach(() => vi.useRealTimers()) - - it('wakes on a status change without waiting for the recheck', async () => { - vi.useFakeTimers() - const h = hold(true) - const waiting = waitWhileAgentPromptBlocked(h.deps) - h.state.blocked = false - h.wake() - await expect(waiting).resolves.toBeUndefined() - expect(h.released).toEqual({ status: 1, exit: 1 }) - expect(vi.getTimerCount()).toBe(0) - }) - - it('re-reads on its timer for an answer no hook reports', async () => { - vi.useFakeTimers() - const h = hold(true) - const waiting = waitWhileAgentPromptBlocked(h.deps) - h.state.blocked = false - await vi.advanceTimersByTimeAsync(AGENT_PROMPT_PERMISSION_RECHECK_MS) - await expect(waiting).resolves.toBeUndefined() - }) - - it('rejects with the read error when the binding changes', async () => { - const h = hold(true) - const waiting = waitWhileAgentPromptBlocked(h.deps) - h.state.stale = true - h.wake() - await expect(waiting).rejects.toThrow('terminal_handle_stale') - }) - - it('rejects on exit, including an exit already known at subscribe time', async () => { - const h = hold(true) - const waiting = waitWhileAgentPromptBlocked(h.deps) - h.exit() - await expect(waiting).rejects.toThrow('terminal_not_writable') - - await expect( - waitWhileAgentPromptBlocked({ - ...h.deps, - subscribeExit: (listener) => { - listener() - return () => {} - } - }) - ).rejects.toThrow('terminal_not_writable') - }) - - it('rejects on abort and clears its timer', async () => { - vi.useFakeTimers() - const controller = new AbortController() - const h = hold(true) - const waiting = waitWhileAgentPromptBlocked({ ...h.deps, signal: controller.signal }) - controller.abort() - await expect(waiting).rejects.toThrow('request_aborted') - expect(vi.getTimerCount()).toBe(0) - expect(h.released).toEqual({ status: 1, exit: 1 }) - }) -}) diff --git a/src/renderer/src/components/activity/activity-search-query.test.tsx b/src/renderer/src/components/activity/activity-search-query.test.tsx deleted file mode 100644 index 3415e65a600..00000000000 --- a/src/renderer/src/components/activity/activity-search-query.test.tsx +++ /dev/null @@ -1,194 +0,0 @@ -// @vitest-environment happy-dom -import { act, cleanup, renderHook } from '@testing-library/react' -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { AgentStatusEntry } from '../../../../shared/agent-status/contracts/agent-status-types' -import { makePaneKey } from '../../../../shared/workspace-layout/stable-pane-id' -import { toSshExecutionHostId } from '../../../../shared/execution-host' -import { useAppStore } from '@/store' -import { - LEAF_ID, - makeRepo, - makeTabWithIds, - makeWorktree -} from './ActivityPrototypePage-test-fixtures' - -import { useAgentPaneThreads } from './use-agent-pane-threads' - -vi.mock('@/store', async () => { - const { createTestStore } = await import('@/store/testing/app-store-test-fixture') - return { useAppStore: createTestStore() } -}) - -afterEach(() => { - cleanup() - vi.restoreAllMocks() -}) - -function installThreads(count: number, prompt = 'Task PROJECT ☃ progress'): string[] { - vi.spyOn(Date, 'now').mockReturnValue(100_000) - const repo = makeRepo() - const worktree = makeWorktree() - const tabs = Array.from({ length: count }, (_, index) => - makeTabWithIds(`tab-${index}`, worktree.id) - ) - const entries: Record = {} - for (const tab of tabs) { - const paneKey = makePaneKey(tab.id, LEAF_ID) - entries[paneKey] = { - paneKey, - state: 'working', - prompt, - agentType: 'claude', - updatedAt: 100_000, - stateStartedAt: 99_000, - stateHistory: [] - } - } - useAppStore.setState({ - agentStatusByPaneKey: entries, - - migrationUnsupportedByPtyId: {}, - runtimeAgentOrchestrationByPaneKey: {}, - acknowledgedAgentsByPaneKey: {}, - activityClearedAtByPaneKey: {}, - repos: [repo], - worktreesByRepo: { [repo.id]: [worktree] }, - folderWorkspaces: [], - detectedWorktreesByRepo: {}, - tabsByWorktree: { [worktree.id]: tabs }, - unifiedTabsByWorktree: {}, - agentsVisibleHostIds: null, - agentsFilterRepoIds: [] - }) - return Object.keys(entries) -} - -function options(query: string): Parameters[0] { - return { query, readFilter: 'all', groupBy: 'none', selectedPaneKey: null, showChildAgents: true } -} - -describe('Activity search query in the real hook', () => { - it('keeps live rows but excludes acknowledged finished rows from an unread search', () => { - const panes = installThreads(12) - const entries = useAppStore.getState().agentStatusByPaneKey - useAppStore.setState({ - agentStatusByPaneKey: Object.fromEntries( - panes.map((paneKey, index) => [ - paneKey, - index === 0 ? entries[paneKey] : { ...entries[paneKey], state: 'done' as const } - ]) - ), - acknowledgedAgentsByPaneKey: Object.fromEntries(panes.map((paneKey) => [paneKey, 100_000])) - }) - const activity = renderHook(() => - useAgentPaneThreads({ ...options(' PROJECT ☃ '), readFilter: 'unread' }) - ) - expect(activity.result.current.allThreads).toHaveLength(12) - expect(activity.result.current.visibleThreads.map((thread) => thread.paneKey)).toEqual([ - panes[0] - ]) - }) - - it('hides acknowledged unavailable rows unless selected in the unread filter', () => { - const [livePane, unavailablePane] = installThreads(2) - const entries = useAppStore.getState().agentStatusByPaneKey - useAppStore.setState({ - agentStatusByPaneKey: { [livePane]: entries[livePane] }, - migrationUnsupportedByPtyId: { - 'pty-tab-1': { - ptyId: 'pty-tab-1', - paneKey: unavailablePane, - reason: 'legacy-numeric-pane-key', - source: 'local', - updatedAt: 99_000 - } - }, - acknowledgedAgentsByPaneKey: { [livePane]: 100_000, [unavailablePane]: 100_000 } - }) - const activity = renderHook, string | null>( - (selectedPaneKey: string | null) => - useAgentPaneThreads({ ...options(''), readFilter: 'unread', selectedPaneKey }), - { initialProps: null } - ) - expect(activity.result.current.visibleThreads.map((thread) => thread.paneKey)).toEqual([ - 'tab-0:11111111-1111-4111-8111-111111111111' - ]) - activity.rerender(unavailablePane) - expect( - activity.result.current.visibleThreads.map((thread) => thread.paneKey).toSorted() - ).toEqual([ - 'tab-0:11111111-1111-4111-8111-111111111111', - 'tab-1:11111111-1111-4111-8111-111111111111' - ]) - act(() => useAppStore.setState({ activityClearedAtByPaneKey: { [unavailablePane]: 99_000 } })) - activity.rerender(null) - expect(activity.result.current.visibleThreads.map((thread) => thread.paneKey)).toEqual([ - 'tab-0:11111111-1111-4111-8111-111111111111' - ]) - act(() => - useAppStore.setState({ - activityClearedAtByPaneKey: {}, - acknowledgedAgentsByPaneKey: { [livePane]: 100_000 } - }) - ) - expect( - activity.result.current.visibleThreads.map((thread) => thread.paneKey).toSorted() - ).toEqual([ - 'tab-0:11111111-1111-4111-8111-111111111111', - 'tab-1:11111111-1111-4111-8111-111111111111' - ]) - }) - - it('keeps selection, child classification and scoped row order', () => { - const panes = installThreads(8) - const parent = panes[0] - const child = panes[1] - useAppStore.setState({ - runtimeAgentOrchestrationByPaneKey: { - [child]: { parentPaneKey: parent, taskId: 'task', dispatchId: 'dispatch' } - }, - acknowledgedAgentsByPaneKey: { [child]: 100_000 } - }) - const activity = renderHook((input) => useAgentPaneThreads(input), { - initialProps: { - ...options('PROJECT'), - readFilter: 'unread' as const, - showChildAgents: false, - selectedPaneKey: child - } - }) - expect(activity.result.current.visibleThreads.map((thread) => thread.paneKey)).toEqual(panes) - act(() => useAppStore.setState({ agentsVisibleHostIds: [toSshExecutionHostId('other')] })) - expect(activity.result.current.visibleThreads.map((thread) => thread.paneKey)).toEqual([child]) - activity.rerender({ - ...options('NO MATCH'), - readFilter: 'unread', - showChildAgents: false, - selectedPaneKey: child - }) - expect(activity.result.current.visibleThreads).toEqual([]) - expect(activity.result.current.effectiveSelectedPaneKey).toBe(child) - }) - - it('uses a changed query and new thread data without a retained query cache', () => { - const panes = installThreads(12, 'first prompt') - const activity = renderHook((query) => useAgentPaneThreads(options(query)), { - initialProps: 'first' - }) - expect(activity.result.current.visibleThreads).toHaveLength(12) - activity.rerender('second') - expect(activity.result.current.visibleThreads).toEqual([]) - act(() => { - const entries = useAppStore.getState().agentStatusByPaneKey - useAppStore.setState({ - agentStatusByPaneKey: { - ...entries, - [panes[2]]: { ...entries[panes[2]], prompt: 'second prompt' } - } - }) - }) - expect(activity.result.current.visibleThreads.map((thread) => thread.paneKey)).toEqual([ - panes[2] - ]) - }) -}) diff --git a/src/renderer/src/components/agent/AgentLaunchSetupSubmenu.focus.test.tsx b/src/renderer/src/components/agent/AgentLaunchSetupSubmenu.focus.test.tsx deleted file mode 100644 index 003b6215b65..00000000000 --- a/src/renderer/src/components/agent/AgentLaunchSetupSubmenu.focus.test.tsx +++ /dev/null @@ -1,96 +0,0 @@ -// @vitest-environment happy-dom -import { act, useState, type ReactElement } from 'react' -import { fireEvent, waitFor } from '@testing-library/react' -import { createRoot, type Root } from 'react-dom/client' -import { afterEach, beforeEach, expect, it, vi } from 'vitest' -import { TooltipProvider } from '@/components/ui/tooltip' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuTrigger -} from '@/components/ui/dropdown-menu' -import { AgentLaunchSetupButton } from './AgentLaunchSetupButton' -import type { AgentPickerEntry } from '../../../../shared/agent-launch/picker/agent-launch-picker' - -vi.mock('@/hooks/useShortcutLabel', () => ({ useOptionalShortcutLabel: () => null })) - -const entry: AgentPickerEntry = { - agent: 'codex', - label: 'codex', - rows: [{ agent: 'codex', kind: 'terminal' }], - surfaces: ['chat', 'terminal'], - defaultSurface: 'terminal', - terminal: {}, - structured: {}, - catalog: { - origin: 'probe', - fetchedAt: 1, - models: [{ id: 'astra', label: 'Astra', isDefault: true, efforts: [] }] - } -} -const anchor = (trigger: ReactElement) =>
{trigger}
-let root: Root -let host: HTMLDivElement -let setOpen: (open: boolean) => void -beforeEach(() => { - vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true) - host = document.createElement('div') - document.body.append(host) - root = createRoot(host) -}) -afterEach(() => { - act(() => root.unmount()) - host.remove() - vi.unstubAllGlobals() -}) - -function Omnibox() { - const [open, changeOpen] = useState(false) - setOpen = changeOpen - return ( - - - New tab - - - - document.querySelector('input')?.focus()} - onUse={vi.fn()} - renderAnchor={anchor} - /> - - - - ) -} - -async function openWithFocusInPanel() { - act(() => root.render()) - fireEvent.click(document.querySelector('button[aria-label="Configure codex"]')!) - await waitFor(() => expect(document.querySelector('[cmdk-input]:not(:disabled)')).not.toBeNull()) - const search = document.querySelector('[cmdk-input]')! - search.focus() - expect(document.activeElement).toBe(search) -} - -it('returns typing to the caller input when the caller closes a focused setup', async () => { - await openWithFocusInPanel() - act(() => setOpen(false)) - await waitFor(() => expect(document.querySelector('[cmdk-input]')).toBeNull()) - expect(document.activeElement).toBe(document.querySelector('input[aria-label="Query"]')) -}) - -it('leaves focus where the user moved it when the setup then closes', async () => { - await openWithFocusInPanel() - const elsewhere = [...document.querySelectorAll('button')].find( - (button) => button.textContent === 'Elsewhere' - )! - elsewhere.focus() - act(() => setOpen(false)) - await waitFor(() => expect(document.querySelector('[cmdk-input]')).toBeNull()) - expect(document.activeElement).toBe(elsewhere) -}) diff --git a/src/renderer/src/components/artifacts/ArtifactCollection.test.tsx b/src/renderer/src/components/artifacts/ArtifactCollection.test.tsx deleted file mode 100644 index 4b3586a5225..00000000000 --- a/src/renderer/src/components/artifacts/ArtifactCollection.test.tsx +++ /dev/null @@ -1,95 +0,0 @@ -// @vitest-environment happy-dom - -import '@testing-library/jest-dom/vitest' -import { cleanup, render, screen, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { useState } from 'react' -import { afterEach, describe, expect, it, vi } from 'vitest' -import type { ArtifactListItem } from '../../../../shared/artifacts/artifacts' - -vi.mock('./ArtifactPreview', () => ({ - ArtifactPreview: ({ shareUrl }: { shareUrl: string }) =>
{`Preview ${shareUrl}`}
-})) - -import { TooltipProvider } from '@/components/ui/tooltip' -import { ArtifactCollection } from './ArtifactCollection' - -const DAY_MS = 24 * 60 * 60 * 1000 - -// Use relative dates because the labels under test are relative times. -function artifact(slug: string, title: string): ArtifactListItem { - const createdAt = new Date(Date.now() - DAY_MS).toISOString() - return { - artifact: { - version: 1, - slug, - title, - originalFileName: `${slug}.html`, - sourceContentType: 'text/html', - renderedContentType: 'text/html', - createdAt, - updatedAt: createdAt, - expiresAt: new Date(Date.now() + 30 * DAY_MS).toISOString(), - byteSize: 1200, - deletedAt: null - }, - shareUrl: `https://share.onorca.dev/a/${slug}` - } -} - -/** Selection held in state, so whether a click selected is readable off the row's own wash. */ -function SelectingCollection({ items }: { items: ArtifactListItem[] }): React.JSX.Element { - const [selectedSlug, setSelectedSlug] = useState(null) - return ( - - ) -} - -// Include aria-hidden rows behind Radix’s modal menu so assertions can inspect their selection state. -function rowFor(title: string): HTMLElement { - return screen.getByRole('button', { name: new RegExp(title), hidden: true }) -} - -describe('ArtifactCollection', () => { - afterEach(cleanup) - // Restore prototype layout spies or later tests inherit fabricated geometry. - afterEach(() => vi.restoreAllMocks()) - - /** Guard clicks from both descendant triggers and React-bubbling portaled menu items so actions cannot select the row behind them. */ - it('runs a row menu action without selecting the artifact behind the menu', async () => { - const user = userEvent.setup() - const items = [artifact('first', 'First artifact'), artifact('second', 'Second artifact')] - render( - - - - ) - - // Positive control: a click on the row body does select, so the negatives below are not vacuous. - await user.click(rowFor('First artifact')) - expect(rowFor('First artifact')).toHaveAttribute('data-current', 'true') - - const trigger = within(rowFor('Second artifact')).getByRole('button', { - name: 'Artifact actions' - }) - await user.click(trigger) - // Radix mounts menu content only while the menu is open, so a match here is the menu opening. - expect(screen.getByRole('menuitem', { name: 'Copy link' })).toBeInTheDocument() - expect(rowFor('Second artifact')).not.toHaveAttribute('data-current') - - await user.click(screen.getByRole('menuitem', { name: 'Copy link' })) - expect(rowFor('Second artifact')).not.toHaveAttribute('data-current') - expect(rowFor('First artifact')).toHaveAttribute('data-current', 'true') - }) -}) diff --git a/src/renderer/src/components/browser-pane/stream-remote/remote-browser-page-session.test.ts b/src/renderer/src/components/browser-pane/stream-remote/remote-browser-page-session.test.ts deleted file mode 100644 index 3c522a48d7c..00000000000 --- a/src/renderer/src/components/browser-pane/stream-remote/remote-browser-page-session.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { - RemoteBrowserPageSession, - type RemoteBrowserPageHandle, - type RemoteBrowserRpcCall -} from './remote-browser-page-session' -import { RemoteBrowserOperationTokens } from './remote-browser-stream-tokens' - -const layoutOwner = vi.hoisted(() => ({ isMain: true })) -vi.mock('../../../../../shared/layout-owner-switch', () => ({ - get ORCA_LAYOUT_OWNER_IS_MAIN() { - return layoutOwner.isMain - } -})) - -type ShowReply = 'runs' | 'not-found' | 'other-error' - -function rpcError(code: string): Error { - return Object.assign(new Error(code), { code }) -} - -function setup(args: { show: ShowReply; switchOn?: boolean; onShow?: () => void }) { - layoutOwner.isMain = args.switchOn ?? true - const tokens = new RemoteBrowserOperationTokens({ - isMounted: () => true, - isActive: () => true, - getTabId: () => 'host-page-1', - getEnvironmentId: () => 'env-1', - browserPageExists: () => true - }) - const calls: { method: string; params: unknown }[] = [] - const closedMissing: (string | null)[] = [] - let stored: RemoteBrowserPageHandle | null = null - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the fake answers each method with the reply shape its caller reads. - const callRpc = (async (_target: unknown, method: string, params?: unknown) => { - calls.push({ method, params }) - if (method === 'browser.tabShow') { - args.onShow?.() - if (args.show === 'not-found') { - throw rpcError('browser_tab_not_found') - } - if (args.show === 'other-error') { - throw rpcError('request_timeout') - } - return { tab: { url: 'https://example.test/', title: 'Example' } } - } - if (method === 'browser.tabCreate') { - return { browserPageId: 'created-page' } - } - return {} - }) as unknown as RemoteBrowserRpcCall - const session = new RemoteBrowserPageSession({ - tokens, - callRpc, - getWorktreeSelector: () => 'id:wt-1', - readCurrentObservation: () => [], - getCurrentUrl: () => 'about:blank', - readStoredHandle: () => stored, - writeStoredHandle: (handle) => { - stored = handle - }, - removeStoredHandle: () => { - stored = null - }, - applyTabInfo: () => {}, - closeMissingRemotePage: (id) => closedMissing.push(id) - }) - return { - tokens, - calls, - closedMissing, - stored: () => stored, - ensure: () => session.ensureRemotePage(tokens.createOperationToken()!), - methods: () => calls.map((call) => call.method) - } -} - -describe('RemoteBrowserPageSession.ensureRemotePage without a stored handle', () => { - // A timeout or transient failure says nothing about the page; creating would duplicate a live one. - it('surfaces any other probe failure without creating a page', async () => { - const harness = setup({ show: 'other-error' }) - - await expect(harness.ensure()).rejects.toMatchObject({ code: 'request_timeout' }) - - expect(harness.methods()).toEqual(['browser.tabShow']) - expect(harness.tokens.remotePage).toBeNull() - expect(harness.stored()).toBeNull() - expect(harness.closedMissing).toEqual([]) - }) - - it('adopts nothing when the pane moved on during the probe', async () => { - let harness: ReturnType | null = null - harness = setup({ show: 'runs', onShow: () => harness?.tokens.supersedeOperations() }) - - await expect(harness.ensure()).resolves.toBeNull() - - expect(harness.methods()).toEqual(['browser.tabShow']) - expect(harness.stored()).toBeNull() - expect(harness.tokens.remotePage).toBeNull() - }) -}) diff --git a/src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts b/src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts deleted file mode 100644 index c95e0aa261e..00000000000 --- a/src/renderer/src/components/browser-pane/stream-remote/remote-browser-stream-restart-scheduler.test.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { RemoteBrowserStreamRestartScheduler } from './remote-browser-stream-restart-scheduler' - -afterEach(() => { - vi.restoreAllMocks() - vi.useRealTimers() -}) - -describe('RemoteBrowserStreamRestartScheduler', () => { - // The property the pane depends on: retries are finite, and it is told when they run out. An - // unbounded scheduler leaves a dead stream retrying forever behind a recurring error. - it('stops after the budget and reports it exactly once', async () => { - vi.useFakeTimers() - const onExhausted = vi.fn() - const scheduler = new RemoteBrowserStreamRestartScheduler(undefined, onExhausted) - const run = vi.fn(async () => true) - - scheduler.schedule(run) - await vi.advanceTimersByTimeAsync(60_000) - - expect(run).toHaveBeenCalledTimes(5) - expect(onExhausted).toHaveBeenCalledTimes(1) - expect(scheduler.isBudgetExhausted).toBe(true) - expect(scheduler.isScheduled).toBe(false) - - await vi.advanceTimersByTimeAsync(300_000) - expect(run).toHaveBeenCalledTimes(5) - }) - - it('keeps retrying when an attempt rejects rather than dropping the cycle', async () => { - vi.useFakeTimers() - const onExhausted = vi.fn() - const scheduler = new RemoteBrowserStreamRestartScheduler([10, 20, 40], onExhausted) - const run = vi.fn(async () => { - throw new Error('start failed') - }) - - scheduler.schedule(run) - await vi.advanceTimersByTimeAsync(1_000) - - expect(run).toHaveBeenCalledTimes(3) - expect(onExhausted).toHaveBeenCalledTimes(1) - }) - - // Why: clearTimeout cannot recall an attempt already dispatched into an await. Pre-fix, a cancel() - // during that window was a no-op and the resolving attempt re-armed a "cancelled" scheduler. - it('does not re-arm when cancelled while an attempt is already in flight', async () => { - vi.useFakeTimers() - const scheduler = new RemoteBrowserStreamRestartScheduler() - let resolveAttempt: ((shouldRetry: boolean) => void) | undefined - const run = vi.fn( - () => - new Promise((resolve) => { - resolveAttempt = resolve - }) - ) - - scheduler.schedule(run) - await vi.advanceTimersByTimeAsync(500) - expect(run).toHaveBeenCalledTimes(1) - expect(scheduler.isScheduled).toBe(true) - - scheduler.cancel() - resolveAttempt?.(true) // the in-flight attempt reports a transient failure after the cancel - await vi.advanceTimersByTimeAsync(0) - - expect(scheduler.isScheduled).toBe(false) - await vi.advanceTimersByTimeAsync(60_000) - expect(run).toHaveBeenCalledTimes(1) - }) - - it('queues one replacement chain while the current attempt is in flight', async () => { - vi.useFakeTimers() - const scheduler = new RemoteBrowserStreamRestartScheduler([10, 20]) - let resolveAttempt: ((shouldRetry: boolean) => void) | undefined - const firstRun = vi.fn( - () => - new Promise((resolve) => { - resolveAttempt = resolve - }) - ) - const replacementRun = vi.fn(async () => false) - - scheduler.schedule(firstRun) - await vi.advanceTimersByTimeAsync(10) - scheduler.schedule(replacementRun) - - expect(scheduler.attemptCount).toBe(1) - resolveAttempt?.(false) - await vi.advanceTimersByTimeAsync(20) - - expect(firstRun).toHaveBeenCalledTimes(1) - expect(replacementRun).toHaveBeenCalledTimes(1) - expect(scheduler.isScheduled).toBe(false) - }) -}) diff --git a/src/renderer/src/components/browser-pane/stream-remote/use-remote-browser-stream-activation.test.ts b/src/renderer/src/components/browser-pane/stream-remote/use-remote-browser-stream-activation.test.ts deleted file mode 100644 index a9aa3e0d21a..00000000000 --- a/src/renderer/src/components/browser-pane/stream-remote/use-remote-browser-stream-activation.test.ts +++ /dev/null @@ -1,96 +0,0 @@ -// @vitest-environment happy-dom - -import { act, cleanup, renderHook } from '@testing-library/react' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { resetStaleDocumentVisibilityForTesting } from '../../terminal-pane/viewport/visibility/stale-document-visibility' -import { WINDOW_STREAM_PARK_DELAY_MS } from '@/hooks/use-window-stream-visibility' -import { useRemoteBrowserStreamActivation } from './use-remote-browser-stream-activation' - -function setDocumentVisibility(state: 'visible' | 'hidden'): void { - Object.defineProperty(document, 'visibilityState', { - configurable: true, - get: () => state - }) - document.dispatchEvent(new Event('visibilitychange')) -} - -function renderActivation(isActive = true, stagedPage = false) { - const closeStream = vi.fn() - const open = vi.fn(() => closeStream) - const lifecycle = { open } - const clearPendingRemoteWheel = vi.fn() - const hook = renderHook( - ({ active, staged }) => - useRemoteBrowserStreamActivation({ - activeRuntimeEnvironmentId: 'env-1', - browserPageId: 'page-1', - clearPendingRemoteWheel, - isActive: active, - lifecycle, - reopenNonce: 0, - runtimeWorktree: 'worktree:one', - stagedPage: staged - }), - { initialProps: { active: isActive, staged: stagedPage } } - ) - return { ...hook, clearPendingRemoteWheel, closeStream, open } -} - -describe('useRemoteBrowserStreamActivation', () => { - beforeEach(() => { - vi.useFakeTimers() - setDocumentVisibility('visible') - }) - - afterEach(() => { - cleanup() - setDocumentVisibility('visible') - resetStaleDocumentVisibilityForTesting() - vi.useRealTimers() - vi.restoreAllMocks() - }) - - it('parks after the grace period and reopens when stale visibility is disproven', async () => { - vi.spyOn(console, 'warn').mockImplementation(() => {}) - const harness = renderActivation() - expect(harness.open).toHaveBeenCalledTimes(1) - - await act(async () => setDocumentVisibility('hidden')) - await act(async () => vi.advanceTimersByTime(WINDOW_STREAM_PARK_DELAY_MS - 1)) - expect(harness.closeStream).not.toHaveBeenCalled() - - await act(async () => vi.advanceTimersByTime(1)) - expect(harness.closeStream).toHaveBeenCalledTimes(1) - expect(harness.clearPendingRemoteWheel).toHaveBeenCalledTimes(1) - - await act(async () => { - document.dispatchEvent(new KeyboardEvent('keydown', { key: 'a' })) - }) - expect(document.visibilityState).toBe('hidden') - expect(harness.open).toHaveBeenCalledTimes(2) - }) - - // Opening a staged page would race its pending create and could close the optimistic tab on failure. - it('does not open a stream for an optimistically staged page', async () => { - const harness = renderActivation(true, true) - expect(harness.open).not.toHaveBeenCalled() - - await act(async () => harness.rerender({ active: true, staged: false })) - expect(harness.open).toHaveBeenCalledTimes(1) - }) - - // Parked unmount has no stream cleanup left; disposed lifecycles must not reopen on window return. - it('stays closed when its tab is closed while the stream is parked', async () => { - const harness = renderActivation() - - await act(async () => setDocumentVisibility('hidden')) - await act(async () => vi.advanceTimersByTime(WINDOW_STREAM_PARK_DELAY_MS)) - expect(harness.closeStream).toHaveBeenCalledTimes(1) - - await act(async () => harness.unmount()) - await act(async () => setDocumentVisibility('visible')) - - expect(harness.open).toHaveBeenCalledTimes(1) - expect(harness.closeStream).toHaveBeenCalledTimes(1) - }) -}) diff --git a/src/renderer/src/components/crash-report/use-crash-report-copy.test.tsx b/src/renderer/src/components/crash-report/use-crash-report-copy.test.tsx deleted file mode 100644 index d52f27718b3..00000000000 --- a/src/renderer/src/components/crash-report/use-crash-report-copy.test.tsx +++ /dev/null @@ -1,115 +0,0 @@ -// @vitest-environment happy-dom - -import { act, cleanup, renderHook } from '@testing-library/react' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { toast } from 'sonner' -import type { - CrashReportCopySubmissionFailure, - CrashReportRecord -} from '../../../../shared/crash-reporting' -import { CRASH_REPORT_COPY_FAILURE_TOAST_ID, useCrashReportCopy } from './use-crash-report-copy' - -const copyLatestDiagnostics = vi.fn() - -vi.mock('sonner', () => ({ - toast: { - dismiss: vi.fn(), - error: vi.fn(), - success: vi.fn() - } -})) - -function report(id = 'crash-1'): CrashReportRecord { - return { - id, - createdAt: '2026-05-16T01:00:00.000Z', - status: 'pending', - source: 'renderer', - processType: 'renderer', - reason: 'crashed', - exitCode: 5, - appVersion: '1.0.0', - platform: 'win32', - osRelease: 'test', - arch: 'x64', - electronVersion: '41', - chromeVersion: '141', - details: {} - } -} - -beforeEach(() => { - vi.clearAllMocks() - copyLatestDiagnostics.mockResolvedValue({ ok: true }) - Object.defineProperty(window, 'api', { - configurable: true, - value: { crashReports: { copyLatestDiagnostics } } - }) -}) - -afterEach(() => { - cleanup() - vi.restoreAllMocks() -}) - -describe('useCrashReportCopy', () => { - it('uses the latest edited notes from an older failure-toast action', async () => { - const failure: CrashReportCopySubmissionFailure = { - error: 'report request timed out', - diagnosticContext: { status: 'not_uploaded', reason: 'logs timed out' } - } - const { result, rerender } = renderHook(({ notes }) => useCrashReportCopy(report(), notes), { - initialProps: { notes: 'notes at submit' } - }) - const failureToastCopyAction = result.current - - rerender({ notes: 'notes edited while waiting' }) - await act(async () => failureToastCopyAction(failure)) - - expect(copyLatestDiagnostics).toHaveBeenCalledWith({ - reportId: 'crash-1', - notes: 'notes edited while waiting', - submissionFailure: failure - }) - }) - - it("does not combine an older report action with a newer report's notes", async () => { - const { result, rerender } = renderHook( - ({ currentReport, notes }) => useCrashReportCopy(currentReport, notes), - { - initialProps: { - currentReport: report('crash-a'), - notes: 'latest notes for A' - } - } - ) - const reportACopyAction = result.current - - rerender({ currentReport: report('crash-b'), notes: 'private notes for B' }) - await act(async () => reportACopyAction()) - - expect(copyLatestDiagnostics).toHaveBeenCalledWith({ - reportId: 'crash-a', - notes: 'latest notes for A' - }) - expect(JSON.stringify(copyLatestDiagnostics.mock.calls)).not.toContain('private notes for B') - }) - - it('shows a safe sticky error toast when copy IPC rejects', async () => { - copyLatestDiagnostics.mockRejectedValueOnce( - new Error('renderer destroyed with token=must-not-be-shown') - ) - vi.spyOn(console, 'error').mockImplementation(() => {}) - const { result } = renderHook(() => useCrashReportCopy(report(), 'current notes')) - - await act(async () => result.current()) - - expect(toast.error).toHaveBeenCalledWith('Crash report details could not be copied.', { - id: CRASH_REPORT_COPY_FAILURE_TOAST_ID, - duration: Infinity, - dismissible: true - }) - expect(JSON.stringify(vi.mocked(toast.error).mock.calls)).not.toContain('must-not-be-shown') - expect(toast.success).not.toHaveBeenCalled() - }) -}) diff --git a/src/renderer/src/components/dictation/dictation-insertion-target.test.ts b/src/renderer/src/components/dictation/dictation-insertion-target.test.ts deleted file mode 100644 index 703cfe5e473..00000000000 --- a/src/renderer/src/components/dictation/dictation-insertion-target.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -// @vitest-environment happy-dom - -import { afterEach, describe, expect, it, vi } from 'vitest' - -import { - TEXT_CONTROL_PASTE_DIRECT_MAX_BYTES, - TEXT_CONTROL_PASTE_MAX_BYTES -} from '@/lib/text-input/paste/text-control-paste-model' -import { captureInsertionTarget, insertText } from './dictation-insertion-target' - -type DocumentWithExecCommand = Document & { - execCommand?: (commandId: string, showUi?: boolean, value?: string) => boolean -} - -const originalExecCommand = (document as DocumentWithExecCommand).execCommand - -afterEach(() => { - document.body.replaceChildren() - vi.useRealTimers() - vi.restoreAllMocks() - vi.unstubAllGlobals() - Object.defineProperty(document, 'execCommand', { - configurable: true, - value: originalExecCommand - }) -}) - -function appendContentEditable(): HTMLElement { - const element = document.createElement('div') - element.contentEditable = 'true' - element.tabIndex = 0 - document.body.appendChild(element) - element.focus() - return element -} - -function installExecCommandMock( - implementation: (commandId: string, showUi?: boolean, value?: string) => boolean -): ReturnType { - const execCommand = vi.fn(implementation) - Object.defineProperty(document, 'execCommand', { - configurable: true, - value: execCommand - }) - return execCommand -} - -describe('dictation insertion target', () => { - it('sends text dictated into a focused browser page to that page', async () => { - const insertDictationText = vi.fn(async () => true) - vi.stubGlobal('api', { browser: { insertDictationText } }) - const viewport = document.createElement('div') - viewport.dataset.browserPageViewportId = 'page-1' - const guest = document.createElement('webview') - guest.tabIndex = 0 - viewport.appendChild(guest) - document.body.appendChild(viewport) - guest.focus() - - const target = captureInsertionTarget() - expect(target).toEqual({ kind: 'browser', browserPageId: 'page-1' }) - await expect(insertText('hello', target!)).resolves.toBe(true) - - expect(insertDictationText).toHaveBeenCalledWith({ browserPageId: 'page-1', text: 'hello' }) - }) - - it('cancels chunked contenteditable dictation when the target disconnects', async () => { - vi.useFakeTimers() - const editor = appendContentEditable() - const execCommand = installExecCommandMock(() => { - editor.remove() - return true - }) - const text = 'x'.repeat(TEXT_CONTROL_PASTE_DIRECT_MAX_BYTES + 1) - - insertText(text, { kind: 'contentEditable', element: editor }) - await vi.runAllTimersAsync() - - expect(execCommand).toHaveBeenCalledTimes(1) - }) - - it('rejects oversized multibyte contenteditable dictation before inserting', async () => { - vi.useFakeTimers() - const editor = appendContentEditable() - const beforeInputEvents: InputEvent[] = [] - editor.addEventListener('beforeinput', (event) => beforeInputEvents.push(event as InputEvent)) - const execCommand = installExecCommandMock(() => true) - const text = '😀'.repeat(Math.floor(TEXT_CONTROL_PASTE_MAX_BYTES / 4) + 1) - - insertText(text, { kind: 'contentEditable', element: editor }) - await vi.runAllTimersAsync() - - expect(execCommand).not.toHaveBeenCalled() - expect(beforeInputEvents).toHaveLength(0) - expect(editor.textContent).toBe('') - }) -}) diff --git a/src/renderer/src/components/diff-comments/DiffCommentDraftCard.test.tsx b/src/renderer/src/components/diff-comments/DiffCommentDraftCard.test.tsx deleted file mode 100644 index f13ee788f2c..00000000000 --- a/src/renderer/src/components/diff-comments/DiffCommentDraftCard.test.tsx +++ /dev/null @@ -1,94 +0,0 @@ -// @vitest-environment happy-dom -import { act, cleanup, fireEvent, render } from '@testing-library/react' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { toast } from 'sonner' -import { DiffCommentDraftCard } from './DiffCommentDraftCard' - -vi.mock('sonner', () => ({ toast: { error: vi.fn(), success: vi.fn(), info: vi.fn() } })) - -describe('DiffCommentDraftCard', () => { - let scrollHeight = 60 - - beforeEach(() => { - scrollHeight = 60 - vi.spyOn(HTMLTextAreaElement.prototype, 'scrollHeight', 'get').mockImplementation( - () => scrollHeight - ) - }) - - afterEach(() => { - cleanup() - vi.restoreAllMocks() - }) - - it('parks focus on the textarea before the pressed submit button turns disabled', async () => { - let resolveSubmit: (result: boolean) => void = () => {} - const onSubmit = vi.fn( - () => - new Promise((resolve) => { - resolveSubmit = resolve - }) - ) - const view = render( - - ) - const textarea = view.getByRole('textbox') - fireEvent.change(textarea, { target: { value: 'Pending note' } }) - const submitBtn = view.getByRole('button', { name: 'Add note' }) - submitBtn.focus() - expect(document.activeElement).toBe(submitBtn) - fireEvent.click(submitBtn) - - // Disabled buttons drop Chromium focus to body; preserve card focus so successful saves can return it to Monaco. - expect(onSubmit).toHaveBeenCalledTimes(1) - expect(submitBtn.hasAttribute('disabled')).toBe(true) - expect(document.activeElement).toBe(textarea) - - await act(async () => resolveSubmit(true)) - }) - - it('submits Cmd+Shift+Enter and ignores duplicate submits while pending', async () => { - let resolveSubmit: (result: boolean) => void = () => {} - const onSubmit = vi.fn( - () => - new Promise((resolve) => { - resolveSubmit = resolve - }) - ) - const onCancel = vi.fn() - const view = render( - - ) - const textarea = view.getByRole('textbox') - fireEvent.change(textarea, { target: { value: 'Pending note' } }) - const submitButton = view.getByRole('button', { name: 'Add note' }) - - fireEvent.keyDown(textarea, { key: 'Enter', metaKey: true, shiftKey: true }) - fireEvent.click(submitButton) - fireEvent.keyDown(textarea, { key: 'Escape' }) - - expect(onSubmit).toHaveBeenCalledTimes(1) - expect(view.getByRole('button', { name: 'Cancel' }).hasAttribute('disabled')).toBe(true) - expect(onCancel).not.toHaveBeenCalled() - - await act(async () => resolveSubmit(true)) - }) - - it('reports a rejected save to the user and re-enables the card', async () => { - const error = new Error('network down') - const onSubmit = vi.fn().mockRejectedValue(error) - const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - const view = render( - - ) - fireEvent.change(view.getByRole('textbox'), { target: { value: 'Rejected note' } }) - - await act(async () => { - fireEvent.click(view.getByRole('button', { name: 'Add note' })) - }) - - expect(toast.error).toHaveBeenCalledWith('Failed to save comment') - expect(consoleError).toHaveBeenCalled() - expect(view.getByRole('button', { name: 'Add note' }).hasAttribute('disabled')).toBe(false) - }) -}) diff --git a/src/renderer/src/components/editor/combined-diff/remember-view/combined-diff-view-cache.test.ts b/src/renderer/src/components/editor/combined-diff/remember-view/combined-diff-view-cache.test.ts deleted file mode 100644 index 012d75470d4..00000000000 --- a/src/renderer/src/components/editor/combined-diff/remember-view/combined-diff-view-cache.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { afterEach, describe, expect, it } from 'vitest' -import { - claimCombinedDiffView, - clearCombinedDiffViewMemory, - forgetCombinedDiffViewsForWorktrees, - readCombinedDiffViewMemory, - releaseCombinedDiffView, - rememberCombinedDiffView, - type CombinedDiffViewSuccession -} from './combined-diff-view-cache' - -const worktreeId = 'repo::/workspace/a' -const contentKey = `${worktreeId}::all-diffs::uncommitted` - -function succession( - scopeId: string, - openScopes: readonly string[] = [scopeId], - content = contentKey -): CombinedDiffViewSuccession { - return { contentKey: content, scopeId, isScopeOpen: (id) => openScopes.includes(id) } -} - -function keyFor(scopeId: string, content = contentKey): string { - return `${content}::${scopeId}` -} - -function viewThenUnmount(scopeId: string, scrollTop: number, content = contentKey): void { - const lease = claimCombinedDiffView( - keyFor(scopeId, content), - worktreeId, - succession(scopeId, [scopeId], content) - ) - releaseCombinedDiffView(lease) - // Mirror unmount ordering: snapshot after releasing mount tracking. - rememberCombinedDiffView(lease, { scrollTop }) -} - -afterEach(() => { - clearCombinedDiffViewMemory() -}) - -describe('combined diff view succession', () => { - it('moves a closed tab view to the fresh tab that reopens the same diff', () => { - viewThenUnmount('tab-1', 640) - - const nextKey = keyFor('tab-2') - expect( - readCombinedDiffViewMemory(nextKey, { worktreeId, succession: succession('tab-2') }) - ?.scrollTop - ).toBe(640) - - claimCombinedDiffView(nextKey, worktreeId, succession('tab-2')) - - expect(readCombinedDiffViewMemory(nextKey)?.scrollTop).toBe(640) - expect(readCombinedDiffViewMemory(keyFor('tab-1'))).toBeUndefined() - }) - - it('never takes the view of a viewer that is still mounted', () => { - const mounted = claimCombinedDiffView(keyFor('tab-1'), worktreeId, succession('tab-1')) - rememberCombinedDiffView(mounted, { scrollTop: 320 }) - - // The mounted tab's scope already reads as closed, so only the lease protects it. - claimCombinedDiffView(keyFor('tab-2'), worktreeId, succession('tab-2')) - - expect(readCombinedDiffViewMemory(keyFor('tab-2'))).toBeUndefined() - expect(readCombinedDiffViewMemory(keyFor('tab-1'))?.scrollTop).toBe(320) - }) - - it('inherits the latest closed view and drops older ones for the same diff', () => { - viewThenUnmount('tab-1', 100) - viewThenUnmount('tab-2', 200) - - claimCombinedDiffView(keyFor('tab-3'), worktreeId, succession('tab-3')) - - expect(readCombinedDiffViewMemory(keyFor('tab-3'))?.scrollTop).toBe(200) - expect(readCombinedDiffViewMemory(keyFor('tab-1'))).toBeUndefined() - expect(readCombinedDiffViewMemory(keyFor('tab-2'))).toBeUndefined() - }) - - it('leaves nothing to inherit once the workspace is forgotten', () => { - viewThenUnmount('tab-1', 640) - forgetCombinedDiffViewsForWorktrees([worktreeId]) - - claimCombinedDiffView(keyFor('tab-2'), worktreeId, succession('tab-2')) - - expect(readCombinedDiffViewMemory(keyFor('tab-2'))).toBeUndefined() - }) -}) diff --git a/src/renderer/src/components/editor/markdown-preview/document-worker/use-markdown-preview-document.test.tsx b/src/renderer/src/components/editor/markdown-preview/document-worker/use-markdown-preview-document.test.tsx deleted file mode 100644 index cc44f977a15..00000000000 --- a/src/renderer/src/components/editor/markdown-preview/document-worker/use-markdown-preview-document.test.tsx +++ /dev/null @@ -1,176 +0,0 @@ -// @vitest-environment happy-dom -import { act, cleanup, renderHook } from '@testing-library/react' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { useMarkdownPreviewDocument } from './use-markdown-preview-document' -import type { MarkdownPreviewWorkerResult } from './markdown-preview-document-types' - -class PreviewWorker extends EventTarget implements Worker { - static instances: PreviewWorker[] = [] - onmessage: Worker['onmessage'] = null - onerror: Worker['onerror'] = null - onmessageerror: Worker['onmessageerror'] = null - postMessage = vi.fn<(message: unknown) => void>() - terminate = vi.fn() - constructor() { - super() - PreviewWorker.instances.push(this) - } - reply(result: MarkdownPreviewWorkerResult): void { - this.onmessage?.(new MessageEvent('message', { data: result })) - } - loaded(): void { - this.reply({ id: 1, type: 'loaded', document: { blocks: [], toc: [] } }) - } -} - -function harness(content = 'first') { - return renderHook(({ content, enabled }) => useMarkdownPreviewDocument(content, enabled), { - initialProps: { content, enabled: true } - }) -} -async function finish(worker: PreviewWorker): Promise { - await act(async () => worker.loaded()) -} -async function advance(): Promise { - await act(async () => vi.advanceTimersByTimeAsync(150)) -} - -beforeEach(() => { - vi.useFakeTimers() - PreviewWorker.instances = [] - vi.stubGlobal('Worker', PreviewWorker) -}) -afterEach(() => { - cleanup() - vi.unstubAllGlobals() - vi.useRealTimers() -}) - -describe('large Markdown revision ownership', () => { - it('debounces edits and never retains more than a displayed and replacement worker', async () => { - const { result, rerender } = harness() - const first = PreviewWorker.instances[0] - await finish(first) - rerender({ content: 'second', enabled: true }) - rerender({ content: 'third', enabled: true }) - expect(PreviewWorker.instances).toHaveLength(1) - await advance() - const replacement = PreviewWorker.instances[1] - expect(replacement.postMessage).toHaveBeenCalledWith({ id: 1, type: 'load', content: 'third' }) - const lateReply = replacement.onmessage - rerender({ content: 'fourth', enabled: true }) - expect(replacement.terminate).toHaveBeenCalledOnce() - await advance() - const current = PreviewWorker.instances[2] - await act(async () => - lateReply?.call( - replacement, - new MessageEvent('message', { - data: { id: 1, type: 'loaded', document: { blocks: [], toc: [] } } - }) - ) - ) - expect(result.current).toMatchObject({ status: 'ready', content: 'first', refreshing: true }) - expect( - PreviewWorker.instances.filter((worker) => !worker.terminate.mock.calls.length) - ).toHaveLength(2) - await finish(current) - expect(result.current).toMatchObject({ status: 'ready', content: 'fourth', refreshing: false }) - expect(first.terminate).toHaveBeenCalledOnce() - }) - - it('keeps the old view with an explicit refresh failure and recovers on the next edit', async () => { - const { result, rerender } = harness() - const first = PreviewWorker.instances[0] - await finish(first) - rerender({ content: 'second', enabled: true }) - await advance() - await act(async () => - PreviewWorker.instances[1].reply({ id: 1, type: 'error', message: 'Too complex' }) - ) - expect(result.current).toMatchObject({ - status: 'ready', - content: 'first', - refreshing: true, - refreshError: 'Too complex' - }) - expect(first.terminate).not.toHaveBeenCalled() - rerender({ content: 'third', enabled: true }) - expect(result.current.refreshError).toBeNull() - await advance() - await finish(PreviewWorker.instances[2]) - expect(result.current).toMatchObject({ status: 'ready', content: 'third', refreshError: null }) - }) - - it('cancels a pending replacement when content returns to the displayed revision', async () => { - const { result, rerender } = harness() - await finish(PreviewWorker.instances[0]) - rerender({ content: 'second', enabled: true }) - await advance() - rerender({ content: 'first', enabled: true }) - expect(PreviewWorker.instances[1].terminate).toHaveBeenCalledOnce() - expect(result.current).toMatchObject({ status: 'ready', content: 'first', refreshing: false }) - }) - - it('closes displayed and replacement workers on unmount without stale state updates', async () => { - const { rerender, unmount } = harness() - await finish(PreviewWorker.instances[0]) - rerender({ content: 'second', enabled: true }) - await advance() - unmount() - await act(async () => {}) - expect( - PreviewWorker.instances.every((worker) => worker.terminate.mock.calls.length === 1) - ).toBe(true) - expect(vi.getTimerCount()).toBe(0) - }) - it('captures the displayed revision before swapping and advances only completed revisions', async () => { - let displayedContent: string | null = null - const captured: (string | null)[] = [] - const beforeSwap = () => captured.push(displayedContent) - const { result, rerender } = renderHook( - ({ content }) => { - const state = useMarkdownPreviewDocument(content, true, beforeSwap) - displayedContent = state.status === 'ready' ? state.content : null - return state - }, - { initialProps: { content: 'first' } } - ) - await finish(PreviewWorker.instances[0]) - expect(result.current).toMatchObject({ revision: 1 }) - rerender({ content: 'second' }) - await advance() - await finish(PreviewWorker.instances[1]) - expect(captured).toEqual([null, 'first']) - expect(result.current).toMatchObject({ content: 'second', revision: 2 }) - }) - - it('removes an unusable displayed client if its worker fails during replacement', async () => { - const { result, rerender } = harness() - const first = PreviewWorker.instances[0] - await finish(first) - rerender({ content: 'second', enabled: true }) - await advance() - await act(async () => first.onerror?.(new ErrorEvent('error'))) - expect(result.current.status).toBe('loading') - expect(first.terminate).toHaveBeenCalledOnce() - await finish(PreviewWorker.instances[1]) - expect(result.current).toMatchObject({ status: 'ready', content: 'second', refreshError: null }) - }) - it('reenables the same content with a fresh worker after a failed replacement', async () => { - const { result, rerender } = harness() - await finish(PreviewWorker.instances[0]) - rerender({ content: 'second', enabled: true }) - await advance() - await act(async () => - PreviewWorker.instances[1].reply({ id: 1, type: 'error', message: 'Too complex' }) - ) - rerender({ content: 'second', enabled: false }) - expect(result.current).toMatchObject({ status: 'loading', refreshError: null }) - rerender({ content: 'second', enabled: true }) - expect(result.current).toMatchObject({ status: 'loading', refreshError: null }) - expect(PreviewWorker.instances).toHaveLength(3) - await finish(PreviewWorker.instances[2]) - expect(result.current).toMatchObject({ status: 'ready', content: 'second', refreshError: null }) - }) -}) diff --git a/src/renderer/src/components/editor/markdown-source-tools/monaco/monaco-markdown-doc-completions-retention.test.ts b/src/renderer/src/components/editor/markdown-source-tools/monaco/monaco-markdown-doc-completions-retention.test.ts deleted file mode 100644 index 244807801c3..00000000000 --- a/src/renderer/src/components/editor/markdown-source-tools/monaco/monaco-markdown-doc-completions-retention.test.ts +++ /dev/null @@ -1,190 +0,0 @@ -// @vitest-environment happy-dom -import { afterEach, describe, expect, it, vi } from 'vitest' -import { cleanup, render } from '@testing-library/react' -import { createElement, useLayoutEffect, useRef } from 'react' -import type { MarkdownDocument } from '../../../../../../shared/file-listing/file-document' -import { useMonacoEditorDecorations } from '../../monaco/use-monaco-editor-decorations' -import type { editor, languages, Position } from 'monaco-editor' -import type { OnMount } from '@monaco-editor/react' -import { - ensureMarkdownDocCompletionProvider, - setMarkdownDocCompletionDocuments, - clearMarkdownDocCompletionDocuments -} from './monaco-markdown-doc-completions' - -afterEach(cleanup) - -type MonacoApi = Parameters[1] - -function model(key: string): editor.ITextModel { - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Completion uses only URI and line content from this model fixture. - return { - uri: { toString: () => key }, - getLineContent: () => '[[Ta' - } as unknown as editor.ITextModel -} - -function register() { - let current: languages.CompletionItemProvider | undefined - const api = { - languages: { - CompletionItemKind: { File: 1 }, - registerCompletionItemProvider: vi.fn( - (_language: string, provider: languages.CompletionItemProvider) => { - current = provider - return { dispose() {} } - } - ) - } - } - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: The provider registers and reads only this languages API and completion kind. - ensureMarkdownDocCompletionProvider(api as unknown as MonacoApi) - return async (textModel: editor.ITextModel) => { - if (!current) { - throw new Error('Missing provider') - } - const position: Position = { - lineNumber: 1, - column: 5, - with: () => position, - delta: () => position, - equals: () => false, - isBefore: () => false, - isBeforeOrEqual: () => false, - clone: () => position, - toString: () => '(1,5)', - toJSON: () => ({ lineNumber: 1, column: 5 }) - } - const result = await current.provideCompletionItems( - textModel, - position, - { triggerKind: 0 }, - { - isCancellationRequested: false, - onCancellationRequested: () => ({ dispose() {} }) - } - ) - return result?.suggestions ?? [] - } -} - -function documents(name: string) { - return [ - { - filePath: `/repo/${name}.md`, - relativePath: `${name}.md`, - basename: `${name}.md`, - name - } - ] -} - -describe('live Markdown completion ownership', () => { - it('preserves every mounted model when many other scopes are supplied', async () => { - const complete = register() - const active = model('active') - const owner = Symbol() - setMarkdownDocCompletionDocuments(active, documents('Target'), owner) - for (let scope = 0; scope < 300; scope++) { - const other = model(`scope-${scope}`) - setMarkdownDocCompletionDocuments(other, documents(`Target-${scope}`), Symbol()) - } - expect((await complete(active)).map((item) => item.label)).toEqual(['Target']) - clearMarkdownDocCompletionDocuments(active, owner) - expect(await complete(active)).toEqual([]) - }) - - it('keeps different model incarnations separate even when their URI is identical', async () => { - const complete = register() - const old = model('same-uri') - const owner = Symbol() - const current = model('same-uri') - setMarkdownDocCompletionDocuments(old, documents('Target old'), owner) - setMarkdownDocCompletionDocuments(current, documents('Target current'), owner) - clearMarkdownDocCompletionDocuments(old, owner) - expect((await complete(current)).map((item) => item.label)).toEqual(['Target current']) - }) -}) - -function Pane({ - textModel, - catalog, - language = 'markdown' -}: { - textModel: editor.ITextModel - catalog: MarkdownDocument[] - language?: string -}): null { - const editorRef = useRef(null) - // Layout effects commit before the hook's passive effects read the editor. - useLayoutEffect(() => { - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: completion registration only reads the editor's model in this hook fixture. - editorRef.current = { - getModel: () => textModel - } as editor.IStandaloneCodeEditor - }, [textModel]) - useMonacoEditorDecorations({ - editorRef, - mountedEditor: null, - content: '[[Ta', - language, - markdownDocuments: catalog, - conflictDecorationsEnabled: false - }) - return null -} - -describe('pane-owned Markdown completion catalogs', () => { - it('preserves a shared-model survivor and releases its catalog on last close', async () => { - const complete = register() - const shared = model('shared') - const catalog = documents('Target') - const first = render(createElement(Pane, { textModel: shared, catalog })) - const second = render(createElement(Pane, { textModel: shared, catalog })) - expect((await complete(shared)).map((item) => item.label)).toEqual(['Target']) - - first.unmount() - expect((await complete(shared)).map((item) => item.label)).toEqual(['Target']) - second.rerender( - createElement(Pane, { - textModel: shared, - catalog: documents('Target next') - }) - ) - expect((await complete(shared)).map((item) => item.label)).toEqual(['Target next']) - second.unmount() - expect(await complete(shared)).toEqual([]) - }) - - it('restores surviving catalogs on language changes and isolates replacement models', async () => { - const complete = register() - const shared = model('same-uri') - const replacement = model('same-uri') - const first = render( - createElement(Pane, { - textModel: shared, - catalog: documents('Target first') - }) - ) - const catalog = documents('Target second') - const second = render(createElement(Pane, { textModel: shared, catalog })) - expect((await complete(shared)).map((item) => item.label)).toEqual(['Target second']) - - second.rerender( - createElement(Pane, { - textModel: shared, - catalog, - language: 'plaintext' - }) - ) - expect((await complete(shared)).map((item) => item.label)).toEqual(['Target first']) - second.rerender(createElement(Pane, { textModel: replacement, catalog })) - expect((await complete(shared)).map((item) => item.label)).toEqual(['Target first']) - expect((await complete(replacement)).map((item) => item.label)).toEqual(['Target second']) - second.unmount() - expect(await complete(replacement)).toEqual([]) - expect((await complete(shared)).map((item) => item.label)).toEqual(['Target first']) - first.unmount() - expect(await complete(shared)).toEqual([]) - }) -}) diff --git a/src/renderer/src/components/editor/notebook/kernel/ipynb-kernel-output-budget.test.ts b/src/renderer/src/components/editor/notebook/kernel/ipynb-kernel-output-budget.test.ts deleted file mode 100644 index 53fc131f313..00000000000 --- a/src/renderer/src/components/editor/notebook/kernel/ipynb-kernel-output-budget.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { describe, expect, it } from 'vitest' -import type { KernelOutputType } from '../../../../../../shared/notebook-kernel-types' -import { parseIpynbOutput } from '../document/ipynb-parse' -import { applyKernelOutput, toStoredOutputs, type LiveOutputs } from './ipynb-kernel-outputs' - -const EMPTY: LiveOutputs = { outputs: [], clearOnNextOutput: false } -type Frame = [KernelOutputType, Record] - -function apply(frames: Frame[], live = EMPTY): LiveOutputs { - return frames.reduce( - (current, [type, content]) => applyKernelOutput(current, type, content), - live - ) -} - -// 2.5 MiB of stdout in 64 KiB chunks. -function flood(): LiveOutputs { - const chunk = 'x'.repeat(65536) - return apply(Array.from({ length: 40 }, (): Frame => ['stream', { name: 'stdout', text: chunk }])) -} - -describe('notebook cell output budget', () => { - it('keeps the first 2 MiB of stream text, then one notice, and drops later chunks', () => { - const live = flood() - expect(live.outputs).toHaveLength(2) - expect(live.outputs[0]).toEqual({ - output_type: 'stream', - name: 'stdout', - text: 'x'.repeat(2097152) - }) - expect(live.outputs[1]?.output_type).toBe('display_data') - expect(toStoredOutputs(live.outputs)).toEqual(live.outputs) - - const after = apply( - [ - ['stream', { name: 'stdout', text: 'more' }], - ['stream', { name: 'stderr', text: 'warn' }] - ], - live - ) - expect(after).toBe(live) - }) - - it('leaves the previous display in place when its update does not fit', () => { - const live = apply([ - [ - 'display_data', - { data: { 'text/plain': '0%' }, metadata: {}, transient: { display_id: 'p' } } - ], - [ - 'update_display_data', - { - data: { 'image/png': 'A'.repeat(16777216) }, - metadata: {}, - transient: { display_id: 'p' } - } - ] - ]) - expect(live.outputs).toHaveLength(2) - expect(live.outputs[0]?.data).toEqual({ 'text/plain': '0%' }) - expect(live.outputs[1]?.output_type).toBe('display_data') - }) - - it('keeps the first error after truncation with its summary visible live and saved', () => { - const live = applyKernelOutput(flood(), 'error', { - ename: 'ValueError', - evalue: 'Set API_TOKEN first.', - traceback: ['Traceback (most recent call last):', 'z'.repeat(33554432), 'ValueError: ...'] - }) - expect(live.outputs.map((output) => output.output_type)).toEqual([ - 'stream', - 'display_data', - 'error' - ]) - const saved = toStoredOutputs(live.outputs) - expect(saved).toEqual(live.outputs) - const parsed = parseIpynbOutput(saved[2]) - if (parsed?.kind !== 'error') { - throw new Error('Expected an error output') - } - expect(parsed.traceback.startsWith('Traceback (most recent call last):\nzzz')).toBe(true) - expect(parsed.traceback.endsWith('\nValueError: Set API_TOKEN first.')).toBe(true) - }) -}) diff --git a/src/renderer/src/components/editor/rich-markdown/images/rich-markdown-image-attributes.test.ts b/src/renderer/src/components/editor/rich-markdown/images/rich-markdown-image-attributes.test.ts deleted file mode 100644 index 7cf2acbe775..00000000000 --- a/src/renderer/src/components/editor/rich-markdown/images/rich-markdown-image-attributes.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -// @vitest-environment happy-dom -import { Editor } from '@tiptap/core' -import { afterEach, beforeEach, expect, it, vi } from 'vitest' -import { createRichMarkdownExtensions } from '../schema/rich-markdown-extensions' -import { setRichMarkdownImageResolverContext } from './rich-markdown-image-context' -import { createRichMarkdownEditorCodec } from '../document/rich-markdown-source-transport' -import '../../document-images/useLocalImageSrc' -import { resetLocalImageCacheState as resetLocalImageSrcStateForTests } from '../../document-images/local-image-src-cache' - -const readFile = vi.fn() -const originalApi = Object.getOwnPropertyDescriptor(window, 'api') -let editor: Editor | undefined - -function updateImage(attributes: Record): void { - const node = editor?.state.doc.nodeAt(1) - if (!editor || !node) { - throw new Error('Image node missing') - } - editor.view.dispatch( - editor.state.tr.setNodeMarkup(1, undefined, { ...node.attrs, ...attributes }) - ) -} - -beforeEach(() => { - resetLocalImageSrcStateForTests() - readFile.mockReset().mockResolvedValue({ content: 'AA==', isBinary: true, mimeType: 'image/png' }) - Object.defineProperty(window, 'api', { configurable: true, value: { fs: { readFile } } }) - vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:attributes') - vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => {}) -}) - -afterEach(() => { - editor?.destroy() - editor = undefined - resetLocalImageSrcStateForTests() - vi.restoreAllMocks() - if (originalApi) { - Object.defineProperty(window, 'api', originalApi) - } else { - Reflect.deleteProperty(window, 'api') - } - document.body.innerHTML = '' -}) - -it('syncs changed and cleared metadata onto the mounted image without reloading it', async () => { - const host = document.createElement('div') - document.body.appendChild(host) - editor = new Editor({ - element: host, - extensions: createRichMarkdownExtensions({ codec: createRichMarkdownEditorCodec() }), - content: '![Before](before.png "Old title")', - contentType: 'markdown' - }) - setRichMarkdownImageResolverContext(editor, { filePath: '/repo/docs/readme.md' }) - const image = host.querySelector('img') - await vi.waitFor(() => expect(image?.getAttribute('src')).toBe('blob:attributes')) - expect(image?.alt).toBe('Before') - - updateImage({ alt: 'After', title: 'New title', width: 160, height: 90 }) - expect(host.querySelector('img')).toBe(image) - expect(image?.alt).toBe('After') - expect(image?.title).toBe('New title') - expect(image?.width).toBe(160) - expect(image?.height).toBe(90) - expect(image?.draggable).toBe(false) - - updateImage({ alt: null, title: null, width: null, height: null }) - expect(host.querySelector('img')).toBe(image) - for (const name of ['alt', 'title', 'width', 'height']) { - expect(image?.hasAttribute(name), name).toBe(false) - } - expect(image?.getAttribute('src')).toBe('blob:attributes') - expect(readFile).toHaveBeenCalledTimes(1) -}) diff --git a/src/renderer/src/components/editor/rich-markdown/links/rich-markdown-editor-click-routing.test.ts b/src/renderer/src/components/editor/rich-markdown/links/rich-markdown-editor-click-routing.test.ts deleted file mode 100644 index f3214bb1933..00000000000 --- a/src/renderer/src/components/editor/rich-markdown/links/rich-markdown-editor-click-routing.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -// @vitest-environment happy-dom - -import { Editor } from '@tiptap/core' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { - registerHttpLinkStoreAccessor, - registerWorkspaceHttpLinkBrowserOpener -} from '@/lib/browser/navigation/http-link-routing' -import { createRichMarkdownHtmlSuperscriptLinkContext } from '../citations/rich-markdown-html-superscript-link-context' -import { createRichMarkdownEditorCodec } from '../document/rich-markdown-source-transport' -import { encodeRawMarkdownHtmlForRichEditor } from '../raw-source/raw-markdown-html' -import { createRichMarkdownExtensions } from '../schema/rich-markdown-extensions' -import { handleRichMarkdownEditorClick } from './rich-markdown-editor-click-routing' -import { handleRichMarkdownEditorAuxClick } from './rich-markdown-link-dom-events' -import { openMarkdownExternalUrl } from '../../markdown/link-routing/markdown-external-url-open' -import { useAppStore } from '@/store/index' - -const editors: Editor[] = [] -const openWorkspaceBrowserMock = vi.fn(async () => 'page-1') -const openUrlMock = vi.fn() - -beforeEach(() => { - openWorkspaceBrowserMock.mockClear() - openUrlMock.mockClear() - ;(window as unknown as { api: unknown }).api = { - shell: { - openUrl: openUrlMock, - openFileUri: vi.fn(), - pathExists: vi.fn(async () => true) - } - } - registerHttpLinkStoreAccessor(() => ({ - settings: { openLinksInApp: false, activeRuntimeEnvironmentId: null }, - setActiveWorktree: vi.fn(), - createBrowserTab: vi.fn() - })) - registerWorkspaceHttpLinkBrowserOpener(openWorkspaceBrowserMock) -}) - -afterEach(() => { - vi.unstubAllGlobals() - registerWorkspaceHttpLinkBrowserOpener(null) - for (const editor of editors.splice(0)) { - editor.destroy() - } -}) - -function createDocLinkEditor(): Editor { - const codec = createRichMarkdownEditorCodec() - const editor = new Editor({ - element: document.body.appendChild(document.createElement('div')), - extensions: createRichMarkdownExtensions({ codec }), - content: encodeRawMarkdownHtmlForRichEditor('See [[docs/guide|some label]] next', codec), - contentType: 'markdown' - }) - editors.push(editor) - return editor -} - -function docLinkEnd(editor: Editor): number { - let end = -1 - editor.state.doc.descendants((node, pos) => { - if (node.type.name === 'markdownDocLink') { - end = pos + node.nodeSize - } - }) - return end -} - -// posAtCoords puts a click on the right half of an inline atom at the position after it. -function modClickAt(editor: Editor, pos: number, target: Element): string[] { - const opened: string[] = [] - const event = new MouseEvent('click', { metaKey: true }) - Object.defineProperty(event, 'target', { value: target }) - handleRichMarkdownEditorClick({ - activateMarkdownLink: () => undefined, - editorRef: { current: editor }, - event, - filePath: '/repo/docs/index.md', - isMac: true, - htmlSuperscriptLinkContext: createRichMarkdownHtmlSuperscriptLinkContext({ - sourceFilePath: '/repo/docs/index.md', - worktreeId: 'worktree-1', - worktreeRoot: '/repo', - sourceOwner: { kind: 'local' } - }), - markdownCommentsRef: { current: [] }, - markdownSourceLineOffsetRef: { current: 0 }, - onOpenDocLinkRef: { current: (docTarget) => opened.push(docTarget) }, - pos, - rootRef: { current: null }, - scrollRichMarkdownReviewNoteCardIntoView: () => undefined, - view: editor.view, - worktreeId: 'worktree-1', - worktreeRoot: '/repo' - }) - return opened -} - -describe('rich markdown modifier-click on a wikilink', () => { - it('opens the wikilink from the right half of its label', () => { - const editor = createDocLinkEditor() - const label = editor.view.dom.querySelector('[data-doc-link-target]') - expect(label).not.toBeNull() - - expect(modClickAt(editor, docLinkEnd(editor), label!)).toEqual(['docs/guide']) - }) -}) - -describe('rich markdown URL click and middle-click routing', () => { - function createUrlEditor(): { editor: Editor; anchor: HTMLAnchorElement } { - const codec = createRichMarkdownEditorCodec() - const editor = new Editor({ - element: document.body.appendChild(document.createElement('div')), - extensions: createRichMarkdownExtensions({ codec }), - content: encodeRawMarkdownHtmlForRichEditor('Read [Orca](https://orca.dev/docs)', codec), - contentType: 'markdown' - }) - editors.push(editor) - const anchor = editor.view.dom.querySelector('a') - if (!anchor) { - throw new Error('Expected rendered anchor') - } - return { editor, anchor } - } - - it('opens external URLs in Orca on plain click without modifier keys', () => { - const { editor, anchor } = createUrlEditor() - const event = new MouseEvent('click', { button: 0 }) - Object.defineProperty(event, 'target', { value: anchor }) - - const handled = handleRichMarkdownEditorClick({ - activateMarkdownLink: () => undefined, - editorRef: { current: editor }, - event, - filePath: '/repo/docs/index.md', - isMac: true, - htmlSuperscriptLinkContext: createRichMarkdownHtmlSuperscriptLinkContext({ - sourceFilePath: '/repo/docs/index.md', - worktreeId: 'worktree-1', - worktreeRoot: '/repo', - sourceOwner: { kind: 'local' } - }), - markdownCommentsRef: { current: [] }, - markdownSourceLineOffsetRef: { current: 0 }, - onOpenDocLinkRef: { current: undefined }, - pos: 6, - rootRef: { current: null }, - scrollRichMarkdownReviewNoteCardIntoView: () => undefined, - view: editor.view, - worktreeId: 'worktree-1', - worktreeRoot: '/repo' - }) - - expect(handled).toBe(true) - expect(openWorkspaceBrowserMock).toHaveBeenCalledWith( - expect.objectContaining({ - workspaceId: 'worktree-1', - url: 'https://orca.dev/docs' - }) - ) - expect(openUrlMock).not.toHaveBeenCalled() - }) - - it('uses the system browser when a paired web workspace cannot host a browser', () => { - vi.stubGlobal('__ORCA_WEB_CLIENT__', true) - openMarkdownExternalUrl('https://orca.dev/docs', { - state: useAppStore.getState(), - worktreeId: 'worktree-1', - sourceOwner: { kind: 'local' }, - destination: 'orca' - }) - - expect(openUrlMock).toHaveBeenCalledWith('https://orca.dev/docs') - expect(openWorkspaceBrowserMock).not.toHaveBeenCalled() - }) - - it('opens external URLs in the system browser on middle-click', () => { - const { editor, anchor } = createUrlEditor() - const event = new MouseEvent('auxclick', { button: 1, cancelable: true }) - Object.defineProperty(event, 'target', { value: anchor }) - - const handled = handleRichMarkdownEditorAuxClick({ - event, - filePath: '/repo/docs/index.md', - htmlSuperscriptLinkContext: createRichMarkdownHtmlSuperscriptLinkContext({ - sourceFilePath: '/repo/docs/index.md', - worktreeId: 'worktree-1', - worktreeRoot: '/repo', - sourceOwner: { kind: 'local' } - }), - view: editor.view, - worktreeId: 'worktree-1', - worktreeRoot: '/repo' - }) - - expect(handled).toBe(true) - expect(event.defaultPrevented).toBe(true) - expect(openUrlMock).toHaveBeenCalledWith('https://orca.dev/docs') - expect(openWorkspaceBrowserMock).not.toHaveBeenCalled() - }) -}) diff --git a/src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-escape-fidelity.test.ts b/src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-escape-fidelity.test.ts deleted file mode 100644 index 9a20e4bd565..00000000000 --- a/src/renderer/src/components/editor/rich-markdown/schema/rich-markdown-escape-fidelity.test.ts +++ /dev/null @@ -1,212 +0,0 @@ -import { Editor, type JSONContent } from '@tiptap/core' -import StarterKit from '@tiptap/starter-kit' -import { describe, expect, it, vi } from 'vitest' -import { encodeRawMarkdownHtmlForRichEditor } from '../raw-source/raw-markdown-html' -import { createRichMarkdownExtensions } from './rich-markdown-extensions' -import { createRichMarkdownEditorCodec } from '../document/rich-markdown-source-transport' -import { createIsolatedMarkdownExtensionForTests } from './isolated-markdown-extension-for-tests' - -function createEditor(content: JSONContent | string) { - return new Editor({ - element: null, - extensions: [StarterKit, createIsolatedMarkdownExtensionForTests()], - content, - ...(typeof content === 'string' ? { contentType: 'markdown' as const } : {}) - }) -} - -function paragraph(text: string): JSONContent { - return { type: 'paragraph', content: [{ type: 'text', text }] } -} - -function expectReopens(editor: Editor, reopen = createEditor): void { - const reopened = reopen(editor.getMarkdown()) - try { - expect(reopened.getJSON()).toEqual(editor.getJSON()) - } finally { - reopened.destroy() - } -} - -function createRichEditor(content: JSONContent | string) { - const codec = createRichMarkdownEditorCodec() - return new Editor({ - element: null, - extensions: createRichMarkdownExtensions({ codec }), - content: - typeof content === 'string' ? encodeRawMarkdownHtmlForRichEditor(content, codec) : content, - ...(typeof content === 'string' ? { contentType: 'markdown' as const } : {}) - }) -} - -describe('optional Markdown escapes', () => { - it.each(['user_name_field', 'a_2_b', 'a__b', 'пристаням_стремятся', '𐐀_𐐁', 'é_value'])( - 'preserves intraword underscores in %s', - (text) => { - const editor = createEditor({ type: 'doc', content: [paragraph(text)] }) - try { - expect(editor.getMarkdown()).toBe(text) - expectReopens(editor) - } finally { - editor.destroy() - } - } - ) - - it.each(['__init__', '___init___', '_word_', 'see a. __b__c', 'a\\_b', 'a\\\\_b'])( - 'keeps literal delimiter runs and backslashes safe: %s', - (text) => { - const editor = createEditor({ type: 'doc', content: [paragraph(text)] }) - try { - expectReopens(editor) - } finally { - editor.destroy() - } - } - ) - - it.each(['feature~2', 'an unmatched ` tick', 'a single * marker', 'a~b_c*d`e'])( - 'omits optional escapes only when the parser proves the literal survives: %s', - (text) => { - const editor = createEditor({ type: 'doc', content: [paragraph(text)] }) - try { - expect(editor.getMarkdown()).toBe(text) - expectReopens(editor) - } finally { - editor.destroy() - } - } - ) - - it.each([ - '~5 dollars, see v2~beta', - '~~deleted~~', - '*italic*', - '**bold**', - '`code`', - '[label](url)', - '[literal] *bold* feature~2' - ])('retains escapes that prevent new Markdown syntax: %s', (text) => { - const editor = createEditor({ type: 'doc', content: [paragraph(text)] }) - try { - expectReopens(editor) - if (text.includes('feature~2')) { - expect(editor.getMarkdown()).toContain('feature~2') - } - } finally { - editor.destroy() - } - }) - - it('preserves identifiers alongside emphasis-like literals', () => { - const editor = createEditor({ type: 'doc', content: [paragraph('__init__ user_name')] }) - try { - expect(editor.getMarkdown()).toContain('user_name') - expectReopens(editor) - } finally { - editor.destroy() - } - }) - - it('preserves callouts and identifiers in nested containers', () => { - const source = '> [!NOTE] user_name\n>\n> - [literal] a__b\n\n- outer_name\n - inner_name' - const editor = createEditor(source) - try { - expect(editor.getMarkdown()).toContain('> [!NOTE] user_name') - expect(editor.getMarkdown()).toContain('[literal] a__b') - expect(editor.getMarkdown()).toContain('inner_name') - expectReopens(editor) - } finally { - editor.destroy() - } - }) - - it('validates marks across adjacent text nodes', () => { - const editor = createEditor({ - type: 'doc', - content: [ - { - type: 'paragraph', - content: [ - { type: 'text', text: 'a_' }, - { type: 'text', text: '_b_', marks: [{ type: 'bold' }] }, - { type: 'text', text: '_c user_name' } - ] - } - ] - }) - try { - expect(editor.getMarkdown()).toContain('user_name') - expectReopens(editor) - } finally { - editor.destroy() - } - }) - - it('does not activate definitions nested in another block', () => { - const editor = createEditor({ - type: 'doc', - content: [paragraph('[ref]'), { type: 'blockquote', content: [paragraph('[ref]: /target')] }] - }) - try { - expectReopens(editor) - } finally { - editor.destroy() - } - }) -}) - -describe('literal escape validation boundaries', () => { - it('validates a nested container once and caches unchanged blocks', () => { - const editor = createEditor('> [!NOTE] user_name\n>\n> - inner_value') - const parse = vi.spyOn(editor.markdown!, 'parse') - try { - expect(editor.getMarkdown()).toContain('[!NOTE] user_name') - expect(parse).toHaveBeenCalledTimes(1) - editor.getMarkdown() - expect(parse).toHaveBeenCalledTimes(1) - editor.commands.insertContentAt(3, { type: 'text', text: 'edit ' }) - editor.getMarkdown() - expect(parse).toHaveBeenCalledTimes(2) - expectReopens(editor) - } finally { - parse.mockRestore() - editor.destroy() - } - }) - - it('skips optional validation for an oversized block', () => { - const editor = createEditor({ type: 'doc', content: [paragraph(`${'a_'.repeat(25_001)}b`)] }) - const parse = vi.spyOn(editor.markdown!, 'parse') - try { - expect(editor.getMarkdown()).toContain('a\\_') - expect(parse).not.toHaveBeenCalled() - } finally { - parse.mockRestore() - editor.destroy() - } - }) - - it.each([ - '> [!TIP] user_name\n>\n> - [x] inner_value', - '> user_name raw\\_value', - '
literal\\_[]
\n\nuser_name', - '> user_name `literal\\_[]`', - '```text\nliteral\\_[]\n```\n\nuser_name', - '[ref]\n\n> [ref]: /target\n>\n> tail', - '> [ref]\n\n[ref]: /target' - ])('preserves source ownership and reopen semantics: %s', (source) => { - const editor = createRichEditor(source) - try { - expectReopens(editor, createRichEditor) - if (source.includes('
')) { - expect(editor.getMarkdown()).toContain('
literal\\_[]
') - } - if (source.includes('') - } - } finally { - editor.destroy() - } - }) -}) diff --git a/src/renderer/src/components/github/github-image-upload.test.ts b/src/renderer/src/components/github/github-image-upload.test.ts deleted file mode 100644 index cd7957880c6..00000000000 --- a/src/renderer/src/components/github/github-image-upload.test.ts +++ /dev/null @@ -1,103 +0,0 @@ -// @vitest-environment happy-dom -import { afterEach, expect, it, vi } from 'vitest' -import { captureGitHubImageUpload } from './github-image-upload' -import type { RuntimeRpcResponse } from '../../../../shared/remote-runtime/rpc/runtime-rpc-envelope' -import { GITHUB_IMAGE_ATTACHMENT_CAPABILITY } from '../../../../shared/github/attachments/image-attachment' - -const { call } = vi.hoisted(() => ({ call: vi.fn() })) -vi.mock('@/runtime/rpc/calls/runtime-rpc-call', () => ({ callRuntimeRpc: call })) -vi.mock('@/runtime/rpc/environment-revisions/runtime-environment-revision', () => ({ - getRuntimeEnvironmentRevision: () => 1 -})) -vi.mock('@/app-shell/platform/web-client-location', () => ({ isWebClientLocation: () => false })) -vi.mock('@/web/web-runtime-environment', () => ({ readStoredWebRuntimeEnvironment: () => null })) -afterEach(() => { - vi.unstubAllGlobals() - vi.restoreAllMocks() - call.mockReset() -}) -const address = { - runtime: { kind: 'local' as const }, - target: { kind: 'repo' as const, repo: 'repo', source: 'origin' as const } -} -const file = () => new File(['image'], 'image.png', { type: 'image/png' }) -const ok = (result: unknown): RuntimeRpcResponse => ({ - id: 'request', - ok: true, - result, - _meta: { runtimeId: 'local' } -}) -function bridge(subscribe: unknown) { - vi.stubGlobal('window', { api: { runtime: { subscribe } } }) -} - -it('releases a late staging ID after retirement without admitting a chunk or POST', async () => { - const allocation = Promise.withResolvers<{ uploadId: string }>() - call.mockImplementation((_runtime, method) => - method === 'clipboard.startImageUpload' ? allocation.promise : Promise.resolve() - ) - const subscribe = vi.fn((_args, reply) => { - reply(ok({ capabilities: [GITHUB_IMAGE_ATTACHMENT_CAPABILITY] })) - return Promise.resolve({ unsubscribe: vi.fn() }) - }) - bridge(subscribe) - const controller = new AbortController() - const pending = captureGitHubImageUpload(address)(file(), controller.signal) - const rejected = expect(pending).rejects.toMatchObject({ name: 'AbortError' }) - await vi.waitFor(() => - expect(call).toHaveBeenCalledWith( - address.runtime, - 'clipboard.startImageUpload', - expect.anything(), - expect.anything() - ) - ) - controller.abort() - allocation.resolve({ uploadId: 'late' }) - await rejected - expect(call.mock.calls.map((args) => args[1])).toEqual([ - 'clipboard.startImageUpload', - 'clipboard.abortImageUpload' - ]) - expect(call.mock.calls[1][2]).toEqual({ uploadId: 'late' }) - expect(call.mock.calls[1][3].signal).toBeUndefined() - expect(subscribe.mock.calls.map(([args]) => args.method)).toEqual(['status.get']) -}) - -it('unsubscribes an active local upload and allows a live successor to finish', async () => { - call.mockImplementation((_runtime, method) => - Promise.resolve(method === 'clipboard.startImageUpload' ? { uploadId: 'staged' } : undefined) - ) - let active: AbortController | undefined - let cancelFirst = true - const subscribe = vi.fn((args, reply) => { - const host = new AbortController() - const unsubscribe = () => host.abort() - if (args.method === 'status.get') { - reply(ok({ capabilities: [GITHUB_IMAGE_ATTACHMENT_CAPABILITY] })) - } else if (args.method === 'github.uploadAttachment' && cancelFirst) { - active = host - } else { - reply( - ok( - args.method === 'github.uploadAttachment' - ? { url: 'https://github.com/user-attachments/assets/success' } - : undefined - ) - ) - } - return Promise.resolve({ unsubscribe }) - }) - bridge(subscribe) - const controller = new AbortController() - const pending = captureGitHubImageUpload(address)(file(), controller.signal) - const rejected = expect(pending).rejects.toMatchObject({ name: 'AbortError' }) - await vi.waitFor(() => expect(active).toBeDefined()) - controller.abort() - await rejected - expect(active?.signal.aborted).toBe(true) - cancelFirst = false - await expect( - captureGitHubImageUpload(address)(file(), new AbortController().signal) - ).resolves.toBe('https://github.com/user-attachments/assets/success') -}) diff --git a/src/renderer/src/components/integrations/source-control/bitbucket-integration-card.test.tsx b/src/renderer/src/components/integrations/source-control/bitbucket-integration-card.test.tsx deleted file mode 100644 index 32e1611c822..00000000000 --- a/src/renderer/src/components/integrations/source-control/bitbucket-integration-card.test.tsx +++ /dev/null @@ -1,125 +0,0 @@ -// @vitest-environment happy-dom - -import { act } from 'react' -import { createRoot, type Root } from 'react-dom/client' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' - -const mocks = vi.hoisted(() => ({ - refresh: vi.fn(), - status: vi.fn(), - statuses: { bitbucketStatus: 'not-authenticated', bitbucketAccount: null } -})) - -vi.mock('./source-control-preflight-card-status', () => ({ - usePreflightCardStatuses: () => ({ - statuses: mocks.statuses, - unavailable: false, - refresh: mocks.refresh - }) -})) -vi.mock('./bitbucket-credentials-dialog', () => ({ - BitbucketCredentialsDialog: ({ open, initialEmail }: { open: boolean; initialEmail?: string }) => - open ?
Credential dialog open {initialEmail}
: null -})) - -import { BitbucketIntegrationCard } from './bitbucket-integration-card' - -const LOAD_FAILED_TEXT = 'Could not check for a saved Bitbucket credential.' - -let container: HTMLDivElement -let root: Root - -async function renderCard(): Promise { - container = document.createElement('div') - document.body.appendChild(container) - root = createRoot(container) - await act(async () => { - root.render() - }) -} - -function recheckButton(): HTMLButtonElement { - const button = Array.from(container.querySelectorAll('button')).find( - (candidate) => candidate.textContent === 'Re-check' - ) - if (!button) { - throw new Error('Re-check button not rendered') - } - return button -} - -describe('BitbucketIntegrationCard credential-read failures', () => { - beforeEach(() => { - vi.clearAllMocks() - mocks.statuses = { bitbucketStatus: 'not-authenticated', bitbucketAccount: null } - Object.assign(window, { - api: { - bitbucket: { status: mocks.status, disconnect: vi.fn(async () => {}) }, - shell: { openUrl: vi.fn() } - } - }) - }) - - afterEach(() => { - act(() => root.unmount()) - container.remove() - }) - - it('does not let an older failed read overwrite a newer successful re-check', async () => { - let rejectInitial!: (error: Error) => void - mocks.status - .mockReturnValueOnce( - new Promise((_resolve, reject) => { - rejectInitial = reject - }) - ) - .mockResolvedValueOnce({ source: 'none', account: null }) - - await renderCard() - await act(async () => { - recheckButton().click() - }) - await act(async () => { - rejectInitial(new Error('late keychain failure')) - }) - - expect(container.textContent).not.toContain(LOAD_FAILED_TEXT) - }) - - it('does not expose stale credential controls after a re-check fails', async () => { - mocks.statuses = { bitbucketStatus: 'connected', bitbucketAccount: null } - mocks.status - .mockResolvedValueOnce({ - configured: true, - source: 'stored', - account: 'stale-account', - authMode: 'token', - email: 'stale@example.com', - baseUrl: null - }) - .mockRejectedValueOnce(new Error('keychain locked')) - - await renderCard() - expect(container.textContent).toContain('stale-account') - expect(container.textContent).toContain('Edit credentials') - expect(container.querySelector('[aria-label="Disconnect Bitbucket"]')).not.toBeNull() - - await act(async () => { - recheckButton().click() - }) - - expect(container.textContent).toContain(LOAD_FAILED_TEXT) - expect(container.textContent).not.toContain('stale-account') - expect(container.textContent).not.toContain('Edit credentials') - expect(container.textContent).toContain('Add or replace credentials') - expect(container.querySelector('[aria-label="Disconnect Bitbucket"]')).toBeNull() - - await act(async () => { - Array.from(container.querySelectorAll('button')) - .find((button) => button.textContent === 'Add or replace credentials') - ?.click() - }) - expect(container.textContent).toContain('Credential dialog open') - expect(container.textContent).not.toContain('stale@example.com') - }) -}) diff --git a/src/renderer/src/components/jira-attachment-image.test.tsx b/src/renderer/src/components/jira-attachment-image.test.tsx deleted file mode 100644 index 6e24c359a01..00000000000 --- a/src/renderer/src/components/jira-attachment-image.test.tsx +++ /dev/null @@ -1,86 +0,0 @@ -// @vitest-environment happy-dom -import { act, cleanup, render, screen, waitFor } from '@testing-library/react' -import { afterEach, beforeEach, expect, it, vi } from 'vitest' -import { JiraAttachmentImage } from './jira-attachment-image' - -const { acquire, release, listeners } = vi.hoisted(() => ({ - acquire: vi.fn(), - release: vi.fn(), - listeners: new Set<(environmentId: string | null) => void>() -})) -vi.mock('@/runtime/jira/runtime-jira-image-cache', () => ({ - acquireJiraImageUrl: acquire, - hasCachedJiraImage: () => false, - onJiraImageCacheInvalidated: (listener: (environmentId: string | null) => void) => { - listeners.add(listener) - return () => listeners.delete(listener) - } -})) -const target = { kind: 'environment' as const, environmentId: 'first-host' } -beforeEach(() => { - acquire.mockReset() - release.mockReset() - listeners.clear() -}) -afterEach(cleanup) - -it('removes the previous image immediately when its mounted owner or reference changes', async () => { - acquire - .mockResolvedValueOnce({ url: 'blob:first', release }) - .mockImplementationOnce(() => new Promise(() => {})) - const view = render( - - ) - await waitFor(() => expect(screen.getByRole('img').getAttribute('src')).toBe('blob:first')) - view.rerender( - - ) - expect(screen.queryByRole('img')).toBeNull() - expect(release).toHaveBeenCalledOnce() -}) - -it('reacquires the same reference after disconnect and reconnect invalidations', async () => { - acquire - .mockResolvedValueOnce({ url: 'blob:first', release }) - .mockRejectedValueOnce(new Error('disconnected')) - .mockResolvedValueOnce({ url: 'blob:reconnected', release }) - render() - await waitFor(() => expect(screen.getByRole('img').getAttribute('src')).toBe('blob:first')) - await act(async () => listeners.forEach((listener) => listener('first-host'))) - expect(screen.queryByRole('img')).toBeNull() - await waitFor(() => expect(acquire).toHaveBeenCalledTimes(2)) - await act(async () => listeners.forEach((listener) => listener('other-host'))) - expect(acquire).toHaveBeenCalledTimes(2) - await act(async () => listeners.forEach((listener) => listener('first-host'))) - await waitFor(() => expect(screen.getByRole('img').getAttribute('src')).toBe('blob:reconnected')) - expect(acquire).toHaveBeenCalledTimes(3) - expect(release).toHaveBeenCalledOnce() -}) - -it('fences a pending rejection synchronously when its cache is invalidated', async () => { - let requestSignal: AbortSignal | undefined - let rejectFirst: ((reason: Error) => void) | undefined - acquire - .mockImplementationOnce((_target, _reference, signal: AbortSignal) => { - requestSignal = signal - return new Promise((_resolve, reject) => { - rejectFirst = reject - }) - }) - .mockResolvedValueOnce({ url: 'blob:retried', release }) - render() - await waitFor(() => expect(acquire).toHaveBeenCalledOnce()) - await act(async () => { - listeners.forEach((listener) => listener('first-host')) - expect(requestSignal?.aborted).toBe(true) - rejectFirst?.(new Error('Cache invalidated')) - await Promise.resolve() - }) - await waitFor(() => expect(screen.getByRole('img').getAttribute('src')).toBe('blob:retried')) - expect(acquire).toHaveBeenCalledTimes(2) -}) diff --git a/src/renderer/src/components/mobile/MobilePage.test.tsx b/src/renderer/src/components/mobile/MobilePage.test.tsx deleted file mode 100644 index 7cd38fa2c40..00000000000 --- a/src/renderer/src/components/mobile/MobilePage.test.tsx +++ /dev/null @@ -1,191 +0,0 @@ -// @vitest-environment happy-dom - -import '@testing-library/jest-dom/vitest' - -import { act, cleanup, render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type { MobilePairingConnectionMode } from '../../../../shared/remote-runtime/pairing/mobile-pairing-connection-mode' - -type StoreState = { - closeMobilePage: () => void - orcaProfileAuthStatus: { state: 'connected' | 'local' } - settings: { - showMobileButton: boolean - mobilePairingConnectionMode?: MobilePairingConnectionMode - mobilePairingCustomAddress?: string | null - mobilePairingCustomAddresses?: string[] - } - updateSettings: () => Promise - fetchOrcaProfileAuthStatus: () => Promise -} - -const mocks = vi.hoisted(() => ({ - storeState: {} as StoreState -})) - -vi.mock('@/store', () => ({ - useAppStore: (selector: (state: StoreState) => unknown) => selector(mocks.storeState) -})) - -vi.mock('@/i18n/i18n', () => ({ - translate: (_key: string, fallback: string) => fallback -})) - -vi.mock('sonner', () => ({ - toast: { error: vi.fn(), message: vi.fn(), success: vi.fn() } -})) - -vi.mock('./use-mobile-install-qr', () => ({ useMobileInstallQr: () => null })) -vi.mock('./use-mobile-page-escape', () => ({ useMobilePageEscape: vi.fn() })) -vi.mock('./pairing/mobile-pairing-device-polling', () => ({ - useMobilePairingDevicePolling: vi.fn() -})) - -vi.mock('./MobilePageContent', () => ({ - MobilePageContent: (props: { - stage: string | null - pairLoading: boolean - pairQrDataUrl: string | null - selectedAddress: string | undefined - enterFlow: () => void - handleContinue: () => void - handleBack: () => void - loadNetworkInterfaces: () => void - }) => ( -
- {props.stage ?? 'loading'} - {String(props.pairLoading)} - {props.pairQrDataUrl ?? 'none'} - {props.selectedAddress ?? 'none'} - - - - -
- ) -})) - -import MobilePage from './MobilePage' - -describe('MobilePage pairing connection mode', () => { - const getPairingQR = vi.fn() - const listNetworkInterfaces = vi.fn() - - beforeEach(() => { - getPairingQR.mockReset().mockResolvedValue({ - available: true, - qrDataUrl: 'data:image/png;base64,qr', - qrSize: 218, - pairingUrl: 'orca://pair#automatic' - }) - listNetworkInterfaces.mockReset().mockResolvedValue({ interfaces: [] }) - mocks.storeState = { - closeMobilePage: vi.fn(), - orcaProfileAuthStatus: { state: 'connected' }, - settings: { showMobileButton: true }, - updateSettings: vi.fn().mockResolvedValue(undefined), - fetchOrcaProfileAuthStatus: vi.fn().mockResolvedValue(null) - } - Object.defineProperty(window, 'api', { - configurable: true, - value: { - mobile: { - getPairingQR, - listDevices: vi.fn().mockResolvedValue({ devices: [] }), - listNetworkInterfaces - }, - shell: { openUrl: vi.fn() }, - ui: { writeClipboardText: vi.fn().mockResolvedValue(undefined) } - } - }) - }) - - afterEach(cleanup) - - async function openPairingStep(): Promise { - const user = userEvent.setup() - render() - await waitFor(() => expect(screen.getByTestId('stage')).toHaveTextContent('intro')) - await user.click(screen.getByRole('button', { name: 'Enter flow' })) - await user.click(screen.getByRole('button', { name: 'Continue' })) - } - - it('does not let an abandoned mint populate a new pairing visit', async () => { - const user = userEvent.setup() - let resolveAbandonedMint: ((value: Record) => void) | undefined, - resolveCurrentMint: ((value: Record) => void) | undefined - getPairingQR - .mockImplementationOnce(() => new Promise((resolve) => (resolveAbandonedMint = resolve))) - .mockImplementationOnce(() => new Promise((resolve) => (resolveCurrentMint = resolve))) - await openPairingStep() - - await user.click(screen.getByRole('button', { name: 'Back' })) - await user.click(screen.getByRole('button', { name: 'Back' })) - await user.click(screen.getByRole('button', { name: 'Enter flow' })) - await user.click(screen.getByRole('button', { name: 'Continue' })) - await waitFor(() => expect(getPairingQR).toHaveBeenCalledTimes(2)) - - await act(async () => { - resolveAbandonedMint?.({ available: true, qrDataUrl: 'abandoned' }) - }) - expect(screen.getByTestId('pairing-qr')).toHaveTextContent('none') - expect(screen.getByTestId('pair-loading')).toHaveTextContent('true') - - resolveCurrentMint?.({ available: true, qrDataUrl: 'current' }) - await waitFor(() => expect(screen.getByTestId('pairing-qr')).toHaveTextContent('current')) - }) - - it('does not release the mint when a superseded lookup for the same visit settles', async () => { - const user = userEvent.setup() - let resolveEntryLookup: ((value: Record) => void) | undefined - let resolveManualLookup: ((value: Record) => void) | undefined - listNetworkInterfaces - .mockImplementationOnce( - () => - new Promise((resolve) => { - resolveEntryLookup = resolve - }) - ) - .mockImplementationOnce( - () => - new Promise((resolve) => { - resolveManualLookup = resolve - }) - ) - render() - await waitFor(() => expect(screen.getByTestId('stage')).toHaveTextContent('intro')) - await user.click(screen.getByRole('button', { name: 'Enter flow' })) - await user.click(screen.getByRole('button', { name: 'Continue' })) - - // Overlap refresh within one visit so only request epoch, not visit identity, can distinguish it. - await user.click(screen.getByRole('button', { name: 'Refresh addresses' })) - await waitFor(() => expect(listNetworkInterfaces).toHaveBeenCalledTimes(2)) - - // The old lookup cannot release minting before its replacement chooses the address. - await act(async () => { - resolveEntryLookup?.({ interfaces: [{ name: 'Wi-Fi', address: '10.0.0.5' }] }) - }) - await waitFor(() => expect(screen.getByTestId('pair-loading')).toHaveTextContent('true')) - expect(getPairingQR).not.toHaveBeenCalled() - expect(screen.getByTestId('selected-address')).toHaveTextContent('none') - - resolveManualLookup?.({ interfaces: [{ name: 'Wi-Fi', address: '10.0.0.9' }] }) - await waitFor(() => - expect(screen.getByTestId('selected-address')).toHaveTextContent('10.0.0.9') - ) - await waitFor(() => expect(getPairingQR).toHaveBeenCalledTimes(1)) - expect(getPairingQR).toHaveBeenCalledWith({ - address: '10.0.0.9', - connectionMode: 'automatic' - }) - }) -}) diff --git a/src/renderer/src/components/native-chat/attachments/chips/use-native-chat-composer-preview-lifetime.test.tsx b/src/renderer/src/components/native-chat/attachments/chips/use-native-chat-composer-preview-lifetime.test.tsx deleted file mode 100644 index 785cc921f98..00000000000 --- a/src/renderer/src/components/native-chat/attachments/chips/use-native-chat-composer-preview-lifetime.test.tsx +++ /dev/null @@ -1,113 +0,0 @@ -// @vitest-environment happy-dom -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { act, createElement, StrictMode, useRef } from 'react' -import { createRoot, type Root } from 'react-dom/client' -import { clearNativeChatAttachmentCacheForTests } from '../../drafts/native-chat-draft-reset' -import { readNativeChatAttachmentCache } from './native-chat-attachment-draft' -import { useNativeChatComposerAttachments } from './use-native-chat-composer-attachments' - -vi.mock('@/i18n/i18n', () => ({ - translate: (_key: string, fallback: string) => fallback -})) - -type AttachmentApi = ReturnType -const roots = new Set() - -beforeEach(() => vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true)) - -async function mount(scopeKey: string) { - let latest: AttachmentApi | null = null - function Probe(): null { - const textareaRef = useRef(null) - latest = useNativeChatComposerAttachments({ - attachmentScopeKey: scopeKey, - allowWithoutTarget: true, - imageReferences: true, - caret: 0, - disabled: false, - isComposing: () => false, - resolveTarget: () => null, - textareaRef, - setCaret: () => {}, - setDraft: () => {}, - setNotice: () => {} - }) - return null - } - const container = document.createElement('div') - document.body.append(container) - const root = createRoot(container) - roots.add(root) - await act(async () => root.render(createElement(StrictMode, null, createElement(Probe)))) - return { - api: (): AttachmentApi => { - if (!latest) { - throw new Error('Composer did not mount') - } - return latest - }, - unmount: () => { - act(() => root.unmount()) - roots.delete(root) - container.remove() - } - } -} - -function begin(api: AttachmentApi, previewUrl: string): string { - const id = api.beginPendingImageAttachment(previewUrl) - if (!id) { - throw new Error('Attachment was refused') - } - return id -} - -afterEach(() => { - act(() => { - for (const root of roots) { - root.unmount() - } - }) - roots.clear() - clearNativeChatAttachmentCacheForTests() - vi.restoreAllMocks() - vi.unstubAllGlobals() - document.body.replaceChildren() -}) - -describe('composer preview lifetime', () => { - it.each([null, 'ssh-connection'])( - 'releases settled previews while retaining saved paths (%s)', - async (connectionId) => { - const revoke = vi.spyOn(URL, 'revokeObjectURL') - const first = await mount('preview-scope') - act(() => { - const id = begin(first.api(), 'blob:clipboard-preview') - first.api().resolvePendingImageAttachment(id, '/workspace/image.png', connectionId) - }) - expect(first.api().imageAttachments).toMatchObject([ - { path: '/workspace/image.png', previewUrl: 'blob:clipboard-preview' } - ]) - expect(revoke).not.toHaveBeenCalled() - const saved = readNativeChatAttachmentCache('preview-scope') - - first.unmount() - expect(revoke).toHaveBeenCalledExactlyOnceWith('blob:clipboard-preview') - expect(readNativeChatAttachmentCache('preview-scope')).toEqual(saved) - const restored = await mount('preview-scope') - expect(restored.api().imageAttachments).toEqual(saved) - expect(saved[0]?.connectionId).toBe(connectionId ?? undefined) - restored.unmount() - expect(revoke).toHaveBeenCalledTimes(1) - } - ) - - it('releases pending previews without turning them into saved attachments', async () => { - const revoke = vi.spyOn(URL, 'revokeObjectURL') - const composer = await mount('pending-scope') - act(() => begin(composer.api(), 'blob:pending-preview')) - composer.unmount() - expect(revoke).toHaveBeenCalledExactlyOnceWith('blob:pending-preview') - expect(readNativeChatAttachmentCache('pending-scope')).toEqual([]) - }) -}) diff --git a/src/renderer/src/components/native-chat/composer/focus/use-native-chat-composer-app-menu-selection.test.tsx b/src/renderer/src/components/native-chat/composer/focus/use-native-chat-composer-app-menu-selection.test.tsx deleted file mode 100644 index 73d21954f4c..00000000000 --- a/src/renderer/src/components/native-chat/composer/focus/use-native-chat-composer-app-menu-selection.test.tsx +++ /dev/null @@ -1,119 +0,0 @@ -// @vitest-environment happy-dom - -import { act, cleanup, fireEvent, render } from '@testing-library/react' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type { AppMenuSelectionAction } from '@/lib/app-commands/app-menu-selection-actions' -import { useAppMenuSelectionActions } from '@/hooks/app-commands/useAppMenuSelectionActions' -import { useNativeChatComposerAppMenuSelection } from './use-native-chat-composer-app-menu-selection' - -let appMenuListener: ((action: AppMenuSelectionAction) => void) | null = null -const performNativeSelectionAction = vi.fn() - -function AppMenuBoundary(): null { - useAppMenuSelectionActions() - return null -} - -function ComposerHarness(): React.JSX.Element { - const { textareaRef, isComposingRef } = useNativeChatComposerAppMenuSelection() - return ( -
-