Automated PR created by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #464
355 lines
22 KiB
Markdown
355 lines
22 KiB
Markdown
# Implementation Plan: Spec 393 - Evidence Anchor Reconciliation v1
|
|
|
|
**Branch**: `feat/393-evidence-anchor-reconciliation-v1` | **Date**: 2026-06-20 | **Spec**: `specs/393-evidence-anchor-reconciliation-v1/spec.md`
|
|
**Input**: Feature specification from `specs/393-evidence-anchor-reconciliation-v1/spec.md`
|
|
|
|
## Summary
|
|
|
|
Introduce one canonical Evidence Anchor Resolver/result contract and replace product-facing local evidence selectors with that contract. Current dashboard/workspace/environment surfaces must resolve only valid current evidence; released review/report/review-pack output must stay bound to release evidence; Customer Review Workspace must show customer-safe evidence summary without raw evidence links by default; technical evidence detail remains available only through secondary internal/audit paths.
|
|
|
|
This is a clean-cut correctness fix. Do not preserve legacy fallback-to-latest behavior, old tests expecting partial/superseded evidence, or compatibility aliases.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4.15
|
|
**Primary Dependencies**: Laravel 12.52, Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1
|
|
**Storage**: PostgreSQL; no migration expected by default
|
|
**Testing**: Pest 4 Unit, Feature/HTTP, Filament/Livewire, bounded Browser smoke
|
|
**Validation Lanes**: fast-feedback, confidence, browser
|
|
**Target Platform**: Laravel Sail local; Dokploy container deployment for staging/production
|
|
**Project Type**: Laravel monolith under `apps/platform`
|
|
**Performance Goals**: Resolver decisions must be DB-only, deterministic, scoped, and avoid render-time remote calls
|
|
**Constraints**: no legacy fallback, no UI expansion, no new customer proof surface, no Graph calls during render, no new persisted truth unless spec/plan are updated first
|
|
**Scale/Scope**: existing evidence, dashboard, review, customer workspace, review-pack, stored-report, rendered-report, and management-report provenance surfaces
|
|
|
|
## Technical Approach
|
|
|
|
1. Inventory every evidence selector/link/action/output path.
|
|
2. Define a derived `EvidenceAnchorResolver` contract and result value object/array shape with a non-persisted anchor type/state vocabulary.
|
|
3. Implement current-scope resolution with strict scope, active/complete/non-expired checks, and deterministic ordering.
|
|
4. Implement released-review/review-pack/report resolution from existing release-bound relations.
|
|
5. Implement customer-safe summary resolution that omits target routes by default.
|
|
6. Implement technical-detail resolution with actor permission checks.
|
|
7. Replace local selectors in affected product surfaces.
|
|
8. Remove deprecated local fallback logic and stale test expectations.
|
|
9. Add regression tests and focused browser smoke.
|
|
|
|
Preferred shape:
|
|
|
|
```text
|
|
Existing evidence/review/report truth
|
|
-> EvidenceAnchorResolver
|
|
-> EvidenceAnchorResult
|
|
-> UI labels, target routes, route/report provenance, tests
|
|
```
|
|
|
|
Do not create a new evidence lifecycle, proof framework, or persisted readiness model.
|
|
|
|
## Likely Affected Repository Surfaces
|
|
|
|
Implementation must re-verify exact current code before editing, but likely surfaces are:
|
|
|
|
- `apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php`
|
|
- new or consolidated resolver under `apps/platform/app/Services/Evidence/` or a similarly scoped namespace
|
|
- `apps/platform/app/Models/EvidenceSnapshot.php`
|
|
- `apps/platform/app/Services/EnvironmentReviews/EnvironmentReviewService.php`
|
|
- `apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php`
|
|
- `apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php`
|
|
- `apps/platform/resources/views/filament/pages/reviews/customer-review-workspace.blade.php`
|
|
- `apps/platform/app/Filament/Resources/EnvironmentReviewResource.php`
|
|
- `apps/platform/app/Filament/Resources/ReviewPackResource.php`
|
|
- `apps/platform/app/Filament/Resources/StoredReportResource.php`
|
|
- `apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php`
|
|
- `apps/platform/app/Support/ReviewPacks/ManagementReportPdfPayloadBuilder.php`
|
|
- `apps/platform/app/Support/ReviewPublicationResolution/ReviewPublicationProofResolver.php`
|
|
- `apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php`
|
|
- `apps/platform/app/Support/OperationRunLinks.php`
|
|
- `apps/platform/app/Support/Navigation/RelatedNavigationResolver.php`
|
|
- `apps/platform/app/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilder.php`
|
|
- review-pack rendered-report/download/report payload code where evidence provenance is displayed
|
|
- dashboard/workspace/environment summary builders that produce evidence CTAs
|
|
- localization files only where labels change
|
|
- focused tests under `apps/platform/tests/Unit`, `apps/platform/tests/Feature`, and `apps/platform/tests/Browser`
|
|
|
|
Implementation may remove a surface from the touched list if repo truth proves it is not product-facing or already uses the canonical resolver safely.
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: existing product-facing evidence labels/links and customer-safe evidence disclosure.
|
|
- **Affected routes/pages/actions/states/navigation/panel/provider surfaces**: dashboard/workspace/environment evidence CTA, Evidence Overview, Customer Review Workspace, Environment Review detail, Review Pack detail/rendered report, Stored Report/Management Report provenance, Evidence Snapshot technical detail links.
|
|
- **No-impact class, if applicable**: N/A.
|
|
- **Native vs custom classification summary**: mixed existing native Filament resources/pages plus existing Blade composition.
|
|
- **Shared-family relevance**: evidence links, status messaging, dashboard signals, artifact/report viewers, customer-safe disclosure.
|
|
- **State layers in scope**: page, detail, row URL, route target, report payload/provenance.
|
|
- **Audience modes in scope**: customer/read-only, operator-MSP, support/internal where authorized.
|
|
- **Decision/diagnostic/raw hierarchy plan**: product evidence decision first; diagnostics/raw proof secondary or gated.
|
|
- **Raw/support gating plan**: no raw evidence route by default on Customer Review Workspace; technical detail only through internal/audit action with permission.
|
|
- **One-primary-action / duplicate-truth control**: default UI shows at most one evidence-related action/state per context.
|
|
- **Handling modes by drift class or surface**: wrong current evidence is hard-stop; customer raw link leakage is hard-stop; technical/audit link mislabeling is review-mandatory.
|
|
- **Repository-signal treatment**: related completed specs are context only and must not be rewritten.
|
|
- **Special surface test profiles**: customer-safe strategic review surface + evidence/artifact detail + dashboard signal.
|
|
- **Required tests or manual smoke**: Unit resolver tests, Feature/Filament product surface tests, Browser smoke for dashboard/customer/review/evidence flows.
|
|
- **Exception path and spread control**: no exception expected; any retained page-local selector must be documented as technical/admin-only and proven not product-facing.
|
|
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage.
|
|
- **UI/Productization coverage decision**: update existing page-report artifacts if visible behavior materially changes; otherwise document no route/archetype expansion.
|
|
- **Coverage artifacts to update**: likely existing page reports for Customer Review Workspace, Evidence Overview, Review Pack detail, Environment Review detail, Stored Report detail, and Evidence Snapshot detail only if implementation materially changes default-visible behavior.
|
|
- **Explicit no-route/no-archetype expectation**: no route inventory, design matrix, strategic surfaces, grouped follow-up, or unresolved-page updates are expected unless implementation changes route reachability or page archetype/count; implementation must document that no-impact decision in the close-out.
|
|
- **No-impact rationale**: N/A.
|
|
- **Navigation / Filament provider-panel handling**: no provider registration or panel path change; provider registration remains `apps/platform/bootstrap/providers.php`.
|
|
- **Screenshot or page-report need**: focused browser smoke with screenshots if visible link/summary behavior changes; not required for purely route/service changes.
|
|
|
|
## Shared Pattern & System Fit
|
|
|
|
- **Cross-cutting feature marker**: yes.
|
|
- **Systems touched**: evidence resolver, review/review-pack/report provenance, dashboard/evidence links, customer-safe disclosure, technical/audit detail actions, `ArtifactTruthPresenter`/GovernanceArtifactTruth, `OperationRunLinks`, `RelatedNavigationResolver`, `GovernanceDecisionRegisterBuilder`, policies.
|
|
- **Shared abstractions reused**: existing `EvidenceSnapshot` scopes/relations where correct, existing review/review-pack/report relations, existing policies/capabilities, existing BadgeRenderer/BadgeCatalog, existing ArtifactTruthPresenter/GovernanceArtifactTruth presentation paths, Spec 392 output gate where customer output routes need gate context.
|
|
- **New abstraction introduced? why?**: one narrow derived Evidence Anchor Resolver/result contract because current product surfaces have multiple real evidence-anchor consumers and current local selectors can produce wrong proof.
|
|
- **Why the existing abstraction was sufficient or insufficient**: `EvidenceSnapshotResolver` is dimension/readiness oriented and does not encode product anchor type, customer-safe/no-link behavior, release-bound stability, or technical-only authorization.
|
|
- **Bounded deviation / spread control**: the new resolver must own evidence anchor decisions only. It must not become a generic proof-currentness, report-readiness, or technical annex framework. Shared link builders may remain technical/internal-only, but any product-facing EvidenceSnapshot link they emit must consume resolver output.
|
|
|
|
## OperationRun UX Impact
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: no new start/completion/link semantics. Existing OperationRun proof may remain only as technical/internal detail.
|
|
- **Central contract reused**: existing OperationRun link helpers where technical detail remains.
|
|
- **Delegated UX behaviors**: N/A.
|
|
- **Surface-owned behavior kept local**: evidence anchor labels/states only.
|
|
- **Queued DB-notification policy**: N/A.
|
|
- **Terminal notification path**: unchanged.
|
|
- **Exception path**: none.
|
|
|
|
## Provider Boundary & Portability Fit
|
|
|
|
- **Shared provider/platform boundary touched?**: no new provider seam.
|
|
- **Provider-owned seams**: N/A.
|
|
- **Platform-core seams**: evidence anchor selection, customer-safe evidence summary, technical evidence detail labels.
|
|
- **Neutral platform terms / contracts preserved**: workspace, managed environment, evidence, current evidence, review evidence, audit trail, internal evidence details.
|
|
- **Retained provider-specific semantics and why**: existing raw evidence technical pages may contain provider/source detail; default product surfaces must not.
|
|
- **Bounded extraction or follow-up path**: none unless implementation finds provider-specific leakage outside technical contexts.
|
|
|
|
## Constitution Check
|
|
|
|
- Inventory-first / snapshots-second: no new inventory truth; evidence snapshots remain explicit artifacts.
|
|
- Read/write separation: no destructive action or Graph write introduced.
|
|
- Graph contract path: no Graph calls expected; resolver/render paths must remain DB-only.
|
|
- Deterministic capabilities: existing capability/policy checks reused for target route availability.
|
|
- RBAC-UX: non-member workspace/environment access remains 404; member missing capability remains no technical link/403 on direct route.
|
|
- Workspace/tenant isolation: resolver scopes by workspace and managed environment before selecting anchors.
|
|
- OperationRun UX: no OperationRun start/completion changes; technical OperationRun links remain secondary.
|
|
- Test governance: Unit, Feature/Filament, and Browser proof are explicitly scoped.
|
|
- Proportionality: new resolver abstraction is justified by evidence trust, isolation, auditability, and multiple existing consumers.
|
|
- No premature abstraction: resolver replaces duplicated local selection and is not a generic proof framework.
|
|
- Persisted truth: no new persisted truth expected.
|
|
- Behavioral state: allowed UI states are derived result vocabulary, not persisted lifecycle truth.
|
|
- UI semantics: no new badge framework; use existing badge/status helpers.
|
|
- Shared pattern first: central resolver replaces local selectors; shared link helpers either consume it for product-facing links or are explicitly classified technical/internal-only.
|
|
- Provider boundary: provider-specific internals stay technical.
|
|
- UI/Productization coverage: visible surface changes require existing page-report updates or explicit no-archetype-change note.
|
|
|
|
## Domain And Data Implications
|
|
|
|
No migration is expected. Existing fields appear sufficient:
|
|
|
|
- `evidence_snapshots.workspace_id`
|
|
- `evidence_snapshots.managed_environment_id`
|
|
- `evidence_snapshots.status`
|
|
- `evidence_snapshots.completeness_state`
|
|
- `evidence_snapshots.generated_at`
|
|
- `evidence_snapshots.expires_at`
|
|
- `environment_reviews.evidence_snapshot_id`
|
|
- `environment_reviews.current_export_review_pack_id`
|
|
- `environment_reviews.status`
|
|
- `environment_reviews.published_at`
|
|
- `review_packs.evidence_snapshot_id`
|
|
- `review_packs.environment_review_id`
|
|
- `review_packs.status`
|
|
- `review_packs.expires_at`
|
|
- `stored_reports.source_environment_review_id`
|
|
- `stored_reports.source_review_pack_id`
|
|
|
|
If implementation proves an anchor cannot be represented with existing truth, stop and update spec/plan before adding schema. A schema change must be minimal, cleanly named, and pre-production clean-cut with no compatibility shim.
|
|
|
|
## Resolver Design Notes
|
|
|
|
Expected result fields:
|
|
|
|
```text
|
|
anchor_type: string
|
|
state: string
|
|
evidence_snapshot_id: int|null
|
|
target_route: string|null
|
|
is_current: bool
|
|
is_release_bound: bool
|
|
is_customer_safe: bool
|
|
is_technical_only: bool
|
|
is_partial: bool
|
|
is_superseded: bool
|
|
is_expired: bool
|
|
can_link: bool
|
|
can_view_technical_detail: bool
|
|
primary_reason: string
|
|
blocking_reasons: list<string>
|
|
display_label: string
|
|
```
|
|
|
|
Current evidence query rules:
|
|
|
|
```text
|
|
where workspace_id = scope workspace
|
|
where managed_environment_id = scope environment when present
|
|
where managed_environment_id in actor-authorized environment ids when no explicit environment is present and a product link is returned
|
|
where status = active
|
|
where completeness_state = complete
|
|
where expires_at is null or expires_at > now()
|
|
order by generated_at desc nulls last, id desc
|
|
```
|
|
|
|
Queued/generating evidence may be represented as draft/internal/in-progress state but must not be returned as product-facing current evidence.
|
|
|
|
When `environment` is null, implementation must not query arbitrary workspace evidence and return a single product-facing target. It must either return a non-link workspace summary state or limit selection to actor-authorized managed environments before returning per-environment/current anchors. Product-facing single-target links should prefer an explicit environment.
|
|
|
|
Released evidence rules:
|
|
|
|
- Environment Review: use `environment_reviews.evidence_snapshot_id`.
|
|
- Review Pack: use `review_packs.evidence_snapshot_id` and `environment_review_id` when release-bound output is in scope.
|
|
- Stored/management report: prefer source review/review-pack provenance when present; otherwise no valid released evidence rather than current fallback.
|
|
|
|
Customer-safe rules:
|
|
|
|
- Return summary state and copy.
|
|
- Do not return raw evidence route by default.
|
|
- Optional internal/audit action must be a separate technical result or secondary route.
|
|
|
|
Technical detail rules:
|
|
|
|
- Return raw EvidenceSnapshot route only if actor can view it and scope matches.
|
|
- Label as internal/audit detail.
|
|
|
|
## Route And Authorization Plan
|
|
|
|
- Resolver must not be the only security boundary. Direct routes remain protected by existing policies/controllers.
|
|
- UI target routes are returned only when the actor can view the target.
|
|
- Customer-safe actors get no technical target route.
|
|
- Internal/operator actors can get technical detail only through secondary/internal actions.
|
|
- Wrong-scope evidence direct access remains deny-as-not-found by policy/controller tests.
|
|
|
|
## Filament And Livewire Plan
|
|
|
|
- Filament v5 / Livewire v4.0+ compliance is required; the app currently uses Livewire 4.1.4.
|
|
- Panel provider registration remains `apps/platform/bootstrap/providers.php`; no provider changes are expected.
|
|
- No global search participation should be added or changed. If any touched resource currently participates in global search, verify View/Edit page and scoped search rules; otherwise keep global search disabled.
|
|
- No destructive action is introduced. Existing EvidenceSnapshot/ReviewPack/EnvironmentReview actions remain out of scope and must keep existing confirmation, authorization, audit, notifications, and tests.
|
|
- Labels must be truthful:
|
|
- `Current evidence` for current valid evidence.
|
|
- `Review evidence` for review-bound/released evidence.
|
|
- `Evidence captured for this review` for customer-safe summary.
|
|
- `View audit trail` or `View internal evidence details` for technical routes.
|
|
|
|
## Audit And Observability Plan
|
|
|
|
- No new `OperationRun` is expected.
|
|
- No new AuditLog requirement is expected for read-only anchor resolution.
|
|
- Existing audit events for downloads, review publication, evidence generation, and review-pack generation remain unchanged.
|
|
- If implementation adds logging for blocked technical route exposure or direct access, metadata must be safe and stable with no raw payloads/secrets/source keys.
|
|
|
|
## Test Strategy
|
|
|
|
### Unit tests
|
|
|
|
- Select newest valid current evidence for workspace/environment.
|
|
- Do not select superseded evidence as current.
|
|
- Do not select partial evidence as current.
|
|
- Do not select expired evidence as current.
|
|
- Do not select queued/generating/failed/stale evidence as current.
|
|
- Do not select wrong-workspace evidence.
|
|
- Do not select wrong-environment evidence, including workspace-wide/no-environment requests where the actor lacks entitlement.
|
|
- Return no valid evidence when only partial/superseded/expired evidence exists.
|
|
- Resolve released review evidence independently from current evidence.
|
|
- Keep released review evidence stable after newer current evidence is created.
|
|
- Resolve draft review evidence as internal/draft, not customer-safe.
|
|
- Resolve customer workspace as customer-safe summary with no raw route by default.
|
|
- Actor without permission receives no technical evidence link.
|
|
- Internal/operator actor may receive technical detail link where appropriate.
|
|
- Deterministic tie-breaker when multiple valid snapshots share timestamp.
|
|
- Workspace-wide current anchor does not select evidence from environments the actor cannot access.
|
|
|
|
### Feature / Filament / HTTP tests
|
|
|
|
- Dashboard/evidence overview evidence link targets current evidence.
|
|
- Dashboard/evidence overview does not link to superseded/partial evidence.
|
|
- Customer Review Workspace does not render raw evidence links by default.
|
|
- Review Pack detail uses release-bound evidence.
|
|
- Environment Review detail uses release-bound evidence.
|
|
- Rendered report/Stored Report/Management Report provenance uses released review evidence.
|
|
- Stored report/review output does not switch provenance after new current evidence.
|
|
- Direct wrong-scope evidence route remains blocked by scope authorization.
|
|
- Technical evidence detail requires internal permission.
|
|
- Customer-facing pages do not expose technical evidence terms by default.
|
|
- Affected list/detail paths avoid per-row evidence-link N+1 behavior by using explicit eager-loading or bounded resolver query shape where practical.
|
|
|
|
### Browser smoke
|
|
|
|
Focused smoke should cover:
|
|
|
|
- Environment Dashboard or workspace dashboard evidence CTA.
|
|
- Evidence Overview.
|
|
- Review Pack detail.
|
|
- Customer Review Workspace.
|
|
- Rendered/Stored Report surface if evidence provenance is visible.
|
|
|
|
Assertions:
|
|
|
|
- Current dashboard evidence link opens current evidence, not stale/superseded evidence.
|
|
- Customer Review Workspace has no raw evidence snapshot link by default.
|
|
- Review Pack evidence label is truthful.
|
|
- Technical evidence link, if present, is secondary/internal.
|
|
- No visible `Evidence #<id>` style product link on customer-safe surface.
|
|
- No 500/Livewire/Filament/console errors in affected flows.
|
|
- Direct wrong/old evidence URL does not become a customer-facing proof path.
|
|
|
|
## Validation Commands
|
|
|
|
Preferred Sail commands:
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec393
|
|
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec393EvidenceAnchorReconciliationSmokeTest.php
|
|
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
|
|
git diff --check
|
|
```
|
|
|
|
If Sail/Docker is unavailable, run the equivalent local PHP/Pest commands and document the fallback.
|
|
|
|
## Rollout And Deployment Considerations
|
|
|
|
- No env vars expected.
|
|
- No migrations expected.
|
|
- No queue/scheduler/storage changes expected.
|
|
- No Graph scope or provider configuration changes expected.
|
|
- No Filament assets expected.
|
|
- Dokploy/staging validation is still required for the later PR because user-facing `/admin` surfaces change, but there is no production-data compatibility burden.
|
|
|
|
## Risk Controls
|
|
|
|
- Resolver tests must fail if partial/superseded/wrong-scope evidence is selected.
|
|
- Feature/browser tests must fail if customer workspace exposes raw evidence by default.
|
|
- Released review tests must fail if new current evidence changes old released output provenance.
|
|
- Code review must search for remaining local fallback selectors and arbitrary latest evidence ordering in affected product surfaces.
|
|
|
|
## Implementation Phases
|
|
|
|
1. Repo truth inventory and local selector map.
|
|
2. Resolver contract and Unit tests.
|
|
3. Current evidence replacement in dashboard/evidence overview.
|
|
4. Released review/report/review-pack provenance replacement.
|
|
5. Customer Review Workspace customer-safe summary replacement.
|
|
6. Technical evidence detail gating and labels.
|
|
7. Deprecated local selector/test cleanup.
|
|
8. Browser smoke and close-out report.
|
|
|
|
## Stop Conditions
|
|
|
|
- Stop if implementation requires a new persisted entity/table/status family not justified in this spec.
|
|
- Stop if a route/controller change would create a new customer portal or broad technical annex.
|
|
- Stop if a local selector appears necessary for a product-facing surface; update spec/plan or fold it into the resolver instead.
|
|
- Stop if the only way to keep an old test green is to preserve partial/superseded/latest fallback behavior.
|