tegwick f8097cb683 WP-0001-T002: registry data model, Alembic, initial migration with retention seed
Schema (src/artifactstore/db/schema.py):
- events table (ADR-0002 source of truth): sequence BIGSERIAL PK, created_at,
  event_type, subject_kind, subject_id, actor, payload (CBOR bytes),
  payload_digest. Indexes on (subject_kind, subject_id) and
  (event_type, sequence).
- artifact_packages, artifact_files, storage_locations, retention_state
  (materialised views over events).
- retention_classes (seed table) and metadata_schemas (config table).
- ADR-0001 columns present: digest_algorithm, digest_primary, digest_sha256,
  content_address. Blueprint tiering columns present: retrieval_tier
  (default 'hot'), restore_status.
- Types portable: SQLAlchemy 2.0 Core with JSON().with_variant(JSONB, 'postgresql'),
  Uuid, LargeBinary, DateTime(timezone=True), Boolean false() default.

Seed (src/artifactstore/db/seed.py): five v1 retention classes (transient,
raw-evidence, summary-evidence, release-evidence, permanent-record) with
default durations in seconds; permanent-record has no expiry.

Alembic:
- alembic.ini with sync sqlite URL default; path_separator=os to silence the
  1.13 deprecation warning.
- migrations/env.py: translates async URLs (+aiosqlite, +asyncpg) to sync
  counterparts at migrate-time so a single ARTIFACTSTORE_DATABASE_URL works
  for both runtime (async) and Alembic (sync).
- migrations/script.py.mako template.
- migrations/versions/20260516_0001_initial.py: metadata.create_all + bulk
  insert of retention class seeds.

Make:
- make migrate: alembic upgrade head (ensures var/ exists).
- make migrate-fresh: drop local SQLite + re-run.

Deps: psycopg[binary] added as optional `postgres` extra (PostgreSQL prod
path; SQLite default for dev needs no extra).

Tests:
- tests/unit/test_db_schema.py: every expected table present; ADR-0001 and
  tiering columns present; seed has the five v1 classes; permanent-record
  has no default_duration; create_all + FK insert + Boolean default
  round-trip on in-memory SQLite.
- tests/integration/test_migrations.py: alembic upgrade head against a
  tempfile SQLite produces all tables (+ alembic_version) and the seed rows.

Gates: ruff clean, mypy --strict clean on 32 files, 38 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 01:50:38 +02:00
2026-05-15 20:08:32 +02:00
2026-05-15 16:14:36 +00:00
2026-05-15 20:08:32 +02:00

artifact-store

Generic artifact registry and storage gateway for generated outputs, evidence packages, reports, logs, snapshots, exports, and release artifacts.

The registry owns artifact identity, metadata, provenance, retention policy, and retrieval records. Bytes are delegated to configured storage backends (local filesystem in v1, S3-compatible / Ceph RGW next).

The shape is library-first (artifactstore Python package); the HTTP server and the CLI are thin consumers. Content is addressed by digest; state is authoritative in an append-only event log; materialised views are rebuildable.

Status

Scaffold landed. The core kernels and local FS backend follow in the remaining tasks of WP-0001.

Develop

Requires Python ≥ 3.12 and uv on the path.

make install        # uv sync --all-extras
cp .env.example .env

make dev            # uvicorn artifactstore.api.http:app --reload
make test           # pytest
make lint           # ruff check + ruff format --check
make type           # mypy --strict
make migrate        # alembic upgrade head (configured in WP-0001-T002)

The dev server listens on 127.0.0.1:8000. The scaffold root route returns {"service": "artifact-store", "status": "scaffold"}; the real /health endpoint lands in WP-0001-T014.

Documentation

Active workplans

Agent operating notes

See AGENTS.md for the StateHub-integrated session protocol, workplan conventions, and progress-logging contract.

Description
Generic shared service artifact store to integrat S3 Buckets or scalable selfhosted Storage based on Ceph.
Readme MIT-0 750 KiB
Languages
Python 99.4%
Makefile 0.4%
Mako 0.2%