TenantAtlas/specs/174-evidence-freshness-publication-trust/plan.md
ahmido 44898a98ac feat: harden evidence freshness publication trust (#205)
## Summary
- harden governance artifact truth propagation so stale or partial evidence downgrades evidence snapshots, tenant reviews, review packs, the canonical evidence overview, and the canonical review register consistently
- add the full Spec 174 artifact set under `specs/174-evidence-freshness-publication-trust/` including spec, plan, research, data model, contracts, quickstart, checklist, and completed tasks
- add focused fixture helpers plus a new browser smoke test for the touched evidence, review, and review-pack trust surfaces

## Testing
- `vendor/bin/sail artisan test --compact tests/Feature/Evidence/EvidenceSnapshotResourceTest.php tests/Feature/Evidence/EvidenceOverviewPageTest.php tests/Feature/TenantReview/TenantReviewLifecycleTest.php tests/Feature/TenantReview/TenantReviewRegisterTest.php tests/Feature/ReviewPack/ReviewPackResourceTest.php tests/Feature/Monitoring/ArtifactTruthRunDetailTest.php tests/Browser/Spec174EvidenceFreshnessPublicationTrustSmokeTest.php`
- manual integrated-browser smoke pass across Evidence Overview, Review Register, tenant review detail, tenant evidence snapshot detail, and review-packs list

## Notes
- Livewire v4 compliance is preserved and no Filament v3/v4 APIs were introduced
- no panel or provider changes were made; Laravel 11+ provider registration remains in `bootstrap/providers.php`
- no new global-search behavior was introduced; existing resource view pages remain the relevant detail endpoints
- destructive actions were not broadened; existing confirmation and authorization behavior remains in place
- no new assets were added, so the current Filament asset strategy and deploy-time `php artisan filament:assets` behavior stay unchanged
- branch `174-evidence-freshness-publication-trust` is pushed at `7f2c82c26dc83bbc09fbf9e732d5644cdd143113` and targets `dev`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #205
2026-04-04 11:31:27 +00:00

23 KiB

Implementation Plan: Evidence Temporal Freshness & Review Publication Trust

Branch: 174-evidence-freshness-publication-trust | Date: 2026-04-04 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/174-evidence-freshness-publication-trust/spec.md Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/174-evidence-freshness-publication-trust/spec.md

Summary

Harden evidence freshness and publication trust across the existing evidence snapshot, tenant review, review pack, evidence overview, and canonical review register surfaces without adding new persistence, a new trust layer, or a new reporting subsystem. The implementation will reuse the source-derived stale semantics and their existing source-defined freshness thresholds, tighten propagation in ArtifactTruthPresenter, keep review readiness and publication readiness distinct, preserve the current tenant and canonical routes and action inventory, and close the existing cross-surface gap where stale or partial evidence can still look publishable.

Key approach: keep the work inside the current EvidenceSnapshotService freshness semantics, TenantReviewReadinessGate, ArtifactTruthPresenter, tenant-scoped Filament resources, and canonical summary pages. The slice is primarily about better derivation and consistent display, not about new models or new workflows.

Technical Context

Language/Version: PHP 8.4, Laravel 12, Filament v5, Livewire v4, Blade
Primary Dependencies: Filament v5, Livewire v4, Pest v4, Laravel Sail, existing ArtifactTruthPresenter, ArtifactTruthEnvelope, TenantReviewReadinessGate, EvidenceSnapshotService, TenantReviewRegisterService, and current evidence/review/review-pack resources and pages
Storage: PostgreSQL with existing evidence_snapshots, evidence_snapshot_items, tenant_reviews, and review_packs tables using current summary JSON and timestamps; no schema change planned
Testing: Pest feature tests and Livewire page tests run via Sail, plus existing governance-artifact fixture helpers
Target Platform: Laravel web application in Sail locally and containerized Linux deployment in staging and production Project Type: Laravel monolith web application
Performance Goals: Preserve DB-only render behavior on detail and canonical surfaces, avoid any render-time external calls, keep list-row truth derivation lightweight enough for canonical table scans, and keep operator trust signals readable within a 5-10 second scan on summary surfaces
Constraints: No new tables, no new enum families, no new presenter or resolver subsystem, no route changes, no RBAC drift, no destructive-action placement drift, no global asset changes, and no new global freshness engine if existing source-derived stale semantics are sufficient
Scale/Scope: Five operator-facing surfaces (/admin/evidence/overview, /admin/reviews, /admin/t/{tenant}/evidence/{snapshot}, /admin/t/{tenant}/reviews/{review}, /admin/t/{tenant}/review-packs/{pack}), one central truth presenter, existing readiness helpers, and focused regression coverage across fresh, stale, partial, blocked, internal-only, and publishable scenarios

Constitution Check

GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing.

Principle Status Notes
Inventory-first Pass Evidence freshness remains derived from the existing snapshot-item and source-evaluation chain; no new snapshot ownership semantics
Read/write separation Pass This slice primarily changes truth derivation and display; existing mutate actions remain unchanged
Graph contract path Pass No new Graph calls or contract-registry changes are introduced
Deterministic capabilities Pass No new capability derivation or role mapping is added
RBAC-UX planes and 404 vs 403 Pass Tenant-scoped resources remain tenant-scoped; canonical /admin pages stay workspace- and tenant-entitlement-safe
Workspace isolation Pass Canonical summary pages continue to derive rows only from entitled tenants in the current workspace
Tenant isolation Pass Drill-through links remain tenant-scoped and non-entitled users remain deny-as-not-found
Destructive confirmation Pass Existing destructive actions (Expire snapshot, Archive review, Expire pack) already require confirmation and remain unchanged
Global search safety Pass No global-search behavior is added or broadened; EvidenceSnapshotResource, TenantReviewResource, and ReviewPackResource already have view pages
Run observability Pass Existing evidence, review, and pack generation flows keep their current OperationRun types and ownership; no new run type is introduced
Ops-UX 3-surface feedback Pass No toast, progress, or terminal-notification behavior changes
Ops-UX lifecycle ownership Pass No OperationRun.status or outcome transition logic is touched
Ops-UX summary counts Pass No changes to summary_counts contracts are required
Ops-UX guards Pass Existing operation lifecycle guards stay in place; this feature adds truth-surface regression tests instead
Data minimization Pass No new payload exposure or raw-report surface is introduced
Proportionality (PROP-001) Pass The implementation stays inside existing freshness, readiness, and truth layers rather than adding persistence or abstraction
No premature abstraction (ABSTR-001) Pass No new resolver, gate, presenter family, registry, or taxonomy is planned
Persisted truth (PERSIST-001) Pass All new semantics remain derived from existing timestamps, summary state, and linked records
Behavioral state (STATE-001) Pass No new persisted states are introduced; existing stale/partial/publishable/internal-only semantics become stricter
UI semantics (UI-SEM-001) Pass Existing badge and truth primitives are reused; no second interpretation framework is introduced
V1 explicitness / few layers (V1-EXP-001, LAYER-001) Pass One central presenter and existing pages remain the implementation seam
Badge semantics (BADGE-001) Pass Existing freshness, completeness, publication-readiness, and artifact-truth badge domains stay canonical
Filament-native UI (UI-FIL-001) Pass Existing Filament resources, pages, badges, tables, and infolists are reused; no page-local status language is added
UI/UX surface taxonomy (UI-CONST-001 / UI-SURF-001) Pass Evidence snapshot, tenant review, and review pack remain CRUD / List-first Resource surfaces with dedicated detail pages, while evidence overview and review register remain Read-only Registry / Report Surface surfaces
UI/UX inspect model (UI-HARD-001) Pass Clickable-row inspect remains primary on the affected lists; no redundant view action is introduced
UI/UX action hierarchy (UI-HARD-001 / UI-EX-001) Pass Existing one-inline-safe-shortcut patterns remain; no new row-level destructive actions are added
UI/UX scope, truth, and naming (UI-HARD-001 / UI-NAMING-001 / OPSURF-001) Pass The feature strengthens default-visible trust truth while preserving canonical nouns and existing verbs
List-surface review checklist (UI-STD-001) Pass The affected list and report surfaces will be reviewed against docs/product/standards/list-surface-review-checklist.md during implementation and final verification
Filament Action Surface Contract Pass Current surface declarations already match the required list/detail behavior; the feature changes truth semantics, not action topology
Filament UX-001 Pass Existing Infolist and table layouts remain; this slice strengthens the truth surfaces inside them
Filament v5 / Livewire v4 compliance Pass The work remains inside the current Filament v5 + Livewire v4 stack
Provider registration location Pass No panel/provider changes; Laravel 11+ provider registration remains in bootstrap/providers.php
Asset strategy Pass No new panel or shared assets are required; deployment filament:assets behavior remains unchanged

Phase 0 Research

Research outcomes are captured in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/174-evidence-freshness-publication-trust/research.md.

Key decisions:

  • Reuse the existing source-derived stale semantics from evidence providers and EvidenceCompletenessEvaluator instead of creating a new global freshness engine.
  • Tighten ArtifactTruthPresenter rather than introducing a new publication-trust resolver or freshness-trust gate.
  • Degrade tenant review and review pack publication trust when freshness is stale and downgrade partial evidence to internal_only unless stronger existing blockers already make the artifact blocked.
  • Make review packs inherit stale and partial burden from their linked review and evidence basis instead of treating pack freshness as current whenever the file itself is not expired.
  • Keep canonical register and overview surfaces aligned by reusing the same truth envelope and next-step language rather than adding page-local taxonomies or ad-hoc columns.
  • Expand existing Pest coverage and fixture builders rather than creating a new UI test harness.

Phase 1 Design

Design artifacts are created under /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/174-evidence-freshness-publication-trust/:

  • data-model.md: derived trust-propagation model for evidence snapshots, tenant reviews, review packs, and canonical summary rows
  • contracts/evidence-review-trust-surfaces.openapi.yaml: internal page-contract schema for the affected rendered HTML surfaces and their structured truth payloads
  • quickstart.md: focused verification workflow for manual and automated validation

Design decisions:

  • No schema migration is required; freshness remains derived from existing evidence-source timestamps and summary state.
  • The primary implementation seam is ArtifactTruthPresenter, supported by the current evidence and review readiness services and existing page row builders.
  • TenantReviewReadinessGate remains the publish-blocker authority for required stale or missing sections; this feature tightens how that burden is translated into operator-facing trust and publication surfaces.
  • EvidenceOverview and ReviewRegister continue to render read-only summary rows, but must no longer sound calmer than the corresponding tenant-scoped detail surfaces.
  • Existing destructive actions and capabilities remain unchanged; only truth presentation, next-step guidance, and consistency rules are hardened.

Project Structure

Documentation (this feature)

specs/174-evidence-freshness-publication-trust/
├── spec.md
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│   └── evidence-review-trust-surfaces.openapi.yaml
├── checklists/
│   └── requirements.md
└── tasks.md

Source Code (repository root)

app/
├── Filament/
│   ├── Pages/
│   │   ├── Monitoring/
│   │   │   └── EvidenceOverview.php
│   │   └── Reviews/
│   │       └── ReviewRegister.php
│   └── Resources/
│       ├── EvidenceSnapshotResource.php
│       ├── ReviewPackResource.php
│       ├── TenantReviewResource.php
│       ├── EvidenceSnapshotResource/
│       │   └── Pages/
│       │       └── ViewEvidenceSnapshot.php
│       ├── ReviewPackResource/
│       │   └── Pages/
│       │       └── ViewReviewPack.php
│       └── TenantReviewResource/
│           └── Pages/
│               └── ViewTenantReview.php
├── Models/
│   ├── EvidenceSnapshot.php
│   ├── EvidenceSnapshotItem.php
│   ├── ReviewPack.php
│   └── TenantReview.php
├── Services/
│   ├── Evidence/
│   │   ├── EvidenceCompletenessEvaluator.php
│   │   ├── EvidenceSnapshotService.php
│   │   └── Sources/
│   │       ├── BaselineDriftPostureSource.php
│   │       ├── EntraAdminRolesSource.php
│   │       ├── FindingsSummarySource.php
│   │       ├── OperationsSummarySource.php
│   │       └── PermissionPostureSource.php
│   └── TenantReviews/
│       ├── TenantReviewReadinessGate.php
│       └── TenantReviewRegisterService.php
└── Support/
    └── Ui/
        └── GovernanceArtifactTruth/
            ├── ArtifactTruthEnvelope.php
            └── ArtifactTruthPresenter.php

resources/
└── views/
    └── filament/
        ├── infolists/
        │   └── entries/
        │       └── governance-artifact-truth.blade.php
        └── pages/
            ├── monitoring/
            │   └── evidence-overview.blade.php
            └── reviews/
                └── review-register.blade.php

routes/
└── web.php

tests/
├── Feature/
│   ├── Concerns/
│   │   └── BuildsGovernanceArtifactTruthFixtures.php
│   ├── Evidence/
│   │   ├── EvidenceOverviewPageTest.php
│   │   └── EvidenceSnapshotResourceTest.php
│   ├── Monitoring/
│   │   └── ArtifactTruthRunDetailTest.php
│   ├── ReviewPack/
│   │   └── ReviewPackResourceTest.php
│   └── TenantReview/
│       ├── TenantReviewLifecycleTest.php
│       └── TenantReviewRegisterTest.php
└── Pest.php

Structure Decision: Standard Laravel monolith. The change is concentrated in one existing truth-presenter seam, current readiness helpers, a small set of existing Filament resources/pages, and focused Pest coverage. No new base directories, services, or presentation frameworks are required.

Implementation Strategy

Phase A — Preserve Source-Derived Freshness As The Canonical Input

Goal: Keep existing provider-level stale semantics as the source of truth and document them clearly in the implementation so the feature does not accidentally invent a second freshness system.

Step File Change
A.1 app/Services/Evidence/EvidenceCompletenessEvaluator.php Confirm that source-level stale evaluation and snapshot completeness remain the canonical freshness input used by the UI truth layer
A.2 app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php Keep evidence-snapshot truth derived from snapshot status, completeness, and summary.stale_dimensions rather than introducing new page-local age logic
A.3 specs/174-evidence-freshness-publication-trust/research.md and data-model.md Record the source-derived freshness chain so implementation does not drift into a new threshold engine

Phase B — Downgrade Tenant Review Publication Trust When Freshness Or Completeness Weakens Confidence

Goal: Ensure tenant reviews can remain useful internally while no longer appearing publishable when their evidence basis is stale or partial.

Step File Change
B.1 app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php Tighten buildTenantReviewEnvelope() so stale freshness and partial evidence degrade publication readiness and next-step guidance appropriately
B.2 app/Services/TenantReviews/TenantReviewReadinessGate.php Reuse existing required-section stale and missing blocker semantics; do not create a second publish-blocker system
B.3 app/Filament/Resources/TenantReviewResource.php and app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php Verify the tightened truth envelope is visible on list and detail surfaces without changing action topology or copy vocabulary

Phase C — Propagate Source Review And Evidence Burden Into Review Pack Trust

Goal: Prevent review packs from appearing calmer than the review or evidence basis they were generated from.

Step File Change
C.1 app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php Tighten buildReviewPackEnvelope() so pack freshness and publication readiness inherit stale or partial burden from the source review and evidence resolution
C.2 app/Filament/Resources/ReviewPackResource.php and app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php Ensure pack list/detail surfaces expose internal-only or cautionary trust and next-step caveats before download or sharing
C.3 resources/views/filament/infolists/entries/governance-artifact-truth.blade.php Reuse the existing truth partial to surface freshness and publication dimensions with stronger consistency rather than new local markup

Phase D — Align Canonical Overview And Register Rows With Tenant-Scoped Detail Truth

Goal: Ensure /admin/evidence/overview and /admin/reviews summarize the same truth direction as the tenant-scoped detail pages.

Step File Change
D.1 app/Filament/Pages/Monitoring/EvidenceOverview.php Keep row truth and next-step guidance sourced from the same envelope semantics used by snapshot detail
D.2 app/Filament/Pages/Reviews/ReviewRegister.php Keep artifact truth, publication readiness, and next-step rows aligned with tenant review detail without adding new ad-hoc row taxonomy
D.3 routes/web.php and current navigation helpers Preserve existing canonical route shape and tenant-prefilter continuity; no routing change

Phase E — Regression Protection And Focused Validation

Goal: Add the smallest useful test set that protects stale propagation, partial-evidence trust, review/pack consistency, and canonical summary alignment.

Step File Change
E.1 tests/Feature/Concerns/BuildsGovernanceArtifactTruthFixtures.php Add fixture helpers for stale and partial evidence scenarios so tests do not duplicate setup logic
E.2 tests/Feature/Evidence/EvidenceSnapshotResourceTest.php Add fresh-vs-stale snapshot truth assertions, including stale-dimension next-step behavior
E.3 tests/Feature/TenantReview/TenantReviewLifecycleTest.php Add stale and partial review publication-trust assertions without changing lifecycle behavior
E.4 tests/Feature/ReviewPack/ReviewPackResourceTest.php Add pack trust propagation assertions for stale or partial source review/evidence combinations
E.5 tests/Feature/TenantReview/TenantReviewRegisterTest.php and tests/Feature/Evidence/EvidenceOverviewPageTest.php Add canonical row-alignment assertions so summary pages do not sound calmer than detail
E.6 vendor/bin/sail bin pint --dirty --format agent and focused Pest runs Required formatting and targeted verification before task completion

Key Design Decisions

D-001 — Source-specific stale evaluation stays canonical

Evidence sources already produce stale item states using their own domain-appropriate recency logic, and EvidenceCompletenessEvaluator already rolls those into snapshot completeness. The plan reuses that chain instead of inventing a separate global age-policy system.

D-002 — ArtifactTruthPresenter remains the single trust-propagation seam

The current code already centralizes evidence snapshot, tenant review, and review pack trust in one presenter. Tightening that presenter is narrower and safer than introducing a new publication-trust resolver or freshness framework.

D-003 — Publication readiness remains distinct from freshness and completeness

The feature must not collapse all trust dimensions into one vague ready state. Freshness, completeness, and publication readiness remain separate dimensions, but stale evidence downgrades share safety and partial evidence downgrades publication readiness to internal_only unless existing blockers already make the artifact blocked.

D-004 — Canonical summary pages must reuse existing truth, not invent row-local semantics

EvidenceOverview and ReviewRegister already surface artifact truth, publication, and next-step information. The right fix is to align their inputs with the tightened truth envelope, not to add page-specific badges or prose.

D-005 — No new persistence or reporting subsystem is justified

This is a current-release operator-trust problem, but it is still a derived-truth problem. Existing timestamps, summary state, and linked artifacts are enough to solve it without a StoredReport viewer, new export-governance model, or separate publication-trust entity.

Risk Assessment

Risk Impact Likelihood Mitigation
Review publication trust becomes too strict and downgrades healthy reviews Medium Medium Base downgrades on existing stale/partial semantics already produced by evidence and review services rather than a new heuristic
Review pack truth diverges from review truth because pack code and review code evolve separately High Medium Centralize propagation in ArtifactTruthPresenter and add explicit review-vs-pack consistency tests
Canonical summary pages become denser or harder to scan Medium Low Reuse existing columns and next-step fields instead of adding more row furniture
fresh versus non-fresh envelope variants diverge across surfaces Medium Low Keep one truth-building path and only use fresh variants when cache bypass is genuinely needed
Implementation accidentally introduces a new freshness policy or new abstraction Medium Low Lock the design to current source-derived stale semantics and reject new persistence or resolver additions in review

Test Strategy

  • Extend the current evidence, tenant review, review pack, and canonical summary Pest tests instead of adding a new testing layer.
  • Use BuildsGovernanceArtifactTruthFixtures and existing composeTenantReviewForTest() helpers to build fresh, stale, and partial scenarios consistently.
  • Add explicit assertions for fresh versus stale evidence snapshots, partial versus complete review evidence, review-pack versus review trust alignment, and canonical row truth alignment.
  • Preserve existing authorization semantics: non-entitled users remain 404, in-scope users without manage capability remain 403 for actions, and summary truth remains visible only within entitled scope.
  • Keep destructive actions and operation-launch semantics unchanged; test additions should focus on trust consequences, not on unrelated lifecycle behavior.
  • Focused verification targets: EvidenceSnapshotResourceTest, TenantReviewLifecycleTest, ReviewPackResourceTest, TenantReviewRegisterTest, EvidenceOverviewPageTest, and fixture helpers.

Complexity Tracking

No constitution violations or justified complexity exceptions were identified.

Proportionality Review

Not triggered beyond the already-passed spec review. The plan introduces no new enum/status family, DTO/presenter family, persisted entity, registry, resolver, taxonomy, or cross-domain UI framework.