TenantAtlas/specs/144-canonical-operation-viewer-context-decoupling/data-model.md
ahmido b0a724acef feat: harden canonical run viewer and onboarding draft state (#173)
## Summary
- harden the canonical operation run viewer so mismatched, missing, archived, onboarding, and selector-excluded tenant context no longer invalidates authorized canonical run viewing
- extend canonical route, header-context, deep-link, and presentation coverage for Spec 144 and add the full spec artifact set under `specs/144-canonical-operation-viewer-context-decoupling/`
- harden onboarding draft provider-connection resume logic so stale persisted provider connections fall back to the connect-provider step instead of resuming invalid state
- add architecture-audit follow-up candidate material and prompt assets for the next governance hardening wave

## Testing
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php tests/Feature/144/CanonicalOperationViewerDeepLinkTrustTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/OpsUx/OperateHubShellTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/RunAuthorizationTenantIsolationTest.php tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php tests/Feature/Monitoring/HeaderContextBarTest.php tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php tests/Unit/Onboarding/OnboardingDraftStageResolverTest.php tests/Unit/Onboarding/OnboardingLifecycleServiceTest.php`

## Notes
- branch: `144-canonical-operation-viewer-context-decoupling`
- base: `dev`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #173
2026-03-15 18:32:04 +00:00

4.2 KiB

Data Model: Canonical Operation Viewer Context Decoupling

Overview

This feature introduces no database schema changes. The design work is centered on clarifying how existing records and session state combine to produce canonical run-view behavior.

Core Entities

OperationRun

  • Ownership: Workspace-owned canonical monitoring record
  • Existing fields used by this feature:
    • id
    • workspace_id
    • tenant_id nullable
    • type
    • status
    • outcome
    • context
    • summary_counts
    • initiator_name
  • Relationships:
    • Belongs to workspace
    • Optionally belongs to tenant
    • Optionally belongs to user
  • Feature rule: Route legitimacy is derived from the run itself plus direct entitlement checks, not from remembered tenant context.

Tenant

  • Ownership: Workspace-owned durable record
  • Existing fields used by this feature:
    • id
    • workspace_id
    • name
    • external_id
    • lifecycle state as derived by the tenant operability and lifecycle presentation layer
  • Feature rule: A tenant linked to a run may be active, onboarding, archived, or otherwise non-selectable as current context and still remain a valid tenant reference for the canonical run viewer.

RememberedTenantContext

  • Ownership: Session-backed operator preference state
  • Existing sources used by this feature:
    • Current Filament tenant when present and entitled
    • Workspace remembered tenant when no entitled Filament tenant is present
  • Feature rule: This state may influence labels, back links, and optional information banners, but it never decides whether the canonical run exists or is viewable.

Derived Viewer State

The implementation should model a lightweight derived view state rather than adding persistence.

CanonicalRunViewerState

  • Inputs:
    • OperationRun $run
    • current workspace membership
    • direct tenant entitlement for $run->tenant_id when present
    • current remembered or selected header tenant context
  • Derived outputs:
    • authorization_outcome: allowed, deny-as-not-found, forbidden
    • run_tenant_state: tenantless, active, onboarding, archived, other non-selectable
    • header_context_state: no selected tenant, selected tenant matches run tenant, selected tenant differs from run tenant
    • banner_message: null or an informational message explaining mismatch or lifecycle framing
    • follow_up_affordance_state: available, partially available, unavailable because of lifecycle or entitlement

Authorization State Matrix

Run Exists Workspace Member Tenant Entitled Capability Granted Result
No N/A N/A N/A 404 not found
Yes No N/A N/A 404 deny-as-not-found
Yes Yes No for linked tenant N/A 404 deny-as-not-found
Yes Yes Yes or tenantless No when capability is required 403 forbidden
Yes Yes Yes or tenantless Yes or no capability required Render viewer

Presentation State Matrix

Run Tenant Header Tenant Context Viewer Valid Expected Messaging
Tenantless None Yes Workspace-level framing only
Tenantless Selected tenant present Yes Optional note that run is workspace-level and not tied to the selected tenant
Active tenant Matching selected tenant Yes No mismatch banner required
Active tenant Different selected tenant Yes Non-blocking mismatch message
Onboarding or archived tenant None Yes Lifecycle-aware canonical workspace framing
Onboarding or archived tenant Different selected tenant Yes Lifecycle-aware mismatch message

Validation Rules

  • A run with workspace_id <= 0 remains invalid and is denied as not found.
  • A tenant-linked run must never reveal tenant-linked details to an actor who lacks entitlement to that tenant.
  • A tenantless run must remain viewable based on workspace access and any resolved capability requirement for the run type.
  • Remembered tenant context must never be mutated as a side effect of viewing a canonical run.

No Schema Change Confirmation

  • No new tables
  • No new columns
  • No new indexes
  • No data backfill
  • No migration work required