chore: save workspace changes — automated commit
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m49s

This commit is contained in:
Ahmed Darrazi 2026-05-02 01:02:04 +02:00
parent 25e1f69513
commit f2a92f88d5
11 changed files with 1349 additions and 7 deletions

View File

@ -51,18 +51,20 @@ ## Active Candidate Queue
These packages already provide the needed preparation surface, and several now carry completed task checklists or implementation close-out history. They must not be auto-selected again by `next-best-prep`.
`Workspace, Tenant & Managed Object Lifecycle Governance v1` remains deferred below and still requires an explicit product decision before it becomes a safe prep target.
The historical record for `Workspace, Tenant & Managed Object Lifecycle Governance v1` remains below because it was promoted intentionally, not automatically, into Spec 262 and must not re-enter the active auto-prep queue.
## Deferred / Existing Drafts Outside the Current Queue
These items are still useful, but they are not the next best open specs from the current repo state.
**2026-05-01 explicit promotion note**: `Workspace, Tenant & Managed Object Lifecycle Governance v1` was promoted intentionally, not automatically, into Spec 262 (`lifecycle-governance-taxonomy`). The history below is retained so the manual-promotion rationale and the auto-prep boundary remain visible.
### Workspace, Tenant & Managed Object Lifecycle Governance v1
- **Priority**: P2 — Important hardening / enterprise trust
- **Status**: Strategic candidate, not ready for immediate implementation
- **Status**: Promoted intentionally via explicit product decision -> Spec 262 (`lifecycle-governance-taxonomy`)
- **Do not auto-prep from `next-best-prep`**: this candidate stays intentionally outside the active queue even after the 2026-05-01 repo re-audit. Promote it only through an explicit roadmap/product decision.
- **Why it stays deferred after the queue cleanup**: the repo now has spec-backed follow-through for customer review productization, governance convergence, compare/preflight, commercial lifecycle maturity, compliance mapping, governance packaging, support-desk handoff, and the findings cleanup trio. The remaining lifecycle-governance question is still broader than the current automatic queue and must stay taxonomy-first rather than opportunistically selected.
- **Why the retained history still sits outside the active queue**: the repo now has spec-backed follow-through for customer review productization, governance convergence, compare/preflight, commercial lifecycle maturity, compliance mapping, governance packaging, support-desk handoff, and the findings cleanup trio. This lifecycle-governance work was promoted intentionally as a taxonomy-first package and must remain outside the automatic queue rather than being treated as an opportunistic next-best-prep target.
- **Why this replaces `Policy Lifecycle / Ghost Policies`**: A policy-only ghost lifecycle spec risks introducing local deletion semantics, Laravel `SoftDeletes`, or overloaded `ignored_at` behavior before TenantPilot has a clear platform lifecycle taxonomy. The real roadmap-fit problem is broader: TenantPilot needs consistent lifecycle truth for workspaces, tenants, managed provider objects, evidence, backups, restoreability, export, retention, and purge.
- **Problem**: Lifecycle concerns currently appear across separate product areas such as policies, restore flows, commercial state, workspace entitlements, backup history, evidence snapshots, audit, support, and workspace administration. Without one shared taxonomy, local fixes can collapse different meanings into the same field or UI label: provider object missing, local TenantPilot record deleted, operator ignored the item, workspace suspended, data retained for compliance, data eligible for purge, or restore no longer possible.
- **Product goal**: Define an enterprise-grade lifecycle model before implementing destructive or retention-sensitive workflows. TenantPilot must distinguish at least these dimensions:
@ -105,7 +107,7 @@ ### Workspace, Tenant & Managed Object Lifecycle Governance v1
4. `Retention & Purge Governance v1` — retention periods, legal hold, purge eligibility, irreversible deletion confirmation, and audit trail.
5. `Restoreability Expiry & Evidence Retention v1` — distinguish restorable backup payloads from retained evidence/audit metadata and define when restore is no longer possible but evidence remains retained.
- **Roadmap fit**: This is not a P0 sales feature. It is a P2 enterprise trust and compliance hardening candidate that becomes important before serious production customer offboarding, destructive data operations, or regulated retention commitments. It must not block Customer Review Workspace Productization, Governance Decision Surface Convergence, or Cross-Tenant Compare & Promotion.
- **Candidate decision**: Keep as strategic candidate. Do not let near-term policy fixes expand into a general ghost-policy, deletion, or retention model before the lifecycle taxonomy is agreed. The bounded policy-only exception is now Spec 261 (`provider-missing-policy-visibility`); keep that spec isolated to provider-missing truth and restore continuity rather than treating it as partial completion of this broader taxonomy.
- **Candidate decision**: Explicitly promoted as Spec 262 (`lifecycle-governance-taxonomy`) through a manual product decision. Keep the promotion taxonomy-first and keep near-term policy fixes, closure flows, export-before-delete, retention/purge, and restoreability expiry as separate follow-up slices rather than treating Spec 262 as a runtime umbrella implementation.
- `Workspace-level PII override for review packs`: bounded deferred follow-up from Spec 109.
- `CSV export for filtered run metadata`: valid system-console follow-up, but not near the top of the queue.
@ -139,6 +141,7 @@ ## Promoted to Spec
- Compliance Evidence Mapping v1 -> Spec 259 (`compliance-evidence-mapping`)
- Governance-as-a-Service Packaging v1 -> Spec 260 (`governance-service-packaging`)
- Provider-Missing Policy Visibility & Restore Continuity v1 -> Spec 261 (`provider-missing-policy-visibility`)
- Workspace, Tenant & Managed Object Lifecycle Governance v1 -> Spec 262 (`lifecycle-governance-taxonomy`)
- Queued Execution Reauthorization and Scope Continuity -> Spec 149 (`queued-execution-reauthorization`)
- Livewire Context Locking and Trusted-State Reduction -> Spec 152 (`livewire-context-locking`)
- Evidence Domain Foundation -> Spec 153 (`evidence-domain-foundation`)

View File

@ -1,10 +1,10 @@
# Product Standards
> Canonical, living standards that govern all new and modified Filament UI surfaces.
> Canonical, living standards that govern new and modified product surfaces, lifecycle semantics, and shared review contracts.
> Specs reference these standards; they do not redefine them.
> Guard tests enforce critical constraints automatically.
> Guard tests enforce critical UI constraints automatically where a standard has runtime enforcement.
**Last reviewed**: 2026-04-27
**Last reviewed**: 2026-05-01
---
@ -15,6 +15,7 @@ ## Standards Index
| Table UX | [filament-table-ux.md](filament-table-ux.md) | Column tiers, sort, search, toggle, pagination, persistence, empty states, timestamps, IDs |
| Filter UX | [filament-filter-ux.md](filament-filter-ux.md) | Filter patterns, persistence, soft-delete, date range, enum sourcing, defaults |
| Actions UX | [filament-actions-ux.md](filament-actions-ux.md) | Row/bulk/header actions, grouping, destructive safety, inspect affordance |
| Lifecycle Governance | [lifecycle-governance.md](lifecycle-governance.md) | Lifecycle taxonomy, source ownership, transition safeguards, follow-up boundaries |
| Review Checklist | [list-surface-review-checklist.md](list-surface-review-checklist.md) | PR/spec checklist for any new or modified list surface |
---
@ -25,6 +26,7 @@ ## How Standards Are Enforced
2. **Standards** (this directory) — Concrete rules for how every surface must behave.
3. **Guard tests** — Automated Pest tests that fail CI when critical standards are violated.
4. **PR review** — The [review checklist](list-surface-review-checklist.md) is checked for every spec or PR that touches a list surface.
5. **Lifecycle review** — The [lifecycle governance standard](lifecycle-governance.md) is checked for every spec or PR that introduces archive, delete, provider-missing, suppression, retention, purge, commercial lifecycle, or restoreability semantics.
---

View File

