TenantAtlas/specs/386-review-publication-resolution-workflow-v1/plan.md
ahmido ba7622a158 feat: implement ReviewPublicationResolutionWorkflow (Spec 386) (#457)
## 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
2026-06-18 21:06:20 +00:00

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:

  • id
  • workspace_id required
  • managed_environment_id or the repo-current environment FK required for review publication
  • environment_review_id required or a subject reference constrained to Environment Review only
  • action_key required and fixed to review.publication for v1
  • status
  • current_step_key
  • readiness_fingerprint
  • last_evaluated_at
  • created_by
  • assigned_to
  • started_at, completed_at, cancelled_at, superseded_at
  • summary JSONB for safe derived summary
  • metadata JSONB for safe workflow metadata only
  • timestamps

Step fields should include:

  • id
  • case FK
  • position
  • step_key
  • status
  • primary_action_key
  • operation_run_id nullable
  • proof_type, proof_id, proof_status nullable
  • lifecycle timestamps
  • summary JSONB for safe step summary
  • metadata JSONB 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 are exception-required only 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.md
    • docs/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, ResolutionGuidance DTOs 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 ReviewPublication to 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: /admin and /system remain 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 initial Resolve publication blockers CTA 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 OperationRun through 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/ReviewPublicationResolution
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ReviewPublicationResolution tests/Feature/EnvironmentReview tests/Feature/ReviewPack
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/Spec386ReviewPublicationResolutionUiTest.php
    • cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml --filter Spec386
    • cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec386ReviewPublicationResolutionWorkflowTest.php
    • cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • git 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

  1. Confirm current review/evidence/report/pack/OperationRun services, capabilities, audit helpers, and UI patterns.
  2. Add migration/model/policy tests first, including isolation and pgsql-specific constraints.
  3. Add review-publication-specific models, migrations, enums/value objects, and policy.
  4. Implement readiness evaluator, planner, fingerprinting, case service, action service, and proof resolver.
  5. Integrate Environment Review blocked-state CTA and subject-driven resolution page/action.
  6. Wire step actions through existing services/jobs and link OperationRun/artifact proof.
  7. Add audit events and customer-boundary safeguards.
  8. Update UI coverage artifacts.
  9. Run focused Unit/Feature/Filament/PostgreSQL/Browser/Pint/diff validation.
  10. 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:assets in 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:

  1. Livewire v4.0+ compliance is preserved; current repo uses Livewire 4.1.4.
  2. Filament panel provider registration remains in apps/platform/bootstrap/providers.php; no provider registration change unless explicitly made.
  3. 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.
  4. Destructive/high-impact actions: list all new case/step actions and explain confirmation, authorization, audit, and notification behavior.
  5. Asset strategy: no assets by default; if assets are registered, deploy includes php artisan filament:assets.
  6. Tests added/updated: Unit, Feature, Filament/Livewire, PostgreSQL, Browser.
  7. 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.