A class treated as a sharable record (with public mutable fields or setters) used by many consumers — mutating it in one place affects every reader.
A class with public mutable fields used by many consumers; the agent reasoning about any read must consider every other writer.
An object treated as a sharable record (with setters) becomes a value object — immutable, equal by content, replaced rather than mutated.
The object is immutable + equal-by-content; the agent reasons about value semantics without modeling write timing.
Before the refactoring
class Phone {constructor() { this.area = null; this.number = null; }}phone.area = '617';
After the refactoring
class Phone {constructor(area, number) { this._area = area; this._number = number; }area() { return this._area; }number() { return this._number; }withArea(area) { return new Phone(area, this._number); }}
Concurrent reasoning becomes hazardous; the type system can't enforce immutability; consumers can't trust the object's state between operations.
The agent must trace every writer to model state at any read; concurrent reasoning is practically impossible.
Comparison semantics shift from identity to equality — every call site that depended on `===` or identity caches needs review.
Comparison semantics shift from identity to equality; every call site that depended on === or identity caches needs the agent's review and update.
Concurrency hazards disappear; the type system can mark fields readonly; the object can travel safely across boundaries.
Concurrency hazards disappear; the type system can mark fields readonly; the agent reasons about the object as a stable value.
Switching to value semantics for objects that genuinely belong as references — domain entities with identity (Customer, Account) — strips the identity that consumers depend on.
Switching domain entities (Customer, Account) to value semantics strips the identity the agent's consumers depended on — equality replaces 'this specific thing' with 'anything that looks like it'.