@ -0,0 +1,133 @@
# Lifecycle Governance Standard
> Canonical taxonomy for lifecycle-sensitive TenantPilot work.
> This standard governs naming, source ownership, transition safeguards, and follow-up boundaries before runtime lifecycle flows are implemented.
**Last reviewed**: 2026-05-01
---
## Governing Principle
**Lifecycle meanings stay orthogonal.**
Do not reuse one lifecycle field, label, badge, or status as a proxy for another lifecycle dimension.
The machine-readable source for Spec 262 is `specs/262-lifecycle-governance-taxonomy/contracts/lifecycle-governance-taxonomy.yaml`; this document is the reviewer-facing standard that future lifecycle specs must cite.
This v1 standard introduces no application behavior, migration, lifecycle service, provider rollout, panel surface, or purge/delete/export runtime flow.
---
## Canonical Dimensions
Every lifecycle concern must map to exactly one primary dimension.
| Dimension | Answers | Current repo-real authorities | Current repo-real values | Reserved follow-up values | Must not proxy |
|---|---|---|---|---|---|
| Local record lifecycle | Is a TenantPilot-owned record active, onboarding, archived, removed, or purged locally? | `specs/143-tenant-lifecycle-operability-context-semantics/spec.md`, `specs/091-backupschedule-retention-lifecycle/spec.md`, `apps/platform/app/Models/Tenant.php` | `tenant.draft`, `tenant.onboarding`, `tenant.active`, `tenant.archived`, `backup_schedule.active`, `backup_schedule.archived`, `backup_schedule.force_deleted` | `locally_removed`, `local_purge_scheduled`, `locally_purged` | Provider presence, commercial state, retention expiry |
| Provider presence lifecycle | Is a managed object observed in the supported provider-backed result set? | `specs/261-provider-missing-policy-visibility/spec.md`, `apps/platform/app/Models/Policy.php` | `present`, `provider_missing` | `provider_deleted`, `provider_reappeared` | Local deletion, local suppression, restoreability |
| Operator suppression lifecycle | Did an operator intentionally hide or restore local visibility? | `specs/261-provider-missing-policy-visibility/spec.md`, `apps/platform/app/Models/Policy.php` | `visible`, `ignored`, `restored_to_visibility` | `scoped_suppression_reason_families` | Provider missing, retention, commercial state |
| Commercial/workspace lifecycle | What commercial posture controls workspace expansion and read-only behavior? | `specs/251-commercial-entitlements-billing-state/spec.md` | `trial`, `active_paid`, `grace`, `suspended_read_only` | `closed` | Tenant archive, provider missing, purge due |
| Retention/compliance lifecycle | What must be retained, exported, held, deleted, or purged? | `apps/platform/app/Models/ReviewPack.php`, `apps/platform/app/Console/Commands/PruneReviewPacksCommand.php`, `apps/platform/config/tenantpilot.php` | `review_pack.expired`, `configured_retention_days` | `retained`, `export_requested`, `deletion_requested`, `deletion_scheduled`, `legal_hold`, `purge_due`, `purged` | Workspace suspension, local archive, provider missing |
| Restoreability lifecycle | Is historical backup or evidence truth still restorable? | `specs/261-provider-missing-policy-visibility/spec.md`, `apps/platform/app/Models/BackupSet.php`, `apps/platform/app/Models/RestoreRun.php` | `historical_restore_continuity_available` | `metadata_only`, `blocked_by_dependency`, `not_restorable`, `expired_by_retention` | Provider presence, commercial state, local suppression |
Rules:
- Use current repo-real values only when the repo already owns that meaning.
- Use reserved follow-up values only to name later specs; do not render, persist, or enforce them in this slice.
- If a concern seems to belong to multiple dimensions, choose the dimension that owns the operator consequence and document the secondary relationship as context only.
---
## Mandatory Meaning Answers
### Deleted
`Deleted` is not a shared lifecycle state.
Local removal, provider hard deletion, retention purge, and reduced restoreability are separate lifecycle meanings.
- Local deletion belongs to local record lifecycle and requires an explicit runtime follow-up before it can exist beyond current archive/force-delete patterns.
- Provider hard deletion belongs to provider presence lifecycle and remains provider-owned evidence.
- Purge belongs to retention/compliance lifecycle.
- Not restorable belongs to restoreability lifecycle.
### Missing From Provider
`Provider missing` means the managed object is not observed in the supported provider-backed result set.
It does not mean the local record was deleted, ignored, purged, or no longer historically restorable.
### Ignored
`Ignored` means intentional local operator suppression.
It does not mean the provider object disappeared, the workspace is suspended, or the record is retention-expired.
### Workspace Suspension Or Closure
`Suspended read-only` is commercial/workspace lifecycle.
It does not delete tenants, purge data, expire evidence, or eliminate restoreability.
`Closed` is reserved for `Workspace & Tenant Closure Lifecycle v1`; this standard only names the boundary.
### Export Before Deletion
`export_requested` is a reserved retention/compliance lifecycle value.
The actual export workflow, export contents, customer ownership, and completion proof belong to `Data Export Before Deletion v1`.
### Retained Versus Purgeable
Retained, legal hold, purge due, and purged are retention/compliance lifecycle meanings.
They must not be inferred from workspace suspension, local archive, provider missing, or restoreability status.
### Restore Eligibility
Restoreability is about whether historical backup or evidence truth remains restorable.
It remains distinct from current provider presence: a live provider object can be missing while a historical backup remains restorable, and a present provider object does not prove historical restoreability.
---
## Transition Governance
Future runtime specs must use this matrix before implementing a lifecycle transition.
| Dimension | Example transition | Transition owner | Execution path | Confirmation | Audit evidence | OperationRun | Export / retention preconditions |
|---|---|---|---|---|---|---|---|
| Local record lifecycle | Archive a local record or force-delete a backup schedule | TenantPilot local domain owner | Direct local mutation for bounded DB-only archive; shared `OperationRun` when long-running, cross-resource, or externally mediated | Always | Required | Sometimes | Required before irreversible deletion |
| Provider presence lifecycle | Mark provider missing or reappeared | Provider observation / sync process | Observation-derived update; no operator confirmation | Never | Required | Never unless part of broader reconciliation run | Not required |
| Operator suppression lifecycle | Ignore or restore local visibility | TenantPilot local domain owner | Direct local mutation | Always | Required | Never | Not required |
| Commercial/workspace lifecycle | Suspend read-only or close workspace | Platform workspace/commercial owner | Direct local mutation for bounded state change; shared `OperationRun` for closure-class or multi-artifact flows | Always | Required | Sometimes | Required for closure-class flows |
| Retention/compliance lifecycle | Mark export requested, deletion requested, hold, purge due, or purge | Compliance/retention owner | Shared `OperationRun` for purge-class automation and any long-running/export-coupled flow | Always | Required | Always for purge-class automation | Required |
| Restoreability lifecycle | Mark metadata-only or expired by retention | Backup/restore/evidence owner | Derived status when passive; shared `OperationRun` or guarded mutation when an operator reduces restoreability | Sometimes | Required | Sometimes | Required when retention or irreversible reduction is involved |
Audit-only is insufficient when the transition is destructive, long-running, externally mediated, cross-resource, export-coupled, purge-class, or materially reduces restoreability.
Those slices must reuse the shared OperationRun start and completion UX path instead of composing local queued toast, link, event, or terminal-notification behavior.
---
## Follow-Up Boundaries
Spec 262 deliberately does not implement these runtime slices:
| Follow-up slice | Boundary |
|---|---|
| `Provider-Missing Managed Object Truth v1` | Broader provider-presence rollout beyond policy records |
| `Workspace & Tenant Closure Lifecycle v1` | Workspace or tenant close/remove behavior, including closure-specific UX and authorization |
| `Data Export Before Deletion v1` | Customer-owned export workflow that fulfills `export_requested` before irreversible deletion |
| `Retention & Purge Governance v1` | Retention periods, holds, purge eligibility, irreversible deletion, and purge proof |
| `Restoreability Expiry & Evidence Retention v1` | Distinction between retained evidence and restorable payloads |
If a future spec needs one of these behaviors, it must cite this standard and implement the dedicated follow-up slice instead of expanding Spec 262 retroactively.
---
## Review Checklist
Lifecycle-bearing specs and PRs must answer these questions:
1. Which one lifecycle dimension owns the changed meaning?
2. What current repo-real source owns that meaning today?
3. Is the value current repo-real or reserved follow-up?
4. Which dimensions are explicitly forbidden as proxies?
5. Does the transition require confirmation, audit evidence, shared `OperationRun` execution, export-before-delete, or retention review?
6. Does lifecycle state remain separate from RBAC, workspace entitlement, tenant entitlement, and deny-as-not-found behavior?
7. Does provider-specific evidence stay at a provider-owned seam instead of becoming platform-core truth?
8. Is any adjacent lifecycle runtime work split into a named follow-up slice?
A change fails review if it uses lifecycle language as an authorization substitute, collapses provider absence into local deletion, treats suppression as provider truth, infers retention from commercial state, or claims restoreability from current provider presence alone.

View File

@ -0,0 +1,44 @@
# Preparation Review Checklist: Workspace, Tenant & Managed Object Lifecycle Governance v1
**Purpose**: Verify that the lifecycle-governance package stays repo-grounded, taxonomy-first, and non-runtime.
**Created**: 2026-05-01
**Review outcome class**: Core Enterprise
**Workflow outcome**: approve for implementation on the standards-and-contract path only
**Test-governance outcome**: keep
## Candidate Selection
- [x] CHK001 The package records that this candidate was promoted only by explicit product decision and not by automatic next-best-prep selection.
- [x] CHK002 Already-prepared slices such as Specs 143, 251, 261, and 091 are treated as dependencies or boundaries, not reopened implementation scope.
- [x] CHK003 The selected slice matches the deferred candidate's documented smallest useful v1: taxonomy, naming, transition rules, retention boundaries, and follow-up guardrails only.
## Scope And Truth
- [x] CHK004 The package defines exactly six lifecycle dimensions and maps each to current repo-real sources.
- [x] CHK005 The package explicitly distinguishes current repo-real values from reserved follow-up values.
- [x] CHK006 The package answers the deferred candidate's mandatory meaning questions without adding runtime behavior.
- [x] CHK007 The package forbids proxy use across lifecycle dimensions.
## Safety And Governance
- [x] CHK008 The transition-governance matrix makes confirmation, audit, OperationRun, and export/retention prerequisites explicit.
- [x] CHK009 Provider-specific semantics remain provider-owned, while shared lifecycle labels stay platform-neutral.
- [x] CHK010 No runtime deletion, purge, panel, provider, asset, or lifecycle-engine work appears in the package.
## Test Governance
- [x] CHK011 The package records explicit validation commands and a test-governance outcome even though it is docs-only.
- [x] CHK012 The package leaves no hidden runtime proving requirement or browser/heavy-governance lane expansion.
## Readiness Outcome
- [x] CHK013 Every adjacent concern from the deferred candidate is listed as a named follow-up slice rather than hidden scope.
- [x] CHK014 The standards directory is named as the intended implementation landing zone.
- [x] CHK015 The package is ready for a later implementation loop only if implementation remains on the standards and contract path.
## Implementation Close-Out Outcome
- [x] CHK016 The standards document now exists at `docs/product/standards/lifecycle-governance.md`.
- [x] CHK017 The standards index references the lifecycle-governance standard.
- [x] CHK018 The contract, data model, quickstart, and standard remain aligned on six dimensions, transition ownership, execution path, and follow-up boundaries.
- [x] CHK019 The implementation introduced no runtime behavior, product persistence, Filament surface, provider behavior, asset, queue, or browser-visible flow.

View File

@ -0,0 +1,179 @@
version: 1
feature: workspace-tenant-managed-object-lifecycle-governance-v1
status: implemented_on_standards_and_contract_path_only
standards_document: docs/product/standards/lifecycle-governance.md
dimensions:
- name: local_record_lifecycle
purpose: classify whether a local TenantPilot record is active, onboarding, archived, removed, or purged
authoritative_sources:
- specs/143-tenant-lifecycle-operability-context-semantics/spec.md
- specs/091-backupschedule-retention-lifecycle/spec.md
- apps/platform/app/Models/Tenant.php
current_repo_real_values:
- tenant.draft
- tenant.onboarding
- tenant.active
- tenant.archived
- backup_schedule.active
- backup_schedule.archived
- backup_schedule.force_deleted
reserved_follow_up_values:
- locally_removed
- local_purge_scheduled
- locally_purged
forbidden_proxies:
- provider_presence
- commercial_state
- retention_expiry
- name: provider_presence_lifecycle
purpose: classify whether a managed object is currently observed in a supported provider-backed result set
authoritative_sources:
- specs/261-provider-missing-policy-visibility/spec.md
- apps/platform/app/Models/Policy.php
current_repo_real_values:
- present
- provider_missing
reserved_follow_up_values:
- provider_deleted
- provider_reappeared
forbidden_proxies:
- local_delete
- local_suppression
- restoreability
- name: operator_suppression_lifecycle
purpose: classify whether an operator intentionally hid or restored a local record
authoritative_sources:
- specs/261-provider-missing-policy-visibility/spec.md
- apps/platform/app/Models/Policy.php
current_repo_real_values:
- visible
- ignored
- restored_to_visibility
reserved_follow_up_values:
- scoped_suppression_reason_families
forbidden_proxies:
- provider_missing
- retention
- commercial_state
- name: commercial_workspace_lifecycle
purpose: classify workspace commercial posture independently from tenant or artifact lifecycle
authoritative_sources:
- specs/251-commercial-entitlements-billing-state/spec.md
current_repo_real_values:
- trial
- active_paid
- grace
- suspended_read_only
reserved_follow_up_values:
- closed
forbidden_proxies:
- tenant_archive
- provider_missing
- purge_due
- name: retention_compliance_lifecycle
purpose: classify retention, export-request, expiry, hold, deletion-request, and purge eligibility semantics
authoritative_sources:
- apps/platform/app/Models/ReviewPack.php
- apps/platform/app/Console/Commands/PruneReviewPacksCommand.php
- apps/platform/config/tenantpilot.php
current_repo_real_values:
- review_pack.expired
- configured_retention_days
reserved_follow_up_values:
- retained
- export_requested
- deletion_requested
- deletion_scheduled
- legal_hold
- purge_due
- purged
forbidden_proxies:
- workspace_suspension
- local_archive
- provider_missing
- name: restoreability_lifecycle
purpose: classify whether historical backup or evidence truth remains restorable
authoritative_sources:
- specs/261-provider-missing-policy-visibility/spec.md
- apps/platform/app/Models/BackupSet.php
- apps/platform/app/Models/RestoreRun.php
current_repo_real_values:
- historical_restore_continuity_available
reserved_follow_up_values:
- metadata_only
- blocked_by_dependency
- not_restorable
- expired_by_retention
forbidden_proxies:
- provider_presence
- commercial_state
- local_suppression
transition_governance:
- dimension: local_record_lifecycle
transition: archive_or_force_delete
transition_owner: tenantpilot_local_domain_owner
execution_path: direct_local_mutation_or_shared_operation_run_when_long_running_cross_resource_or_externally_mediated
requires_confirmation: always
requires_audit: true
requires_operation_run: sometimes
requires_export_precondition: true
requires_retention_review: true
- dimension: provider_presence_lifecycle
transition: provider_missing_or_reappeared
transition_owner: provider_observation_sync_process
execution_path: observation_derived_update
requires_confirmation: never
requires_audit: true
requires_operation_run: never
requires_export_precondition: false
requires_retention_review: false
- dimension: operator_suppression_lifecycle
transition: suppress_or_restore_visibility
transition_owner: tenantpilot_local_domain_owner
execution_path: direct_local_mutation
requires_confirmation: always
requires_audit: true
requires_operation_run: never
requires_export_precondition: false
requires_retention_review: false
- dimension: commercial_workspace_lifecycle
transition: suspend_or_close_workspace
transition_owner: platform_workspace_commercial_owner
execution_path: direct_local_mutation_or_shared_operation_run_for_closure_class_or_multi_artifact_flows
requires_confirmation: always
requires_audit: true
requires_operation_run: sometimes
requires_export_precondition: true
requires_retention_review: true
- dimension: retention_compliance_lifecycle
transition: mark_export_request_delete_request_hold_or_purge
transition_owner: compliance_retention_owner
execution_path: shared_operation_run_for_purge_class_automation_and_long_running_export_coupled_flows
requires_confirmation: always
requires_audit: true
requires_operation_run: always
requires_export_precondition: true
requires_retention_review: true
- dimension: restoreability_lifecycle
transition: expire_or_reduce_restoreability
transition_owner: backup_restore_evidence_owner
execution_path: derived_status_when_passive_or_guarded_mutation_or_shared_operation_run_when_operator_reduces_restoreability
requires_confirmation: sometimes
requires_audit: true
requires_operation_run: sometimes
requires_export_precondition: true
requires_retention_review: true
follow_up_slices:
- Provider-Missing Managed Object Truth v1
- Workspace & Tenant Closure Lifecycle v1
- Data Export Before Deletion v1
- Retention & Purge Governance v1
- Restoreability Expiry & Evidence Retention v1

