Skip to content
←Return to Projects
Case Study

KIWI

Autonomous local AI agent and community of voices living in The Grove with private memory.

The Problem

Autonomous AI agents often suffer from leaky memory isolation, unpredictable side-effects on host systems, and lack of human-in-the-loop governance for high-stakes file operations and external device actions.

My Role

Architected and implemented the cognitive engine ("The Grove"), fail-closed host action safety policies, immutable exact-action plan ledgers, multi-device agent companion protocol, and unified multi-channel gateways.

Highlights

  • Community of six voices living in The Grove with local memory running on the user's machine
  • Local cognitive core ("The Grove") separating owner memory from credentialed client sessions
  • Fail-closed security policy requiring immutable exact plans with rollback for all destructive actions
  • DPAPI-secured Windows companion agent with local execution receipts and anti-re-execution guarantees
  • Multi-modal interaction surface: Next.js Web UI, Voice HUD (:4321), and Telegram bot gateway with inline approvals
  • Deterministic audit ledger tracking every state mutation, file movement, and memory association

Stack

TypeScriptNext.js 15Node.jsSQLiteDrizzle ORMDPAPITelegram Bot APIDocker

Constraints

  • Host safety is non-negotiable: no autonomous file deletion or batch reorganization without human-confirmed exact plans.
  • Offline-first engine: core cognitive loops and memory databases must run purely locally without cloud dependencies.
  • Multi-tenant memory isolation: administrative sessions and API token holders must never access the owner private mind context.

System Architecture

Interaction Channels
Next.js 15 Web App (:3333)
Voice HUD (:4321)
Telegram Bot
Embed Bridge (:3234)
Gateway & Protocol
Private Grove API (:8431)
Device Control API
DPAPI Token Auth
Cognitive Engine ("The Grove")
Mind Core
Behavior & Persona
Memory Tiering (STM/MTM/LTM)
Skill Registry
Execution & Safety
Host Action Policy
Exact-Action Ledger
Backup & Rollback Ledger
Distributed Node Runtime
Windows Companion Daemon
Local File Executor
SQLite / Drizzle State

Key Trade-offs

The decisions worth defending — what I chose, what I turned down, and why.

File management execution model

Chose

Immutable two-phase exact-action plans with hash verification and dry-run preview

Rejected

Direct agent tool execution with broad shell permissions

Agents making speculative shell or file modifications risk catastrophic data loss; two-phase plans guarantee human oversight and rollback capability.

Engine-to-web communication architecture

Chose

Dedicated loopback HTTP/SSE gateway with bearer token authentication

Rejected

Monolithic single-process Next.js application

Decoupling the AI engine process from the Next.js frontend ensures background monitoring, telegram polling, and long-running skills survive web redeployments.

Device pairing security model

Chose

Windows DPAPI machine-bound tokens with polling architecture

Rejected

Inbound SSH or remote socket servers on client machines

Inbound listening ports expose clients to local network scans; outbound HTTPS polling behind DPAPI keeps remote companion devices secure.

What I'd Do Differently

An honest retrospective — the stuff I'd change with more time, more users, or a second pass.

  1. 1Implement automated regression tests for memory graph decay sweeps earlier in the development lifecycle.
  2. 2Consolidate SQLite schema migrations between better-sqlite3 and pg-schema under a single unified migration runner.
  3. 3Add fine-grained telemetry dashboards to observe cognitive latency across multi-turn reasoning chains.

Interactive Autonomous Agent Shell

Test live KIWI autonomous agent supervisor routines (agent status, grove ping, mcp tools, help) in the emulated shell below.

icelegends-interactive-shell ~ [kiwi]
History: ↑ / ↓
kiwi@the-grove:~/voices$

Technical Deep-Dive

Architecture, specifications, and implementation details.

SELL-READY — Plan de polish pentru lansarea pe piață

#Actualizare — criterii de lansare ale planului aprobat

