TenantAtlas/specs/392-customer-output-gating-review-pack-navigation/spec.md
ahmido dd7139ebe3 Spec392 customer output gating (#463)
Implements Spec392 customer output gating for review pack downloads, rendered reports, management PDFs, and customer workspace CTAs.

Validation:
- php vendor/bin/pest --filter=Spec392: 12 passed / 58 assertions
- php vendor/bin/pest --filter='ReviewPack|CustomerReviewWorkspace|StoredReport': 283 passed / 1 skipped / 2053 assertions
- affected browser matrix: 12 passed / 420 assertions
- php vendor/bin/pint --dirty: pass
- git diff --check: pass

Notes:
- Deprecated limited-download semantics remain removed.
- Unsafe customer-facing output returns 403/no output.
- Internal preview/report access is operator-only.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #463
2026-06-20 20:54:50 +00:00

41 KiB

Feature Specification: Spec 392 - Customer Output Gating & Review Pack Navigation v1

Feature Branch: 392-customer-output-gating-review-pack-navigation Created: 2026-06-20 Status: Draft Type: Bugfix / trust and safety / customer-output productization Runtime posture: Narrow enforcement and navigation hardening over existing review, review-pack, rendered-report, management-report, and Customer Review Workspace output paths. No broad workspace rebuild, no new customer portal, no new persisted readiness truth, and no review-pack generator rewrite. Input: User-provided Spec 392 draft plus repo truth from Specs 342, 347, 351, 372, 379, 385, 390, the browser productization bug audit, and current review-pack/customer-workspace runtime references.

Dependencies And Historical Context

Spec 392 is a follow-up over already repo-real customer-review and review-output work:

  • Spec 342 - Customer Review Workspace final consumption productization.
  • Spec 347 - Review Pack output contract and readiness semantics.
  • Spec 349 - Customer Review Workspace output resolution guidance.
  • Spec 351 - Review output resolve actions.
  • Spec 372 - Customer/auditor surface safety pass.
  • Spec 379 - Management Report PDF runtime.
  • Spec 385 - Evidence review readiness.
  • Spec 390 - Restore readiness resolution adapter.
  • specs/browser-productization-bug-audit/browser-bug-report.md, especially BUG-007, which records an Open customer workspace CTA opening Review Pack detail.

Repo-truth adjustment against the user draft:

  • Broad Customer Review Workspace v1 completion is completed/historical; this spec must not reopen it.
  • A review-pack output readiness derivation already exists under App\Support\ReviewPacks\ReviewPackOutputReadiness; this spec should reuse or wrap existing readiness truth before adding any new support object.
  • Existing report profile/disclosure structures already distinguish customer and internal report profiles; this spec must not add a second report profile framework.
  • Current routes include /admin/review-packs/{reviewPack}/download, /admin/review-packs/{reviewPack}/report, and /admin/management-report-pdfs/{storedReport}/download; these are in scope only where they expose customer-facing output or customer-safe labels.
  • Current copy still includes a deprecated limited-download concept; Spec 392 removes that customer-output behavior and replaces any authorized internal access with the canonical internal-preview concept.

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

  • Problem: Customer-facing output is a trust boundary. TenantPilot currently has reachable output and navigation paths where customer-safe labels can be stronger than the gate enforced by the route or destination.
  • Today's failure: A user may see a customer-facing download/open action for output with limitations, PII risk, incomplete evidence, missing output, expired/superseded output, or internal-only semantics; a CTA labelled Open customer workspace may route to internal Review Pack detail instead of the actual workspace.
  • User-visible improvement: Operators can trust that customer output actions are either truly safe and routed correctly, or clearly blocked with one reason and a safe next action. Customer workspace, review pack, report, and internal preview actions stop competing or misleading by label.
  • Smallest enterprise-capable version: Inventory all customer-output open/download actions, introduce or consolidate one customer-output gate over existing readiness/disclosure truth, enforce it at route/controller/action level, and correct misleading labels on the existing surfaces only.
  • Explicit non-goals: No broad Customer Review Workspace redesign, no external customer portal, no new review publication workflow, no generator rewrite, no new report renderer, no new persisted readiness table, no new dashboard, no new evidence cards, no new operation-run panels, no new customer-facing technical proof surfaces.
  • Permanent complexity imported: One narrow gate/service or result object if existing readiness guidance cannot serve; focused Unit/Feature/Filament/Browser tests; localized copy updates; UI coverage/page-report updates if implementation changes reachable surfaces. No new tables, no cross-domain readiness framework, and no broad status taxonomy.
  • Why now: The product has completed enough customer review and output productization that the remaining risk is no longer feature absence; it is unsafe availability and misleading customer-facing affordances.
  • Why not local: A local label patch would leave direct-route downloads, report pages, and other surfaces able to bypass the same safety decision. The security boundary must be shared by UI and route enforcement.
  • Approval class: Core Enterprise.
  • Red flags triggered: Customer-facing trust language, route-level access boundary, derived state/gate semantics, cross-surface action labels, and PII/output disclosure. Defense: the slice is security and auditability-critical, derived from existing truth, route-enforced, and explicitly forbids new persistence or a generic readiness engine.
  • 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: Customer Output Gating & Review Pack Navigation v1.
  • Source locations:
    • User-provided draft: /Users/ahmeddarrazi/.codex/attachments/badee408-00ed-499e-b5c2-f6f48278b29a/pasted-text.txt
    • Browser audit evidence: specs/browser-productization-bug-audit/browser-bug-report.md
    • Roadmap relationship: docs/product/roadmap.md states customer review workspace v1 is completed/historical, but customer-safe review consumption remains a current productization and trust concern when fresh repo evidence exists.
    • Candidate relationship: docs/product/spec-candidates.md treats broad Customer Review Workspace v1 as completed and allows only narrow future polish/fresh-evidence follow-ups.
  • Completed-spec check:
    • No specs/392-* package existed before this prep.
    • Specs 342, 347, 351, and 372 contain completed-task, validation, smoke, or implementation-history signals and are read-only historical context.
    • Spec 379 is runtime-gated management-report context, not a target to reopen here.
    • The browser productization audit is an evidence source package and remains read-only.
  • Boundary against related completed specs:
    • Spec 342/372 customer-workspace and customer/auditor surface productization must not be replayed.
    • Spec 347 output-readiness contract must be reused or wrapped, not replaced.
    • Spec 351 resolution actions may inform safe next-action wording, but this spec does not rebuild the resolution guidance framework.
  • Close alternatives deferred:
    • Governance Artifact Lifecycle & Retention runtime: separate lifecycle/retention product gap.
    • Management Report PDF staging/Dokploy validation: follow current Spec 379 runtime gate.
    • External customer portal or external consumption: separate product decision.
    • Broad customer-facing localization polish: copy QA lane only after safety semantics are stable.
    • Report profile/disclosure framework expansion: out of scope because existing profile/disclosure structures already exist.
  • Smallest viable implementation slice: Existing customer-output actions and routes only: Review Pack download/report, management-report download where customer-facing, Customer Review Workspace output actions, Review Pack/Environment Review action labels, Environment Dashboard customer workspace CTA, Evidence Overview customer-workspace links, and direct-route bypass tests.

Spec Scope Fields (mandatory)

  • Scope: Workspace canonical view plus environment-owned review/output artifacts.
  • Primary Routes / Surfaces:
    • /admin/reviews/workspace via App\Filament\Pages\Reviews\CustomerReviewWorkspace
    • /admin/review-packs/{reviewPack}/download via App\Http\Controllers\ReviewPackDownloadController
    • /admin/review-packs/{reviewPack}/report via App\Http\Controllers\ReviewPackRenderedReportController
    • /admin/management-report-pdfs/{storedReport}/download where the report is presented as customer-facing output
    • App\Filament\Resources\ReviewPackResource
    • App\Filament\Resources\EnvironmentReviewResource
    • App\Support\EnvironmentDashboard\EnvironmentDashboardSummaryBuilder
    • App\Filament\Pages\Monitoring\EvidenceOverview
  • Data Ownership:
    • EnvironmentReview remains released-review truth.
    • ReviewPack remains export artifact truth.
    • StoredReport remains report artifact truth.
    • Existing review-pack/readiness/disclosure summaries remain derived truth.
    • OperationRun remains execution/proof truth only; it is not customer-safety truth.
    • No new table, persisted entity, or durable readiness record is expected.
  • RBAC:
    • Workspace membership and managed-environment entitlement are mandatory before revealing customer-output records.
    • Existing capabilities remain authoritative, especially REVIEW_PACK_VIEW, ENVIRONMENT_REVIEW_VIEW, evidence/report view capabilities, and any stored-report download capability.
    • Non-member or cross-workspace/environment access remains deny-as-not-found.
    • Member-without-capability remains 403 for direct action execution, with disabled/hidden UI per existing enforcement helpers.
    • Gate-safe state is required in addition to permission; permission alone never permits unsafe customer-facing output.

For canonical-view specs:

  • Default filter behavior when tenant-context is active: Customer Review Workspace remains workspace-wide with explicit environment_id page filtering only. Spec 392 must not revive /admin/t, hidden tenant context, legacy query aliases, or remembered environment switcher authority.
  • Explicit entitlement checks preventing cross-tenant leakage: All review, review-pack, stored-report, evidence, and report download/open routes must resolve records through current workspace and managed-environment entitlement before checking customer-output safety.
  • Management Report PDF customer-facing decision: Treat a management-report PDF route/action as customer-facing when it is labelled, linked, or positioned as customer/auditor review output from Customer Review Workspace, Review Pack, Environment Review, Environment Dashboard, Evidence Overview, or rendered-report flows. Treat it as internal-only only when current repo truth shows the route is reachable solely from operator/audit/technical surfaces and its label/copy does not imply customer delivery. Implementation must record this decision before changing or excluding the route.

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 (mandatory when UI Surface Impact is not "No UI surface impact")

Route/page/surface Archetype Design depth Repo-truth level Existing pattern reused Screenshot / audit need Customer-safe review Dangerous-action review
Customer Review Workspace Existing strategic customer review surface Strategic Surface repo-verified + browser-tested historical context Specs 342/347/372 customer-safe hierarchy Browser screenshot if action hierarchy changes; update existing page report if material yes no new dangerous action
Review Pack download/report Existing artifact output route/detail Domain Pattern Surface repo-verified Spec 347 output readiness, existing signed download route Route tests required; screenshot only if rendered report/action copy changes yes no new dangerous action
Management report PDF download where customer-facing Existing report artifact route Domain Pattern Surface repo-verified current runtime gate Spec 379 report runtime gate and disclosure posture Route tests if in scope yes no new dangerous action
Environment Dashboard customer-workspace CTA Existing environment dashboard action Decision/workbench context repo-verified BUG-007 source Existing CustomerReviewWorkspace URL helper and ReviewPackResource URLs Browser smoke required for CTA truth yes no new dangerous action
Evidence Overview customer-workspace links Existing evidence monitoring context Secondary Context / Evidence repo-verified Existing CustomerReviewWorkspace URL helper Browser or Feature coverage if touched yes no new dangerous action
  • 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/... when implementation materially changes reachable page behavior
    • 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.

Cross-Cutting / Shared Pattern Reuse (mandatory)

  • Cross-cutting feature?: yes.
  • Interaction class(es): status messaging, action links, customer-output downloads, report viewers, review-pack viewers, dashboard cards, evidence links, route authorization.
  • Systems touched:
    • ReviewPackOutputReadiness
    • ReviewPackOutputResolutionGuidance
    • ReportDisclosurePolicy
    • CustomerReviewWorkspace
    • ReviewPackDownloadController
    • ReviewPackRenderedReportController
    • ReviewPackResource
    • EnvironmentReviewResource
    • EnvironmentDashboardSummaryBuilder
    • EvidenceOverview
    • localization keys for output/download/customer workspace labels
  • Existing pattern(s) to extend: Spec 347 output-readiness contract, Spec 351 resolution guidance action semantics, Spec 372 customer/auditor disclosure hierarchy, existing capability and policy checks, existing signed download protections.
  • Shared contract / presenter / builder / renderer to reuse: Existing review-pack readiness/disclosure helpers first. A new CustomerOutputGate-style service is allowed only if it centralizes cross-route enforcement and absorbs existing readiness/disclosure truth instead of duplicating it.
  • Why the existing shared path is sufficient or insufficient: Existing readiness helpers derive whether output has limitations, PII, export availability, and customer-safe state, but current direct routes and action labels do not yet consistently consume one route-enforced customer-output decision.
  • Allowed deviation and why: One narrow customer-output gate/result object is allowed as a security boundary if existing helpers cannot safely serve both UI affordances and direct route authorization. It must stay scoped to customer-output open/download decisions and must not become a generic governance readiness framework.
  • Consistency impact: Customer output state, primary action, blocking reason, internal preview label, route enforcement, and dashboard/review-pack/customer-workspace CTAs must describe the same decision.
  • Review focus: Block any duplicated page-local readiness logic, any active customer-facing download with limitations, any Open customer workspace action routed to internal detail, and any direct route that streams blocked output.

OperationRun UX Impact (mandatory)

  • Touches OperationRun start/completion/link UX?: Existing proof/deep-link display only; no new operation start, completion, queueing, dedupe, terminal notification, or lifecycle behavior is expected.
  • Shared OperationRun UX contract/layer reused: Existing OperationRun links and artifact proof routes only.
  • Delegated start/completion UX behaviors: N/A for new operation starts.
  • Local surface-owned behavior that remains: Customer-output blocking copy may mention output state, but not raw operation internals.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: unchanged.
  • Exception required?: none.

Provider Boundary / Platform Core Check (mandatory)

  • Shared provider/platform boundary touched?: no new provider seam.
  • Boundary classification: platform-core customer-output boundary over existing review/report artifacts.
  • Seams affected: customer-facing route labels, output safety checks, and report/review-pack artifact access.
  • Neutral platform terms preserved or introduced: customer output, customer workspace, review pack, internal preview, blocking reason, output state.
  • Provider-specific semantics retained and why: Provider-specific facts may remain inside existing customer-safe review/report content only; they must not become gate vocabulary.
  • Why this does not deepen provider coupling accidentally: No Graph contracts, provider credentials, provider connections, provider identifiers, or Microsoft-specific scopes are introduced.
  • Follow-up path: none unless implementation finds provider-specific disclosure leakage, which should become a separate follow-up spec.

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
Customer output actions on Customer Review Workspace yes Existing Filament page plus Blade composition customer-safe output, action links page payload, route, URL-query no Existing route only
Review Pack download/report labels and access yes Filament resource/detail plus HTTP controller artifact viewer, download action detail, route no No generator rewrite
Environment Dashboard customer-workspace CTA yes Existing dashboard summary/action payload dashboard card action links page payload, navigation no Correct label/destination only
Evidence Overview customer-workspace link labels yes if touched Existing Filament page evidence/report viewer links page payload, navigation no Keep proof secondary
Direct customer-output routes no visible UI by themselves N/A route authorization route no Security enforcement 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
Customer Review Workspace output actions Primary Decision Surface Decide whether output can be opened/downloaded for a customer or needs attention one customer output state, one primary next action, concise reason review pack detail, evidence, audit trail, technical details when authorized Primary for customer-safe consumption customer review handoff removes guessing from multiple badges/actions
Review Pack detail/download Secondary Context / Artifact Surface Verify artifact readiness and access the correct output type artifact state, customer-output state, download/internal preview availability operation proof, metadata, report details Secondary because it verifies one artifact output verification prevents unsafe artifact sharing
Environment Dashboard customer-workspace CTA Secondary Context / Navigation Surface Navigate from environment posture to the correct customer review destination truthful CTA label and disabled/unavailable state review pack detail if labelled as internal artifact Not primary; it is a launcher dashboard-to-review navigation removes wrong-destination confusion

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
Customer Review Workspace customer-read-only, operator-MSP, support where authorized customer output state, reason, impact, next action review/evidence/report proof links secondary raw payloads, IDs, source keys, operation internals state-specific customer-safe action or blocker action internal preview and technical proof one state label; details explain rather than restate
Review Pack / rendered report operator-MSP, auditor/customer consumer, support where authorized whether the artifact is customer-safe, blocked, expired, or internal preview only generation proof, metadata, operation link raw ZIP/report internals and debug detail download customer output only when ready internal preview, technical metadata label and route agree
Environment Dashboard link operator-MSP truthful route label and enabled/disabled state none by default none open customer workspace or open review pack, not both as the same label internal detail when not labelled as such destination determines label

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
Customer Review Workspace output block Utility / Workspace Decision Strategic review hub open safe output or resolve blocker explicit primary action forbidden secondary proof links below none in scope /admin/reviews/workspace existing review/pack/report routes workspace and explicit environment filter Customer output safety state and reason none
Review Pack detail/download Utility / Artifact Detail Artifact proof/download download customer output or internal preview detail header/action current repo behavior technical proof secondary existing destructive actions unchanged/out of scope existing review-pack collection existing review-pack detail/download/report workspace/environment context Review pack customer-output gate state none
Environment Dashboard CTA Dashboard Signal Navigation action open correct review surface explicit action payload N/A review pack detail only as Open review pack none environment dashboard customer workspace or review pack detail environment context Customer workspace / Review pack route truth none

UI Action Matrix

Action label Surface(s) Destination / effect Primary or secondary Visible / enabled rule Server-side enforcement Destructive?
Open customer workspace Environment Dashboard, Evidence Overview if touched, Environment Review / Review Pack navigation if present Actual Customer Review Workspace prefiltered to the environment Primary only when the workspace is the intended next customer-safe destination Show or enable only when destination is the workspace and workspace/environment entitlement is established; otherwise use a blocked/unavailable or review action Workspace membership, managed-environment entitlement, capability checks, and customer-output gate state where output access is implied No
Open review pack Review Pack links from dashboard, evidence, environment review, and related detail surfaces Review Pack detail / internal artifact context Secondary context or artifact inspection Use whenever the destination is internal Review Pack detail; never label this destination as customer workspace Workspace membership, managed-environment entitlement, and Review Pack view capability No
Download customer output Customer Review Workspace, Review Pack detail/report, rendered report, and Management Report PDF only when customer-facing Stream or open customer-safe output Primary only when state is Ready Visible/enabled only when the gate returns Ready; hidden/disabled/replaced with blocker copy otherwise Same customer-output gate before streaming/rendering/signing/redirecting, plus membership, entitlement, capability, artifact status, expiry, and file checks No
Download internal preview Review Pack detail/report or internal operator surfaces only Stream limitations-bearing or internal-only artifact for operators Secondary Visible only for authorized internal/operator users when limited output remains useful; hidden from customer/read-only views Internal/operator capability plus internal-preview gate; must not reuse customer-output permission alone No
View audit trail / View technical details Review Pack detail, rendered report, Evidence Overview, Customer Review Workspace secondary proof areas Open internal proof, audit, or diagnostic detail Secondary/diagnostic Gated or collapsed by default on customer-facing surfaces; never presented as customer output Existing audit/detail authorization and workspace/environment entitlement No
Review blockers / Prepare output / existing regenerate action Customer Review Workspace or Review Pack detail when output is blocked/not configured Existing blocker review or output-preparation flow Primary only when it is the safest next action and already supported Use instead of unsafe customer download when output is blocked, missing, or needs attention Existing capability/policy checks for the underlying action; destructive/high-impact existing actions remain out of scope and must keep confirmation Existing behavior unchanged

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
Customer output gate across review surfaces MSP/operator, reviewer, auditor facilitator decide whether output may be shown/downloaded for customers cross-surface output boundary Is this output customer-safe right now, and where should I go next? Ready / Needs attention / Blocked / Not configured / Expired / Unknown, one reason, one next action evidence, operation proof, raw report metadata, internal preview publication state, artifact availability, safety/disclosure, freshness, authorization TenantPilot only for gating; no Microsoft tenant mutation Open customer workspace, Download customer output, Review blockers, Prepare output, Regenerate output if already supported none introduced

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no.
  • New persisted entity/table/artifact?: no.
  • New abstraction?: maybe one narrow customer-output gate/result object.
  • New enum/state/reason family?: derived user-facing state labels only; no persisted enum/status family expected.
  • New cross-domain UI framework/taxonomy?: no.
  • Current operator problem: Customer-facing output actions can imply safe delivery even when readiness/disclosure state or route destination does not support that claim.
  • Existing structure is insufficient because: Existing readiness/disclosure helpers are not a route-enforced access boundary and do not currently force every CTA/download/open path through one safety decision.
  • Narrowest correct implementation: Reuse existing readiness and disclosure structures inside one customer-output gate consumed by UI and direct routes; correct labels to match destinations; block unsafe downloads.
  • Ownership cost: One small support object/service if needed, localized copy, focused tests, and browser smoke. No new database or broad framework ownership.
  • Alternative intentionally rejected: Copy-only rename, page-local hidden/disabled buttons, new persisted readiness table, new output workflow, or broad Customer Review Workspace redesign.
  • Release truth: current-release truth.

Compatibility posture

This feature assumes a pre-production environment.

Backward compatibility, legacy aliases, migration shims, stale signed customer-output downloads, and compatibility-specific tests are out of scope unless explicitly required by implementation-time repo truth. Customer-safety replacement is preferred over preserving unsafe labels.

Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)

  • Test purpose / classification: Unit for customer-output gate derivation; Feature/HTTP for direct route blocking and safe downloads; Filament/Livewire for action visibility/labels; Browser for safe/unsafe customer review output path and CTA destination truth.
  • Validation lane(s): fast-feedback + confidence + browser.
  • Why this classification and these lanes are sufficient: Gate behavior can be proven with focused service tests, direct-route bypass with HTTP tests, Filament action state with Livewire tests, and final user-visible trust boundaries with one bounded browser smoke.
  • New or expanded test families: Spec392CustomerOutputGateTest, Spec392CustomerOutputRouteGateTest, Spec392CustomerOutputActionLabelsTest, and one bounded browser smoke if UI/user-facing changes land.
  • Fixture / helper cost impact: reuse existing review-output browser fixture and current review/review-pack/stored-report factories; do not widen global seed defaults.
  • Heavy-family visibility / justification: one browser smoke is explicit because this is a customer-facing trust boundary and includes CTA destination verification.
  • Special surface test profile: global-context-shell + customer-safe strategic review surface + artifact download route.
  • Standard-native relief or required special coverage: no standard-native relief for route gate; direct-route and customer-facing output proof are mandatory.
  • Reviewer handoff: verify no unsafe output streams through direct routes, no deprecated limited-download copy remains customer-facing, and no Open customer workspace route opens internal Review Pack detail.
  • Budget / baseline / trend impact: none expected beyond one bounded browser test.
  • Escalation needed: document-in-feature for contained label/gate exceptions; follow-up-spec only if implementation discovers structural report-delivery or customer-portal gaps.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
  • Planned validation commands:
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec392
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter='CustomerReviewWorkspace|ReviewPack|StoredReport'
    • cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec392CustomerOutputGatingSmokeTest.php --compact
    • cd apps/platform && ./vendor/bin/sail pint --dirty
    • git diff --check