View File

@ -0,0 +1,178 @@
# Data Model: Workspace, Tenant & Managed Object Lifecycle Governance v1
## Overview
This slice introduces no product persistence. Its data model is a governance contract that classifies existing repo-real lifecycle truth and names reserved follow-up values without implementing them.
`contracts/lifecycle-governance-taxonomy.yaml` is the canonical machine-readable source for this package. `docs/product/standards/lifecycle-governance.md` is the reviewer-facing standard that future specs must cite. This document explains the same lifecycle matrix in prose and must stay aligned with both artifacts.
## Entity: LifecycleDimensionDefinition
**Persistence**: none; governance contract only
| Field | Type | Meaning |
|---|---|---|
| `name` | string | One of the six lifecycle dimensions |
| `purpose` | string | What question this dimension answers |
| `authoritative_sources` | list | Repo-real models, commands, config, or specs that currently own the meaning |
| `current_repo_real_values` | list | Values or states already evidenced in the repo |
| `reserved_follow_up_values` | list | Values named for future work but not yet repo-real |
| `forbidden_proxies` | list | Meanings this dimension must not borrow from another dimension |
## Canonical Lifecycle Dimensions
### 1. Local Record Lifecycle
- **Purpose**: whether a local TenantPilot record is active, onboarding, archived, or otherwise locally present/removed.
- **Authoritative sources**:
- `specs/143-tenant-lifecycle-operability-context-semantics/spec.md`
- `specs/091-backupschedule-retention-lifecycle/spec.md`
- `apps/platform/app/Models/Tenant.php`
- **Current repo-real values**:
- `tenant.draft`
- `tenant.onboarding`
- `tenant.active`
- `tenant.archived`
- `backup_schedule.active`
- `backup_schedule.archived`
- `backup_schedule.force_deleted`
- **Reserved follow-up values**:
- `locally_removed`
- `local_purge_scheduled`
- `locally_purged`
- **Forbidden proxies**:
- `provider_presence`
- `commercial_state`
- `retention_expiry`
### 2. Provider Presence Lifecycle
- **Purpose**: whether a managed object is currently observed in the supported provider-backed result set.
- **Authoritative sources**:
- `specs/261-provider-missing-policy-visibility/spec.md`
- `apps/platform/app/Models/Policy.php`
- **Current repo-real values**:
- `present`
- `provider_missing`
- **Reserved follow-up values**:
- `provider_deleted`
- `provider_reappeared`
- **Forbidden proxies**:
- `local_delete`
- `local_suppression`
- `restoreability`
### 3. Operator Suppression Lifecycle
- **Purpose**: whether an operator intentionally hid or restored visibility for a local record.
- **Authoritative sources**:
- `specs/261-provider-missing-policy-visibility/spec.md`
- `apps/platform/app/Models/Policy.php`
- **Current repo-real values**:
- `visible`
- `ignored`
- `restored_to_visibility`
- **Reserved follow-up values**:
- `scoped_suppression_reason_families`
- **Forbidden proxies**:
- `provider_missing`
- `retention`
- `commercial_state`
### 4. Commercial / Workspace Lifecycle
- **Purpose**: whether a workspace is in trial, active paid use, grace, or suspended read-only posture.
- **Authoritative sources**:
- `specs/251-commercial-entitlements-billing-state/spec.md`
- **Current repo-real values**:
- `trial`
- `active_paid`
- `grace`
- `suspended_read_only`
- **Reserved follow-up values**:
- `closed`
- **Forbidden proxies**:
- `tenant_archive`
- `provider_missing`
- `purge_due`
### 5. Retention / Compliance Lifecycle
- **Purpose**: whether an artifact must be retained, has export requested, is expiring, or is eligible for later purge.
- **Authoritative sources**:
- `apps/platform/app/Models/ReviewPack.php`
- `apps/platform/app/Console/Commands/PruneReviewPacksCommand.php`
- `apps/platform/config/tenantpilot.php`
- **Current repo-real values**:
- `review_pack.expired`
- `configured_retention_days`
- **Reserved follow-up values**:
- `retained`
- `export_requested`
- `deletion_requested`
- `deletion_scheduled`
- `legal_hold`
- `purge_due`
- `purged`
- **Forbidden proxies**:
- `workspace_suspension`
- `local_archive`
- `provider_missing`
### 6. Restoreability Lifecycle
- **Purpose**: whether historical evidence or backup truth is still restorable and what kind of continuity remains.
- **Authoritative sources**:
- `specs/261-provider-missing-policy-visibility/spec.md`
- `apps/platform/app/Models/BackupSet.php`
- `apps/platform/app/Models/RestoreRun.php`
- **Current repo-real values**:
- `historical_restore_continuity_available`
- **Reserved follow-up values**:
- `metadata_only`
- `blocked_by_dependency`
- `not_restorable`
- `expired_by_retention`
- **Forbidden proxies**:
- `provider_presence`
- `commercial_state`
- `local_suppression`
## Entity: TransitionGovernanceRule
**Persistence**: none; governance contract only
| Field | Type | Meaning |
|---|---|---|
| `dimension` | string | Which lifecycle dimension owns the transition |
| `transition` | string | Human-readable transition |
| `transition_owner` | string | Repo authority or future owner class that owns the transition decision |
| `execution_path` | string | Whether the transition stays direct/local, observation-derived, derived/passive, or must use shared `OperationRun` semantics |
| `requires_confirmation` | enum | `never`, `sometimes`, or `always` depending on whether the transition is passive, conditional, or irreversible |
| `requires_audit` | boolean | Whether audit evidence is mandatory |
| `requires_operation_run` | enum | `never`, `sometimes`, or `always` based on transition class |
| `requires_export_precondition` | boolean | Whether export-before-delete or similar preconditions must be satisfied |
| `requires_retention_review` | boolean | Whether retention rules must be resolved first |
## Transition Guidance (v1)
| Dimension | Example transition | Transition owner | Execution path | Confirmation | Audit | OperationRun | Export / Retention Preconditions |
|---|---|---|---|---|---|---|---|
| Local record lifecycle | archive a locally managed record or force-delete a backup schedule | TenantPilot local domain owner | direct local mutation, or shared `OperationRun` when long-running, cross-resource, or externally mediated | always | yes | sometimes; always if long-running or cross-resource | yes before irreversible deletion |
| Provider presence | object becomes provider missing or reappears | provider observation / sync process | observation-derived update | never | yes | no, unless wrapped in a broader long-running reconciliation flow | no |
| Operator suppression | ignore / restore local visibility | TenantPilot local domain owner | direct local mutation | always | yes | no | no |
| Commercial/workspace lifecycle | enter suspended read-only or close workspace | platform workspace/commercial owner | direct local mutation for bounded state changes, or shared `OperationRun` for closure-class / multi-artifact flows | always | yes | sometimes; closure-class flows are likely `always` | yes |
| Retention/compliance lifecycle | mark export requested, delete requested, hold, purge due, or purge | compliance / retention owner | shared `OperationRun` for purge-class automation and long-running/export-coupled flows | always | yes | always for purge-class automation | yes |
| Restoreability lifecycle | mark metadata-only or expired-by-retention | backup / restore / evidence owner | derived status when passive; guarded mutation or shared `OperationRun` when an operator reduces restoreability | sometimes; never for passive derived status, always for irreversible operator action | yes | sometimes | yes |
## Entity: FollowUpSliceBoundary
**Persistence**: none; governance contract only
| Follow-up slice | Why it stays separate |
|---|---|
| Provider-Missing Managed Object Truth v1 | broader provider-presence rollout beyond policies |
| Workspace & Tenant Closure Lifecycle v1 | workspace or tenant close/remove behavior |
| Data Export Before Deletion v1 | customer-owned export workflow that fulfills the reserved `export requested` lifecycle value before irreversible deletion |
| Retention & Purge Governance v1 | retention periods, holds, purge eligibility, irreversible deletion |
| Restoreability Expiry & Evidence Retention v1 | distinction between retained evidence and restorable payload |

View File

