Current state: embeddings and quiz-generation read model files straight off the ro bind; both are pinned to SERVER solely because of it (spikersoft-embeddings/docker-stack*.yml, spikersoft-quiz-generation/docker-stack*.yml).
Steps: bucket + scoped ro keys per service → backend PR: model loader fetches from ai-models into a container-local cache dir at startup (models are read-once-at-load; an ephemeral/named local cache is fine — the decoupling goal is placement, not zero local disk for caches) → backfill mc mirror /mnt/fusionio/spikersoft/ai spiker/ai-models → dual-run → remove ro binds, relax placement to the GPU label.
Important caveat (from docs/minio-storage-migration.md non-goals): migrating ai-models is necessary but NOT sufficient to run embeddings/quiz on the 4090 — the gpu-coordinator still needs per-node lease routing (#367 U2). Placement relaxation lands together with that work.
Parent epic: #413.
**Scope:** `ai-models` bucket — `/mnt/fusionio/spikersoft/ai` (backend rw; embeddings + quiz-generation ro).
**Current state:** embeddings and quiz-generation read model files straight off the ro bind; both are pinned to SERVER solely because of it (`spikersoft-embeddings/docker-stack*.yml`, `spikersoft-quiz-generation/docker-stack*.yml`).
**Steps:** bucket + scoped ro keys per service → backend PR: model loader fetches from `ai-models` into a container-local cache dir at startup (models are read-once-at-load; an ephemeral/named local cache is fine — the decoupling goal is *placement*, not zero local disk for caches) → backfill `mc mirror /mnt/fusionio/spikersoft/ai spiker/ai-models` → dual-run → remove ro binds, relax placement to the GPU label.
**Important caveat (from `docs/minio-storage-migration.md` non-goals):** migrating `ai-models` is necessary but NOT sufficient to run embeddings/quiz on the 4090 — the gpu-coordinator still needs per-node lease routing (#367 U2). Placement relaxation lands together with that work.
Backend PR #261: ObjectFileCache in SpikerSoft.Storage (local-wins → atomic bucket download → null), embeddings resolves its gguf directly, quiz-generation via a ModelPathResolver delegate so Business.Ai.Workers stays storage-free. Placement relaxation deliberately NOT included — waits on #367 U2 per the migration-doc non-goal. Deploy: ai-models bucket + ro keys, mc mirror backfill, optionally a node-local named volume for the model cache.
Backend PR #261: ObjectFileCache in SpikerSoft.Storage (local-wins → atomic bucket download → null), embeddings resolves its gguf directly, quiz-generation via a ModelPathResolver delegate so Business.Ai.Workers stays storage-free. Placement relaxation deliberately NOT included — waits on #367 U2 per the migration-doc non-goal. Deploy: ai-models bucket + ro keys, mc mirror backfill, optionally a node-local named volume for the model cache.
Code MERGED (backend #261 — ObjectFileCache + embeddings direct + quiz via ModelPathResolver delegate). Remaining = ops: ai-models bucket + per-service ro keys, mc mirror /mnt/fusionio/spikersoft/ai (multi-GB), Storage__UseS3 + secrets on both GPU stacks, optional node-local named volume for the model cache. Placement relaxation stays gated on #367 U2 per the ticket.
Code MERGED (backend #261 — ObjectFileCache + embeddings direct + quiz via ModelPathResolver delegate). Remaining = ops: ai-models bucket + per-service ro keys, mc mirror /mnt/fusionio/spikersoft/ai (multi-GB), Storage__UseS3 + secrets on both GPU stacks, optional node-local named volume for the model cache. Placement relaxation stays gated on #367 U2 per the ticket.
Infra: #120 (embeddings sources the model from the ai-models bucket, /app/ai bind dropped, named cache volume) — merged and deployed; quiz-generation stack likewise runs Storage__UseS3=true.
Live state checked on the swarm: both services Running; embeddings has NO fusionio bind (only the named model-cache volume) and resolves its model path; quiz-generation has a working Bao-sourced storage key and generated a quiz at 2026-07-16T15:03Z (17 in book-generated-quizzes), proving the bucket holds the weights and the on-demand fetch works.
Placement relaxation (un-pinning from SERVER/GPU node) stays gated on #367 U2 per the ticket scope. Closing; #592 (quiz-generation empty secret) closed with the same evidence.
Complete and verified live (2026-07-17):
- Code: backend #261 (ObjectFileCache + embeddings direct + quiz ModelPathResolver) — merged earlier.
- Infra: #120 (embeddings sources the model from the `ai-models` bucket, `/app/ai` bind dropped, named cache volume) — merged and deployed; quiz-generation stack likewise runs `Storage__UseS3=true`.
- Live state checked on the swarm: both services Running; embeddings has NO fusionio bind (only the named model-cache volume) and resolves its model path; quiz-generation has a working Bao-sourced storage key and **generated a quiz at 2026-07-16T15:03Z** (17 in `book-generated-quizzes`), proving the bucket holds the weights and the on-demand fetch works.
Placement relaxation (un-pinning from SERVER/GPU node) stays gated on #367 U2 per the ticket scope. Closing; #592 (quiz-generation empty secret) closed with the same evidence.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Parent epic: #413.
Scope:
ai-modelsbucket —/mnt/fusionio/spikersoft/ai(backend rw; embeddings + quiz-generation ro).Current state: embeddings and quiz-generation read model files straight off the ro bind; both are pinned to SERVER solely because of it (
spikersoft-embeddings/docker-stack*.yml,spikersoft-quiz-generation/docker-stack*.yml).Steps: bucket + scoped ro keys per service → backend PR: model loader fetches from
ai-modelsinto a container-local cache dir at startup (models are read-once-at-load; an ephemeral/named local cache is fine — the decoupling goal is placement, not zero local disk for caches) → backfillmc mirror /mnt/fusionio/spikersoft/ai spiker/ai-models→ dual-run → remove ro binds, relax placement to the GPU label.Important caveat (from
docs/minio-storage-migration.mdnon-goals): migratingai-modelsis necessary but NOT sufficient to run embeddings/quiz on the 4090 — the gpu-coordinator still needs per-node lease routing (#367 U2). Placement relaxation lands together with that work.Backend PR #261: ObjectFileCache in SpikerSoft.Storage (local-wins → atomic bucket download → null), embeddings resolves its gguf directly, quiz-generation via a ModelPathResolver delegate so Business.Ai.Workers stays storage-free. Placement relaxation deliberately NOT included — waits on #367 U2 per the migration-doc non-goal. Deploy: ai-models bucket + ro keys, mc mirror backfill, optionally a node-local named volume for the model cache.
Code MERGED (backend #261 — ObjectFileCache + embeddings direct + quiz via ModelPathResolver delegate). Remaining = ops: ai-models bucket + per-service ro keys, mc mirror /mnt/fusionio/spikersoft/ai (multi-GB), Storage__UseS3 + secrets on both GPU stacks, optional node-local named volume for the model cache. Placement relaxation stays gated on #367 U2 per the ticket.
Complete and verified live (2026-07-17):
ai-modelsbucket,/app/aibind dropped, named cache volume) — merged and deployed; quiz-generation stack likewise runsStorage__UseS3=true.book-generated-quizzes), proving the bucket holds the weights and the on-demand fetch works.Placement relaxation (un-pinning from SERVER/GPU node) stays gated on #367 U2 per the ticket scope. Closing; #592 (quiz-generation empty secret) closed with the same evidence.