User Scenarios & Testing (mandatory)

User Story 1 - Block Unsafe Customer Output Everywhere (Priority: P1)

An operator or reviewer attempts to open or download customer-facing review output. TenantPilot allows it only when the customer-output gate returns a ready/safe state, and blocks direct URL access otherwise.

Why this priority: This is the core trust and safety boundary; UI hiding is not enough.

Independent Test: Feature/HTTP tests create ready, PII-limited, missing, expired, internal-only, and unknown output scenarios and assert direct customer-facing routes stream only the ready output.

Acceptance Scenarios:

  1. Given a review pack with unresolved PII or internal-only output, When an authorized user opens the customer-facing download URL directly, Then no file is returned and the response is 403 or safe redirect with a concise block reason.
  2. Given a published, customer-safe review pack with a generated artifact and no blockers, When an authorized user downloads customer output, Then the correct artifact is returned and an audit event is recorded.
  3. Given a review pack is missing, failed, expired, archived, superseded, revoked, or stale beyond allowed currentness, When a customer-facing open/download route is used, Then the route blocks the output and does not leak artifact contents.

User Story 2 - Use Truthful Review Pack And Customer Workspace Navigation (Priority: P1)

An operator moves between dashboard, evidence, review, review pack, and customer workspace surfaces. Each CTA label matches its actual destination and customer-safety posture.

