JANE
A personal AI operating system. Deterministic workflows, append-only audit logs, voice UI.

TL;DR
- Audit-first: append-only log, no record mutation or deletion.
- Deterministic workflows via Inngest — no ad-hoc LLM calls.
- Memory layer: Postgres + pgvector, inspectable + deletable.
- Voice & multi-party calls with hierarchy-aware handoff.
- Type-safe end-to-end with Drizzle + Zod.
Architecture
Modular monolith. Strict service boundaries. Every state change funnels into the append-only audit log.
Problem
Most personal-AI projects fail a basic safety bar: they can take consequential actions without showing their work, retain unbounded memory, and call LLMs ad-hoc with no audit trail. The result is software you have to fully trust before you can use — which is exactly backwards.
Approach
JANE is a modular monolith with strict service boundaries. Sensitive actions require explicit approval gates. Memory lives in Postgres + pgvector — inspectable, deletable, with no magic recall. Workflows run on Inngest so every step is deterministic and replayable. Voice and multi-party calls are first-class, not bolt-ons.
Deep dive
Why a modular monolith (and not microservices)
Microservices push complexity to the network. A solo-built personal OS doesn't have the ops budget for that. The modular monolith gives strict boundaries via packages and type signatures without paying the deployment-topology cost. If a service ever needs to break out, the interface is already drawn.
Append-only audit log as a design constraint
Once you commit that no record may be mutated or deleted, a surprising number of design questions answer themselves. Memory becomes a derived view. Permissions become attestations. Bugs become forensics, not mysteries.
Determinism via Inngest
Every workflow step is a function with explicit inputs, outputs, retries, and idempotency keys. LLM calls happen inside steps, never at the top level. Replay a workflow with the same inputs, get the same result — or a deterministic divergence point.
import { inngest } from "@/lib/inngest";
export const dailyReview = inngest.createFunction(
{ id: "daily-review", retries: 3 },
{ cron: "0 8 * * *" },
async ({ step }) => {
const entries = await step.run("fetch-entries", () =>
db.select().from(journal).where(eq(journal.date, today())),
);
const summary = await step.run("summarize", () =>
llm.complete({
prompt: buildPrompt(entries),
idempotencyKey: `summary:${today()}`,
}),
);
await step.run("audit", () =>
db.insert(audit).values({
action: "daily-review",
payload: { count: entries.length },
}),
);
return { summarized: entries.length };
},
);Outcome
Production MVP. Voice UI, multi-party agent 'board rooms', append-only audit log, day-0 onboarding path (OB-01 through OB-09). Built as a personal OS, designed so anyone could fork it without trust assumptions.
Related