Planul P0–P6 stabilește ordinea curentă. Bifele istorice de mai jos nu certifică noile capabilități. Pentru pilotul agentului Windows sunt obligatorii izolarea a două conturi/dispozitive, confirmarea exactă, refuzul, revocarea, reconectarea fără execuții duplicate și instalarea curată. TUI/Telegram se verifică pe același contract de sarcini. Nu prezentați camerele comune sau ISO-ul Linux ca disponibile înainte de acceptarea P5/P6. Prețurile și contractele nu se modifică prin acest plan.

"

Creat 1 sep 2026. Nu este viziunea de produs (vezi ROADMAP.md pentru asta) — este lista de lucruri operaționale / de încredere de bifat înainte ca Kiwi să ajungă în mâinile altora. Ordinea: Blocaje → High → Medium/Low. Bifează pe măsură ce progresezi.


#BLOCANTE — fără astea NU vindem

##1. ✅ Audit de secrete (repo + git history) — CURAT (1 sep 2026)

  • Pattern-uri de chei în istoric (sk-, ghp_, AKIA, AIza, xox, enc:v1): 0
  • Fișiere sensibile track-uite vreodată (kiwi.config.json, .env, auth.json, cloudflared config.yml, .odt): 0
  • kiwi.config.json, web/.env, opencode.json, data/, backups/ sunt corect gitignored.
  • Rămâne pe viitor: rulează gitleaks pe istoric periodic (CI-ul are deja job security).

