## 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
24 KiB
Implementation Plan: Spec 386 - Review Publication Resolution Workflow v1
Branch: 386-review-publication-resolution-workflow-v1 | Date: 2026-06-18 | Spec: spec.md
Input: Feature specification from /specs/386-review-publication-resolution-workflow-v1/spec.md
Summary
Create a bounded, review-publication-specific resolution workflow for blocked Environment Reviews. The implementation should add narrow case/step persistence, derive a step plan from existing review/evidence/report/review-pack readiness, execute only source-owned domain actions, link OperationRun and artifact proof, support pause/resume/currentness, audit lifecycle events, and keep customer-facing surfaces free of internal resolution details.
The plan explicitly excludes a generic workflow engine, top-level navigation, global search, CRUD resource exposure, auto-publish behavior, cross-domain adapters, customer self-resolution, and generic proof/currentness infrastructure.
Technical Context
Language/Version: PHP 8.4.15
Primary Dependencies: Laravel 12.52.0, Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, PostgreSQL via Sail/Dokploy
Storage: New review-publication-specific case/step tables plus existing EnvironmentReview, EvidenceSnapshot, StoredReport, ReviewPack, and OperationRun truth.
Testing: Pest Unit, Feature, Filament/Livewire Feature, PostgreSQL migration/constraint lane, and one bounded Browser smoke.
Validation Lanes: fast-feedback, confidence, pgsql, browser.
Target Platform: Laravel monolith in apps/platform, Sail locally, Dokploy for staging/production.
Project Type: Laravel/Filament web application inside apps/platform.
Performance Goals: Resolution page renders from DB-local readiness and proof references; no Graph/provider calls during render; planner evaluation remains bounded to one review and its known evidence/report/pack/run references.
Constraints: no generic workflow registry; no raw provider/report/evidence payloads in case metadata; no direct OperationRun.status/outcome transitions outside existing services; no new panel provider or assets by default; no auto-publish.
Scale/Scope: one blocked Environment Review at a time, one active current resolution case per subject/action/currentness, ordered sequential steps for review publication only.
Existing Repository Surfaces Likely Affected
apps/platform/database/migrations/
apps/platform/app/Models/
apps/platform/app/Policies/
apps/platform/app/Services/EnvironmentReviews/
apps/platform/app/Services/Evidence/
apps/platform/app/Services/ReviewPacks/
apps/platform/app/Services/OperationRunService.php
apps/platform/app/Support/ResolutionGuidance/
apps/platform/app/Support/ReviewPacks/ReviewPackOutputResolutionGuidance.php
apps/platform/app/Support/ReviewPacks/ReviewPackOutputReadiness.php
apps/platform/app/Support/OpsUx/OperationUxPresenter.php
apps/platform/app/Support/OperationRunLinks.php
apps/platform/app/Support/Rbac/UiEnforcement.php
apps/platform/app/Support/Rbac/WorkspaceUiEnforcement.php
apps/platform/app/Filament/Resources/EnvironmentReviewResource.php
apps/platform/app/Filament/Resources/EnvironmentReviewResource/Pages/ViewEnvironmentReview.php
apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php
apps/platform/resources/views/filament/infolists/entries/environment-review-summary.blade.php
apps/platform/resources/views/filament/pages/reviews/customer-review-workspace.blade.php
apps/platform/tests/Unit/
apps/platform/tests/Feature/
apps/platform/tests/Browser/
docs/ui-ux-enterprise-audit/route-inventory.md
docs/ui-ux-enterprise-audit/design-coverage-matrix.md
docs/ui-ux-enterprise-audit/page-reports/
Likely new implementation paths, subject to repo verification:
apps/platform/app/Models/ReviewPublicationResolutionCase.php
apps/platform/app/Models/ReviewPublicationResolutionStep.php
apps/platform/app/Policies/ReviewPublicationResolutionCasePolicy.php
apps/platform/app/Support/ReviewPublicationResolution/
apps/platform/app/Filament/Resources/EnvironmentReviewResource/Pages/ResolveReviewPublication.php
If implementation proves an existing resource/page naming convention is better, use the repo convention and keep the subject-driven/no-top-level-nav boundary.
Data and Migration Plan
Prefer review-specific table names:
review_publication_resolution_cases
review_publication_resolution_steps
Case fields should include:
idworkspace_idrequiredmanaged_environment_idor the repo-current environment FK required for review publicationenvironment_review_idrequired or a subject reference constrained to Environment Review onlyaction_keyrequired and fixed toreview.publicationfor v1statuscurrent_step_keyreadiness_fingerprintlast_evaluated_atcreated_byassigned_tostarted_at,completed_at,cancelled_at,superseded_atsummaryJSONB for safe derived summarymetadataJSONB for safe workflow metadata only- timestamps
Step fields should include:
id- case FK
positionstep_keystatusprimary_action_keyoperation_run_idnullableproof_type,proof_id,proof_statusnullable- lifecycle timestamps
summaryJSONB for safe step summarymetadataJSONB for safe workflow metadata only- timestamps
Indexes/constraints:
- PostgreSQL-enforced unique active/current case constraint for one active case per workspace/environment/review/action/currentness, backed by transactional service locking/idempotency for double-click and concurrent Livewire requests.
- unique
case_id+step_key. - indexes for workspace/environment/action/status/current step/operation run/proof reference.
- PostgreSQL JSONB lane validation for JSONB/default/index behavior.
Do not use polymorphic subject persistence unless implementation updates this spec/plan/tasks first. A generic action_resolution_* schema requires a proportionality update before coding.
No persisted reason_code column or reason-code enum is approved in v1. Step reasons remain evaluator/planner-derived and may appear only as safe summary text unless the spec/plan/tasks are updated with STATE-001 consequences and tests.
UI / Surface Guardrail Plan
- Guardrail scope: existing Environment Review blocked-state change, new subject-driven resolution workflow page/action, high-impact step actions, OperationRun/artifact proof links, and customer-safe non-leakage.
- Affected routes/pages/actions/states/navigation/panel/provider surfaces:
- Environment Review detail
- new Review Publication Resolution page or page action route
- Customer Review Workspace non-leakage/preparation wording
- existing OperationRun/evidence/report/pack proof destinations
- No-impact class, if applicable: N/A.
- Native vs custom classification summary: use native Filament Resource/Page actions and shared primitives first. Custom Blade only where existing review summary/customer workspace views already use it.
- Shared-family relevance: next-action guidance, review readiness, OperationRun proof links, evidence/report viewers, audit/status messaging, customer-safe disclosure.
- State layers in scope: persisted case, persisted steps, page current step, detail action state, URL route parameters, proof links.
- Audience modes in scope: operator-MSP, workspace manager, support-platform, customer-safe viewer.
- Decision/diagnostic/raw hierarchy plan: decision-first blocked reason, missing requirements, next safe action, and no-auto-publish note by default; proof and diagnostics secondary/collapsed; raw/support detail never customer default.
- Raw/support gating plan: raw provider payloads, raw report content, full evidence JSON, internal reason families, and OperationRun context stay behind existing gated diagnostics or are not exposed.
- One-primary-action / duplicate-truth control: one primary CTA on blocked review and one primary action for the current step. Completed/secondary proof links are demoted into technical disclosure.
- Handling modes by drift class or surface: new strategic workflow surface is
review-mandatory; high-impact actions areexception-requiredonly if deviating from existing confirmation/audit patterns. - Repository-signal treatment: UI-COV-001 applies because a new reachable route/action surface is planned.
- Special surface test profiles: workflow detail surface, shared-detail-family, and browser smoke.
- Required tests or manual smoke: Unit, Feature, Filament/Livewire, PostgreSQL, and Browser smoke.
- Exception path and spread control: no generic workflow exception approved.
- Active feature PR close-out entry: Review Publication Resolution Workflow.
- UI/Productization coverage decision: update route inventory, design coverage matrix, and page reports for the new workflow surface and affected review/customer surfaces.
- Coverage artifacts to update:
docs/ui-ux-enterprise-audit/route-inventory.mddocs/ui-ux-enterprise-audit/design-coverage-matrix.md- relevant
docs/ui-ux-enterprise-audit/page-reports/...
- No-impact rationale: N/A.
- Navigation / Filament provider-panel handling: no top-level navigation and no panel provider changes. Laravel 12 panel providers remain in
apps/platform/bootstrap/providers.php. - Screenshot or page-report need: yes for the new workflow and blocked/recovery/customer-safe states.
Shared Pattern & System Fit
- Cross-cutting feature marker: yes.
- Systems touched: Review readiness, evidence/report/pack readiness, OperationRun proof, Filament action UX, audit logging, RBAC UI enforcement, customer-safe disclosure.
- Shared abstractions reused:
ReviewPackOutputResolutionGuidance,ReviewPackOutputReadiness,ResolutionGuidanceDTOs where useful,OperationRunLinks,OperationUxPresenter,BadgeCatalog,UiEnforcement,WorkspaceUiEnforcement, existing review/evidence/pack services. - New abstraction introduced? why?: yes, a review-publication-specific evaluator/planner/case/action/proof service family. It exists because the workflow must persist/resume state and proof over time.
- Why the existing abstraction was sufficient or insufficient: existing derived guidance can explain and select actions but cannot persist case lifecycle, steps, proof references, currentness, or audit lifecycle.
- Bounded deviation / spread control: no registry, no generic adapters, no cross-domain workflows. Namespace/service names should include
ReviewPublicationto preserve scope.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: yes.
- Central contract reused: existing OperationRun service/job creation and link/presenter helpers.
- Delegated UX behaviors: queued toast, run link, artifact link, run-enqueued browser event, dedupe/already-running messaging, blocked/failed-to-start messaging, tenant/workspace-safe URL resolution, and terminal notifications stay in shared/source-owned paths.
- Surface-owned behavior kept local: internal case status/current step selection, operator-facing next-action explanation, collapsed proof reference display, "Open operation", "Retry", and "Return to review" placement.
- Queued DB-notification policy: unchanged unless spec is updated.
- Terminal notification path: unchanged central lifecycle mechanism.
- Exception path: none approved.
Implementation must never mark OperationRun.status or OperationRun.outcome directly from the resolution page. It should link runs and re-evaluate domain truth.
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes, indirectly.
- Provider-owned seams: raw provider IDs, raw Graph payloads, provider permission details, and provider-specific report internals.
- Platform-core seams: review publication, evidence basis, report requirement, operation proof, artifact proof, readiness currentness, customer-ready boundary.
- Neutral platform terms / contracts preserved: review publication, resolution case, resolution step, publication blocker, proof reference, evidence basis, report requirement, artifact proof.
- Retained provider-specific semantics and why: only inside existing proof/diagnostics where needed; never as primary customer or operator workflow vocabulary.
- Bounded extraction or follow-up path: follow-up-spec for provider onboarding adapter or generic proof/currentness.
Constitution Check
- Inventory-first: readiness derives from last-observed evidence/review/report/pack truth; no provider calls during render.
- Read/write separation: publication is not automatic. Step actions that create/refresh TenantPilot artifacts or queue operations use existing services, explicit operator intent, authorization, audit, and tests.
- Graph contract path: no direct Graph calls. Any existing evidence/report generation must continue through approved services/jobs and
GraphClientInterface. - Deterministic capabilities: step action availability must derive from existing capabilities/policies and be testable.
- RBAC-UX:
/adminand/systemremain separated; non-members 404; entitled users missing capability get safe denial/disabled state; customer users cannot access case internals. - Workspace isolation: cases and proof links are workspace scoped.
- Tenant/environment isolation: review publication cases are environment scoped; no cross-environment proof leakage.
- Global search: no global-search resource for cases in v1.
- Destructive/high-impact actions: high-impact queued/artifact actions, retry that queues/regenerates work, case cancellation, and operator-triggered supersede/restart use
->action(...), authorization, confirmation, audit, notification, and tests. URL-only actions are navigation only. The initialResolve publication blockersCTA creates/resumes an internal TenantPilot case and does not require confirmation, but must communicate scope and audit create/resume. - Run observability: long-running/queued step actions create or reuse
OperationRunthrough existing paths and link the run to the step. - OperationRun start UX: shared start/link/presenter paths are reused; no local queued-toast/run-link composition.
- Ops-UX lifecycle: no direct OperationRun lifecycle transitions outside service-owned paths.
- Ops-UX summary counts: no new summary count keys unless
OperationSummaryKeys::all()and tests are updated. - Data minimization: case and step metadata contain safe identifiers/summaries only.
- Test governance: Unit, Feature, Filament/Livewire, PostgreSQL, and Browser lanes are explicit.
- Proportionality: new persistence is justified by pause/resume, audit, currentness, and proof-linked workflow needs.
- No premature abstraction: namespace and persistence remain review-publication-specific.
- Persisted truth: new tables store workflow state, not readiness or artifact truth.
- Behavioral state: case/step statuses affect routing/actionability/audit/lifecycle; v1 does not persist
skipped,not_applicable, or a separate reason-code family for steps. - UI semantics: use existing badges/disclosure/action-group patterns, no local color/status framework. Default page copy stays operator-facing; technical proof and implementation terms remain behind explicit disclosure.
- Shared pattern first: existing guidance/proof/action helpers are reused before local composition.
- Provider boundary: platform-core workflow vocabulary stays provider-neutral.
- V1 explicitness / few layers: direct review-specific services, no registry.
- UI/Productization coverage: new reachable workflow surface must update UI coverage artifacts.
Gate result for preparation: PASS.
Test Governance Check
- Test purpose / classification by changed surface:
- Unit: evaluator, planner, fingerprint, proof resolver.
- Feature: migrations/models, case service, step actions, audit, RBAC, scope, customer boundary.
- Filament/Livewire Feature: CTA, resolution page, action enabled/disabled/executed states.
- PostgreSQL: JSONB/index/unique/constraint behavior.
- Browser: critical workflow smoke and non-leakage.
- Affected validation lanes: fast-feedback, confidence, pgsql, browser.
- Why this lane mix is the narrowest sufficient proof: the feature adds stateful workflow persistence and a new operator workflow page; SQLite-only tests cannot prove all PostgreSQL constraints and feature tests cannot prove full browser workflow presentation.
- Narrowest proving command(s):
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
- Fixture / helper / factory / seed / context cost risks: review/evidence/report/pack/operation fixtures can grow expensive. Keep new fixtures local and explicit unless existing helpers already provide cheap setup.
- Expensive defaults or shared helper growth introduced?: none planned.
- Heavy-family additions, promotions, or visibility changes: none planned.
- Surface-class relief / special coverage rule: no standard-native relief for the new workflow page; it needs explicit page/action/browser coverage.
- Closing validation and reviewer handoff: verify no generic workflow spread, no stale proof, no customer leakage, correct audit/RBAC, and updated UI coverage artifacts.
- Budget / baseline / trend follow-up: document-in-feature if pgsql/browser runtime or fixture cost materially grows.
- Review-stop questions: duplicate truth, generic naming, proof currentness, unauthorized action execution, raw detail leakage, OperationRun lifecycle misuse, no-Graph-during-render.
- Escalation path: document-in-feature for bounded implementation choices; follow-up-spec for structural proof/currentness or additional adapters.
- Active feature PR close-out entry: Review Publication Resolution Workflow.
- Why no dedicated follow-up spec is needed: Spec 386 itself is the bounded review-publication workflow. Generic proof/currentness and other adapters are listed as future specs.
Project Structure
Documentation (this feature)
specs/386-review-publication-resolution-workflow-v1/
├── checklists/
│ └── requirements.md
├── plan.md
├── spec.md
└── tasks.md
Source Code (repository root)
apps/platform/
├── app/
│ ├── Models/
│ │ ├── ReviewPublicationResolutionCase.php
│ │ └── ReviewPublicationResolutionStep.php
│ ├── Policies/
│ │ └── ReviewPublicationResolutionCasePolicy.php
│ ├── Support/
│ │ └── ReviewPublicationResolution/
│ │ ├── ReviewPublicationReadinessEvaluator.php
│ │ ├── ReviewPublicationResolutionPlanner.php
│ │ ├── ReviewPublicationResolutionCaseService.php
│ │ ├── ReviewPublicationResolutionActionService.php
│ │ ├── ReviewPublicationResolutionProofResolver.php
│ │ └── DTOs and enums/value objects as needed
│ ├── Services/
│ │ ├── EnvironmentReviews/
│ │ ├── Evidence/
│ │ └── ReviewPacks/
│ └── Filament/
│ └── Resources/
│ └── EnvironmentReviewResource/
│ └── Pages/
│ └── ResolveReviewPublication.php
├── database/
│ └── migrations/
├── resources/views/
└── tests/
├── Unit/ReviewPublicationResolution/
├── Feature/ReviewPublicationResolution/
├── Feature/Filament/
└── Browser/
Structure Decision: Laravel monolith under apps/platform; review-publication-specific support namespace; subject-driven Filament page/action under Environment Review; no top-level resource/navigation.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| New persisted case/step tables | Operator workflow must survive navigation, queued operation completion, permission fixes, audit review, and currentness changes | Derived cards cannot preserve pause/resume, proof linkage, lifecycle audit, or current step over time |
| New case/step statuses | Status changes drive next action, wait state, failure handling, completion, cancellation, and supersession | Presentation-only labels would not support resume, audit, or safe action routing |
| New review-specific service family | Evaluation, planning, persistence, action execution, and proof/currentness must remain thin and testable | Putting this behavior in Filament closures would bury business logic and make RBAC/audit hard to verify |
Implementation Phases
- Confirm current review/evidence/report/pack/OperationRun services, capabilities, audit helpers, and UI patterns.
- Add migration/model/policy tests first, including isolation and pgsql-specific constraints.
- Add review-publication-specific models, migrations, enums/value objects, and policy.
- Implement readiness evaluator, planner, fingerprinting, case service, action service, and proof resolver.
- Integrate Environment Review blocked-state CTA and subject-driven resolution page/action.
- Wire step actions through existing services/jobs and link OperationRun/artifact proof.
- Add audit events and customer-boundary safeguards.
- Update UI coverage artifacts.
- Run focused Unit/Feature/Filament/PostgreSQL/Browser/Pint/diff validation.
- Record implementation close-out with Filament v5 output contract and deployment impact.
Data Truth Separation
- Execution truth:
OperationRun. - Artifact truth:
EvidenceSnapshot,StoredReport,EnvironmentReview,ReviewPack. - Backup/snapshot truth: unchanged and out of scope.
- Recovery/evidence truth: existing evidence/report/review/pack services.
- Operator next action: Review Publication Resolution Case current step and planner output.
The case may store a pointer to proof but must re-evaluate current truth before completing steps or the case.
Rollout and Deployment Considerations
- Migrations are required and must be safe on PostgreSQL.
- Queue workers are already involved through existing evidence/report/review/pack operations; no new queue name is planned.
- No new environment variables are planned.
- No new scheduler entry is planned.
- No new storage volume is planned.
- No Filament asset registration is planned. If assets are added later, include
cd apps/platform && php artisan filament:assetsin deploy. - Staging validation must include migration, focused tests, and browser smoke before production promotion.
Filament v5 Output Contract For Implementation Close-Out
The implementation close-out must explicitly state:
- Livewire v4.0+ compliance is preserved; current repo uses Livewire 4.1.4.
- Filament panel provider registration remains in
apps/platform/bootstrap/providers.php; no provider registration change unless explicitly made. - No globally searchable Resolution Case resource is added. If any Resource is added unexpectedly, global search is disabled or a safe View/Edit page exists.
- Destructive/high-impact actions: list all new case/step actions and explain confirmation, authorization, audit, and notification behavior.
- Asset strategy: no assets by default; if assets are registered, deploy includes
php artisan filament:assets. - Tests added/updated: Unit, Feature, Filament/Livewire, PostgreSQL, Browser.
- Deployment impact: migrations, queues, scheduler, env vars, storage, Dokploy/staging notes.
Spec Readiness Gate
Preparation readiness is expected to pass after spec.md, plan.md, tasks.md, and checklists/requirements.md are present and consistent.
Implementation must stop and update artifacts first if it needs any of:
- generic
action_resolution_*persistence; - generic workflow registry/adapter;
- top-level navigation;
- global-searchable case resource;
- customer self-resolution;
- auto-publish behavior;
- new Graph/provider call path;
- new OperationRun type outside existing services;
- new public state/status family beyond the case/step statuses listed in the spec.