Plan — bahalaka + Nous Integration
Nous IS the backend. Every feature is triples. Every message is an atom. Firebase goes away.
The Insight
Everything Is a Triple
Nous stores facts as {subject, predicate, object}. Every bahalaka feature — chat, status, schedule, finances, agreements, stories — is just triples in a store. The wire protocol moves them. The journal makes them permanent. The reasoning engine detects patterns across them.
No new database. No new protocol. No new auth. Nous already has all of it.
Data Model — Everything as Triples
Chat
{msg:a1b2, from, user:joey}
{msg:a1b2, to, user:maria}
{msg:a1b2, text, "kumusta ka?"}
{msg:a1b2, time, 1712345678}
{msg:a1b2, sig, ed25519:abc123...}
Forward-only: no delete triple. Edits create new triples with {msg:a1b2, edit:1, "kumusta ka na?"} — original preserved.
Status
{user:maria, status, at_home}
{user:maria, status_time, 1712345678}
{user:maria, location:home, geo:14.5995,120.9842}
GPS auto-matches registered locations. Status transitions journal-logged.
Finances
{allowance:001, recipient, user:maria}
{allowance:001, amount, 5000}
{allowance:001, cycle, weekly}
{allowance:001, withholding, 1000}
{disbursement:042, allowance, allowance:001}
{disbursement:042, net, 4000}
{disbursement:042, date, 2026-04-04}
{disbursement:042, sig, ed25519:def456...}
Balance = computed sum of all disbursement + withdrawal triples. The ledger is the truth — no mutable balance field.
Agreements
{agree:001, her_ask, template:1}
{agree:001, his_dec_1, template:III}
{agree:001, his_dec_2, template:A}
{agree:001, sig_her, ed25519:aaa...}
{agree:001, sig_him, ed25519:bbb...}
{agree:001, signed_at, 1712345678}
{agree:001, cooling_start, 1712259278}
Dual-signed, 48-hour cooling period enforced by timestamp math. Forward-only — new agreement supersedes, old stays.
Concern Detection — reason.c
{concern:c01, type, promise_ratio}
{concern:c01, user, user:maria}
{concern:c01, kept, 2}
{concern:c01, total, 6}
{concern:c01, confidence, 0.78}
The nous reasoning engine walks the journal graph, counts patterns, scores confidence. Same engine that reasons over knowledge — now pointed at relationship data.
Architecture
The Flow
- Client (browser/Capacitor)
Vanilla HTML/JS + C→WASM (wire.c + crypt.c)
User types a message → JS calls WASM → WASM packs atoms, encrypts with AES-256-GCM, signs with Ed25519 → sends to relay via WebSocket
- Relay (relay_server.c — already running)
Authenticates the connection (HMAC + nonce + session token)
Forwards encrypted atoms to the user's prime
Never decrypts. Never reads. Stores noise.
- Prime (catalog_server.c — already running)
Decrypts with user's transport key
Unpacks atoms → stores as triples in user's encrypted store
Runs concern detection via reason.c on schedule
Pushes notifications back through relay
What Changes on Nous
- New endpoint on Prime:
/bahalaka — handles app-specific atom verbs (chat, status, schedule, finance, agree, declare)
- Per-user encrypted stores: each bahalaka user gets their own triple store on the prime (already supported by store.c — just a different path per user)
- WebSocket on Relay: relay_server.c currently does raw TCP. Add WebSocket upgrade for browser clients (thin wrapper — WS is just framed TCP with a handshake)
- Concern cron: scheduled reason.c walks across user stores for pattern detection
What Dies
- Firebase/Firestore — replaced by nous triple store. Comments migrate to triples.
- Cloudflare Workers proxy — no longer needed. Client talks directly to relay.
- API keys in client code — gone. Auth is Ed25519 + session tokens.
C → WASM Strategy
What Compiles to WASM
wire.c — atom pack/unpack (no I/O deps, pure data transform)
crypt.c — Ed25519, AES-256-GCM, SHA-256 (no platform deps)
journal.c — local append-only log (IndexedDB backing via JS)
store.c — local triple store for offline cache (IndexedDB backing)
policy.c — client-side rule enforcement
What Stays Server-Side C
relay_server.c — TCP/WebSocket forwarder (runs on Linux VMs)
catalog_server.c — prime with /bahalaka endpoint
reason.c — concern detection runs on prime (needs full store access)
auth.c — session management on relay (server-side only)
acquire.c — stories/field guide content acquisition
Emscripten Build
- Target:
libbahalaka.wasm + libbahalaka.js (glue)
- Exports:
wire_pack, wire_unpack, crypt_encrypt, crypt_decrypt, crypt_sign, crypt_verify, crypt_keypair, journal_append, store_insert, store_query
- Memory: WASM linear memory for crypto ops, JS↔WASM data copying via shared ArrayBuffer
- I/O shim: Replace mmap/fopen with IndexedDB callbacks (Emscripten IDBFS or custom)
Build Phases
Phase 1 — WASM Foundation ~2 weeks
Prove C runs in the browser via nous modules.
- Emscripten toolchain setup + build script for wire.c + crypt.c
bahalaka.js bridge: keypair generation, sign/verify, encrypt/decrypt, atom pack/unpack
- Local journal + store via Emscripten IDBFS (IndexedDB-backed)
- Auth page: TOTP login → session token from relay
- Demo: generate Ed25519 keys in C/WASM, pack an atom, encrypt it, send to relay, get response — all from the browser
Phase 2 — Relay WebSocket + Prime /bahalaka ~2 weeks
Server-side changes to accept browser clients and handle app atoms.
- WebSocket upgrade in relay_server.c (RFC 6455 handshake, frame decode)
/bahalaka endpoint on prime — routes app verbs to per-user stores
- Per-user encrypted stores on prime (path:
/data/bahalaka/{user_id}/)
- User registration flow: keypair → relay auth → prime creates store
- Connection pairing: provider links to connected person via signed invite atom
Phase 3 — Chat ~3 weeks
Forward-only messaging over nous wire protocol.
- Chat UI: vanilla HTML/JS, dark theme, mobile-first
- Message flow: type → WASM packs atom + encrypts → WebSocket to relay → prime stores triple
- Receive: prime pushes atom via relay → WASM decrypts + unpacks → JS renders
- Forward-only journal: no delete, edits preserve original, all signed
- Read receipts + typing indicators (atom verbs:
read, typing)
- Offline queue: WASM encrypts + stores locally, sends on reconnect
- Photo + voice: binary atoms with type metadata
Phase 4 — Status + Schedule ~2 weeks
Asymmetric visibility. Geo-verified presence.
- Status atoms:
{user, status, location_type} with GPS verification
- Capacitor GPS plugin for auto-matching registered locations
- Provider dashboard: query prime for all connections' status triples
- Schedule: time slot triples, request/approve/decline flow as atoms
- Isolation: prime enforces — connection A's queries never return connection B's data
Phase 5 — Finances ~3 weeks
Allowance, savings, sponsorships. Ledger = journal triples.
- Financial atoms: allowance, disbursement, savings, withdrawal, sponsorship, sponsor_request
- Balance computed server-side by summing journal triples (no mutable field)
- Sponsorship lifecycle: created → accepted → active → semester proof → renewed/suspended
- Grade proof: photo upload as binary atom via relay
- Financial dashboard: provider view + connected person view, queried from prime
Phase 6 — Agreements + Concern Detection ~3 weeks
Templates, promises, dual signatures. reason.c for pattern detection.
- Agreement templates stored as triples on prime (7 + 7 + 3 = 147 combos)
- Template selection → 48-hour cooling → dual Ed25519 signature → sealed
- Mismatch detection: policy.c checks her_ask vs his_dec before signing
- Promises/commitments: declare atoms with optional deadlines, tracked by prime
- Concern detection: scheduled reason.c walk — promise ratio, request frequency, status conflicts, edit frequency, response asymmetry
- Provider-only concern dashboard: query prime for flagged patterns
Phase 7 — Stories + Ship ~2 weeks
Field guide. Onboarding. App store. Friends-first launch.
- Stories engine: curated content as triples, tagged, searchable via reason.c
- Contextual suggestions: when concern pattern detected, surface relevant story
- Onboarding: key generation, identity creation, first-week story set
- Capacitor → iOS + Android build
- Friends-only invite codes (signed atoms)
- Migrate proposal site comments from Firestore → nous triples
Summary
What This Means
- Zero new backend infrastructure — nous relay + prime are already running in 3 regions
- Zero new database — triple store is the database
- Zero new auth system — Ed25519 + TOTP + sessions already exist
- Zero new wire protocol — NTRP0001 carries everything
- 3 server-side changes: WebSocket on relay, /bahalaka endpoint on prime, per-user stores
- Client: C→WASM + vanilla HTML/JS + Capacitor (same as previous plan, now connected to nous)
- Concern detection: reason.c — the graph-walking reasoning engine already built for knowledge queries, now pointed at relationship data