295 lines
23 KiB
Markdown
295 lines
23 KiB
Markdown
# 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)
|
|
|
|
```text
|
|
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)
|
|
|
|
```text
|
|
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.
|