09·AI / ML·Passion project
AriOS
A personal knowledge companion that captures what you see, read, and hear into an Obsidian vault, then helps you actually learn it. A Knowledge Trainer turns notes into flashcards, grades your free recall, and schedules spaced-repetition reviews. Local-first; vault sovereignty is the hard constraint.
ResultDaily driver, now a learning engine too.

Discover
Why it exists.
Most personal AI tools are windows into someone else's database: you pay monthly, they remember things on their servers, and the moment you stop, the memories evaporate. I wanted the opposite, a companion that captures everything I encounter (photos, conversations, articles, voice notes) into my own Obsidian vault as plain markdown I'd still have if the tool died tomorrow.
AriOS is that companion. Every input lands in the vault as a structured concept node plus a timestamped trail line in today's diary. Markdown only, no DB, no sidecar metadata. The vault is the product; the AI is the staff.
StackTypeScript · Express · Telegram Bot API · Cloudflare Workers AI · Ollama · Whisper
Define
The brief.
Capture everything I encounter into an Obsidian vault as plain markdown I would still own if the tool died tomorrow, degrading gracefully when a cloud layer is unavailable.
Develop
What it took
Skills behind it.
Primary discipline plus the support stack.
Skills demonstrated
- AI & Machine LearningPrimary
Pluggable multimodal pipeline: vision (Cloudflare llava / Ollama with stub fallback), transcription (Cloudflare Whisper), classification (Ollama with heuristic fallback), retrieval (BM25 + MiniLM + CLIP via RRF), vault RAG with citation.
- Backend EngineeringSecondary
One Express server, five capture surfaces. URL ingest with platform-specific extractors (yt-dlp, Mozilla Readability, Reddit JSON API). Async job queue with status polling. Vercel-hosted Telegram webhook bot. Vercel-cron reminders running 24/7.
- Product StrategySecondary
Vault sovereignty as a hard constraint (markdown only, no DB, no sidecar). Telegram as the universal capture surface, replaces iOS Shortcut maintenance. Heuristic-first classify so the loop never blocks on a slow LLM. Pluggable provider layer so cloud paths are opt-in, not load-bearing.
- Prompt EngineeringSupporting
Prompt design for the on-device classifier and the vault-RAG /ask path, heuristic-first routing with an LLM fallback prompt tuned for low latency and citation.
- Data PipelinesSupporting
Append-only JSONL retrieval index next to the vault. Activity log per ingest with per-step timing. Full source preserved in collapsed <details> blocks so the index has the raw words, not just the summary.
Develop · Build
How it came together.
- 01
Telegram as the OS, not iOS Shortcuts
I started with iOS Shortcuts for photo capture and a Chrome extension for URLs. Two surfaces, two auth flows, two failure modes. Telegram collapses both: one bot reachable from any phone, laptop, web client, or iPad, with a native share sheet from every iOS app. Long-poll the Bot API, allowlist my user ID, and the bot becomes a universal inbox for photos, voice notes, documents, and links. Everything routes through one /ingest endpoint on the server. New surfaces ship as thin clients.
Backend Engineering - 02
Heuristic classify is the default, not the fallback
Ollama on a Dell CPU takes 30 seconds to classify a 1500-char prompt into a 12-option enum. That's unacceptable on the happy path. So the classifier inverts: a phrase-aware heuristic strips clickbait separators, clause-boundary truncates titles at 4-7 words, and matches a 12-domain regex against the body. Right answer about 80% of the time, in under 50 ms. The LLM only fires when the daemon is responsive AND the heuristic is unsure, which means most ingests are fast and the rare ones get the smart path. Failure modes inverted: nothing waits on a slow model.
AI & Machine Learning - 03
Vision moved to Cloudflare after every local tuning failed
I spent a session tuning llava-7b on the Dell, sharp pre-resize to 672 px, num_predict 220, num_ctx 2048, 30-minute keep-alive, P-core-only threads, trimmed prompt. The baseline was 90 s and the timeout was 90 s. After every lever was pulled it was still 162 s per image because vision-token tokenisation dominates prompt-eval on CPU, not text generation. Anthropic was off the table on principle. Cloudflare Workers AI runs llava-1.5-7b on GPU with a free tier covering 10k requests a day; warm round-trip is 10-15 s. The vault stays local, only the photo bytes leave the device, and only for the perception step. The provider layer is one env var to flip, so I can move back to local the day a GPU mini-PC lands.
AI & Machine Learning - 04
Voice transcribes locally, photos route to cloud
Voice notes are 1-2 minute Whisper-base ONNX inferences via @xenova/transformers, slow enough on CPU that I had to add a 'transcribing…' ack so the user knows the bot heard them, fast enough that the vault entry is written before they switch apps. Photos go to Cloudflare because vision is the harder local problem. The split is honest: keep what works locally local, send what doesn't, never pretend either is the full answer.
AI & Machine Learning - 05
The bot writes its own resilience
Telegram's long-poll dropped silently after a bad socket and the bot got stuck in a 5-second-retry loop for hours. Fix: AbortController on every poll with a 35 s ceiling, exponential backoff with a 60 s floor, and a debounced undici dispatcher reset that fires on any consecutive failure across both the poll and the localhost forward path. The same dispatcher handles both, so a borked pool can starve both surfaces at once. Now a network blip clears in under a minute without intervention.
Backend Engineering - 06
Vault RAG over the same retrieval index
There's no separate database. The retrieval index is an append-only JSONL file next to the vault: BM25 tokens + 384-dim MiniLM text embedding + 512-dim CLIP image embedding per entry, fused via Reciprocal Rank Fusion. Ask the bot 'what did I save about the SEO trick' and it BM25-plus-cosine-searches the vault, hands the top 4 passages to Ollama as context, and answers with [1] [2] citations. When Ollama is slow it degrades to retrieval-only mode, the user still gets the relevant sources, just without prose. The index can be rebuilt from the markdown at any time; the vault is still the source of truth.
Data Pipelines
Develop · Forks
Decisions on the record.
The few calls worth defending. Each one is a fork; the other branch would have been a different project.
Decision · 01
Why hybrid retrieval, text and image together
Image-dense retrieval catches 'show me other things I've seen that look like this', nothing else in the personal-knowledge-graph space does that. Pair it with semantic-text and keyword search so named entities stay findable, and fuse the three without a weight tournament.
Deliver
What shipped.
Daily driver, now a learning engine too. Capture and the trainer's auto-cards + graded recall are shipped; server-side spaced repetition with Telegram reminders is the active build.
Daily driver as of May 2026. Five capture surfaces (Telegram bot, Chrome extension, iOS share sheet, web PWA, CLI), one /ingest pipeline, every input landing in plain markdown. Voice notes transcribe in 5-15 s on-device; photos perceive in 10-15 s via Cloudflare; URL ingest covers YouTube, Reddit, Wikipedia, Instagram, generic web, and documents. Vault search answers under a second. The bot replies in-thread with the concept it just wrote, then ntfy pushes the deep link. Roadmap from here: Oracle ARM or a small Linux mini-PC as a faster always-on compute substrate, MentraOS app for the wearable-glasses surface (Phase 4), and a personal-voice LoRA fine-tuned on the vault content once there's enough corpus to learn from (Phase 5b).