Why this priority: Mislabelled navigation causes operators to trust or share the wrong surface.

Independent Test: Filament/Livewire and browser tests assert Open customer workspace routes only to CustomerReviewWorkspace, while Review Pack detail uses Open review pack.

Acceptance Scenarios:

  1. Given an environment dashboard card links to a ready review pack detail, When the link is rendered, Then its label is Open review pack, not Open customer workspace.
  2. Given the label is Open customer workspace, When the user clicks it, Then it opens the actual Customer Review Workspace prefiltered to the environment.
  3. Given customer workspace is missing or blocked, When the page renders, Then no active primary CTA says Open customer workspace; the UI shows a truthful unavailable or prepare/review action.

User Story 3 - Separate Internal Preview From Customer Output (Priority: P1)

An internal operator may still access an internal preview when authorized, but the UI and route never present it as customer-ready output.

Why this priority: Internal preview is useful, but only if it cannot be mistaken for customer output.

Independent Test: Unit/Feature/Filament tests assert limitations-bearing output maps to internal-preview or blocked behavior, never customer-output download.

Acceptance Scenarios:

  1. Given a generated artifact has limitations or unresolved blockers, When an internal operator has the required permission, Then any allowed access is labelled Download internal preview and remains secondary.
  2. Given a customer-facing/read-only user views the same state, When actions render, Then internal preview is hidden or unavailable and customer output remains blocked.
  3. Given output is limitations-bearing, When rendered reports or review-pack details show actions, Then the page does not show customer-output download wording or equivalent customer-safe wording.

