| name | check-for-breaking-changes |
| description | Detect breaking changes by analyzing git diff against dev branch. Checks for state access changes in call/genesis handlers, state item ordering violations, and demo-rollup-schema.json changes. |
Check for Breaking Changes
Analyze the current branch for breaking changes compared to dev.
What Counts as Breaking
-
New state accesses in call()/genesis handlers
- Accessing a
#[state] field that wasn't touched before
- Changing number of
.get(), .set(), .get_or_err(), .remove() calls
-
Stored struct definition changes
- Adding or removing fields from any struct that is stored in a
#[state] container (e.g. as a value in StateMap<K, V> or StateValue<V>)
- This changes the Borsh serialization layout, making existing stored data unreadable
-
State item ordering violations
- New
#[state] items NOT added as the last item in module struct
-
demo-rollup-schema.json changes
- Any modification to
examples/demo-rollup/demo-rollup-schema.json
Exception: Accessory state (AccessoryStateMap, AccessoryStateValue) accesses are NOT breaking.
Instructions
Step 1: Get Changed Files
git diff dev...HEAD --name-only
Step 2: Check autogenerated.rs
If examples/demo-rollup/demo-rollup-schema.json appears in changed files:
- Report as BREAKING: "demo-rollup-schema.json has changed - this affects CHAIN_HASH and schema"
- Show the diff summary
Step 3: Check Module State Ordering
For each changed file that contains #[derive( and ModuleInfo:
- Get the full diff for module struct definitions
- Identify if new
#[state] fields were added
- Check if new fields appear AFTER all existing
#[state] fields
- Parse by finding
#[state] attribute lines and their field declarations
Flag as BREAKING if: A new #[state] field was inserted before existing state fields
Example detection:
#[state]
existing_field: StateMap<K, V>,
#[state]
new_field: StateValue<X>,
#[state]
new_field: StateValue<X>,
#[state]
existing_field: StateMap<K, V>,
Step 4: Check Stored Struct Definitions
For each #[state] field in a module, identify the value type stored (e.g. Token<S> in StateMap<TokenId, Token<S>>). Then check if any of those struct definitions were modified in the diff:
- Collect all value types from
#[state] fields across modules
- Search the diff for changes to those struct definitions
- Flag if fields were added, removed, or reordered
Flag as BREAKING if: A struct stored in any #[state] container has fields added, removed, or reordered. This changes its Borsh serialization layout.
Example:
#[state]
tokens: StateMap<TokenId, Token<S>>,
pub struct Token<S: Spec> {
pub name: String,
pub total_supply: Amount,
+ pub decimals: u8,
}
Note: Enum variants are also sensitive โ adding a new variant is safe only if it's appended at the end AND the enum uses default Borsh discriminants.
Step 5: Check State Access Patterns
For files with changes to fn call( or fn init( (genesis):
- Get the function diff
- Identify state access method calls:
.get(, .get_or_err(, .get_or_default(
.set(, .set_or_err(
.remove(
.push(, .pop(
.iter(, .keys(, .values(
- Compare before/after to detect:
- New state fields being accessed
- Changed number of access calls
- Changes to struct fields (serialized size)
Skip if the access is on:
AccessoryStateMap
AccessoryStateValue
- Any field with
Accessory in its type name
Flag as POTENTIAL BREAKING with hints:
- "New access to
self.tokens in call() - verify gas impact"
- "Added .set() call on
self.balances - check if this changes access count"
- "Added .set() call to
self.config - check if this changes access count"
Step 6: Generate Report
## Breaking Change Analysis
### demo-rollup-schema.json
โ BREAKING / โ No changes
### State Item Ordering
โ BREAKING: [field] added at position [N] in [module] / โ No violations
### Stored Struct Definitions
โ BREAKING: [struct] has fields added/removed, stored in [module].[field] / โ No changes
### State Access Patterns
#### [Module/File]
- [POTENTIAL BREAKING] New access to `field_name` in `fn call()`
- [INFO] Accessory state access (safe): `accessory_field`
### Summary
- Breaking changes detected: [N]
- Potential issues requiring review: [N]
- Safe changes: [N]
Notes
- Focus on
crates/module-system/module-implementations/ for module changes
- State field discriminants are 0-indexed based on declaration order
- Max 127 state fields per module
- When in doubt, flag for manual review rather than missing a breaking change