## Summary\n- Implements the ReviewPublicationResolutionWorkflow for Spec 386.\n- Adds resolution case/step persistence, policies, services, audit action IDs, and Filament integration.\n- Updates specs, UI/UX documentation, screenshots, and Pest coverage.\n\n## Tests\n- Not run during this handoff; branch was already clean and pushed.\n\n## Target\n- Base: platform-dev\n- Head/topic: 386-review-publication-resolution-workflow-v1 Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #457
53 KiB
Feature Specification: Spec 386 - Review Publication Resolution Workflow v1
Feature Branch: 386-review-publication-resolution-workflow-v1
Created: 2026-06-18
Status: Draft / Ready for implementation planning review
Input: User-provided draft candidate "Spec 386 - Review Publication Resolution Workflow v1" from /Users/ahmeddarrazi/.codex/attachments/48ede29c-82e5-412d-b014-976812779abd/pasted-text.txt.
Repo-Truth Adjustment
The user supplied a complete numbered draft for Spec 386 after Spec 385. Repo truth confirms:
docs/product/spec-candidates.mdexplicitly states that no safe automatic next-best-prep target remains in the active queue.- The candidate is therefore treated as a direct manual promotion, not as an auto-selected backlog item.
specs/385-evidence-review-readiness/is implemented and becomes dependency context only.- Specs 350, 351, and 367 provide existing derived guidance and OperationRun actionability foundations, but they do not persist a review-publication-specific resolution workflow.
- No existing
specs/386-*package or local/remote386-*branch was found before the Spec Kit create script ran.
The draft proposed mildly generic action_resolution_cases and action_resolution_steps table names. This preparation narrows that by default:
- V1 persistence should be review-publication-specific, for example
review_publication_resolution_casesandreview_publication_resolution_steps. - A generic
action_resolution_*schema is not approved by default because it would imply a broader workflow foundation before multiple real persisted cases exist. - Implementation may use generic names only if it updates this spec/plan/tasks first with a bounded proportionality defense and constraints proving it remains
action_key=review.publicationonly.
Candidate Selection Gate
- Selected candidate: Spec 386 - Review Publication Resolution Workflow v1.
- Source: Direct user-provided candidate attachment.
- Why selected: The active automatic queue is empty, and the user provided the next numbered manual candidate. It directly follows implemented Spec 385 by turning specific publication blockers into a guided, auditable operator workflow.
- Roadmap relationship: Supports R2 Evidence & Exception Workflows, customer-safe review consumption, Governance-of-Record auditability, OperationRun-backed proof, and operator workflow compression.
- Close alternatives deferred:
- Management Report PDF runtime validation remains tied to Specs 378-380 and staging/Dokploy runtime validation.
- Governance artifact lifecycle retention runtime remains manual promotion only.
- Provider readiness onboarding productization remains optional manual promotion only.
- Cross-domain indicator runtime follow-through remains a broader guardrail lane.
- Generic Resolution Proof & Currentness Contract, Restore adapter, Provider onboarding adapter, and Cross-Tenant Promotion adapter are follow-up candidates only.
- Completed-spec guardrail result:
specs/350-operator-resolution-guidance-framework-v1/,specs/351-review-output-resolve-actions-v1/, andspecs/385-evidence-review-readiness/are dependency context only.specs/381-*throughspecs/384-*contain close-out or completed-task signals and must not be modified by this work.specs/367-operationrun-actionability-system/has an implementation close-out file and is treated as completed OperationRun context.
- Smallest viable implementation slice: Create or resume one persistent Review Publication Resolution Case for one blocked Environment Review, derive ordered steps from existing readiness truth, link OperationRun/artifact proof, support pause/resume/currentness, and return the operator to existing publication only when current readiness is satisfied.
- Gate result: PASS. The candidate is direct user input, unprepared, not completed, roadmap-aligned, bounded to one workflow, and the broader generic workflow follow-ups are explicitly out of scope.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: A blocked Environment Review can explain that publication is unsafe, but the operator still has to reconstruct the exact next safe action across Evidence, Stored Reports, Review Packs, OperationRuns, baseline readiness, permission posture, and technical detail surfaces.
- Today's failure: Operators see "Publication blocked" or "Output not customer-ready" states but must infer whether to collect evidence, generate reports, refresh review composition, inspect a failed run, generate a review pack, or wait for a current OperationRun.
- User-visible improvement: The Review surface exposes one dominant "Resolve publication blockers" action. The operator enters a persistent, proof-linked workflow that shows ordered steps, one current next action, proof state, and safe return to publication.
- Smallest enterprise-capable version: One review-publication-specific case and step persistence model; one evaluator/planner over existing review/evidence/report/pack readiness; one subject-driven Filament resolution page or page action; focused RBAC, audit, OperationRun/proof, customer-boundary, and browser coverage.
- Explicit non-goals: No generic workflow engine, no BPMN/process designer, no global resolution-case resource, no top-level navigation, no automatic publish, no customer self-resolution, no Restore/provider/baseline/report-delivery adapters, no AI workflow, no generic proof/currentness platform, no cross-tenant promotion workflow, and no broad dashboard or Governance Inbox rebuild.
- Permanent complexity imported: Two narrow persisted entities/tables, case and step status families, one readiness/result DTO family, one review-specific evaluator/planner/case/action/proof service set, policy/audit/tests, one new subject-driven operator surface, and browser smoke coverage.
- Why now: Spec 385 made publication blockers more precise. The remaining product gap is workflow compression: operators need TenantPilot to turn those blockers into a guided, resumable resolution path instead of raw troubleshooting.
- Why not local: A local CTA or copy change would still leave long-running actions, proof links, stale/currentness, pause/resume state, RBAC, and audit scattered across separate surfaces. Persistence is justified because an operator may leave and return after queued operations or permission fixes.
- Approval class: Core Enterprise.
- Red flags triggered: New persistence, new status families, new DTO/service layer, and workflow-like terminology. Defense: the scope is one current operator workflow, persistence has independent lifecycle and audit need, execution/artifact truth remains in existing records, no generic engine is approved, and broader adapters are follow-up specs only.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 1 | Gesamt: 10/12
- Decision: approve as a bounded Core Enterprise workflow-compression slice with strict no-generic-engine constraints.
Problem Statement
TenantPilot can already derive publication blockers and customer-readiness states for review output. However, blocked publication still reads like a diagnostic condition instead of an operator workflow.
The operator must currently answer questions manually:
- Which evidence dimension is missing or stale?
- Which StoredReport must be generated or refreshed?
- Is baseline drift posture missing, empty, stale, limited, or failed?
- Is permission posture missing or stale?
- Was an OperationRun already started?
- Did the run fail, or did a newer proof supersede it?
- Which artifact is current proof?
- Should the review be refreshed?
- Is a Review Pack/export still missing?
- When is publication safe again?
Spec 386 turns those questions into one guided, resumable Review Publication Resolution workflow.
Business / Product Value
- Compresses blocked review publication from cross-page troubleshooting into one guided operator flow.
- Keeps TenantPilot honest about customer readiness and avoids false "ready to publish" states.
- Uses OperationRun as execution truth and evidence/report/review/pack artifacts as output truth.
- Creates an audit trail for resolution lifecycle events.
- Supports long-running operations and pause/resume without inventing a generic workflow engine.
- Keeps customer-facing review surfaces clean and free of internal remediation details.
Primary Users / Operators
- MSP or tenant operator preparing an Environment Review for customer publication.
- Workspace manager responsible for review output quality and customer-safe handoff.
- Support/platform operator diagnosing why publication is blocked.
- Read-only customer/auditor users who must not see internal resolution cases or technical OperationRun detail.
Spec Scope Fields (mandatory)
- Scope: tenant-owned review/evidence/output workflow inside established workspace and managed-environment boundaries.
- Primary Routes:
- existing Environment Review detail route(s);
- one new subject-driven resolution route/page/action under the Environment Review flow, for example an existing resource page route like
/admin/.../environment-reviews/{record}/resolve-publication; - existing Evidence Snapshot, Stored Report, Review Pack, OperationRun, and Baseline Subject Resolution destinations as linked proof or next-action targets only;
- Customer Review Workspace only for non-leakage regression and safe preparation wording.
- Data Ownership:
EnvironmentReview,EvidenceSnapshot,StoredReport,ReviewPack, andOperationRunremain source-of-truth records.- Review Publication Resolution Case stores operator workflow state, current step, scope, actor metadata, proof references, and readiness fingerprint only.
- The case must not store raw provider payloads, full report content, full evidence JSON, secrets, tokens, or customer-private evidence beyond safe identifiers.
- RBAC:
- Workspace membership and managed-environment entitlement are required to view the resolution case.
- Viewing the case does not grant permission to execute every step.
- Each step action must enforce the same policy/capability as the underlying review, evidence, report, or review-pack operation.
- Non-member or non-entitled access is deny-as-not-found; entitled users missing a capability receive a safe blocked/forbidden state according to existing policy behavior.
For canonical-view specs:
- Default filter behavior when tenant-context is active: existing route-owned workspace/environment context remains. No retired
/admin/tTenant Panel behavior is revived. - Explicit entitlement checks preventing cross-tenant leakage: every case, step, subject, proof, operation, and artifact reference must resolve through workspace and managed-environment scoped queries/policies before rendering or mutation.
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
Clarification: the "dangerous action" impact is high-impact workflow/action surfacing, not destructive external mutation. Publication remains controlled by the existing publish action and is never auto-executed by this spec.
UI/Productization Coverage (mandatory when UI Surface Impact is not "No UI surface impact")
- Route/page/surface:
- existing Environment Review detail blocked-state / publication-readiness area;
- new Review Publication Resolution subject-driven page or page-action surface;
- new resolution case step cards/state presentation;
- existing OperationRun/evidence/report/review-pack linked proof destinations;
- Customer Review Workspace safe non-leakage state.
- Current or new page archetype: existing Environment Review detail plus new workflow/detail surface under the review flow. No top-level navigation or CRUD resource archetype.
- Design depth: Strategic Surface / Primary Decision Surface for the resolution page; Domain Pattern Surface for Environment Review blocked-state integration.
- Repo-truth level: repo-verified existing review/evidence/report/pack/operation truth; spec-only for the new persistent resolution case.
- Existing pattern reused: existing Environment Review detail,
ReviewPackOutputResolutionGuidance, existingResolutionGuidancederived case/action contract,OperationRunLinks,OperationUxPresenter, badge catalog/domain badges,UiEnforcement/WorkspaceUiEnforcement, and existing review/evidence/pack service actions. - New pattern required: one review-publication-specific workflow page and persisted case/step state. No global resolution pattern, no generic CRUD resource, no top-level navigation.
- Screenshot required: yes. Implementation must capture the blocked CTA, open case, running/failed/proof-completed states, ready-to-return state, customer no-leakage path, and dark/mobile smoke where feasible.
- Page audit required: yes. Implementation must update the relevant existing page report or create a new page report for the resolution workflow, plus update the route inventory/design matrix for the new reachable review-owned route/page-action surface.
- Customer-safe review required: yes. Customer-facing surfaces must not expose internal case, step, run-debug, permission blocker, or raw technical details.
- Dangerous-action review required: yes for high-impact queued/actions and cancel/supersede behavior. Each mutating/high-impact action must preserve authorization, audit, the confirmation behavior defined below, notification, OperationRun link behavior, and tests.
- Coverage files updated or explicitly not needed:
docs/ui-ux-enterprise-audit/route-inventory.mddocs/ui-ux-enterprise-audit/design-coverage-matrix.mddocs/ui-ux-enterprise-audit/page-reports/...docs/ui-ux-enterprise-audit/strategic-surfaces.mddocs/ui-ux-enterprise-audit/grouped-follow-up-candidates.mddocs/ui-ux-enterprise-audit/unresolved-pages.mdN/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, next-action guidance, header/page actions, OperationRun proof links, evidence/report viewers, customer-safe disclosure, audit events, badge/status presentation.
- Systems touched:
EnvironmentReviewResource/ViewEnvironmentReview;EnvironmentReviewReadinessGate,EnvironmentReviewComposer, and lifecycle/refresh services;EvidenceSnapshotServiceand evidence readiness paths;- Stored report generation services such as permission posture/admin roles where repo-real;
ReviewPackService/GenerateReviewPackJob;OperationRunService,OperationRunLinks,OperationUxPresenter, reconciliation/actionability helpers;- existing
ResolutionGuidanceDTO/derived case/action support; - audit logging helpers and capability/UI enforcement helpers.
- Existing pattern(s) to extend: review-output resolution guidance, existing source-owned Filament actions, existing OperationRun start/link UX, and existing badge/disclosure patterns.
- Shared contract / presenter / builder / renderer to reuse: existing
ResolutionGuidance\ResolutionCaseandResolutionActionmay inform presentation, but persisted case state must be a new review-publication-specific model/service, not a replacement for existing derived guidance. - Why the existing shared path is sufficient or insufficient: existing paths can explain blockers and select next actions, but they do not persist operator workflow state, step proof, pause/resume, or readiness fingerprint over long-running operations.
- Allowed deviation and why: one review-publication-specific persisted workflow service and page are allowed because the operator workflow must survive navigation and queued operation completion. A generic registry/adapter framework is not allowed.
- Consistency impact: the blocked review state, resolution page, step cards, OperationRun proof, ReviewPack readiness, and customer-safe output must agree about the same publication-readiness truth.
- Review focus: prevent duplicate truth, stale proof, fake enabled actions, raw technical leakage, missing policy checks, and generic workflow spread.
OperationRun UX Impact (mandatory)
- Touches OperationRun start/completion/link UX?: yes.
- Shared OperationRun UX contract/layer reused: existing
OperationRunService, jobs,OperationRunLinks,OperationUxPresenter, operation notifications, and reconciliation/actionability layers. - Delegated start/completion UX behaviors: queued toast, run links, artifact links, dedupe/already-running messaging, blocked/failed-to-start messaging, browser event, terminal notifications, and tenant/workspace-safe URL resolution must use existing shared paths.
- Local surface-owned behavior that remains: internal case status/current step selection, operator-facing next-action explanation, collapsed proof reference display, and "Return to review" behavior.
- Queued DB-notification policy: no new queued DB-notification policy unless the underlying existing operation already uses one or this spec is updated before implementation.
- Terminal notification path: central lifecycle mechanism remains authoritative.
- Exception required?: none approved. Any exception must be documented in spec/plan/tasks before implementation.
OperationRun remains execution truth. The resolution step may link an operation_run_id; it must not duplicate run status as canonical truth.
Provider Boundary / Platform Core Check (mandatory)
- Shared provider/platform boundary touched?: yes, indirectly.
- Boundary classification: platform-core for review publication workflow, readiness, operation proof, artifact proof, and operator vocabulary; provider-owned for any raw Microsoft/provider identifiers or Graph payload detail.
- Seams affected: evidence/report readiness, baseline posture, permission posture, review output readiness, stored report proof, OperationRun proof, and provider-resource/baseline proof links.
- Neutral platform terms preserved or introduced: Review Publication Resolution Case, resolution step, publication blocker, evidence basis, report requirement, operation proof, artifact proof, readiness fingerprint, customer-ready output.
- Provider-specific semantics retained and why: provider/Microsoft identifiers may remain internal proof or support diagnostics only where existing services already expose them safely. They must not appear in customer-facing default output or primary operator copy.
- Why this does not deepen provider coupling accidentally: the workflow is anchored to Environment Review publication, not Microsoft-specific provider actions. It calls existing domain services and does not introduce Graph endpoints or provider-specific contracts.
- Follow-up path: provider onboarding/permissions adapter and generic proof/currentness contract remain future specs.
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 |
|---|---|---|---|---|---|---|
| Environment Review blocked publication CTA | yes | Native Filament resource/detail plus existing Blade/infolist patterns | review readiness, next-action guidance | detail, action state | no | Existing detail route changed with one primary CTA |
| Review Publication Resolution workflow | yes | New Filament page or subject-driven action surface | workflow/detail, steps, proof links | page, persisted case, step state | yes | New strategic workflow surface, no top-level nav |
| Resolution step actions | yes | Filament actions using existing source-owned services | OperationRun UX, audit, RBAC | step action, run link, artifact link | yes | High-impact actions must preserve shared start/action contracts |
| Customer Review Workspace non-leakage | yes | Existing customer-safe workspace surface | customer-safe disclosure | page/readiness copy | no | No internal resolution detail by default |
| OperationRun/artifact proof links | yes | Existing OperationRun/evidence/report/pack destinations | proof/readiness viewers | URL/link state | no | Navigation only; no local OperationRun lifecycle handling |
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 |
|---|---|---|---|---|---|---|---|
| Environment Review blocked state | Primary Decision Surface | Operator decides how to start resolving publication blockers | blocked state, reason summary, impact, one CTA | evidence basis, technical details, proof links | Primary because publication decision starts here | review publication workflow | removes cross-page blocker interpretation |
| Review Publication Resolution page | Primary Decision Surface | Operator resolves the current blocker step by step | blocked reason, missing requirements, next safe action, no-auto-publish note | completed steps, technical detail, operation/artifact proof | Primary because it owns the resolution workflow | pause/resume and proof-linked resolution | reduces search across evidence, reports, operations, and packs |
| OperationRun detail | Tertiary Evidence / Diagnostics | Operator inspects run proof or failure | run status and safe summary | full diagnostics per existing route/policy | Not primary because execution truth is proof, not the workflow owner | supports step proof | keeps failed-run detail out of default workflow cards |
| Customer Review Workspace | Secondary Context / Customer-Safe Surface | Customer or operator consumes ready output | safe preparation or latest customer-ready review state | none by default for internal resolution | Not primary for resolution | customer-safe review consumption | avoids exposing remediation/debug detail |
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 |
|---|---|---|---|---|---|---|---|
| Review Publication Resolution page | operator-MSP, manager, support-platform | operator-state title, publication blocked state, missing required reports, next safe action, compact preparation progress, what happens after this, no-auto-publish note | technical proof and operation history, readiness fingerprint/currentness | raw provider/report/evidence payloads never default; support detail only through existing gated surfaces | yes | raw provider payloads, report contents, full evidence JSON, internal reason families, proof/operation links by default, implementation terms such as report-backed evidence | page states blocker once; proof sections add evidence only on demand |
| Environment Review detail | operator-MSP, manager | publication state, reason summary, CTA | blocker list, evidence basis, operation proof | raw/support detail existing/gated | resolve publication blockers | internal case detail hidden until CTA | same readiness evaluator drives CTA and case |
| Customer Review Workspace | customer-safe, operator-MSP | latest customer-ready review or safe "being prepared" state | none by default | no internal resolution case, failed run debug, permission internals | view/download current customer-ready output when available | resolution case, step list, OperationRun debug | customer copy does not duplicate operator blocker text |
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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Environment Review detail blocked state | Detail / Review Context | Existing review detail | resolve publication blockers | existing detail page | current behavior | proof/detail links below CTA | existing dangerous actions unchanged | existing review register | existing review detail | workspace + environment | Environment review | publication blocked, reason, impact, one CTA | none |
| Review Publication Resolution | Workflow / Primary Decision | Subject-driven workflow detail | execute current resolution step, then inspect proof only if needed | direct page/action route from review | N/A | proof links and technical details collapsed | cancel/supersede grouped under More and confirmation-gated if mutating | no collection route in v1 | review-owned resolve-publication route | workspace + environment + review | Review publication resolution | blocked reason, required reports, next safe action, compact preparation progress | special workflow surface; no CRUD resource |
| Resolution step card | Workflow / Step | Step card | run/open/retry the one current step action | expanded current step | N/A | supporting links in collapsed technical proof section | retry/cancel confirmation per action risk | N/A | same workflow page | inherited from case | Resolution step | operator step label, status, safe action meaning | one-primary-action exception to ordinary table patterns |
| Customer Review Workspace preparation state | Utility / Workspace Decision | Customer-safe review hub | wait for or open current customer-ready review | existing workspace page | N/A | existing customer-safe supporting links | none in scope | /admin/reviews/workspace |
existing review/pack detail | workspace + environment filter | Customer review output | safe availability/preparation state | non-leakage guard only |
UI Action Matrix (mandatory when Filament is changed)
| Surface | Location | Header Actions | Inspect Affordance | Row Actions | Bulk Actions | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| Environment Review detail | apps/platform/app/Filament/Resources/EnvironmentReviewResource.php and Pages/ViewEnvironmentReview.php |
Add or reprioritize Resolve publication blockers only when blocked |
Existing detail inspect model unchanged | Existing list row actions unchanged | Existing bulk behavior unchanged | Existing empty state unchanged | Publish/refresh/export actions remain guarded | N/A | Existing + new resolution lifecycle audit | The CTA must not compete with publish when blocked |
| Review Publication Resolution page | new review-owned Filament page or action surface | One primary current-step action, Back to review, grouped More menu for cancellation | Page is opened from subject review | N/A | none | Ready/no-blocker state returns to review | N/A | yes for case/step lifecycle | New strategic workflow surface; no resource/global search | |
| Resolution step actions | new page/action class | One visible primary step action | N/A | N/A | none | N/A | N/A | N/A | yes for step start/link/complete/fail/cancel | Step actions call services; no business logic in Blade |
| Customer Review Workspace | existing page/view | unchanged except safe wording if needed | N/A | N/A | N/A | unchanged | existing links only | N/A | unchanged | Must not expose case/step/run-debug by default |
Filament v5 requirements for implementation:
- Livewire v4.0+ compliance is mandatory; this repo uses Livewire 4.1.4.
- Panel providers stay in
apps/platform/bootstrap/providers.php; no provider registration change is planned. - No global-searchable Resolution Case resource is approved. If a model-backed resource is created contrary to this spec, global search must be disabled unless it has a safe View/Edit page and scoped URLs.
- Destructive/high-impact actions must use
Action::make(...)->action(...), server-side authorization, the confirmation behavior defined in this spec, audit, notification, and tests. Do not assume confirmation behavior on URL-only actions. - No Filament asset registration is planned. If implementation registers assets, deploy must include
cd apps/platform && php artisan filament:assets.
Action confirmation contract:
| Action | Mutation / Scope | Confirmation Required? | Notes |
|---|---|---|---|
Resolve publication blockers |
Creates or resumes an internal TenantPilot resolution case only | No | Must communicate TenantPilot-only scope near the action and audit create/resume. |
| Current step action that queues report, evidence, review refresh/composition, review-pack generation, or regeneration | Queues TenantPilot artifact/workflow work through existing services and may create/reuse an OperationRun |
Yes | Must use Action::make(...)->action(...), server-side authorization, audit, notification, and OperationRun link behavior. |
| Retry failed actionable step | Same behavior as the underlying current step action | Yes when retry queues/regenerates work; no when it only opens an existing proof/run | Retry availability must follow underlying capability and stale-proof rules. |
| Open OperationRun, artifact proof, technical detail, or return to review | Navigation only | No | These may use URL/navigation actions and must not mutate state. |
| Cancel an active case | Mutates internal case lifecycle | Yes | Must be grouped/demoted, audited, and authorization-gated. |
| Operator-triggered supersede/restart of a stale case | Mutates internal case lifecycle and creates or resumes the current case | Yes | Automatic supersession during service re-evaluation may occur without modal but must be audited and must not publish. |
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 |
|---|---|---|---|---|---|---|---|---|---|---|
| Environment Review blocked state | MSP/workspace operator | Start resolving blockers for a blocked review | review detail | Can this review be published, and if not what starts resolution? | publication blocked, blocker summary, impact, CTA | technical details, evidence basis, operation proof | review lifecycle, publication readiness, artifact readiness | TenantPilot only / queued internal work | Resolve publication blockers | existing publish remains blocked by gates |
| Review Publication Resolution page | MSP/workspace operator | Work through a guided resolution case | workflow detail | Why can this review not be published, and what should I safely do next? | operator-state title, blocked reason, missing required reports, next safe action, compact preparation progress, what happens after this | technical proof, operation/artifact references, fingerprint/currentness | review readiness, step status, run status, artifact currentness | TenantPilot state and existing queued operations; no auto-publish | current step action, return to review; proof links only on demand | cancel/supersede grouped under More and queued regeneration actions as high-impact |
| Customer Review Workspace preparation state | customer-safe viewer / operator | Consume only customer-ready review output | customer-safe review hub | Is customer-ready output available? | safe availability/preparation state | none by default | output readiness only | none | view/download current ready output | none in scope |
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: yes, but only for operator resolution workflow state. It is not truth for readiness, execution, artifacts, or publication safety.
- New persisted entity/table/artifact?: yes. Review Publication Resolution Case and Step persistence are approved for this one workflow because the case must survive navigation, queued operations, and support audit.
- New abstraction?: yes. One review-specific evaluator/planner/case/action/proof service family is approved. Generic registries/adapters are not approved.
- New enum/state/reason family?: yes for case and step status families only. They are approved because they change routing, actionability, audit, and pause/resume behavior. No persisted reason-code family is approved in v1.
- New cross-domain UI framework/taxonomy?: no.
- Current operator problem: blocked publication forces manual cross-surface troubleshooting and loses continuity after long-running operations.
- Existing structure is insufficient because: existing derived guidance does not persist case/step state, actor metadata, currentness/fingerprint, proof links, or pause/resume lifecycle.
- Narrowest correct implementation: one review-publication-specific persisted case/step model, one evaluator/planner over existing readiness truth, one subject-driven page/action, and direct reuse of existing services for execution.
- Ownership cost: migrations, models, policy, services, audit events, tests, one new workflow page, UI coverage artifacts, and ongoing status/currentness semantics.
- Alternative intentionally rejected: a generic action-resolution engine, transient-only guidance cards, page-local copy changes, or auto-running all blocker steps.
- Release truth: current-release product truth after implemented Spec 385.
Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility readers, old case/state aliases, migration shims, dual-write logic, legacy OperationRun readers, or old evidence/review payload compatibility are out of scope unless this spec is explicitly updated before implementation.
Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)
- Test purpose / classification: Unit for readiness evaluator/planner/proof resolver; Feature for persistence, policy, audit, OperationRun/artifact proof, case lifecycle, and customer-boundary behavior; Filament/Livewire Feature for actions/page states; PostgreSQL for migrations/constraints/indexes; Browser for critical workflow smoke.
- Validation lane(s): fast-feedback, confidence, pgsql, browser.
- Why this classification and these lanes are sufficient: the feature adds persistence, policy-sensitive workflow state, queued-operation proof, and a new operator workflow surface. Unit/Feature prove behavior; pgsql proves JSONB/index/constraint behavior; browser proves the real guided workflow is usable and non-leaky.
- New or expanded test families: new focused Spec 386 unit/feature/Filament/browser families. No heavy-governance family unless implementation widens discovery/surface scanning.
- Fixture / helper cost impact: review/evidence/report/OperationRun fixtures may be expensive; any new setup must remain explicit and local to Spec 386 tests unless existing helpers already cover it cheaply.
- Heavy-family visibility / justification: no heavy-governance family planned. Browser smoke is explicit and bounded.
- Special surface test profile: workflow detail surface plus shared-detail-family proof links. Native Filament relief applies only where existing resources are not structurally changed.
- Standard-native relief or required special coverage: the new workflow page requires special coverage for one-primary-action, step states, proof links, RBAC disabled/denied states, and customer non-leakage.
- Reviewer handoff: verify no generic engine, no stale proof, no customer leakage, correct 404/403 semantics, no Graph calls during render, and no direct OperationRun lifecycle transitions outside services.
- Budget / baseline / trend impact: pgsql and browser lanes are expected additions. Document-in-feature if fixture/runtime cost grows materially.
- Escalation needed: document-in-feature for bounded implementation decisions; follow-up-spec for generic proof/currentness, additional adapters, customer self-resolution, or lifecycle retention.
- Active feature PR close-out entry: Review Publication Resolution Workflow.
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/ReviewPublicationResolutioncd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ReviewPublicationResolution tests/Feature/EnvironmentReview tests/Feature/ReviewPackcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/Spec386ReviewPublicationResolutionUiTest.phpcd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml --filter Spec386cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec386ReviewPublicationResolutionWorkflowTest.phpcd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentgit diff --check
User Scenarios & Testing (mandatory)
User Story 1 - Operator starts resolution from a blocked review (Priority: P1)
As an operator, I need a blocked Environment Review to expose one clear primary action so I can start resolving publication blockers without searching across evidence, reports, operations, and packs.
Why this priority: This is the entry point and visible workflow compression.
Independent Test: Render a blocked Environment Review and verify one primary CTA, blocked reason summary, impact copy, and no misleading publish/refresh primary action.
Acceptance Scenarios:
- Given an Environment Review has publication blockers, When I view the review, Then I see "Resolve publication blockers" as the one primary CTA with blocked reason and impact.
- Given publication is blocked, When the review actions render, Then publish remains blocked by existing gates and refresh is not promoted as the main next step.
- Given no blockers exist, When I view the review, Then no new resolution case is created and the UI shows ready/return behavior.
User Story 2 - Operator opens or resumes a persistent case (Priority: P1)
As an operator, I need the resolution workflow to create or resume one active case so I can return after long-running operations or permission fixes.
Why this priority: Persistence is the main justification for the new entity.
Independent Test: Start resolution from a blocked review twice and assert the same active case resumes when the readiness fingerprint still matches.
Acceptance Scenarios:
- Given blockers exist and no active current case exists, When I click the CTA, Then TenantPilot creates a Review Publication Resolution Case and ordered steps.
- Given a current active case exists, When I open resolution again, Then the same case resumes.
- Given readiness fingerprint changed materially, When I open resolution, Then the case re-evaluates and updates or supersedes stale steps safely.
User Story 3 - Operator follows ordered steps with proof (Priority: P1)
As an operator, I need ordered steps with one current primary action and proof state so I know what to do next and what already happened.
Why this priority: This turns diagnostics into a product workflow.
Independent Test: Seed cases for missing reports, missing evidence, failed run, running run, completed proof, and ready-to-return states, then verify step status/action/proof behavior.
Acceptance Scenarios:
- Given missing required reports, When the plan renders, Then a complete-required-reports step is actionable with one primary action.
- Given a step starts an async operation, When an OperationRun is created, Then the step links that run and the case becomes waiting-for-run.
- Given a run fails, When the case re-evaluates, Then the step becomes failed and the primary action opens the failed operation or offers retry only when allowed.
- Given a required artifact is current, When the case re-evaluates, Then the step shows artifact proof and completes.
User Story 4 - Truth remains in existing domains (Priority: P1)
As a platform operator, I need the case to point to evidence/report/review/pack/run truth instead of becoming a second readiness system.
Why this priority: Avoiding duplicate truth is central to the architecture.
Independent Test: Change current evidence/report/review/pack state after a case exists and assert final readiness follows current domain truth, not stale step metadata.
Acceptance Scenarios:
- Given old successful proof exists, When relevant review/evidence/report state changes, Then old proof is not treated as current completion.
- Given a newer successful proof supersedes an older failed run, When the case renders, Then the old failure is not the current blocker.
- Given all blockers are resolved, When readiness is evaluated, Then the case completes only if current readiness says publication blockers are resolved.
User Story 5 - RBAC, audit, and customer boundaries hold (Priority: P1)
As a workspace manager, I need resolution cases to respect workspace/environment scope, capabilities, auditability, and customer-safe disclosure.
Why this priority: The workflow handles governance output and proof near customer handoff.
Independent Test: Exercise view/start/step actions as owner/operator/readonly/foreign workspace/customer-safe users and assert 404/403/safe blocked states, audit events, and no customer leakage.
Acceptance Scenarios:
- Given a user lacks workspace or environment entitlement, When they request a case or proof link, Then TenantPilot denies as not found.
- Given a readonly user can view safe status but lacks a step capability, When the step renders, Then the action is not executable and shows a permission-safe explanation.
- Given a step starts, links an operation, completes, fails, cancels, or supersedes, When the event occurs, Then an audit log entry records safe identifiers and no raw payloads.
- Given a customer-safe user opens Customer Review Workspace, When a resolution case exists internally, Then no case, step, OperationRun debug, permission internals, or technical remediation details are exposed by default.
Functional Requirements (mandatory)
- FR-386-001: A blocked Environment Review MUST show one primary "Resolve publication blockers" CTA with reason summary and impact.
- FR-386-002: The CTA MUST create or resume one active Review Publication Resolution Case for the same workspace, environment, subject, action, and current readiness fingerprint.
- FR-386-003: No case MUST be created when current readiness has no publication blockers.
- FR-386-004: The case MUST derive requirements from existing review/evidence/report/review-pack readiness truth and MUST NOT duplicate those domains as canonical truth.
- FR-386-005: The case MUST persist case status, current step, actor metadata, readiness fingerprint, and safe summary metadata.
- FR-386-006: Steps MUST persist ordered step state, one step key, one current primary action, one primary OperationRun proof link when relevant, and one primary artifact proof reference when relevant.
- FR-386-007: Step planning MUST include only relevant required steps plus a return-to-publication step; it MUST NOT always show every possible step.
- FR-386-008: V1 step keys MUST remain bounded to review publication:
validate_review_readiness,complete_required_reports,collect_evidence_snapshot,refresh_review_composition,generate_review_pack, andreturn_to_publication. - FR-386-009: Step actions MUST reuse existing domain services/actions/jobs for reports, evidence snapshots, review refresh/composition, and review-pack generation.
- FR-386-010: Step actions MUST NOT publish the review automatically.
- FR-386-011: OperationRun status/outcome MUST remain execution truth and MUST NOT be copied as canonical case truth.
- FR-386-012: EvidenceSnapshot, StoredReport, EnvironmentReview, and ReviewPack currentness MUST remain artifact truth.
- FR-386-013: Case completion MUST occur only after current readiness evaluation says publication blockers are resolved.
- FR-386-014: Old/stale OperationRuns or artifacts MUST NOT complete current steps after readiness fingerprint/currentness changes.
- FR-386-015: Zero findings or zero drift MUST be treated as complete only when the relevant source was evaluated successfully and current readiness allows it.
- FR-386-016: Existing publish/export gates MUST still run and MUST still block unsafe publication.
- FR-386-017: Customer-facing surfaces MUST NOT expose internal resolution case details, step lists, failed OperationRun debug, permission blocker internals, raw report state, raw provider payloads, or raw evidence JSON.
- FR-386-018: Workspace/environment isolation MUST be enforced on case, step, subject, proof, operation, and artifact resolution.
- FR-386-019: Each step action MUST enforce the underlying capability/policy server-side and expose safe disabled/blocked UI state.
- FR-386-020: Audit events MUST be emitted for case creation/resume, step start, operation link, step completion/failure, case completion, cancellation, and supersession.
- FR-386-021: The implementation MUST NOT add a top-level navigation item, generic CRUD resource, global search resource, or generic workflow registry for resolution cases in v1.
- FR-386-022: The implementation MUST update UI coverage artifacts for the new reachable workflow surface and affected review/customer-safe surfaces.
Non-Functional Requirements
- NFR-386-001 - Auditability: Case and step lifecycle changes must be traceable through audit logs with safe identifiers.
- NFR-386-002 - Source-of-Truth Separation: Readiness, execution, and artifact truth stay in existing services/models; the case stores workflow state and proof references only.
- NFR-386-003 - Customer Safety: Customer-facing output remains free of internal resolution and debug details.
- NFR-386-004 - Determinism: The same current readiness inputs must produce the same step plan and readiness fingerprint.
- NFR-386-005 - Performance: Resolution rendering must be DB-local and must not call Graph/provider APIs during UI render.
- NFR-386-006 - Accessibility and Usability: The workflow must show one dominant current action, clear status, safe explanations, and progressive technical detail.
- NFR-386-007 - Least Privilege: View, execute, proof, and technical detail access must be separately authorized where needed.
- NFR-386-008 - Bounded Architecture: No generic workflow engine, registry, adapter framework, or cross-domain proof platform is introduced.
Key Entities / Truth Sources
- EnvironmentReview: subject and review lifecycle/publication truth.
- EvidenceSnapshot / EvidenceSnapshotItem: evidence artifact truth.
- StoredReport: report artifact truth.
- ReviewPack: export/package artifact truth.
- OperationRun: execution proof truth.
- Review Publication Resolution Case: new workflow-state record for one blocked review publication resolution.
- Review Publication Resolution Step: new workflow-step record tied to a case.
- Readiness fingerprint: hash or stable key derived from current publication-relevant state.
Case and Step Statuses
Case statuses:
open: case exists, no execution started.in_progress: operator is actively resolving blockers.waiting_for_run: a current step waits on an OperationRun.blocked: current step failed or needs external permission/action.ready_to_continue: prior action completed and the next operator step is available.completed: current readiness has no publication blockers.cancelled: operator cancelled the resolution case.superseded: subject/readiness changed enough that this case is no longer current.
Step statuses:
pendingactionablerunningfailedcompletedsuperseded
Requirement status may remain DTO-derived:
passedwarningblockedmissingstalerunningfailednot_applicableunknown
Every persisted status must have a behavioral consequence in actionability, routing, audit, or lifecycle handling.
V1 does not persist skipped, not_applicable, or a separate reason_code family for steps. Inapplicable requirements are omitted from persisted steps or represented only as DTO-derived readiness status. Operator-facing reasons remain derived from the evaluator/planner and may be rendered or copied into safe summary text, but they must not become a persisted reason-code enum/column unless this spec, plan, and tasks are updated with STATE-001 consequences and tests.
Assumptions
- Spec 385 is implemented and review/evidence/readiness blockers are specific enough for a planner to consume.
- Existing review, evidence, report, review-pack, and OperationRun services provide the execution primitives; implementation verifies exact class names before coding.
- Review publication is environment-scoped, so environment scope is required for this workflow even if the schema technically allows nullable environment references for future/non-review cases.
- Existing
ResolutionGuidancesupport can inform presentation but does not replace the need for persisted case/step state. - Existing action authorization and UI enforcement helpers are sufficient for step capability handling.
- Existing Customer Review Workspace can safely render a generic preparation/unavailable state without exposing internal case details.
Out of Scope
- Generic workflow engine, process designer, global action-resolution registry, or cross-domain resolution adapter framework.
- Restore readiness adapter.
- Provider onboarding/permissions resolution adapter.
- Baseline compare adapter beyond linked proof/next-action destinations.
- Report delivery readiness workflow.
- Cross-tenant promotion readiness workflow.
- Commercial billing resolution workflow.
- Private AI execution workflow.
- Customer-facing resolution workflow or customer self-remediation.
- Automatic execution of all resolution steps without operator intent.
- New top-level navigation for resolution cases.
- New generic CRUD resource or global search surface for resolution cases.
- Auto-publishing reviews.
- Raw provider/report/evidence payload storage in case metadata.
- Management Report PDF runtime changes.
- Legacy compatibility readers/shims for old readiness/case/status shapes.
Risks
- Overbuilding a generic workflow engine: mitigated by review-publication-specific models/services and no registry/top-level resource.
- Duplicating readiness or artifact truth: mitigated by deriving readiness on demand and storing only case/step/proof references.
- Stale proof: mitigated by readiness fingerprint and re-evaluation before completion.
- Customer leakage: mitigated by customer-safe tests and default hidden technical details.
- Button/action bloat: mitigated by one primary CTA on review and one primary action per current step.
- RBAC drift: mitigated by policy tests for view/start/step/proof/technical detail access.
- Fixture/test cost growth: mitigated by focused local fixtures and explicit pgsql/browser lanes.
Success Criteria (mandatory)
- A blocked review exposes one primary
Resolve publication blockersaction. - The action creates/resumes one current case and ordered step plan.
- Steps persist and resume across navigation.
- Current step has one primary action and a decision-first explanation of what is safe to do next.
- The resolution page title and default copy use operator-facing publication language, not implementation terms such as case status or report-backed evidence.
- OperationRun/artifact proof links are available behind explicit technical disclosure but are not canonical truth.
- Stale proof does not complete current steps.
- Case completes only when current readiness is unblocked.
- Existing publish gate still controls final publication.
- Customer-facing surfaces do not reveal internal resolution details.
- Workspace/environment isolation, step capability checks, and audit events are covered by tests.
- UI coverage artifacts and browser smoke evidence are included during implementation.
Open Questions
No product question blocks preparation.
Implementation must update this spec, plan, and tasks before adding any generic action_resolution_* schema, top-level resource, global search exposure, new workflow registry, customer-facing resolution feature, or auto-execution behavior.
Follow-Up Spec Candidates
- Spec 387 - Resolution Proof & Currentness Contract v1.
- Spec 388 - Governance Inbox Resolution Intake v1.
- Spec 389 - Restore Readiness Resolution Adapter v1.
- Spec 390 - Provider Onboarding & Permissions Resolution Adapter v1.
- Spec 391 - Evidence/Baseline Readiness Resolution Adapter v1.
- Spec 392 - Report Delivery Readiness Resolution v1.
- Spec 393 - Customer Review Workspace Resolution Consumption v1.
- Spec 394 - Cross-Tenant Promotion Readiness Resolution v1.
These must not be implemented as part of Spec 386.