Bot
Bot Core
AI Router, message drafts, owner-review state machine, queue model, audit trail.
SENDING_ENABLED = false
Send gate is LOCKED — Red-Zone owner approval required to change.
Review State Machine — 8 States
Terminal states (red): rejected, expired, cancelled — no outgoing transitions.
Actions (7)
Transitions (14)
State Machine Invariants
- The only path to ready_to_send is through approved.
- Any edit forces edited_pending_reapproval — re-approval is mandatory.
- rejected, expired, cancelled are terminal — no outgoing transitions.
- consentStatus !== 'confirmed' blocks submit_for_review.
Queue Model — OwnerReviewItem
draftId: stringstate: ReviewStatesubmittedAt: stringreviewedAt: string | nullreviewerRef: 'owner'decisionNote: string | nullpriority: 'normal' | 'high'expiresAfterHours: number (default 24)Example Flows
Happy Path
{ "description": "Happy path: draft submitted, approved, ready to send.", "steps": [ { "from": "draft", "action": "submit_for_review", "expectedTo": "pending_owner_review" }, { "from": "pending_owner_review", "action": "approve", "expectedTo": "approved" }, { "from": "approved", "action": "submit_for_review", "expectedTo": "ready_to_send" } ], "invariantsVerified": { "consentConfirmed": true, "consentBlocksSubmit": true, "terminalCheck": true, "readyToSendNotTerminal": true } }
Rejection
{ "description": "Rejection: draft submitted, owner rejects. Terminal.", "steps": [ { "from": "draft", "action": "submit_for_review", "expectedTo": "pending_owner_review" }, { "from": "pending_owner_review", "action": "reject", "expectedTo": "rejected" } ], "invariantsVerified": { "rejectedIsTerminal": true, "noActionsFromRejected": true } }
Edit → Reapproval
{ "description": "Edit forces reapproval: draft → pending → edit → edited_pending_reapproval → resubmit → pending → approve → approved.", "steps": [ { "from": "draft", "action": "submit_for_review", "expectedTo": "pending_owner_review" }, { "from": "pending_owner_review", "action": "edit", "expectedTo": "edited_pending_reapproval" }, { "from": "edited_pending_reapproval", "action": "resubmit", "expectedTo": "pending_owner_review" }, { "from": "pending_owner_review", "action": "approve", "expectedTo": "approved" } ], "invariantsVerified": { "editForcesReapproval": true, "canResubmit": true, "editedPendingIsNotTerminal": true } }
Audit Trail — maskPhone
PII-safe phone masking. Never stores raw phone numbers in audit events.
+970-599-123456→+970***56972501234567→972***671234→12**null→null