Skip to content

Persistent OCI cache with XDG_CACHE_HOME support #88

Description

@jpower432

Problem / Motivation

The CacheDir field on ServerOptions is declared but never used. loadBundleArtifacts always creates a fresh memory.New() in-memory store and pulls from the OCI registry on every invocation (internal/mcp/server.go:324). The --cache-dir CLI flag is a no-op.

The default path is hardcoded to $HOME/.complypack/cache but never actually used. It should respect $XDG_CACHE_HOME/complypack when set, falling back to $HOME/.complypack/cache when unset.

This is the foundational piece for CLI/MCP parity — without persistent caching, every CLI invocation pays the full cost of OCI pulls and CUE compilation. With a warm cache, CLI commands become fast enough for interactive and CI/CD use.

Proposed Solution

  1. Wire up CacheDir in loadBundleArtifacts — use an on-disk OCI store (e.g. oras-go file store) instead of memory.New() when a cache directory is configured
  2. Default to $XDG_CACHE_HOME/complypack when set, $HOME/.complypack/cache otherwise
  3. Add a complypack pull command that pre-warms the cache for all configured sources
  4. Both MCP server and future CLI subcommands should read from the same on-disk cache

Open Design Questions

Cache pruning

A persistent cache needs a pruning strategy. Options include:

  • Manual CLI command to clean artifacts not referenced by current config
  • Full cache wipe command
  • TTL-based expiry (auto-evict after N days)
  • Size cap with LRU eviction

The CLI UX for pruning needs discussion — what commands and flags feel right alongside pull?

Acceptance Criteria

  • loadBundleArtifacts uses persistent on-disk store when CacheDir is set
  • Default cache path respects $XDG_CACHE_HOME, falls back to $HOME/.complypack/cache
  • Second invocation with warm cache does not make network requests
  • complypack pull command populates cache for all configured sources
  • MCP server startup uses cached artifacts when available
  • Pruning mechanism exists (design TBD)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Ready 🚀

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions