Reads mode off any account-shaped value, with back-compat for
the legacy sandbox: boolean field. Returns the explicit mode if
present; otherwise infers 'sandbox' from sandbox === true;
otherwise 'live'.
Adopters that have not yet migrated to the mode field continue to
work — account.sandbox === true reads as sandbox mode through this
helper. New code should prefer mode directly.
Prototype-pollution defense: both mode and sandbox are read via
Object.hasOwn rather than bare property access. Bare access traverses
the prototype chain, so an attacker who reaches a __proto__-via-merge
sink upstream (reachable in MCP envelope handling and similar deep-merge
sites) could stamp Object.prototype.mode = 'sandbox' and silently
downgrade every account's gate to a no-op. The own-property check makes
the gate immune to that class of attack regardless of upstream hardening.
Reads
modeoff any account-shaped value, with back-compat for the legacysandbox: booleanfield. Returns the explicit mode if present; otherwise infers'sandbox'fromsandbox === true; otherwise'live'.Adopters that have not yet migrated to the
modefield continue to work —account.sandbox === truereads as sandbox mode through this helper. New code should prefermodedirectly.Prototype-pollution defense: both
modeandsandboxare read viaObject.hasOwnrather than bare property access. Bare access traverses the prototype chain, so an attacker who reaches a__proto__-via-merge sink upstream (reachable in MCP envelope handling and similar deep-merge sites) could stampObject.prototype.mode = 'sandbox'and silently downgrade every account's gate to a no-op. The own-property check makes the gate immune to that class of attack regardless of upstream hardening.