jackin-remote design research (run on another machine, attend from laptop)
Designs remote agent execution that preserves the local console experience, isolation model, and explicit transport boundaries.
Summary
Remote execution should keep the console local while an authenticated transport and remote daemon own workload lifecycle, isolation, and failure recovery.
Research question
Some agent workloads do not fit on the operator's laptop. A long parallel queue, a CPU-heavy build pipeline, or a memory-hungry indexing job benefits from running on a beefy host while the operator continues to use their laptop normally.
The current design has no first-class remote-host orchestration path. Operators can run jackin❯ over SSH or point Docker at a remote daemon, but those paths do not preserve the local console UX, explicit state ownership, credential posture, or local handler affordances that a first-class remote mode needs.
multicode addresses this with multicode-remote: a helper binary that runs the multicode TUI on the local laptop while agents run on a remote machine, with bidirectional rsync of workspace state and SSH-relayed handler invocations.
Inspiration in multicode
Sources:
- README — multicode-remote
- Source —
remote/src/main.rs(themulticode-remotebinary entry point) - Source —
remote/src/orchestration.rs(SSE relay, file sync, symlink dereferencing) - Source —
lib/src/remote_action.rs(handler-relay protocol —RemoteActionRequest) - Config —
config.toml[remote]block (sync intervals, sync-up/sync-bidi mounts, install command)
The useful kernel for jackin❯: SSH control, explicit sync direction, local action relay, and remote bootstrap should be evaluated before inventing a custom network protocol.
Recommended shape
Use SSH + rsync for the initial remote-host contract, designed so future Kubernetes support can reuse the same attach, status, credential, and handler vocabulary. A typed RPC/gRPC client may be cleaner later, but ordinary SSH-accessible machines define the current design boundary.
jackin-remote (local laptop)
└── ssh ──> jackin (remote host)
├── runs agents through the selected remote backend
└── exposes a small control channel for status events, handler invocation requests, and launch/session lifecycleConfig sketch
Remote config should be an explicit remote-host surface, not a silent overload of existing backend config. The unresolved schema needs named remotes with SSH target, remote jackin path, sync interval, sync rules, and optional install/bootstrap command.
[remote.dev-server]
ssh = "user@dev-server.local"
remote_jackin_path = "/usr/local/bin/jackin"
sync_interval_seconds = 2
[[remote.dev-server.sync_up]]
local = "~/.config/jackin"
remote = "~/.config/jackin"
[[remote.dev-server.sync_bidi]]
local = "~/dev/projects"
remote = "~/dev/projects"
exclude = ["target/", "node_modules/", ".jackin/"]
[remote.dev-server.install]
command = "curl -fsSL https://jackin.tailrocks.com/install.sh | bash"CLI sketch
The jackin --remote <name> ... interface must reconcile with backend selection and console launch flows. Its operator vocabulary needs three verbs: attach the local console to a remote host, launch a role on a remote host, and sync without launching.
jackin --remote dev-server console
jackin --remote dev-server load the-architect
jackin --remote dev-server syncHandler relay
When the operator clicks a link in the local console, the action should fire on the local host — browser, IDE, diff viewer — not on the remote machine. The contract needs a structured remote action event such as RemoteAction { kind: web|ide|diff, argument: url|path } over the SSH control channel, decoded locally by jackin-remote and dispatched through the same local handler paths used by the console. This depends on Operator handler system existing as the local dispatch target.
Credentials
Current auth forwarding (sync, api_key, oauth_token, ignore, plus sync_source_dir) is a local-backend baseline, not enough for remote hosts. Remote execution should resolve credentials locally, pass only invocation-scoped grants/material to the remote side, and avoid broad rsync rules that copy credential directories or long-lived tokens into a shared host. The credential source pattern remains the right owner for that deeper grant model.
Sync contract
Every synced path needs an explicit direction and owner. sync_up means the local host is authoritative, sync_bidi means conflict behavior is part of the contract, and remote-only jackin❯ runtime state stays remote unless the operator requests a recovery copy. Credentials are never included in broad sync rules; they use the credential grant path instead.
Limitations and open questions
- State ownership. Which remote runtime state, if any, mirrors back to the laptop? Recommendation: remote runtime state remains authoritative on the remote host; local copies are recovery/export artifacts only.
- Status transport. Should the SSH control channel carry SSE-style lines, framed JSON, or reuse a future jackin❯ protocol stream?
- Remote plus backend selection. How does
--remote dev-servercompose with[runtime].default_backend, workspace[runtime].backend, and future--backend? Recommendation: remote chooses the host; backend selection still resolves on that host and must be reported explicitly. - Trust model. A compromised remote can read synced workspaces and any credentials granted to that invocation. Remote-host isolation is not a feature; document the trust boundary plainly.
- Handler protocol owner. The local console has browser-opening and link affordances, but no general operator handler system. Decide whether this item owns the first typed handler protocol or depends on Operator handler system.
Related work
- jackin-remote — the roadmap item this dossier backs.
- Agent Orchestration Program
- Operator handler system
- Credential source pattern
- Session contract and explain mode