Repository navigation
Conversation
…ases (stablyai#30625) * test(relay): census every activity-lease reader for phones without leases Step 6 lets a reserve cell accept phones without writing confirmation or splice leases. This ratchet classifies every reader of the lease table by why that is safe, and pins the guards that keep completion and idle rehome off a reserve cell whose host holds no source lease. * test(relay): scan subdirectories and USING reads, and ban a bare lease table name The ratchet now walks every production file under src, counts USING as a read, and fails on a bare table-name value, which could reach an interpolated FROM it cannot see.
…later saves (stablyai#30694) * fix(persistence): a commit that runs out of disk no longer retires the profile-state writer A WAL COMMIT on a full disk fails with SQLITE_FULL after SQLite rolls the transaction back. It was reported as indeterminate, which retires the writer, so every later write failed until a restart: on a managed SSH host, a disk that filled once left orcad unable to open a terminal even after the space was freed. SQLITE_FULL fails a frame write before the commit point, so it is now a known failure; every other failed commit stays indeterminate. Co-Authored-By: Claude <noreply@anthropic.com> * docs(persistence): say why SQLITE_FULL on COMMIT is safe to treat as not committed Opus review: the claim holds because powersafe overwrite (on by default) means no padding frames follow the WAL commit frame. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
stablyai#30649) * feat(relay): add the per-cell phonePath switch, effective only in reserve mode Step 6 of the relay redesign keys every phone-path change on this switch. The cell reports the effective value in runtime status, and the flag tool refuses phonePath=memory unless the cell is reserve, and a reserve flip that would turn phones over unnamed. * feat(relay): resume paired phones from one device read on memory cells With phonePath=memory in reserve mode, a phone resume is admitted from one device read and the cell's own seat, and takes no activity leases. A refused device closes 4401, a failed read 4503, and only a missing device row falls through to the invite path. A phone whose host has no seat gets one assignment read: 4409 when the row names another cell or the read fails, otherwise 4404. * fix(relay-ops): store phonePath=db as no key, so old images keep taking writes An explicit phonePath=db left in the switch file would make the flag tool refuse every later write after an image rollback, including a watcher's admitMode=db flip back. * fix(relay): log a failed no-seat read, recheck the switch after the device read A failed assignment read for a phone with no seat now logs a rate-limited line before its 4409. A switch that turned off during the device read sends the phone down today's path. resolveResume reuses the one-read lookup, so the expiry and grace rules have one copy.
…old (stablyai#30652) The revocation gate, the input cancel list and the hold's lifecycle each lived in two places. Sinks now call one gate, held input is recorded at the CDP send (and the one native key path), and runWithRemoteCliPageAdmission owns retire-on-revoke, release and error conversion.
…f on a breach (stablyai#30662) * feat(relay): add the per-cell phonePath switch, effective only in reserve mode Step 6 of the relay redesign keys every phone-path change on this switch. The cell reports the effective value in runtime status, and the flag tool refuses phonePath=memory unless the cell is reserve, and a reserve flip that would turn phones over unnamed. * feat(relay-ops): watch a memory phone cell and turn its phone path off on a breach The reserve watch now also judges five phone rules while the switch file says phonePath=memory, from the cell's own runtime metrics against the 10 minutes before flipped-at: 4401s, confirm failures, attach-deadline 4404s and accept database errors over their lines for 3 minutes, and completed accepts under half of background. A phone-rule trip writes phonePath=db only; any other trip still flips the cell back whole. Resume audit drops page after 5 minutes and flip nothing. * fix(relay-ops): store phonePath=db as no key, so old images keep taking writes An explicit phonePath=db left in the switch file would make the flag tool refuse every later write after an image rollback, including a watcher's admitMode=db flip back. * fix(relay-ops): keep phone watch rules off traffic noise, and keep watching after a phone trip Completed accepts are no longer judged. Rate lines use the background mean plus max(margin, share, 4 Poisson deviations), with a margin of 3 for attach deadlines. A phone trip writes phonePath=db mid-watch and the reserve rules go on; both flip backs remove the phonePath key so a cell rolled back to an image without it takes the write. The phone background starts where phonePath went memory, and a background broken by a restart refuses the watch. Audit drops page only while rising; failing renewals page too. * test(relay-ops): replay the phone rules on 26 recorded hours of c7 and c29 Per-minute counts from the cells' runtime metrics (read-only, 10-18/19) replace the synthetic quiet window. c29's bursty auth failures tripped the attach-deadline rule at a margin of 3 in 29% of 300-minute watches, so its margin is now 5 like the others. * fix(relay): judge the phone rules as a share of attempts, retry a failed phonePath write The count rule false-tripped busy c28 (33/121 five-hour watches). The share rule (over half of the minute's attempts, 0.25 over the background, capped at 0.6) trips none of the recorded c7, c28 and c29 watches and catches two refusals per accept within 3 minutes. A failed mid-watch phonePath=db write now keeps watching, retries each sample and pages after 3 failures; break glass also drops phonePath. Co-Authored-By: Claude <noreply@anthropic.com> * docs(relay): cite the replayed c28 count-rule false trips Co-Authored-By: Claude <noreply@anthropic.com> * fix(relay): judge phone confirm failures against completed accepts Each completed accept makes one confirm, so failures/(failures + accepts) could never pass half and a total confirm outage never tripped. Confirm failures are now a share of accepts. Co-Authored-By: Claude <noreply@anthropic.com> * test(relay): note why the confirm replay tests only trips Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…y how to pick one of twin projects (stablyai#30676) * fix(cli): refuse a paired server name --environment cannot tell apart, and say how to pick one of twin projects * fix(cli): point an ambiguous --worktree at its host-qualified identity * fix(cli): keep the ambiguity listing on the paired server the command chose * fix(cli): compare saved server names the way --environment does, and route cross-host twin projects to --project --host
… into named pieces (stablyai#30703) * refactor(composer): build run-target rows from per-section builders * refactor(composer): move run-target row actions into their own module * refactor(composer): render run-target rows in RunTargetRowList * refactor(worktree-create): dispatch remote-target preparation and share the provisioning log * refactor(worktree-create): extract the pending create's tab strip * refactor(sidebar): split the ephemeral VM resume out of worktree activation * refactor(composer): give the run-target submenu rows an explicit row type
…ai#30695) Pure refactor. Twelve rows, trees and menus called getFileTypeIcon(path) and then rendered or createElement-ed the result themselves; they now render <FileTypeIcon filePath />, so a change to where file icons come from lands in one component. The tab and chat pill keep getFileTypeIcon because they hand an icon component to another component.
- one repoRowOwnerStamp for the SSH and runtime session placeholder builders - lineage refresh resolves the transport host once; pin that a server reply never appends a copy - markdown-document-paths tests live next to the shared module
…from one read (stablyai#30651) * feat(relay): add the per-cell phonePath switch, effective only in reserve mode Step 6 of the relay redesign keys every phone-path change on this switch. The cell reports the effective value in runtime status, and the flag tool refuses phonePath=memory unless the cell is reserve, and a reserve flip that would turn phones over unnamed. * feat(relay): resume paired phones from one device read on memory cells With phonePath=memory in reserve mode, a phone resume is admitted from one device read and the cell's own seat, and takes no activity leases. A refused device closes 4401, a failed read 4503, and only a missing device row falls through to the invite path. A phone whose host has no seat gets one assignment read: 4409 when the row names another cell or the read fails, otherwise 4404. * feat(relay): keep a memory resume's basis in the cell and confirm it from one read A phone resumed on the memory path keeps its connection basis in the cell, not in relay_connection_bases. Its confirm rereads the device row once, renews it only when less than 29 days remain, and always answers a current-version confirm renewed:true with the expiry the database holds. Confirms route by where their basis lives, so a flip between accept and confirm completes either way. Retries answer from a 10-min in-memory result map. * fix(relay-ops): store phonePath=db as no key, so old images keep taking writes An explicit phonePath=db left in the switch file would make the flag tool refuse every later write after an image rollback, including a watcher's admitMode=db flip back. * fix(relay): log a failed no-seat read, recheck the switch after the device read A failed assignment read for a phone with no seat now logs a rate-limited line before its 4409. A switch that turned off during the device read sends the phone down today's path. resolveResume reuses the one-read lookup, so the expiry and grace rules have one copy. * fix(relay): log a failed memory renewal; test flips, replays and basis cleanup A renewal write that fails still answers the stored expiry, but now logs a rate-limited line so a persistently failing update is visible before phones age toward re-pairing.
…n so they pass with the switch on (stablyai#30667) * test(e2e): create reveal-spec workspaces through main so they pass with the sidebar switch on The agent-send picker and host-section reveal specs injected fake repos and workspaces into the window store. With ORCA_SIDEBAR_INPUTS=main the sidebar lists main's rows, so those workspaces never appeared. The SSH host is now an unreachable target seeded into the stopped profile, and the paired-server host is a real headless orca serve host; pins, lineage and notes go through main. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): type the seeded hosts as execution host ids Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): poll the reveal specs' page setup instead of awaiting it across CDP An evaluate that awaits a preload promise sometimes fails with "Resulting promise was garbage collected" in switch-on runs. evaluatePolled runs the work in the page, polls its outcome, and still fails on a rejected or failed write. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): parent reorder spec creates its workspaces and links through main Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): lineage specs create their workspaces and links through main seedLineageScenario names and orders the two seeded workspaces and links them with assignWorktreeParent. Extra families and surrounding rows come from a fresh repo with real worktrees; pins and stale instances are main writes. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): default-branch and downward-drag specs create their workspaces through main Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): reveal and active-delete specs create workspaces through main The 60-row reveal, the folder-workspace reveal and both active-delete tests now use real workspaces and folder workspaces added through main, ordered with metadata writes. The deletes go through the real removal path, so the row removal sampler waits by time rather than a frame count. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): address review on the switch-on spec follow-up writeWorkspaceMeta now fails unless main lists the written values; the sleep test's parent is a real worktree instead of a store-faked one; the legacy inline-lineage case stays window-only and is skipped with the switch on; the parent-reorder collapse key is built from the row's host. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): read-back reports an unlisted workspace and compares values structurally Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): wait for the added repo before showing its worktrees updateRepo returns false without writing when the store does not list the repo yet. On CI the add's own refresh superseded the helper's fetch, so the visibility write was skipped and every discovered worktree stayed hidden. The helper now waits until the store lists the repo and fails if the write is refused. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): name the repo wait in its failure message Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): size the setup poll budget to the number of main writes evaluatePolled waited a fixed 10 s, sized for one write. Linking 53 children takes about 8 s locally and 36 folder workspaces about 4.5 s, so CI ran past it ("page work never settled"). Bulk setup now passes a budget of 10 s plus 500 ms per write. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…yai#30655) * feat(relay): add the per-cell phonePath switch, effective only in reserve mode Step 6 of the relay redesign keys every phone-path change on this switch. The cell reports the effective value in runtime status, and the flag tool refuses phonePath=memory unless the cell is reserve, and a reserve flip that would turn phones over unnamed. * feat(relay): resume paired phones from one device read on memory cells With phonePath=memory in reserve mode, a phone resume is admitted from one device read and the cell's own seat, and takes no activity leases. A refused device closes 4401, a failed read 4503, and only a missing device row falls through to the invite path. A phone whose host has no seat gets one assignment read: 4409 when the row names another cell or the read fails, otherwise 4404. * feat(relay): keep a memory resume's basis in the cell and confirm it from one read A phone resumed on the memory path keeps its connection basis in the cell, not in relay_connection_bases. Its confirm rereads the device row once, renews it only when less than 29 days remain, and always answers a current-version confirm renewed:true with the expiry the database holds. Confirms route by where their basis lives, so a flip between accept and confirm completes either way. Retries answer from a 10-min in-memory result map. * test(relay): roll a memory phone cell back with confirms in flight Flipping back by admitMode=db, phonePath=db or a dead-man trip leaves in-flight confirms to finish on their memory basis, writes no phone lease and leaks none, and evacuation still refuses the cell while Postgres records it as reserve. * feat(relay): batch a memory cell's resume-confirmed audit rows Memory confirms buffer their audit rows and the cell writes them as one multi-row insert every 5 s or 500 rows, idempotent by a per-event id. The buffer holds at most 5,000 rows and drops a row older than 10 minutes rather than retrying it, counting and logging both kinds of drop. * fix(relay-ops): store phonePath=db as no key, so old images keep taking writes An explicit phonePath=db left in the switch file would make the flag tool refuse every later write after an image rollback, including a watcher's admitMode=db flip back. * fix(relay): log a failed no-seat read, recheck the switch after the device read A failed assignment read for a phone with no seat now logs a rate-limited line before its 4409. A switch that turned off during the device read sends the phone down today's path. resolveResume reuses the one-read lookup, so the expiry and grace rules have one copy. * fix(relay): log a failed memory renewal; test flips, replays and basis cleanup A renewal write that fails still answers the stored expiry, but now logs a rate-limited line so a persistently failing update is visible before phones age toward re-pairing. * test(relay): assert a rolled-back memory splice issues no statement when it closes * fix(relay): flush resume audit early only on crossing the batch size, drop the shutdown flush A failing database no longer takes a 500-row insert per confirm; retries wait for the 5 s timer. The shutdown flush raced the pool closing, so it is gone and the at most 5 s loss is documented. A stopped buffer no longer re-arms its timer.
…k, layout-owner build only) (stablyai#30582) * ci: run the layout-owner switch-on specs as an advisory PR job Build the e2e app with ORCA_LAYOUT_OWNER=main through the existing e2e.yml (new layout_owner input, read only by the app and orcad builds), run the layout oracle, its positive control and the layout-owner acceptance specs with the save-divergence log on, and upload a summary by kind and spec. Not in the PR aggregate's needs. * ci: summarize divergence logs without a test report, and drop file-path ids from kinds * ci: switch-on job adds the stream-loss spec and the managed-SSH Docker lane, drops diff-word-wrap (fails switch off), and names each looped test in the summary * test(e2e): editor-model-host-isolation opens both files through the store's open action, so a layout-owner build's main holds the tabs * ci: the divergence summary skips a cut-short test report instead of failing * ci: re-run PR checks on a merge ref that includes the main typecheck repair (stablyai#30680)
… build only) (stablyai#30678) * The layout drift log names the values that differ * Keep the drift log's value copies type-checked and lint-clean * Give each side of each logged change its own size allowance * Name the drift log's id length cap apart from other modules' caps * The drift log names the terminal bound to each pane of a changed tab * Pin the terminal id length rule in the drift log tests
…e the commit (S10-H) (stablyai#30665) * feat(orcad-migration): host applies a signed editor-drafts blob inside the commit * fix(orcad-migration): consume received blobs only after the commit is on disk
… another host is never touched (stablyai#30664) * fix(projects): setup edits and removals name the host, so a twin on another host is never touched Repo-backed project host setups take the repo id, so a project on two hosts has two setups with one id. Update and delete took the first match by id, so editing or removing the SSH copy could rename or remove the local one. The args gain an optional hostId (older peers strip it and keep the first match). * fix(projects): tolerate only the legacy runtime stamp when a named host misses an independent setup * fix(projects): refuse a twin edit on a server that would act on the wrong twin; read legacy runtime stamps as local * fix(cli): refuse setup --host on a server that would ignore it * refactor(projects): exact host match only; name the host on the wire only for twins on one route * fix(projects): a named host the catalog lacks refuses; settings remove stays by id * refactor(projects): name hosts on the wire only for this computer's catalog; paired servers keep the by-id request
…crawl (stablyai#30704) * fix(ssh): keep SFTP uploads pipelined so a high-latency link doesn't crawl ssh2's WriteStream acks each chunk before writing the next, so uploadFile moved one 64 KiB chunk per round trip: about 200 KB/s on a 300 ms link, which made the ~90 MB managed-server deploy (Node runtime plus orcad bundle) take over seven minutes. A 2 MiB write buffer lets ssh2's _writev keep that many bytes of WRITE requests in flight, as fastPut's default does. Co-Authored-By: Claude <noreply@anthropic.com> * test(ssh): type the fake session's stream options with ssh2's WriteStreamOptions Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
… refuse a reserve roll target by name (stablyai#30707) * fix(relay-ops): let same-cap rolls run while another cell is reserve; refuse a reserve roll target by name The director refuses cell-status for a step-5 reserve cell with a 404 {error: cell_in_reserve_mode}. The same-cap headroom check read it for every general cell, so any roll failed while c7 was reserve. A reserve cell that is not being rolled now counts as no free slots (its seats are not in the database) and is listed with reserve: true. A reserve roll target, in the headroom check, the same-cap job's first cell-status read and the candidate tool, now fails with the design's procedure: flip it to admitMode=db first, roll, then flip it back. Any other 404 still fails. * fix(relay-ops): pin the headroom gate's imports as evidence code; name both cells in a two-cell reserve refusal
…d runtime-terminal-inspection (D2, D3) (stablyai#30684) * refactor: de-barrel remote-runtime-client and runtime-terminal-stream (D2) importers name the defining modules; the two vi.mock factories that named a re-export move to the defining module (pty-id spy) or drop the dead key (RemoteRuntimeClientError) * refactor(renderer): de-barrel runtime-terminal-inspection (D3) importers name runtime-terminal-input-recording, runtime-terminal-verified-input and shared/remote-runtime-pty-id; 22 vi.mock factories move the re-exported keys to those modules (pty-id keeps its other exports via importOriginal) * test: drop the duplicated verified-input mock (Opus P3)
…store (stablyai#30697) * plugins: extract the verified artifact-pack registry from language packs Pure refactor. Verify, bounded read, parse and per-plugin error handling move into PluginArtifactPackRegistry; language packs become one instance, so later data families reuse it instead of copying the file. * plugins: reconcile content families from one list Pure refactor. Reconcile and error reporting walk one family list in the same order as before, so a new family is one entry. * plugins: one line per family for declared artifacts and contribution defaults Pure refactor. Declared artifact paths are a list of per-family rows, and the contributes default comes from the schema (prefault) instead of a second copy of the field list; the existing defaults test pins the result. * plugins: extract the renderer plugin content list store Pure refactor. The fetch generation, startup join window and content-change subscription move into createPluginContentListStore; language packs become one instance, and store fields are renamed to entries/fetchEntries.
…uns out of space (stablyai#30679) * fix(ssh): say the host's disk is full when a managed-server install write fails for lack of space OpenSSH's sftp-server reports ENOSPC and EDQUOT as the generic SSH_FX_FAILURE, so a deploy onto a full home failed with the bare detail "Failure" under "Try connecting again". After a failed install write, probe the host's free space where the write was going; when it cannot hold the write, fail with an error that names the filesystem, how much is free and how much is needed. Lost or aborted transfers and Windows hosts keep their original error. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): diagnose only SFTP's generic failure on an exhausted filesystem Codex review: a partial upload may spend the room the rest needed, so compare against an empty filesystem, not the bundle size, and keep explicit refusals such as permission denied. Co-Authored-By: Claude <noreply@anthropic.com> * refactor(ssh): reuse formatKb and size an upload the way uploadDirectory walks it Opus review: the shared formatKb already exists, and following symlinks inside the tree could recurse; uploadDirectory follows the root and skips links below it. Co-Authored-By: Claude <noreply@anthropic.com> * test(ssh): measure the free-space probe in the host-op byte budget --------- Co-authored-by: Claude <noreply@anthropic.com>
…stablyai#30710) * fix(security): put every trust dialog on a host-owned token surface Plugin themes write CSS tokens on the document root, and dialogs portal to body, so any trust surface without plugin-security-chrome inherits them; a theme could hide what is being approved. The orca.yaml hook trust dialog, notebook run confirmation, plugin install, remove and rollback dialogs were missing it. DialogContent gains surface="security", which applies the host-owned tokens, and a scrollable prop for the plugin dialogs' existing viewport-height scrolling; every trust dialog uses the surface and a test lists them. The style guide says when to use each. * fix(security): keep inline trust decisions on the host-owned surface The agent command approval card (Allow/Deny) and the browser certificate override sit outside a dialog, so plugin theme tokens still reached them. A SecuritySurface primitive puts its child on the same host-owned token set as DialogContent surface="security"; both use it, and the security surface test now lists inline trust surfaces as well as dialogs.
…ablyai#30693) The Git runner sends a command into WSL when the working directory is a \wsl.localhost UNC path, even if no WSL distro is set in the options. literalPathspec only looked at the options, so Windows-style backslashes in file paths reached Git inside WSL unconverted and stage, unstage and discard failed to match the file. literalPathspec now also checks the worktree path, and every caller passes it. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…stablyai#30659) GitHub orgs using an SSH certificate authority get an SCP remote whose user is org-<id> rather than git. The three GitHub remote parsers only matched a literal git@ user, so those repos were classified not-github and lost PR, issue and check support. Co-authored-by: Yi-111-a <yi-111-a@users.noreply.github.com>
…er pages everywhere, headless sleep stops terminals (stablyai#30715) * fix(runtime): one owned-session teardown policy; removal closes host browser pages everywhere, headless sleep stops terminals A declared table says what each entry point (worktree, folder and project removal, sleep, disconnect) does to each owned kind (PTY, native chat, host browser page, launch record), so a new kind is a compile error until decided. Removal over desktop IPC and repo.rm now close the host's browser pages and launch records like the runtime removal; worktree.sleep with no renderer sleeps the host's terminals instead of doing nothing. Sleep->chat is declared pending stablyai#28445; disconnect stops nothing. * fix(runtime): project removal finds headless pages and failed launches without a client page; stub the new runtime method * fix(runtime): headless sleep rejects an unproven stop; read headless page owners through the bridge, not Electron
… remote contradicts (stablyai#30717) * fix(projects): refuse to set a folder up under a project its own GitHub remote contradicts Setting an existing folder up for a project stamped the project's identity as the folder's upstream even when the folder's own remote named another GitHub repository, so the folder was silently relabelled into the wrong project (fabricated upstream, wrong projectId on its setup and workspaces). Fixes stablyai#30663 * test: type the folder-remote spec store without casts * fix(projects): judge a registered folder by its current remotes; ignore host aliases * test: cover the desktop re-read of an already-registered folder
…the desktop (dark switch) (stablyai#30721) * fix(sidebar): key folder workspace rows by host in the shared builder so the phone matches the desktop Co-Authored-By: Claude <noreply@anthropic.com> * test(sidebar): pin the SSH folder row key encoding Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…all an older version" (stablyai#30724) * fix(ssh): name a noexec home instead of calling the host unsupported * test(ssh): measure the stage exec probe in the host-op byte budget * fix(ssh): the connect error names a noexec home too * chore(i18n): add the noexec status line to the English catalog * fix(ssh): only the shell's exec refusal reads as noexec; other probe failures reach the self-test * fix(ssh): a stage the probe can't write skips the probe, so a full disk still reads as full * fix(ssh): read the probe's exit 126 as noexec in any locale
v1.4.232 dropped the shellQuote export from preflight-command-exec (now quotePosixShell in shared/shell-argument-quoting, same bytes), stopped re-exporting RemoteRuntimeClientError from remote-runtime-client, moved ssh-target-registry under ssh/targets/, and moved invalidateAuthorizedRootsCache to ipc/registered-worktree-roots-cache. Four fork modules still imported the old paths and failed typecheck:node with TS2305/TS2307/TS2459.
v1.4.232 (stablyai#30756, stablyai#30811) made removeProjectForHost take the repo row and setWorktreeMeta take a HostWorktreeTarget instead of bare ids. The project ledger's contained-project removal now passes each captured repo row, and the worktree-groups membership test builds its targets with hostWorktreeTarget.
…y-id v1.4.232 (stablyai#30684) de-barreled runtime-terminal-inspection and runtime-terminal-stream, so isRemoteRuntimePtyId and toRemoteRuntimePtyId are no longer re-exported there. Two fork modules imported them through the old barrels and failed typecheck:web with TS2459/TS2305.
… fork code v1.4.232 renamed the composer catalog's sessionSkillNames to sessionSkills (name plus description) and added limit and trigger params ahead of the fork's namespacePluginSkills flag on buildNativeChatPickerItems. The fork composer passes the renamed field through unchanged, and the plugin-attribution tests pass the flag in its new position.
v1.4.232 (stablyai#28133) added an onStarted callback to AgentSessionContinuationDialog so the AI Vault panel can step aside once the new session launches. The vault panel renders the fork's handoff dialog through an import swap, which lacked the prop and failed typecheck:web with TS2322. It now fires after a successful start, as upstream's does.
…rag doubles v1.4.232 added status-drop-twin-host.test.ts, which builds the drop commit context without the fork's worktree-group drag, and a main-process sidebar list model that assembles its visible scope by hand. The group-membership drag is now optional (the context fields it fills already were), and the main list model reports no activity-hidden folders; that path is dark in shipped builds. Declares both seams and re-baselines the two residuals the earlier fixes moved.
…blish copy v1.4.232 (stablyai#30410) swapped ArtifactPublishButton's plain sign-in button for OrcaSignInButton plus OrcaSignInWaitNotice, so a sign-in in progress shows a copy-link and cancel. The fork's protected-sharing copy of the button still called connectCurrentOrcaProfile directly; it now takes the same nine-line change, and its fork header points at v1.4.232.
…orm is open (stablyai#31167) (cherry picked from commit fbc7488)
…blyai#31169) (cherry picked from commit 703b313)
v1.4.232 (stablyai#28133) makes /resume [search] in a structured chat open Agent Session History instead of reaching the agent, wired into upstream's NativeChatComposer. The fork replaces that composer, so the Orca row was listed in / but sent to the agent as text. Per the owner's decision, the fork wrapper now uses upstream's useNativeChatComposerCommandPicker, hands resume.consume to the structured submit, and wraps both pick bridges with resume.interceptPick (AgentComposer still applies goal mode outside it, as upstream does). Upstream's resume composer test mocks components the fork does not render, so it is rewritten against the fork field, keydown and draft hooks and declared a permanent exception.
v1.4.232 (stablyai#30254) points pnpm-workspace.yaml at config/pnpmfile.cjs, so the sandbox image's install failed with ERR_PNPM_PNPMFILE_NOT_FOUND and no test could run. The image context and Dockerfile now carry the file, and the image pins ORCA_PNPM_GLOBAL_VIRTUAL_STORE=0 so each throwaway shard keeps a project-local node_modules, as CI does.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
v1.4.232's repo-remove-for-host-teardown test pins runtime.removeProject(row)
with no second argument. The fork's ledger guard always passed
{ expectedLedgers: undefined }, so a plain removal no longer matched upstream's
call shape. It now passes the options only when the caller sent expected
ledgers, as project-group-handlers already does.
…override test v1.4.232 (stablyai#30725) passes { notifyFailure: false } to every web-runtime terminal create from the launch path. The fork's override-gating case still asserted the one-argument call; it now expects upstream's second argument.
v1.4.232's main-process-ready-duplicate-pty-repair test drives initializeMainProcessRuntime with a runtime double that has no getAskServices, and the fork seam called it unconditionally. forwardRuntimeAskEventsToRenderer does nothing on a runtime without ask services, which also shrinks the seam to one call. Re-baselines the three residuals these fixes moved.
…ai-orca-ru-20261020T1400 v1.4.233
Stacked on the v1.4.232 resolution (v1.4.233 carries upstream's clock fix for the cold-authority scanner test, stablyai#31098, which failed this PR at v1.4.232). - exceptions: release-mac-build.yml, electron-builder.config.cjs and the mac notarization contract test take upstream's delta cleanly; release-cut.yml keeps the fork's disabled Windows/Linux build job but takes upstream's build-mac need, since the merged signing gate reads its outputs; package.json keeps the fork version; generated catalogs regenerated. - seams: compute-visible-worktrees keeps both option sets; SectionHeader is v1.4.233 (host tooltip wrapper) plus the fork's lines, re-indented, with the worktree-groups seam line moved to match.
v1.4.232 (stablyai#30429) added a startup test that runs the real initializeMainProcessRuntime under an electron mock with no ipcMain. The fork's startup wiring hands ipcMain to the Claude suppression publisher, and Heimdall's hosted-review registration installs handlers on it, so the test failed on the missing export. The mock now carries an inert ipcMain, declared as a seam.
…lease-cut v1.4.233 (stablyai#31032) added release-windows-signing-gate.test.mjs, which pins release-cut.yml's Windows build job to run only after build-mac succeeds. The fork's release-cut.yml is a permanent exception whose Windows/Linux build job is disabled (if: false, no SignPath), so that one assertion can never hold. The test becomes a permanent exception that keeps every other upstream assertion and pins the fork's invariant instead: the job never runs.
zpyoung
deleted the
zpyoung/auto-sync-fork-with-upstream-stablyai-orca-ru-20261020T1400
branch
October 20, 2026 22:06
This was referenced Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ELI5
This brings the fork up to upstream's newest stable release, v1.4.233 (from v1.4.230), in two steps: v1.4.232 first, then v1.4.233 stacked on it. Upstream reworked a few places fork features hang off, mostly by moving modules and changing function shapes, so the fork's hooks were moved to the new homes. One upstream feature,
/resumein structured chats, lands inside a composer the fork replaces, so it was ported into the fork's composer at the owner's direction.What Changed
v1.4.233atc60a9b0a2a, merged on top of thev1.4.232resolution (49109f362f) described below. v1.4.233 shipped while this PR was in CI and carries upstream's own fix (test(ai-vault): stop the cold-authority scope test depending on the clock stablyai/orca#31098) for a clock-dependent ai-vault test that failed here at v1.4.232 and fails identically at the bare v1.4.232 tag.auto-ours+tree. 66 content conflicts resolved by-X ours, then 19 delete/modify tree conflicts by the two mechanical rules, then everything by the manifest.origin/backup/main-20261020-140239Zat762bf46be3.Ownership classifier: 4,398 paths reset to the tag, 212 removed, 167 exceptions restored, 2,188 merge-review paths.
ours.txt): 32 changed upstream and were three-way merged against v1.4.230. 21 merged clean. The 11 conflicts:pr.yml: all four go to the fork side, per ci: trim PR checks and disable standalone test workflows #127's trim. Upstream's new oxfmt check, the two new ratchet steps and SSH e2e sharding are not added; the ratchets still run inpnpm lint.release-mac-build.yml: takes upstream'squalification_onlydry-run plumbing but keeps the fork's runner, timeouts andzpyoung/orcagate. It also keeps the direct electron-builder call: upstream's newbuild-mac-notarization-overlap.mjssigns x64 and arm64 together, and this channel ships arm64 only.release-cut-token-permissions.test.mjs: upstream's newbuild-macexpressions with the fork repository.package.json: the fork's version line; upstream'spnpm@12.14.0pin and other edits merged clean.bug-1quarantine): the fork side. Upstream only de-barreled imports there (refactor: de-barrel remote-runtime-client, runtime-terminal-stream and runtime-terminal-inspection (D2, D3) stablyai/orca#30684), and the fork keeps its own quarantine-awaresendRuntimePtyInputVerified.en-runtime-required.jsonre-synced; the RPC params catalog was already current.reliability-gates.jsonc.checkout.txt): 8 workflows differed from v1.4.230. They were the v1.4.230 run's release-branch workflow copies, not fork edits, so they reset to the tag.v1.4.228) is fetched on demand by the fork'srelease-checkout.ts.Seams (
merge-review.txt). 158 seam files changed upstream. 125 re-merged identically. 32 conflicted and were resolved by hand, and 1 moved:OrcaRuntimeWithAgentTransitionsinto the runtime class chain, so the ledger import-swap moved into that layer (one seam replaces two). Repo removal now goes through upstream's row-basedruntime.removeProject(row, { expectedLedgers }). A paired server's residue row is dropped from the store directly, as upstream does, so it skips the ledger guard.native-chat-picker-items.tstosrc/shared/. The plugin-namespacing delta is replayed there, with the flag after upstream's newlimit/triggerparams. The newpiprofile getsnamespacesPluginSkills: false.use-terminal-tab-activity.ts.store/index.tsandAiVaultSessionRow.tsxwere rebuilt from the tag plus the fork's lines (upstream re-indented both);bundled-skill-guides.tsregenerated.Tier-2 copies: 16 checked.
loop-precheck-runner.tsreplays upstream's SSH registry move andquotePosixShell.AgentComposerActions.tsxreplays the keep-focusonMouseDown. All 16 headers now point at49109f362f.Tier-4 pending-upstream: every item still diverges from the tag, and every ledger target exists.
New fork exceptions:
mac-notarization-builder-contract.test.mjs(the release case asserts the fork's arm64 direct build) andci-managed-ssh-execution.test.mjs(the fork's PR workflow has no e2e caller).Fixes after the merge, one commit each:
cea4b0d33d: fork imports of helpers upstream moved (shellQuote,RemoteRuntimeClientError,ssh-target-registry,invalidateAuthorizedRootsCache).c62061a69f: row-basedremoveProjectForHostandHostWorktreeTargetwrites.01b5644801: remote PTY id helpers fromshared/remote-runtime-pty-id.6a96bca4e0: the picker'ssessionSkillsrename and new positional params.4ea1fc6fba:onStartedon the fork's continuation dialog.559b5c03ce: sidebar seams tolerate upstream's new list model and drag test doubles.d8a1a15f6b: upstream's sign-in progress button replayed into the fork's publish-button copy.eea537b9c8: upstream's/resumeported into the fork composer (see below).15e8408b3a: the test-sandbox image ships upstream's newconfig/pnpmfile.cjs(build: share one pnpm virtual store across worktrees (off in CI and on Windows) stablyai/orca#30254), without which its install fails withERR_PNPM_PNPMFILE_NOT_FOUND. The image keeps a project-localnode_modules, as CI does.Fixes from this PR's first CI run (v1.4.232 head
15e8408b3a):cross-version wire compatibility: the runtime-launcher protocol ratchet saw upstream's daemon protocol bump (49→50) and upstream's launcher changes in one diff. Upstream landed them in separate PRs, so this PR carries theallow-runtime-launcher-protocol-bumplabel, as sync PRs sync: absorb upstream v1.4.224 #115 and sync: absorb upstream v1.4.230 #122 did.26c4d7865e:removeProjectgets its options only when ledgers are expected, matching upstream's pinned one-argument call.e44603faca: the fork's launch-override test expects upstream's new{ notifyFailure: false }argument.c67e3af10b: the ask-forwarding seam no-ops on a runtime double without ask services, and shrinks to one call.81c03bba07: upstream's new duplicate-pty startup test gets an inertipcMainin its electron mock (declared seam), since the fork's startup wiring passesipcMainon.Fixes from the second CI run (v1.4.233 head
81c03bba07):ca08c3dc4c: v1.4.233's newrelease-windows-signing-gate.test.mjspins the Windows build job to wait onbuild-mac. The fork's Windows/Linux build job is disabled, so the test is now a permanent exception that keeps every other upstream assertion and pinsif: falseinstead.ArtifactPasswordPanel.test.tsxfailed once (it reads the passphrase label right after awaiting only the publish mock). It passed in the sandbox and on the next CI run, so it was flake.Final run on
ca08c3dc4c: 40 checks pass, 6 skipped, no advisory failures.session-scanner-scope-cwd-factsfailed identically at the bare v1.4.232 tag in the sandbox; v1.4.233's test(ai-vault): stop the cold-authority scope test depending on the clock stablyai/orca#31098 fixes it.v1.4.233 on top
-X oursover 4 content conflicts, no tree conflicts. Classifier againstv1.4.233: 680 reset to the tag, 31 removed (22 fork deletions, 9 files upstream dropped in its Remote Orca Servers rework), 170 exceptions restored, 2,191 merge-review paths. The undeclared-edit sweep found nothing.release-mac-build.yml,electron-builder.config.cjsandmac-notarization-builder-contract.test.mjsmerged clean.release-cut.ymlkeeps the fork's disabled Windows/Linuxbuildjob and takes upstream'sbuild-macneed, because the merged signing gate in that job readsneeds.build-mac.outputs.package.jsonkeeps the fork version. Both generated catalogs were regenerated.compute-visible-worktrees.tskeeps both sides' option fields.SectionHeader.tsxis upstream's new host-tooltip version plus the fork's 22 lines, re-indented, with the worktree-groups seam line moved to match. Residual budgets are unchanged.Feature-collision review
7 confirmed, 10 possible, 16 none. Every one except agent-composer is adapted above with no fork behavior removed. Two edge cases remain: id-based group-membership writes are refused on a same-id twin workspace, and per-run model/effort overrides do not apply to upstream's opt-in reused sessions.
Agent-composer, decided by the owner (orca ask): port. Upstream's
/resume(stablyai#28133) is wired intoNativeChatComposer.tsx, which the fork replaces with its agent-composer wrapper. Before the port,/resumewas listed in a structured chat's/menu but went to the agent as text. The wrapper now uses upstream'suseNativeChatComposerCommandPicker, handsresume.consumeto the structured submit, and wraps both pick bridges withresume.interceptPick;AgentComposerstill applies goal mode outside it, matching upstream's order. Terminal-backed chats and the terminal dock are unchanged, since/resumeonly acts with a structured transport. Upstream'sNativeChatComposer.resume-command.test.tsxmocks components the fork doesn't render, so it is rewritten against the fork field, keydown and draft hooks (same three cases) and declared a permanent exception. The owner also kept every other adaptation listed above.Why
Merging the stable tag keeps every fork SHA permanent. Moving each seam to the module upstream now uses keeps the fork's footprint in upstream files small, where defending the old module shapes would make the next sync conflict again.
Linked Issue
N/A. This is an upstream sync.
Visual Proof
N/A. This is an upstream merge; the fork-side changes are wiring only.
Testing
pnpm install --frozen-lockfile--verify-seamsand--verify-residuals v1.4.232typecheck:node,typecheck:web,typecheck:cliand the process-host test project, run one after anotherpnpm lintcheck-pr-verify-selections, the root-entry guard,check-fork-ownership.mjs, and thepreflightreplay