Commit Graph
264 Commits
Author SHA1 Message Date
Brennan Benson a3eabcd730 Merge main into native chat SQLite storage
Carry retained Codex input intent, admission safety, account attribution and
idle confirmation through the SQL journal owners. Preserve main relocations
and deletions and the SQL queue, history and custody assertions.

Suppress publication of unchanged SQL command acknowledgments so empty queue
claims cannot renew a chat's idle clock. This SQL mismatch predates this sync;
main's new idle-retirement coverage exposed it. Mail custody fixtures now hold
native admission and use real edit leases without altering automatic delivery.

Validation: direct Node through tc-gate; merge hook, basic lint, tc:node,
e2e typecheck and pinned-main changed quality pass. All 148 owning tests in
25 files pass on both Node and configured Bun. O1 diagnostics remain excluded.
2026-11-12 18:41:39 -08:00
Neil d634063ef2 refactor: organize mobile cloud relay by lifecycle owner (#41681) 2026-11-12 14:36:07 -08:00
Brennan Benson 24c1bdee80 test(native-chat): preserve released chat queue publication coverage
Use the surviving queue publication owner after rewind and reopen,
preserving visible card persistence checks across both providers and all
three release cohorts without a production wrapper used only by tests.

Validation: all 49 cross-version and owning files pass on Node and the
configured Bun entry (148 passed, 1 skipped each); the e2e typecheck
ratchet has zero test errors and the owning static gates pass.
2026-11-12 14:14:03 -08:00
Brennan Benson 9ac5555fe0 Merge main into native chat SQLite source
Preserve the SQL journal authority while adopting main's consumer relocations, account holds, context usage and deliberate API/test removals. Move retained SQL regression assertions to surviving owners and keep the retired conversation title owner deleted.

The P7 costs remain small measured overhead: warm work lookup p50 rises by 0.167 us (3.542 to 3.709 us; ratio 1.047, 60/80 pairs slower), and empty / two subscribers / changed writer acknowledgment p50 rises 5.5% (0.259459 to 0.273833 ms; paired interval excludes parity) on a writer path P7 does not change. Completion improves from 1.546834 to 0.657125 ms.

The 232-commit consumer audit and local validation receipts are recorded in the lane evidence. O1 diagnostics work remains excluded from this merge.
2026-11-12 12:20:33 -08:00
Neil 9eb2195c64 refactor(ai-vault): group scanner modules by defining owner (#41520)
* refactor(ai-vault): group scanner modules by defining owner

* refactor(ai-vault): consolidate owner imports and isolate path absence

* Preserve mobile CI triggers for extracted absence predicate
2026-11-12 03:44:09 -08:00
Neil d3b6609ac9 refactor(rpc): group root modules by defining owner (#41475)
* refactor(rpc): group root modules by defining owner

* test(orcad): include JSON CLI failures in launcher diagnostics
2026-11-12 02:18:19 -08:00
Neil fb58871bdb refactor(claude): group root modules by defining owners (#41437) 2026-11-12 00:20:10 -08:00
Neil e902c9a65b refactor(workspace-layout): organize concrete domain owners (#41350)
* refactor(workspace-layout): organize concrete domain owners

* test(layout): retire obsolete legacy-leaf publication setup
2026-11-11 20:54:34 -08:00
Brennan Benson 4a34549647 Merge origin/main into native chat SQLite host 2026-11-11 07:12:42 -08:00
OrcaWinandOrcaWin 0184d8187d test: remove 98 low-value cases and 17 suites (#41124)
* test: remove 60 low-value cases and orphaned conversion fixtures

* docs(ci): list supported Windows SSH host cells

* test: recognize direct Windows orcad server entry

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 06:08:53 -08:00
Brennan Benson d24c8b2e00 Merge origin/main into native chat SQLite host 2026-11-11 05:33:44 -08:00
Neil 2195eae589 refactor(main): group search and profile implementation owners (#41082)
* refactor(main): group search and profile implementation owners

* test(browser): isolate retained preview grant callbacks
2026-11-11 01:02:18 -08:00
OrcaWinandOrcaWin 0db6fe6c44 test: remove 337 low-value test definitions across 13 suites (#41071)
* test: remove 337 low-value test definitions across 13 suites

* test: brace relay assignment fixture conditionals

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 00:15:57 -08:00
OrcaWinandOrcaWin fce98d7d21 test: remove 167 low-value cases and 93 suites (#41057)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-10 23:17:08 -08:00
Brennan Benson 7804c86776 Merge main while retaining SQL chat readers 2026-11-10 10:49:29 -08:00
Neil b07b3d318a refactor(renderer): group startup platform and runtime owners (#40777)
* refactor(renderer): group startup platform and runtime owners

* refactor(renderer): reconcile imports and retained validation metadata

* test: clear runtime pairing revisions between repo generation cases
2026-11-10 06:30:52 -08:00
Brennan Benson 37f033bd16 test: admit downgrade fixture owners through the SQL store 2026-11-10 06:10:08 -08:00
Brennan Benson 0c0bbc3e65 Merge commit '9728801985f' into brennanb2025/native-chat-sqlite-host
# Conflicts:
#	src/main/native-chat/agent-session-journal/journal-domain-import-rows.ts
#	src/main/native-chat/agent-session-journal/journal-sql-database-read.ts
#	src/main/native-chat/agent-session-journal/journal-sql-maintenance.ts
#	src/main/native-chat/agent-session-wire/journal-ingress/structured-agent-session-event-sink-queue.ts
2026-11-09 23:27:05 -08:00
Brennan Benson 1d2020a3cf Merge pinned main into the SQL journal branch 2026-11-09 23:16:27 -08:00
Brennan Benson 38d50953db Commit complete provider dispatches and preserve Stop sources 2026-11-09 20:44:36 -08:00
Brennan Benson befa38b3b9 Establish restart recovery debt in the record writer 2026-11-09 20:22:18 -08:00
Brennan Benson f351bf0e6f Align cross-version fixtures with async SQL publication
Wait for frames that follow committed reads, await the async
completion feed, route the outline and item calls to their current
host methods, and expect the restart unreconciled latch on loaded
records.
2026-11-09 05:36:02 -08:00
Brennan Benson 119bd3884f Align cross-version downgrade tests with one-way conversion
A downgraded build sees the chat and records as converted and its
later writes are not carried forward. Drop tests whose subject was
this build's legacy row and outcome writes; seed newer legacy rows
before the first conversion.
2026-11-09 03:01:42 -08:00
Brennan Benson 1d945af231 Port cross-version wire tests to SQL journal reads
Hosts take the shared domain database, reads go through named async
journal reads and catch-up history pages, and released-build fixtures
type the release's own synchronous journal API.
2026-11-09 03:01:40 -08:00
Brennan Benson 889a3233fe Use current chat test fixtures and name the handover journal owner 2026-11-09 02:21:18 -08:00
Neil 39902f398b refactor: bind browser and remote runtime consumers to concrete owners (#40135)
* refactor: use concrete browser and input owners

* refactor: bind remote runtime callers to concrete transport owners

* Use checked subscription mock argument types

* Type browser lease mock with its subscription contract

* refactor: bind sleeping VM status probe test to socket owner
2026-11-08 21:41:28 -08:00
Neil c50d4cd3e4 refactor: organize browser guest lifecycle owners (#39996)
* refactor: organize browser guest lifecycle owners

* test: resolve cross-version client owners and pre-ticket baseline

* test: record the released terminal registry path
2026-11-08 15:23:09 -08:00
Neil 0d1220c31f Organize SSH and managed-server modules by concrete owner (#39937)
* refactor(main): organize SSH transport and managed server owners

* Remove orphan deploy readiness fixture and shrink test baselines

* refactor(wsl): import lock records from their defining owner

* refactor(wsl): use the canonical deferred update contract
2026-11-08 12:20:22 -08:00
OrcaWinandOrcaWin 0da741a22f test: remove 988 low-value tests (#39797)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 00:42:37 -08:00
Neil 3a0e9a27d0 refactor: organize backend runtime by defining owner (#39625)
* refactor(main): organize runtime implementation owners

* test: retire wall-clock CLI title recovery case

* refactor: route new folder mutation to runtime store owner

* test: import folder mutation store contract from its owner
2026-11-07 22:24:34 -08:00
Neil c99e71b315 refactor: group renderer runtime resource owners (#39571) 2026-11-07 20:52:26 -08:00
Jinwoo Hong f341558b82 feat(cli): match folder workspaces by path: and name:, keep same-id ps rows apart (#39637)
* feat(cli): match folder workspaces by path: and name:, and keep same-id ps rows apart

Adds one runtime matcher for worktrees and folder workspaces. With the new
matchFolderWorkspaces opt-in (advertised as workspace-selector.folder-match.v1),
path: and name: also match folder workspaces; branch:, issue: and identity:
stay repo-backed. Several matches refuse with each choice's kind, host, path
and selector; a folder id shared by two folder workspaces refuses with the
repair step. The CLI resolves path:/name: through it, so terminal, file and
ports commands reach a folder workspace, and create/set parents record a
folder parent. Explicit ambiguous parents report LINEAGE_PARENT_AMBIGUOUS.

worktree ps now keeps rows that share an id on different hosts apart, with
their own host, identity, metadata and activity; activity whose host can't
be proven attaches to neither.

* test: let the cross-version ps harness pass the host-qualified summary lookup

* fix(cli): read each ps row's own host session; qualify folder selector help

* fix(runtime): refuse unscoped duplicate folder ids; hand lineage the matcher's typed result

Unscoped folder:<id> refuses a duplicated id even when only one copy's host
is derivable; a host-scoped lookup still picks that host's copy. A wsl: hook
stamp counts as local host evidence. The lineage controller receives the
worktree-or-folder candidate directly instead of re-deriving the kind.

* docs(cli): guide the ambiguity fallback through truncated ps and id: selectors

* fix(cli): report an ambiguous parent by its own choices; cover per-host sessions

* fix(cli): send parents to the runtime parent resolver as typed; translate WSL paths for folders too

Parent selectors skip the CLI's show-based folder lookup, so worktree.create
and worktree.set classify them with parent rules: a folder spanning hosts is
a valid parent, and ambiguity reports LINEAGE_PARENT_AMBIGUOUS. Caller-distro
Linux path translation now also matches folder workspaces.

* chore(rpc): import the computer-use recovery data directly instead of through an alias

* fix(runtime): report a missing set parent as LINEAGE_PARENT_NOT_FOUND, as create does

worktree set and worktree create now share one explicit-parent error
conversion: several matches give LINEAGE_PARENT_AMBIGUOUS and none give
LINEAGE_PARENT_NOT_FOUND, so a missing parent is no longer reported as a
bare selector_not_found that could mean the child.
2026-11-07 23:35:33 -05:00
OrcaWinandOrcaWin 8d2b5a2c07 test(rpc): drop the default-RPC-manifest guard where no default remains (#39684)
RpcDispatcher now requires its method list, so these suites can no longer consume
the default manifest. Suites that still reach the registry through the RPC server
keep the guard.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 20:10:01 -08:00
OrcaWinandOrcaWin 331864e249 test: remove 259 low-value tests (#39701)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 19:53:07 -08:00
Brennan Benson f108081dc3 Merge origin/main (single ordered queue) into the SQLite projection foundation
The queue's one ordered list now runs over the storage interfaces: the
SQL side reads live rows from the typed current-card table in
(position, message id) order, and the released-position, candidate and
lineage ports leave the projection. Old saved queues decode only at
open, in memory, and the writer's open converts them as main's does.
2026-11-07 13:03:23 -08:00
Neil b0ac9ae521 refactor: organize native chat composer and conversation owners (#39534) 2026-11-07 12:26:03 -08:00
Brennan Benson 133bc99e5a Keep waiting chat input in one ordered queue (#39271)
* Prepare queue rows to preserve accepted delivery intent

* Keep waiting native chat input in one ordered queue

* Keep a typed view of admitted queue records

* Keep the removed queue caption in the runtime catalog

* Remove the unused queue barrier caption

* Keep queue writes local and preserve accepted send provenance

* Read the sender from the queued admission request

* Keep continuation fixture clock within its operation window

* Remove deleted queue-barrier test from ratchet baseline

* Keep ratchet baseline change scoped to the deleted test

* Filter historical acceptance reads before loading payloads

* Instrument cached acceptance cursor once per fixture

* Restore original personal provenance after legacy card cleanup

* Complete legacy sender fixture metadata

* Narrow admitted history record types

* Reconstruct accepted personal proof after restoring original admissions

* Use the fixed clock for historical queue fixtures

* Consolidate queue source and type imports

* Preserve admission refusals and failed startup ownership

* Keep manual queue holds independent of later turn endings

* Remove obsolete mobile queue barrier expectations

* Keep journal format initialization independent of its decoder

* Assert returned-row recovery for released send clients

* Preserve Stop assertion across handoff-only publication
2026-11-07 11:35:38 -08:00
Brennan Benson d307cf015e fix(agents): workspaces created on a paired host use the host's launch settings (#38670)
* fix(agents): workspaces created on a paired host use the host's launch settings

Creating a workspace with agent picks or a draft could launch the paired host's agent with desktop settings, or lose the picks during recovery. Let capable hosts compose those launches from their own settings and preserve the user's inputs through fallback creation. Older hosts retain their existing requests.

* fix(agents): workspaces created on a paired host use the host's launch settings

When a workspace is created on a paired computer, agent picks and Arguments can be replaced by this computer's defaults or dropped during recovery. Keep explicit choices with the submission and let the paired computer resolve its own launch settings.

Preserve older-host request behavior, disabled-agent draft substitution and prompt submission, and restore the composer if compatibility preparation fails.

* fix(agents): workspaces created on a paired host use the host's launch settings

Keep the submitted choices available when a background launch has no prepared startup carrier. Tighten the regression checks for restored composer names, legacy commands and prompt submission so recovery preserves the user's work.

* fix(agents): workspaces created on a paired host use the host's launch settings

Creating a workspace on a paired machine could ignore its agent settings or lose a draft while the terminal connected. Keep the selected launch inputs and the pending text together through fallback and reconnect, and never replay partially written input. Preserve older hosts' launch commands and ordinary new-tab prompts' editable behavior.

* fix(agents): workspaces created on a paired host use the host's launch settings

Keep a workspace's pending prompt attached to its original terminal while the pane reconnects. Stop automatic delivery before reporting a final failure, retain the recoverable text, and recognize a launch handed off to the paired host even before its tab appears. Avoid delaying creation on a redundant host status request.

* fix(agents): workspaces created on a paired host use the host's launch settings

New workspaces on a paired computer could lose their first prompt when the terminal briefly disconnected. Delayed delivery could also continue after reporting failure, or leave terminal-only agents without an accessible copy of their prompt.

Keep pending prompts through attachment loss, stop content writes when automatic delivery ends, and offer the existing composer to recover unsent text. Preserve launch identity without inventing empty Arguments or treating missing metadata as a replacement.

* fix(agents): workspaces created on a paired host use the host's launch settings

A replacement pane can learn its terminal before the layout catches up after reconnecting. Re-registering the effective launch settings then dropped the original first-prompt identity.

Recover that identity from the existing verified terminal binding so later remounts keep the same pending prompt.

* fix(agents): workspaces created on a paired host use the host's launch settings

A terminal binding can identify the launch before its effective Arguments are known. Keep permission notifications working in that state without assuming a launch-settings recipe exists.

* fix(agents): workspaces created on a paired host use the host's launch settings

Keep an unsent prompt attached to its launch when a paired host briefly disappears, so reconnecting the same terminal can finish delivery. Clear the rest of the exited pane's status as before, and release the binding after delivery or a confirmed end.

Offer Copy prompt when automatic delivery finally fails, so the prompt can be pasted into the terminal that already opened. Keep creation-failure Reopen separate.

* fix(agents): preserve paired prompt recovery across transport updates

Resolve the consumed startup token through the pane's verified binding instead of reading renderer ownership during every remote attach. Keep the transport's host-authoritative exit and reconnect behavior and its fixture guards.

Settle pending prompt delivery when the host reconfirms a closed surface, including after it discards the terminal's exit record. Update the remount fixture for the Windows PTY model binding.

* fix(agents): merge duplicate imports flagged by type-aware lint

* test(agents): fix type assertions in paired launch fixtures

Type the repository rows, mutable agent choice and terminal tab used by
launch regressions. Reuse the session binding across its real installers
and document the partial-fixture adapters required by the runtime APIs.

Keep the RPC, remount and prompt-delivery assertions unchanged.

* fix(agents): route workspace terminals through their owning host

Creating a terminal for an existing workspace could send it to another focused server. Resolve its owning host when no explicit route was supplied, and keep the host-shaped draft regression within the shared startup contract so renderer checks do not pull in main-process code.

* test(agents): align launch fixtures with runtime dependencies

Retain real i18n exports while replacing translation output, hoist the terminal restore toast spy, and supply the explicit host environment used by paired terminal callers. Keep the existing behavior assertions unchanged.

* fix(agents): isolate prompt failure notice dependencies

Load the prompt failure notice only when a settled hosted launch needs it,
so workspace recovery consumers do not initialize toast and localized agent
catalogs just by importing delivery code. Keep prompt retirement and its
recoverable draft synchronous, and preserve the existing Copy prompt action.

Restore the ordinary new-tab failure toast's original invocation and verify
that Fix Checks retains its edited request through the activation handoff.

* test(agents): route legacy wire launches to their fixture host

Pass the paired environment explicitly in legacy terminal-creation fixtures,
matching real launch callers instead of relying on the focused host. Keep
all compatibility and accepted-creation assertions unchanged.

* fix(agents): preserve paired work-item completion without a startup plan

Blank-terminal work-item launches on paired hosts now keep their successful activation result. If the agent command cannot be built, show that error once instead of reporting an activation failure.

* refactor(agents): deliver paired creation prompts once like agent tabs

Drop the retained hosted-prompt lifecycle (pending map, rebind, deadline,
terminal retirement, token recovery). After the host creates the session the
desktop attempts the prompt once; failure shows the prompt-not-sent toast with
Copy prompt.

* fix(agents): silence prompt failures after closing a workspace terminal

Closing a paired workspace terminal before the agent was ready could report a prompt failure after that terminal was gone. Use shared launch completion and existing tab records to keep deliberate closes silent while preserving one Copy prompt notice after an interrupted delivery. Prepared launches now decide client delivery from the host request.

* fix(agents): report every failed paired prompt delivery

A paired host can retract its tab from inventory without the user cancelling the launch. Always report a failed prompt attempt with Copy prompt, using the same single-attempt completion as agent tabs.

* test(agents): name host-session fixture mock types
2026-11-07 11:12:43 -08:00
Neil 4d33cd22cc refactor: group native chat session reads and delivery by owner (#39526) 2026-11-07 10:02:15 -08:00
Neil c231b5d7da refactor: place renderer store state with defining feature owners (#39508) 2026-11-07 08:19:02 -08:00
Neil 23808bb73f refactor(renderer): organize host and terminal owners and remove forwarding shells (#39320)
* refactor(renderer): organize host and terminal implementation owners

* fix(refactor): align active adoption reliability references

* refactor(terminal): remove forwarding shells and stale mocks

* fix(renderer): consolidate direct owner imports

* fix(refactor): route incoming issue trust type to its owner

* test(runtime): give independent status viewers separate pairing tickets

* style(refactor): normalize rebased terminal mock formatting
2026-11-07 03:31:13 -08:00
Neil 55f353f4cc fix(ssh): keep old relay channels off the host's own SSH connection (#39435)
* fix(ssh): keep old relay channels off the host's own SSH connection

Each old relay still running a shell held one exec session on the target's
connection. At sshd's MaxSessions (default 10) every later exec failed, so the
host stuck at Connecting with 'Could not detect the remote platform: (SSH)
Channel open failure: open failed'.

* test: say why the session-limit repro needs a longer timeout

* test: note why the relay channel fakes are cast

* test: move the many-relays repro into the existing legacy relay bridge suite
2026-11-07 02:40:00 -08:00
Neil ee04233cf2 feat(pairing): show which devices still sign in with their original pairing code (#38949)
* feat(pairing): show which devices still sign in with their original pairing code

Settings lists paired phones and access links that signed in with a pairing
code but never exchanged it (apps from before single-use pairing) with
"Uses an older pairing method. Update ...". Display only; rows from older
builds are never flagged.

* fix(pairing): no update hint for links used by plain-http browsers or still pairing

A link that served a session-only browser key is marked, so the hint stays
off after a host restart drops those keys. Codes still inside the pairing
window are not flagged either: an updated client exchanges within moments.
2026-11-07 02:17:33 -08:00
Neil e1379b34f3 feat(pairing): Add server and orca environment add exchange the link for their own token (#38948)
* feat(pairing): Add server and orca environment add exchange the link for their own token

After verifying the host, Add server (and repair) swap the access link's
token for one generated on this computer when the host advertises
pairing.ticket-exchange.v1, and save that instead. orca environment add does
the same with a short best-effort probe. Any failure saves the link as today;
the host keeps accepting it until the new token is used.

* test(pairing): Add server and CLI leave links unchanged for a released host

* fix(pairing): Add server and orca environment add sign in once after exchanging, and the CLI rejects a refused code

After exchanging a link, sign in once with the new token so the host
retires the link right away instead of at the first later use; a host
downgraded in between would not know the new token.

orca environment add no longer saves a pairing code the host refuses
(for example one another device already used); it asks for a new code.
2026-11-07 01:48:16 -08:00
Neil ddd3a071c3 feat(pairing): a browser's saved device key retires the pairing link it came from (#38947)
* feat(pairing): a browser's saved device key retires the pairing link it came from

When a browser signs in for the first time with a saved device key forked
from a ticket row, the row's link token is replaced by a value nobody holds
(the row stays as the fork's anchor; orchestration fingerprint pinned).
Session-only keys re-register from the link on every page load, so they never
retire it. Links from older builds are untouched.

* fix(pairing): a browser key retires a link only during pairing and only if nobody claimed it

A saved browser key now retires its link only when it was registered within
the pairing window of the link's first sign-in, and only when no other
client already proposed its own token for it (that first claim wins, so the
desktop that proposed first is never locked out).

* test(pairing): the web key migration wire test expects a fresh link to be single use

* fix(web): say a refused pairing link may already have been used

A browser opening a single-use link after another device used it is
refused as unauthorized; the message now names that case and asks for a
new pairing link from Orca.
2026-11-07 00:42:11 -08:00
Jinwoo Hong 228263d566 feat(automations): launch desktop runs from main, not the renderer window (#39247)
Desktop automation runs now launch from the main process through the same launcher orca serve uses. The renderer dispatch path is deleted.
2026-11-07 03:04:56 -05:00
Neil b0a4b33908 feat(pairing): let clients exchange a pairing code for their own token (#38937)
* feat(pairing): let clients exchange a pairing code for their own token

New offers are marked as tickets. A client signed in with the pairing token
can call pairing.exchangeTicket with a token it generated; the host stores it
durably and keeps accepting the pairing token until the client first signs in
with the new one. That sign-in retires the pairing token and cuts sockets
still using it. Advertised as pairing.ticket-exchange.v1; clients that never
call it keep working exactly as before.

* fix(pairing): never retire a code other clients may already rely on

Exchange is offered only within 10 minutes of a ticket's first sign-in;
after that the code may be in use by several older clients and stays a
plain token. The first client to propose keeps its claim: a different
proposal is refused (that client keeps the code) instead of displacing it,
so two clients pairing at once can't lock out the first. Adds cross-version
tests against the pinned release: downgrade keeps exchanged and unexchanged
phones working, rows from an older host are never single-use, and the older
host doesn't advertise the exchange.
2026-11-06 23:57:05 -08:00
Brennan Benson ad4bb83fa1 Open the chat model picker without walking every worktree (#38660)
* fix(native-chat): list Claude and Codex models per account, not per folder

Opening the chat model picker rebuilt every worktree row to work out which
folder the read was for, because Claude and Codex model lists were keyed by
folder. Only the default model/effort depends on the project, so lists are now
keyed by account, WSL and the resolved CLI invocation and listed from the
account folder; the CLI is still resolved where the chat would launch. The
selected workspace is derived directly from its selector, and its own project
settings decide whether the account's default model and effort are shown.
The worktree projection and its cache are removed.

* test: merge duplicate node:os import

* fix(native-chat): list from Orca's probe folder, keep cwd-relative CLIs in their folder, one project-settings pass

- List Claude/Codex models from Orca's empty probe folder so a home folder's settings never read as another account's project settings.
- A command line naming files relative to the chat's folder lists there and is keyed to it.
- Read project settings once per binding for both the model and effort answers; per-model effort-only Claude settings keep the account model.
- A running chat's catalog withholds the account's configured choice where its project may pick its own.
- Bound the picker's workspace resolution so a stalled floating folder cannot hold it.

* fix(native-chat): catch quoted ./ arguments, list prewarm from Orca's probe folder, fake-timer the shared-listing test

* perf(native-chat): parse each project settings file once for both model and effort

* test: catalog e2e expectations list from Orca's probe folder; phone saturation keys per folder

* fix(native-chat): share a listing while any reader wants it; list custom command lines in the chat's folder; resolve a floating folder within the read's own wait

- A model listing shared by several folders keeps running while any reader still waits on it, queued or running, and stops (never starts) once the last one gives up.
- A Claude or Codex command line with user arguments or a relative command lists in the chat's folder; Claude reads only user settings there so project settings never narrow the account's list.
- A waiting read resolves a floating folder within its own deadline; a read that doesn't wait returns at once and starts the listing when the folder resolves.

* fix(native-chat): every reader of a shared model listing owns it until its own deadline; floating reads list their folder within their own budget

- Readers of the same request share one lookup that lives until the last reader's deadline, so later readers neither repeat CLI/settings setup nor lose the listing when an earlier one ends or is cancelled.
- A shared listing's requests carry no single reader's deadline: the provider timeout bounds them and the last reader leaving stops them.
- A floating picker read that doesn't wait starts its folder's listing under its own deadline and retirement, and says the listing is in progress so the picker follows with a waiting read.

* fix(native-chat): a shared model listing survives the chat that started it; unreadable workspaces list as the account

- Each reader of a shared lookup fences its own request, so one chat closing never ends another chat's listing; the lookup's budget is the latest deadline among readers still waiting, and its listeners are released when it ends.
- A picker for a workspace this host can't inspect (remote, WSL, ambiguous, stalled) lists as the account does from Orca's probe folder, never from wherever Orca itself runs.

* refactor(native-chat): readers of one model request share an ownerless setup and each own only their claim and the listing

- Same-request readers share one setup (folder, account, CLI scope and the folder's own default settings) that belongs to no reader: its budget is fixed when it starts, it ends with the service or the agent's retirement, and it is reused while it runs and while the listing it found runs.
- Each reader keeps its own claim, deadline and cancellation; a binding holds scope facts only and never cancels another reader's claim or a shared listing, so one chat closing never ends another chat's listing.
- A floating picker read that doesn't wait no longer asks to list the unresolved folder.

* fix(native-chat): shared catalog setups end on their budget or a workspace change, readers settle on cancel, and defaults and account seeding happen once

- A shared setup that runs out of its budget, or whose workspace or agent is retired, answers nothing at once and leaves the cache, so a reader with time left resolves afresh (a moved folder never reuses the old path).
- Cancelling a reader, or stopping the service, ends its wait at once.
- A folder's own default settings apply to its binding whenever they arrive; the account list is seeded once per shared setup, not per reader.
- A reader shares a setup only with readers whose own chat agrees on whether it may list.

* fix(native-chat): a settled catalog setup serves its whole listing, and a folder's default settings stay bounded and reach every reader

- A setup that has answered stays reusable while the listing it found runs, past its first reader's deadline, until it is ended or its agent retired, so later readers don't redo CLI and project-settings work.
- The setup's budget holds until the folder's default settings have answered too; settings that outlive it are read again while a reader still has time, and apply to the request's current binding whichever reader asked.

* refactor(native-chat): the catalog service owns each model refresh within one fixed budget; pickers only wait

A refresh (account, folder and CLI resolution, the folder's default settings,
admission and the listing) now belongs to the catalog service with one 30s
budget fixed before setup. Readers join it and wait only until their own
deadline or cancellation; none extends, shortens or ends it. Expiry withdraws
queued listings, stops the process and drops late answers. Defaults apply only
to the refresh's own binding, so a moved folder's late settings never describe
the new folder. A waiting read that used its whole budget is final.

Replaces per-reader claims, shared setups and reader-counted listing demand.

* fix(native-chat): retiring an agent or a chat's folder ends its catalog refresh at once, and a shared setup never rechecks the chat that started it

- Retiring an agent ends a refresh still stalled in setup, so a waiting picker
  answers at once instead of after the refresh's budget.
- A listing that runs in a chat's own folder stops, and its answer is dropped,
  when that folder's command context retires; listings shared across folders
  stay independent.
- Scope resolution uses only the passivity its readers had when they asked,
  so another chat's record going away mid-setup no longer turns it saved-only.
- A reader that stops waiting unsubscribes from the listing at once.

* fix(native-chat): one workspace's retirement no longer stops a catalog listing another workspace shares

A listing is keyed by the folder it lists in and the CLI invocation, so moving
one workspace never makes it describe the wrong folder; stopping it there
cancelled a listing another workspace on the same folder still needed. Agent
retirement and shutdown still stop listings at once.

* test(native-chat): a folder change keeps another workspace's shared catalog listing, and never answers the new folder with the old one's

* test(native-chat): a folder agent's listing survives another workspace on its folder moving

* test(native-chat): type the shared-setup harness's held stages without casts

* fix(native-chat): Claude and Codex pickers show the account's default in every folder

The picker no longer reads a repo's own model or effort settings for Claude and
Codex: they show the account's list and default everywhere, and the CLI still
applies the repo's settings at launch. OpenCode, OMP and Pi keep their project
checks. The model/effort split and the peek withholding go back to main's shapes.

* fix(native-chat): a Codex listing in the chat's folder never loads that folder's project config

A Codex command line that may name files in the chat's folder still lists there,
but now marks that folder and its parents untrusted for the listing, so a repo's
own model catalog can't replace the account's. The exported project-settings
check also answers no for Claude and Codex.

* fix(native-chat): Codex lists models only from Orca's probe folder

A Codex listing no longer starts in the chat's folder for custom or relative
command lines, so a repo's own config can never change the picker's list, as
other Codex hosts do. Chats still launch with the user's command line and folder.
Drops the untrusted-folder override.

* fix(native-chat): Codex listings never read project config above Orca's folder

With no project-root markers, Codex reads project config only from the listing's
own folder, so a trusted repo that contains Orca's profile can't supply the
account's model list.

* docs(native-chat): say what Codex listing isolation covers, and what managed config can still restore
2026-11-06 16:59:49 -08:00
Brennan Benson 113d0c6d74 Keep released journal states readable in upgrade comparisons 2026-11-06 16:57:53 -08:00
Brennan Benson 58593c1626 Adapt journal contract tests to keyed storage types 2026-11-06 16:55:47 -08:00