A declaration such as int color; gives an editor and a compiler different work to do. The editor needs to find the declaration and show its type. The compiler needs to know how values of that type behave. Both depend on what the source language means by that declaration.

An editor can reconstruct those facts from its own parser and type model. That works until the language changes and someone has to update both implementations. Adding another tool creates another place where the same rule can be understood differently. This is the repeated integration work described in the Background essay.

The language provider can instead expose the declaration and answer questions about it. The editor uses the source and type information it understands; the compiler asks for the facts needed to generate code. Each tool still does its own work, but the language's meaning has an owner they can both ask.

That leaves a practical problem: how does an independently built tool ask those questions? Giving it a pointer to the parser's private C++ object would make it depend on that parser's classes and lifetime. The first interface has to be usable before either side knows the other's implementation.

We can examine that interface problem with the smaller example in the Godot lab. A consumer requests convolution from a native, script or GPU provider. The operation has specified behavior, including kernel centering and edge handling, while each provider chooses its algorithm and storage. The caller needs to identify that operation, establish how to call it and keep the result alive. These are also obligations a language service has when it exposes a query to another tool.

Agreeing on an interface

Two libraries can both export convolve and still disagree on the arguments, boundary conditions or ownership of the result. TTX uses a UUID to identify the intended contract, so the consumer can ask for that particular meaning without relying on a coincidental spelling.

That still leaves the physical call. A function that receives an image pointer isn't interchangeable with one that receives an opaque receiver followed by an image pointer. Even if their API tables occupy the same number of bytes, calling through the wrong description can fail before the operation gets a chance to do anything useful.

The participants therefore also agree on the concrete representation of the API. It describes the fields and callable signatures the consumer expects to receive. Binding checks that agreement before supplying the record in the consumer's storage. A provider can recognize the UUID and still reject the requested API when the representations differ.

Sometimes we only need the first answer. A policy may want to know whether an object accepts a contract without using any of its operations. That's what supports asks. Keeping it separate from bind means we don't need to construct an interface merely to ask a question about its meaning.

Keeping the implementation available

Once we have the API record, its receiver still belongs to somebody. A script runtime might keep that state alive, a native module might own it, or the receiver might forward the work to another system. Copying a pointer into our own storage doesn't transfer any of those obligations.

The supplying contract must tell us how long the interface is usable and what keeps its state and code available. Within that lifetime, the consumer calls the agreed operations and lets the provider interpret its own receiver. There is no need for the consumer to recover a private C++ class to make the call work.

The Query contract supplies the support and binding operations. A usable interface still doesn't promise that every question has a settled answer: an editor may ask about a declaration whose type depends on unfinished source. The next chapter follows that distinction between an answer that is absent, unsettled or refused.