Status:
draft · Version 0.2 · Filed 2026-05-04 · Updated 2026-05-04 (Texi review v0.1 → v0.2)version: 0.2 status: draft
Title: SPEC-084 v0.2 — prism_install_editor_host — AI-FIRST editor-host install verb
Origin
P2 install rehearsal on mini1 (Win 11, Node 22.17, pointing at mini4 LAN backend) surfaced an MCP-verb gap: the editor-host install lane has no MCP wrapper. Available install verbs:
Today the editor-host install path is a manual sequence: SSH to host, scp
cli/dist + mcp-node/dist + each package.json, npm install --ignore-scripts in each, then run prism install --mode lan --host <backend> --port <port> --api-key <key> on the host. This violates feedback_ai_first_end_to_end.md and forces the operator to remember the scp recipe.
Validated end-to-end manually (mini1 cycles 1–4, 2026-05-04) — every step is mechanical and SSH-ready.
§1 — Goals
- One verb call → working editor host. From the operator’s machine:
prism_install_editor_host(target=mini1)produces a Win/Mac/Linux editor host wired with the prism MCP shim talking to the named backend, with no manual SSH or scp. - Re-uses the credential exfiltration chain shipped in PR #157: the operator’s
~/.prism/credentials.<backend_target>.jsonis the source of truth for the API key the new editor host needs. Operator never sees or copies the secret. - Same per-invocation log file UX as install_lan. Writes
~/.prism/logs/install-editor-host-<target>-<UTC>.logwith timestamped per-stage entries;tail -f-compatible. - Idempotent. Re-running on an already-installed editor host equals an upgrade — refresh dist tarballs, re-run
prism install, validate handshake.
Non-goals (v0.2)
- Distribution mechanism beyond scp-from-operator. npm publish / fetch-on-demand / single-binary is the next install-lane SPEC.
- Per-host fan-out / concurrent installs. v0.2 is one host per verb call.
- PowerShell remote shell support. v0.2 requires
cmd.exeon Windows targets (default for Win OpenSSH 9.x); PowerShell-shell support deferred to v0.3 with separate command builders.
§2 — Target Registry — Discriminated Union (Texi v0.1 finding 1)
~/.prism/targets.json is extended with an explicit kind discriminator. Verbs select targets by kind; cross-kind selection is a config error.
§2.1 — Schema
§2.2 — Resolver Rules
resolveTarget(name, expected_kind) algorithm:
- Look up entry by name. Missing →
target_not_found. - Read
entry.kind. If absent (legacy v1 registry), see §2.4. - If
entry.kind !== expected_kind, fail withkind_mismatch{got: <kind>, expected: <kind>}. No silent coercion. - For
kind=editor_host: also resolveentry.backend_target. Missing →editor_host_missing_backend_target. Resolved entry’s kind must bebackend_lan→ otherwisebackend_target_not_backend_lan.
§2.3 — Verb / Kind Matrix (normative)
§2.4 — Migration from registry v1
Pre-existing v1 entries (nokind field) are interpreted as kind=backend_lan for backward compatibility. The first write through prism_configure_lan upgrades the file: writes version: 2 and adds kind: "backend_lan" to existing entries. New editor_host entries are written via a new prism_configure_editor_host companion verb (out of scope for this SPEC; tracked as a §6 follow-up).
§3 — Verb Argument Contract (Texi v0.1 finding 3)
Two mutually-exclusive modes, validated at the input boundary:§3.1 — Mode A: target (registered)
§3.2 — Mode B: target_host (one-shot)
target MUST be empty in Mode B.
§3.3 — Validation rules
- Exactly one of
{target, target_host}non-empty. Both empty or both set →arg_mode_ambiguous. - Mode A: all other args MUST be empty →
arg_mode_a_extra_args. - Mode B:
target_hostANDssh_keyANDinstall_rootANDplatformall required →missing_required_arg. - Mode B backend identity:
backend_targetXOR (backend_urlANDapi_key). Both groups set →backend_identity_ambiguous. Neither set →backend_identity_missing. - Backend identity precedence: in v0.2 the two backend-identity groups are mutually exclusive. A future v0.x extension may allow both with an explicit precedence flag.
- Resolved kind in Mode A and resolved backend_target in either mode MUST satisfy §2.2.
§4 — Stages
Mirrorsupgrade_lan.ts flow but adapted for editor-host:
- preflight_local — local repo
cli/dist+mcp-node/distexist + are fresh. Fail-fast with actionable error if missing perfeedback_preflight_checks(no auto-build inside the verb — caller invokesnpm run buildfirst; verb is side-effect-narrow). - preflight_remote — see §5 for the OS-detection + shell-policy detail.
- distribution —
mkdir -p $install_root/{cli,mcp-node}(per §5 platform branch);scp cli/dist + cli/package.jsonandmcp-node/dist + mcp-node/package.jsonto remote. - prereqs —
npm install --ignore-scripts --no-audit --no-fundincli/andmcp-node/. - install —
node $install_root/cli/dist/index.js install --mode lan --host <backend_host> --port <backend_port> --api-key <api_key>. - verify — fresh SSH session running JSON-RPC
initializehandshake againstnode $install_root/cli/dist/mcp-launcher.jswith the configured env block; assert version + capabilities; asserttools/call list_projectsreturns clean (real backend round-trip).
§5 — Cross-Platform Policy (Texi v0.1 finding 2)
v0.2 selects approach (a) from the v0.1 sketch: single Windows shell required (cmd.exe), explicit detection at preflight, fail-fast otherwise. PowerShell support is v0.3 work with separate command builders.§5.1 — Platform identification
entry.platform (Mode A) or the platform arg (Mode B) is normative — operator declares the target’s platform explicitly. The verb does NOT auto-detect from uname / ver because:
- The probe itself differs per shell (cmd
vervs PowerShell$PSVersionTablevs POSIXuname -s). - Auto-detection masks misconfigured target entries; explicit declaration surfaces them at registration time.
§5.2 — Shell policy
§5.3 — Command builders per platform
ARemoteCommands interface dispatches per platform:
mcp-node/src/ops/_smoke/remote_commands_{windows,posix}.ts (or similar). The branch is decided once at preflight_remote; subsequent stages call methods on the dispatched instance.
§5.4 — scp destination handling
scp uses host:path syntax. Path semantics differ:
- POSIX target: forward slashes, absolute path:
Lafonda@mini1.home.lan:/home/lafonda/Prism/cli/dist/. - Windows target: forward slashes ALSO work in scp’s path argument (translated by Win OpenSSH). Use forward-slash form for the scp arg even when
install_rootin registry is backslash form. Path normalization:install_root.replace(/\\/g, "/")for scp args.
shq (operator side, POSIX) wraps the destination string. The remote-side path interpretation is by Win OpenSSH, NOT cmd.exe — no double-quoting needed.
§6 — Open Questions (v0.2)
- PowerShell support timeline. v0.3 candidate. Question: detect at preflight and select builder, or require operator to declare shell in target entry? Lean toward declaration for the same reason as platform — explicit > magic.
prism_configure_editor_hostcompanion verb. Out of scope here but blocks fully programmatic registration of editor_host entries. File as separate small SPEC after this one ratifies.- Daemon binary distribution. SPEC-072 daemon source is not part of cli/dist. v0.2 install path leaves
daemon/absent on editor host (CLI already handles it gracefully per cycle 3 output). Future v0.x SPEC for daemon-included editor-host installs.
§7 — Validation Plan
- Greenfield mini1 cycle: tear down
C:\Users\lafonda\Prism\{cli,mcp-node}, thenprism_install_editor_host(target=mini1)from operator → all stages green, MCP initialize handshake clean against mini4. - Idempotency: re-run immediately → distribution refreshes dist, install reports “already wired”, verify still green.
- Failure surface: register a target with bad ssh key → preflight_remote fails fast with remediation hint; no partial state on remote.
- Kind mismatch: call
prism_install_editor_host(target=mini4)(mini4 is backend_lan) →kind_mismatch{got: backend_lan, expected: editor_host}. - PowerShell rejection: deliberately reconfigure mini1 OpenSSH to PowerShell →
windows_powershell_unsupported_v0_2. - Mode-validation: call with both
targetandtarget_host→arg_mode_ambiguous. Call withbackend_targetandbackend_url→backend_identity_ambiguous.
§8 — Implementation Notes
- New file:
mcp-node/src/ops/install_editor_host.ts(mirrorsupgrade_lan.tsshape). - New files:
mcp-node/src/ops/_smoke/remote_commands_{windows,posix}.tsfor the §5.3 command builders. - Verb wiring:
mcp-node/src/verbs/tier1c.tsaddsregisterVerb({ name: "prism_install_editor_host", ... }). - Re-uses POSIX
shq()(from PR #157) for operator-shell quoting. Adds a Windowswinq()helper alongside. - Re-uses log-file helper (
newLogFile/logLine) — refactor into a shared util as a third consumer arrives. - Targets registry resolver gains
expected_kindarg; existing callers updated to pass"backend_lan"explicitly.
§9 — Related
- Implements: the install-lane verb taxonomy gap surfaced in P2 mini1 rehearsal 2026-05-04.
- Depends on: SPEC-055 (target registry) + PR #157 (
stageBootstrapApiKeyfor credentials chain) + PR #159 (CLI consumer-install no-src guard). - Extends: SPEC-054 (Node MCP shim distribution model — explicit consumer install path).
- Out-of-scope follow-up: distribution mechanism (npm publish vs scp vs single-binary) — separate SPEC TBD.
§10 — Review history
- v0.1 → Texi review (PR #160 commit dda33a6): 3 findings — discriminated-union resolver rules (blocking), Win/POSIX shell-policy inconsistency (blocking), verb-arg-contract precedence (medium).
- v0.2 → applied: §2.1 schema + §2.2 resolver rules + §2.3 kind/verb matrix + §2.4 migration; §5 single-shell Windows policy with explicit
platformdeclaration + §5.3 RemoteCommands dispatch + §5.4 scp path normalization; §3 mutually-exclusive Mode A vs Mode B with normative validation rules.