@ -0,0 +1,243 @@
# Implementation Plan: Workspace, Tenant & Managed Object Lifecycle Governance v1
**Branch**: `262-lifecycle-governance-taxonomy` | **Date**: 2026-05-01 | **Spec**: [spec.md](spec.md)
**Input**: Feature specification from [spec.md](spec.md)
## Summary
Prepare one taxonomy-first lifecycle governance package that converts the deferred lifecycle candidate into an implementation-ready standards and contract slice without reopening runtime deletion, purge, or provider-specific rollout work. The narrow implementation path is to codify six lifecycle dimensions, their authoritative repo sources, transition-governance rules, export/retention/restoreability preconditions, and explicit follow-up boundaries in one new product standard plus one machine-readable contract artifact.
Repo truth already provides the inputs this slice needs: tenant lifecycle and canonical-view semantics in `specs/143-tenant-lifecycle-operability-context-semantics`, workspace commercial lifecycle in `specs/251-commercial-entitlements-billing-state`, provider-missing policy truth in `specs/261-provider-missing-policy-visibility`, reversible archive / irreversible force-delete in `specs/091-backupschedule-retention-lifecycle`, and current runtime lifecycle evidence in `apps/platform/app/Models/Tenant.php`, `apps/platform/app/Models/Policy.php`, `apps/platform/app/Models/ReviewPack.php`, `apps/platform/app/Models/BackupSet.php`, `apps/platform/app/Models/RestoreRun.php`, `apps/platform/app/Console/Commands/PruneReviewPacksCommand.php`, and `apps/platform/config/tenantpilot.php`.
V1 therefore stays deliberately non-runtime: no new app behavior, no migration, no new lifecycle service, no delete or purge flow, no panel/provider work, and no asset changes. It is a standards-track contract that later runtime specs must cite.
## Technical Context
**Language/Version**: Markdown and YAML governance artifacts inside a PHP 8.4 / Laravel 12 repo
**Primary Dependencies**: existing specs 143, 251, 261, 091; product standards workflow in `docs/product/standards/README.md`; current lifecycle-bearing runtime models and commands as source truth only
**Storage**: none for product runtime; one standards document and one machine-readable contract artifact
**Testing**: manual artifact review plus targeted repo-search validation
**Validation Lanes**: N/A (docs/standards-only package)
**Target Platform**: repo standards and spec artifacts only
**Project Type**: Laravel monorepo with documentation and standards track
**Performance Goals**: N/A
**Constraints**: no runtime behavior change, no new persistence, no reinterpretation of current lifecycle fields, no new panel/provider/assets, and no hidden follow-up implementation
**Scale/Scope**: 1 new standards-track lifecycle contract, 6 lifecycle dimensions, 1 transition-governance matrix, 5 named follow-up slices, and bounded updates to candidate history
## Likely Affected Repo Surfaces
- `docs/product/standards/README.md` as the existing landing zone for shared standards.
- `docs/product/standards/lifecycle-governance.md` as the intended new standard for later implementation.
- `docs/product/spec-candidates.md` to record explicit promotion history for the deferred candidate.
- `specs/143-tenant-lifecycle-operability-context-semantics/spec.md` as the current tenant lifecycle authority.
- `specs/251-commercial-entitlements-billing-state/spec.md` as the current workspace commercial lifecycle authority.
- `specs/261-provider-missing-policy-visibility/spec.md` as the current provider-presence authority.
- `specs/091-backupschedule-retention-lifecycle/spec.md` as the current reversible archive / irreversible force-delete pattern authority.
- `apps/platform/app/Models/Tenant.php`, `apps/platform/app/Models/Policy.php`, `apps/platform/app/Models/ReviewPack.php`, `apps/platform/app/Models/BackupSet.php`, `apps/platform/app/Models/RestoreRun.php`, `apps/platform/app/Console/Commands/PruneReviewPacksCommand.php`, and `apps/platform/config/tenantpilot.php` as repo-real lifecycle inputs that the contract classifies but does not change.
## Lifecycle Taxonomy Fit
- Treat lifecycle governance as a standards contract, not as a runtime engine or umbrella service.
- Keep the six lifecycle dimensions orthogonal:
- local record lifecycle
- provider presence lifecycle
- operator suppression lifecycle
- commercial/workspace lifecycle
- retention/compliance lifecycle
- restoreability lifecycle
- For each dimension, distinguish:
- current repo-real values and sources
- reserved follow-up values that are named for future work but not yet repo-real
- forbidden proxy meanings that later specs may not reuse locally
- Explicitly classify where current repo truth already exists versus where the taxonomy is defining a prerequisite for later runtime work.
- Treat `contracts/lifecycle-governance-taxonomy.yaml` as the canonical machine-readable lifecycle matrix for this package; supporting prose artifacts must mirror it.
- Classify `export requested` as a reserved retention/compliance value while keeping `Data Export Before Deletion v1` as the dedicated runtime follow-up that fulfills that state before irreversible deletion.
## Transition Governance Fit
- Build one transition matrix that answers, per lifecycle dimension:
- who owns the transition
- whether confirmation is required
- whether audit evidence is required
- whether shared `OperationRun` execution semantics are required
- whether an `export requested` state or other export-before-delete / retention preconditions must be satisfied first
- Reuse current repo truth instead of inventing new action families:
- direct audit-backed local mutation already proven by Spec 091
- provider observation transitions already bounded by Spec 261
- commercial-workspace gating already bounded by Spec 251
- canonical-view legitimacy already bounded by Spec 143
- Do not let the matrix imply runtime behavior beyond those current boundaries.
## UI / Surface Guardrail Plan
- **Guardrail scope**: workflow-only guardrail change
- **Native vs custom classification summary**: N/A
- **Shared-family relevance**: status vocabulary, destructive-action naming, audit wording, retention wording, restoreability claims
- **State layers in scope**: none
- **Audience modes in scope**: N/A
- **Decision/diagnostic/raw hierarchy plan**: N/A
- **Raw/support gating plan**: N/A
- **One-primary-action / duplicate-truth control**: the package states lifecycle meaning once per dimension and forbids duplicate cross-dimension summaries
- **Handling modes by drift class or surface**: review-mandatory
- **Repository-signal treatment**: review-mandatory because this package sets a new cross-domain taxonomy
- **Special surface test profiles**: N/A
- **Required tests or manual smoke**: manual artifact review only
- **Exception path and spread control**: none; any runtime scope added here is out-of-scope drift
- **Active feature PR close-out entry**: Guardrail
## Shared Pattern & System Fit
- **Cross-cutting feature marker**: yes
- **Systems touched**: lifecycle-bearing specs, product standards workflow, audit naming, and future destructive or retention-sensitive follow-up specs
- **Shared abstractions reused**: current specs, current standards workflow, `BadgeCatalog` / `BadgeRenderer`, `AuditLog`, and the shared OperationRun UX contract as referenced authorities only
- **New abstraction introduced? why?**: one governance contract only; no new runtime abstraction
- **Why the existing abstraction was sufficient or insufficient**: the repo already has enough bounded lifecycle slices, but not enough shared classification to stop future overlap
- **Bounded deviation / spread control**: none planned
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: yes, as a rule-setting artifact only
- **Central contract reused**: shared OperationRun UX contract remains authoritative
- **Delegated UX behaviors**: later lifecycle slices must delegate any queued, long-running, or remote destructive flow to the shared OperationRun path; this package does not add a new run type
- **Surface-owned behavior kept local**: later runtime surfaces remain responsible for their own initiation UI once the taxonomy tells them which safeguard path applies
- **Queued DB-notification policy**: unchanged
- **Terminal notification path**: unchanged
- **Exception path**: none
## Provider Boundary & Portability Fit
- **Shared provider/platform boundary touched?**: yes
- **Provider-owned seams**: provider proof of object presence, subtype filtering, and hard-deletion evidence
- **Platform-core seams**: archive versus delete semantics, suppression, retention, restoreability, commercial suspension, and audit/export preconditions
- **Neutral platform terms / contracts preserved**: `provider missing`, `archived`, `retained`, `purge due`, `restorable`, `metadata only`, `suspended read-only`
- **Retained provider-specific semantics and why**: provider-specific hard deletion remains reserved because the repo does not yet have a generalized proof path for it
- **Bounded extraction or follow-up path**: `follow-up-spec` for explicit provider-deleted semantics and broader managed-object rollout
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- Inventory-first / snapshot truth: PASS. The package classifies current inventory, backup, and historical restore truths without redefining them.
- Read/write separation: PASS. No write path is introduced.
- Graph contract path: PASS. No new Graph family or provider behavior is introduced.
- Deterministic capabilities: PASS. No capability or role changes are introduced.
- Workspace and tenant isolation: PASS. Existing isolation rules remain referenced, not changed.
- RBAC-UX: PASS. Lifecycle state remains explicitly separate from authorization.
- Destructive confirmation standard: PASS. The package defines when later destructive work must require confirmation instead of implementing it now.
- Global search safety: PASS. No resource or search behavior changes are proposed.
- OperationRun / Ops-UX: PASS. The package only states when future lifecycle work must reuse the shared contract.
- Data minimization: PASS. No new runtime data or payload exposure is introduced.
- Test governance (TEST-GOV-001): PASS. The package leaves explicit validation and workflow outcomes despite being docs-only.
- Proportionality / no premature abstraction: PASS. One contract is the narrowest way to answer the deferred candidate questions.
- Persisted truth (PERSIST-001): PASS. No new product persistence.
- Behavioral state (STATE-001): PASS. The package classifies current and reserved states without implementing new runtime state machines.
- Provider boundary (PROV-001): PASS. Shared language stays provider-neutral.
- Filament / Laravel planning contract: PASS. Filament remains v5 on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, no globally searchable resource behavior changes, and no asset work is planned.
**Gate evaluation**: PASS.
- The package remains valid only if implementation stays on the standards and contract path.
- The gate fails if runtime deletion, purge, panel, provider, or lifecycle-engine work appears in this slice.
**Post-design re-check**: PASS. `research.md`, `data-model.md`, `quickstart.md`, `contracts/lifecycle-governance-taxonomy.yaml`, and `checklists/requirements.md` are present and aligned with the package.
## Test Governance Check
- **Test purpose / classification by changed surface**: N/A - docs/standards package
- **Affected validation lanes**: N/A
- **Why this lane mix is the narrowest sufficient proof**: runtime proof is unnecessary because the slice changes no runtime behavior
- **Narrowest proving command(s)**:
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n -- "Workspace, Tenant & Managed Object Lifecycle Governance v1|Provider-Missing Managed Object Truth v1|Workspace & Tenant Closure Lifecycle v1|Data Export Before Deletion v1|Retention & Purge Governance v1|Restoreability Expiry & Evidence Retention v1" docs/product/spec-candidates.md specs/262-lifecycle-governance-taxonomy`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n -- "draft|onboarding|active|archived|ignored_at|missing_from_provider_at|suspended|expired|retention" apps/platform/app/Models/Tenant.php apps/platform/app/Models/Policy.php apps/platform/app/Models/ReviewPack.php apps/platform/app/Models/BackupSet.php apps/platform/app/Models/RestoreRun.php apps/platform/app/Console/Commands/PruneReviewPacksCommand.php apps/platform/config/tenantpilot.php specs/143-tenant-lifecycle-operability-context-semantics/spec.md specs/251-commercial-entitlements-billing-state/spec.md specs/261-provider-missing-policy-visibility/spec.md specs/091-backupschedule-retention-lifecycle/spec.md`
- **Fixture / helper / factory / seed / context cost risks**: none
- **Expensive defaults or shared helper growth introduced?**: no
- **Heavy-family additions, promotions, or visibility changes**: none
- **Surface-class relief / special coverage rule**: N/A
- **Closing validation and reviewer handoff**: reviewers must confirm the dimensions, authoritative sources, transition matrix, and follow-up boundaries stay aligned and non-runtime
- **Budget / baseline / trend follow-up**: none
- **Review-stop questions**: hidden runtime scope, future-state speculation, contradictory lifecycle meanings, missing transition safeguards, or missing follow-up boundaries
- **Escalation path**: `reject-or-split` if runtime work appears; `follow-up-spec` if a new lifecycle family is discovered later
- **Active feature PR close-out entry**: Guardrail
- **Why no dedicated follow-up spec is needed**: this package itself is the dedicated governance follow-up for lifecycle taxonomy; later runtime work remains separate
## Rollout & Risk Controls
- Keep the contract standards-first and implementation-light.
- Keep all reserved future values clearly marked as follow-up only.
- Keep runtime authorities with their existing specs and models.
- Keep promotion history explicit so the repo does not treat this candidate as still merely deferred.
- Keep lifecycle vocabulary neutral and avoid provider-shaped truth at shared boundaries.
## Close-Out Outcome
- **Review outcome**: Core Enterprise
- **Workflow outcome**: approve for implementation on the standards-and-contract path only
- **Test-governance outcome**: keep docs-only validation; no runtime lane expansion is required in this package
## Implementation Close-Out Outcome
- **Review outcome**: Core Enterprise
- **Workflow outcome**: implemented on the standards-and-contract path only
- **Test-governance outcome**: keep docs-only validation; no runtime lane expansion was introduced
- **Runtime impact**: none; no application code, migration, Filament surface, provider behavior, asset, queue, or browser-visible flow was changed
## Project Structure
### Documentation (this feature)
```text
specs/262-lifecycle-governance-taxonomy/
├── checklists/
│ └── requirements.md
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ └── lifecycle-governance-taxonomy.yaml
└── tasks.md
```
### Source Code And Standards Truth (repository root)
```text
docs/product/
├── spec-candidates.md
└── standards/
├── README.md
└── lifecycle-governance.md # planned by this feature
apps/platform/
├── app/
│ ├── Console/Commands/PruneReviewPacksCommand.php
│ └── Models/
│ ├── AuditLog.php
│ ├── BackupSet.php
│ ├── Policy.php
│ ├── RestoreRun.php
│ ├── ReviewPack.php
│ └── Tenant.php
└── config/
└── tenantpilot.php
specs/
├── 091-backupschedule-retention-lifecycle/
├── 143-tenant-lifecycle-operability-context-semantics/
├── 251-commercial-entitlements-billing-state/
└── 261-provider-missing-policy-visibility/
```
## Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| Cross-domain lifecycle taxonomy | The deferred candidate explicitly requires one shared answer before destructive or retention-sensitive runtime work continues | Local per-feature fixes would preserve the ambiguity the candidate is trying to remove |
## Proportionality Review
- **Current operator problem**: future lifecycle work can still mislead operators by overloading fields or labels across tenant, workspace, provider presence, retention, and restoreability contexts
- **Existing structure is insufficient because**: current bounded specs each solve their local runtime problem but do not classify how their lifecycle meanings differ
- **Narrowest correct implementation**: add one standards document and one machine-readable contract that later runtime slices must cite
- **Ownership cost**: one shared vocabulary and one review step for lifecycle-bearing follow-up specs
- **Alternative intentionally rejected**: a runtime lifecycle framework or immediate archive/delete/closure implementation was rejected as broader than the deferred candidate allows
- **Release truth**: current-release truth only; the package classifies repo-real lifecycle signals and names reserved follow-up values without pretending that later runtime deletion, export, purge, or closure flows already exist

