feat(ci): freeze the raw zone-mutation census as a full-tree authority ratchet#5647
Merged
Conversation
…y ratchet Every gameplay zone change must be proposed through zone_pipeline so that replacement effects, ZoneChanged events, triggers, and draw bookkeeping each get their opportunity (CR 614 / CR 400.7). Today 82 production sites still mutate zones raw, in three families the existing diff-only authority gate does not see: mover 50 the five raw movers game/zones.rs exports container 20 direct writes to the im::Vector zone containers zone-assign 12 direct `GameObject::zone = ...` assignment Add section (B) to the engine authority gate: a full-tree, syntax-aware census (scripts/zone_authority_census.py) ratcheted against a frozen baseline. Unlike section (A) this cannot be diff-only — a diff gate cannot tell a migrated site from a duplicated one, and privacy on the movers alone would not close the container/assign families. The baseline is keyed on (file, enclosing fn, family, count), not on line numbers, so it survives the constant line drift in these files. It may only shrink: a new or grown site fails as a bypass, and a baseline row that no longer reproduces fails as stale. When the baseline empties out, the gate is zero-tolerance by construction. Sites that are genuinely not replaceable zone events (CR 733 rollback, component absorption, in-library reorder, cease-to-exist, test setup) are annotated at the call site with `// allow-raw-zone: <reason>` rather than carried as debt. The census excludes inline `#[cfg(test)]` mod bodies, outlined `*_tests.rs`, and the test-support placement helpers. Note engine-wasm gates its tests with `#[cfg(all(test, target_arch = "wasm32"))]`, which a scanner keying on bare `#[cfg(test)]` silently treats as production code. Verified red before green: a new raw site, a grown site, a stale baseline row, and — the motivating case — the `effects/token.rs` raw add_to_zone that landed after the migration census was first taken, which this gate flags as NEW.
matthewevans
enabled auto-merge
July 12, 2026 06:35
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
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.
Every gameplay zone change must be proposed through zone_pipeline so that
replacement effects, ZoneChanged events, triggers, and draw bookkeeping each
get their opportunity (CR 614 / CR 400.7). Today 82 production sites still
mutate zones raw, in three families the existing diff-only authority gate does
not see:
mover 50 the five raw movers game/zones.rs exports
container 20 direct writes to the im::Vector zone containers
zone-assign 12 direct
GameObject::zone = ...assignmentAdd section (B) to the engine authority gate: a full-tree, syntax-aware census
(scripts/zone_authority_census.py) ratcheted against a frozen baseline. Unlike
section (A) this cannot be diff-only — a diff gate cannot tell a migrated site
from a duplicated one, and privacy on the movers alone would not close the
container/assign families.
The baseline is keyed on (file, enclosing fn, family, count), not on line
numbers, so it survives the constant line drift in these files. It may only
shrink: a new or grown site fails as a bypass, and a baseline row that no
longer reproduces fails as stale. When the baseline empties out, the gate is
zero-tolerance by construction. Sites that are genuinely not replaceable zone
events (CR 733 rollback, component absorption, in-library reorder,
cease-to-exist, test setup) are annotated at the call site with
// allow-raw-zone: <reason>rather than carried as debt.The census excludes inline
#[cfg(test)]mod bodies, outlined*_tests.rs,and the test-support placement helpers. Note engine-wasm gates its tests with
#[cfg(all(test, target_arch = "wasm32"))], which a scanner keying on bare#[cfg(test)]silently treats as production code.Verified red before green: a new raw site, a grown site, a stale baseline row,
and — the motivating case — the
effects/token.rsraw add_to_zone that landedafter the migration census was first taken, which this gate flags as NEW.