6.3 KiB
6.3 KiB
Research: Governance Artifact Lifecycle & Retention v1
Branch: 267-artifact-lifecycle-retention
Date: 2026-05-03
Decision 1 - Extend the current governance-artifact truth path
- Decision: Extend
ArtifactTruthPresenterand its existing derived-state path instead of creating a second lifecycle presenter or a generic artifact registry. - Rationale: The repo already uses
ArtifactTruthPresenterforEvidenceSnapshot,TenantReview, andReviewPack, and the visible Filament surfaces already depend on that path for outcome summary and compressed outcome rendering. The missing gap is support for immutable reference plus retention semantics, and support forStoredReportand decision-record families. - Alternatives considered:
- Page-local lifecycle labels on each resource: rejected because evidence, review, review-pack, customer-workspace, and decision surfaces would drift immediately.
- Generic artifact super-table or registry UI: rejected because it would import persistence, migration, and browsing scope beyond current release truth.
Decision 2 - Keep the first visible adoption on current surfaces only
- Decision: Limit operator-facing adoption to
EvidenceSnapshotResource,TenantReviewResource,ViewTenantReview,ReviewPackResource,CustomerReviewWorkspace, andReviewPackDownloadController, while keeping stored-report and accepted-risk decision-history adoption headless. - Rationale: Those surfaces already answer artifact availability and next-step questions today. Stored reports still have no dedicated operator surface, and current Spec 265 surfaces already own accepted-risk browsing and detail workflows, so this slice should not rewrite
DecisionRegisterorViewFindingException. - Alternatives considered:
- New artifact-management console: rejected because the user explicitly wants the slice to stay on current evidence, review, review-pack, and download surfaces.
- New stored-report or decision-record resource: rejected because that would hide product-surface work inside a lifecycle contract feature.
Decision 3 - Keep persistence family-local and derived-first
- Decision: Reuse current-table lifecycle and retention anchors per family, and only add family-local hold or deletion-request persistence if v1 can keep that work on the current owning record without widening scope.
- Rationale: Evidence snapshots and review packs already have
expires_at; stored reports already havecreated_at,fingerprint,previous_fingerprint, and an age-based prune command; finding exceptions and decisions already have append-only history plus current aggregate state. A shared contract can be derived from those facts without a new table, and the package should stop at read-only lifecycle truth plus existing download audit if mutation persistence needs shared orchestration. - Alternatives considered:
- Central polymorphic lifecycle table: rejected because current repo truth does not justify a second persistence layer.
- Purely presentational contract with no family-local persistence option: rejected as too weak if v1 needs auditable hold or deletion-request mutations on current detail surfaces.
Decision 4 - Preserve the current suspended-read-only split
- Decision: Keep the repo's current distinction between blocked future generation and preserved retained-history access.
- Rationale:
ReviewPackServicealready blocks new review-pack starts throughWorkspaceCommercialLifecycleResolver, whileReviewPackDownloadControllerandReviewPackDownloadTestprove that ready-pack downloads remain available when the workspace is suspended read-only. That split is the current release truth and should not be collapsed into retention state. - Alternatives considered:
- Treat suspended read-only as retention expiry: rejected because it would contradict Spec 251 and current download behavior.
- Hide retained history whenever generation blocks: rejected because it would misstate existing artifact availability.
Decision 5 - Keep default proof in unit and feature lanes only
- Decision: Plan default proof in
Unitand focusedFeaturesuites, with browser validation only as an exception. - Rationale: The repo already has current feature coverage for evidence, review packs, customer review workspace, tenant review detail, finding-exception workflows, and stored-report pruning. Those suites are the narrowest sufficient proof for this slice.
- Alternatives considered:
- Add browser smoke by default: rejected because the user asked to keep browser-heavy proof out of the default plan, and the current surfaces already have strong native test seams.
Decision 6 - Keep the prep package minimal
- Decision: Create
research.md,data-model.md, andquickstart.md, but omit acontracts/directory and skip the agent-context update step. - Rationale: This slice reuses existing Filament resources, the existing signed
admin.review-packs.downloadroute, and the existing Laravel stack. A separate OpenAPI or route-contract artifact would duplicate repo truth. The task is also explicitly restricted tospecs/267-artifact-lifecycle-retention/, so agent-context files outside the spec directory stay untouched. - Alternatives considered:
- Add a contracts package anyway: rejected because there is no new API surface or route contract.
- Run
.specify/scripts/bash/update-agent-context.sh copilot: rejected for this prep run because it would modify files outside the allowed folder without introducing any new technology.
Cross-Spec Alignment
- Spec 158 remains the truth-semantics anchor for existing evidence, review, and review-pack outcome surfaces. This slice extends that shared truth path instead of contradicting it.
- Spec 251 remains the commercial lifecycle anchor for suspended read-only behavior. This slice reuses its existing allow or block split and does not turn commercial posture into retention truth.
- Spec 262 remains the taxonomy authority for keeping lifecycle, retention, commercial state, provider presence, and restoreability separate. This slice consumes that taxonomy and does not reopen it.
- Spec 265 remains the decision-register surface spec. This slice extends shared artifact semantics into accepted-risk decision history at the aggregate seam only and does not introduce or rewrite a decision console.