The foundation of Tetrodotoxin

How TTX connects independent systems

Two systems can agree on what they want to do and still disagree on almost everything about how to do it. One may keep an image in device memory, another may calculate its pixels when asked, and a third may already have an ordinary byte array. TTX separates the agreements they need to share from the implementation choices they can keep.

The same problem appears when exchanging interfaces. Knowing that a provider offers an operation is only part of establishing how to call it and how long the resulting interface can be used.

Separating the questions we need to answer

Data describes the concrete form at a boundary. A Schema contains the primitives, geometry, repetitions, pointers and callable signatures an owner wants to publish. Compilation turns that description into a canonical Representation, while Storage supplies the bytes and the access protocols describe how another participant can obtain them.

Semantic adds the agreement about what an interface means. A UUID identifies the contract. A consumer can ask whether the provider supports that contract, or request an API record with the concrete representation it expects. Flow negotiates an access protocol both participants can fulfill.

Concept lets the resulting interfaces expose richer questions and policies through Abstracts. A provider can answer the questions it understands, preserve uncertainty, or restrict a capability without requiring the consumer to adopt its native object model.

These jobs depend on different kinds of information. Keeping them separate means the data engine doesn't need to understand assignment policy, and a conceptual question doesn't need to prescribe where the provider stores its bytes.

Establishing that an interface can be called

Suppose both participants recognize the UUID for an image operation. One expects a function with an opaque receiver and three arguments, while the other supplies a function with a different argument list. Their tables may occupy the same number of bytes, but that doesn't make the call safe.

TTX includes callable signatures in the Data representation, with the calling convention, ordered arguments and result. Generic binding compares the complete prepared API description before transferring the record into caller-owned storage. A mismatch rejects the binding before the consumer invokes it. The initial native realization uses System V AMD64; supporting another ABI requires an accurate description of that call boundary.

supports(UUID) asks a smaller question: whether the provider accepts the semantic contract at all. It can succeed when the particular API a caller understands cannot be bound. Keeping the two operations explicit lets a policy inspect meaning without requesting an operation table it will never use.

A Query supplies the already established bootstrap surface for these requests. The owner makes that first interface available under its lifetime, so negotiation has somewhere concrete to begin.

Accessing data through an established Flow

The fastest useful mechanism depends on what both participants can promise. Flow tries these independent protocols in preference order and retains the agreement it establishes.

ProtocolWhat the agreement provides
DirectThe provider supplies a pointer that remains usable under the publication’s stable lifetime, without an acquisition for each access.
SharedThe provider supplies a compatible pointer under an explicit acquire/release lifetime agreement.
BlockThe provider fills caller-supplied storage in one whole-block operation, without exposing its private backing storage.
FragmentThe consumer requests typed values at ABI coordinates. The provider can generate them individually, and a request may fail after earlier values have been transferred.

A provider offering Direct doesn't implicitly offer Fragment as well. Unsupported or incompatible candidates can allow negotiation to try the next protocol, while Pending or Rejected bindings preserve the encountered provider's answer. Once a protocol has been selected, an operation failure belongs to that agreement.

Copy can then use the Flow to produce a concrete observation in supplied Storage. Swizzle adds an admitted mapping for a different output arrangement. The owners formulating those operations decide what the values mean; the transport engine carries out the concrete agreement.

What canonicalization lets the consumer forget

A producer may describe adjacent bytes as separate fields or as a repeated primitive. When those descriptions express the same admitted format, compilation gives them the same encoded representation. The consumer can compare lengths and bytes rather than reconstruct the original schema objects.

That simplification depends on preserving the distinctions that affect agreement, including structural boundaries, primitive identity, geometry, byte order and callable facts. It doesn't require the provider's private state to use the same layout. The provider can satisfy the published form through whichever access protocol it supplies.

The descriptor establishes format agreement. The UUID establishes the intended meaning, and behavior still has to meet that contract. Convolution tests, lifetime checks and policy refusal remain useful because a matching description cannot prove those properties for us.

Preparing the description has a cost. It is useful when the owner can publish it once and let several consumers or repeated calls reuse the result. Runtime compilation and C++ constant evaluation are two ways to pay that cost. They produce the same agreed form, so a foreign provider can participate without adopting the consumer's implementation language.

The specification beside the representation compiler records the exact format and normalization rules. Flow's implementation shows how the transport agreements are selected, and the Godot lab puts both to use.