generated from coulomb/repo-seed
Aligns the v1 architecture with the longer-horizon platform thesis so we can start implementation without the schema-level inconsistencies the prior review surfaced. ADRs (docs/adr/0001..0006): content-addressed dual-digest storage, append-only event log as source of truth, canonical CBOR manifests, control/data-plane contract, v1 tech stack (Python 3.12 / uv / FastAPI / SQLAlchemy Core + asyncpg / Alembic / cbor2 / blake3 / ruff / mypy / pytest / typer), OCI compatibility kept reachable. Architecture blueprint rewritten to v2: library-first (ffmpeg-shaped) module layout, materialised-view data model over the event log, upload-session and event-stream endpoints pinned, retrieval tiering promoted into the schema. Roadmap added (docs/ROADMAP.md) with three phases. WP-0001 rewritten as the Foundation plan (scaffold + kernels + local FS + minimal app). WP-0002..0005 created carrying the existing state_hub_task_ids forward semantically: ingestion API (T004), retention lifecycle (T005), S3-compatible backend (T006), guide-board pilot (T007). T001/T002/T003/T008 remain in WP-0001 with refined acceptance. README and AGENTS.md refreshed to reflect the new repo shape. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3.6 KiB
3.6 KiB
id, type, title, repo, domain, status, owner, topic_slug, planning_priority, planning_order, created, updated
| id | type | title | repo | domain | status | owner | topic_slug | planning_priority | planning_order | created | updated |
|---|---|---|---|---|---|---|---|---|---|---|---|
| ARTIFACT-STORE-WP-0003 | workplan | Retention Lifecycle: Defaults, Extensions, Holds, Deletion Eligibility | artifact-store | stack | planned | codex | stack | high | 3 | 2026-05-15 | 2026-05-15 |
ARTIFACT-STORE-WP-0003: Retention Lifecycle
Purpose
Implement the retention engine. By the end of this workplan, every
package has a computed expires_at, operators can extend retention or
apply / release holds, and the system can mark expired packages as
eligible for deletion — without actually deleting bytes (GC is
WP-0006).
Constraints
- ADR-0002 (every retention change is an event).
docs/ARCHITECTURE-BLUEPRINT.mdretention sections.
Prerequisites
- WP-0001 done (
retention_classesseeded,retention_stateview exists). - WP-0002 done (HTTP surface exists to attach the new endpoints to).
D3.1 - Default Retention Application
id: ARTIFACT-STORE-WP-0003-T001
status: todo
priority: high
state_hub_task_id: "2d6cbd83-c348-45ad-a223-7870a3412225"
Acceptance:
- On
POST /packages, the requestedretention_classis validated and thev1.retention.default_appliedevent is written with the computedexpires_at. - Default durations per class are operator-configurable via a
config file (TOML); the file path is documented in
OPERATOR.md. permanent-recordpackages haveexpires_at = NULLandeligible_for_deletion = false.
D3.2 - Retention Extensions
id: ARTIFACT-STORE-WP-0003-T002
status: todo
priority: high
Acceptance:
POST /packages/{id}/retention/extensionsaccepts{new_expires_at, reason}. The new value must be strictly later than the current; reason is mandatory.- Each extension writes a
v1.retention.extendedevent;retention_state.current_expires_atupdates on the same transaction. - A package's full extension history is recoverable from
events.
D3.3 - Holds (Apply And Release)
id: ARTIFACT-STORE-WP-0003-T003
status: todo
priority: high
Acceptance:
POST /packages/{id}/retention/holdsrecords a hold with a reason and actor; emitsv1.retention.hold_applied.- A package with at least one active hold is never
eligible_for_deletionregardless ofexpires_at. POST /packages/{id}/retention/holds/{hold_id}/releaserequires a reason; emitsv1.retention.hold_released.- Test: hold applied → expiry passes → eligibility stays
false; hold released → eligibility flips totrue.
D3.4 - Deletion Eligibility Sweeper
id: ARTIFACT-STORE-WP-0003-T004
status: todo
priority: medium
Acceptance:
- A scheduled task (cron-style configurable interval; default 1 hour)
scans packages whose
expires_athas passed and no active hold exists, and emitsv1.retention.deletion_eligibleevents. - The sweeper is idempotent: events are emitted at most once per package per eligibility transition.
- The sweeper is invokable as a CLI subcommand for tests:
artifactstore retention sweep.
D3.5 - Audit Surface For Retention
id: ARTIFACT-STORE-WP-0003-T005
status: todo
priority: medium
Acceptance:
GET /packages/{id}/retention/historyreturns the ordered list of retention events for a package.- The default response is the JCS projection; CBOR is available via
Accept: application/cbor.
Success criteria
- A guide-board run can be ingested, given
release-evidence, later extended once, held for a quarter, released, swept, and marked eligible — all visible through bothretention_stateand the event log. - No bytes are deleted by this workplan; that is WP-0006.