##2. ✅ Separă config de dev vs. prod-client — GATA (1 sep 2026)

  • web/.env.example rescris complet + comentat, cu ierarhia [PER-INSTALARE] vs [PER-OPERATOR], toate cheile, Stripe activ (LemonSqueezy marcat LEGACY), Cloudflare de rezervă, cron, feature flags.
  • .gitignore întărit: .env.* ignorat, .env.example ⟨reținut⟩.
  • Verificat build: .next NU conține secrete (scanned — OK).
  • Verificat ISO-uri Kiwi OS/*.iso (7 GB): doar media de boot (BOOT/EFI), fără .env/config/DB; ne-track-uite + gitignored. ✅
  • Rămas doar decizia (nu cod): LLM partajat (recomandat) vs fiecare client cheia lui.

##3. ✅ Izolare instanțe (decizie de model, NU automat Docker)

  • Decizie luată (SaaS logic multi-tenant): un singur deploy, brain embedded per-user în web/, motorul PC rămâne owner-only. Vezi secțiunea „Modele de vânzare" de jos.
  • Scopul: instanța unui client să NU aibă acces la datele/cheile altora.
  • Pas 1 (audit, 31 aug 2026): toate tabelele au user_id — găurile reale erau la nivel de rută/executor, nu de schema DB.
  • Pas 2 (fix-uri, 31 aug–1 sep 2026, LIVE):
    • 🔴 OCR: resolveSandboxedPdf — path restricționat la rădăcina documentelor userului; refuză orice escape (resolveInSandbox în docs-storage). (arbitrary file read închis)
    • 🔴 Executori Living Grove: UPDATE grove_dynamic_locations / grove_conflicts cu AND user_id = ?; location-engine scoped pe userId.
    • 🟠 Import grove/export: ownership-check pe project/persona/circle înainte de INSERT.
    • 🟠 Reacții chat: verificare chat_messages.user_id înainte de setReaction (404 dacă străin).
    • 🟡 Pairing Telegram: pairing_expires_at (TTL 15 min), rate-limit 5/min pe chat, doar pending se leagă, cod expirat → regenerare, nu suprascrie link-uri legate.
  • Pas 3 (teste, 1 sep 2026): web/tests/instance-isolation.test.ts — cross-user write isolation (vitality, explore pe locație străină), path sandbox OCR, plus mapare snake_case→camelCase pe grove_resources/grove_biomes (bug latent: max_amount/resource_yield erau citite ca undefined → NaN). test:mind 14 files / 114 tests ✅, typecheck:web ✅, deploy live ✅ (200, migrări aplicate).
  • Rămas (opțional, LOW): rate-limit/quota pe documents/summarize + documents/index.

##4. ✅ Onboarding / setup simplu (1 sep 2026)

  • Deci SaaS cu onboarding ghidat, point-and-click, fără token/tunel/config manual.
  • Wizard post-signup pe 3 pași (/dashboard/onboarding): Bun venit → Telegram BYOB (funcție Pro, upsell la free) → Gata.
  • Coloana users.onboarding_completed_at + migrare idempotentă (ambele scheme sqlite/pg) + helper-e isOnboardingComplete/completeOnboarding/needsOnboarding.
  • API PATCH/GET /api/onboarding (complete_step / complete / status).
  • Gate client-side în DashboardShell (OnboardingGate): userii noi (care n-au atins niciodată app-ul) sunt redirectați la wizard după login; userii activi nu sunt forțați niciodată.
  • Overlay de chat existent (GroveOnboard) rămâne ca rampă de intrare în chat după wizard.
  • Testare E2E automată (1 sep 2026): web/tests/live-e2e.cjs curge flow-ul complet pe cont nou register → verify-sim → login → needsWizard → wizard page → complete_step 1-3 → complete → chat (brain per-user) → telegram gate 403 → izolare cross-user (reacție pe mesaj străin → 404, sesiuni A/B separate). 24/24 checks ✅ live pe kiwi.ice4legends.com.
  • Rămas (necesită om): verificarea REALĂ a email-ului (cod de 6 cifre din inbox) și pairing Telegram REAL (un bot + mesaj /start <code>). Flow-ul API din fața lor e acoperit de simulare.

#Securizarea „LLM cloud partajat" (checkpoint 1 sep 2026)

"

Audit al tuturor rutelor care cheamă LLM-ul cloud pe cheia operatorului (web/.env → KIWI_LLM_API_KEY, api.hcnsec.cn). Scop: niciun user să nu ruleze LLM-ul operatorului fără limită (cost nelimitat = factură explodată).

Confirmat sigur (quota per-user aplicat):

  • ✅ api/chat, api/chat/stream, api/telegram/webhook, api/documents/chat/stream
  • ✅ api/admin/tick — protejat cu CRON_SECRET (intern)
  • ✅ metabolic.ts (declanșează dawn council) — doar prin fluxul de chat cu quota + flag

Găuri reparate (1 sep 2026):

  • ✅ api/grove/agency/intent (GET) — gate pe USE_LIVING_GROVE + checkUsage/consumeMessage
  • ✅ api/grove/agency/agenda (POST run_dawn_council) — idem
  • ✅ documents/summarize + documents/index (1 sep 2026, LIVE) — gaura de quota închisă: ambele rute acum fac checkUsage + consumeMessage (proxy la engine-ul owner-ului e gated pe plan/mesaje, la fel ca chat-ul). Coincide cu decizia de limite finite (vezi §Limite).

Cheia LLM e 100% server-side (toți consumatorii @/lib/kiwi/brain sunt route handlers, zero componente client) — nu e expusă în browser. ✅


#Limite ferme pe planuri (sarcina „limite ferme", 1 sep 2026, LIVE)

  • Nu există nimic „nelimitat". PLANS în web/src/lib/utils.ts:
    • Free: 300 msg/lună, 20 documente · Pro: 10 000 msg, 500 doc · Enterprise: 100 000 msg, 5 000 doc.
    • MESSAGE_LIMITS + ABSOLUTE_MESSAGE_CAP = 200_000 (cap dur de siguranță).
  • planMessageLimit(plan) nu returnează niciodată -1/0 (fallback Free finit, cap la cap absolut).
  • checkUsage — abonament lipsă = Free (finit), NU „unlimited" ca înainte. consumeMessage atomic.
  • checkVoiceUsage — abonament lipsă = Free (fără voice engine); free 0 / pro 100 min / ent 500 min.
  • Sincronizat: register, lemonsqueezy webhook → messagesLimit valid; pricing/landing/FAQ în translations (en+ro) și plan-specs.ts fără „Unlimited messages/memory/embeds".
  • Pagina billing afișează cifra reală (nu mai e logica -1 → ∞).

#Telemetrie opt-in minimală (sarcina „telemetrie", 1 sep 2026, LIVE)

  • Strict opt-in, OFF implicit. Consent în consent_log (telemetry_accept / telemetry_decline).
  • web/src/lib/telemetry.ts: getTelemetryConsent (ultima decizie) + recordFeatureUse (înregistrează feature_used pe usage_events DOAR dacă userul a optat; fără conținut/PII).
  • API: GET/PATCH /api/settings/telemetry (toggle), POST /api/telemetry (raportare).
  • UI: toggle TelemetrySetting în Dashboard → Settings → Telemetry & Analytics.
  • Menționat în Terms (§11) și Privacy (§9).

#Terms / Privacy completate (sarcina „Terms/Privacy", 1 sep 2026, LIVE)

  • Terms: aliniat la limitele reale; secțiuni noi pentru AI-generated content & răspundere, Telemetrie, Termination & Deletion (Art. 17), Governing Law & Jurisdiction.
  • Privacy: corectat local-first reality (subprocesori reali: Stripe, Lemon Squeezy, Resend, Cloudflare, + providerii LLM configurați — NU Vercel/Neon), actualizat retention (2 ani Ent, nu „forever"), secțiuni noi: LLM data flow, Telemetrie, Security (bcrypt/encrypted keys — nu „AES-256 at rest" inventat).

#Pagină demo pentru vânzare (sarcina „demo", 1 sep 2026, LIVE)

  • /demo — landing dedicat de vânzare care arată produsul unitar în 30 sec: ChatDemo live, Grove demo interactiv, OsPreview, mesaj „One product. Three lives." (dev tool + ecosistem în buzunar + învățare continuă), pași „start în sub 2 minute".
  • Link „Live demo" adăugat în navigarea landing (en+ro).


#Operațional prioritar (HIGH)

##5. Alege UN use-case principal de vânzare

  • Proiectul e foarte bogat (monitoring + documente + agent dev + Living Grove + Arhiva Grove). Pentru vânzare, alege focusul și ascunde restul.

##6. Reactive la „prinde"

  • VM mc (192.168.254.128) e JOS acum — găsește și pornește.
  • Adaugă cheia SSH în config vm_control (momentan fără key; SSH dă timeout).
  • Calibrează balance-ul de outreach după testul pe useri reali.

##7. Value demo / landing care arată CE face în 30 sec

  • Screenshot cu /diag, /docs, alerting. Fără asta nu convingi.

##8. Commerce: pricing + licențiere + Terms/Privacy

  • Licență, termeni de folosire, politica de date.
  • Decizie: open-source vs. closed.

#Polish final (MEDIUM/LOW)

##9. Ghid de securitate pentru client (extinde SECURITY.md)

##10. Teste E2E pe flow-ul Telegram (nu doar unit)

##11. Branding consistent pe tot (Papa Ko / Grove / Kiwi — deja solid, extinde web)

##12. Telemetry/analytics opt-in (vezi cum folosesc clienții)

##13. i18n decis — o limbă primară (acum amestec RO/EN în mesaje)


#Modele de vânzare (decizie cerută)

  1. SaaS cu cont — userul se loghează, nu instalează nimic. Docker e doar intern (izolare), NU visible userului. Onboarding simplu.
  2. Self-hosted — userul îl instalează. Docker e prea tehnic pentru userul normal → alternativ: installer one-click sau VPS preconfigurat.
  3. Hibrid — open-core: engine self-hostable + web SaaS.
"

Întrebarea-cadru: „o să-mi acceseze cineva datele mele?" — se rezolvă în principal prin izolarea instanțelor (modelul de vânzare) + auditul de secrete ✅.


#Status actual

  • Blocaje: 1 ✅ · 2 ✅ · 3 ✅ · 4 ✅
  • Securizarea LLM cloud partajat: agency ✅ · documents summarize/index ✅ (gaura închisă)
  • Limite ferme pe planuri: ✅ LIVE (fără „nelimitat", cap absolut 200k)
  • Telemetrie opt-in: ✅ LIVE (OFF implicit, feature_used doar pe consent)
  • Terms/Privacy completate: ✅ LIVE
  • Pagină demo /demo: ✅ LIVE
  • High: #5·#6·#7·#8 — neîncepute
  • Medium/Low: #12 telemetrie fiind făcută ✅; restul neîncepute
~ End of Document ~