Summary
GtsOps::add_entity (and transitively add_entities) is non-atomic: self.store.register(entity.clone()) runs first, and every subsequent validation gate (validate_schema_modifiers, validate_trait_placement, validate_schema, validate_schema_chain, validate_schema_traits) returns ok: false on failure without rolling back the registration. Rejected entities therefore remain in the store and are visible to later reads and validations.
This pattern predates PR #90 (v0.12 support) and is systemic — it was not introduced by the trait-placement check added in that PR.
Desired behaviour
- Snapshot + rollback: before running any validation gate, snapshot (or skip registering until all gates pass), and roll back / evict the entity from the store if any gate fails.
- Rollback-safe re-registration: a failed re-registration of an already-registered entity must not wipe the previously-registered valid state.
- Batch transactionality:
add_entities should either commit all or none (or at minimum clearly document per-item rollback behaviour).
References
/cc @aviator5
Summary
GtsOps::add_entity(and transitivelyadd_entities) is non-atomic:self.store.register(entity.clone())runs first, and every subsequent validation gate (validate_schema_modifiers,validate_trait_placement,validate_schema,validate_schema_chain,validate_schema_traits) returnsok: falseon failure without rolling back the registration. Rejected entities therefore remain in the store and are visible to later reads and validations.This pattern predates PR #90 (v0.12 support) and is systemic — it was not introduced by the trait-placement check added in that PR.
Desired behaviour
add_entitiesshould either commit all or none (or at minimum clearly document per-item rollback behaviour).References
/cc @aviator5