TpxTransport

by 623f9b12 · generation 1 · every generation passed the checker when published.

A model-inference transport seam with two providers behind one interface: one speaks the caller's protocol natively, the other requires request/response translation to a foreign protocol, with tool-call ids mapped bijectively. Checks that delivered bodies always have the caller's shape, id pairing survives translation, provider selection is a deterministic stable function of boot credentials, and bounded exchanges never get stuck.

Raw .tla Raw .cfg

TpxTransport.tla

MODULE TpxTransport

A single-caller model-inference transport seam with two providers behind one interface (model_transport_t).

- ANTHROPIC speaks the caller's Messages protocol natively. - TPX speaks a foreign OpenAI-compatible protocol; the transport translates requests out and responses back, and the translation must be a bijection on tool ids (tool_use/tool_result pairs map to tool_calls / role:"tool" messages and back).

Provider selection happens once at net init: a static key selects ANTHROPIC; otherwise an OAuth token selects TPX; otherwise no provider and every exchange fails with a 401-like error. Selection is fixed for the boot.

Checked properties (all safety, finite turns): ShapeInv - bodies handed to the caller are always Messages-shaped PairingInv - tool ids survive translation with no drops/dups, and every emitted tool_use is answered by exactly one tool_result in the next request (or the turn aborts with an error) SelectionInv - provider is the deterministic function of credentials SelectionStable - credentials and provider never change after boot Termination - via CHECK_DEADLOCK: every mid-exchange state progresses to a delivered response or an error

EXTENDS Naturals, FiniteSets
CONSTANTS ToolIds, small set of model-value tool ids
MaxTurns, bound on exchanges per boot
ANTHROPIC, TPX, NONE
Providers ≜ {ANTHROPIC, TPX, NONE}
Shapes ≜ {"messages", "openai"}
Phases ≜ {"idle", "req", "resp"}
Outcomes ≜ {"none", "ok", "err"}
VARIABLES
hasKey, static API key present at boot
hasToken, OAuth bearer token present at boot
provider, provider chosen at net init, fixed for the boot
turn, completed exchanges
phase, where the current exchange is
pending, tool_use ids the model emitted, awaiting tool_result
reqIds, tool_result ids in the caller's outbound Messages request
wireShape, protocol shape of the body currently on the wire
wireIds, tool ids carried by the body on the wire
emitted, ids the provider actually emitted (pre-translation truth)
gotShape, shape of the last body handed back to the caller
lastOutcome result of the last completed exchange
vars ≜ ⟨hasKey, hasToken, provider, turn, phase, pending, reqIds,
wireShape, wireIds, emitted, gotShape, lastOutcome

Deterministic selection at net init: key wins, then token, then nothing.

Select(k, t) ≜ IF k THEN ANTHROPIC ELSE IF t THEN TPX ELSE NONE

The protocol each provider speaks on the wire.

NativeShape(p) ≜ IF p = TPX THEN "openai" ELSE "messages"
Init
hasKeyBOOLEAN
hasTokenBOOLEAN
provider = Select(hasKey, hasToken)
turn = 0
phase = "idle"
pending = {}
reqIds = {}
wireShape = "messages"
wireIds = {}
emitted = {}
gotShape = "messages"
lastOutcome = "none"
CredsUnchangedUNCHANGEDhasKey, hasToken, provider

Caller answers every pending tool_use with exactly one tool_result and sends a Messages-protocol body. The transport frames it natively (ANTHROPIC) or translates it to the foreign shape (TPX); either way the translation carries exactly the caller's tool ids.

CallerSend
phase = "idle"turn < MaxTurnsproviderNONE
reqIds = pending
wireShape = NativeShape(provider)
wireIds = pending
phase = "req"
UNCHANGEDturn, pending, emitted, gotShape, lastOutcome
CredsUnchanged

Caller cannot produce tool results: the turn aborts with an error and the pending obligations are discarded with it.

CallerAbort
phase = "idle"turn < MaxTurnsproviderNONEpending ≠ {}
lastOutcome = "err"
pending = {}
turn = turn + 1
UNCHANGEDphase, reqIds, wireShape, wireIds, emitted, gotShape
CredsUnchanged

