Gremlin

NETGRIMOIRE

LOCAL INTELLIGENCE ARCHITECTURE
Gremlin as the connective tissue between every AI tool you use
Architecture Diagram
Wiki Page
Container Design
NetGrimoire — Local Intelligence Data Flow
// interface layer — you
🖥️
GREMLIN INTERFACE
Open WebUI or avatar frontend. One place for all queries. Provider-agnostic.
ai.netgrimoire.com
💻
CLAUDE CODE
Direct repo access. Reads CLAUDE.md + CONTEXT.md at session start.
MCP tools
📱
MOBILE / CLI
Any interface. All route through same proxy and share same memory.
same context
ALL QUERIES ROUTE HERE
// context injection layer — gremlin's brain
Gremlin
GREMLIN PROXY
FastAPI · pulls Qdrant context · builds enriched prompt · routes to backend · captures response · triggers write-back
🔍
CONTEXT RETRIEVER
Qdrant similarity search. Top-k chunks injected into system prompt before query leaves.
🗺️
ROUTER
Routes by task type or @provider prefix. Config-driven from gremlin/config.yaml.
✍️
WRITE-BACK
After response: n8n → Ollama summarize → update memory files → commit to Forgejo.
ENRICHED PROMPT → PROVIDER
// ai provider layer — external reasoning
🤖
CLAUDE
Long context reasoning, architecture, writing.
api.anthropic.com
💻
CLAUDE CODE
Code generation, repo ops via -p mode.
MCP / SSH
🔎
PERPLEXITY
Research, current events, web retrieval.
api
💎
GEMINI
Multimodal, large context, Google data.
api
🏠
OLLAMA LOCAL
Private queries. Never leaves network. Always available offline.
docker4
// memory layer — gremlin's knowledge store
🗄️
QDRANT
Vector store. Collections per source. Semantic retrieval at query time.
docker4
📁
MEMORY FILES
MD files in traveler/memory. Human-readable. Git-versioned. CLAUDE.md + CONTEXT.md per repo.
Forgejo
📋
SESSION LOG
Every AI exchange logged with provider, cost estimate, timestamp, summary.
n8n → Forgejo
INGEST — ASYNC / SCHEDULED
// knowledge sources — everything gremlin knows
📓
OBSIDIAN
traveler/notes vault. Git push → n8n → chunk + embed → Qdrant.
obsidian_v1
📄
PAPERLESS
REST API. Documents, receipts, contracts. Nightly pull.
paperless_v1
☁️
NEXTCLOUD
Calendar, contacts, files. CalDAV events → structured memory.
nextcloud_v1
🖼️
IMMICH
EXIF + album metadata. Phase 2 — photo understanding needs GPU.
immich_v1
📧
MAILCOW
IMAP. VIP senders always surfaced. Already partially wired via briefing.
email_v1
⚙️
FORGEJO REPOS
Stack configs, scripts, docs. CI/CD decisions → memory write-back.
repo_v1
active / query-time
ingest / async
Gremlin core

Overview

NetGrimoire's Local Intelligence system is a self-hosted personal knowledge graph, retrieval-augmented generation (RAG) pipeline, and AI proxy that gives every AI tool you use — Claude, Claude Code, ChatGPT, Gemini, Perplexity, and local Ollama models — persistent memory of your entire life and infrastructure.

The system is managed by Gremlin, a grumbling but diligent AI agent persona that runs on your homelab. Gremlin acts as the connective tissue: ingesting knowledge from all your services, storing it in a vector database, and injecting relevant context into every query before it reaches an external provider.

Core Property
Knowledge lives in the infrastructure, not in the AI session. You stop being the memory. Gremlin holds it. Every AI tool continues the same conversation regardless of which tool made the last change.

How It Works

1. Ingest (The Slow Work)

