Implemented report evidence reconciliation. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #432
20 KiB
Tasks: Spec 361 - Report and Evidence Reconciliation Adapters
Input: /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/361-report-evidence-reconciliation/spec.md, plan.md, and checklists/requirements.md
Prerequisites: spec.md and plan.md
Tests: REQUIRED (Pest). Keep proof bounded to Unit + Feature + one explicit Browser smoke.
Operations: Reuse current OperationRun lifecycle ownership. No new run status column, no new queue family, and no new schema.
RBAC: Reuse current workspace-first OperationRun access plus existing EvidenceSnapshot and ReviewPack policies. No new capability strings and no cross-scope artifact resolution.
Shared Pattern Reuse: Reuse OperationRunService, current operations surfaces, OperationRunLinks, ArtifactTruthPresenter, and current evidence/review-pack detail families. Introduce only bounded artifact-specific adapters plus at most one small derived proof/helper path.
Filament / Panel Guardrails: Filament remains v5 on Livewire v4. Provider registration stays in apps/platform/bootstrap/providers.php. No new panel, global-search change, or asset strategy is allowed.
Organization: Tasks are grouped by user story so Evidence Snapshot reconciliation, Review Pack reconciliation, and honest unsupported-report handling remain independently reviewable.
Repo Baseline At Prep Time
- Branch:
361-report-evidence-reconciliation - HEAD:
840c9bd2 refactor: rename ManagedEnvironment context badge to Environment context (#431) git status --short --branchbefore Spec 361 prep: clean onplatform-dev; Spec Kit created this feature branch and copied the spec/plan templates- Merged adapter baseline:
3a750726 feat: implement review compose reconciliation adapter (spec 359) (#430)is already in repo history and remains the adapter-registry baseline - Relevant runtime surfaces:
apps/platform/app/Services/AdapterRunReconciler.phpapps/platform/app/Services/OperationRunService.phpapps/platform/app/Models/OperationRun.phpapps/platform/app/Models/EvidenceSnapshot.phpapps/platform/app/Models/ReviewPack.phpapps/platform/app/Models/StoredReport.phpapps/platform/app/Services/Evidence/EvidenceSnapshotService.phpapps/platform/app/Services/ReviewPackService.phpapps/platform/app/Support/Operations/Reconciliation/OperationRunReconciliationRegistry.phpapps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.phpapps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.phpapps/platform/app/Filament/Pages/Monitoring/Operations.phpapps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.phpapps/platform/app/Filament/Resources/EvidenceSnapshotResource.phpapps/platform/app/Filament/Resources/ReviewPackResource.php
- Completed-spec context only: Specs 347, 349, 351, 356, and 357 are context only and must not be reopened for rendered-report or disclosure-policy scope
- Scope guardrail: generic
StoredReportcausality is context only unless direct proof is stronger than expected during implementation
Test Governance Checklist
- Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- New or changed tests stay in the smallest honest family, and the Browser addition remains explicit.
- Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
- Planned validation commands cover the change without widening into unrelated lane cost.
- The declared monitoring/detail surface profile is explicit.
- Any material budget, baseline, trend, or escalation note is recorded in the active feature close-out.
Phase 1: Setup (Repo Truth Inventory)
Purpose: confirm the current registry baseline, the artifact models, and the exact unsupported report-family boundary before runtime edits begin.
- T001 Re-read
spec.md,plan.md,checklists/requirements.md,.specify/memory/constitution.md,docs/ai-coding-rules.md,docs/architecture-guidelines.md,docs/testing-guidelines.md,docs/security-guidelines.md,docs/filament-guidelines.md, andspecs/358-operationrun-queue-truth-foundation/{spec,plan,tasks}.mdplusspecs/359-operationrun-reconciliation-adapter-framework-review-compose-adapter/{spec,plan,tasks}.mdandspecs/360-operationrun-canonical-cutover-cleanup/{spec,plan,tasks}.mdtogether before touching runtime code. - T002 [P] Confirm the current adapter and write seams in
apps/platform/app/Services/AdapterRunReconciler.php,apps/platform/app/Services/OperationRunService.php,apps/platform/app/Models/OperationRun.php, andapps/platform/app/Support/Operations/Reconciliation/OperationRunReconciliationRegistry.php. - T003 [P] Confirm the current artifact-truth seams in
apps/platform/app/Models/EvidenceSnapshot.php,apps/platform/app/Models/ReviewPack.php,apps/platform/app/Models/StoredReport.php,apps/platform/app/Services/Evidence/EvidenceSnapshotService.php,apps/platform/app/Services/ReviewPackService.php, andapps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php. - T004 [P] Confirm the current canonical operation types and run-start contexts for
tenant.evidence.snapshot.generate,environment.review_pack.generate,permission.posture.check, andentra.admin_roles.scaninapps/platform/app/Support/OperationCatalog.php,apps/platform/app/Support/OperationRunType.php, and the current job/service start paths. - T005 Confirm that no new schema, no new panel/provider path, no new asset registration, no new
stored_report.generateoperation type, and no generic stored-report lifecycle model are required; if any of those are needed, stop and update the spec/plan instead of widening scope silently.
Phase 2: Foundational (Bounded Artifact-Proof and Registry Setup)
Purpose: settle the bounded proof checks and registry shape before story-specific adapter work begins.
Critical: no user-story runtime work should begin until this phase is complete.
- T006 [P] Add failing Unit coverage in
apps/platform/tests/Unit/Support/Operations/Reconciliation/Spec361ArtifactRegistryResolutionTest.phpfor adapter resolution oftenant.evidence.snapshot.generate,environment.review_pack.generate, and unsupported generic report families. - T007 [P] Add failing Unit coverage in
apps/platform/tests/Unit/Support/Operations/Reconciliation/Spec361ArtifactProofRulesTest.phpfor scope checks, completeness checks, expiration handling, canonical related-identity tie-breaking, and fail-closed unsupported-report behavior. - T008 No bounded shared helper was needed; evidence and review-pack proof logic stayed local to their adapters.
- T009 Add
EvidenceSnapshotReconciliationAdapterandReviewPackArtifactReconciliationAdapter(or equivalent bounded names) underapps/platform/app/Support/Operations/Reconciliation/and register them inOperationRunReconciliationRegistry. - T010 Keep generic
StoredReportreconciliation out of the registry in Spec 361. Do not add anyStoredReport-backed success path in this package; record a named follow-up spec instead of a heuristic adapter. - T011 Update or add Unit coverage proving that adapters never mutate
EvidenceSnapshot,ReviewPack, orStoredReport, that all lifecycle writes still go throughOperationRunService, thatcontext.reconciliationkeeps the canonical adapter or reason or previous-state or related-artifact shape, and that rerunning reconciliation is idempotent.
Checkpoint: the registry is ready for artifact-backed extensions, and the unsupported report-family boundary is explicit.
Phase 3: User Story 1 - Reconcile evidence generation against an existing snapshot (Priority: P1)
Goal: tenant.evidence.snapshot.generate runs can finalize against an existing current-scope snapshot when current repo truth already proves success.
Independent Test: run focused Unit and Feature coverage showing that a queued/running/stale evidence-generation run finalizes successfully only when a matching active, non-partial snapshot already exists.
Tests for User Story 1
- T012 [P] [US1] Add
apps/platform/tests/Feature/Operations/Spec361EvidenceSnapshotReconciliationTest.phpcovering active complete success, partial rejection, failed/expired rejection, wrong-scope rejection, and ambiguous-candidate rejection. - T013 [P] [US1] Extend
apps/platform/tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.phpor a focused companion file so stale queued/running evidence-generation runs can prove the adapter-backed finalization path without changing artifact generation semantics.
Implementation for User Story 1
- T014 [US1] Implement
EvidenceSnapshotReconciliationAdapterunderapps/platform/app/Support/Operations/Reconciliation/using existingoperation_run_id,managed_environment_id,workspace_id,fingerprint,status, andcompleteness_statetruth. - T015 [US1] Reuse
apps/platform/app/Services/Evidence/EvidenceSnapshotService.phpandapps/platform/app/Services/OperationRunService.phpwithout adding a new evidence lifecycle or persistence layer. - T016 [US1] Update existing operations/detail presentation paths in
apps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php,apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php,apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php,apps/platform/app/Filament/Pages/Monitoring/Operations.php, andapps/platform/app/Filament/Resources/EvidenceSnapshotResource.phponly as needed so reconciled evidence runs explain the matched snapshot calmly, scope-safely, and without duplicate default-visible truth.
Checkpoint: evidence-generation runs reconcile safely from current snapshot truth and never overclaim partial or wrong-scope success.
Phase 4: User Story 2 - Reconcile review-pack generation against an existing pack (Priority: P1)
Goal: environment.review_pack.generate runs can finalize against an existing ready, non-expired pack when current repo truth already proves success.
Independent Test: run focused Unit and Feature coverage showing that a queued/running/stale review-pack run finalizes successfully only when a matching ready, current-scope pack already exists.
Tests for User Story 2
- T017 [P] [US2] Add
apps/platform/tests/Feature/Operations/Spec361ReviewPackReconciliationTest.phpcovering ready success plus queued/generating/failed/expired/wrong-scope rejection. - T018 [P] [US2] Extend focused review-pack coverage in
apps/platform/tests/Feature/ReviewPack/EnvironmentReviewDerivedReviewPackTest.php,apps/platform/tests/Feature/ReviewPack/ReviewPackDownloadTest.php,apps/platform/tests/Feature/ReviewPack/ReviewPackResourceTest.php, or a companion file only as needed to prove canonical related-artifact metadata, current host detail fallout, and no false success on incomplete or non-shareable output.
Implementation for User Story 2
- T019 [US2] Implement
ReviewPackArtifactReconciliationAdapterunderapps/platform/app/Support/Operations/Reconciliation/forenvironment.review_pack.generate, using existingReviewPackscope, status, expiration, fingerprint,operation_run_id, and review/evidence linkage where current repo truth exposes it. - T020 [US2] Reuse
apps/platform/app/Services/ReviewPackService.php,apps/platform/app/Support/OperationRunLinks.php, andapps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.phpso reconciled runs link to the current pack without exposing raw storage or expired artifacts. - T021 [US2] Keep customer-safe and operator-safe boundaries intact: no new download mutation, no rendered-report rewrite, no new readiness taxonomy, and no reopening of Specs 347/349/351/356/357 scope.
Checkpoint: review-pack generation runs reconcile safely from current pack truth and never overclaim expired or still-generating output.
Phase 5: User Story 3 - Keep unsupported generic report families honest (Priority: P2)
Goal: report-producing runs backed only by weak StoredReport truth stay fail-closed instead of falsely succeeding from "latest report exists" heuristics.
Independent Test: run focused Unit and Feature coverage showing that permission.posture.check and entra.admin_roles.scan remain unresolved or diagnostic-first because Spec 361 keeps StoredReport success reconciliation out of scope.
Tests for User Story 3
- T022 [P] [US3] Add focused Unit or Feature coverage in
apps/platform/tests/Feature/Operations/Spec361UnsupportedStoredReportReconciliationTest.phpproving that retainedStoredReportrows alone do not reconcilepermission.posture.checkorentra.admin_roles.scan. - T023 [P] [US3] Add or extend operations-detail coverage in
apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.phpor a companion Spec 361 file so unsupported report-family runs remain attention-first, keep one dominant default next action, keep diagnostics secondary, and do not expose raw/support evidence in the default-visible layer for ordinary operators.
Implementation for User Story 3
- T024 [US3] Verify that generic
StoredReportfamilies remain excluded from the Spec 361 registry path and record the named follow-up spec in the feature close-out instead of widening this package. - T025 [US3] No unsupported-report helper was needed; stored-report families stayed on existing operations diagnostics and artifact-truth paths without a new lifecycle model.
- T026 [US3] Ensure
permission.posture.check,entra.admin_roles.scan, restore, sync, backup, and review-compose semantics remain unchanged except for clearer unsupported or related-artifact diagnostics on current operations surfaces and existing host-gated disclosure paths.
Checkpoint: the feature improves artifact-backed truth where repo proof is strong and explicitly refuses false success where proof is weak.
Phase 6: Polish & Validation
- T027 [P] Refresh
spec.md,plan.md, andchecklists/requirements.mdonly if implementation proves a thinner touched-file boundary or requires an explicit recorded defer for generic stored-report causality. - T028 [P] Run the primary in-scope Unit and Feature gate:
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Unit/Support/Operations/Reconciliation tests/Feature/Operations/Spec361*
- T029 [P] Run the bounded contextual artifact regressions:
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php tests/Feature/Evidence/EvidenceSnapshotResourceTest.phpcd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Feature/ReviewPack/EnvironmentReviewDerivedReviewPackTest.php tests/Feature/ReviewPack/ReviewPackDownloadTest.php tests/Feature/ReviewPack/Spec347ReviewPackOutputContractTest.php
- T030 [P] Run the primary browser smoke and verify the changed operations surfaces still show one dominant next action, keep duplicate visible decision truth out of the default layer, and keep deeper diagnostics behind explicit reveal paths:
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec361ArtifactReconciliationSmokeTest.php
- T031 [P] Run the bounded contextual browser smoke only if visible copy or link behavior changes on related surfaces:
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec360OperationRunCanonicalCutoverSmokeTest.php tests/Browser/Spec337EvidenceReviewPackProductFlowSmokeTest.php
- T032 [P] Run
cd apps/platform && ./vendor/bin/pint --dirty. - T033 [P] Run
git diff --check. - T034 [P] Record the final artifact families reconciled, the explicit unsupported generic report-family decision, validation results, no-migration status, no-asset status, and the final Guardrail / Smoke Coverage note in the active feature close-out.
Close-Out Notes
- Reconciled artifact families:
tenant.evidence.snapshot.generateviaEvidenceSnapshotReconciliationAdapterandenvironment.review_pack.generateviaReviewPackArtifactReconciliationAdapter. - Explicit unsupported generic report-family decision:
permission.posture.checkandentra.admin_roles.scanremain outside the adapter registry becauseStoredReportstill lacks direct lifecycle truth and causal linkage; any future auto-success path needs a follow-up spec. - No migration status: no schema or persisted-truth changes were required.
- No asset / panel status: no Filament panel/provider/global-search/asset changes were required; Laravel 12 provider registration remains in
apps/platform/bootstrap/providers.php, and Filament stays on v5 with Livewire v4. - Guardrail / Smoke Coverage: Spec 361 added bounded Unit + Feature coverage for registry shape, canonical related IDs, artifact-safe success/fail-closed behavior, and a Browser smoke for evidence snapshot and review-pack drill-through on existing Operations surfaces.
- Validation results:
cd apps/platform && php vendor/bin/pest tests/Unit/Support/Operations/Reconciliation tests/Feature/Operations/Spec359OperationRunAdapterReconciliationTest.php tests/Feature/Operations/Spec360CanonicalReconciliationCutoverTest.php tests/Feature/Operations/Spec361EvidenceSnapshotReconciliationTest.php tests/Feature/Operations/Spec361ReviewPackReconciliationTest.php tests/Feature/Operations/Spec361UnsupportedStoredReportReconciliationTest.php tests/Feature/EnvironmentReview/Spec359ReviewComposeReconciliationTest.php tests/Feature/EnvironmentReview/Spec360ReviewComposeAdapterOwnershipTest.php tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php tests/Feature/ReviewPack/EnvironmentReviewDerivedReviewPackTest.php tests/Feature/ReviewPack/ReviewPackDownloadTest.php tests/Feature/ReviewPack/Spec347ReviewPackOutputContractTest.php-> 55 passed, 443 assertions.cd apps/platform && php vendor/bin/pest tests/Browser/Spec361ArtifactReconciliationSmokeTest.php-> 2 passed, 20 assertions.cd apps/platform && php vendor/bin/pint --dirty-> fixed 3 style issues across 19 files.git diff --check-> clean.
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): no dependencies
- Foundational (Phase 2): depends on Setup and blocks all story work
- US1 (Phase 3): depends on Foundational completion
- US2 (Phase 4): depends on Foundational completion; can land after US1 or in parallel once shared proof rules settle
- US3 (Phase 5): depends on US1 and US2 because the unsupported-family boundary should be validated against the final in-scope adapter set
- Polish (Phase 6): depends on all desired user stories
Parallel Opportunities
T002,T003, andT004can run in parallel.T006andT007can run in parallel.T012andT013can run in parallel.T017andT018can run in parallel.T022andT023can run in parallel.T028throughT033can run in parallel once implementation stabilizes, but the primary merge gate should be read out separately from contextual regressions.
Implementation Strategy
- Freeze the current registry and artifact-model baseline first.
- Land the bounded proof rules and registry setup before story-specific runtime edits.
- Land Evidence Snapshot reconciliation first because its proof path is strongest.
- Land Review Pack reconciliation second because it is customer-visible and already repo-real.
- Finish by locking fail-closed behavior for weak generic report families and recording any explicit defer.
Non-Goals / Must-Not-Do
- NT001 Do not add a new
OperationRunstatus column, boolean, or separate reconciliation table. - NT002 Do not add a
stored_report.generateoperation type, a generic report-artifact lifecycle model, or a new rendered-report workflow. - NT003 Do not mutate
EvidenceSnapshot,ReviewPack, orStoredReportfrom adapters. - NT004 Do not widen scope into backup, restore, sync, review-compose, PDF/HTML rendering, disclosure policy, or customer portal work.
- NT005 Do not add compatibility shims or heuristics only to preserve pre-production historical report behavior.