ReadonlyactorReadonlyprincipalWHO is executing. For an authenticated HTTP request this is the human in
actor; trusted internal contexts (schedule ticks, provider delivery, cron
maintenance) carry an automated principal instead of fabricating a role.
ReadonlytenantDisplay hint only: whether THIS actor may decide its OWN request — true iff the actor holds a decider role AND the deployment's self-decision policy exempts that role. Enforcement stays in ApprovalService.decide(); the GET /workflows echo reads this so the SPA can drop its "the server will refuse your decision" hint for an exempt role.
Mint a tenant-salted agent-memory resourceId over the host's business
key (a user id, a lead id): ${tenantId}_${resourceKey}. Same key, two
tenants, disjoint ids — the memory-leak class the salting closes.
Mint a tenant-salted runId: ${tenantId}_${uuid}.
Mint a tenant-salted agent-memory threadId: ${tenantId}_${uuid} —
extending the tenant-salted identifier scheme to Mastra memory
(docs/agent-memory-tenancy.md). Hosts never accept a client-supplied
threadId; this is the constructor.
Exact ownership over memory ids (threadId or resourceId) — assert on every memory read/write path; answer 404 on a foreign id.
Exact ownership: runId.startsWith(${tenantId}_).
The approval service over a store bound to THIS tenant.
Already authenticated; tenantId equals actor.tenantId and matches the tenant-ID pattern.