Gremlin continuously ingests from all connected knowledge sources on a schedule. Each source gets its own Qdrant collection, versioned for safe re-embedding when better models become available:

  • Obsidian vault — Git push webhook → n8n → chunk by note → nomic-embed-textobsidian_v1
  • Paperless-ngx — REST API, nightly pull → Ollama summarize + entity extract → paperless_v1
  • Nextcloud — CalDAV/files → structured event records → nextcloud_v1
  • Forgejo repos — CI/CD decisions, commit messages, stack configs → repo_v1
  • MailCow — IMAP, VIP senders prioritized → email_v1
  • Immich — EXIF + album metadata now; full photo understanding after GPU upgrade → immich_v1

All records include embedded_with, summarized_with, and ingested_at metadata so re-processing is targeted when hardware improves.

2. Query (The Fast Work)

When you send a query through any interface, the proxy layer intercepts it before it reaches any AI provider:

# Every query follows this path
1. Query arrives at Gremlin Proxy (FastAPI)
2. Embed query with nomic-embed-text
3. Qdrant similarity search across relevant collections
4. Top-k chunks formatted as context block
5. Router selects provider (config-driven or @override)
6. Enriched prompt dispatched to provider
7. Response returned to interface
8. Write-back worker captures exchange

The embedding step (step 2–3) runs on CPU in milliseconds — it's just a vector lookup, not inference. The external provider sees a well-contextualized prompt and responds as if it has long-term memory.

3. Routing

The router selects a backend based on query classification or explicit prefix. Rules live in gremlin/config.yaml so no workflow code changes are needed to add or adjust providers:

routing:
  default: claude
  rules:
    - pattern: code|script|function|debug
      backend: claude-code
    - pattern: research|news|current|latest
      backend: perplexity
    - pattern: private|local|sensitive
      backend: ollama
  overrides:
    @claude:    claude
    @code:      claude-code
    @gemini:    gemini
    @perplexity: perplexity
    @local:     ollama      # never leaves network

4. Memory Write-Back

After every significant exchange, n8n triggers a write-back worker:

  • Ollama summarizes the session (what was asked, what was decided, what changed)
  • Summary appended to daily log in traveler/memory/YYYY-MM-DD.md
  • Key decisions extracted to structured frontmatter
  • Committed to Forgejo — fully git-versioned and auditable
  • New chunks embedded and upserted into Qdrant

5. Claude Code Continuity

Claude Code sessions achieve continuity through two Gremlin-maintained files in every repo root:

  • CLAUDE.md — auto-generated by Gremlin CI/CD. Stack standards, active work, recent decisions, open questions. Always current.
  • CONTEXT.md — session state. Current focus, last stopping point, exact next steps. Written by Gremlin write-back after each session.

Claude Code reads both automatically at startup. Every session continues exactly where the last one left off, regardless of how much time has passed.

Hardware Tiers

TierHardwareGremlin CapabilityExternal AI Role
0 CPU only NOW Slow async ingestion, basic summarization, nomic embeddings, context injection All heavy reasoning, real-time responses
1 RTX 3090 / 24GB Fast ingestion, qwen2.5:32b locally, real-time chat, deep entity extraction Specialized tasks, very long context
2 Dual GPU or 48GB+ 70B models locally, autonomous multi-step agents, real-time photo understanding Optional — used for genuinely hard problems
3 Serious local compute Mostly self-sufficient. External AI is a specialty tool. Exceptional cases only

The architecture does not change between tiers. Gremlin's endpoints and config.yaml routing rules are the only things that update as hardware improves.

Key Design Principles

  • Deterministic before LLM — embedding and retrieval are fast and reliable. Ollama only runs for summarization and entity extraction, never for routing logic.
  • Opt-in privacy@local prefix forces any query to Ollama. It never reaches an external API. Sensitive infrastructure queries stay home.
  • Versioned collectionsobsidian_v1, paperless_v1 etc. Re-embedding with a better model populates _v2 alongside without downtime.
  • Config-driven routing — no code changes to add a provider or adjust routing rules. Everything lives in gremlin/config.yaml.
  • Auditability — every AI exchange is logged with provider, estimated cost, timestamp, and summary. Full history in Forgejo.
  • Single memory store — Qdrant + MD files in traveler/memory. All interfaces read from and write to the same place.
