* fix(runtime): recover stale session owners and await retirement
* fix(runtime): preserve session hydration and smoke compatibility
* test(runtime): cover empty and unindexed session owners
* feat(cli): make terminal close the canonical workspace teardown
* fix(preload): align ssh termination result type
* test(runtime): assert folder hydration owner
* fix(runtime): fence legacy terminal stop by worktree host
* fix(preload): reconcile ssh result import with main
* fix(runtime): keep same-id sibling hosts out of workspace close
The stale-owner fallback in the session controller re-routed any worktree whose
catalog partition had no tabs to whichever other partition held tabs. Only
`runtime:` environment ids rotate across relay restarts; `repoId::path` legitimately
repeats across hosts, so an SSH workspace close could retire the local copy's
tabs and resume records, or flip owners mid-close and strand the SSH PTY.
Restrict the fallback to runtime hosts, and pin the session partition once per
workspace close so record clearing targets the partition that owned the tabs.
* test(runtime): give the cross-host close fixture a real resume record
* fix(preload): take main's ssh-bridge import order so the merge stays duplicate-free
* Fix orchestration CLI recovery, settled-Dispatch mail, and guide defects
Five reported orchestration CLI defects, verified individually before fixing.
Two were real code defects, one was a docs error, one was correct as-is, and
one was correct on both ends except for its recovery wording.
- Mail addressed to a settled `dispatch:<id>` was accepted and silently dropped.
Local sends bypassed the settlement check the federated branch already had, so
the caller was told success for a delivery no worker would ever read. Reject
with `dispatch_inactive` and name the Run mailbox to use instead.
- A lost mutation response offered no read-only way to ask whether it took
effect. `--retry-request` does dedupe correctly, but the recovery guidance
emitted a query command only when the payload carried a dispatch id, which is
exactly what a lost response lacks. Add read-only
`orca orchestration request-show --request <id>` over the durable receipt
ledger, and always emit a read-only step before the keyed retry.
- The bundled `orca-cli` guide documented `check --unread --inject`, a flag the
parser rejects. Correct it to `--format` and add a ratchet that runs every
orchestration invocation in the bundled guides through the real CLI parser.
- `check --json` is one stdout document and its keepalives are stderr-only; the
reported `Extra data: line 2` came from merging the streams. Document the
contract rather than changing the wire.
- A rejected lifecycle message is loud on both ends already, but the rejection
never named the flag that supplies the missing capability. Name it.
* Harden orchestration mutation recovery guidance
* fix(artifacts): gate agent artifact publishing behind an off-by-default capability
Public artifact sharing was reachable by any agent through `orca artifacts
share`: the Artifacts settings toggle only controlled sidebar visibility, and
nothing in the main process checked a capability before minting a public URL.
Add `artifactSharingEnabled` (default off) and enforce it in
ArtifactCloudService.share/update — before auth, network, or the share-record
write — so the CLI, relay-forwarded remote CLI, and IPC paths are all denied.
The denial carries a stable `artifact_sharing_disabled` code plus next steps
through the RPC error allowlist, so the CLI prints actionable guidance.
list, unshare, and delete stay ungated: turning publishing off must not strand
already-published links. The capability is absent from the `settings.update`
RPC schema, so an agent cannot grant it to itself — only the desktop UI can.
Co-authored-by: Orca <help@stably.ai>
* fix(artifacts): gate agent artifact publishing behind an off-by-default
Publishing is blocked until enabled in Settings → Artifacts. CLI preflights the capability before reading files to avoid unnecessary uploads. RPC surface rejects capability grants so callers cannot self-grant. UI shows opt-in workflow and recovery path when publishing is off. Web clients mirror the host's setting read-only.
---------
Co-authored-by: Orca <help@stably.ai>
* perf(runtime): gate terminal.list visual layouts and stop the false writable claim
visualLayouts is ~31% of a large terminal.list payload (44,208 B of 137,412 B on a live 134-terminal remote runtime) and has exactly one consumer: the human-readable CLI formatter. Gate it behind an includeVisualLayouts request param that defaults to included, so pre-flag clients are unaffected, and have every --json/internal caller opt out.
Also drop the record-backed builder's writable, which was a verbatim copy of connected. terminal.show now states writability explicitly as exactly what terminal.send's PTY gate enforces.
* test(runtime): type the payload-size fixture arrays for tsc
* fix(runtime): preserve terminal list compatibility
* test(runtime): guard terminal list optimization
* fix(cli): preserve agent access to terminal layouts
* Add version-matched bundled skill guides
* Clarify skill freshness rollout PRs
* Add canonical skills show alias
* fix(skills): address guide review feedback
* fix(skills): make guide commands cross-platform
* fix(skills): apply the ORCA convention to the emulator guides
Review follow-up: the emulator guides still instructed literal
`orca emulator ...` in sh fences with no Linux disambiguation, so on
unmanaged Linux they could launch the GNOME screen reader — the exact
failure the executable-selection preamble prevents. Both emulator
guides now carry the preamble and ORCA placeholder across fences,
tables, and prose, and the cross-platform safety test covers all four
converted guides. Also replaces computer-use's "unless a block names a
shell" carve-out, which contradicted its own POSIX example, with the
unconditional placeholder rule.