QM's domain types divide platform access by principal type (internal member or guest) and scope kind (personal, channel, team, org, or group), each scope identified by scopeId(kind, ref) strings and governed by distinct policies for management, sharing, filesystem access, and network egress. The type system represents the agent turn loop (TurnRequest, TurnOrigin, Resolution) as a configuration bundle for execution, and the session tape (EntryType) as a record of interactions, with fine-grained policies (CommandPolicy, EgressPolicy, ApprovalGrantModes) controlling what actions are permitted under which identities and approval conditions.
PrincipalType in src/types.ts is a union of "internal" and "guest", distinguishing authenticated org members from external guests.[1] The five valid ScopeKind values in src/types.ts are "personal", "channel", "team", "org", and "group", forming the isolation hierarchy for the platform.[1] ScopeId strings are formatted as "<kind>:<ref>" (e.g., "personal:user123"), produced by the exported scopeId(kind, ref) function in src/types.ts.[1] personalScope(principalId) is a convenience wrapper that returns scopeId("personal", principalId), representing a user's private isolation boundary.[1] parseScopeId returns { kind: null, ref: "" } when the input contains no : separator, and { kind: null, ref: ... } when the prefix is not a recognized ScopeKind.[1] isManageableCreationScope returns true only for "channel" and "team" scopes, meaning only those scopes support managed resource creation.[1] isSharedScope returns true only for "channel" and "group" scopes, distinguishing them from "personal", "team", and "org" scopes.[1] In QM's isolation hierarchy, narrower scopes (e.g., "personal") are fully private to a single user, while broader scopes (e.g., "org") span all members, determining which agents and users can share context and access resources. Person resolution in src/api/routes/directory.ts and src/directory/directory-store.ts handles deployments with no Slack surface configured, preventing failures and empty results for non-Slack deployments when resolving members. src/api/app-helpers.ts and src/api/app-sessions.ts permit adding a project member whose identity the directory store has never encountered, allowing external users to be added to projects before their first directory sync.
TurnRequest in src/types.ts is the primary input structure for the agent turn loop, covering model selection (model, harness, thinkingLevel, fastMode), approval handling, attachment passing, and async dispatch.[1] TurnOrigin is a discriminated union distinguishing "human" (interactive user), "ambient" (background observation), "automation" (scripted/scheduled), and "direct" (internal programmatic) origins for a turn.[1] EntryType in src/types.ts is a union covering "user", "assistant", "thinking", "text", "tool_call", "tool_result", "soul", "system", "delivery", "approval_request", and "approval_resolved" — the full set of tape entry kinds.[1]
The Resolution interface in src/types.ts is the fully resolved runtime configuration for a turn, bundling workspace layers, system prompt, egress policy, command policy, security policy, approval grant modes, org scope, and granted handles.[1] WorkspaceLayer has a mode of "ro" (read-only) or "rw" (read-write), controlling filesystem access for each mounted scope layer.[1] EgressPolicy controls outbound network access via allowedHosts (whitelist), an optional denyPrivateNetworks flag, privateNetworkAllowedHosts exemptions, and an optional deniedHosts list.[1] CommandPolicy operates in either "denylist" or "allowlist" mode, with an ordered list of CommandRule entries each carrying a pattern, a decision ("allow" | "deny" | "require_approval"), and an optional reason.[1] ApprovalGrantModes has two boolean flags — session and always — controlling whether an approval can be granted for the current session only or permanently.[1]
BackgroundWakeTrigger in src/types.ts is typed as "cron" | "webhook" | "monitor" | (string & {}), allowing known trigger kinds to be named while still accepting arbitrary future strings.[1] The Cron trigger interface supports a runAs field with values "owner", "scopeFloor", or "scopeShared", controlling which identity context the cron job executes under.[1]
The Session interface in src/types.ts tracks agent-session lifecycle state via optional fields including archived, pinned, working, awaitingInput, backgroundJobs, and watches.[1] Session.forkedFrom records the parent session ID and title when a session is a fork, with forkBoundarySeq marking the tape sequence where the fork diverges.[1]
The Destination interface in src/types.ts supports a taskList field for structured task tracking, with each item carrying an id, title, and status of "pending", "in_progress", "completed", "skipped", or "failed".[1] RecipientConsent tracks whether a delivery recipient has accepted or declined being contacted, with statuses "pending", "accepted", or "declined".[1]
Sources