Files
orca/docs/reference/agent-session-search.md

119 lines
6.6 KiB
Markdown

# Agent-session search across hosts
```sh
orca search --agent-session "key phrase"
orca search --agent-session "key phrase" --host runtime:server
orca search --agent-session "key phrase" --host ssh:target
orca search --agent-session "key phrase" --environment server --host ssh:target
orca search --agent-session "key phrase" --host all --json
```
The default searches the addressed runtime. `all` includes that runtime, saved
pairings on the CLI machine, and its already-connected direct SSH targets. When a
remote environment or pairing is selected, `all` includes only that runtime and
its connected direct SSH targets. It never recursively enumerates peers, connects
SSH targets, deploys a relay, or enables indexing. Connection aliases are retained;
identical paths or session IDs do not establish identical owners.
Results are grouped by host, with each host's ranking, query repairs, and coverage.
`--limit` is per host (20 by default, at most 100). Five matches on each of two
hosts return ten hits when budgets permit. Aggregate JSON includes each host's
outcome and `partial`; a failed or excluded host is distinct from a successful
query with no matches. The exit status is successful if any host completes its
query, including a zero-match query. Interrupting returns status 130.
`--agent` and `--path` repeat. Paths are literal predicates evaluated on each
execution host, with no implicit current-folder restriction. SSH/all require
absolute host-native paths, including Windows drive/UNC paths. Remote/all do not
expand `~`. A query's filters do not restrict indexing consent.
## Consent and index lifecycle
```sh
orca search --enable --history-days 90 --host ssh:target
orca search --index-status --host ssh:target
orca search --pause --host ssh:target
orca search --resume-indexing --host ssh:target
orca search --disable --clear-index --host ssh:target
```
Management always selects one host. Status cannot be combined with a query or
mutation; contradictory flags and invalid filters are rejected before mutation.
Clear with indexing enabled rebuilds the index. Disable plus clear removes it.
Pause retains searchable data while stopping new indexing.
Paired runtimes use their existing settings, scanner child, and canonical
`ai-vault-search/index.sqlite` under their data directory. Standalone `orcad`
ships the same scanner and its sibling workers. Availability checks use an
in-memory FTS5 probe, never transcript discovery. Node.js 22.13+ with `node:sqlite`
and FTS5 is required; unsupported runtimes keep ordinary runtime operations and
report search unavailable. Failed policy application is exposed as unapplied,
and explicit configuration does not acknowledge success before application and
the runtime's durable settings flush.
Plain SSH runs the existing search service inside the relay's existing low-priority
scanner child. Its account-local state lives in `~/.orca/session-search-relay`,
outside versioned relay install directories, separately from runtime profiles.
Consent defaults off and is bound to the authenticated account's default source
home. The scanner also includes the existing remote managed Codex home. Controller
environment variables and arbitrary client-supplied discovery roots are not used.
A separate stable SQLite database holds an exclusive transaction while a relay
owns the index. Other owners fail explicitly; SQLite releases the lock on process
exit. Policy is atomically persisted under that lock. After five seconds the owner
releases the index when its active requests and backfill pass finish. It does not
abort discovery or parsing to hand off: doing so can permanently starve a slow
source tree. Search, status and pause remain responsive through the same owner;
a different relay generation receives an explicit busy error until the pass
finishes or the current owner pauses. This deliberately favors a single complete
pass over periodic teardown and rediscovery. Reacquisition rereads authoritative
policy. Scanner retirement after ten idle minutes pauses work; a later search
resumes it, skipping files already current in the durable index.
Returned files are checked on the execution host for local, paired and SSH search. Confirmed missing files are
invalidated; unverifiable files are omitted with an explicit count. Raw resume
commands are labeled with the execution host and working directory. Search does
not add a cross-host resume/delete command or infer workspace identity from a
path. Provider coverage remains that of the existing indexer, including its
unindexed providers.
OpenCode rows are checked individually, so deleting or archiving one session in a
shared database does not remove the other sessions or leave the deleted hit visible.
## Routing, compatibility, and budgets
The controlling runtime forwards `aiVault.sshSearchSessions`,
`aiVault.sshSearchIndexStatus`, and `aiVault.sshSearchConfigure` through its
registered SSH provider's existing `requestHostRpc` and relay multiplexer.
Distinct targeted methods ensure an older runtime rejects the request instead
of stripping a target field and searching or clearing its own index. Existing
runtime `executionHostId` remains a label. Aggregate search requires affirmative
policy evidence; absent legacy policy is unknown and is excluded.
The CLI queries at most 16 routes with concurrency three, a 15-second host budget,
a 30-second overall deadline, and a three-second SSH inventory budget. New hosts
project replies to 512 KiB, snippets to 4 KiB, and the aggregate to 4 MiB, reporting
omissions. Cancellation travels through the existing RPC, provider, relay and
scanner cancellation paths. Already-sent mutations are not replayed after lost
acknowledgement. Synchronous SQLite work cannot be interrupted mid-statement.
## Verification
```sh
ORCA_BACKGROUND_LAUNCH=1 pnpm exec vitest run --config config/vitest.config.ts \
src/cli/session-search-all-hosts.test.ts \
src/main/runtime/runtime-ai-vault-ssh-search.test.ts \
src/main/runtime/rpc/methods/ai-vault-search.test.ts \
src/relay/session-search-owner.test.ts \
src/relay/session-search-owner-process.test.ts \
src/shared/ai-vault-search-projection.test.ts
```
The fixtures cover owner-separated results with colliding IDs, unknown consent,
stalled inventory, cancellation, mixed-version refusal, lease release, a real
scanner-process crash, durable consent, clear, missing transcripts, and byte limits.
Live validation also exercised the built CLI against an isolated authenticated
paired `orcad`, and a registered provider through real authenticated Docker SSH,
relay and scanner. The latter retained its relay PID and a test PTY through clear.
Native Windows/WSL and rendered desktop/web selection UI require separate live
coverage; this implementation adds the CLI surface.