# Infra Storage

> Manage AICP's storage surfaces — model GGUF files (`models/` host volume mounted into LocalAI container), config YAMLs (`config/` source-controlled), runtime state (`~/.aicp/dlq/`, `~/.aicp/history/`, `.aicp/state.yaml`), KB vector store (LocalAI Collections at `localhost:8090/app/collections`), per-model prompt caches. AICP has no SQL database — storage is files + LocalAI Collections. Loads when the operator says "where does AICP store X" / "disk usage growing" / "back up state" / "move models to bigger disk" / "migrate to faster storage". Use when this capability is needed.

- Skill: `tomevault-io/infra-storage` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/infra-storage`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/infra-storage/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/infra-storage

---


# infra-storage

Manage AICP's storage surfaces. AICP doesn't use a SQL database — storage
is a mix of:

1. **Model GGUF files** — `models/` directory on host, volume-mounted
   into the LocalAI container at `/models`. Largest disk consumer (4-30GB
   per model).
2. **Config YAMLs** — `config/` source-controlled, small.
3. **Runtime state** — `~/.aicp/` (gitignored): `dlq/<UTC-date>.jsonl`,
   `history/...jsonl`, `metrics/`, `prometheus_snapshot.json`, plus
   per-project `.aicp/state.yaml`.
4. **KB vector store** — LocalAI Collections at
   `localhost:8090/app/collections` (chromem-backed, persistent inside
   LocalAI container at `/app/collections`).
5. **Prompt caches** — per-model cache files inside LocalAI container
   (per `infra-cache` skill).

## Trigger phrases (when to load this skill)

Load when the conversation matches any of:

- **Direct verb**: operator says "where does AICP store X", "disk usage
  growing", "back up state", "move models to bigger disk", "migrate to
  faster storage"
- **Inventory**: post-incident audit of what disk AICP touches
- **Backup planning**: identifying backup-worthy state vs ephemeral state
- **Storage upgrade**: moving from one disk to another (e.g., HDD → SSD
  for model files)

Do NOT load when:

- The concern is the DLQ runtime ops (load `aicp-ops-dlq`)
- The concern is prompt cache tuning (load `infra-cache`)
- The concern is config schema (load `config-env`/`config-migrations`)

## Operations

### Operation 1 — Inventory storage surfaces and disk usage

**When**: pre-cleanup audit or storage upgrade planning.

**Process**:

1. Models: `du -sh models/` (host) — usually 5-50GB depending on count
2. Config: `du -sh config/` — small (kilobytes)
3. Runtime state: `du -sh ~/.aicp/` — DLQ + history + metrics
4. LocalAI Collections: `docker exec aicp-localai du -sh /app/collections`
   — KB embeddings + indices
5. Prompt caches inside container: `docker exec aicp-localai du -sh
   /tmp/cache` (or wherever prompt_cache_path resolves)
6. Build inventory table: surface × path × size × backup-worthy?

**Quality bar**: NEVER assume storage usage without measuring. Models
dominate disk; everything else is small in comparison.

### Operation 2 — Move model GGUFs to a different disk

**When**: host disk is full or operator wants faster I/O for model loading.

**Process**:

1. Identify source: `models/` (volume-mounted into container at `/models`)
2. Move data to new location:
   `mv models/ /new/disk/models/ && ln -s /new/disk/models models`
   (symlink preserves the relative path used by docker-compose.yaml)
3. OR: update `docker-compose.yaml` volume mount to point at new path
   directly (cleaner; symlink is the quick option)
4. Restart LocalAI: `docker compose restart localai`
5. Verify: `aicp --models list` shows all models still discoverable
6. If model load fails, the volume mount in docker-compose.yaml needs
   updating to the new path

**Quality bar**: NEVER `cp` then forget to delete the source — duplicates
silently waste disk. Use `mv` (or `cp` then verify, then `rm` source).

### Operation 3 — Back up runtime state

**When**: operator wants to preserve `~/.aicp/` before reformatting,
upgrading, or migrating to a new machine.

**Process**:

1. Identify backup-worthy:
   - `~/.aicp/dlq/` — failed tasks (re-runnable)
   - `~/.aicp/history/` — task history (audit trail)
   - `~/.aicp/metrics/`, `prometheus_snapshot.json` — metrics state
   - per-project `.aicp/state.yaml` (ephemeral, per-operator — usually
     not worth backing up)
2. Create archive: `tar czf aicp-state-$(date +%F).tar.gz ~/.aicp/`
3. Store off-machine (cloud sync, USB, etc.)
4. To restore: `tar xzf aicp-state-<date>.tar.gz -C /`

**Quality bar**: backup verifies restorability — test the restore on a
scratch machine before relying on the backup.

### Operation 4 — Migrate KB Collections to a different LocalAI instance

**When**: moving AICP from one LocalAI deployment to another (e.g., for
fleet rollout).

**Process**:

1. Source: KB collections live in LocalAI's `/app/collections` directory
2. Stop the source LocalAI: `docker compose stop localai`
3. Tar the collections: `docker run --rm -v aicp_localai_data:/data
   alpine tar czf - /data/collections > kb-snapshot.tar.gz`
4. On target host: extract into the target LocalAI's volume
5. Start target LocalAI; verify: `aicp --kb status` shows the same
   chunk count

**Quality bar**: KB migration is a STATEFUL operation — NEVER do it on
a running LocalAI (writes during the snapshot can corrupt the migrated
DB).

## Gotchas

- **Detection**: agent assumes AICP uses a SQL database.
  **Rule**: AICP has no SQL DB. Storage is files + LocalAI Collections.
  **Reasoning**: setting expectations correctly avoids wasted time
  searching for nonexistent migrations or schema files.

- **Detection**: agent treats `~/.aicp/` as project-state.
  **Rule**: `~/.aicp/` is OPERATOR-state (per-machine); per-project state
  lives in `<project>/.aicp/state.yaml`.
  **Reasoning**: backup scope differs — operator state is per-machine;
  per-project state is per-checkout (and gitignored).

- **Detection**: agent moves models with `cp` and forgets to delete source.
  **Rule**: use `mv` (atomic), or `cp + verify + rm`. Never leave
  duplicates.
  **Reasoning**: model files are 4-30GB each; duplicates silently consume
  disk.

- **Detection**: agent backs up KB collections from a running LocalAI.
  **Rule**: stop LocalAI before snapshotting Collections (or use the
  LocalAI export API if available).
  **Reasoning**: live snapshot of a write-active DB can produce a
  corrupted backup.

- **Detection**: agent thinks symlinking models will break the container.
  **Rule**: docker volume mounts follow symlinks; symlink is a valid
  quick relocate option. Updating docker-compose.yaml is cleaner long-term.
  **Reasoning**: volume mounts resolve through symlinks at mount time;
  this is well-supported.

## Reference exemplars

- `docker-compose.yaml` — `models/` volume mount (line ~XX, search for
  `volumes:`)
- `aicp/core/dlq.py` `_dlq_dir()` — `~/.aicp/dlq/` location
- `aicp/core/history.py` — `~/.aicp/history/` location
- `aicp/core/state.py` `STATE_DIR` — `<project>/.aicp/` location
- `wiki/patterns/01_drafts/per-day-jsonl-dlq-with-retry-budget.md` —
  why per-day JSONL was chosen (operator-inspectable, no daemon)

## Domain context

AICP's storage strategy mirrors its operational philosophy: file-based
where reasonable (models, DLQ, history, config), service-managed where
necessary (LocalAI Collections for KB embeddings). Per CLAUDE.md
`## Tech Stack`, no SQL DB; storage is filesystem + LocalAI's
self-managed stores. This trades schema flexibility for operator
inspection (`cat`, `grep`, `du`).

## Related skills

| Skill | When to use |
|-------|-------------|
| `aicp-ops-dlq` | When the concern is DLQ runtime ops (CLI workflow) |
| `infra-cache` | When the concern is prompt/KV cache specifically |
| `ops-backup` | When the concern is backup procedure (broader than just identifying state) |
| `evolve-scale` | When migrating to fleet-scale storage |
| `infra-monitoring` | When alerting on disk usage growth |

---
> Source: [cyberpunk042/devops-expert-local-ai](https://github.com/cyberpunk042/devops-expert-local-ai) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-16 -->

