# Data Model — Private AI Execution & Policy Foundation **Spec**: [spec.md](spec.md) No new persistent tables or AI artifact stores are required for v1. The feature reuses existing workspace settings, operational controls, and audit logs. New AI-specific structures are code-owned or request-scoped. ## Persisted Truth Reused ### Workspace AI Policy (`workspace_settings` carrier) **Purpose**: Workspace-owned policy truth that determines whether AI is disabled entirely or limited to approved private-only use cases. **Persisted carrier**: existing `workspace_settings` row via `WorkspaceSetting` **Planned definition**: - `domain`: `ai` - `key`: `policy_mode` - `type`: `string` - `system_default`: `disabled` - `allowed values`: `disabled`, `private_only` - `scope`: workspace only; no tenant override in v1 **Validation rules**: - required - string - `in:disabled,private_only` **Authorization**: - view: existing `workspace_settings.view` - mutation: existing `workspace_settings.manage` **Audit strategy**: - reuse `workspace_setting.updated` and `workspace_setting.reset` - include AI-specific metadata in the existing workspace-settings audit context **State transitions**: - `disabled` -> `private_only` - `private_only` -> `disabled` ### AI Execution Control (`operational_control_activations` carrier) **Purpose**: Platform-owned runtime stop for new AI execution attempts. **Persisted carrier**: existing `OperationalControlActivation` **Planned definition**: - `control_key`: `ai.execution` - `label`: `AI execution` - `supported_scopes`: `global` - `affected_surfaces`: governed AI decision callers only **Behavior**: - a matching active control blocks new AI execution decisions before provider resolution - global pause is the required v1 incident path - workspace-specific pause or tenant-specific pause is out of scope for v1 and remains a follow-up concern if future incident handling genuinely requires it **State transitions**: - `enabled` -> `paused` - `paused` -> `enabled` ### AI Decision Audit (`audit_logs` carrier) **Purpose**: Stable record of governed AI allow/block evaluations without storing raw prompt or output content. **Persisted carrier**: existing `audit_logs` rows through `WorkspaceAuditLogger` / `AuditRecorder` **Planned action strategy**: - reuse existing workspace-setting actions for policy mutation - add one bounded AI decision action ID, e.g. `ai_execution.decision_evaluated`, for governed decision evaluations **Planned metadata**: - `use_case_key` - `decision_outcome` (`allowed` or `blocked`) - `decision_reason` - `workspace_ai_policy_mode` - `requested_provider_class` - `data_classifications` - `source_family` - `workspace_id` - optional `tenant_id` - optional `context_fingerprint` - optional `matched_operational_control_scope` **Explicit exclusions**: - raw prompt text - raw source payloads - raw provider payloads - full model output text ## Code-Owned Truth ### Approved AI Use Case Definition **Purpose**: Code-owned allowlist entry that defines one approved AI purpose and its trust constraints. **Fields**: - `key` - `future_consumer` - `visibility` - `allowed_provider_classes` - `allowed_data_classifications` - `source_family` - `tenant_context_permitted` **v1 catalog is locked to exactly two entries**: | Key | Future Consumer | Visibility | Allowed Provider Classes | Allowed Data Classifications | Source Family | Tenant Context Permitted | |---|---|---|---|---|---|---| | `product_knowledge.answer_draft` | `ContextualHelpResolver` and related code-owned knowledge sources | `internal_only_draft` | `local_private` | `product_knowledge`, `operational_metadata` | `product_knowledge` | no | | `support_diagnostics.summary_draft` | redacted summary derived from `SupportDiagnosticBundleBuilder` | `internal_only_draft` | `local_private` | `redacted_support_summary` | `support_diagnostics` | yes | **Validation rules**: - key must be registered in the catalog - no third use case may appear in v1 without a spec update - `external_public` is never allowed for these entries in v1 ### Provider Class **Purpose**: Vendor-neutral trust boundary for AI routing decisions. **Allowed values**: - `local_private` - `external_public` **Behavioral consequence**: - `external_public` is always blocked in v1 - `local_private` may be allowed only when the use case and data classifications permit it ### AI Data Classification **Purpose**: Declarative label that determines whether a data family may cross the governed AI boundary. **Values**: - `product_knowledge` - `operational_metadata` - `redacted_support_summary` - `personal_data` - `customer_confidential` - `raw_provider_payload` **Behavioral consequence**: - `personal_data`, `customer_confidential`, and `raw_provider_payload` are always blocked in v1 - allowed classifications vary by use case ## Request-Scoped Contracts ### AI Execution Request **Purpose**: In-process request envelope passed to the governed decision boundary before any provider resolution or model execution is attempted. **Fields**: - `workspace_id` - optional `tenant_id` - `actor_type` - `actor_id` - `use_case_key` - `requested_provider_class` - `data_classifications` (list) - `source_family` - optional `caller_surface` - optional `context_fingerprint` **Validation rules**: - `workspace_id` is required - `use_case_key` must be registered - `requested_provider_class` must be declared by the registered use case - every declared data classification must be allowed for the use case - host-surface authorization must already be resolved before evaluation **Important v1 boundary**: - the request is a preflight contract and does not need to carry raw prompt or payload text in v1 - future runtime/provider work can extend around this envelope later, but not inside this spec ### AI Execution Decision **Purpose**: Terminal allow/block result returned by the governed boundary. **Fields**: - `outcome` (`allowed` or `blocked`) - `reason_code` - `workspace_ai_policy_mode` - `matched_operational_control_scope` (nullable) - `use_case_key` - `requested_provider_class` - `data_classifications` - `source_family` - `audit_action` - `audit_metadata` **Behavioral consequence**: - `blocked`: provider resolution must not occur - `allowed`: returns an approved handoff envelope only; v1 still does not execute a provider call or create a persisted result ## State Transitions Summary ### Workspace AI Policy - `disabled` <-> `private_only` ### Operational Control - `enabled` <-> `paused` ### AI Execution Decision - `evaluating` -> `allowed` - `evaluating` -> `blocked` There is no queued, running, retrying, completed, or persisted-result lifecycle in v1.