# Cortex / Inara — Agent Task List > Read this file before starting any work on this project. > **Status:** Active development — ongoing. --- ## 🔴 High Priority ### [Auth] Token expiry — sudo restart - Cortex currently requires `sudo systemctl restart cortex` after OAuth token refresh - This must be done manually by the user (cannot run interactively from Claude Code) - **Future:** Explore hot-reload or token-passing mechanism so restart isn't required ### [Backend] Ollama local model backend - Add Ollama as a third LLM backend option (direct Ollama API, no CLI wrapper) - Endpoint: `http://scott-gaming:/api/` (WireGuard) - Model selection: configurable per-request or per-session - Auth status check: ping `/api/tags` to confirm reachability ### [Testing] Gitea SSH port 2222 - pfSense port forward configured but not yet verified end-to-end - Test: `ssh -p 2222 git@` from outside WireGuard - Document result in this file --- ## 🟡 Medium Priority ### [Intelligence] Orchestrator service — Phase 1 ✅ Complete See `ARCH__Intelligence_Layer.md` for full design. Committed: `ed472ce` (2026-03-18) - [x] Add Gemini API (google-generativeai SDK) as a library dependency (not CLI) - [x] Create `cortex/routers/orchestrator.py` — `POST /orchestrate` endpoint - [x] Basic tool registry: web search (DuckDuckGo), AE API query, file read, task list - [x] ReAct loop: Gemini calls tools, assembles context, hands off to Claude for final response - [x] `GET /orchestrate/{job_id}` — poll for status/result - [x] Cron can trigger via HTTP POST (same endpoint) - **Note:** Default model is `gemini-2.5-flash` — free tier key required (AI Studio) ### [Intelligence] Knowledge consolidation — Phase 1 See `ARCH__Intelligence_Layer.md` for full design. Initial scope: - [ ] Tool: `ae_journal_search` — search before creating to avoid duplicates - [ ] Tool: `ae_journal_entry_create` — write a new entry with source metadata - [ ] Import script: walk a markdown directory, chunk by H2 section, create entries - [ ] Target: markdown files from `~/DgrZone_Nextcloud/` and `~/OSIT_Nextcloud/` - [ ] Tag strategy: source path, date, topic tags from frontmatter or filename ### [Channel] Nextcloud Talk integration ✅ Complete - NC Talk bot is implemented (`cortex/routers/nextcloud_talk.py`) - HMAC: incoming uses `random + raw_body`; outgoing reply uses `random + message_text` — both correct - [x] Test end-to-end after any Cortex restart — confirmed working 2026-03-20 - [x] Bot registration docs completed in `docs/NEXTCLOUD_TALK_BOT.md` — 2026-03-20 - **Note:** Currently uses default user/persona only — per-conversation persona routing is a future enhancement ### [Multi-user] Holly onboarding - Multi-user is built into Cortex — single instance, multiple users under `home/` - `home/holly/persona/tina/` directory created from template (stub content — needs real persona files) - [ ] Send Holly's invite email: `python manage_passwords.py invite holly holly.danner@gmail.com` - [ ] Walk Holly through onboarding flow (`/setup/{token}` → persona creation) - [ ] Review and flesh out Tina's persona files (IDENTITY.md, SOUL.md, PROTOCOLS.md, USER.md) --- ## 🟢 Lower Priority / Future ### [Intelligence] Dev agent pipeline See `ARCH__Intelligence_Layer.md`. Full design not yet started. - [ ] Specialist agent: frontend (SvelteKit) code changes - [ ] Specialist agent: backend (FastAPI) code changes - [ ] Supervisor agent: diff review, syntax check, test runner - [ ] Gitea webhook integration: trigger on push/PR, report back - [ ] Human approval gate before commit ### [Intelligence] Supervisor agent - Runs `py_compile`, `svelte-check`, unit tests after specialist agent work - Reports pass/fail back to orchestrator - Only commits on explicit approval ### [Channel] Gitea webhooks - Receive push/PR/issue events → route to appropriate agent - `cortex/routers/` already has pattern; add `gitea.py` - Gitea Actions (CI) for "run tests on push" — simpler than custom runner ### [Auth] Session auth + persona onboarding ✅ Complete - bcrypt passwords stored in `home/{username}/auth.json` - JWT session cookies (HS256, 30-day expiry) — `auth_utils.py`, `auth_middleware.py` - Login/logout at `/login`, `/logout` - Invite tokens (72h, one-time-use) — admin generates via `manage_passwords.py invite [email]` - Self-service onboarding: `/setup/{token}` (set password) → `/setup/persona` (create persona) - Multi-persona switcher in UI header — `/api/personas` endpoint - SMTP invite email — `noreply@oneskyit.com`, HTML + plain text body - CSS routing fix — `app.mount("/static")` must precede `app.include_router(ui.router)` - Committed: 2026-03-20 ### [Channel] Google Chat integration ✅ Complete See `cortex/routers/google_chat.py`. Committed: 2026-03-20 - [x] JWT verification via `authorizationEventObject.systemIdToken` (audience = endpoint URL, issuer = accounts.google.com) - [x] Workspace Add-on event format: event type inferred from payload key (`messagePayload`, `addedToSpacePayload`, etc.) - [x] Response format: `hostAppDataAction.chatDataAction.createMessageAction.message.text` - [x] Session management, LLM pipeline, session logging — same pattern as NC Talk - [x] Nginx: `/channels/` prefix exposed without basic auth (covers all future channel integrations) - **Note:** Google Chat API now forces the Workspace Add-on framework — legacy standalone bot format is gone. `{"text": "..."}` and `renderActions` do NOT work; `hostAppDataAction` is required. ### [Distill] Monitor first auto_distill_long run - Scheduled for ~April 1 at 04:00 - Manually review `inara/MEMORY_LONG.md` output before fully trusting - Adjust distill prompts if needed ### [Distill] Distill quality review - Short/mid/long distill prompts live in `cortex/memory_distiller.py` - After first few automatic runs, review quality and tune ### [Backend] Intelligent model routing - Currently hardcoded: Claude default, Gemini fallback - Future: route by task type (code → Claude, search → Gemini, private → Ollama) - Future: route by context length (Gemini 2.0 has 1M token context) --- ## ✅ Completed ### [UI] Mobile-friendly header - Backend toggle, font size, theme buttons moved into ⚙ settings panel - Header reduced to 4 buttons: Sessions, Files, ⚙, ? - Committed: `mobile_header` (2026-03) ### [UI] Mobile text input - `flex-direction: column` on `#input-area` at ≤520px - `font-size: 16px` on `#input` (prevents iOS Safari auto-zoom) - `body { height: 100dvh }` (handles soft keyboard) - Committed: `23f8659` (2026-03) ### [UI] Auth warning banner - Claude CLI token expiry check (`~/.claude/.credentials.json`) - Gemini CLI auth check (warns only if no `refresh_token`) - Dismissible amber/red banner with re-auth instructions - Committed: `fe6561b` (2026-03) ### [UI] Distill schedule in ⚙ panel - Shows next_run times for short/mid/long distill jobs - Fetches from existing `/distill/status` endpoint ### [UI] Help modal collapsible sections - H2 sections collapse/expand via `
` elements - Top 4 sections (Header Controls, Chat, Sessions, Notes) open by default ### [Backend] Gemini CLI backend - `gemini -p` subprocess, streaming output - Auth check endpoint `/auth/status` ### [Backend] Memory distiller - APScheduler jobs: `distill_short` (6h), `distill_mid` (24h), `distill_long` (weekly) - Writes to `inara/MEMORY_SHORT.md`, `MEMORY_MID.md`, `MEMORY_LONG.md` ### [Backend] Session logging + file browser - Sessions saved to `inara/sessions/` - Files panel in UI browses `inara/` directory ### [Backend] Dispatcher core - FastAPI service with streaming response - `claude -p` and `gemini -p` subprocess backends - Session context management (rolling window) - Nextcloud Talk webhook handler