User Story 4 - Keep Customer-Facing Surfaces Free Of Internal Proof By Default (Priority: P2)

Customer-facing review output surfaces keep internal proof, raw metadata, operation links, and technical diagnostics secondary or capability-gated by default.

Why this priority: It prevents accidental internal proof leakage while preserving audit depth for operators.

Independent Test: Feature/Browser tests render customer-facing surfaces and assert no raw IDs, operation internals, source keys, fingerprints, or report-generation metadata are default-visible.

Acceptance Scenarios:

  1. Given a customer-facing output surface renders, When the user has ordinary review permissions, Then internal proof links and technical metadata are not default-visible.
  2. Given an authorized operator needs proof, When they use an internal technical/audit action, Then proof remains reachable as internal detail and not labelled customer output.

Functional Requirements

  • FR-001: Customer-facing output open/download actions MUST be blocked unless the canonical customer-output gate returns Ready.
  • FR-002: The gate MUST evaluate existing publication state, artifact availability, readiness/disclosure state, PII/redaction blockers, internal-only flags, expired/superseded/revoked/archived state where repo-backed, customer workspace availability, user authorization, workspace/environment scope, and destination type.
  • FR-003: Every customer-facing open/download route MUST enforce the same gate decision before streaming a file, rendering a customer-facing report, issuing a signed URL, or redirecting to customer output.
  • FR-004: Direct route access MUST return 403, 404 deny-as-not-found, or a safe admin redirect without output content when blocked.
  • FR-005: Deprecated limited-download copy MUST NOT appear as a customer-facing output action. If an internal artifact remains accessible, it MUST be labelled Download internal preview.
  • FR-006: Open customer workspace MUST route only to the actual Customer Review Workspace. Internal Review Pack detail MUST use Open review pack.
  • FR-007: Affected surfaces MUST show only one top-level customer output state by default: Ready, Needs attention, Blocked, Not configured, Expired, or Unknown.
  • FR-008: Blocked states MUST show one concise customer-safe reason and avoid implementation terms such as artifact payload, detector, source key, operation failure, or raw policy internals in default copy.
  • FR-009: Internal preview routes/actions MUST require internal/operator authorization and MUST NOT appear by default on customer-facing surfaces.
  • FR-010: Route and UI checks MUST both enforce workspace membership, managed-environment entitlement, capability authorization, and customer-output gate-safe state.
  • FR-011: Customer-facing surfaces MUST not expose internal proof links, operation internals, raw evidence, source keys, fingerprints, raw payloads, baseline internals, or report-generation metadata by default.
  • FR-012: The implementation MUST reuse existing readiness/disclosure truth before adding any new derived helper.

