Skip to content

Sidecar (Compiler, Not LLM)

The sidecar is AgentCTX’s trust boundary between agents and humans. It translates CTX statements into human-readable formats — and signs every translation with Ed25519. There is no LLM in the translation path. It’s a compiler, not a model.

LLMs can hallucinate translations. A model might tell you an agent did one thing when it actually did another. The sidecar eliminates this risk:

PropertyLLM TranslationSidecar Translation
Deterministic❌ Different runs, different output✅ Same input, same output, always
Verifiable❌ No way to prove correctness✅ Ed25519 signature
Auditable❌ Black boxactx verify validates any translation
Fast❌ ~500ms per call✅ <1ms per translation
Cost❌ API call each time✅ Zero — runs locally
Agent writes: +m "decision" #arch "JWT for API, session tokens for WebSocket"
Sidecar emits: "Stored architecture decision: JWT for API, session tokens for WebSocket"
Crypto signs: Ed25519(ctx_raw + human_output) → signature + digest
Written to: .context/translations/{digest}.ctx
.context/translations/{digest}.md
.context/translations/{digest}.json

The signAndWrite method produces three files per translation:

  • .ctx — the raw CTX statement
  • .md — human-readable markdown with signature
  • .json — structured translation with all metadata

The sidecar supports multiple emitter backends via an EmitterRegistry. The surrealql target includes sub-emitters for memory, knowledge, graph, and document operations (19 source files total):

TargetOutputUse Case
humanEnglish proseHuman audit trails
surrealqlSurrealQL queriesDirect database operations
sqlStandard SQLRelational database integration
restHTTP requestsREST API generation
graphqlGraphQL queriesGraphQL endpoint integration
mcp-jsonrpcJSON-RPCMCP protocol messages

Each emitter implements the Emitter interface: { id: string; emit(ast: CTXStatement): string; emitBatch?(asts: CTXStatement[]): string }. No state, no side effects, no LLM.

For production performance, the sidecar can route through a Rust native addon:

TypeScript Sidecar Rust Native Sidecar
↓ ↓
EmitterRegistry.emit() napi-rs → ctx-sidecar crate
↓ ↓
~1ms per translation ~0.01ms per translation

Enable with: USE_RUST_SIDECAR=true (must be explicitly set — defaults to TypeScript emitters)

The Rust implementation (crates/ctx-sidecar/) provides identical output through napi-rs bindings. It falls back to TypeScript emitters if the native addon isn’t available.

Terminal window
actx verify

This command:

  1. Reads every .json file in .context/translations/
  2. Re-computes the Ed25519 signature
  3. Compares against the stored signature
  4. Reports any mismatches (tampering detected)

If every signature matches, you have cryptographic proof that the human-readable translation accurately represents what the agent did.

The EmitterRegistry supports custom translation targets:

import { Sidecar, EmitterRegistry } from '@agentctx/core';
const registry = new EmitterRegistry();
registry.register('yaml', {
emit(ast) {
return `operator: ${ast.operator}\nplane: ${ast.plane}\ntarget: ${ast.target}`;
}
});
const sidecar = new Sidecar(registry);
const result = sidecar.translate(ast, 'yaml');

The sidecar also supports version control projection — translating CTX operations into git-compatible formats for integration with existing workflows.