Automated PR provided by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #477
20 KiB
Implementation Plan: Spec 406 - Governance Artifact Lifecycle & Retention
Branch: 406-governance-artifact-lifecycle-retention | Date: 2026-06-23 | Spec: specs/406-governance-artifact-lifecycle-retention/spec.md
Input: Feature specification from specs/406-governance-artifact-lifecycle-retention/spec.md
Summary
Prepare a bounded runtime hardening slice for existing governance artifacts. Implementation must inventory review packs, stored reports/management PDFs, evidence snapshots, customer-review outputs, OperationRun proof packages where exposed, and finding/exception artifacts; classify lifecycle behavior; add only necessary current-owner metadata/actions/jobs; prove hold/delete/export/download/file consistency; and produce a final lifecycle matrix. This is not a new artifact portal, purge platform, export center, compliance product, or full browser audit.
Technical Context
Language/Version: PHP 8.4.15, Laravel 12.52.0, Filament 5.2.1, Livewire 4.1.4.
Primary Dependencies: Laravel models, migrations, policies/gates, storage disks, queues/scheduler where already used, Filament v5 actions/resources/pages, Pest 4, browser lane.
Storage: PostgreSQL; private exports disk for generated artifacts; existing artifact tables such as review_packs, stored_reports, evidence_snapshots, operation_runs, finding_exceptions, and related review/output tables.
Testing: Pest 4 Feature/Filament/Livewire/action tests, focused storage/file tests, targeted scheduler/command tests, focused browser proof.
Validation Lanes: fast-feedback, confidence, browser; PostgreSQL lane if migrations/constraints/indexes are added.
Target Platform: TenantPilot Laravel monolith under apps/platform, deployed through Sail locally and Dokploy for staging/production.
Constraints: no new major UI surface, no new panel/provider, no global artifact registry, no broad purge/export framework, no compliance claim, no evidence/currentness rewrite, no PDF layout/template rewrite, no JSONB/data-layer scope, and no completed-spec rewrite.
Inherited Baseline
- Spec 267 delivered the shared read-only lifecycle/retention contract on evidence, tenant-review, review-pack, stored-report, and accepted-risk seams, then explicitly deferred hold and deletion-request persistence.
ReviewPackhas status, fingerprint, file disk/path/size/SHA, generated/expiry timestamps, evidence/review links, and retention config throughtenantpilot.review_pack.StoredReporthas report type/format/status/profile, payload, file disk/path/size/SHA, generated timestamp, operation/source links, and JSONB payload indexing.EvidenceSnapshothas status, completeness state, summary, fingerprints, generated/expiry timestamps, and links to review packs/environment reviews.OperationRunhas separate execution truth through status/outcome/context/summary counts and must not become artifact lifecycle truth.PruneReviewPacksCommandandPruneStoredReportsCommandalready provide retention-like behavior, but require lifecycle/hold/file consistency proof before broader claims.- Specs 403, 404, and 405 are proof lineage for evidence/currentness, management-report PDF runtime, and JSONB storage. Their contracts must not regress.
- Specs 404 and 405 are
PASS WITH CONDITIONSbecause external Staging/Dokploy proof remains unavailable. Spec 406 may harden local runtime semantics, but must not claim production/staging readiness for PDF, storage, deployment, or download paths unless new proof is collected or the carry-forward condition is explicitly not applicable.
Technical Approach
- Record branch, HEAD, dirty state, and
git diff --check. - Create
implementation-report.mdbefore runtime changes and populate the lifecycle matrix as inventory proceeds. - Inventory in-scope artifact families, actions, routes, policies, commands/jobs, file dependencies, retention config, audit paths, and tests.
- Classify each artifact family as
PASS,PASS WITH EXCEPTION,MISSING PROOF,DEFECT FOUND,PRODUCT DECISION REQUIRED, orDEFERRED, and separately classify hold/delete support asSUPPORTED_NOW,DEFERRED, orPRODUCT_DECISION_REQUIRED. - Add tests before fixes where feasible for hold, delete/archive/expire, export/download, direct authorization, customer-safe output, and file/database consistency.
- Implement only confirmed in-scope lifecycle behavior on existing artifact owners.
- Run focused tests and browser proof.
- Complete implementation-report gate result and next recommendation.
Likely Affected Repository Surfaces
Implementation must verify exact paths before editing.
apps/platform/app/Models/ReviewPack.php
apps/platform/app/Models/StoredReport.php
apps/platform/app/Models/EvidenceSnapshot.php
apps/platform/app/Models/OperationRun.php
apps/platform/app/Models/FindingException.php
apps/platform/app/Models/FindingExceptionDecision.php
apps/platform/app/Filament/Resources/ReviewPackResource.php
apps/platform/app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php
apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php
apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php
apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php
apps/platform/app/Http/Controllers/ReviewPackDownloadController.php
apps/platform/app/Http/Controllers/ManagementReportPdfDownloadController.php
apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php
apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthEnvelope.php
apps/platform/app/Support/Badges/BadgeCatalog.php
apps/platform/app/Support/Badges/BadgeRenderer.php
apps/platform/app/Support/Badges/Domains/GovernanceArtifactLifecycleBadge.php
apps/platform/app/Support/Badges/Domains/GovernanceArtifactRetentionBadge.php
apps/platform/app/Support/Audit/AuditActionId.php
apps/platform/app/Services/Audit/WorkspaceAuditLogger.php
apps/platform/app/Services/ReviewPackService.php
apps/platform/app/Services/Evidence/EvidenceSnapshotService.php
apps/platform/app/Services/ManagementReports/
apps/platform/app/Console/Commands/PruneReviewPacksCommand.php
apps/platform/app/Console/Commands/PruneStoredReportsCommand.php
apps/platform/config/tenantpilot.php
apps/platform/config/filesystems.php
apps/platform/database/migrations/
apps/platform/tests/
UI / Surface Guardrail Plan
- Guardrail scope: existing lifecycle/download/action/status surfaces.
- Affected routes/pages/actions/states/navigation/panel/provider surfaces: existing review-pack, evidence, stored-report/PDF, customer-review, and finding/exception artifact surfaces only.
- No-impact class: N/A.
- Native vs custom classification summary: native Filament resources/pages plus existing controllers.
- Shared-family relevance: evidence/report viewers, status messaging, download actions, dangerous lifecycle actions, audit links.
- State layers in scope: artifact lifecycle, retention, file availability, evidence/currentness, customer-safe availability, execution proof.
- Audience modes in scope: operator/MSP, customer/read-only, support/platform internal.
- Decision/diagnostic/raw hierarchy plan: decision-first; diagnostics secondary; support/raw evidence third.
- Raw/support gating plan: raw evidence, provider payloads, source keys, OperationRun internals, file paths, and technical errors remain hidden or capability-gated.
- One-primary-action / duplicate-truth control: each surface shows one lifecycle summary and one dominant next action; secondary lifecycle actions move to More/danger placement.
- Handling modes by drift class or surface: review-mandatory for all changed existing surfaces; exception-required for any new route/nav/page or broad lifecycle framework.
- Repository-signal treatment: hard-stop-candidate if implementation adds new panel/provider, generic artifact table, portal, export center, or purge framework without spec update.
- Special surface test profiles: standard-native-filament, shared-detail-family, download/controller, browser.
- Required tests or manual smoke: feature/action tests plus focused browser proof.
- Exception path and spread control: none planned. Any product surface exception must be recorded in the implementation report.
- Active feature PR close-out entry: Guardrail / Product Surface.
Product Surface Contract Plan
- Product Surface Contract reference:
docs/product/standards/product-surface-contract.md. - No-legacy posture: canonical lifecycle behavior; no fallback readers, duplicate old labels, hidden compatibility routes, or old lifecycle copy.
- Page archetype and surface budget plan: Report Page, Receipt Page, Decision Page, Technical Annex, Search/Index Page; budgets expected to pass.
- Technical Annex and deep-link demotion plan: raw IDs, provider payloads, source keys, detector names, OperationRun internals, file paths, and low-level logs are demoted from customer/product defaults.
- Canonical status vocabulary plan: map to Ready, Needs attention, Blocked, Running, Failed, Expired, Historical, Superseded, Unknown, and severity vocabulary where visible.
- Product Surface exceptions: none planned.
- Browser verification plan: focused browser proof for representative lifecycle state, allowed download/export, blocked customer/internal access,
SUPPORTED_NOWheld-delete block where applicable, and missing-file/not-downloadable state. - Human Product Sanity plan: review changed rendered behavior and final implementation report.
- Visible complexity outcome target: neutral or decreased.
- Implementation report target:
specs/406-governance-artifact-lifecycle-retention/implementation-report.md.
Filament / Livewire / Deployment Posture
- Livewire v4 compliance: Livewire 4.1.4 confirmed; any changed Filament page/resource remains Livewire v4 compatible.
- Panel provider registration location: Laravel 12 panel providers remain in
apps/platform/bootstrap/providers.php; no provider registration change is planned. - Global search posture: no new globally searchable resource is planned. Existing affected resources must either remain non-searchable or have safe View/Edit pages and scoped queries.
- Destructive/high-impact action posture: delete, hard-delete, purge-like, hold release that enables deletion, archive/expire where availability changes, export, and regeneration-affecting lifecycle actions are high-impact. Filament actions must use
->action(...),->requiresConfirmation(), policy/gate authorization, and audit proof. - Asset strategy: no new assets or
FilamentAsset::register()work planned. Existing deployment baseline forphp artisan filament:assetsremains unchanged unless implementation adds registered assets, which should stop for spec update. - Testing plan: Feature/Filament/Livewire action tests, storage/file tests, command/job tests, direct-route authorization tests, customer-safe output tests, focused browser proof.
- Deployment impact: possible migrations, config/env additions for retention defaults, scheduler/command behavior, queue/storage implications, and Dokploy staging validation. No Graph scopes or provider credentials expected.
RBAC / Security / Audit Plan
- Workspace membership and managed-environment entitlement remain isolation boundaries.
- Wrong workspace/environment/non-member access returns 404.
- In-scope capability denial returns 403.
- Customer reviewers remain read-only and customer-safe bounded.
- UI visibility is not authorization; direct routes/actions must enforce policies/gates.
- Audit events must redact secrets, raw provider payloads, stack traces, internal exception bodies, and sensitive file paths.
- Lifecycle audit metadata should include actor, workspace, managed environment, artifact family, safe artifact reference, old state, new state, result, and failure reason.
Data / Migration Plan
- Reuse existing columns first:
status,expires_at, file metadata, fingerprints, source links, and generated timestamps. - Add current-table fields only when required for behavior, such as
held_at,held_by_user_id,hold_reason,archived_at,deleted_at,deleted_by_user_id, or deletion-request fields. - Hold/delete metadata requires per-family
SUPPORTED_NOWclassification before migration.DEFERREDorPRODUCT_DECISION_REQUIREDmeans no partial column, action, retention branch, or controller behavior is added for that family in Spec 406. - Do not add a generic artifact table by default.
- If migrations are needed, make them reversible where possible and document PostgreSQL/staging risk.
- Add indexes only for proven query paths such as retention scans or held-state lookup.
- Do not create compatibility shims unless the spec is updated with an explicit exception.
Retention / File Consistency Plan
- Review
PruneReviewPacksCommand,PruneStoredReportsCommand,tenantpilot.review_pack.*,tenantpilot.stored_reports.*, andfilesystems.exports. - File/database consistency must be proven before any ready/downloadable state is shown.
- Retention cleanup must skip held artifacts only for families with hold support classified
SUPPORTED_NOW; deferred families must preserve current behavior and record explicit follow-up/no-runtime-mutation rationale. - Missing/zero-byte/corrupt/wrong-disk files must fail closed.
- Delete/archive/expire behavior must define whether files are removed, blocked, or retained.
- Signed URLs must re-check current artifact state and file availability at request time.
OperationRun / Observability Plan
- Artifact lifecycle state must not replace
OperationRun.statusorOperationRun.outcome. - Existing review-pack/PDF generation OperationRun paths remain shared.
- Long-running export/delete/purge-class work should reuse the existing OperationRun start/completion UX. If that work exceeds this slice, split it.
- Direct local lifecycle mutations may stay audit-only when they are bounded DB/file operations and not queued/cross-resource.
- Final report must classify which lifecycle actions created OperationRuns and which produced audit-only proof.
Test Governance Check
- Test purpose / classification by changed surface: Feature and Filament/Livewire action tests for behavior; browser for rendered action/status proof; PostgreSQL lane when migrations/indexes are added.
- Affected validation lanes: fast-feedback, confidence, browser, pgsql conditional.
- Why this lane mix is sufficient: lifecycle correctness is behavioral and authorization-sensitive, and rendered/browser proof is needed only for representative product-surface and action-state behavior.
- Narrowest proving commands:
cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec406- targeted existing suites for ReviewPack, StoredReport/management PDF, Evidence, CustomerReviewWorkspace, Findings, and OperationRun.
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser --filter=Spec406 --compactif a focused browser test is added.cd apps/platform && ./vendor/bin/sail pint --dirtygit diff --check
- Fixture/helper cost risks: moderate; use existing factories and focused fixtures, not a broad artifact matrix harness unless implementation report justifies it.
- Heavy-family additions: no heavy-governance family planned.
- Browser proof: required and focused.
- Budget/baseline impact: record any material browser or retention-job runtime in implementation report.
- Escalation path:
document-in-featurefor bounded family-local exceptions;follow-up-specfor purge/export-before-delete/portal;reject-or-splitfor broad registry/framework scope.
Implementation Phases
Phase 1 - Inventory and lifecycle matrix
Inventory each artifact family, existing states, file dependencies, customer-safe boundaries, policy/capability checks, actions, retention config, commands/jobs, audit proof, tests, and browser coverage. Populate the implementation-report matrix before code edits.
Phase 2 - Tests for current gaps
Add failing tests for confirmed gaps: SUPPORTED_NOW held delete block where applicable, unauthorized direct action, cross-workspace access, missing-file download, failed-to-released prevention, expired/current distinction, customer-safe export boundary, and retention job idempotency.
Phase 3 - Bounded runtime hardening
Implement only the smallest confirmed changes on existing artifact owners, services, commands, controllers, and Filament actions. Use current-table metadata where necessary. Stop if a change requires a portal, registry, purge engine, or export center.
Phase 4 - UI/browser proof and product sanity
Run focused browser proof on representative artifact surfaces. Complete Human Product Sanity and record visible complexity outcome.
Phase 5 - Final gate and handoff
Run focused validation, complete implementation-report sections, classify remaining findings, and recommend PASS, PASS WITH CONDITIONS, or FAIL.
Stop Conditions
- A new generic artifact registry table appears necessary.
- Irreversible purge or export-before-delete workflow is required for correctness.
- A new route/navigation/panel/customer portal is needed.
- Legal/compliance claims are required to define behavior.
- Lifecycle behavior depends on rewriting completed specs.
- Staging/production data compatibility requires shims not approved by this spec.
- Spec 404/405 carry-forward conditions are needed for a Spec 406 readiness claim and cannot be proven or ruled not applicable.
Rollout Considerations
- Migrations must be staged and reversible where possible.
- Scheduler/command changes need staging validation before production.
- Storage changes must account for private
exportspersistence and Dokploy volumes. - Queue/OperationRun changes require worker deployment notes.
- Config/env additions must be documented in
.env.exampleor deployment docs only if implementation adds them. - Production promotion requires staging validation of lifecycle actions, downloads, retention job behavior, and browser proof.
Deferred Follow-ups
- Retention & Purge Governance v1.
- Data Export Before Deletion v1.
- Workspace & Tenant Closure Lifecycle v1.
- External/customer artifact portal.
- Full Browser/UX Runtime Audit after Spec 406 gate.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| BLOAT-001 - lifecycle/action semantics across several artifact families | Existing artifacts are already customer/audit proof and unsafe lifecycle behavior can delete, expose, or overstate retained proof | Family-local one-off labels and tests cannot prove cross-artifact hold/export/delete/file consistency; a generic artifact registry is wider than current-release truth |
Project Structure
specs/406-governance-artifact-lifecycle-retention/
├── checklists/
│ └── requirements.md
├── spec.md
├── plan.md
└── tasks.md
Implementation may add:
specs/406-governance-artifact-lifecycle-retention/implementation-report.md
apps/platform/database/migrations/
apps/platform/app/... existing artifact owner/service/controller/resource paths
apps/platform/tests/... focused Spec406 and existing family tests
Why This Plan Is Narrow Enough
The repo already has the artifact families, generated-file metadata, signed downloads, retention commands, customer-output gates, evidence/currentness semantics, OperationRun proof, and audit model. Spec 406 uses those seams to prove lifecycle behavior instead of introducing a new product surface or lifecycle platform. Broader purge/export/closure/customer-portal work remains explicitly deferred.