Why it is shaped this way
A format is per emitter
Status: accepted, 2026-10-07; amended 2026-10-08, the number before a first release. Serves The compiler decides. Built as decided: nothing moves. Reopen if the plan IR is ever written out and read as data by something other than the compiler.
Status: accepted, 2026-10-07; amended 2026-10-08, the number before a first release. Serves The compiler decides. Built as decided: nothing moves. Reopen if the plan IR is ever written out and read as data by something other than the compiler.
Context#
What generated Swift names in the Swift runtime is fenced by one number.
compiler/src/emit.rs declares pub const FORMAT: u32 = 16; generated
code writes static let format = Baton.Format16.self in its Types enum;
swift/Sources/Baton/Plan.swift declares Format16 and keeps every earlier
marker unavailable, with a message. CLAUDE.md states the rule: a change
to what generated code names raises the number on both sides in one commit.
Nothing says what the number means for a second runtime.
Decision#
-
A format is per emitter. The Kotlin emitter gets its own number and its own fence, enforced the way its language allows.
-
The plan IR between the emitters is not serialized and carries no number.
-
The two emitters change together when the plan's shape changes, and apart when one language's interface does.
-
A format's number is raised from the emitter's first release on. Before it, nothing generated by a released compiler can meet the runtime, so generated code and runtime move together under the first number: the Kotlin format stays 1 while the Kotlin runtime is built, and goes to 2 with the first change after the Kotlin runtime is first released.
Evidence#
- The compiler and the runtime as built, by reading:
FORMATincompiler/src/emit.rs; the line that writes the marker incompiler/src/emit/shared.rs, and the same line in the goldencompiler/src/tests/goldens/Baton.baton.swift; the markers inswift/Sources/Baton/Plan.swift, from format 1 to the availableFormat16. - What the fence guards is one language's interface: the messages on the unavailable markers name changes to Swift's generated code, such as a schema enum reading as the Swift enum generated for it.
Not chosen#
- One number shared by both emitters: a Swift-only interface change would raise Kotlin's number for nothing, and the reverse.
- A versioned IR: nothing reads it as data.
Baton