TenantAtlas/specs/149-queued-execution-reauthorization/data-model.md
ahmido 5bcb4f6ab8 feat: harden queued execution legitimacy (#179)
## Summary
- add a canonical queued execution legitimacy contract for actor-bound and system-authority operation runs
- enforce legitimacy before queued jobs transition runs to running across provider, inventory, restore, bulk, sync, and scheduled backup flows
- surface blocked execution outcomes consistently in Monitoring, notifications, audit data, and the tenantless operation viewer
- add Spec 149 artifacts and focused Pest coverage for legitimacy decisions, middleware ordering, blocked presentation, retry behavior, and cross-family adoption

## Testing
- vendor/bin/sail artisan test --compact tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/QueuedExecutionMiddlewareOrderingTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Verification/ProviderExecutionReauthorizationTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/RunInventorySyncExecutionReauthorizationTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/ExecuteRestoreRunExecutionReauthorizationTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/SystemRunBlockedExecutionNotificationTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/BulkOperationExecutionReauthorizationTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/QueuedExecutionRetryReauthorizationTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/QueuedExecutionContractMatrixTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/QueuedExecutionAuditTrailTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Operations/TenantlessOperationRunViewerTest.php
- vendor/bin/sail bin pint --dirty --format agent

## Manual validation
- validated queued provider execution blocking for tenant operability drift in the integrated browser on /admin/operations and /admin/operations/{run}
- validated 404 vs 403 route behavior for non-membership vs in-scope capability denial
- validated initiator-null blocked system-run behavior without creating a user terminal notification

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #179
2026-03-17 21:52:40 +00:00

7.3 KiB

Phase 1 Data Model: Queued Execution Reauthorization and Scope Continuity

Overview

This feature does not require a new database table in its first implementation slice. The data-model work is the formalization of existing persisted records plus new derived support-layer objects that express queued execution legitimacy consistently across job families.

Persistent Domain Entities

OperationRun

Purpose: Canonical workspace-owned observability record for queued tenant-affecting work.

Key fields:

  • id
  • workspace_id
  • tenant_id nullable for workspace-scoped runs
  • user_id nullable for scheduled or system runs
  • initiator_name
  • type
  • status
  • outcome
  • run_identity_hash
  • context
  • summary_counts
  • failure_summary

Relationships:

  • Belongs to one workspace
  • May belong to one tenant
  • May belong to one human initiator

Validation rules relevant to this feature:

  • workspace_id and tenant_id must remain authoritative for scope continuity checks.
  • status and outcome remain service-owned through OperationRunService.
  • context may gain additional execution-authority metadata, but it must remain sanitized and serializable.

State transitions relevant to this feature:

  • queuedrunning only after legitimacy passes
  • queued → terminal status with blocked outcome when execution is refused before work begins, using the canonical OperationRunService transition path
  • retry attempts re-evaluate legitimacy from the current state, not from the original queued truth

Tenant

Purpose: Tenant-owned execution target whose current scope, entitlement, and operability determine whether queued work may begin.

Key fields:

  • id
  • workspace_id
  • lifecycle or operability-related state already consumed by TenantOperabilityService
  • provider and RBAC-health fields already used by hardening gates

Relationships:

  • Belongs to one workspace
  • Has many provider connections, restore runs, inventory records, and operation runs

Validation rules relevant to this feature:

  • Must still belong to the expected workspace when the job starts
  • Must remain entitled and operable for the requested execution class

User

Purpose: Human initiator for actor-bound queued runs.

Key fields:

  • id
  • membership and role relationships already used by capability resolution

Relationships:

  • May initiate many OperationRun records
  • May or may not still be entitled to the tenant when execution starts

Validation rules relevant to this feature:

  • Actor-bound execution must re-check current workspace membership, tenant membership, and required capability

ProviderConnection

Purpose: Provider-backed execution prerequisite for queued provider operations.

Key fields:

  • id
  • tenant_id
  • provider
  • status
  • consent_status
  • verification_status
  • entra_tenant_id

Relationships:

  • Belongs to one tenant
  • May be referenced in OperationRun.context

Validation rules relevant to this feature:

  • Provider-backed jobs must re-check that the connection still matches tenant scope and is still valid before execution side effects occur

New Derived Domain Objects

ExecutionAuthorityMode

Purpose: Declares whose authority the queued job is executing under.

Canonical values:

  • actor_bound
  • system_authority

Behavior:

  • actor_bound requires current actor membership, entitlement, and capability checks at execution time
  • system_authority requires current tenant operability plus explicit system-allowed execution semantics, but not a human capability check
  • system_authority is valid only when the operation type appears in the canonical system-execution allowlist owned by the execution legitimacy gate and sourced from trusted scheduler or system entry paths

QueuedExecutionContext

Purpose: Normalized evaluation input for execution-time legitimacy.

Fields:

  • run
  • operationType
  • workspaceId
  • tenant nullable
  • initiator nullable
  • authorityMode
  • requiredCapability nullable
  • providerConnectionId nullable
  • targetScope structured payload with nullable tenant- or provider-level members when not applicable
  • prerequisiteClass nullable or list-based

Validation rules:

  • workspaceId must match the resolved workspace of the run and target tenant
  • actor-bound context requires an initiator reference or a safe failure path
  • target-scope metadata may inform evaluation, but authoritative truth is always re-resolved from current records

QueuedExecutionLegitimacyDecision

Purpose: Structured answer to whether queued work may begin.

Contract note:

  • The internal PHP DTO may use camelCase property names, but when serialized into OperationRun.context, failure payloads, or contract fixtures it must map directly to the schema-defined snake_case contract in contracts/execution-legitimacy.schema.json.

Fields:

  • operationType
  • allowed
  • authorityMode
  • initiator nullable
  • targetScope
  • checks
  • denialClass nullable
  • reasonCode nullable
  • retryable
  • metadata

Behavior:

  • allowed=false means the job must not produce side effects
  • targetScope is always present, with nullable tenant- or provider-level members when a narrower target is not applicable
  • checks always records the canonical evaluation results for workspace scope, tenant scope, capability, tenant operability, and execution prerequisites
  • retryable is decided centrally by denial class: scope_denied, capability_denied, and initiator_invalid are terminal; tenant_not_operable and prerequisite_invalid are retryable and must be re-evaluated fresh on each attempt
  • metadata may carry safe hints for audit or Monitoring detail views

ExecutionDenialClass

Purpose: High-level category of why execution was refused.

Canonical values:

  • scope_denied
  • capability_denied
  • tenant_not_operable
  • prerequisite_invalid
  • initiator_invalid

ExecutionDenialReasonCode

Purpose: Stable reason-code vocabulary for execution-time refusal.

Initial values:

  • workspace_mismatch
  • tenant_not_entitled
  • missing_capability
  • tenant_not_operable
  • tenant_missing
  • initiator_missing
  • initiator_not_entitled
  • provider_connection_invalid
  • write_gate_blocked
  • execution_prerequisite_invalid

Consumer Mapping

Consumer Primary execution concern
Queue middleware before run start Evaluate legitimacy before running transition
ProviderOperationStartGate adopters Preserve dispatch-time gate and add execution recheck
Restore or write jobs Reuse write-hardening semantics inside canonical execution contract
Inventory or sync jobs Re-check actor-bound scope and tenant operability before local mutation work
Bulk orchestrator and worker jobs Re-check legitimacy on orchestrator start and retry paths
Monitoring run detail Render blocked execution reasons distinctly from generic failure

Migration Notes

  • No persistence migration is required for the first slice.
  • New authority metadata can live in OperationRun.context and sanitized failure payloads.
  • Existing provider-blocked reason handling can be reused rather than replaced.
  • Existing TrackOperationRun behavior will likely become an adapter over the new legitimacy-first flow rather than remain the earliest middleware in the chain.