TenantAtlas/specs/394-provider-freshness-permission-semantics/spec.md
ahmido a6c064cbf1 feat: improve provider readiness semantics and freshness guidance (#465)
Automated PR created by Codex via Gitea API.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #465
2026-06-21 17:20:10 +00:00

51 KiB

Feature Specification: Spec 394 - Provider Freshness & Permission Semantics v1

Feature Branch: 394-provider-freshness-permission-semantics Created: 2026-06-21 Status: Draft / Ready for implementation preparation review Type: Bugfix / correctness / trust boundary / productization Priority: P1 Runtime posture: Clean canonical replacement over existing provider freshness, provider readiness, verification, and required-permission count behavior. No legacy compatibility shim, no parallel provider health truth, no new provider integration, and no UI expansion. Input: User-provided full Spec 394 draft plus repo truth from provider connections, required permissions, verification, provider capability, environment dashboard, workspace overview, governance inbox, restore/review readiness, and related completed specs.

Dependencies And Historical Context

Spec 394 is a correctness follow-up over existing provider scope, capability, verification, guidance, and readiness work:

  • Spec 281 - Provider Connection Scope, completed/historical provider target-scope foundation.
  • Spec 283 - Provider Capability Registry, implemented provider capability vocabulary and evaluator context.
  • Spec 294 - Provider Verification Runtime Semantics Stabilization, completed provider/verification runtime context.
  • Spec 339 - Provider Connection Scope Hardening, completed provider authority-source guardrails.
  • Spec 353 - Provider Connections Resolution Guidance v1, implemented guidance hierarchy over existing provider truth.
  • Spec 381 - Provider Resource Identity and Binding Foundation v1, completed provider-resource binding context, not modified by this spec.
  • Spec 385 - Evidence and review readiness integration, completed downstream readiness context.
  • Spec 390 - Restore readiness resolution adapter, prepared/runtime context for restore readiness consumers.
  • Spec 393 - Evidence anchor reconciliation, adjacent trust-boundary cleanup pattern.

Repo-truth observations that shape this spec:

  • ProviderConnection stores verification_status, last_health_check_at, consent_status, is_enabled, scope fields, and provider identity metadata.
  • ManagedEnvironmentPermission stores permission rows with managed_environment_id, workspace_id, permission_key, status, details, and last_checked_at.
  • ManagedEnvironmentPermissionService compares configured required permissions against stored or live evidence but currently keys granted rows by permission key for one environment and does not expose a canonical provider-connection or verification-batch result.
  • ManagedEnvironmentRequiredPermissionsViewModelBuilder currently derives present, missing_application, missing_delegated, error, and freshness from permission row timestamps. Its filters still include the legacy present label.
  • ProviderConnectionSurfaceSummary maps ProviderVerificationStatus::Healthy directly to Ready, independent from permission freshness and required permission coverage.
  • ProviderCapabilityEvaluator blocks missing/error/stale permission evidence but is not the one canonical readiness and count contract for all product surfaces.
  • ProviderReadinessResolutionAdapter already detects stale health checks and stale permission snapshots for guidance cards, but this behavior is not the single source used by all provider health, table, badge, count, and downstream readiness consumers.
  • Provider UI guidance from Spec 353 is intentionally a bounded guidance layer over existing truth. Spec 394 must replace inconsistent truth calculations, not add a second visible guidance layer.

Spec Candidate Check (mandatory - SPEC-GATE-001)

  • Problem: Provider readiness is a trust boundary, but current provider surfaces can derive health, freshness, required permission counts, and readiness from different local sources.
  • Today's failure: Required Permissions can show ambiguous counts such as Present 0 while granted permission rows exist, and Provider Connections can show Healthy or Ready from verification_status=healthy even when verification evidence or permission evidence is stale.
  • User-visible improvement: Operators see one truthful provider state across Provider Connections, Required Permissions, Environment Dashboard, Workspace Overview, Governance Inbox, and downstream readiness surfaces. Stale, failed, unknown, missing, wrong-scope, or blocked provider evidence never appears as Healthy or Ready.
  • Smallest enterprise-capable version: Consolidate provider readiness, verification freshness, permission coverage, row state, count semantics, recommended action, and capability-aware action visibility into one canonical resolver contract. Replace local visible health/readiness/count paths on affected existing surfaces. Add focused tests and one bounded browser smoke.
  • Explicit non-goals: No new provider integration, no OAuth redesign, no new onboarding wizard, no new dashboard/card/page, no new raw evidence panel, no customer-facing provider internals, no broad Product Surface Contract Enforcement pass, no restore/review adapter rebuild beyond preventing direct provider surfaces from lying.
  • Permanent complexity imported: One canonical resolver/result contract, a derived provider-readiness state family, explicit required-permission row/count vocabulary, focused Unit/Feature/Filament/Browser tests, and artifact/reporting obligations. No new table is expected by default.
  • Why now: Provider readiness now feeds evidence capture, review readiness, restore readiness, governance checks, and customer-safe outputs. False readiness is a direct trust failure, not a cosmetic label issue.
  • Why not local: ProviderConnectionSurfaceSummary, ManagedEnvironmentRequiredPermissionsViewModelBuilder, ProviderCapabilityEvaluator, ProviderReadinessResolutionAdapter, dashboard builders, and tests already encode overlapping provider truth. Page-local fixes would preserve drift and allow stale verification to become Healthy elsewhere.
  • Approval class: Core Enterprise.
  • Red flags triggered: New resolver abstraction, provider state vocabulary, multiple surfaces, and canonical semantics. Defense: the resolver replaces existing parallel truth for a security/trust boundary, has multiple real consumers now, remains derived unless existing schema cannot represent the contract, and explicitly forbids UI expansion and compatibility shims.
  • Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
  • Decision: approve.

Candidate Source And Completed-Spec Guardrail

  • Selected candidate: Provider Freshness & Permission Semantics v1.
  • Source location: Direct user-provided Spec 394 draft in this conversation. Roadmap relationship is the manual-promotion lane Provider readiness and onboarding productization in docs/product/roadmap.md and docs/product/spec-candidates.md.
  • Why selected: The active auto-prep queue is empty, but the user explicitly provided a numbered manual candidate. Repo inspection confirms visible drift in provider readiness/count/freshness seams.
  • Close alternatives deferred:
    • Provider onboarding redesign: deferred because this spec must fix truth before adding setup flows.
    • Secondary-action density cleanup from Spec 353: deferred because this spec is correctness, not action-density polish.
    • Cross-domain indicator runtime follow-through: deferred because this spec is provider-specific readiness truth.
    • Governance artifact lifecycle/retention runtime: unrelated trust lane.
    • Product Surface Contract Enforcement pass: broader later pass, not needed to fix provider readiness truth.
  • Completed-spec check:
    • No specs/394-* package existed before this preparation.
    • Specs 281, 283, 294, 339, 353, and 381 contain completed-task, implementation, review, close-out, or smoke-history signals and are read-only historical context.
    • Spec 353 guidance surfaces and UI audit artifacts must not be rewritten into preparation state. Spec 394 may require follow-up updates only if implementation materially changes visible UI behavior.
  • Smallest viable implementation slice: Existing provider readiness/health/count consumers only: Provider Connections, Required Permissions, Environment Dashboard provider area, Workspace Overview provider signals, Governance Inbox provider-related items if present, and direct provider-blocking summaries used by restore/evidence/review readiness.
  • Gate result: PASS. The candidate is user-provided, unprepared, not completed, roadmap-aligned, and narrowed to a bounded trust-boundary correction.

Spec Scope Fields (mandatory)

  • Scope: workspace-owned provider connection plus managed-environment permission/readiness scope.
  • Primary Routes / Surfaces:
    • /admin/provider-connections
    • /admin/provider-connections/{record}
    • /admin/provider-connections/{record}/edit
    • /admin/workspaces/{workspace}/environments/{environment}/required-permissions
    • /admin/workspaces/{workspace}/environments/{environment}
    • /admin Workspace Overview provider/readiness signals where repo-real
    • Governance Inbox provider-related rows where repo-real
    • Restore, evidence, review, and report readiness summaries only where they directly consume provider health/readiness state
  • Data Ownership:
    • ProviderConnection remains workspace-owned and managed-environment-linked.
    • ManagedEnvironmentPermission remains managed-environment-owned permission evidence with workspace scope.
    • Provider verification remains represented by existing provider connection fields, OperationRun verification reports, and permission row timestamps unless implementation proves a minimal clean schema change is necessary.
    • Provider account/context for v1 is the current ProviderConnection identity: provider connection ID, workspace ID, managed environment ID, provider key, persisted provider identity metadata already stored on the connection, and verification OperationRun context that references the same provider connection. A grant without an exact current provider connection, managed environment, workspace, and provider-key match cannot satisfy a required permission.
    • No new persisted truth is expected by default. Any schema change must be clean, pre-production, reversible where practical, and justified in updated spec/plan before implementation.
  • RBAC:
    • Workspace membership and managed-environment entitlement are required before any provider readiness result or route is exposed.
    • Product-safe readiness summaries require view capability.
    • Provider-changing actions such as verify, reconnect, refresh grants, repair permissions, or admin consent require existing provider management/run capabilities.
    • Technical detail requires an existing technical capability if present; otherwise use the stricter provider management capability.
    • Non-member or wrong workspace/environment remains deny-as-not-found. Member without capability remains 403 or disabled/hidden per existing UI enforcement.

For canonical-view or mixed-scope specs:

  • Default filter behavior when environment-context is active: Provider readiness must be resolved for the explicit workspace/environment/provider connection context. Workspace-wide summaries may aggregate only actor-authorized environments and must not pick wrong-scope grants.
  • Explicit entitlement checks preventing cross-tenant leakage: Resolver methods must scope by workspace, managed environment, provider connection, provider key, and actor entitlement before resolving grants, rows, links, or actions. Wrong-scope grants must not satisfy current required permissions.
  • Provider account/context stop condition: If implementation discovers a required permission cannot be safely reconciled from the current ProviderConnection identity, managed-environment scope, provider key, and verification context, stop and update spec/plan before adding a separate provider-account identifier or schema.

Canonical Provider Readiness Contract

The implementation must create or consolidate one resolver/service with behavior equivalent to:

ProviderReadinessResolver::forWorkspace($workspace, ?User $actor)
ProviderReadinessResolver::forEnvironment($environment, ?User $actor)
ProviderReadinessResolver::forProviderConnection($providerConnection, ?User $actor)
ProviderReadinessResolver::requiredPermissions($providerConnection, $scope, ?User $actor)
ProviderReadinessResolver::freshness($providerConnection, ?User $actor)

Exact class and method names may differ if repo ownership points to a better namespace. The product-facing decision must still be one canonical contract consumed by affected surfaces.

Resolver result fields:

provider_connection_id
scope_type
scope_id
readiness_state
connection_state
verification_state
verification_checked_at nullable
verification_expires_at nullable
is_verification_fresh
required_count
granted_required_count
missing_required_count
blocked_required_count
expired_required_count
unknown_required_count
not_applicable_count
permission_rows[]
primary_reason
blocking_reasons[]
recommended_action
can_view_technical_detail
can_manage_provider
child_results[] nullable for workspace/environment aggregate entry points

Entry-point result shape:

  • forProviderConnection(...), requiredPermissions(...), and freshness(...) return one provider-scoped resolver result.
  • forEnvironment(...) returns one aggregate result with scope_type=environment, provider_connection_id=null when multiple provider connections are represented, and child_results[] containing provider-scoped resolver results for actor-authorized provider connections in that environment.
  • forWorkspace(...) returns one aggregate result with scope_type=workspace, provider_connection_id=null, and child_results[] containing environment/provider-scoped results for actor-authorized environments and provider connections in that workspace.
  • Aggregate readiness uses the same state precedence as provider-scoped readiness, sums canonical count fields from child results, and takes the recommended action from the highest-severity child blocker. Product surfaces must not hand-roll workspace or environment aggregation from raw permission rows.

Each permission row fields:

permission_key
product_label
provider_permission_name nullable
state
required_for
is_required
is_effective
matched_grant_id nullable
last_verified_at nullable
reason
recommended_action nullable
is_technical_only

Canonical Product States

Provider-facing product states:

  • Ready
  • Needs attention
  • Blocked
  • Not configured
  • Expired
  • Failed
  • Unknown

Provider readiness mapping:

  • Provider connected + verification fresh + all required permissions effective -> Ready
  • Provider connected + permissions partially missing -> Needs attention
  • Provider connected + required permissions blocked or admin consent denied -> Blocked
  • Provider missing or disconnected -> Not configured
  • Verification stale -> Expired
  • Verification failed -> Failed
  • Insufficient data -> Unknown

Individual required permission row states:

  • Granted
  • Missing
  • Blocked
  • Expired
  • Unknown
  • Not applicable

Row mapping:

  • Fresh matching grant exists -> Granted
  • No matching grant -> Missing
  • Provider denies or admin consent blocked -> Blocked
  • Matching grant exists but verification is stale -> Expired
  • Insufficient verification data -> Unknown
  • Permission not required in this scope -> Not applicable

Required permission counts:

required_count
granted_required_count
missing_required_count
blocked_required_count
expired_required_count
unknown_required_count
not_applicable_count

Invariant:

required_count =
  granted_required_count
+ missing_required_count
+ blocked_required_count
+ expired_required_count
+ unknown_required_count

not_applicable_count is outside required_count unless a later spec explicitly changes that product contract.

Forbidden ambiguous product-facing count labels:

  • Present
  • Present 0
  • OK count
  • Permission count
  • Granted rows
  • Raw grants

These terms may remain only in internal technical notes when clearly defined and not shown as default product UI.

Functional Requirements

  • FR-394-001: Any visible provider health/readiness state must be derived from the canonical resolver. Legacy helpers must delegate to it or be removed.
  • FR-394-002: Stale provider verification must never render as Healthy, Ready, Current, or OK.
  • FR-394-003: Connected/configured provider state must not be treated as provider readiness.
  • FR-394-004: Required permission summary counts and row states must come from the same resolver result.
  • FR-394-005: A grant is effective only when it matches the current workspace, managed environment, provider connection, provider account/context represented by the current provider connection identity, provider namespace, required permission, and fresh verification basis.
  • FR-394-006: Permission evidence from stale verification must not satisfy current required permissions. It may appear only as technical/historical detail when authorized.
  • FR-394-007: Unknown permission state fails closed as Unknown, Needs attention, or a non-ready equivalent.
  • FR-394-008: Missing permissions must produce actionable product copy and a truthful next action such as review required permissions, verify provider, reconnect provider, request admin consent, or open provider connection.
  • FR-394-009: Provider readiness consumers in provider connections, required permissions, environment/workspace readiness, governance inbox, and direct downstream readiness summaries must use the canonical resolver or be documented as an explicit remaining local path with reason and follow-up.
  • FR-394-010: Default product UI must not expose raw provider payloads, raw permission JSON, opaque provider IDs, grant object IDs, token details, verification payloads, Graph/API dumps, or internal job/run IDs.
  • FR-394-011: Default permission labels must explain product purpose first. Raw provider permission names may appear only as secondary technical detail where authorized.
  • FR-394-012: Resolver output must be deterministic. Multiple matching grants must use explicit ordering: correct scope, fresh verification batch, non-revoked grant, most recent verification timestamp, deterministic ID tie-breaker.
  • FR-394-013: Provider-changing actions must require existing management/run capability. View-only users may view product-safe summaries when authorized but cannot execute provider-changing actions.
  • FR-394-014: Downstream readiness surfaces that depend on provider access must not override provider blockers from stale, failed, unknown, or missing provider state.
  • FR-394-015: Old tests, fixtures, labels, translation keys, query ordering, action keys, and fallback logic preserving misleading provider health or Present 0 behavior must be removed or updated.

UX Requirements

Provider Connection summary should show:

  • Provider
  • Connection state
  • Verification state
  • Last verified at
  • Required permissions state
  • At most one primary action

Required Permissions should show canonical counts such as:

Required permissions: 8
Granted: 6
Missing: 2
Expired: 0

Rows should show:

  • Permission purpose
  • State
  • Required for
  • Last verified
  • Next action

Stale provider copy:

Provider verification expired.
Verify this provider to refresh permission status.
Required permissions cannot be trusted until verification is current.

Missing permission copy:

Required permission missing.
Admin consent is required.
Provider access needs attention.

Allowed primary actions by state:

  • Ready -> View provider
  • Needs attention -> Review required permissions
  • Expired -> Verify provider
  • Failed -> Review provider error
  • Not configured -> Connect provider
  • Blocked -> Resolve provider blocker
  • Unknown -> Check provider status

This spec must reduce or preserve visible complexity. Wrong labels/states are replaced, not duplicated.

UI Surface Impact (mandatory - UI-COV-001)

Does this spec add, remove, rename, or materially change any reachable UI surface?

  • No UI surface impact
  • Existing page changed
  • New page/route added
  • Navigation changed
  • Filament panel/provider surface changed
  • New modal/drawer/wizard/action added
  • New table/form/state added
  • Customer-facing surface changed
  • Dangerous action changed
  • Status/evidence/review presentation changed
  • Workspace/environment context presentation changed

UI/Productization Coverage

  • Route/page/surface:
    • Provider Connections list/view/edit
    • Environment Required Permissions
    • Environment Dashboard provider area
    • Workspace Overview provider/readiness signals where repo-real
    • Governance Inbox provider-related items where repo-real
    • Direct restore/evidence/review readiness summaries where provider state is consumed
  • Current or new page archetype:
    • Provider Connections: existing Provider / Integration Strategic Surface from ui-009-provider-connections.md
    • Required Permissions: existing Provider / Integration Domain Pattern Surface from ui-077-required-permissions.md
    • Environment Dashboard and Workspace Overview: existing operator overview surfaces
    • Governance Inbox: existing operator decision queue
  • Design depth: Domain Pattern Surface / Strategic Surface follow-through over existing surfaces.
  • Repo-truth level: repo-verified.
  • Existing pattern reused: Spec 353 provider readiness guidance card, existing Filament resource/page surfaces, existing BadgeCatalog/BadgeRenderer, existing UiEnforcement/WorkspaceUiEnforcement, existing OperationRun start UX for verification.
  • New pattern required: one canonical provider readiness resolver/result contract; no new dashboard, no new onboarding wizard, no new raw technical table.
  • Screenshot required: yes for focused browser smoke only if visible labels/counts/actions change, likely under specs/394-provider-freshness-permission-semantics/artifacts/screenshots/.
  • Page audit required: update existing page reports only if visible page behavior materially changes:
    • docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md
    • docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md
    • dashboard/workspace/governance page reports only if implementation materially changes default-visible provider/readiness behavior there
  • Customer-safe review required: no direct customer-facing provider detail is added; downstream customer-safe readiness must not expose raw provider data.
  • Dangerous-action review required: yes for provider-changing actions already present. They must remain capability-gated and confirmation/audit-safe where high-impact.
  • Coverage files updated or explicitly not needed:
    • docs/ui-ux-enterprise-audit/route-inventory.md
    • docs/ui-ux-enterprise-audit/design-coverage-matrix.md
    • docs/ui-ux-enterprise-audit/page-reports/...
    • docs/ui-ux-enterprise-audit/strategic-surfaces.md
    • docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md
    • docs/ui-ux-enterprise-audit/unresolved-pages.md
    • N/A - no reachable UI surface impact
  • No-impact rationale when applicable: N/A. Existing surfaces are materially changed because labels, states, counts, and primary actions may change.

Cross-Cutting / Shared Pattern Reuse

  • Cross-cutting feature?: yes.
  • Interaction class(es): status messaging, action links, dashboard signals, readiness summaries, provider guidance, permission rows/counts, support/technical disclosure, OperationRun verification links.
  • Systems touched:
    • App\Support\Providers\TargetScope\ProviderConnectionSurfaceSummary
    • App\Support\ResolutionGuidance\Adapters\ProviderReadinessResolutionAdapter
    • App\Services\Intune\ManagedEnvironmentRequiredPermissionsViewModelBuilder
    • App\Services\Intune\ManagedEnvironmentPermissionService
    • App\Support\Providers\Capabilities\ProviderCapabilityEvaluator
    • App\Filament\Resources\ProviderConnectionResource
    • App\Filament\Pages\EnvironmentRequiredPermissions
    • App\Support\EnvironmentDashboard\EnvironmentDashboardSummaryBuilder
    • App\Support\Workspaces\WorkspaceOverviewBuilder
    • App\Support\GovernanceInbox\GovernanceInboxSectionBuilder
    • existing restore/evidence/review readiness adapters where provider state is consumed
  • Existing pattern(s) to extend: Spec 353 readiness guidance hierarchy, existing capability evaluator, existing provider connection scope hardening rules, existing OperationRun verification start path, existing badge catalog.
  • Shared contract / presenter / builder / renderer to reuse: Existing BadgeCatalog/BadgeRenderer, ProviderOperationStartResultPresenter, OperationRunLinks, RequiredPermissionsLinks, UiEnforcement/WorkspaceUiEnforcement, and provider capability registry/evaluator where they remain the correct input.
  • Why the existing shared path is sufficient or insufficient: Existing paths each solve part of the problem. None currently owns the complete product truth for readiness, freshness, permission row states, count invariants, scope matching, and action capability together.
  • Allowed deviation and why: one canonical resolver is allowed because current local truth is already duplicated across multiple real product surfaces and can produce false Healthy/Ready.
  • Consistency impact: Provider Connections, Required Permissions, dashboard guidance, workspace summaries, governance inbox, and direct downstream readiness summaries must share state names, freshness behavior, count semantics, next-action labels, and raw-detail gating.
  • Review focus: no stale verification as healthy/ready, no Present 0, no wrong-scope grant satisfaction, no raw provider payloads, no compatibility shim, no second readiness truth.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes, existing provider verification start/proof links only.
  • Shared OperationRun UX contract/layer reused: existing StartVerification, ProviderOperationStartResultPresenter, OperationUxPresenter, OperationRunLinks, and OperationRunService.
  • Delegated start/completion UX behaviors: verify-provider action must keep existing queued/deduped/blocked/run-link behavior. This spec may change when the action is primary or visible, not how OperationRun UX is composed.
  • Local surface-owned behavior that remains: resolver output decides recommended action and capability visibility; surfaces render it through existing action patterns.
  • Queued DB-notification policy: unchanged. No new queued notification family.
  • Terminal notification path: unchanged central lifecycle mechanism.
  • Exception required?: none.

Provider Boundary / Platform Core Check

  • Shared provider/platform boundary touched?: yes.
  • Boundary classification: mixed. Provider-owned evidence and permission names feed a platform-core readiness contract.
  • Seams affected: provider connection state, verification freshness, required permission coverage, permission evidence, provider capability evaluation, provider health labels, dashboard readiness signals, workspace/governance summaries, and downstream readiness blockers.
  • Neutral platform terms preserved or introduced: provider connection, verification, freshness, required permission, granted permission, effective permission, permission coverage, readiness, scope, recommended action.
  • Provider-specific semantics retained and why: Microsoft Graph permission names and admin-consent details remain necessary as secondary technical/operator detail for the current Microsoft provider.
  • Why this does not deepen provider coupling accidentally: product-facing labels use provider-neutral and purpose-first language. Raw Microsoft permission names stay secondary and do not define the platform-core readiness vocabulary.
  • Follow-up path: deeper provider onboarding and permission resolution adapter remains a later follow-up; this spec fixes current truth only.

UI / Surface Guardrail Impact

Surface / Change Operator-facing surface change? Native vs Custom Shared-Family Relevance State Layers Touched Exception Needed? Low-Impact / N/A Note
Provider Connections list/view/edit yes Native Filament resource plus shared provider summary/guidance provider readiness, health, actions, verification proof table, detail, header/action state no Existing routes only
Environment Required Permissions yes Native Filament page plus Blade summary/matrix permission rows/counts, freshness, provider action page summary, filters, rows, copy no Existing route only
Environment Dashboard provider area yes Existing dashboard builder/view readiness signal and next action dashboard decision/guidance no Existing dashboard only
Workspace Overview provider/readiness signal conditional yes Existing builder/view workspace readiness aggregation overview signal no Only if repo-real provider signals are consumed
Governance Inbox provider-related items conditional yes Existing inbox builder/view provider blocker item truth queue item/status/action no Only if repo-real provider items are consumed
Restore/evidence/review readiness summaries conditional yes Existing resources/builders provider blocker propagation readiness state no Direct provider-state consumers only

Decision-First Surface Role

Surface Decision Role Human-in-the-loop Moment Immediately Visible for First Decision On-Demand Detail / Evidence Why This Is Primary or Why Not Workflow Alignment Attention-load Reduction
Provider Connections view Primary Decision Surface Decide whether this provider can be trusted now readiness state, verification freshness, permission coverage, one action capability rows, verification history, technical provider detail Primary because connection readiness is a trust authority provider administration removes parallel health/count interpretation
Provider Connections list Secondary Context Surface Find which connection needs attention readiness state and scope-safe summary detail page Secondary because detail owns the decision workspace integration scanning avoids multiple top-level truth labels
Environment Required Permissions Primary Decision Surface Decide which permission/freshness blocker must be resolved canonical counts, row states, freshness, one action raw provider permission names and technical details Primary for permission remediation permission remediation workflow replaces Present ambiguity
Environment Dashboard provider area Secondary Context Surface Confirm provider blocker and jump to resolver-owned remediation canonical blocker and next action provider/permission detail page Secondary because dashboard summarizes environment operations prevents dashboard from claiming ready from old evidence
Workspace Overview / Governance Inbox Secondary Context Surface Prioritize affected environments/items canonical blocker state and link environment/provider details Secondary aggregation portfolio triage avoids contradictory readiness signals

Audience-Aware Disclosure

Surface Audience Modes In Scope Decision-First Default-Visible Content Operator Diagnostics Support / Raw Evidence One Dominant Next Action Hidden / Gated By Default Duplicate-Truth Prevention
Provider Connections operator-MSP, workspace owner, support when authorized readiness, verification freshness, required permission state, next action last verification, capability groups, permission coverage raw provider IDs/payloads excluded by default View provider, verify provider, review permissions, connect provider technical details capability-gated canonical resolver result owns state once
Required Permissions operator-MSP, workspace owner, support when authorized required/granted/missing/blocked/expired/unknown counts and rows provider permission names as secondary detail raw permission JSON excluded by default verify provider or review consent raw details collapsed/gated summary count aggregates rows
Dashboard/Workspace/Inbox operator-MSP, readonly where authorized blocker state and target link none or concise proof raw provider detail never default open provider/permissions/remediation technical detail hidden aggregations consume resolver output

UI/UX Surface Classification

Surface Action Surface Class Surface Type Likely Next Operator Action Primary Inspect/Open Model Row Click Secondary Actions Placement Destructive Actions Placement Canonical Collection Route Canonical Detail Route Scope Signals Canonical Noun Critical Truth Visible by Default Exception Type / Justification
Provider Connections list List / Integration CRUD / List-first Resource Open provider or verify/review blocker row opens detail required More/header unchanged existing grouping /admin/provider-connections /admin/provider-connections/{record} workspace, environment, provider Provider connection readiness and freshness none
Provider Connections view/edit Detail / Configuration Authority Provider readiness detail/config verify provider, review permissions, reconnect, or view provider dedicated detail/edit N/A header More / details existing confirmations retained /admin/provider-connections existing view/edit routes workspace, environment, provider Provider connection canonical readiness none
Required Permissions List / Guidance / Diagnostic read-first remediation page verify provider or review/admin consent same page matrix forbidden page body secondary links none added required permissions route same page workspace and environment Required permissions canonical counts and row states existing inline diagnostic page
Environment Dashboard Overview / Decision operator environment dashboard open provider remediation cards/links N/A dashboard guidance unchanged environment route same workspace/environment/provider Provider readiness provider blocker cannot be overridden none
Workspace Overview / Governance Inbox Queue / Overview aggregation/triage open environment/provider remediation item/action link N/A item secondary links unchanged existing routes existing target routes workspace and environment Provider readiness blocker state conditional only

Operator Surface Contract

Surface Primary Persona Decision / Operator Action Supported Surface Type Primary Operator Question Default-visible Information Diagnostics-only Information Status Dimensions Used Mutation Scope Primary Actions Dangerous Actions
Provider Connections Workspace operator Decide whether provider is ready now integration list/detail Can TenantPilot rely on this provider right now? connection state, verification freshness, permission coverage, recommended action raw provider permission names, verification history connection, verification, permission coverage, readiness TenantPilot provider metadata or provider verification operation Verify provider, Review required permissions, Connect provider, View provider existing credential/disable/reconnect actions only
Required Permissions Workspace operator Decide which permission or freshness issue blocks provider use diagnostic remediation page Are required permissions effective for this scope? canonical counts, row states, last verified, next action provider permission names, technical detail permission row state, freshness, readiness verification operation only Verify provider, Request admin consent, Open connection none added
Dashboard/Workspace/Inbox Governance operator Prioritize provider blockers across environments overview/queue Which provider blocker needs attention? canonical state, impact, link deeper provider detail readiness only none Open provider/permissions none added

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no persisted source of truth by default. One derived canonical resolver becomes the product-facing decision contract.
  • New persisted entity/table/artifact?: no by default. Existing ProviderConnection, ManagedEnvironmentPermission, OperationRun, and verification reports should be used first.
  • New abstraction?: yes, a canonical provider readiness resolver/result contract.
  • New enum/state/reason family?: yes, derived product-facing readiness and permission row states. They must change behavior and next action, not just presentation.
  • New cross-domain UI framework/taxonomy?: no.
  • Current operator problem: Operators can be told a provider is healthy/ready or permission coverage is absent/present based on local, stale, or ambiguous calculations.
  • Existing structure is insufficient because: Existing structures separately compute health, guidance, capability, required-permission counts, and freshness. At least ProviderConnectionSurfaceSummary, ManagedEnvironmentRequiredPermissionsViewModelBuilder, ProviderCapabilityEvaluator, and ProviderReadinessResolutionAdapter can diverge.
  • Narrowest correct implementation: one derived resolver over existing records and verification evidence, adopted by affected provider/readiness consumers, replacing visible labels/counts instead of adding new UI.
  • Ownership cost: one canonical contract, focused tests, migration of existing consumers, and future review discipline that provider readiness changes go through the resolver.
  • Alternative intentionally rejected: local copy/count fixes in Required Permissions and Provider Connections. That would leave stale health/readiness drift elsewhere.
  • Release truth: current-release trust-boundary correction.

Compatibility posture

TenantPilot is pre-production. Do not preserve old Healthy, Ready, Present, fallback, compatibility alias, translation key, fixture, or test behavior when it conflicts with this spec. Canonical replacement wins.

Testing / Lane / Runtime Impact

  • Test purpose / classification: Unit for resolver state/count logic, Feature for DB/scope/RBAC/action semantics, Filament/Livewire for provider pages/actions, Browser for focused end-to-end UI proof.
  • Validation lane(s): fast-feedback, confidence, browser. PostgreSQL only if implementation adds schema or relies on PostgreSQL-specific query/index behavior.
  • Why this classification and these lanes are sufficient: The core risk is deterministic business truth and visible trust-boundary rendering. Unit/Feature tests prove semantics; Filament tests prove actions and visibility; one browser smoke proves the real product surfaces no longer display forbidden labels/states.
  • New or expanded test families: focused Spec394 provider readiness resolver tests, provider connection/required-permission feature tests, capability-boundary tests, and one browser smoke.
  • Fixture / helper cost impact: moderate. Tests need workspace, managed environment, provider connection, permission evidence, verification timestamps, and actor capabilities. Helpers must stay explicit and not widen default provider setup globally.
  • Heavy-family visibility / justification: one bounded browser smoke only. No broad heavy-governance family is justified.
  • Special surface test profile: provider/integration strategic surface, diagnostic matrix page, dashboard/overview readiness signal.
  • Standard-native relief or required special coverage: standard Filament coverage plus one browser smoke for visible state/count/action behavior.
  • Reviewer handoff: verify no stale provider renders as healthy/ready, counts equal row aggregation, wrong-scope/stale grants fail closed, readonly users cannot run provider actions, raw provider payloads are absent by default, and no compatibility shim remains.
  • Budget / baseline / trend impact: contained feature-local increase. Escalate if implementation creates broad browser/heavy-governance suites or shared expensive setup defaults.
  • Escalation needed: document-in-feature if a narrow local path remains with reason; follow-up-spec if downstream adapters require a broader readiness propagation contract.
  • Active feature PR close-out entry: Provider Freshness / Permission Semantics Guardrail.
  • Planned validation commands:
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec394
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections tests/Feature/RequiredPermissions tests/Feature/Verification
    • cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec394ProviderFreshnessPermissionSmokeTest.php
    • cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • git diff --check

User Scenarios & Testing

User Story 1 - Stale verification is not healthy (Priority: P1)

As a workspace operator, I need stale provider verification to be visibly non-ready so I do not rely on provider data that TenantPilot has not recently verified.

Why this priority: This prevents the most dangerous false-green provider state.

Independent Test: Create a provider connection with verification_status=healthy, old last_health_check_at, and old permission evidence. The resolver and UI return Expired or Needs attention, never Healthy or Ready, and the primary action is to verify provider.

Acceptance Scenarios:

  1. Given a successful verification older than the freshness window, When provider readiness is rendered, Then the provider state is Expired or Needs attention, not Healthy or Ready.
  2. Given stale permission grants, When required permission rows are resolved, Then row states are Expired and coverage does not count them as granted.

User Story 2 - Required permission counts match effective rows (Priority: P1)

As an operator reviewing permissions, I need the summary counts to match the visible required permission rows so remediation is not misleading.

Why this priority: Ambiguous Present counts break trust and can send users to the wrong action.

Independent Test: Seed required permission rows with fresh effective grants, missing rows, blocked rows, expired rows, and unknown rows. The summary counts equal row-state aggregation and no product UI shows Present 0.

Acceptance Scenarios:

  1. Given six required rows in Granted and two in Missing, When the Required Permissions page renders, Then required_count=8, granted_required_count=6, missing_required_count=2, and the row count matches.
  2. Given granted raw rows that are wrong-scope, When the resolver runs for the current provider connection, Then those rows do not count as granted.

User Story 3 - Wrong-scope and unknown grants fail closed (Priority: P1)

As a security-conscious operator, I need TenantPilot to reject wrong-scope, unknown, or out-of-date permission evidence instead of assuming access is available.

Why this priority: Scope leakage or stale evidence can produce false confidence across workspaces, environments, provider connections, or provider accounts.

Independent Test: Create grants for another workspace, another environment, another provider connection, and a stale verification batch. Current-scope coverage remains Missing, Expired, or Unknown.

Acceptance Scenarios:

  1. Given a grant belongs to another workspace or environment, When current provider readiness is resolved, Then the grant is ignored and readiness is not Ready.
  2. Given insufficient verification data, When readiness is rendered, Then the state is Unknown or Needs attention and no provider-changing action appears for readonly users.

User Story 4 - Product surfaces share one provider truth (Priority: P2)

As an operator moving between dashboard, provider connection, required permissions, and governance work surfaces, I need the provider blocker to be consistent and actionable.

Why this priority: It prevents contradictory signals and reduces search work after the core resolver is correct.

Independent Test: Run focused feature and browser tests across Provider Connections, Required Permissions, Environment Dashboard, Workspace Overview, and Governance Inbox provider-related items. Each uses the same resolver state and recommended action.

Acceptance Scenarios:

  1. Given a provider is stale, When dashboard and provider details render, Then both point to verification and neither shows ready/healthy.
  2. Given missing required permissions, When dashboard guidance opens Required Permissions, Then the target page shows the same missing-permission blocker and canonical counts.

Non-Functional Requirements

  • NFR-394-001: Resolver decisions must be DB-only during render and must not call Microsoft Graph or any external provider.
  • NFR-394-002: Queries must be scope-safe and deterministic; no implicit database ordering.
  • NFR-394-003: Default UI must remain calm, decision-first, and no more complex than current surfaces.
  • NFR-394-004: Raw provider payloads, tokens, credentials, API response bodies, and grant IDs must not appear in default product UI or audit metadata.
  • NFR-394-005: Filament v5 / Livewire v4.0+ compliance is required. Current repo uses Livewire 4.1.4.
  • NFR-394-006: Provider panel registration remains unchanged in apps/platform/bootstrap/providers.php.

Data And Truth-Source Requirements

Prefer existing schema and relations:

  • provider_connections.verification_status
  • provider_connections.last_health_check_at
  • provider_connections.consent_status
  • provider_connections.is_enabled
  • provider_connections.provider
  • provider_connections.workspace_id
  • provider_connections.managed_environment_id
  • existing provider identity metadata fields/casts on provider_connections
  • managed_environment_permissions.workspace_id
  • managed_environment_permissions.managed_environment_id
  • managed_environment_permissions.permission_key
  • managed_environment_permissions.status
  • managed_environment_permissions.details
  • managed_environment_permissions.last_checked_at
  • provider verification OperationRun context/report where repo-real

Potential clean concepts only if existing data cannot represent the contract:

  • provider_verification_checked_at
  • provider_verification_expires_at
  • provider_verification_state
  • permission_grants.verification_batch_id
  • permission_grants.scope_type
  • permission_grants.scope_id
  • required_permissions.provider_key
  • required_permissions.product_purpose

If implementation proves one of these is needed, stop and update spec/plan before adding migrations.

Provider account/context is not an implicit free-form match. For v1, it is derived from the current ProviderConnection identity and same-provider verification context. If existing records cannot distinguish two provider accounts behind the same workspace/environment/provider key, affected permissions must resolve as Unknown or the implementation must stop and update spec/plan before adding schema.

Acceptance Criteria

  • AC-394-001: Stale provider is not Healthy or Ready; primary action is verify/refresh provider.
  • AC-394-002: Fresh provider with all effective required permissions is Ready.
  • AC-394-003: Required permission counts match row states and no UI shows Present 0 while granted rows are visible.
  • AC-394-004: Missing permission blocks readiness and recommends permission remediation.
  • AC-394-005: Wrong-scope grants do not satisfy current required permissions.
  • AC-394-006: Stale grants produce Expired permission row state and non-ready provider readiness.
  • AC-394-007: Unknown state fails closed and never renders as ready/healthy.
  • AC-394-008: Readonly users cannot trigger verify/reconnect/manage provider actions and cannot view raw provider technical detail.
  • AC-394-009: Affected pages show one provider readiness/health truth by default.
  • AC-394-010: Affected pages do not gain new cards, sections, evidence/proof links, or long technical tables as part of this spec.

Success Criteria

  • A stale provider never appears healthy on Provider Connections, Required Permissions, Environment Dashboard, or provider readiness consumers.
  • Required permission summary counts equal canonical row-state aggregation.
  • Connected provider state and provider readiness are visibly distinct.
  • Wrong-scope and stale grants are excluded from effective permission coverage.
  • Provider-changing actions are capability-gated.
  • No raw provider payload or technical permission dump appears by default.
  • No legacy compatibility shim preserves old provider health or Present semantics.

Regression Risks

  • Existing tests may expect old Healthy behavior. Mitigation: update tests to canonical behavior without weakening the resolver.
  • Fixture inconsistencies may appear when counts change. Mitigation: fix fixtures to represent canonical grants and scope.
  • Downstream surfaces may lose Ready states. Mitigation: if provider state is stale or incomplete, losing Ready is correct.
  • Readonly users may lose technical detail. Mitigation: product-safe summary remains visible where authorized; technical detail remains manage/technical-capability gated.
  • Provider labels may become too technical. Mitigation: product labels first, raw provider names secondary/internal only.

Assumptions

  • TenantPilot remains pre-production for this feature area; no legacy customer data compatibility is required.
  • Existing ProviderConnection, ManagedEnvironmentPermission, and verification report/OperationRun data can represent the v1 contract unless implementation proves otherwise.
  • Microsoft remains the first provider, but product-facing readiness vocabulary must stay provider-neutral.
  • No new dashboard, onboarding wizard, provider integration, or customer-facing provider detail is required.

Open Questions

  • None blocking preparation. During implementation, if current schema cannot distinguish fresh verification batch scope from stale permission rows, update spec/plan before adding schema.

Follow-Up Spec Candidates

  • Provider Onboarding & Permissions Resolution Adapter: guided setup/remediation flow after canonical readiness semantics are stable.
  • Product Surface Contract Enforcement provider pass: broader cross-surface enforcement if additional downstream consumers keep local provider truth.
  • Provider secondary-action density cleanup: optional Spec 353 follow-up if the canonical state change reveals action clutter.

Required Implementation Report

Later implementation must report:

  1. Files changed.
  2. Resolver/API created or consolidated.
  3. Old local provider health/readiness logic removed or replaced.
  4. Required permission count logic source.
  5. Tests added/updated.
  6. Browser flows run.
  7. Evidence that stale verification no longer renders Healthy or Ready.
  8. Evidence that required permission counts match rows.
  9. Evidence that wrong-scope grants are excluded.
  10. Confirmation that no legacy compatibility shim was added.
  11. Confirmation that visible UI complexity did not increase.
  12. Remaining known unrelated failures, if any.