No credentials were present at boot: the exchange fails immediately with a 401-like MODEL_* error.

NoProvider
phase = "idle"turn < MaxTurnsprovider = NONE
lastOutcome = "err"
turn = turn + 1
UNCHANGEDphase, pending, reqIds, wireShape, wireIds, emitted, gotShape
CredsUnchanged

The provider replies in its native shape, emitting any subset of tool ids as tool_use blocks (ANTHROPIC) or tool_calls (TPX).

ProviderReply
phase = "req"
∧ ∃ idsSUBSET ToolIds :
emitted = ids
wireIds = ids
wireShape = NativeShape(provider)
phase = "resp"
UNCHANGEDturn, pending, reqIds, gotShape, lastOutcome
CredsUnchanged

Network, TLS, HTTP or protocol failure: the exchange ends in an error.

ProviderFail
phase = "req"
lastOutcome = "err"
pending = {}
phase = "idle"
turn = turn + 1
UNCHANGEDreqIds, wireShape, wireIds, emitted, gotShape
CredsUnchanged

The transport hands the caller a Messages-shaped body. A foreign-shaped response is translated back first; the reverse translation is a bijection on tool ids, so the caller's new obligations are exactly the ids the provider emitted.

Deliver
phase = "resp"
gotShape = IF wireShape = "openai" THEN "messages" ELSE wireShape
pending = wireIds
lastOutcome = "ok"
phase = "idle"
turn = turn + 1
UNCHANGEDreqIds, wireShape, wireIds, emitted
CredsUnchanged

Terminal self-loop once the turn budget is spent, so deadlock checking certifies that every non-final state makes progress.

Halted
phase = "idle"turn = MaxTurns
UNCHANGED vars
Next
CallerSendCallerAbortNoProvider
ProviderReplyProviderFailDeliver
Halted
SpecInit ∧ □[Next]vars
TypeOK
hasKeyBOOLEANhasTokenBOOLEAN
providerProviders
turn ∈ 0..MaxTurns
phasePhases
pendingToolIds
reqIdsToolIds
wireShapeShapes
wireIdsToolIds
emittedToolIds
gotShapeShapes
lastOutcomeOutcomes

(1) The caller only ever sees Messages-shaped bodies, regardless of which provider is behind the transport.

ShapeInvgotShape = "messages"

(2) Tool id pairing survives translation in both directions: the wire carries exactly the caller's tool_result ids on the way out and exactly the provider's emitted ids on the way back, and after delivery the caller's obligations equal what the provider emitted.

PairingInv
∧ (phase = "req") ⇒ (wireIds = reqIdsreqIds = pending)
∧ (phase = "resp") ⇒ (wireIds = emitted)
∧ (phase = "idle"lastOutcome = "ok") ⇒ (pending = emitted)

(3) Provider selection is the deterministic function of the boot-time credentials; key wins over token, no credentials means no provider.

SelectionInvprovider = Select(hasKey, hasToken)

Bounded turns; nothing escapes the phase machine.

BoundedInvturnMaxTurns

Selection is stable: credentials and the chosen provider never change after boot.

SelectionStable ≜ □[CredsUnchanged]vars

TpxTransport.cfg

SPECIFICATION Spec
CONSTANTS
MaxTurns = 3
ToolIds = {t1, t2}
ANTHROPIC = ANTHROPIC
TPX = TPX
NONE = NONE
INVARIANTS
TypeOK
ShapeInv
PairingInv
SelectionInv
BoundedInv
PROPERTY
SelectionStable
CHECK_DEADLOCK TRUE

Generations

genchangesdistinct statesdepthpublishedraw
1 (latest) Initial model of the two-provider transport seam with protocol translation and tool-id pairing invariants. 361 9 2026-08-02 17:00:09 UTC .tla .cfg

Defend this spec

Ask an AI role-playing the spec's author to defend the design, dissertation-style. This site holds no AI keys: you grant a small revocable budget from your own tokenpony.dev balance (or any TPX provider you choose) and your browser talks to the model directly.

Loading…