# Data Model — Support Diagnostic Pack **Spec**: [spec.md](spec.md) No new persistent tables are required for the first support-diagnostics slice. The bundle is computed at request time from existing canonical records. ## Existing Canonical Entities Reused ### Workspace (`workspaces`) **Purpose**: Primary admin-plane isolation boundary and audit scope for every support-diagnostic bundle. **Key fields (existing)**: - `id` - `name` **Bundle use**: - Supplies the workspace scope label. - Anchors workspace-membership checks. - Owns audit-log scope for bundle-open activity. ### Tenant (`tenants`) **Purpose**: Tenant-plane scope boundary and the canonical subject for tenant-context support diagnostics. **Key fields (existing)**: - `id` - `workspace_id` - `external_id` - `name` - `status` **Bundle use**: - Acts as the primary subject for tenant-context bundles. - Supplies tenant identity and tenant authorization scope. ### OperationRun (`operation_runs`) **Purpose**: Canonical execution truth and the primary subject for operation-context support diagnostics. **Key fields (existing)**: - `id` - `workspace_id` - `tenant_id` (nullable) - `type` - `status` - `outcome` - `summary_counts` - `context` - `started_at` - `completed_at` **Relationships (existing)**: - `tenant()` - `workspace()` - `user()` **Bundle use**: - Supplies the primary execution summary. - Carries run-bound reference ids such as `provider_connection_id` and artifact references in `context`. - Reuses existing humanized run explanation and canonical run URLs. ### ProviderConnection (`provider_connections`) **Purpose**: Canonical provider readiness and connection state for the tenant or run context. **Key fields (existing)**: - `id` - `workspace_id` - `tenant_id` - `provider` - `connection_type` - `consent_status` - `verification_status` - `last_error_reason_code` - `last_error_message` - `is_default` - `is_enabled` - `last_health_check_at` **Relationships (existing)**: - `tenant()` - `workspace()` - `credential()` **Bundle use**: - Supplies provider readiness summary, translated provider failure reasons, and target-scope detail. - Never contributes raw credential payloads or secrets to the bundle. ### Finding (`findings`) **Purpose**: Canonical drift or permission posture issues that may explain current support pressure. **Key fields (existing)**: - `id` - `workspace_id` - `tenant_id` - `type` - `severity` - `status` - `baseline_operation_run_id` - `current_operation_run_id` - `due_at` - `last_seen_at` **Relationships (existing)**: - `tenant()` - `baselineRun()` - `currentRun()` - `findingException()` **Bundle use**: - Supplies prioritized open or recent findings relevant to the current tenant or run. - Contributes summary and freshness cues only; finding detail remains on canonical pages. ### StoredReport (`stored_reports`) **Purpose**: Canonical report/evidence truth for report identity and freshness. **Key fields (existing)**: - `id` - `workspace_id` - `tenant_id` - `report_type` - `fingerprint` - `previous_fingerprint` - `payload` **Relationships (existing)**: - `workspace()` - `tenant()` **Bundle use**: - Supplies report identity, report type, and freshness/continuity cues. - The bundle must not expose the full stored report payload by default. ### TenantReview (`tenant_reviews`) **Purpose**: Canonical tenant review state and review-level summary for governance follow-up. **Key fields (existing)**: - `id` - `workspace_id` - `tenant_id` - `operation_run_id` - `status` - `completeness_state` - `summary` - `generated_at` - `current_export_review_pack_id` **Relationships (existing)**: - `workspace()` - `tenant()` - `operationRun()` - `reviewPacks()` **Bundle use**: - Supplies current review status, completeness, blockers, and canonical review references when review truth is relevant. ### ReviewPack (`review_packs`) **Purpose**: Canonical review export/package truth when a tenant review already has a pack. **Key fields (existing)**: - `id` - `workspace_id` - `tenant_id` - `operation_run_id` - `tenant_review_id` - `status` - `summary` - `generated_at` - `expires_at` - `file_size` **Relationships (existing)**: - `workspace()` - `tenant()` - `operationRun()` - `tenantReview()` **Bundle use**: - Supplies pack availability, readiness, and expiry cues. - The bundle links to the canonical pack viewer instead of reproducing pack content. ### AuditLog (`audit_logs`) **Purpose**: Canonical audit trail for workspace-, tenant-, and operation-related events. **Key fields (existing)**: - `id` - `workspace_id` - `tenant_id` - `action` - `resource_type` - `resource_id` - `target_label` - `metadata` - `outcome` - `operation_run_id` - `recorded_at` **Relationships (existing)**: - `tenant()` - `workspace()` - `operationRun()` **Bundle use**: - Supplies the most relevant authorized audit references for the current tenant or run. - Also records bundle-open activity with redacted metadata only. ## Derived Runtime Entities ### SupportDiagnosticBundle (computed, not persisted) **Purpose**: One machine-readable, redacted support-safe envelope for either a tenant context or an operation-run context. **Proposed shape (runtime array / view-model)**: - `context_type` — `tenant` or `operation_run` - `workspace` — workspace reference and label - `tenant` — tenant reference when applicable - `operation_run` — primary run reference when applicable - `headline` — dominant support summary - `dominant_issue` — translated blocker or issue statement - `freshness_state` — derived cue such as `fresh`, `stale`, `mixed`, or `missing_context` - `redaction_mode` — fixed first-slice mode: default-redacted - `sections` — ordered list of section payloads - `notes` — explicit redaction, completeness, or degradation notes **Relationships**: - 1 workspace - 0..1 tenant - 0..1 primary operation run - 0..1 provider connection section - 0..n finding references - 0..n stored report references - 0..1 tenant review reference - 0..1 review pack reference - 0..n audit references ### SupportDiagnosticSection (computed, not persisted) **Purpose**: One deterministic section inside the bundle. **Proposed shape**: - `key` — fixed section key such as `provider_connection`, `operation_context`, `findings`, `stored_reports`, `tenant_review`, `review_pack`, `audit_history` - `label` - `availability` — derived local status (`available`, `missing`, `stale`, `inaccessible`, `redacted`) - `summary` - `freshness_at` or `freshness_note` - `references` — ordered support references for that section - `redaction_markers` — explicit markers when detail is intentionally excluded **Note**: these are presentation-contract values only, not new persisted domain state. ### SupportDiagnosticReference (computed, not persisted) **Purpose**: Stable canonical link/reference metadata for one related record. **Proposed shape**: - `type` — `tenant`, `operation_run`, `provider_connection`, `finding`, `stored_report`, `tenant_review`, `review_pack`, or `audit_log` - `record_id` - `label` - `action_label` - `url` (nullable when inaccessible or no viewer exists) - `availability` - `freshness_note` (nullable) - `access_reason` or `missing_reason` (nullable) ### RedactionMarker (computed, not persisted) **Purpose**: Make exclusion deterministic and explicit. **Proposed shape**: - `path` (nullable) - `reason` — `secret`, `credential`, `raw_payload`, `restricted_log_excerpt`, or `inaccessible_record` - `replacement_text` ## Derived Rules and Validation - Bundle generation requires established workspace membership first. - Tenant-context bundle generation requires tenant entitlement before any tenant-owned section resolves. - Operation-context bundle generation must first pass `OperationRunPolicy::view(...)`; if the run points at a tenant, tenant entitlement still applies before tenant-owned related records resolve. - After membership/entitlement is established, missing `support_diagnostics.view` is a `403` capability denial. - The bundle must never include secrets, tokens, credentials, unrestricted provider response bodies, or unrestricted stored-report payloads. - Missing or inaccessible related records must degrade into explicit placeholders or unavailable references, not hard-fail the whole bundle. - For unchanged authorized input, section order, reference order, and redaction output must remain stable. ## Lifecycle and Audit Behavior - `SupportDiagnosticBundle` has no persisted lifecycle. - Opening the bundle writes one audit event with redacted metadata only. - Opening linked canonical records follows their own existing authorization and audit behavior.