Build Order
Memory schema → Obsidian ingestion → Paperless ingestion → Proxy shim → Write-back loop → Additional sources → Avatar / voice layer. The proxy shim is the unlock that makes all interfaces share memory. Build that first.

Related Pages

  • Gremlin CI/CD Pipeline — stack deployment automation
  • Gremlin Morning Briefing — daily HTML dashboard
  • Pocket Grimoire — travel-subset deployment
  • Obsidian Vault — traveler/notes structure and sync
  • Qdrant — vector database configuration

Container Consolidation Analysis

The question is whether to consolidate related services into shared containers, or keep them separate. Here's the analysis for each logical grouping.

General Rule
Consolidate when services share a lifecycle, have no independent scaling needs, and the operational savings outweigh the debugging complexity. Keep separate when services have different update cadences, resource profiles, or failure domains.

Option: Gremlin Intelligence Stack

The proxy, write-back worker, and ingest workers are all Python services with shared library dependencies. These are strong consolidation candidates:

ServiceConsolidate?Rationale
Gremlin Proxy (FastAPI) YES — anchor service Small, stateless, always-on. The core of the stack.
Ingest Workers (n8n-triggered Python) MAYBE — keep as scripts n8n SSHes in and runs these. They don't need to be long-running services — just scripts on disk that n8n executes. Simpler than a dedicated container.
Write-back Worker YES — fold into proxy Triggered by proxy after response. Same process, async task. No reason to separate.
Embedding Service CONSIDER — separate If you run nomic-embed-text outside Ollama (e.g. via sentence-transformers), a tiny dedicated container is cleaner. If via Ollama, no separate service needed.

Recommendation: One gremlin-proxy container running FastAPI with the write-back logic as an async background task. Ingest workers stay as scripts on the host, executed by n8n. Keeps the container small and debuggable.

Option: Ollama + Open WebUI

ServiceConsolidate?Rationale
Ollama NO — keep separate Already a well-designed standalone service. Used by multiple consumers (n8n, proxy, Open WebUI). Separating keeps failure domains clean.
Open WebUI NO — keep separate Different update cadence from Ollama. Stateful (user data, settings). Independent lifecycle.
Gremlin Avatar (future) CONSIDER — alongside proxy Open-LLM-VTuber is a Node service. Could share a compose stack with gremlin-proxy but keep separate containers. Same deploy unit, different processes.

Option: n8n + Supporting Services

ServiceConsolidate?Rationale
n8n NO — keep standalone Already running. Central orchestrator — too important to share a failure domain with anything else.
n8n Postgres NO — keep separate Stateful. Different backup and upgrade needs.

Recommended Stack Layout

Two new Swarm stacks covering the new intelligence layer:

# Stack 1: gremlin-intelligence
services:
  gremlin-proxy:        # FastAPI proxy + write-back + router
    image: gremlin-proxy:latest
    # Built from traveler/services/gremlin-proxy/

  gremlin-avatar:       # Open-LLM-VTuber (future)
    image: openllm-vtuber:latest

# Stack 2: gremlin-knowledge (already partially exists)
services:
  qdrant:               # already running
  ollama:               # already running
  open-webui:           # already running

What NOT to Consolidate

  • Qdrant — stateful, needs independent backup management, separate from application logic
  • Ollama — shared dependency for too many services; isolating it in a bundle breaks other consumers
  • n8n — orchestrator, too critical to co-locate
  • Forgejo — git server, completely separate lifecycle
Bottom Line
Build one new container: gremlin-proxy. It's the proxy, router, and write-back worker in one small FastAPI service. Everything else you already have runs fine as-is. The intelligence layer is mostly glue code connecting existing services, not new infrastructure.