LISAOS // DOCS
DECISIONS // RAW TWIN DISCIPLINE

ADR-0003 — Raw-twin write path for gateway write tools

Every gateway write tool exposes a single-string payload twin, so schema evolution never silently drops fields.

Status: Accepted

Context

The shells reach the memory gateway through tools whose input schemas are advertised at connection time. Some clients cache that schema at session start. When a write tool's schema later gains a field, a client running against the cached schema silently strips the new field before sending — the call succeeds, but the data is quietly incomplete. For a write to memory, a dispatch record, or context feedback, silent partial success is the worst possible failure: it looks fine and corrupts the record.

This was not hypothetical. A real incident saw a structured field coerced and rejected — and a related class saw array and boolean fields mangled by a stale client serialiser — precisely because the rich, evolving schema was exposed directly to a client that had cached an older shape.

Decision

Give every write-path gateway tool a raw twin: a second tool with a permanently stable, one-field schema — a single JSON-serialised payload string. The rich validation moves server-side: the twin forwards the whole payload untouched, and the gateway validates it against the real schema. Because the twin's schema is one string forever, there is nothing for a client to cache incorrectly and nothing to strip. All new work uses the raw twins; the rich tools remain only for backwards compatibility.

A binding rule accompanies the pattern: the twin's handler must forward the entire incoming payload to the gateway. Per-field stripping in the tool layer is the exact bug the pattern exists to kill, and is forbidden.

Consequences

  • Positive: Schema evolution is now a purely server-side concern. Fields can be added to a write contract without any risk that a client with a stale cache silently drops them.
  • Positive: Validation has a single home — the gateway's schemas — rather than being duplicated and drifting across clients.
  • Negative / accepted: Callers hand-serialise a JSON payload string, which is slightly less ergonomic than a fielded tool call and moves the "did I get the shape right?" check from connect-time to call-time. This is accepted because a legible server-side validation error is vastly preferable to a silent partial write.
  • Governance: The discipline is documented and must be read before any write-path tool is added or changed.

See raw-twin discipline and the memory gateway.

On this page