ResearchSecurityIsolation Architecture

Session Contract and Explain Mode: Design

Status: Open — design proposal, not yet implemented

This is the design record for the resolved launch contract and explain preview surface tracked at Session contract and explain mode. It captures the problem framing, competitive inspiration, and the full contract shape so the roadmap item itself can stay a lean status/remaining-work tracker.

Problem

jackin load resolves a lot of behavior before an agent starts: role image, workspace mounts, isolated worktrees, credential forwarding, Docker/DinD wiring, agent runtime, persisted state, and cleanup policy. Today the operator can inspect pieces of that model, but there is no single command that answers what exactly the agent will be able to read and write, which credentials will be present and in what form, which Docker daemon it will talk to, which host-side effects happen before the agent receives control, and which recovery path applies if the session exits dirty or destructive. That gap matters most for the engineers jackin targets: people who run agents from terminals on local machines, over SSH, on servers, and eventually inside Kubernetes workflows. They need a fast way to audit the boundary without launching the agent or mutating the host.

Inspiration

Hazmat and Docker Sandboxes are the two products that treat the launch boundary as a first-class product surface; the full competitive read (what each gets right, where jackin should differ, and the containment/recovery comparison table) lives in Agent Orchestration Program research. The short version for this design: Hazmat treats the session contract as the product surface (mode, project access, integrations, read-only paths, service access, snapshot state) and previews it with hazmat explain before launch; Docker Sandboxes documents the trust boundary in terms of what crosses into the VM (workspace files, proxied network requests, credential injection). jackin already has the raw inputs to build an equivalent — the missing piece is a resolved contract object that makes those inputs inspectable before side effects.

Proposal

Add a launch contract that can be printed in two modes:

jackin explain agent-smith my-workspace
jackin load agent-smith my-workspace --explain
jackin explain agent-smith my-workspace --json

The human contract should be compact enough to read in a terminal and complete enough to use as an audit artifact.

Contract sections

SectionContents
Identityworkspace, role, agent runtime, instance name, role source, image tag/digest when known
Routing / tier decisionselected backend, configured alternatives, recommendation reason, and why stronger or weaker tiers were not selected
Sandboxbackend (dind, microvm, future remote/Kubernetes), Docker daemon shape, privileged sidecar status, TLS/rootless status
Filesystemread-write mounts, read-only mounts, isolated worktree/clone mounts, generated override files, workdir, sensitive path warnings
Credentialsper-runtime auth mode, GitHub CLI mode, 1Password references, env/file/bridge delivery, granted/denied/unavailable credentials, known exposure warnings
Integrationsactive stack integrations, recommendation source, approval state, and any diff from the previously approved recommendation hash
Networkcurrent network mode, egress policy if configured, enforcement quality, connection logging posture, host localhost exposure caveats
Service portsrequested and active host-to-container mappings, sandbox-to-host aliases, protocol, persistence, and host-side effects
Runtime homesprovider home directories and state roots for Claude, Codex, GitHub CLI, plugins, and skills, including whether each path is persisted
Host-side effectsimage build, container creation, DinD sidecar creation, worktree/config writes, generated files, port publications, auth sync, state directory writes, firewall/proxy helper setup, future snapshots
Recoverycleanup policy, preserved worktree path, snapshot availability, hardline/purge recovery path

The --json shape should be stable enough for docs, tests, CI checks, and future jackin daemon consumers. The JSON schema should be versioned and stable: additive fields are allowed, but existing field names and enum values must not change without a schema-version bump. It should not expose secret values.

Phases

Phase 1 — Static launch preview

  • Factor the existing workspace/role/agent resolution into a side-effect-free contract builder.
  • Print filesystem, runtime, auth mode, and Docker/DinD sections.
  • Print planned host mutations even in explain mode, including worktree/config writes, generated files, port publications, auth sync, image builds, state-directory creation, and firewall/proxy helper setup. The command reports them as planned effects and performs none of them.
  • Include a routing explanation such as: selected dind because no microVM backend is configured; network policy is guest-enforced only.
  • Add jackin explain <role> <workspace> and jackin load --explain.
  • Include a JSON form that redacts values but preserves delivery type.

Phase 2 — Host-side effects and recovery

  • Add worktree creation, generated mount overrides, data directory writes, and cleanup/finalization policy to the contract.
  • Surface the same summary at the start of load, hardline, and future console launch flows.
  • Make non-interactive output copy-pasteable for bug reports.

Phase 3 — Backend-specific risk text

  • Add explicit risk language for dind, rootless DinD, microVM backends, SSH/remote hosts, and Kubernetes once those backends exist.
  • Include network and credential-proxy posture from the selected backend.
  • Keep Docker Sandboxes parity claims out of the output unless network and credential proxy gaps are actually closed.

Host-side effects invariant

The explain command must not mutate host state. It may read config, role metadata, cached role manifests, and workspace state. If a future contract needs to compute a value that would normally require mutation, print it as a planned effect rather than executing it. jackin load --explain should also remain side-effect-free and exit after printing; a later --confirm or normal load invocation performs the launch.

Existing partial building blocks

Two backend-specific text renderers already exist and inform this design (see Session contract and explain mode for their exact status): crates/jackin-runtime/src/runtime/docker_profile.rs format_session_contract (Docker profile, network, resources, credentials, residual risk, gated behind --debug) and crates/jackin-runtime/src/runtime/apple_container.rs print_session_contract (Apple Container isolation, mounts, network, residual risk, printed unconditionally at attach). Neither is backend-neutral, neither has a JSON form, and neither is reachable through a stand-alone explain command — the resolved contract object this design proposes would unify and supersede both.

Source materials

On this page