Guard Mail Compose
Outbound draft validator for b.mail.agent.compose / b.mail.agent.reply / b.mail.agent.forward. Composes the existing b.guardEmail.validateMessage for address + header shape and adds compose-specific rules:
- identity vs From alignment — operator-supplied identity.email must equal the From header local-part + domain (defends spoof- at-submission) - recipient deduplication — Sender / To / Cc / Bcc combined cardinality cap (default 100; envelope-from never duplicated) - attachment byte cap — sum of body.attachments[*].size_bytes must not exceed maxAttachmentBytes (default 25 MiB to match the RFC 5321 §4.5.3.1.10 receiver cap) - body shape — exactly one of text / html required (multipart at submission-time per RFC 2046 §5.1.3); both allowed when operator explicitly opts in via allowMultipartAlternative - Subject control-char refusal — same C0 / DEL rule the existing b.guardEmail applies to header values
Profile vocabulary mirrors the rest of the guard family (strict / balanced / permissive); posture vocabulary (hipaa / pci-dss / gdpr / soc2) pins strict.
b.guardMailCompose.validate(draft, opts?) #
{
profile: "strict" | "balanced" | "permissive",
posture: "hipaa" | "pci-dss" | "gdpr" | "soc2",
identity: { email: string, name?: string }, // required if checkIdentity
checkIdentity: boolean, // default true
allowMultipartAlternative: boolean, // default false
}
Validate an outbound draft envelope. Returns the input on success; throws GuardMailComposeError on refusal.
b.guardMailCompose.validate({
from: "alice@example.com",
to: ["bob@example.com"],
subject: "hello",
body: { text: "hi" },
}, { identity: { email: "alice@example.com" } });
b.guardMailCompose.compliancePosture(name) #
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.guardMailCompose.compliancePosture("hipaa"); // → "strict"
b.guardMailCompose.compliancePosture("not-a-regime"); // → null
Last updated 2026-08-08T16:39:49.652Z by seeder.