Skip to content

Support cloud agents & sandboxes (transport, not authority) #18

Description

@bigboateng

Context

Pitot launches Controllers as local subprocesses and mediates events over JSON-Lines stdio (control.requestedcontrol.response), with deadlines and fail-closed on_timeout: deny / on_unavailable: deny defaults. This works well on a developer laptop. As Interlock/Pitot get used from cloud coding agents (Claude Code remote, Cursor cloud, Devin-style, Codespaces) and ephemeral sandboxes, we need to confirm the transport still reaches a controller — and fails closed when it can't.

Scope: transport & ergonomics only. The enforcement authority stays the broker (hash-bound evidence + effect) and the CI merge gate. This issue must not move the guarantee into the transport.

Problem

In remote/sandboxed environments, the assumptions Pitot relies on locally may not hold:

  • the controller binary may be absent (ephemeral, fresh clone)
  • egress may be blocked (a remote controller becomes unreachable → denies all)
  • the agent may not run an interactive shell / the shell-hook path may not fire
  • runtime state (rt.json) is per-session and must be re-initialized

Scenario matrix (what we need to verify)

Environment Controller present? Hooks fire? Notes
Local laptop yes shell + git hooks works today
Local agent (Claude Code / Cursor) yes yes — incl. Claude Code PreToolUse hooks needs a thin host adapter
Remote/cloud agent (sandbox) needs hydration maybe the gap this issue targets
CI yes n/a the authority (merge gate)

Proposed approaches (to evaluate)

  1. Local sidecar controller (recommended default). Hydrate + run the controller inside the sandbox; keep stdio IPC local so no egress is required and on_unavailable: deny stays meaningful. Claude Code's hooks execute shell in the sandbox, so if the controller is hydrated and hooks are wired, enforcement fires locally — even remotely.
  2. Host-hook adapters. Thin per-host shims mapping the agent's native hook system to control.requested emission (Claude Code PreToolUse/PostToolUse, git hooks via core.hooksPath, devcontainer postCreate bootstrap). Idempotent on a fresh clone.
  3. Optional network transport. A gRPC/HTTP variant of the Controller contract for a centralized policy service, with auth + latency budget + fail-closed on unreachable. Only where a local controller isn't viable.

Bias toward explicit control.requested (structured EffectRequest) over shell-hook inference — consistent with Interlock refusing to infer effects from command strings.

Non-goals

  • Changing the enforcement authority (broker + CI gate remain authoritative).
  • Inferring file effects from shell command strings.
  • Requiring network egress for the common path.

Open questions

  • Bootstrap/hydration story for ephemeral sandboxes (who runs it, when)?
  • Per-host adapters vs one common interception point?
  • How do we test each host in CI (matrix of agent environments)?

Acceptance criteria

  • A documented, tested path for at least one cloud-agent host (Claude Code sandbox) where a control.requested reaches a hydrated local controller.
  • Verified fail-closed behavior when the controller is unreachable.
  • No change to the broker/CI enforcement authority.

References

  • integrations/pitot Controller contract (interlock-pitot)
  • Interlock broker (authority): labs/21-interlock/interlock/broker

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions