docs: plan safe cleanup deletes

This commit is contained in:
lda
2026-06-09 03:55:35 +07:00 Verified
parent 974b5c690f
commit 50f2313782
3 changed files with 399 additions and 3 deletions
@@ -0,0 +1,91 @@
# Artifact Delete Policy
This is the current design contract for adding artifact deletion. It is separate
from `wf draft delete` because artifact deletion is not only CLI plumbing.
## Current State
- Draft workspace deletion already exists in `wf_api` and can be exposed safely
through CLI/RPC.
- Deployment deletion already exists and is stored through
`WorkflowArtifactStore.delete_deployment`.
- Artifact deletion does **not** exist yet as a store/API operation.
- Deployments live in the artifact store area and can reference a specific
`(artifact_id, version)`.
This means `wf artifact delete <artifact_id> <version>` needs store-level policy,
not just a CLI command.
## Required Safety Rule
Artifact deletion must not remove an artifact version while any deployment
references that artifact version.
The first implementation should reject with structured output like:
```json
{
"deleted": false,
"artifact_id": "smoke_artifact_20260609",
"version": 1,
"blocked_by_deployments": ["smoke_deploy_20260609"]
}
```
The exact response can be adjusted to match existing API payload style, but it
must include the blocking deployment ids.
## Non-Goals For First Slice
- Do not cascade-delete deployments.
- Do not delete runs.
- Do not delete draft workspaces that created the artifact.
- Do not add soft-delete/tombstones unless a store migration spec exists.
- Do not silently ignore missing referenced deployments.
## Future Cascade Policy
If cascade deletion is added later, make it explicit and noisy:
```bash
wf artifact delete smoke_artifact_20260609 1 --cascade-deployments --confirm
```
The non-cascade path must remain the default.
## Implementation Shape
Add store primitives first, then API, then transport, then CLI:
1. `WorkflowArtifactStore` gains an artifact-version delete method.
2. `WorkflowArtifactStore` gains a helper to find deployments referencing
`(artifact_id, version)`, or the delete method returns the blockers itself.
3. `wf_api` exposes `delete_artifact(artifact_id, version)` and rejects when
blockers exist.
4. JSON-RPC and `RpcWorkflowApiClient` expose the same operation.
5. CLI adds `wf artifact delete <artifact_id> <version> --confirm`.
## Test Requirements
The first artifact-delete slice should include tests for:
- Deleting an unreferenced artifact version succeeds.
- Deleting a missing artifact version is idempotent only if the existing artifact
store style already treats deletes that way; otherwise it should return a
clear not-found error.
- Deleting an artifact version referenced by one deployment is blocked and
returns that deployment id.
- Deleting an artifact version referenced by multiple deployments returns all
blocking deployment ids.
- Deleting one artifact version does not delete other versions of the same
artifact id.
- CLI requires `--confirm`.
## Relationship To Deployment Delete
`wf deploy delete <deployment_id>` removes a deployment record. It does not remove
the artifact that deployment referenced.
`wf artifact delete <artifact_id> <version>` removes an artifact version only
after proving no deployment references it.