Audience: maintainer verification.
This record contains reusable version-scoped evidence for active runtime guarantees. The backend guides own current setup, safety boundaries, and limitations. Exact task chronology, branch names, temporary homes, local paths, process ids, thread ids, and delivery transcripts remain in private reports or PR evidence.
Foreground-process behavior was verified on 2026-07-07 with tmux 3.6a on macOS.
tmux new-session -d -s fmtest -n testwin
tmux display-message -p -t fmtest:testwin '#{pane_current_command}'
tmux send-keys -t fmtest:testwin 'sleep 30' Enter
tmux display-message -p -t fmtest:testwin '#{pane_current_command}'
tmux send-keys -t fmtest:testwin C-c
tmux display-message -p -t fmtest:testwin '#{pane_current_command}'Observed output:
zsh
sleep
zsh
A persistent parent shell waiting for a child remained reported as the parent process, while a shell that directly execed a simple command changed identity with the process itself.
Claude, Codex, OpenCode, and Grok were observed under their own process names.
Kimi Code CLI 0.29.1 was observed under kimi on 2026-07-25.
Pi and pi-signed 0.82.0 were reverified on 2026-07-27 through real isolated fm-spawn.sh launches.
Installed-wrapper checks:
basename "$(command -v pi-signed)"
pi-signed --version
pi --versionObserved bounded output:
pi-signed
0.82.0
0.82.0
The isolated process and endpoint checks used:
tmux display-message -p -t "$target" '#{pane_current_command}'
ps -o comm= -p "$wrapper_pid"
ps -o comm= -p "$engine_pid"
FM_HOME="$fixture_home" bin/fm-crew-state.sh "$task_id"Observed bounded shapes:
pi-launcher
.../pi-signed
.../Pi Launcher.app/Contents/Resources/pi/pi
state: done ...
Both launches executed a submitted tool instruction and touched the generated turn_end marker.
The pi-signed launch retained harness=pi-signed, while the plain comparison retained harness=pi.
The exact wrapper ancestry was pi-signed parent to Pi engine child, and the plain Pi Launcher path also traversed the signed wrapper on this installation.
That shared plain-Pi path is retained as disconfirming evidence against using ancestry as runtime-selection authority.
Firstmate therefore sets the exact FM_PI_HARNESS selection marker on both worker launch paths, while an unmarked Pi-family process remains pi.
Both recorded runtime identities now classify the exact pi-launcher foreground command as alive.
Backend applicability was reviewed across every spawn adapter.
Tmux needs the exact pi-launcher, pi-signed, pi, and Pi process identities for recovery-grade liveness.
Herdr uses native registered-agent state and needs no process-name branch.
Zellij has no verified recovery-grade agent process probe, while Orca and cmux do not support secondmate spawns, so those three retain their existing generic ordinary-launch semantics without a new liveness matcher.
The structural multi-row composer reader, Kimi pointer-delivery path, and OpenCode 1.18.4 busy-queue behavior are pinned by:
tests/fm-composer-ghost.test.sh
tests/fm-kimi-harness.test.sh
tests/fm-tmux-submit-busy.test.shExpected structural matrix: real text on any content row is pending; all-empty complete boxes are empty; unreadable, incomplete, or unsafe boxes are unknown; and non-bordered panes retain cursor-row compatibility. Expected submit matrix: proven pending plus busy is accepted as queued; proven pending plus idle remains pending; ambiguous pending is never converted by the busy exception; and only a proven empty composer succeeds directly.
The cleanup identity boundary was validated on 2026-07-28 with tmux 3.6a and metadata fixtures for every supported backend.
tests/fm-teardown-endpoint-safety.test.sh
tests/fm-teardown.test.sh
tests/fm-backend-herdr.test.sh
tests/fm-backend-zellij.test.sh
tests/fm-backend-orca.test.sh
tests/fm-backend-cmux.test.shBounded output from the incident regression:
ok - fm-teardown: missing, empty, malformed, ambiguous, and task-mismatched endpoints refuse before every mutation or runtime call
ok - cleanup identity: valid tmux, Herdr, Zellij, Orca, and cmux records validate while every empty backend target refuses
ok - tmux backend: direct empty target returns nonzero without invoking tmux
ok - process cleanup: creation-time PID identity removes only the exact child and preserves the control child
ok - fm-teardown: dedicated-socket invalid cleanup preserves target/control and valid cleanup removes only the exact target
The dedicated tmux cell removed ambient tmux variables, required a socket-bound wrapper, kept one target and one independent control window, and proved the wrapper was not called for invalid metadata or a direct empty target. Valid cleanup removed only the exact task-bound target and left the control window live. The metadata-only validation covers tmux, Herdr, Zellij, Orca, and cmux before backend dispatch. Claude, Codex, OpenCode, Pi, pi-signed, Grok, and Kimi share that backend cleanup boundary; their harness-specific hook files and token cleanup run only after it, so no harness needs a separate endpoint parser.
The compatibility floor is protocol 14. The latest active verification uses Herdr 0.7.5 protocol 17 on macOS aarch64, with earlier 0.7.5 protocol-16, 0.7.4, protocol-14, and 0.7.3 evidence retained where they define current behavior or fallbacks. Protocol 17 keeps every protocol-16 feature gate satisfied; the event and workspace-move floors remain 16.
Core read-only probes:
herdr --version
herdr status --json | jq -c '{client:.client.protocol,server:.server.protocol}'
herdr api schema --json | jq -c '.schemas.subscription_event["$defs"].SubscriptionEventKind.enum'Observed protocol-16 compatibility shapes:
herdr 0.7.5
{"client":17,"server":17}
["pane.output_matched","pane.agent_status_changed","pane.scroll_changed"]
The CLI matrix was checked directly:
| Guarantee | Command shape | Result |
|---|---|---|
| Explicit session routing | herdr <verb> ... --session <name> |
Reached the named session even while another server was running. |
| Literal send | herdr pane send-text <pane> <text> --session <name> |
Left text unsubmitted until Enter. |
| Keys | `herdr pane send-keys enter | escape |
| Capture | herdr pane read <pane> --source recent --lines N |
Small N could return empty below viewport height; a 200-line request plus local trim was stable. |
| Native state | herdr agent get <pane> |
Working and done transitions were visible; native busy remains positive activity evidence, while native idle cannot close a turn and the adapter's semantic lifecycle decides worker state. |
| Restart | guarded named-session stop then start | Workspace, tab, pane, and labels persisted; the agent process and registration did not. |
| Close | herdr pane close <pane> --session <name> |
The exact one-pane task tab closed; closing a final tab could remove the workspace. |
All destructive verification used bin/fm-herdr-lab.sh with a non-default fm-lab- name and a byte-identical default-session tripwire.
No ambient herdr server stop command is a supported test operation.
The real label-collision reproduction is owned by:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-prune-safety-e2e.test.shObserved guarantee: a pre-existing captain-owned workspace with a seed-shaped tab was adopted for routing but its tab was never eligible for prune because the current create call did not return that seed id.
Restart-husk replacement is owned by:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-respawn-idem-e2e.test.shObserved guarantee: a restored no-agent tab was replaced create-before-close, while a registered live agent caused refusal.
Herdr exports its pane identity into every process it manages, checked on 2026-07-30 against Herdr 0.7.5 protocol 17 inside a guarded lab pane:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh
"$HERDR_LAB_HELPER" run "$LAB" pane run "$PANE" "sh -c 'env | grep ^HERDR | sort > /tmp/env.txt'"HERDR_ENV=1
HERDR_PANE_ID=w1:p1
HERDR_SESSION=fm-lab-fm-herdr-env-pro-65961-25535
HERDR_SOCKET_PATH=/Users/kunchen/.config/herdr/sessions/fm-lab-fm-herdr-env-pro-65961-25535/herdr.sock
HERDR_TAB_ID=w1:t1
HERDR_WORKSPACE_ID=w1
This complete injection shape is verified only for Herdr 0.7.5.
Firstmate requires both HERDR_PANE_ID and HERDR_SOCKET_PATH before accepting claimed launcher ancestry.
pane get reports the pane's current owning tab and workspace, which is what placement resolves from; the injected HERDR_TAB_ID and HERDR_WORKSPACE_ID are creation-time snapshots and are not read as current identity:
"$HERDR_LAB_HELPER" run "$LAB" pane get w1:p1 | jq -c '.result.pane | {pane_id,tab_id,workspace_id}'{"pane_id":"w1:p1","tab_id":"w1:t1","workspace_id":"w1"}
Placement is owned by:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-launcher-workspace-e2e.test.shObserved guarantees on 2026-07-30 against Herdr 0.7.5 protocol 17:
ok - real herdr E2E: with one 'firstmate' workspace and no herdr parent, a crewmate still lands in this home's own workspace without stealing focus
ok - real herdr E2E: the normal unique-label path is unchanged when the launcher's own pane identifies the workspace
ok - real herdr E2E: presentation spaces still create the isolated child workspace and bind it under the launcher's exact parent, without stealing focus
ok - real herdr E2E: with two 'firstmate' workspaces, a worker spawned from inside the second one lands in that exact workspace
ok - real herdr E2E: the duplicate-labeled sibling workspace is left entirely untouched and focus is preserved
ok - real herdr E2E: with a duplicated home label, a projected worker still hangs off the launcher's exact workspace and the sibling stays untouched
ok - real herdr E2E: an ambiguous home label with no launcher identity refuses before any worker endpoint exists
ok - real herdr E2E: a launcher pane that no longer exists refuses before any worker endpoint exists
ok - real herdr E2E: a secondmate launching its own worker gets the same exact-workspace guarantee, and its same-labeled sibling is untouched
ok - real herdr E2E: a --secondmate launch still stands up that secondmate's own workspace instead of inheriting the launcher's
ok - real herdr E2E: teardown closes only the worker's own pane and leaves the launcher, its workspace, and the same-labeled sibling intact
That suite's headline case runs bin/fm-spawn.sh inside a real Herdr pane, so the parent identity comes from Herdr's own injection rather than a composed environment.
Cross-session and contradictory bindings are covered deterministically in tests/fm-backend-herdr.test.sh, which can script a second server's socket without provisioning one.
Per-home behavior is owned by:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-workspace-per-home-e2e.test.shObserved guarantee: the primary and secondmate used distinct home workspaces, a child launched by the secondmate stayed in that secondmate workspace, list-live remained home-scoped, and exact cleanup did not affect sibling homes.
The complete projection suite ran on 2026-07-21 against Herdr 0.7.4 protocol 16:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-presentation-e2e.test.shObserved guarantees included:
ok - real Herdr lab: primary and two secondmate homes each own a top-level contiguous child block
ok - real Herdr lab: concurrent primary/A/B spawns stay session-locked with zero focus drift
ok - real Herdr lab: session lock contention from a secondmate home falls back flat with no journal
ok - real Herdr lab: legacy projection labels and flat secondmate tabs are left unmigrated
ok - real Herdr lab: multi-home exact-pane teardowns restore captain focus without workspace close authority
ok - real Herdr lab validation completed on Herdr 0.7.4 with the default-session tripwire intact
The suite also covers lost or failed move responses, active-tab refusal, restart husks, missing and duplicate tokens, manual renames, concurrent cleanup, and exact focus restoration.
The mandatory projection suite ran again on 2026-07-24 against Herdr 0.7.5 protocol 16:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-presentation-e2e.test.shObserved restart-reclaim guarantees:
ok - real Herdr lab: Hi Bit and Wheelhouse-style same-identity restarts reclaim one nested space with exact focus and idempotence
ok - real Herdr lab: secondmate restart binding and reclaim stay isolated to the exact child home and parent
ok - real Herdr lab: concurrent cross-home recoveries replace exact husks under one session lock with no focus drift
ok - real Herdr lab: missing, renamed, and duplicate tokens trigger zero destructive or adoptive calls, and live duplicate risk refuses launch
ok - real Herdr lab validation completed on Herdr 0.7.5 with the default-session tripwire intact
The restored-shell session-start cleanup ran on 2026-07-24 against Herdr 0.7.5 protocol 17:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-herdr-session-cleanup-e2e.test.shObserved guarantee: one exact home-local, journal-correlated, one-tab and one-pane childless idle shell was closed after restoration while the exact non-target focus and default fleet session remained unchanged, and a repeat run was a no-op.
The focus-flash regression ran on 2026-07-28 against Herdr 0.7.5 protocol 17 on macOS aarch64:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-focus-flash-e2e.test.shObserved output:
ok - old path: the explicit last-pane close of a non-focused workspace stole focus (w3 w3:t1 -> w2 w2:t1)
ok - mitigation: every in-operation sample preserved exact focus while the doomed workspace was removed
ok - mitigation: no explicit close and no corrective focus were needed on the defective release
evidence: herdr=0.7.5 protocol=17 steal_live=1 default-session-tripwire=armed
Direct lab probes on the same day established the removal rules the emptying-close plan relies on, each verified with workspace list focus reads around one mutation in a guarded fm-lab- session:
- An explicit
pane closethat emptied a non-focused workspace moved focus off the focused workspace in both before-focus and after-focus geometries. - Ending a workspace's lone shell preserved the focused workspace exactly when the dying workspace sat behind it or the focused workspace was last, and moved focus to the focused workspace's right neighbor otherwise.
- The production focus-preserving close in the dangerous geometry repositioned the doomed workspace, ended its proved shell, and left every concurrent focus sample on the exact anchor with no corrective
tab focusissued.
Two real-hardware conditions were required for the pane-death path to engage and are now encoded in the adapter and its unit fixtures: BSD ps reports a login shell's comm as -zsh, and an idle shell transiently hosts a prompt helper (starship) as a second foreground process immediately after a workspace.move relayout, which the bounded settle window absorbs.
The rules match the v0.7.5 tag source (close_selected_workspace reassigns focus from the closing workspace's index; handle_pane_died only clamps the stale focused index), and the upstream default branch resolves both paths by workspace id (PR #1877, commit 165dca45, for the explicit close; PR #1912, commit a979916, for pane death), so the plan degrades to a harmless reorder-then-remove once a release carries them.
The full projection and restored-shell suites were re-run the same day on the same version with the updated close path; the presentation suite completed with real Herdr lab validation completed on Herdr 0.7.5 with the default-session tripwire intact, and the restored-shell cleanup guarantee above was unchanged.
The teardown-level record-retention gate was verified on 2026-07-28 with metadata fixtures and a live contending lock holder:
tests/fm-teardown.test.sh
tests/fm-backend-herdr.test.shObserved guarantees: a contended presentation lock refused the teardown before the isolated copy was returned, with the task branch, every durable record, and the endpoint intact and no pane close attempted; the retry after the contention cleared returned the copy, closed the pane under the lock, and removed the records; an unknown structured-presence result after an attempted projected close retained the journal and every record with a nonzero exit; and every presence-gate mode accepted only a structured not-found as gone.
The same fixtures verified three further boundaries on 2026-07-29: missing or malformed endpoint identity and an unparseable pane presence refused record removal with everything retained; the SIGKILL escalation re-read the exact pane's process information and refused to signal when a different shell pid owned the pane, falling back to the plain close with the original process untouched; and a reposition whose removal then failed on every path restored the exact original workspace order through a second verified move and reported the close as failed.
The teardown fixture was re-run on 2026-07-31 after extending the same fail-closed boundary through forced secondmate cleanup, including recursive cleanup of a nested secondmate whose Herdr grandchild close remains unconfirmed.
Observed output:
ok - forced secondmate teardown preflights every Herdr child before cleanup mutation
ok - forced secondmate teardown retains Herdr child identity until exact pane disappearance
ok - forced teardown retains a nested secondmate home and its grandchild's Herdr identity when the grandchild close is unconfirmed
Real captures verified these active distinctions:
- Claude and Codex use bare
❯and›agent composers. - Pi uses content between complete separator rows and requires exact native Pi identity.
- Dim or faint suggestion text is ghost content, while normally styled text is pending input.
- Grok dark truecolor placeholders are ghost content, while bright truecolor typed input remains pending.
- A bare shell prompt has no safe agent-composer container and is unknown.
tests/fm-composer-ghost.test.sh, tests/fm-composer-lib.test.sh, and the Herdr composer cases pin the exact captured ANSI bytes.
The U+2063 operational and routed-request separators were exercised through a real Pi-on-Herdr path; the byte-exact active regression is:
FM_SEND_MARKER_HERDR_E2E=1 \
tests/fm-send-secondmate-marker-herdr-e2e.test.shThe protocol-16 event path was measured on 2026-07-11 with Herdr 0.7.3 and Python 3.13:
HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-backend-herdr-eventwait-smoke.test.shObserved output:
ok - real herdr: events.subscribe capability gate passes
ok - real herdr: a driven idle->blocked transition returns the blocked record in 0.129s
ok - real herdr: the watcher fast-path enqueues a stale wake naming the task window
Polling remained active and is covered as the fallback for capability, connect, subscribe, and repeated reader failure.
The Pi/Herdr return and injection path was reverified on Herdr 0.7.3 and Pi 0.80.7:
FM_AFK_PI_HERDR_E2E=1 HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-afk-pi-herdr-return-e2e.test.shObserved guarantees: pending composer input refused injection and raised one alert; idle Pi accepted one marked escalation; the return gate refused ordinary work while a live blocker remained; resolving the blocker allowed the return flow.
The dedicated Herdr daemon workspace topology is covered by tests/fm-afk-launch.test.sh and preserves the captain tab's pane count.
The accepted-but-unconfirmed away-digest path is covered separately, against a real Pi primary with Calm on in an isolated non-default Herdr lab:
FM_AFK_DIGEST_REPLAY_HERDR_E2E=1 HERDR_LAB_HELPER=bin/fm-herdr-lab.sh \
tests/fm-afk-digest-replay-herdr-e2e.test.shThe regression probes both backends before it runs: it refuses to pass on a Pi older than the 0.83.0 operational follow-up acceptance path (it skips with that reason instead), calls fm_backend_herdr_version_check against the installed Herdr client, and prints an evidence: line carrying the observed herdr --version and pi --version.
Observed guarantees: Herdr's native working edge was suppressed after Pi accepted one operational message, so the daemon could never confirm the submit; the logical digest was typed exactly once and persisted exactly once in Pi's session JSONL, semantically inspected, across multiple housekeeping ticks and a daemon crash/restart; the unresolved items stayed buffered and durably marked unresolved with no concatenation and no replay; exactly one bounded delivery-uncertain alarm reached the wedge-alarm channel; and a captain-relevant escalation raised after the ambiguity still received its own single delivery attempt under a new logical digest identity, so the away channel never went dark.
The current compatibility floor and latest verification are Zellij 0.44.0 with jq on macOS aarch64.
All real tests use a uniquely named session and tests/zellij-test-safety.sh; they never touch a session named firstmate or call all-session deletion.
| Guarantee | Command shape | Result |
|---|---|---|
| Headless session | zellij attach -b <name> without a TTY |
Created a persistent background session and returned. |
| Session list | zellij list-sessions --short --no-formatting |
Returned one plain name per line without starting a session. |
| Create tab | zellij action new-tab --cwd <dir> --name <title> |
Returned a numeric tab id and focused the new tab when a client was attached. |
| Pane discovery | zellij action list-panes --json |
Included terminal pane id, tab id, plugin flag, and top-level pane_cwd. |
| Literal send | zellij action paste --pane-id <id> -- <text> |
Left text unsubmitted. |
| Keys | send-keys --pane-id <id> Enter, Esc, and one argument Ctrl c |
All three shared operations worked. |
| Capture | dump-screen --pane-id <id> or --full |
Worked with no attached client; no line-bound flag exists. |
| Close | close-tab-by-id <id> |
Removed the live task pane and tab together. |
| Failure exit | actions against missing targets | Returned exit 0, requiring structural preflight and output-shape validation. |
pane_cwd stayed frozen when a foreground subshell changed directory.
The marker-delimited pwd probe returned the live nested cwd and is covered by the real smoke.
The focus mitigation restored the previously active tab after new-tab, with the unavoidable narrow race documented in the operator guide.
tests/fm-backend-zellij.test.sh
tests/fm-backend-zellij-smoke.test.shThe real lifecycle smoke proved spawn, metadata, nested-subshell worktree discovery, send, capture, unlanded-work refusal, approved local landing, exact tab cleanup, and session cleanup without retaining task-specific ids or branch names here.
Real readiness was verified against /usr/local/bin/orca with /Applications/Orca.app bundle version 1.4.116.
orca status --jsonObserved fields:
result.runtime.reachable=true
result.runtime.state=ready
orca terminal create --json returned result.terminal.handle.
orca worktree create returned result.worktree.id and result.worktree.path.
Speculative bare ids and nested terminal fields were deliberately rejected.
tests/fm-backend-orca.test.sh
tests/fm-backend.test.sh
tests/fm-bootstrap.test.shThe fake-Orca suite covers readiness, registration, create response parsing, metadata routing, popup-safe submit, and path-matched release refusal.
The current compatibility floor is cmux 0.64, and the active live evidence uses 0.64.17 build 97 on macOS aarch64.
Real tests use only exact fm-test- workspaces guarded by tests/cmux-test-safety.sh and never quit or relaunch the captain's app.
cmux version
cmux pingObserved version:
cmux 0.64.17 (97) [9ed29d81a]
Source and live checks established the five control modes:
offstarts no listener.cmuxOnlyrejects an external Firstmate process by ancestry.automationuses an owner-only 0600 socket with no handshake.passworduses the same 0600 socket plusauth <password>.allowAlluses a 0666 socket with no authentication.
The live default rejection was Access denied - only processes started inside cmux can connect.
The live password challenge was Authentication required - send auth <password> first.
The app configuration writer did not retain a hand-added socket password, which is why the operator guide requires Settings and a local Firstmate password source.
Current active CLI findings:
| Guarantee | Command shape | Result |
|---|---|---|
| Create | new-workspace --name <title> --cwd <dir> --focus false --id-format uuids |
Created one workspace with one surface without focusing it. |
| Fresh readiness | list-panes --workspace <id> --json --id-format uuids |
Found a brand-new surface before content existed. |
| Fresh read counterexample | read-screen before any write |
Returned internal_error: Failed to read terminal text. |
| Literal send | send --workspace <id> --surface <id> -- <text> |
Left text unsubmitted. |
| Keys | `send-key ... enter | escape |
| Nested cwd | current_directory plus foreground subshell |
Structured cwd froze; the marker-delimited pwd probe found the live cwd. |
| Last surface | close-surface on the only surface |
Refused with invalid_state: Cannot close the last surface. |
| Last workspace | close-workspace on the only workspace in a window |
Printed success but left the workspace present. |
The last-workspace workaround was reverified on 2026-07-10 in Automation mode.
After creating one unfocused unnamed sibling in the same window, close-workspace removed the exact task workspace and left only cmux's default sibling.
A selected non-last workspace closed directly, proving that window cardinality rather than selection is the trigger.
Source inspection confirmed each workspace constructor creates a new UUID with no restored-id input.
Recovery therefore remains title-based.
The bundled Claude wrapper was observed stripping CMUX_* variables on its failed socket-probe path while retaining the app bundle id, supporting the macOS-only bundle-id and ancestry fallbacks.
tests/fm-backend-cmux.test.sh
tests/fm-backend-cmux-smoke.test.shThe real smoke proves socket access, fresh readiness, current-path probing, send and keys, bounded capture, title identity, and guarded exact cleanup.
A reusable Desktop host-tool smoke ran on 2026-07-06 against Codex Desktop bundle version 26.623.101652, build 4674, bundle id com.openai.codex.
Local paths and task-specific ids are intentionally not retained here.
The host-tool sequence was:
- list a saved project;
- create a Desktop-owned worktree thread;
- recover and read the thread while active and after completion;
- verify the thread appended a Firstmate status line and wrote its report;
- send a follow-up to the same thread;
- read the completed follow-up;
- archive the exact thread;
- read the archived transcript with state
notLoaded.
Observed guarantee: a Desktop-owned thread can write Firstmate lifecycle files when the prompt provides an authorized absolute path, and create, send, read, and archive work at the Desktop host-tool layer. The missing guarantee remains a supported shell-callable bridge that lets Firstmate perform those operations against the same visible Desktop endpoint. App-server partial methods and raw socket experiments do not satisfy that bridge contract.