Non-Functional Requirements

  • NFR-001 - Security: Deny cross-workspace/environment access as not found and avoid leaking blocked artifact existence to non-members.
  • NFR-002 - Auditability: Successful customer-output downloads and any internal-preview downloads MUST preserve or add audit entries with safe metadata only.
  • NFR-003 - Performance: Gate evaluation MUST be DB-backed and must not call Microsoft Graph or remote services during render or route access.
  • NFR-004 - Simplicity: No new persisted readiness truth or generalized readiness framework is allowed unless spec/plan are amended.
  • NFR-005 - Accessibility/UX: Disabled/blocked output actions must provide concise helper text or reason copy for entitled users.

Out Of Scope

  • Customer portal, external user invitation, or customer authentication.
  • Review publication workflow redesign.
  • Review-pack ZIP contract or generator rewrite beyond minimal data required by the gate.
  • Management Report PDF renderer validation or Dokploy runtime enablement.
  • Governance artifact lifecycle/retention runtime.
  • New dashboards, new cards, new evidence panels, new proof pages, or new operation-run surfaces.
  • New database tables, migrations, packages, queue families, scheduler changes, storage topology changes, or Graph scopes unless implementation proves an unavoidable need and spec/plan are updated first.

Assumptions

  • Existing ReviewPackOutputReadiness, ReviewPackOutputResolutionGuidance, and ReportDisclosurePolicy can provide most customer-output safety signals.
  • Existing policies and capabilities already cover Review Pack, Environment Review, Evidence, Stored Report, and Customer Review Workspace access.
  • Current product is pre-production, so unsafe labels can be replaced rather than preserved for compatibility.
  • The safest V1 is route-gate-first and UI-copy-second.

Risks

  • Existing tests may expect limitations-bearing output to remain downloadable from customer-facing routes.
  • Some surfaces may duplicate readiness logic and need careful consolidation without broad refactor.
  • Management Report PDF runtime is gated; implementation must not make it appear production-ready.
  • Internal-preview access may require a clear capability mapping; if current capabilities cannot express it, the implementation must update spec/plan before expanding scope.

Success Criteria

  • 100% of affected customer-facing output routes call the same gate or equivalent shared policy before returning output.
  • 0 customer-facing occurrences of deprecated limited-download copy remain.
  • 0 Open customer workspace CTAs route to Review Pack detail or other internal detail pages.
  • Targeted Feature/HTTP/Filament tests cover safe, unsafe, direct-route, label, and permission cases.
  • Browser smoke proves one safe path, one unsafe/blocked path, and the corrected customer-workspace CTA.

Follow-Up Spec Candidates

  • Governance Artifact Lifecycle & Retention runtime.
  • Management Report PDF staging/Dokploy renderer validation and release hardening.
  • Customer portal or external/customer-consumption boundary contract.
  • Customer-facing localization copy QA once gate copy is stable.
  • Structural report-delivery packaging if route gating exposes a larger artifact-delivery design gap.