Skip to main content

Crate nomoreide_remote_protocol

Crate nomoreide_remote_protocol 

Source
Expand description

The frozen v1 wire protocol between a local NoMoreIDE daemon and the hosted remote-control relay.

Nothing here talks to a socket, a service or an agent. It is the shape of what may be said and the rules for refusing everything else.

Why this is its own package. Two independently deployed programs speak this protocol — the daemon on a developer’s machine and the platform’s API container, which live in different repositories and different Cargo workspaces. Writing it twice would make it two implementations of one meaning, which is the mistake the desktop app already made and is still paying 150 duplicated commands for. So it is one implementation, in a package light enough for both: serde, serde_json, chrono, and nothing else. The daemon reaches it through nomoreide_core::remote::protocol.

The daemon always dials out over TLS. Nothing in this protocol opens a port, asks for a port forward, or accepts an inbound connection — a machine running NoMoreIDE is not reachable from the internet because of this feature, and that is the property the whole design is arranged around.

Where to look:

  • envelope — the invariant frame, and the order a frame is checked in.
  • device_bound — every command the platform may send. This union is the remote attack surface.
  • platform_bound — every event a daemon may send.
  • snapshot and agent_event — the sanitized shapes those carry.
  • limits — every number either side is allowed to assume.
  • errors — the refusal codes, and which of them may ever be retried.
  • version — negotiation, capabilities, and what a phone does against a machine that has not been updated.
  • idempotency — why a mutation is never automatically re-sent.
  • fixtures — one sample of every frame, and the golden files an independent implementation checks itself against.

Three properties hold across all of it, and each has a test that fails if it stops holding:

  1. Unknown is refused, not ignored. A type outside the union is errors::ErrorCode::UnknownCommand in either direction, whatever its payload looks like.
  2. No frame can carry what the allowlist excludes. There is no variant for a shell command, a path, an environment, a terminal, a database query, a git mutation or a process id — so no payload can smuggle one.
  3. Ambiguity never retries. A mutation whose outcome is unknown is a question for a human, not a frame to send again.

The contract in prose, including the threat model, is docs/remote-protocol-v1.md in the repository.

Re-exports§

pub use device_bound::DeviceBound;
pub use envelope::Envelope;
pub use errors::ErrorCode;
pub use errors::ProtocolError;
pub use platform_bound::PlatformBound;
pub use terminal_bytes::TerminalBytes;
pub use version::Capability;
pub use version::CapabilitySet;
pub use version::SessionMode;
pub use version::PROTOCOL_VERSION;

Modules§

agent_event
What one agent turn emits, in order.
device_bound
Everything the platform may send to a daemon — the frozen v1 command union.
envelope
The frame every relay message travels in, and the order it is checked in.
errors
The frozen error codes, and the one thing a caller is allowed to conclude from each: whether retrying is safe.
fixtures
One sample of every frame the protocol defines, and the golden files generated from them.
idempotency
What happens when the same request id arrives twice.
limits
The frozen limits. Every number a v1 peer is allowed to assume about the other side lives here, and nowhere else.
linear
Linear operations shared by local and remote clients. Credentials never enter this protocol.
platform_bound
Everything a daemon may send to the platform — the frozen v1 event union.
snapshot
The sanitized shapes a daemon is allowed to describe itself with.
terminal_bytes
Raw PTY bytes on a JSON wire.
version
Version negotiation, capabilities, and what a phone does when the machine at the other end is out of date.