- config.py: VERSION → v1.0.0, DEFAULT_MODEL from CAIC_DEFAULT_MODEL env,
HW_STATE_PATH from CAIC_HW_STATE_PATH env
- README.md: Docker install section (recommended), updated file structure,
added What's New in v1.0.0, requirements note for Docker
- ai.md: Docker run path, work state updated, version to v1.0.0,
external services table with Docker service names
- CLAUDE.md: Docker quick start, fixed dependencies note
- docker.md: checked off completed items in §10 checklist, updated §11
file list with actual paths and status
- TASKS.md: struck through B3 [DONE]
- config.py: defaults to localhost/localhost, AMQP to rabbitmq, secret
path to /run/secrets, RAG_MAX_VECTORS from env
- rag.py: EMBED_URL default to localhost
- app.py: syslog handler wrapped in try/except
- routers/completions.py: db.close() in try/finally
- db.py: PRAGMA journal_mode = WAL
- amqp.py: subscription append before try for reconnect safety
- tests/conftest.py: add project root to sys.path for test discovery
NEW/OLD button toggles between newest-first and oldest-first ordering.
scrollToTop() replaced by scrollToLatest() which checks direction.
appendMessage() uses prepend/append based on direction.
Preference persisted in localStorage.
model_pull.py: ensure_model() checks llama-server availability at
startup, falls back to Ollama pull API if model not found.
Integrated into app.py lifespan after assess_hardware().
11 tests cover all paths: available/unreachable/pull success/fail.
gpu.py: darwin branch via system_profiler SPDisplaysDataType for GPU
model/VRAM on macOS, falls back to rocm-smi on Linux.
hardware.py: _get_vram_darwin() parses system_profiler output.
node_agent/agent.py: get_load() reports VRAM on darwin via
system_profiler.
tests: 5 new gpu tests (linux/darwin/absent), 3 new hardware tests
(darwin assessment + VRAM parsing).
- scrollToTop() now respects user scroll position (100px threshold)
- resetScrollLock() called on new messages
- SESSION_TIMEOUT_SECONDS 90 -> 3600 (1 hour) to prevent mid-use expiry
- wrap 10 unprotected authFetch calls in try/catch to kill unhandled rejections
- auto_detect_facts() scans chat turns for factual content (IPs, paths,
services, config changes, hardware refs) using pattern matching
- check_fact_conflicts() cross-references detected facts against stored
FTS5 memories — when a contradiction exists (same topic, diff value)
the system surfaces a rag_update_suggestion in the done SSE payload
- Frontend shows a floating notification banner comparing old vs new
fact with Update/Dismiss buttons
- confirm_fact_update() replaces the memory + re-embeds/re-indexes
the Qdraft entry on user confirmation
- Silent auto-ingest (memories + Qdrant) when no conflict exists
- Frontend: msg-toolbar opacity 0→0.35 for visibility
- request_model_swap() publishes cmd.swap_model on jc.admin, sets node status to swapping
- handle_model_ready() updates active_model from inventory, restores active status
- handle_model_failed() sets node status to error with failure detail
- select_node() made async with two-pass logic: find ready node or trigger swap
- inventory field stored in node records for swap target lookup
- Both handlers subscribed on jc.system via SUBSCRIBE_TABLE
- Move all eviction logic (evict_batch, maybe_evict, EVICTION_LOG,
get_collection_count/stats, get_rag_operational_stats) into eviction.py
- Move QDRANT_URL, RAG_COLLECTION into config.py to break circular dep
- rag.py re-exports eviction symbols for backward compatibility
- Router imports updated to use eviction module directly
- All 130 tests pass
- Paperclip icon left of text input, file preview pill (image thumb or file icon)
- Conversation list shows attachment icon right of trash, opens gallery overlay
- Gallery overlay: scrollable, close (X), delete attachment per item
- DELETE /api/upload/{id} removes from SQLite + Qdrant
- PATCH /api/upload/{id}/link ties upload to conversation
- GET /api/upload/by-conversation/{id} lists attachments
- Chat accepts upload_context_id, injects [ATTACHED DOCUMENT] into system prompt
- Conversation list includes attachment_count field
- 8 new tests: upload context injection, delete, link, by-conversation, image type, attachment count
Still missing (P3): drag-and-drop upload, global attachments page, file download, batch upload