Skip to content

feat: implement artifact and project persistence #612

@Aureliolo

Description

@Aureliolo

Summary

Artifact and project API endpoints exist as stubs returning 501 (Not Implemented). Implement the persistence layer and flesh out the controllers.

Backend only. Web dashboard UI for artifacts/projects is a separate follow-up issue in v0.6.

Finding (from codebase audit)

Artifact controller stub

  • src/synthorg/api/controllers/artifacts.py:52-66:
    async def get_artifact(...) -> Response[ApiResponse[None]]:
        """Get an artifact by ID (stub -> not implemented)."""
        return Response(
            content=ApiResponse[None](error="Artifact persistence not implemented yet"),
            status_code=501,
        )

Project controller stub

  • src/synthorg/api/controllers/projects.py:52-66:
    async def get_project(...) -> Response[ApiResponse[None]]:
        """Get a project by ID (stub -> 501)."""
        return Response(
            content=ApiResponse[None](error="Project persistence not implemented yet"),
            status_code=501,
        )

Scope

Project persistence

  • Define project repository protocol in the persistence layer
  • Implement SQLite repository (matching existing persistence patterns -- settings repo, user repo)
  • Flesh out list/get/create endpoints in the projects controller
  • Wire into auto_wire.py service initialization

Artifact persistence (pluggable storage backend)

Artifact storage MUST follow the same pluggable backend pattern as MemoryBackend and PersistenceBackend -- a protocol/ABC defining the interface, with concrete implementations swapped at runtime.

Storage backend protocol:

  • ArtifactStorageBackend protocol with standard operations: store, retrieve, delete, list, exists
  • Metadata (artifact ID, content type, size, timestamps, owning task/agent) stored in SQLite alongside other persistence data
  • Content bytes handled by the pluggable storage backend

This issue implements: FileSystemArtifactStorage

  • Stores artifact content as files in the SynthOrg data directory (same parent as the SQLite database)
  • Directory structure: <data_dir>/artifacts/<artifact_id> (or similar)
  • Sensible limits for local file storage:
    • Max single artifact size: 50 MB
    • Max total artifact storage: 1 GB (configurable via settings)
    • Validated at the API boundary before writing

Future backends (not this issue):

  • Object storage (S3-compatible) -- as addon container or externally hosted
  • DB blob storage -- for small artifacts where a separate backend is overkill

What is NOT in scope

  • No web dashboard UI -- separate follow-up issue for v0.6
  • No migration system -- we do not entertain backwards-compatible schema changes until feat: implement production-grade database persistence backend #210 (production-grade database persistence backend, v0.8.5). Until then, schema changes are destructive -- the SQLite database is re-created from scratch. Users on pre-1.0 accept this.
  • No object storage implementation -- just the pluggable interface that makes it trivially addable later

Design Spec Reference

  • Communication design page, section 2 (Message Format -- artifact references)
  • Operations design page (general artifact handling)

Files to Modify

  • src/synthorg/api/controllers/artifacts.py
  • src/synthorg/api/controllers/projects.py
  • src/synthorg/persistence/ (new repository interfaces + SQLite implementations + artifact storage protocol + file system backend)
  • src/synthorg/api/auto_wire.py (wire new repositories and storage backend)

Metadata

Metadata

Assignees

No one assigned

    Labels

    scope:large3+ days of workspec:architectureDESIGN_SPEC Section 15 - Technical Architecturetype:featureNew feature implementationv0.5Minor version v0.5v0.5.3Patch release v0.5.3

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions