Guard Mail Move

Destination-folder allowlist validator for b.mail.agent.move. Refuses moves to system folders the actor doesn't have admin scope for, refuses cross-account moves (fromFolder and toFolder must belong to the same agent context), and refuses path-traversal-shaped folder names (.. / leading . / NUL / bidi).

System folders the framework treats specially:

- **INBOX / Sent / Drafts**: always writable by the owner; no admin scope required. - **Junk / Trash**: always writable (Junk is the default Sieve junk destination; Trash is the soft-delete target). - **Archive**: always writable. - any operator-created folder: writable when in the actor's allowed-folders list (per the operator's RBAC) OR when the actor has mailScope: "admin".

The guard does NOT touch the underlying mail-store; that composition lives in b.mail.agent.move. The guard validates the SHAPE of the move call.

b.guardMailMove.validate(move, opts?) #

stable0.9.20
{
  profile:   "strict" | "balanced" | "permissive",
  posture:   "hipaa" | "pci-dss" | "gdpr" | "soc2",
}

Validate a { actor, fromFolder, toFolder, objectIds } shape.

b.guardMailMove.validate({
  actor:      { id: "u1", mailScope: "user" },
  fromFolder: "INBOX",
  toFolder:   "Archive",
  objectIds:  ["abc123"],
});

b.guardMailMove.compliancePosture(name) #

stable0.9.20hipaapci-dssgdprsoc2

Return the effective profile NAME for a compliance posture, or null for a name this parser does not map. Unlike the content-guard variant this returns the resolved profile string (every line-protocol parser composes gateContract.ALL_STRICT_POSTURES, so "hipaa" / "pci-dss" / "gdpr" / "soc2" all resolve to "strict") and never throws — the parser shape carries no overlay-clone, no buildProfile, and no loadRulePack. Wired by gateContract.defineParser.

b.guardMailMove.compliancePosture("hipaa");                   // → "strict"
b.guardMailMove.compliancePosture("not-a-regime");            // → null

Last updated 2026-08-08T16:39:49.652Z by seeder.