Automated PR created by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #464
22 KiB
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
- Inventory every evidence selector/link/action/output path.
- Define a derived
EvidenceAnchorResolvercontract and result value object/array shape with a non-persisted anchor type/state vocabulary. - Implement current-scope resolution with strict scope, active/complete/non-expired checks, and deterministic ordering.
- Implement released-review/review-pack/report resolution from existing release-bound relations.
- Implement customer-safe summary resolution that omits target routes by default.
- Implement technical-detail resolution with actor permission checks.
- Replace local selectors in affected product surfaces.
- Remove deprecated local fallback logic and stale test expectations.
- Add regression tests and focused browser smoke.
Preferred shape:
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.phpapps/platform/app/Services/EnvironmentReviews/EnvironmentReviewService.phpapps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.phpapps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.phpapps/platform/resources/views/filament/pages/reviews/customer-review-workspace.blade.phpapps/platform/app/Filament/Resources/EnvironmentReviewResource.phpapps/platform/app/Filament/Resources/ReviewPackResource.phpapps/platform/app/Filament/Resources/StoredReportResource.phpapps/platform/app/Filament/Resources/EvidenceSnapshotResource.phpapps/platform/app/Support/ReviewPacks/ManagementReportPdfPayloadBuilder.phpapps/platform/app/Support/ReviewPublicationResolution/ReviewPublicationProofResolver.phpapps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.phpapps/platform/app/Support/OperationRunLinks.phpapps/platform/app/Support/Navigation/RelatedNavigationResolver.phpapps/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, andapps/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
EvidenceSnapshotscopes/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:
EvidenceSnapshotResolveris 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_idevidence_snapshots.managed_environment_idevidence_snapshots.statusevidence_snapshots.completeness_stateevidence_snapshots.generated_atevidence_snapshots.expires_atenvironment_reviews.evidence_snapshot_idenvironment_reviews.current_export_review_pack_idenvironment_reviews.statusenvironment_reviews.published_atreview_packs.evidence_snapshot_idreview_packs.environment_review_idreview_packs.statusreview_packs.expires_atstored_reports.source_environment_review_idstored_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:
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:
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_idandenvironment_review_idwhen 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 evidencefor current valid evidence.Review evidencefor review-bound/released evidence.Evidence captured for this reviewfor customer-safe summary.View audit trailorView internal evidence detailsfor technical routes.
Audit And Observability Plan
- No new
OperationRunis 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:
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
/adminsurfaces 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
- Repo truth inventory and local selector map.
- Resolver contract and Unit tests.
- Current evidence replacement in dashboard/evidence overview.
- Released review/report/review-pack provenance replacement.
- Customer Review Workspace customer-safe summary replacement.
- Technical evidence detail gating and labels.
- Deprecated local selector/test cleanup.
- 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.