Changelog
This file tracks changes to the ethdebug/format specification: the schemas
under schemas/. Those schemas ship inside the @ethdebug/format package,
whose build generates its distributed copies from schemas/, so the spec
version is that package's version and this file is keyed by it. Each published
package that implements the spec (@ethdebug/pointers, @ethdebug/evm, and so
on) has its own CHANGELOG.md under packages/<name>/; this file covers only
the spec itself.
Each entry gives a summary of what changed. Three sub-items follow:
Schemas:the fully qualified name(s) of the schema(s) the change touches.Producers:what the change means for an emitter ofethdebug/formatdata (a compiler such as solc or bugc).Consumers:what the change means for a reader ofethdebug/formatdata (a debugger such as soldb).
Each Producers: and Consumers: sub-item starts with one of three prefixes:
no change needed.Nothing that was valid becomes invalid, and nothing changes meaning for this party. One short reason may follow.optional:The change adds a capability. Nothing that was valid in the previous published version changes. No party is obliged to do anything. The sub-item says what the party may now do.required:Output that was valid in the previous published version no longer validates, or the specification adds or changes a normative must, or the meaning of data that was already valid changes. The sub-item names the schema keyword, or quotes the specification prose, that imposes the obligation. Prose that says should or "preferred" is neverrequired:.
A consumer has an obligation only where producers can now emit something that a conforming consumer would otherwise misread or reject, or where the meaning of data that was already valid changed. A consumer that does not use a new optional feature has no obligation.
A new branch in a closed oneOf that a consumer must interpret to read the data
at all (for example a new pointer expression or collection) is required: for
consumers, because producers may start to emit it at any time. An addition that
a consumer can skip without misreading anything else (for example a new kind of
context) is optional:.
Each impact line states the net effect for a party that moves from the previous
published version to the version of the section. A change inside a schema that
is new in that version obliges nobody, so its lines are optional: or
no change needed. and describe how the new schema works. An obligation that a
later change in the same version reverses does not appear in an impact line; the
summary may tell the history.
Each version has at most two sections. ### Added holds a new schema, or a new
keyword or capability. ### Changed holds a change to something that exists.
The sections do not signal obligations; the prefixes do.
Unreleased
Added
- An
ethdebugfield on ethdebug/format/info, ethdebug/format/info/resources and ethdebug/format/program names the schema the object conforms to and the specification version that defines it, through the new ethdebug/format/data/identification schema. The field is optional now and becomes required at0.1.0. An object without it predates the field (#305).- Schemas: ethdebug/format/data/identification, ethdebug/format/info, ethdebug/format/info/resources, ethdebug/format/program
- Producers: optional: emit
ethdebug: { schema, version }with the version of the specification whose schemas the producer targets; a program inside a container may omit it, and when both carry it the versions must be equal. - Consumers: optional: a consumer may read the field.
ethdebug/format/program and ethdebug/format/info are closed
objects (
unevaluatedProperties: false), so a consumer that validates against the previous release's schemas rejects an identified object until it updates its schemas.
Changed
- The
offsetof a segment counts bytes from the most significant byte of the slot: byte0is the first byte of the slot's big-endian word. The description now says so, says how to convert from a layout that counts from the low-order end ($wordsize - o - n), and allows writing that conversion as an expression. New segment examples pack anaddressand auint32into one slot, each written with literal offsets (12and8) and with an expression that takes the value's size from the region's ownlength({ ".length": "$this" }) (#309).- Schemas: ethdebug/format/pointer/scheme/segment
- Producers: no change needed. The reference implementation and bugc already resolve offsets this way; the text states existing meaning.
- Consumers: no change needed. A consumer that resolved
offsetagainst the big-endian word already follows this.
0.1.0-draft.0 — 2026-09-21
The version scheme changed: prerelease versions of the specification are now
draft.<n>, and 0.1.0-draft.0 follows 0.1.0-2. No schema changed.
0.1.0-2 — 2026-09-17
Changed
-
The pointer fields of an external call or contract creation
invoke(target,gas,value,input,salt) describe the operands that the marked CALL or CREATE instruction consumes, so they resolve against the state immediately before that instruction executes. This is the one exception to the rule from #281 that a context's pointers resolve after its instruction. Theinvokedescription had kept the earlier "trace step" sentence, which contradicted that rule; the context itself stays on the call instruction (#303).- Schemas: ethdebug/format/program/context/function/invoke, ethdebug/format/program/instruction, ethdebug/format/program/context/function/return
- Producers: no change needed. The
invokeexamples already placed the context on the call instruction with pointers to its operands. - Consumers: required: resolve the pointer fields of a
messageorcreateinvokeagainst the state before the marked instruction executes (a new exception in thecontextdescription). A consumer that followed theinvokeexamples already does this.
-
A segment's
offsetis no longer limited to a value below$wordsize: an offset at or past$wordsizenow carries into later slots. The defaultlengthis now$wordsize - (offset mod $wordsize), which runs to the end of the slot in which the segment begins and equals the earlier default for an offset inside the slot. Alengththat spans slots was already defined. A new segment example shows the carry, and a new pointer example collapses a long storage string to one multi-slot region (#284).- Schemas: ethdebug/format/pointer/scheme/segment, ethdebug/format/pointer
- Producers: optional: a producer may emit an
offsetat or past$wordsizeand let it carry into later slots. Every pointer that was valid before keeps its meaning. - Consumers: required: find the slot and byte of an
offsetby division and remainder against$wordsize, and compute the defaultlengthas$wordsize - (offset mod $wordsize). Theoffsetdescription no longer says that the offset "must begin inside the slot".
-
A property lookup through
$this(for example{ ".length": "$this" }) must not be circular: the property it reads has to be resolvable without depending on the value being defined. A struct-array example that named its own region the long way around now uses$this(#284).- Schemas: ethdebug/format/pointer/expression, ethdebug/format/pointer
- Producers: required: do not emit a circular property lookup through
$this. A new "must not be circular" in the description imposes this; no validator catches it. A pointer that already resolves is not affected. - Consumers: no change needed. The rule constrains producers only, and no valid data changes meaning.
-
Expressions now evaluate to one of two sorts, an unbounded integer or definite-width bytes, and the
$concatand$keccak256operands must be width-bearing bytes rather than bare integers. A hexadecimal literal with an even number of digits is bytes of exactly the width written, a literal with an odd number of digits is an integer, and widths are never inferred from context; the earlier text let a literal omit leading zeroes and padded it to the width of its context. No schema keyword changes, so a validator accepts the same documents as before, but an expression that passes a bare integer to$concator$keccak256, as the schema's own earlier examples did, no longer conforms. Those examples are corrected (#286).- Schemas: ethdebug/format/pointer/expression
- Producers: required: give each bare-integer operand of
$concator$keccak256a width first with$wordsizedor a$sizedNform, and write a literal that is meant as bytes with its full number of digits (a new "must be width-bearing" in the description). No validator catches this. - Consumers: required: the meaning of literals changed ("Widths are never inferred from context"). Read an even-digit hexadecimal literal as bytes of exactly the width written, and an odd-digit literal or a JSON number as an integer. Arithmetic results are unbounded integers. The specification does not say what a consumer does with a bare-integer operand.
0.1.0-1 — 2026-09-16
Added
-
A character encoding is a label defined by the WHATWG Encoding Standard, and an omitted optional encoding field means
utf-8. ethdebug/format/materials/source and ethdebug/format/type/elementary/string both reference the new primitive instead of accepting a free-form string. The label requirement is a normative tightening that no validator catches: the schema is stilltype: string, so a label the Standard does not define validates anyway. (#285)- Schemas: ethdebug/format/materials/encoding, ethdebug/format/materials/source, ethdebug/format/type/elementary/string
- Producers: required: an
encodingvalue must be a label that the Standard defines (a new must in the description); no validator catches this. The canonical lowercase name (utf-16le, notutf-16) is only preferred. - Consumers: optional: a consumer may pass the value straight to
new TextDecoder(label). No validator rejects a label from outside the Standard. An omitted field meansutf-8, as it did before.
-
A context may list the compiler transformations that produced an instruction —
inline,tailcall,fold,coalesce, with an extensible identifier set and repeats allowed. A transform annotates rather than replaces the semantic contexts, and composes flat beside them on one context object. The ethdebug/format/program/context/function/invoke page now describes how a debugger reconstructs activations frominvokeandreturncontexts, and says that a compiler must emit the two as a bracket around a body. (#216)- Schemas: ethdebug/format/program/context/transform, ethdebug/format/program/context, ethdebug/format/program/context/function/invoke
- Producers: optional: the ethdebug/format/program/context schemas are new
in 0.1.0-1. A producer that emits
invokeandreturnmust emit them as a bracket:invokeon the first instruction of a body,returnon its last.transformis optional. - Consumers: optional: the schemas are new in 0.1.0-1. A consumer may ignore
transform, or use it to reconstruct inlined and tail-call activations. It should keep an unfamiliar identifier as an opaque label.
-
An optional
activationstring pairs an invocation with the return or revert that ends it. Distinct activations carry distinct values, unique within the program. (#245)- Schemas: ethdebug/format/program/context/function/invoke, ethdebug/format/program/context/function/return, ethdebug/format/program/context/function/revert
- Producers: optional: the ethdebug/format/program/context/function
schemas are new in 0.1.0-1. A producer may put one
activationstring on aninvokeand on thereturnorrevertthat ends it, distinct for each activation. - Consumers: optional: the schemas are new in 0.1.0-1. Where
activationis present, a consumer that reads them may pair a call with its return or revert by that value instead of by strict nesting in trace order.
-
Contexts mark the function-call lifecycle — an invocation of exactly one kind (
jumpfor an internal call,messagefor an external message call,createfor a contract creation), a successful return, or a revert — each carrying optional function identity (identifier,declaration,type). ethdebug/format/type/specifier names the "full type or{ id }reference" pattern that ethdebug/format/type/wrapper and context variables now share. Thecontextdescription in ethdebug/format/program/instruction also gained a sentence that tied context pointers to the machine state at that instruction's trace step; #281 later replaced it with the postcondition convention. (#154)- Schemas: ethdebug/format/program/context/function, ethdebug/format/program/context/function/invoke, ethdebug/format/program/context/function/return, ethdebug/format/program/context/function/revert, ethdebug/format/type/specifier, ethdebug/format/type/wrapper, ethdebug/format/program/context, ethdebug/format/program/context/variables, ethdebug/format/program/instruction
- Producers: optional: the ethdebug/format/program/context/function
schemas and ethdebug/format/type/specifier are new in 0.1.0-1. An
invokegives exactly one ofjump,messageandcreate. ethdebug/format/type/wrapper accepts the same data as at 0.1.0-0. - Consumers: optional: the function contexts are new in 0.1.0-1; a consumer may read them to follow calls, returns and reverts. ethdebug/format/type/wrapper validates the same data as at 0.1.0-0.
-
A context may carry a
namelabel, now wired into the context dispatcher; it is most useful for tellingpickalternatives apart. (#179)- Schemas: ethdebug/format/program/context/name, ethdebug/format/program/context, ethdebug/format/program/context/pick
- Producers: optional: ethdebug/format/program/context/name is new in
0.1.0-1. A producer that emits contexts may put a
namestring on one, for example to tellpickalternatives apart. - Consumers: no change needed. The schema is new in 0.1.0-1; a consumer that
reads it treats
nameas an opaque label with no format-imposed semantics.
-
An array type may state a fixed element
count; omitting it means the array is dynamically sized. (#168)- Schemas: ethdebug/format/type/complex/array
- Producers: required: for fixed-size arrays only. State
count, because an array type withoutcountnow means a dynamic array ("When omitted, the array is dynamically sized").countis not inrequired. - Consumers: required: read a missing
countas a dynamic array and a presentcountas the fixed number of elements. Thecountdescription changed the meaning of an array type withoutcount.
-
A pointer may declare templates inline with a
templates/inpair, and a template reference may remap the region names a template produces throughyields; unmapped names pass through unchanged. (#158)- Schemas: ethdebug/format/pointer/collection/templates, ethdebug/format/pointer/collection/reference, ethdebug/format/pointer, ethdebug/format/pointer/collection
- Producers: optional: a producer may declare templates inline with
templatesandin, which makes a pointer self-contained, and may addyieldsto a template reference to reuse it without region-name collisions. - Consumers: required: a consumer that resolves pointers must support both
forms, because a valid pointer can now contain them (a new
oneOfbranch fortemplatesin ethdebug/format/pointer/collection; a newyieldsproperty). Templates intemplatesare available by name insidein.yieldsrenames regions; unmapped names pass through unchanged.
-
A
{ "$concat": [...] }expression evaluates to the concatenation of its operands' bytes, preserving each operand's byte width; an empty operand list is permitted. (#156)- Schemas: ethdebug/format/pointer/expression
- Producers: optional: a producer may use
$concatto build a byte sequence from several operands, for example a storage slot key or the input to a hash. - Consumers: required: a consumer that resolves pointers must support
$concat, because a valid pointer can now contain it (a newConcatbranch in the schema'soneOf). Operands join in list order and keep their byte widths; no padding is added or removed.
-
A
picklists two or more alternative contexts of which one holds, agatherlists two or more contexts that all hold simultaneously, andframenames, as a bare string, the compilation frame a context's facts belong to — for example"ir"or"source". (#144)- Schemas: ethdebug/format/program/context/pick, ethdebug/format/program/context/gather, ethdebug/format/program/context/frame, ethdebug/format/program/context
- Producers: optional: the ethdebug/format/program/context schemas are new
in 0.1.0-1. A
pickorgatherlist needs at least two members (minItems: 2).gatheris needed only where two facts use the same key. - Consumers: optional: the schemas are new in 0.1.0-1. A consumer that reads
them reads a
pickas alternatives of which one is true, reads all members of agatheras true together, and may separate facts byframe.
-
One schema covers a non-negative integer given either as a JSON number or as a
0x-prefixed hex string; ethdebug/format/materials/source-range offsets and lengths, ethdebug/format/pointer/expression literals, and ethdebug/format/program/instruction offsets and operation arguments all reference it. (#126)- Schemas: ethdebug/format/data/value, ethdebug/format/materials/source-range, ethdebug/format/pointer/expression, ethdebug/format/program/instruction
- Producers: optional: ethdebug/format/materials/source-range
offsetandlengthmay now be0x-prefixed hex strings. The new ethdebug/format/program/instruction takes either form. - Consumers: required: accept
0x-prefixed hex strings as well as JSON numbers in ethdebug/format/materials/source-rangeoffsetandlength(type: numberat 0.1.0-0; now ethdebug/format/data/value). ethdebug/format/program/instruction is new in 0.1.0-1 and takes both forms too.
-
A context may carry a human-readable
remarkstring, intended primarily for humans to use as an annotation and not for compilers to use directly. (#125)- Schemas: ethdebug/format/program/context/remark, ethdebug/format/program/context
- Producers: optional: ethdebug/format/program/context is new in 0.1.0-1.
A producer that emits a context may put a
remarkstring on it; a context may hold only aremark. - Consumers: optional: the schema is new in 0.1.0-1. A consumer that reads it
may display the
remark. It is an annotation for humans and has no other meaning.
-
A new ethdebug/format/info schema can represent all debugging information of one compilation as one standalone document that holds its
compilation, itsprograms, and by-name lookup tables fortypesandpointers. A new ethdebug/format/info/resources schema holds only the lookup tables (and an optionalcompilation), for compilers that give the other data elsewhere in their output. The same change raised the compilationiduniqueness requirement from should to must (relaxed back to should by #131). (#123)- Schemas: ethdebug/format/info, ethdebug/format/info/resources, ethdebug/format/materials/compilation
- Producers: optional: ethdebug/format/info and
ethdebug/format/info/resources are new in 0.1.0-1. A resources object
gives
typesandpointers(required); an ethdebug/format/info document also givescompilationandprograms. Compilationiduniqueness stays should. - Consumers: optional: the schemas are new in 0.1.0-1. A consumer that reads
either form may look up types and pointer templates by name in
typesandpointers; how a reference resolves against them is not specified.
-
A program describes one bytecode of a compilation — its
contract, itsenvironment(callorcreate), thecontextholding before its first instruction, and itsinstructions, each with anoffset, anoperation, and acontextcarrying source-range and variable facts. (#113)- Schemas: ethdebug/format/program, ethdebug/format/program/instruction, ethdebug/format/program/context, ethdebug/format/program/context/code, ethdebug/format/program/context/variables, ethdebug/format/program/context/name
- Producers: optional: ethdebug/format/program is new in 0.1.0-1. A
producer that emits one per bytecode gives
contract,environmentandinstructions, and anoffsetper instruction (required). For EOF bytecode,offsetmust count from the container start. A variabletype, when given, must be a full type or an{ id }reference. - Consumers: no change needed. Every schema here is new in 0.1.0-1, and no
schema from 0.1.0-0 references them. A consumer that reads a program finds
each instruction by its
offset.
-
A pointer template is a pointer parameterised over the variables it lists in
expect, and a{ "template": ... }collection instantiates one by name. (#103)- Schemas: ethdebug/format/pointer/template, ethdebug/format/pointer/collection/reference, ethdebug/format/pointer/collection
- Producers: optional: a producer may write a repeated pointer shape one time
as a template and refer to it with a
templatecollection. Definitions can go in ethdebug/format/info/resourcespointers(#123) or an inlinetemplatescollection (#158). - Consumers: required: a consumer that resolves pointers must support the
templatecollection (a newoneOfbranch in ethdebug/format/pointer/collection): find the template by name and bind itsexpectvariables from the scope at the reference.
-
Two primitives cover a
0x-prefixed hex string of at least one digit and a non-negative JSON integer. ethdebug/format/materials/source-rangeoffsetandlength, ethdebug/format/pointer/expression literals, and ethdebug/format/type/elementary/bytessizereference them. This tightens source-range values from any number to a non-negative integer and makes the non-negative limit on integer literals effective. Thebitsandplacesof the elementary numeric types change fromtype: numbertotype: integer. (#104