View File

@ -0,0 +1,69 @@
# Quickstart: Workspace, Tenant & Managed Object Lifecycle Governance v1
## Preconditions
1. No application runtime needs to be started for this slice.
2. Keep validation repo-based and artifact-based. No Sail test lane or browser smoke is required because this package changes no runtime behavior.
## Scenario 1: Verify the six lifecycle dimensions
1. Open `specs/262-lifecycle-governance-taxonomy/contracts/lifecycle-governance-taxonomy.yaml`.
2. Open `docs/product/standards/lifecycle-governance.md`.
3. Verify the contract and standard list exactly these dimensions:
- local record lifecycle
- provider presence lifecycle
- operator suppression lifecycle
- commercial/workspace lifecycle
- retention/compliance lifecycle
- restoreability lifecycle
4. Confirm each dimension names current repo-real sources and reserved follow-up values separately.
## Scenario 2: Verify the deferred candidate questions are answered
1. Review `specs/262-lifecycle-governance-taxonomy/spec.md`, `specs/262-lifecycle-governance-taxonomy/data-model.md`, and `docs/product/standards/lifecycle-governance.md`.
2. Confirm the package gives explicit answers for:
- what `deleted` means
- what `missing from provider` means
- what `ignored` means
- what workspace suspension or closure means in relation to retention and restoreability
- whether `export requested` is named as a reserved retention/compliance value while the actual export workflow remains a follow-up slice
- that concrete artifact-level export contents are intentionally deferred to `Data Export Before Deletion v1`
- what data remains retained versus purgeable
## Scenario 3: Verify current repo truth maps cleanly into the taxonomy
1. Use the repo search commands below.
2. Confirm that tenant lifecycle, commercial lifecycle, provider presence, retention expiry, and restore continuity all map into one dimension each.
3. Confirm the package does not claim runtime meanings that the repo does not yet implement.
## Scenario 4: Verify follow-up boundaries remain explicit
1. Review the follow-up slice list in `spec.md`, `data-model.md`, `contracts/lifecycle-governance-taxonomy.yaml`, and `docs/product/standards/lifecycle-governance.md`.
2. Confirm the package repeats these exact follow-up slice names:
- `Provider-Missing Managed Object Truth v1`
- `Workspace & Tenant Closure Lifecycle v1`
- `Data Export Before Deletion v1`
- `Retention & Purge Governance v1`
- `Restoreability Expiry & Evidence Retention v1`
3. Confirm that `export requested` is treated as a reserved retention/compliance value and that those follow-up slices stay separate rather than hidden in the primary scope.
## Focused Validation Commands
```bash
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n -- "Workspace, Tenant & Managed Object Lifecycle Governance v1|Provider-Missing Managed Object Truth v1|Workspace & Tenant Closure Lifecycle v1|Data Export Before Deletion v1|Retention & Purge Governance v1|Restoreability Expiry & Evidence Retention v1" docs/product/spec-candidates.md specs/262-lifecycle-governance-taxonomy
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n -- "local record lifecycle|provider presence lifecycle|operator suppression lifecycle|commercial/workspace lifecycle|retention/compliance lifecycle|restoreability lifecycle|export_requested|OperationRun" docs/product/standards/lifecycle-governance.md specs/262-lifecycle-governance-taxonomy/contracts/lifecycle-governance-taxonomy.yaml specs/262-lifecycle-governance-taxonomy/data-model.md
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n -- "draft|onboarding|active|archived|ignored_at|missing_from_provider_at|suspended|expired|retention" apps/platform/app/Models/Tenant.php apps/platform/app/Models/Policy.php apps/platform/app/Models/ReviewPack.php apps/platform/app/Models/BackupSet.php apps/platform/app/Models/RestoreRun.php apps/platform/app/Console/Commands/PruneReviewPacksCommand.php apps/platform/config/tenantpilot.php specs/143-tenant-lifecycle-operability-context-semantics/spec.md specs/251-commercial-entitlements-billing-state/spec.md specs/261-provider-missing-policy-visibility/spec.md specs/091-backupschedule-retention-lifecycle/spec.md
```
## Finish
1. Re-run the preparation checklist in `specs/262-lifecycle-governance-taxonomy/checklists/requirements.md`.
2. Confirm the package still introduces no runtime behavior, no new product persistence, and no hidden follow-up implementation.
## Close-Out Outcome
- Review outcome: `Core Enterprise`
- Workflow outcome: `implemented` on the standards-and-contract path only
- Test-governance outcome: `keep` docs-only validation with no runtime lane expansion

View File

@ -0,0 +1,44 @@
# Research: Workspace, Tenant & Managed Object Lifecycle Governance v1
## Decision 1: Implement the deferred candidate as a standards contract, not a runtime engine
- **Decision**: Keep this v1 on the standards-and-contract path only.
- **Rationale**: The deferred candidate explicitly says the smallest useful v1 is to define taxonomy, naming rules, state boundaries, audit expectations, OperationRun expectations, retention boundaries, and implementation guardrails before destructive runtime work proceeds.
- **Why this is enough**: The repo already has several lifecycle-bearing runtime slices. What is missing is the contract that tells future slices how those meanings fit together.
- **Alternatives considered**:
- immediate tenant archive/delete implementation: rejected because the deferred candidate explicitly excludes it
- broad lifecycle service or registry: rejected as premature abstraction
## Decision 2: Reuse existing bounded specs as authorities per lifecycle dimension
- **Decision**: Treat Specs 143, 251, 261, and 091 plus current retention/expiry surfaces as the authoritative current repo inputs.
- **Rationale**: These specs already codify the runtime meanings that the taxonomy must classify. Reopening them here would duplicate scope.
- **Alternatives considered**:
- define lifecycle dimensions from roadmap prose alone: rejected because the candidate requires repo truth
- infer lifecycle meanings directly from models without the spec layer: rejected because some meanings already live in spec packages, not only runtime code
## Decision 3: Keep the lifecycle dimensions orthogonal
- **Decision**: Define exactly six lifecycle dimensions for v1: local record lifecycle, provider presence lifecycle, operator suppression lifecycle, commercial/workspace lifecycle, retention/compliance lifecycle, and restoreability lifecycle.
- **Rationale**: These are the minimum dimensions needed to answer the deferred candidate's mandatory questions without collapsing meanings.
- **Alternatives considered**:
- a single generic lifecycle axis: rejected because it would recreate the current ambiguity
- more than six dimensions: rejected as broader than current repo truth requires
## Decision 4: Distinguish current repo-real values from reserved follow-up values
- **Decision**: The taxonomy will name reserved future values where the deferred candidate requires them, but it will mark them as follow-up-only when the repo does not yet model them.
- **Applied distinction**: `export requested` is named as a reserved retention/compliance value in v1, while the workflow that satisfies that request remains part of `Data Export Before Deletion v1`.
- **Rationale**: This keeps the package useful for planning without pretending the runtime already owns meanings it does not.
- **Alternatives considered**:
- model every listed candidate value as repo-real now: rejected as false product truth
- omit reserved values entirely: rejected because the deferred candidate explicitly asks for future lifecycle boundaries
## Decision 5: Use one transition-governance matrix to answer safety and observability questions
- **Decision**: Define one matrix describing confirmation, audit, OperationRun, and export/retention preconditions per lifecycle dimension.
- **Applied distinction**: The matrix records when irreversible transitions depend on export or retention preconditions, but it does not invent the export workflow itself.
- **Rationale**: The candidate's core risk is unsafe destructive or retention-sensitive follow-up work. One matrix is the narrowest cross-domain answer.
- **Alternatives considered**:
- leave safeguard choices to each future spec independently: rejected because that is the current failure mode
- define runtime handlers now: rejected because this v1 is non-runtime

View File

