TenantAtlas/specs/043-cross-tenant-compare-and-promotion/tasks.md
ahmido ff3392892b
Some checks failed
Main Confidence / confidence (push) Failing after 56s
Merge 248-private-ai-policy-foundation into dev (#288)
Automated PR: merge branch 248-private-ai-policy-foundation into dev (created by Copilot)

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #288
2026-04-27 21:18:37 +00:00

16 KiB

description
Task list for Cross-Tenant Compare Preview and Promotion Preflight

Tasks: Cross-Tenant Compare Preview and Promotion Preflight

Input: Design documents from /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/043-cross-tenant-compare-and-promotion/
Prerequisites: /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/043-cross-tenant-compare-and-promotion/plan.md (required), /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/043-cross-tenant-compare-and-promotion/spec.md (required)

Tests: REQUIRED (Pest) for runtime behavior changes. Keep proof in narrow Unit plus Feature lanes only; do not add browser or heavy-governance coverage by default for this first read-only slice.
Operations: No new OperationRun, queue, retry, monitoring page, or execution ledger is introduced. Promotion remains preflight-only.
RBAC: Existing workspace and tenant membership semantics remain authoritative. Non-members or actors lacking source or target tenant entitlement receive 404; members who reach the canonical compare surface but lack the required capability receive 403. Page access uses Capabilities::WORKSPACE_BASELINES_VIEW, preview data uses Capabilities::TENANT_VIEW on both tenants, and preflight execution adds Capabilities::WORKSPACE_BASELINES_MANAGE.
Provider Boundary: The page contract stays platform-neutral (source tenant, target tenant, governed subject, promotion preflight) while reusing Microsoft-first inventory and baseline compare seams under the hood.
Organization: Tasks are grouped by user story so compare preview, promotion preflight, and portfolio launch continuity remain independently testable once the shared contracts exist.

Test Governance Checklist

  • Lane assignment stays Unit plus Feature and remains the narrowest sufficient proof for the changed behavior.
  • New or changed tests stay in apps/platform/tests/Unit/Support/PortfolioCompare/ and apps/platform/tests/Feature/PortfolioCompare/ only.
  • Shared helpers, fixtures, and context defaults stay cheap by default; do not add browser setup, queue scaffolding, or seeded promotion history.
  • Planned validation commands cover compare preview, promotion preflight, launch continuity, audit, and authorization without widening scope.
  • The declared surface test profile remains standard-native-filament because the slice adds one canonical page and one launch action on existing surfaces.
  • Any deferred execution, mapping automation, or multi-provider follow-up resolves as document-in-feature or follow-up-spec, not hidden scope growth.

Phase 1: Setup (Shared Context)

Purpose: Confirm the narrowed slice, the reusable compare seams, and the reviewer stop conditions before implementation begins.

  • T001 Review the narrowed compare-preview and promotion-preflight slice in /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/043-cross-tenant-compare-and-promotion/spec.md and /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/043-cross-tenant-compare-and-promotion/plan.md together with the current candidate and ledger references.
  • T002 [P] Confirm the compare and subject-identity seams that this slice must reuse in apps/platform/app/Filament/Pages/BaselineCompareLanding.php, apps/platform/app/Filament/Pages/BaselineCompareMatrix.php, apps/platform/app/Services/Baselines/BaselineCompareService.php, apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php, apps/platform/app/Support/Baselines/Compare/CompareStrategyRegistry.php, apps/platform/app/Models/InventoryItem.php, and apps/platform/app/Models/PolicyVersion.php.
  • T003 [P] Confirm the portfolio launch, authorization, and audit seams that this slice must reuse in apps/platform/app/Filament/Resources/TenantResource.php, apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php, apps/platform/app/Services/PortfolioTriage/TenantTriageReviewService.php, apps/platform/app/Services/Audit/WorkspaceAuditLogger.php, apps/platform/app/Support/Audit/AuditActionId.php, apps/platform/app/Services/Auth/CapabilityResolver.php, and apps/platform/app/Services/Auth/WorkspaceCapabilityResolver.php.

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Add the shared compare scope and promotion-preflight primitives that every user story depends on.

Critical: No user-story work should begin until this phase is complete.

  • T004 [P] Define the minimal compare-page input/output shape inside apps/platform/app/Support/PortfolioCompare/ or apps/platform/app/Services/PortfolioCompare/ for source tenant, target tenant, governed-subject filters, and preflight output without adding a wider DTO or resolver framework.
  • T005 [P] Implement source-plus-target entitlement checks inside the canonical compare page and shared preview/preflight services using the existing capability resolvers so workspace membership, source entitlement, target entitlement, and capability denial all follow existing 404/403 semantics.
  • T006 Implement the compare preview builder so it reuses stable governed-subject identity from existing inventory and baseline compare seams and produces a canonical preview summary without storing new compare truth.
  • T007 Implement the promotion-preflight service so it classifies governed subjects as ready, blocked, or manual-mapping-required and explicitly performs no target mutation, queue dispatch, or OperationRun creation.
  • T008 [P] Add bounded preflight audit action IDs and metadata shaping in apps/platform/app/Support/Audit/AuditActionId.php and apps/platform/app/Services/Audit/WorkspaceAuditLogger.php for promotion-preflight entry points only.

Checkpoint: Shared compare scope, entitlement resolution, preview building, preflight classification, and audit metadata exist; user stories can proceed independently.


Phase 3: User Story 1 - Compare Two Authorized Tenants (Priority: P1) MVP

Goal: Give an authorized workspace operator one canonical compare page that shows a reproducible source-vs-target preview without cross-page reconstruction.

Independent Test: Open the compare page with two authorized tenants, apply governed-subject filters, and verify that the preview shows match/difference/missing states plus drill-down links.

Tests for User Story 1

  • T009 [P] [US1] Add feature coverage for rendering the canonical compare page, selecting source and target tenants, rejecting same-tenant selection, and showing one default-visible compare summary with no duplicate decision truth or raw/support evidence in apps/platform/tests/Feature/PortfolioCompare/CrossTenantComparePageTest.php.
  • T010 [P] [US1] Add feature coverage for 404 vs 403 semantics across source/target entitlement, workspace WORKSPACE_BASELINES_VIEW, tenant TENANT_VIEW, visible-disabled preflight UX for members lacking WORKSPACE_BASELINES_MANAGE, and server-side denial of forced preflight requests in apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareAuthorizationTest.php.
  • T011 [P] [US1] Add unit coverage for compare preview subject matching and reproducible summary output in apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantComparePreviewBuilderTest.php.

Implementation for User Story 1

  • T012 [US1] Add the canonical compare page under apps/platform/app/Filament/Pages/ with source/target selectors, governed-subject filters, shareable query state, and compare preview summary built from the shared preview builder.
  • T013 [US1] Reuse existing baseline compare and inventory seams so the compare page deep-links to tenant-level proof surfaces instead of duplicating raw diagnostics.
  • T014 [US1] Keep page copy, chips, and summary wording aligned to source tenant, target tenant, governed subject, and compare preview rather than Microsoft-first or execution-first vocabulary.

Checkpoint: User Story 1 is independently functional when the canonical page produces a reproducible compare preview for two authorized tenants.


Phase 4: User Story 2 - Generate a Read-Only Promotion Preflight (Priority: P1)

Goal: Let the operator ask whether the chosen target is ready for a later promotion workflow without performing any write.

Independent Test: From an authorized compare preview, trigger the preflight action and verify that the page shows ready, blocked, and manual-mapping-required groups without mutating target data.

Tests for User Story 2

  • T015 [P] [US2] Add unit coverage for preflight classification across ready, blocked, manual-mapping, stale-evidence, and missing-identifier cases in apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantPromotionPreflightTest.php.
  • T016 [P] [US2] Add feature coverage for the compare page's Generate promotion preflight action, visible-disabled manage-denial UX, one dominant next action, visible readiness summary, and no default-visible raw/support evidence in apps/platform/tests/Feature/PortfolioCompare/CrossTenantComparePageTest.php.
  • T017 [P] [US2] Add feature coverage for preflight audit metadata and explicit no-write semantics in apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionPreflightAuditTest.php.

Implementation for User Story 2

  • T018 [US2] Add the read-only Generate promotion preflight action to the canonical compare page, keeping it distinct from any future execution action and free of queue/runtime side effects.
  • T019 [US2] Render a promotion-preflight summary that groups governed subjects into ready, blocked, and manual-mapping-required buckets with explicit operator-readable reasons.
  • T020 [US2] Route preflight entry-point audit through the existing workspace audit pipeline with source tenant, target tenant, subject counts, and blocked-reason metadata only.

Checkpoint: User Story 2 is independently functional when the operator can generate an audited, read-only readiness decision from the compare page.


Phase 5: User Story 3 - Launch Compare from Portfolio Context Without Losing State (Priority: P2)

Goal: Make compare part of the portfolio workflow by preserving the launch tenant and return state from the tenant registry / portfolio-triage path.

Independent Test: Launch compare from the tenant registry with active triage filters, verify the launched tenant is prefilled, and verify the return path restores the prior registry state.

Tests for User Story 3

  • T021 [P] [US3] Add feature coverage for compare launch and return continuity from the tenant registry / portfolio-triage path in apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareLaunchContextTest.php.
  • T022 [P] [US3] Extend authorization coverage so launch actions only appear or resolve when the current actor is entitled to the launched tenant and the compare surface in apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareAuthorizationTest.php.

Implementation for User Story 3

  • T023 [US3] Add a bounded launch action from apps/platform/app/Filament/Resources/TenantResource.php or apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php that opens the canonical compare page with the current tenant prefilled as the target tenant.
  • T024 [US3] Preserve and restore portfolio-triage return state using the existing navigation-context pattern rather than a page-local custom token format.

Checkpoint: User Story 3 is independently functional when compare can be launched from portfolio context and the operator can return without losing triage filters.


Phase 6: Polish & Cross-Cutting Concerns

Purpose: Finish narrow validation and reviewer close-out without widening scope.

  • T025 [P] Run the focused unit validation commands for apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantComparePreviewBuilderTest.php and apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantPromotionPreflightTest.php.
  • T026 [P] Run the focused feature validation commands for apps/platform/tests/Feature/PortfolioCompare/CrossTenantComparePageTest.php, apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareAuthorizationTest.php, apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionPreflightAuditTest.php, and apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareLaunchContextTest.php.
  • T027 Run dirty-only formatting for touched platform files with export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent.
  • T028 [P] Add or update the checklist/reviewer guard confirming that this slice introduces no new asset registration and no globally searchable resource.
  • T029 Record TEST-GOV-001 close-out and any document-in-feature or follow-up-spec deferrals for actual execution, mapping automation, or multi-provider compare in the active feature PR or implementation notes.

Dependencies & Execution Order

Phase Dependencies

  • Phase 1 (Setup): no dependencies; start immediately.
  • Phase 2 (Foundational): depends on Phase 1 and blocks all user stories.
  • Phase 3 (US1): depends on Phase 2 and establishes the canonical compare truth.
  • Phase 4 (US2): depends on Phase 2 and should ship with US1 because compare without readiness reasoning leaves promotion language vague.
  • Phase 5 (US3): depends on Phase 2 and is safest after US1 because the canonical compare page must exist before launch continuity can target it.
  • Phase 6 (Polish): depends on all desired user stories being complete.

User Story Dependencies

  • US1 (P1): independently testable after Phase 2 and forms the MVP decision surface.
  • US2 (P1): independently testable after Phase 2 and should ship with US1 for a complete P1 slice.
  • US3 (P2): independently testable after Phase 2 and improves portfolio workflow continuity once the canonical page exists.

Within Each User Story

  • Write the listed Pest coverage first and make it fail for the intended behavior gap.
  • Settle the shared preview/preflight service contract before adding or widening page wiring.
  • Re-run the narrowest affected validation command after each story checkpoint before moving to the next story.

Parallel Execution Examples

User Story 1

  • T009, T010, and T011 can run in parallel before runtime edits begin.
  • After the preview contract settles, T012 and T013 can proceed in parallel because page wiring and compare-service reuse touch different seams; T014 should follow both.

User Story 2

  • T015, T016, and T017 can run in parallel because they cover separate unit, page, and audit concerns.
  • After T018 settles the action shape, T019 and T020 can proceed in parallel because UI rendering and audit metadata touch different seams.

User Story 3

  • T021 and T022 can run in parallel before implementation starts.
  • T023 should land before T024 so return-state handling can target the final launch route.

Implementation Strategy

Suggested MVP Scope

  • MVP = US1 + US2 together. The feature is only product-complete when the operator can compare two tenants and immediately ask whether that comparison is promotion-ready.

Incremental Delivery

  1. Complete Phase 1 and Phase 2.
  2. Deliver US1 and US2 together.
  3. Add US3 launch and return continuity.
  4. Finish with narrow validation and formatting in Phase 6.

Team Strategy

  1. Finish the preview/preflight contracts together before splitting page work.
  2. Parallelize unit and feature test authoring inside each story first.
  3. Serialize merges around the canonical compare page and shared PortfolioCompare service namespace so the workflow language stays coherent.