conventions: require a changelog entry per MR#3
Open
sribst wants to merge 2 commits into
Open
Conversation
added 2 commits
May 11, 2026 09:55
Adds a Changelog section to conventions.md spelling out the four rules (MR link, descriptive wording, breaking-change callout, peer-version constraint at the release header) and a companion changelog-examples.md reverse-engineered from 14 recently-merged Etherlink / Tezos X / EVM-node MRs. The examples illustrate where the existing repo entries already follow the convention and where checked-off changelog boxes shipped with no entry at all.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
conventions.mdspelling out four rules every MR must satisfy: link back to the MR, describe the user-visible change (not which file moved), flag breaking changes explicitly, and record cross-component peer-version constraints at the release/version header (not buried in a bullet).Why now
A quick survey on 2026-05-07 (14 recently-merged Etherlink / Tezos X / EVM-node MRs) found that 7 of 12 feature MRs had no changelog entry at all (several with the changelog checkbox ticked in the MR description), 2 entries were missing the MR link, and both release MRs landed without moving
Unreleasedto a versioned block. A self-checked checkbox is not load-bearing; the prior wording inconventions.mdwas vague enough that this slipped through. The new section is specific about each rule's failure mode.Examples — what the convention looks like in practice
The examples below were reverse-engineered from recently-merged MRs on
gitlab.com/tezos/tezos, picked to cover the Etherlink kernel, the Tezos X kernel, and the Octez EVM node. The wording is what I would have written into the appropriateetherlink/CHANGES_*.mdfile at MR time. Some entries already exist verbatim in the repo (e.g.!21791,!21792,!21807); others (!21814,!21817,!21820,!21824) had no entry at merge time and are drafted here to show the gap.Source data:
glab mr list -R tezos/tezos -M --per-page 50taken on 2026-05-07, filtered to titles matchingEtherlink,EVM Node,TezosX, orTezos X.How each example maps to the four rules
conventions.md)(!21814)style at end of bullet!21797(indexer impact),!21792(Blockscout symptom),!21786(RPC)!21791(cap diverges from L1),!21792(storage V55 migration)etherlink/CHANGES_TEZOSX.md— additions to the Unreleased sectionNative atomic composability
Persist
original_evm_sourceacross re-entrant EVM frames so every CRAC issued from a Michelsoncall_evmcallback recoversalias(EOA)regardless of nesting depth. The EOA identity used to live on the per-executionJournaland was reset toNoneevery time the EVM runtime was re-entered, causing nested CRACs to recordtx.origin = alias(intermediate_Mich)instead of the original EOA and to poison the alias cache with a spurious alias-of-alias entry. The field now lives onEvmJournal(transaction-scoped) and keeps first-set-wins semantics. (!21817, L2-1303)Place failed re-entrant inner CRACs in DFS execution order on the merged synthetic Michelson manager-op, matching the order of successful re-entrant CRACs. Previously
drain_reentrant_crac_opsonly drainedpending_crac_receipts, so a failed inner CRAC kept its (smaller, push-time) sequence number and surfaced ahead of its outer parent's transfer. The receipt layout used to read[failed inner C2 / outer C1 / …]; it now reads[outer C1 / inner C2 …]. (!21814, L2-1300)Surface user
EMITevents from re-entrant inner Michelson CRACs on the synthetic CRAC transaction receipt. Events emitted by a Michelson contract reached through a nested cross-runtime call (EVM → Mich → EVM → Mich within one EVM transaction) used to be silently discarded, breaking parity for Michelson-side event indexers. (!21807, L2-1301)Surface inner
LOG0..LOG4and the precompile'sCracReceivedlog on the synthetic CRAC transaction receipt produced by Michelson%call_evm. Pre-fix, onlyCracIdEventsurvived becausecommit_evm_journal_from_externalran beforeextract_cross_runtime_effectsandJournalInner::finalizehad already clearedinner.logs. Restores indexer parity (subgraphs, on-chain analytics, ERC-1155 wallet trackers) between EOA-originated and Michelson-originated EVM activity. (!21797)Record native classification on freshly-originated KT1 contracts. Adds a default-no-op
record_native_originhook on theContexttrait, overridden byTezosRuntimeContextto write the native variant ofOriginat the KT1 origin sibling path viaset_origin_at, called fromoriginate_smart_contract. Closes the third native observation point of the transitive address-translation feature; protocol code shared with Tezlink stays decoupled from Tezos X storage layout. (!21824)Record native classification on EVM-side accounts (signer or freshly-deployed contract) and on Tezos implicit accounts at reveal time. EVM
update_accountmarks the account native when the nonce strictly increases or the code hash transitions from empty to a non-alias non-empty hash; Tezosset_manager_public_keymarks the implicit account viaset_origin_for_implicit. KT1 origination is handled separately in!21824. (!21820)Breaking change (parametric constants): raise the Michelson runtime
hard_gas_limit_per_operationandhard_gas_limit_per_blockfrom 1,040,000 to 3,000,000 gas units (3,000,000,000 milligas) to match the EVM 30M-gas per-transaction cap. These two parametric constants now diverge from the L1 mainnet defaults (which both stay at 1,040,000): a Michelson operation accepted by Tezos X may exceed the gas budget the same operation would be allowed on L1. Without this change, an EVM transaction reaching the cross-runtime precompile with more than ~10.4M gas remaining forwarded an oversizedX-Tezos-Gas-Limitand was rejected by the Michelson runtime, surfacing as a misleading EVM out-of-gas. (!21791, L2-1295)Breaking change (storage migration V55): stop persisting a
U256::MAXbalance for the internalTEZOSX_CALLER_ADDRESS(0x7e205800…01) used bygenerate_alias. The internal call usesgas_price = 0andvalue = 0, so the funding was unnecessary in the first place; only the manualset_info_without_codewrite was persisting (the surroundingCrossRuntimerun_transactionnever commits the EVM journal), leaking a visible huge balance on Blockscout. The new V55 migration deletes the residue on TezosX networks where it has already been written (e.g. Previewnet); reads of the account fall back toAccountInfo::default()(balance 0, nonce 0, empty code) afterwards. (!21792, L2-1296)Internals
etherlink/kernel_latest/tezosx-constantsso the kernel andtezos_executionderive both caps from the same source of truth. Pure refactor — no behavior change — but removes the two-place hard-coding that re-introduced the cross-runtime gas mismatch fixed in!21791if the constants ever drifted. (!21806)etherlink/CHANGES_KERNEL.md— new release block for kernel 0.3This format demonstrates the version-level cross-component constraint (rule 4): the peer-version note belongs at the release header, not buried in a bullet, so operators and releasers can gate upgrades on it without reading every line.
etherlink/CHANGES_NODE.md— additions to the Unreleased sectionRPCs changes
Add an optional
blockparameter to thetez_kernelVersionandtez_kernelRootHashJSON-RPC methods, so callers can query the kernel version and kernel root hash at any historical block. Omitting the parameter preserves the previous behavior (returns the value atlatest); no breaking change for existing clients. (!21786)Include
injectTezlinkOperationin the list of supported EVM methods reported by the RPC node. (!21785)Experimental features changes
compact_receipt_encodingfeature flag (off by default). When enabled, the EVM node serializes transaction receipts using the new compact encoding, reducing on-disk receipt size for nodes with large historical state. The flag is experimental: the encoding is subject to change without deprecation and an experimental-feature-awareoctez-evm-node check configshould be used to validate the configuration after upgrade. (!21761)etherlink/CHANGES_NODE.md— new release block for EVM Node 0.58Side-by-side: existing entry vs. drafted entry
One row per MR from the 2026-05-07 survey, in ascending MR-number order. The left column is the entry as it appears on
masterofgitlab.com/tezos/tezostoday (verbatim where present, italicised); the right column is what I would have written under the new convention._(none)_on the left means the original MR added no changelog entry.!21761— (none)!21761— Add acompact_receipt_encodingfeature flag (off by default). When enabled, the EVM node serializes transaction receipts using the new compact encoding, reducing on-disk receipt size for nodes with large historical state. The flag is experimental: the encoding is subject to change without deprecation and an experimental-feature-awareoctez-evm-node check configshould be used to validate the configuration after upgrade. (!21761)Delta: lands in the
Experimental features changessub-section (rule 4-adjacent — that section's preface already states the stability contract for opt-in flags).!21785— "IncludeinjectTezlinkOperationin the list of supported EVM methods used by the RPC node. (!21785)"!21785— Identical to the existing entry. Reference convention working as intended (rules 1 + 2 satisfied).!21786— (none)!21786— Add an optionalblockparameter to thetez_kernelVersionandtez_kernelRootHashJSON-RPC methods, so callers can query the kernel version and kernel root hash at any historical block. Omitting the parameter preserves the previous behavior (returns the value atlatest); no breaking change for existing clients. (!21786)Delta: RPC surface change with a new optional parameter — a prime "must be in the changelog" candidate. The omitted-param default is called out explicitly to make non-breaking-ness obvious.
!21791— "Raise the Michelson runtimehard_gas_limit_per_operationandhard_gas_limit_per_blockfrom 1,040,000 to 3,000,000 gas units (i.e. 3,000,000,000 milligas) to match the EVM 30M-gas per-transaction cap. These two parametric constants now diverge from the L1 mainnet defaults (which both stay at 1,040,000), so a Michelson operation accepted by Tezos X may exceed the gas budget the same operation would be allowed on L1. Without this change, an EVM transaction reaching the cross-runtime precompile with more than ~10.4M gas remaining would forward an oversizedX-Tezos-Gas-Limitand be rejected by the Michelson runtime, surfacing as a misleading EVM out-of-gas. (!21791)"!21791— Breaking change (parametric constants): raise the Michelson runtimehard_gas_limit_per_operationandhard_gas_limit_per_blockfrom 1,040,000 to 3,000,000 gas units (3,000,000,000 milligas) to match the EVM 30M-gas per-transaction cap. These two parametric constants now diverge from the L1 mainnet defaults (which both stay at 1,040,000): a Michelson operation accepted by Tezos X may exceed the gas budget the same operation would be allowed on L1. […same prose as existing…] (!21791, L2-1295)Delta: adds the
**Breaking change (parametric constants):**prefix and theL2-1295Linear ref. The existing entry is excellent on what / why / consequence but does not visually flag the L1↔Tezos-X divergence as breaking — a reader skimming sub-section titles only sees "Native atomic composability" and misses the divergence. Rule 3 (flag breaking changes explicitly) is exactly the gap the prefix closes.!21792— "Stop persisting aU256::MAXbalance for the internalTEZOSX_CALLER_ADDRESS(0x7e205800…01) used bygenerate_alias. Earlier kernels wrote that balance to durable storage as a 'safety' buffer, but the surroundingrun_transactionisCrossRuntimeso its EVM journal never commits — only the manual storage write persisted, leaking a visible huge balance on Blockscout. The funding has been removed (gas_price = 0andvalue = 0in the internal call mean no pre-flight balance is required), and storage version 55 cleans up the residue on TezosX networks. (L2-1296)"!21792— Breaking change (storage migration V55): stop persisting aU256::MAXbalance for the internalTEZOSX_CALLER_ADDRESS… The new V55 migration deletes the residue on TezosX networks where it has already been written (e.g. Previewnet); reads of the account fall back toAccountInfo::default()afterwards. (!21792, L2-1296)Delta: the existing entry links only the Linear issue (
L2-1296) and not the MR (!21792) — straight rule-1 violation. A releaser walking the changelog cannot jump to the diff. The drafted version adds(!21792, L2-1296)(both refs side by side) and the**Breaking change (storage migration V55):**prefix. The storage-version bump and the irreversible-downgrade implication also belong at the release header for kernel 0.3 (rule 4), not just in this bullet.!21797— "Fix EVM logs from cross-VM%call_evmcalls being dropped from the synthetic CRAC transaction receipt. Previouslycommit_evm_journal_from_externalran beforeextract_cross_runtime_effects; the former callsJournalInner::finalizewhich clearsinner.logs, leaving the receipt builder with an empty buffer. Only theCracIdEvent(constructed by the receipt builder itself) survived; both the precompile'sCracReceivedlog and anyLOG0..LOG4from the inner EVM call were lost. The order is now reversed so the receipt builder readsinner.logswhile revm's standard accumulation is still intact, restoring parity between the two ways into the EVM for indexers (subgraphs, on-chain analytics, ERC-1155 wallet trackers)." (no MR or Linear ref at all)!21797— Surface innerLOG0..LOG4and the precompile'sCracReceivedlog on the synthetic CRAC transaction receipt produced by Michelson%call_evm. […same root-cause prose as existing…] (!21797)Delta: the existing entry has no MR or Linear reference at all — straight rule-1 violation. The drafted version adds
(!21797). Otherwise the wording is essentially what I would have written; this entry is the gold standard for descriptive ("what / why / user impact") content.!21806— (none)!21806— Move the EVM 30M-gas per-tx cap and its Michelson 3,000,000,000-milligas mirror into a new leaf crateetherlink/kernel_latest/tezosx-constantsso the kernel andtezos_executionderive both caps from the same source of truth. Pure refactor — no behavior change — but removes the two-place hard-coding that re-introduced the cross-runtime gas mismatch fixed in!21791if the constants ever drifted. (!21806)Delta: lands in the
Internalssub-section. Releasers skip that block on a normal release scan, but reviewers diffing two kernels for a regression need to know the constant moved crates.!21807— "Surface user MichelsonEMITevents from re-entrant inner CRACs on the synthetic CRAC transaction receipt. Previously, events emitted by a Michelson contract reached through a nested cross-runtime call (EVM → Mich → EVM → Mich within one EVM transaction) were silently discarded, breaking parity for Michelson-side event indexers. (!21807)"!21807— Same wording as existing entry, withL2-1301Linear ref appended:(!21807, L2-1301).Delta: existing entry is essentially identical to my draft — this is the convention working as designed. Only addition is the Linear ref for cross-system traceability.
!21814— (none) — the MR's checklist marked the changelog item as[x]but no entry was added in this MR or any descendant.!21814— Place failed re-entrant inner CRACs in DFS execution order on the merged synthetic Michelson manager-op, matching the order of successful re-entrant CRACs. Previouslydrain_reentrant_crac_opsonly drainedpending_crac_receipts, so a failed inner CRAC kept its (smaller, push-time) sequence number and surfaced ahead of its outer parent's transfer. The receipt layout used to read[failed inner C2 / outer C1 / …]; it now reads[outer C1 / inner C2 …]. (!21814, L2-1300)Delta: the "before / after" sequence-number diagram from the MR description is exactly the kind of user-observable change that belongs in the changelog: any indexer or block explorer that consumed the merged synthetic Michelson manager-op pre-fix saw failed inner CRACs ahead of their parent's transfer. Strongest argument for the convention — the MR landed checked-off but the artifact is missing.
!21817— (none) — same as!21814, checklist marked complete, no entry written.!21817— Persistoriginal_evm_sourceacross re-entrant EVM frames so every CRAC issued from a Michelsoncall_evmcallback recoversalias(EOA)regardless of nesting depth. The EOA identity used to live on the per-executionJournaland was reset toNoneevery time the EVM runtime was re-entered, causing nested CRACs to recordtx.origin = alias(intermediate_Mich)instead of the original EOA and to poison the alias cache with a spurious alias-of-alias entry. The field now lives onEvmJournal(transaction-scoped) and keeps first-set-wins semantics. (!21817, L2-1303)Delta: user-visible symptom (alias cache poisoning across nested CRACs) deserves a bullet so operators can correlate the fix with any spurious entries on their existing alias-cache state.
!21820— (none)!21820— Record native classification on EVM-side accounts (signer or freshly-deployed contract) and on Tezos implicit accounts at reveal time. EVMupdate_accountmarks the account native when the nonce strictly increases or the code hash transitions from empty to a non-alias non-empty hash; Tezosset_manager_public_keymarks the implicit account viaset_origin_for_implicit. KT1 origination is handled separately in!21824. (!21820)Delta: part of the transitive-address-translation suite (RFC). Without a changelog entry, downstream consumers of the classification storage have no signal that the native variant of
Originis now written on commit / reveal.!21824— (none)!21824— Record native classification on freshly-originated KT1 contracts. Adds a default-no-oprecord_native_originhook on theContexttrait, overridden byTezosRuntimeContextto write the native variant ofOriginat the KT1 origin sibling path viaset_origin_at, called fromoriginate_smart_contract. Closes the third native observation point of the transitive address-translation feature; protocol code shared with Tezlink stays decoupled from Tezos X storage layout. (!21824)Delta: same gap as
!21820. Together they should land as two adjacent bullets inNative atomic composability, both pointing at the same RFC.!21828(EVM Node 0.58 release) — release MR description is just "Hop.";etherlink/CHANGES_NODE.mdstill has## Unreleasedat the top, no## Version 0.58block.!21828— Full## Version 0.58 (2026-05-06)release block (see "release block for EVM Node 0.58" above) with the explicit Compatibility note ("EVM Node 0.58 is the minimum version required to talk to a kernel 0.3 rollup… backward-compatible with kernels 0.2 and 0.1") and No store migration note.Delta: the release MR landed without moving
Unreleasedto a versioned block and without a release-level cross-component constraint header. Rule 4 (peer-version constraint at the version header) is exactly what the absence here illustrates.!21830(kernel 0.3 release) —etherlink/CHANGES_TEZOSX.mdstill has## Unreleasedat the top, no## Version 0.3block. Most recent versioned block is## Version 0.2.!21830— Full### 0.3 (<commit-sha>)release block (see "release block for kernel 0.3" above) with three release-level notes: EVM-node ≥ 0.58 required, Storage version 55 / downgrade not supported, Parametric constants diverge from L1 mainnet.Delta: same as
!21828— the version bump landed with no versioned block. Rule 4 is exactly the gap.Comparison with what is actually in the repo
Snapshot taken from
masteron 2026-05-07.!21785,!21791,!21807!21792(Linear only, no MR ref),!21797(no ref at all)!21806,!21814,!21817,!21820,!21824,!21786,!21761Unreleased→ versioned block!21830(kernel 0.3),!21828(EVM Node 0.58)That's 7 of 12 feature MRs with no changelog entry, and 2 of 2 release MRs without a versioned release block to anchor the new peer-version constraint. Several of the 7 missing entries had their changelog checkbox ticked in the MR description (e.g.
!21814,!21817) — so the gap is real and a self-checked checkbox is not load-bearing.The convention's value lands in two places: pushing the already-present entries to add the missing MR/Linear ref (rules 1 and 2), and pushing un-entered changes to actually write something — most cheaply caught by a CI lint that reads
git log --since=last-releaseand checks each MR has a matching mention in someCHANGES_*file.What I deliberately did not write
A few cases worth calling out, because the convention is just as much about restraint:
!21806) still get an entry — but in theInternalssub-section, not in the user-facing one. Releasers reading the changelog can skip theInternalsblock; reviewers comparing two kernels need it to find the constant-source-of-truth move.L2-1300/1301/1302/1303/1304chain that landed as!21807→!21808→!21811→!21812→!21814→!21817) get one bullet per MR, not one bullet for the whole stack. Each MR is independently revertible; collapsing them hides the revert surface from releasers triaging a regression.!21828) are not an excuse to skip the changelog. The release header above is what I would have insisted on before approving the release MR.Test plan
conventions.mdend-to-end and confirm the new section sits well between Pull requests on GitLab and Repository hosting.conventions.mdbullets.!21814and!21817(cited as gap examples) really have no changelog entry onmasterofgitlab.com/tezos/tezos.