@ -0,0 +1,295 @@
# Feature Specification: Workspace, Tenant & Managed Object Lifecycle Governance v1
**Feature Branch**: `262-lifecycle-governance-taxonomy`
**Created**: 2026-05-01
**Status**: Approved for implementation on the standards-and-contract path only
**Input**: User description: "Promote the deferred lifecycle-governance candidate explicitly and prepare a tightly scoped, taxonomy-first spec package without implementing deletion, purge, or provider-specific runtime behavior."
## Spec Candidate Check *(mandatory — SPEC-GATE-001)*
- **Problem**: TenantPilot already carries real lifecycle semantics across tenants, workspace commercial posture, provider-missing policy truth, backup schedule archive/force-delete, review-pack expiry, restore continuity, and audit history, but those meanings are still scattered and can be locally overloaded.
- **Today's failure**: A future feature can still confuse `archived`, `deleted`, `ignored`, `missing from provider`, `expired`, `suspended read-only`, `retained`, or `restorable` because there is no single lifecycle taxonomy saying which dimension owns which meaning, which source is authoritative, and which transition rules apply.
- **User-visible improvement**: Future destructive, retention-sensitive, and recovery-sensitive features can land with one truthful lifecycle vocabulary, one transition-governance matrix, and one explicit follow-up map instead of reusing the wrong field or label locally.
- **Smallest enterprise-capable version**: Define a taxonomy-first lifecycle governance contract that classifies the existing repo-real lifecycle dimensions, names their authoritative sources, answers the deferred candidate's mandatory questions, and sets follow-up boundaries for runtime work without opening any deletion or purge implementation.
- **Explicit non-goals**: No workspace deletion flow, no tenant deletion flow, no purge engine, no retention executor, no review-pack or evidence rewrite, no `SoftDeletes` rollout, no reinterpretation of `ignored_at`, no provider-missing rollout beyond Spec 261, no commercial-lifecycle runtime work beyond Spec 251, no lifecycle dashboard, no new panel, no new asset strategy, and no application-code mutation in this v1 contract slice.
- **Permanent complexity imported**: One shared lifecycle taxonomy, one transition-governance matrix, one standards-track reference target, one bounded follow-up map, and explicit review/test-governance expectations for future specs. No new product persistence, runtime engine, or UI framework is introduced.
- **Why now**: The active queue was intentionally emptied for automatic next-best-prep, but this candidate was preserved for explicit promotion once the repo had enough concrete lifecycle examples to justify a taxonomy-first package. Specs 143, 251, 261, and 091 now provide exactly that evidence.
- **Why not local**: The deferred candidate's mandatory questions span workspace state, tenant state, provider presence, suppression, retention, and restoreability. A page-local or model-local fix would reopen the same ambiguity instead of bounding it.
- **Approval class**: Core Enterprise
- **Red flags triggered**: New cross-domain taxonomy, broad lifecycle language, and lower immediate end-user visibility than a normal workflow slice. Defense: the package stays contract-only, reuses existing repo-real slices as its only inputs, introduces no runtime engine or new persistence, and exists specifically to stop future destructive work from overloading the wrong meanings.
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexität: 1 | Produktnähe: 1 | Wiederverwendung: 2 | **Gesamt: 10/12**
- **Decision**: approve
## Spec Scope Fields *(mandatory)*
- **Scope**: workspace + tenant + canonical-view
- **Primary Routes**:
- no new runtime route is introduced in this slice
- the taxonomy governs existing route families that later lifecycle follow-ups may touch, including `/admin/tenants`, `/admin/onboarding/{onboardingDraft}`, `/admin/t/{tenant}/policies`, `/admin/reviews/workspace`, `/admin/t/{tenant}/backup-sets`, `/admin/t/{tenant}/restore-runs`, and `/system/directory/workspaces/{workspace}`
- **Data Ownership**:
- no new product persistence is introduced
- the contract classifies existing workspace-owned and tenant-owned truth only: `Tenant`, workspace commercial state from Spec 251, provider-backed managed-object presence from Spec 261, review or report retention signals, and backup and restore continuity truth
- audit evidence and `OperationRun` responsibilities remain transition-governance guardrails, not separate lifecycle source inventories
- the lifecycle taxonomy itself is a standards and governance artifact, not a new product table or domain record
- **RBAC**:
- no new capability or role family is introduced
- the taxonomy preserves existing isolation rules from the contributing specs: non-member or out-of-scope access remains deny-as-not-found, capability denials remain `403` after scope is established, and future lifecycle follow-ups must not use lifecycle state as an authorization substitute
For canonical-view specs, the spec MUST define:
- **Default filter behavior when tenant-context is active**: This slice introduces no new collection surface. It preserves Spec 143's rule that remembered tenant context is convenience only and must not determine canonical record legitimacy.
- **Explicit entitlement checks preventing cross-tenant leakage**: This slice introduces no new viewer surface. It defines that lifecycle meaning on a canonical workspace record remains subordinate to workspace ownership plus referenced-tenant entitlement rather than to remembered tenant state.
## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*
- **Cross-cutting feature?**: yes
- **Interaction class(es)**: status messaging, badge vocabulary, destructive-action naming, confirmation rules, audit action naming, evidence/report availability wording, and restore or export precondition wording
- **Systems touched**: tenant lifecycle semantics from Spec 143, workspace commercial lifecycle from Spec 251, provider-missing policy truth from Spec 261, reversible archive / irreversible force-delete pattern from Spec 091, review-pack expiry and retention cleanup, backup/restore continuity, and the current audit plus OperationRun governance paths
- **Existing pattern(s) to extend**: existing lifecycle-bearing specs, the standards directory in `docs/product/standards/`, the current audit naming path, and the shared OperationRun UX contract
- **Shared contract / presenter / builder / renderer to reuse**: `BadgeCatalog` / `BadgeRenderer`, `AuditLog` + stable action IDs, current lifecycle-bearing specs and runtime models as authoritative sources, and the standards workflow described in `docs/product/standards/README.md`
- **Why the existing shared path is sufficient or insufficient**: The repo already has the concrete runtime truths and shared standards workflow. What is missing is the cross-domain lifecycle matrix that says how those truths relate and where later slices may extend them safely.
- **Allowed deviation and why**: none. Later slices may document bounded exceptions, but this v1 taxonomy must not create a parallel lifecycle language.
- **Consistency impact**: `archived`, `deleted`, `ignored`, `missing from provider`, `expired`, `retained`, `suspended read-only`, and `restorable` must each map to one lifecycle dimension and must not be used as interchangeable operator-facing labels.
- **Review focus**: Reviewers must verify that the package classifies lifecycle concerns by dimension and source instead of silently importing local runtime behavior or future-state assumptions.
## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*
- **Touches OperationRun start/completion/link UX?**: yes, as a governance contract only
- **Shared OperationRun UX contract/layer reused**: existing shared OperationRun start UX and lifecycle rules remain authoritative for any future lifecycle transitions that become queued, long-running, or externally mediated
- **Delegated start/completion UX behaviors**: this package defines when future lifecycle work may remain audit-only and when it must use the existing shared `OperationRun` start UX rather than local queued toast/link/event logic
- **Local surface-owned behavior that remains**: later runtime specs remain responsible for their own initiation surfaces; this slice only defines the guardrail for choosing audit-only versus `OperationRun`-backed execution
- **Queued DB-notification policy**: unchanged; future lifecycle slices must use the shared policy already in force
- **Terminal notification path**: unchanged; any future lifecycle run must flow through the central lifecycle mechanism
- **Exception required?**: none
## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*
- **Shared provider/platform boundary touched?**: yes
- **Boundary classification**: mixed
- **Seams affected**: provider presence versus local lifecycle, suppression, restoreability, and retention vocabulary
- **Neutral platform terms preserved or introduced**: `provider missing`, `local suppression`, `archived`, `retained`, `purge due`, `restorable`, `metadata only`, `not restorable`, `suspended read-only`
- **Provider-specific semantics retained and why**: provider-side subtype filtering and provider proof of hard deletion remain provider-owned evidence. The taxonomy only defines their platform effect.
- **Why this does not deepen provider coupling accidentally**: provider presence is only one lifecycle dimension. It is explicitly separated from local record lifecycle, suppression, retention, and commercial state.
- **Follow-up path**: `follow-up-spec` for explicit provider-deleted semantics or multi-object provider-presence rollout beyond Spec 261
## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*
N/A - no operator-facing surface change. This slice prepares a taxonomy and standards package only and must not smuggle runtime UI work into the lifecycle candidate.
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface change.
## Audience-Aware Disclosure *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface change.
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface change.
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface change.
## Proportionality Review *(mandatory when structural complexity is introduced)*
- **New source of truth?**: yes - one lifecycle governance standard and contract artifact
- **New persisted entity/table/artifact?**: yes - a standards/contract artifact only, not a new product table or persisted domain record
- **New abstraction?**: no new runtime abstraction; one governance contract only
- **New enum/state/reason family?**: yes - one cross-domain lifecycle taxonomy that classifies current repo-real and reserved follow-up meanings
- **New cross-domain UI framework/taxonomy?**: yes - taxonomy only, explicitly not a UI framework
- **Current operator problem**: future destructive or retention-sensitive work can still overuse one local field or status label and make false lifecycle claims across operator surfaces.
- **Existing structure is insufficient because**: the current repo truths are correct only within their local slices. There is no one contract saying how tenant lifecycle, commercial state, provider presence, suppression, retention, and restoreability differ.
- **Narrowest correct implementation**: create one taxonomy-first contract that names the dimensions, authoritative sources, transition rules, and follow-up boundaries, then require later runtime slices to consume it instead of inventing new meanings.
- **Ownership cost**: one new standards document, one lifecycle matrix, bounded review overhead, and later follow-up specs that must cite the taxonomy explicitly.
- **Alternative intentionally rejected**: a broader runtime lifecycle engine or immediate archive/delete/closure implementation was rejected because the deferred candidate explicitly forbids it. A local per-feature fix was rejected because it would preserve ambiguity.
- **Release truth**: current-release truth grounded in already repo-real lifecycle meanings, not speculative multi-provider or post-production future-proofing.
### Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility, migration shims, reinterpretation of existing lifecycle fields, and compatibility-specific tests are out of scope unless a later runtime slice explicitly requires them.
Canonical classification of existing lifecycle meanings is preferred over preserving overloaded semantics.
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
- **Test purpose / classification**: N/A - docs/standards-only governance package
- **Validation lane(s)**: N/A
- **Why this classification and these lanes are sufficient**: this v1 contract introduces no runtime behavior. Readiness is proved by repo-grounded artifact consistency, checklist review, and targeted repo searches.
- **New or expanded test families**: none
- **Fixture / helper cost impact**: none
- **Heavy-family visibility / justification**: none
- **Special surface test profile**: N/A
- **Standard-native relief or required special coverage**: N/A
- **Reviewer handoff**: reviewers must confirm that the six lifecycle dimensions, transition-governance matrix, and follow-up boundaries line up with Specs 143, 251, 261, 091, current retention surfaces, and the deferred candidate questions with no hidden runtime scope.
- **Budget / baseline / trend impact**: none
- **Escalation needed**: none
- **Active feature PR close-out entry**: N/A
- **Planned validation commands**:
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n -- "Workspace, Tenant & Managed Object Lifecycle Governance v1|Provider-Missing Managed Object Truth v1|Workspace & Tenant Closure Lifecycle v1|Data Export Before Deletion v1|Retention & Purge Governance v1|Restoreability Expiry & Evidence Retention v1" docs/product/spec-candidates.md specs/262-lifecycle-governance-taxonomy`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n -- "draft|onboarding|active|archived|ignored_at|missing_from_provider_at|suspended|expired|retention" apps/platform/app/Models/Tenant.php apps/platform/app/Models/Policy.php apps/platform/app/Models/ReviewPack.php apps/platform/app/Models/BackupSet.php apps/platform/app/Models/RestoreRun.php apps/platform/app/Console/Commands/PruneReviewPacksCommand.php apps/platform/config/tenantpilot.php specs/143-tenant-lifecycle-operability-context-semantics/spec.md specs/251-commercial-entitlements-billing-state/spec.md specs/261-provider-missing-policy-visibility/spec.md specs/091-backupschedule-retention-lifecycle/spec.md`
## Scope Boundaries
### In Scope
- one lifecycle taxonomy covering local record lifecycle, provider presence, operator suppression, commercial/workspace lifecycle, retention/compliance lifecycle, and restoreability lifecycle
- one authoritative source map tying each lifecycle dimension to current repo-real models, specs, or runtime surfaces
- one transition-governance matrix covering direct mutation, confirmation requirement, audit requirement, `OperationRun` requirement, and export-before-delete or retention preconditions
- explicit classification that `export requested` belongs to the retention/compliance lifecycle as a reserved follow-up value while `Data Export Before Deletion v1` remains the separate runtime implementation slice
- explicit answers to the deferred candidate's mandatory questions
- explicit follow-up boundaries for runtime implementation slices
- a standards-track landing zone for later implementation in `docs/product/standards/`
### Non-Goals
- runtime archive, restore, delete, close, suspend, purge, or export flows
- new persistence, migrations, or lifecycle columns
- runtime changes to Spec 143, Spec 251, Spec 261, or Spec 091 behavior
- provider-specific rollout beyond the already bounded policy slice in Spec 261
- a new lifecycle dashboard, workboard, or operator console
- a new lifecycle service, registry, or orchestration framework
- changing global search, Filament resources, panels, providers, or assets
## Dependencies
- `docs/product/spec-candidates.md` and `docs/product/roadmap.md` for candidate truth and strategic framing
- `specs/143-tenant-lifecycle-operability-context-semantics/spec.md` for tenant lifecycle and canonical-view semantics
- `specs/251-commercial-entitlements-billing-state/spec.md` for workspace commercial lifecycle
- `specs/261-provider-missing-policy-visibility/spec.md` for provider-presence and restore continuity semantics
- `specs/091-backupschedule-retention-lifecycle/spec.md` for reversible archive / irreversible force-delete pattern
- `apps/platform/app/Models/Tenant.php`, `apps/platform/app/Models/Policy.php`, `apps/platform/app/Models/ReviewPack.php`, `apps/platform/app/Models/BackupSet.php`, `apps/platform/app/Models/RestoreRun.php`, `apps/platform/app/Console/Commands/PruneReviewPacksCommand.php`, and `apps/platform/config/tenantpilot.php` as current runtime truth inputs only
## Assumptions
- the explicit product decision to promote this candidate is the required override for its prior deferred status
- Specs 143, 251, 261, and 091 remain the bounded authoritative sources for their own runtime slices and are not reopened here
- review-pack expiry and configured retention values are current repo-real lifecycle signals even though there is not yet a general retention taxonomy
- later runtime slices will consume a standards document in `docs/product/standards/` rather than inventing a new lifecycle framework
- no application implementation is required to answer the deferred candidate's taxonomy questions in this v1
## Risks
- the taxonomy could drift into future-state wishlisting if it does not distinguish repo-real values from reserved follow-up values clearly
- the package could become too abstract if it names dimensions without tying them back to current specs, models, and commands
- later runtime slices may ignore the contract unless the follow-up map and review checklist are explicit
- terminology such as `deleted`, `expired`, `purged`, and `metadata only` could still be overloaded if the contract does not forbid proxy use across dimensions
## Candidate Selection Rationale
- **Selected candidate**: Workspace, Tenant & Managed Object Lifecycle Governance v1
- **Source locations**:
- `docs/product/spec-candidates.md` deferred candidate section
- `docs/product/roadmap.md` lifecycle-governance section
- `specs/143-tenant-lifecycle-operability-context-semantics/spec.md`
- `specs/251-commercial-entitlements-billing-state/spec.md`
- `specs/261-provider-missing-policy-visibility/spec.md`
- `specs/091-backupschedule-retention-lifecycle/spec.md`
- **Why selected**: The repo explicitly kept this candidate out of auto-prep, not out of product value. The user made the required explicit product decision, and the repo now contains enough concrete lifecycle slices to prepare a taxonomy-first contract without guessing.
- **Why this is the smallest viable implementation slice**: It answers the deferred candidate's mandatory questions through a standards and contract package only. It does not reopen runtime work already assigned to Specs 143, 251, 261, or 091.
- **Intentional narrowing from source candidate**: This v1 defines lifecycle taxonomy, naming rules, transition governance, and follow-up boundaries only. It does not implement workspace closure, tenant deletion, provider-missing rollout beyond policies, export-before-delete flow, retention executor, or purge engine.
- **Why close alternatives are deferred**:
- tenant archive or restore runtime work would violate the candidate's explicit non-goals for this v1 promotion
- further commercial-state runtime work belongs to Spec 251 and should not be duplicated here
- broader provider-presence rollout belongs to a later `Provider-Missing Managed Object Truth v1` follow-up after the taxonomy is accepted
## Follow-up Candidates
- `Provider-Missing Managed Object Truth v1`
- `Workspace & Tenant Closure Lifecycle v1`
- `Data Export Before Deletion v1`
- `Retention & Purge Governance v1`
- `Restoreability Expiry & Evidence Retention v1`
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Classify lifecycle concerns before implementation (Priority: P1)
As a feature author or reviewer, I need one lifecycle taxonomy that tells me whether a concern belongs to local record lifecycle, provider presence, suppression, commercial state, retention, or restoreability so I do not overload existing fields or labels.
**Why this priority**: This is the minimum trust guardrail. If later runtime specs still have to guess where a lifecycle concern belongs, this package has not solved the core problem.
**Independent Test**: Can be fully tested by mapping the current repo-real examples from Specs 143, 251, 261, and 091 plus review-pack expiry or retention signals into the taxonomy and confirming that each one resolves to exactly one primary lifecycle dimension.
**Acceptance Scenarios**:
1. **Given** a future slice touches policy visibility, **When** the reviewer checks the lifecycle taxonomy, **Then** `provider missing` resolves to provider presence and does not reopen local delete semantics.
2. **Given** a future slice touches tenant or workspace archival, **When** the reviewer checks the taxonomy, **Then** the slice finds explicit distinctions between local archive, commercial suspension, retention, and restoreability instead of treating them as one state.
---
### User Story 2 - Choose the right transition safeguards (Priority: P1)
As an implementation reviewer, I need each lifecycle dimension to declare whether a transition is audit-only, confirmation-required, or `OperationRun`-backed so destructive or long-running work follows the correct safety path.
**Why this priority**: The lifecycle candidate exists to prevent unsafe destructive follow-ups from improvising their safeguards.
**Independent Test**: Can be fully tested by checking that the transition-governance matrix gives an explicit rule for archive, force delete, provider-presence observation, workspace suspension, export-before-delete, and restoreability expiry.
**Acceptance Scenarios**:
1. **Given** a future slice proposes irreversible deletion, **When** the reviewer checks the transition matrix, **Then** the contract requires explicit confirmation, audit evidence, and any additional export or retention preconditions before the slice can proceed.
2. **Given** a future slice proposes a long-running closure or purge action, **When** the reviewer checks the transition matrix, **Then** the contract tells the slice to use the shared `OperationRun` path instead of local action-only messaging.
---
### User Story 3 - Keep follow-up slices bounded (Priority: P2)
As a product planner, I need the broader lifecycle-governance candidate split into explicit follow-up slices so later work stays reviewable and does not hide purge, closure, export, provider-missing, and restoreability changes inside one large feature.
**Why this priority**: The candidate was deferred precisely because it was too broad for automatic prep. This v1 must keep it bounded even after promotion.
**Independent Test**: Can be fully tested by confirming that each major adjacent concern from the deferred candidate appears as a named follow-up slice and not as hidden primary-scope work.
**Acceptance Scenarios**:
1. **Given** the lifecycle package is reviewed, **When** the reviewer looks for workspace closure, `export requested`, export-before-delete workflow, retention/purge, and restoreability expiry, **Then** `export requested` is named under retention/compliance and each runtime concern still appears as a named follow-up rather than hidden inside the primary scope.
2. **Given** a future runtime slice wants to broaden scope, **When** it cites this taxonomy, **Then** the follow-up map shows which dedicated slice it belongs to instead of allowing scope creep.
### Edge Cases
- A runtime field such as `ignored_at` already exists and a later slice wants to reuse it for provider absence; the taxonomy must reject that proxy use explicitly.
- A status such as `expired` exists for review-pack retention but not for workspace state; the taxonomy must keep it in retention/compliance rather than promote it into a generic delete state.
- A future slice may require customer export before irreversible deletion; the taxonomy must classify `export requested` under retention/compliance while leaving the actual export workflow to `Data Export Before Deletion v1`.
- A workspace may be suspended/read-only while tenant data remains retained and partially restorable; the taxonomy must keep commercial state, retention, and restoreability distinct.
- A historical backup item may remain restorable when the live managed object is provider-missing; the taxonomy must preserve that separation.
- A future slice may propose audit-only handling for a destructive action; the taxonomy must state when audit-only is insufficient and `OperationRun` or stronger friction is required.
## Requirements *(mandatory)*
**Constitution alignment (required):** This slice introduces no Microsoft Graph calls, no runtime write path, no queue, no new `OperationRun`, and no new product persistence. It prepares a standards and contract package only.
**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** The package may define lifecycle categories and governance rules only because current repo truth already spans multiple lifecycle dimensions and the deferred candidate requires those distinctions before destructive follow-ups proceed. It must stay explicit, bounded, and non-runtime.
**Constitution alignment (XCUT-001):** Lifecycle wording, status semantics, destructive-action naming, retention wording, and restoreability claims are already cross-cutting. This package must attach them to one shared contract path instead of leaving them local.
**Constitution alignment (RBAC-UX):** The package does not change authorization. It must preserve the rule that lifecycle state never replaces scope entitlement or capability checks.
**Constitution alignment (PROV-001):** Provider-specific evidence remains provider-owned. Shared lifecycle labels must stay platform-neutral.
**Constitution alignment (TEST-GOV-001):** Because this is a docs/standards package, runtime test lanes are not required. The package must still leave one explicit validation and workflow outcome.
### Functional Requirements
- **FR-262-001**: The lifecycle governance contract MUST define exactly six lifecycle dimensions for v1: local record lifecycle, provider presence lifecycle, operator suppression lifecycle, commercial/workspace lifecycle, retention/compliance lifecycle, and restoreability lifecycle.
- **FR-262-002**: For each lifecycle dimension, the contract MUST name at least one current repo-real authoritative source and MUST distinguish current repo-real values from reserved follow-up values. When adjacent dimensions need similar delete or purge concepts, the contract MUST use dimension-specific labels so each lifecycle term still has one canonical home.
- **FR-262-003**: The contract MUST answer the deferred candidate's mandatory meaning questions for `deleted`, `missing from provider`, `ignored`, workspace suspension or closure, data export before deletion, retained versus purgeable data, and restore eligibility. For v1, that answer MUST explicitly classify `export requested` as a reserved retention/compliance value while keeping the actual export workflow in the dedicated `Data Export Before Deletion v1` follow-up slice. This taxonomy-first package answers the export-before-delete question at the lifecycle-classification and guardrail level only; artifact-level export contents remain deferred to that follow-up slice.
- **FR-262-004**: The contract MUST forbid treating one lifecycle dimension as a proxy for another, including provider presence versus local deletion, commercial suspension versus retention, and restoreability versus current provider presence.
- **FR-262-005**: The contract MUST define a transition-governance matrix that states, per lifecycle dimension, whether a transition may remain direct local mutation, requires confirmation, requires audit evidence, requires shared `OperationRun` execution semantics, or requires export/retention preconditions.
- **FR-262-006**: The contract MUST classify the current repo-real lifecycle-bearing slices from Spec 143, Spec 251, Spec 261, Spec 091, current review-pack expiry, current retention cleanup, and existing restore-continuity signals without reopening their runtime behavior.
- **FR-262-007**: The contract MUST keep provider-specific semantics bounded to provider-owned seams and MUST use neutral platform terms for shared lifecycle labels.
- **FR-262-008**: The contract MUST define explicit follow-up slice boundaries for provider-missing rollout beyond policies, workspace/tenant closure, export-before-delete, retention/purge, and restoreability expiry.
- **FR-262-009**: This v1 MUST NOT introduce runtime deletion flows, a purge engine, a lifecycle dashboard, a new lifecycle service or registry, a new persisted domain model, or reinterpretation of existing lifecycle fields.
- **FR-262-010**: This v1 MUST use the existing standards workflow in `docs/product/standards/` as the intended implementation landing zone for the lifecycle contract and MUST NOT create a parallel standards mechanism.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: 100% of lifecycle terms used in the prepared package map to one explicit lifecycle dimension and authoritative source with no duplicate meaning.
- **SC-002**: The package answers all mandatory questions listed in the deferred candidate at the taxonomy and guardrail level appropriate to this v1 without requiring runtime implementation to understand the answer boundary.
- **SC-003**: Every major adjacent concern from the deferred candidate is represented as a named follow-up slice instead of hidden in the primary scope.
- **SC-004**: The package introduces zero runtime behavior, zero new product persistence, and zero reopened scope in Specs 143, 251, 261, or 091.

View File

@ -0,0 +1,152 @@
# Tasks: Workspace, Tenant & Managed Object Lifecycle Governance v1
**Input**: Design documents from `/specs/262-lifecycle-governance-taxonomy/`
**Prerequisites**: `plan.md`, `spec.md`, `checklists/requirements.md`, `research.md`, `data-model.md`, `quickstart.md`, `contracts/lifecycle-governance-taxonomy.yaml`
**Tests (TEST-GOV-001)**: N/A - docs/standards-only package. Validation stays repo-based and artifact-based using the search commands already captured in `plan.md` and `quickstart.md`. Do not add browser, heavy-governance, or runtime unit/feature families for this slice.
**Operations**: No new `OperationRun`, queue, scheduled work, or runtime mutation is introduced. This package only defines the governance rule for how future lifecycle work chooses audit-only versus shared `OperationRun` execution paths.
**RBAC**: No new authorization behavior is introduced. The package documents that lifecycle state must never replace scope entitlement or capability checks.
**UI / Surface Guardrails**: No operator-facing runtime surface is changed. This is a workflow-only guardrail package and must not smuggle UI implementation into the lifecycle candidate.
**Organization**: Tasks are grouped by user story so later implementation can remain bounded to standards and governance artifacts only.
## Test Governance Checklist
- [x] Lane assignment stays `N/A` because the slice is docs-only.
- [x] Validation remains artifact and repo-search based; no new runtime tests are added.
- [x] No browser or heavy-governance family is introduced.
- [x] The close-out note records the explicit workflow outcome and test-governance outcome inside the spec package.
## Phase 1: Setup (Repo Truth Inventory)
**Purpose**: Lock the lifecycle source inputs and standards landing zone before drafting the shared contract.
- [x] T001 [P] Verify the current lifecycle-bearing repo sources across `specs/143-tenant-lifecycle-operability-context-semantics/spec.md`, `specs/251-commercial-entitlements-billing-state/spec.md`, `specs/261-provider-missing-policy-visibility/spec.md`, `specs/091-backupschedule-retention-lifecycle/spec.md`, `apps/platform/app/Models/Tenant.php`, `apps/platform/app/Models/Policy.php`, `apps/platform/app/Models/ReviewPack.php`, `apps/platform/app/Models/BackupSet.php`, `apps/platform/app/Models/RestoreRun.php`, `apps/platform/app/Console/Commands/PruneReviewPacksCommand.php`, and `apps/platform/config/tenantpilot.php`
- [x] T002 [P] Verify the standards landing zone and index expectations in `docs/product/standards/README.md`
- [x] T003 [P] Verify the promotion context and follow-up slice names in `docs/product/spec-candidates.md`
**Checkpoint**: The repo-real lifecycle inputs and the standards landing zone are locked before the lifecycle contract is written.
---
## Phase 2: Foundational Contract (Blocking)
**Purpose**: Author the shared lifecycle taxonomy and the machine-readable matrix before any downstream standards or candidate-history updates land.
**CRITICAL**: No downstream standard or candidate-history work should begin until this phase is complete.
- [x] T004 Create `docs/product/standards/lifecycle-governance.md` from the approved taxonomy in `spec.md`, `research.md`, `data-model.md`, and `contracts/lifecycle-governance-taxonomy.yaml`
- [x] T005 Copy the six lifecycle dimensions, authoritative source mapping, current repo-real values, reserved follow-up values, and forbidden proxy meanings from `contracts/lifecycle-governance-taxonomy.yaml` into the standard in `docs/product/standards/lifecycle-governance.md`, keeping the YAML contract as the canonical machine-readable source
- [x] T006 Update `docs/product/standards/README.md` to add the new lifecycle-governance standard to the standards index and explain when future specs must use it
**Checkpoint**: The shared lifecycle standard exists and the standards index points at it.
---
## Phase 3: User Story 1 - Classify lifecycle concerns before implementation (Priority: P1) 🎯 MVP
**Goal**: Give future specs one authoritative map from lifecycle concern to lifecycle dimension.
**Independent Test**: Review the standard and contract artifacts and confirm that each current repo-real lifecycle example maps to exactly one primary lifecycle dimension.
### Validation for User Story 1
- [x] T007 [P] [US1] Run the repo-search validation from `quickstart.md` and confirm that tenant lifecycle, provider presence, commercial lifecycle, retention signals, and restore continuity all map into one dimension each
- [x] T008 [P] [US1] Re-run `checklists/requirements.md` and confirm the package still distinguishes current repo-real values from reserved follow-up values
### Implementation for User Story 1
- [x] T009 [US1] Finalize the dimension definitions, current repo-real examples, and forbidden proxy rules in `docs/product/standards/lifecycle-governance.md`
- [x] T010 [US1] Finalize the machine-readable dimension data in `contracts/lifecycle-governance-taxonomy.yaml` so it stays aligned with the standard
**Checkpoint**: Every lifecycle concern in scope maps to one dimension and one authoritative source.
---
## Phase 4: User Story 2 - Choose the right transition safeguards (Priority: P1)
**Goal**: Make confirmation, audit, OperationRun, and export/retention preconditions explicit before later runtime slices start.
**Independent Test**: Review the standard and contract artifacts and confirm that archive/delete, provider observation, commercial suspension, retention/purge, and restoreability transitions all have explicit safeguard rules.
### Validation for User Story 2
- [x] T011 [P] [US2] Review the transition-governance table in `docs/product/standards/lifecycle-governance.md` against `data-model.md` and `contracts/lifecycle-governance-taxonomy.yaml`, confirming that `export requested` remains a reserved retention/compliance value while `Data Export Before Deletion v1` remains a separate runtime slice
- [x] T012 [P] [US2] Confirm that audit-only versus `OperationRun`-backed guidance is explicit and does not imply new runtime behavior in this slice
### Implementation for User Story 2
- [x] T013 [US2] Finalize the transition-governance matrix in `docs/product/standards/lifecycle-governance.md`, including confirmation, audit, OperationRun, export-before-delete, and retention-review rules
- [x] T014 [US2] Keep `contracts/lifecycle-governance-taxonomy.yaml` aligned with the final transition-governance rules
**Checkpoint**: Future lifecycle slices can choose the correct safeguard path without guessing.
---
## Phase 5: User Story 3 - Keep follow-up slices bounded (Priority: P2)
**Goal**: Prevent the promoted lifecycle candidate from collapsing back into one oversized umbrella change.
**Independent Test**: Review the standard, spec package, and candidate history and confirm that every major adjacent concern is listed as an explicit follow-up slice rather than hidden in primary scope.
### Validation for User Story 3
- [x] T015 [P] [US3] Verify that `export requested` appears as a reserved retention/compliance value and that `Provider-Missing Managed Object Truth v1`, `Workspace & Tenant Closure Lifecycle v1`, `Data Export Before Deletion v1`, `Retention & Purge Governance v1`, and `Restoreability Expiry & Evidence Retention v1` appear consistently across `spec.md`, `quickstart.md`, `data-model.md`, and `contracts/lifecycle-governance-taxonomy.yaml`
- [x] T016 [P] [US3] Verify that the standard in `docs/product/standards/lifecycle-governance.md` points future runtime work at these follow-up slices instead of absorbing them locally
### Implementation for User Story 3
- [x] T017 [US3] Verify that `docs/product/spec-candidates.md` still records the explicit promotion to Spec 262 without turning the active queue back into an auto-prep target, and refine any stale promotion-versus-deferred wording if the retained history drifts
- [x] T018 [US3] Add the follow-up slice boundaries and review instructions to `docs/product/standards/lifecycle-governance.md`
**Checkpoint**: The lifecycle-governance candidate is promoted cleanly and its adjacent concerns stay explicitly separated.
---
## Phase 6: Polish & Final Validation
**Purpose**: Reconcile wording and finish the bounded review path.
- [x] T019 [P] Reconcile any remaining terminology drift for `archived`, `deleted`, `ignored`, `provider missing`, `expired`, `retained`, `export requested`, `purge due`, and `restorable` across `spec.md`, `plan.md`, `data-model.md`, `quickstart.md`, `contracts/lifecycle-governance-taxonomy.yaml`, and `docs/product/standards/lifecycle-governance.md`
- [x] T020 Run the repo-search validation commands from `quickstart.md`
- [x] T021 [P] Record the final review outcome, workflow outcome, and test-governance outcome in `checklists/requirements.md`, `plan.md`, and `quickstart.md`
## Implementation Evidence
- `docs/product/standards/lifecycle-governance.md` created as the reviewer-facing lifecycle standard.
- `docs/product/standards/README.md` updated to index lifecycle governance and route lifecycle-bearing specs through it.
- `contracts/lifecycle-governance-taxonomy.yaml` aligned with the standard through `standards_document`, transition ownership, and execution-path fields.
- Validation passed with the focused repo-search commands from `quickstart.md`, YAML parse for six dimensions and six transition rules, and `git diff --check`.
- Browser smoke test is not applicable because this slice changes no operator-facing runtime surface.
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: starts immediately and locks the repo-real lifecycle inputs.
- **Foundational Contract (Phase 2)**: depends on Setup and blocks all later work.
- **User Story 1 (Phase 3)**: depends on Foundational Contract.
- **User Story 2 (Phase 4)**: depends on User Story 1 because the transition rules rely on the final dimension map.
- **User Story 3 (Phase 5)**: depends on User Stories 1 and 2 so follow-up slices reflect the final taxonomy and safeguard rules.
- **Polish (Phase 6)**: depends on all desired user stories being complete.
### User Story Dependencies
- **US1**: no dependencies beyond Foundational Contract.
- **US2**: depends on US1.
- **US3**: depends on US1 and US2.
### Parallel Opportunities
- `T001`, `T002`, and `T003` can run in parallel during Setup.
- `T004`, `T005`, and `T006` run in sequence during the Foundational Contract phase.
- `T007` and `T008` can run in parallel for User Story 1.
- `T011` and `T012` can run in parallel for User Story 2.
- `T015` and `T016` can run in parallel for User Story 3.
## Notes
- Suggested MVP scope: Phase 1 through Phase 4 only. That is the minimum needed to answer the deferred candidate's lifecycle-question set safely.
- Explicit non-goals remain: runtime deletion, closure, purge, migration, panel/provider work, assets, lifecycle dashboard, and lifecycle framework implementation.
- All tasks above stay on the standards and documentation path only.