Case Study

Noema

A second brain for a business — a digital one. Not a notes app that waits to be read, but a system that keeps its own documentation current, watches the real numbers behind every project, and comes back with conclusions and growth moves.

Back to Projects
Status
In Use · Running Weekly
Role
Solo Builder — Product, Architecture, CLI & Data Engineering
Stack
TypeScript on Node 22 · No npm dependencies · GitHub, Vercel, Supabase & RDAP APIs · Claude · Swift wrapper
The Problem

Two categories of tool, and the gap between them

Anyone running several projects at once spreads the truth about them across files, Notion, spreadsheets and chat threads, with no unified picture. The tools that exist split cleanly into two camps, and neither one closes the gap.

Knowledge tools — Obsidian, Tana, Capacities — are excellent at documenting and linking ideas, and completely passive. They never read the actual numbers behind the business, so the documentation drifts out of date the moment you stop hand-feeding it. AI business tools analyze data well, but they aren't built as a brain: no living graph of how projects, decisions and assets connect, and no memory of what this business looked like three months ago.

A small business can't build the missing middle itself. It needs something it can adopt.

The Idea

A second brain that reads itself

Noema is the digital second brain for a business. The name is Greek — noema, "the object of thought" — which is exactly the job: the place where thinking about your business actually takes shape, instead of the place where notes go to get stale.

Three layers make that work, and the third is the one that separates it from a notes app:

The end goal is a product other small businesses can adopt — each with its own vault the system watches — rather than a tool that only works for me.

Architecture

Five commands, six sources, zero dependencies

Noema is TypeScript executed directly by Node 22 — no npm install, no build step, no dependency tree at all. That was a locked decision, not an accident: a brain meant to outlive the projects it tracks, and to eventually be installed at someone else's business, can't itself be a maintenance liability.

It's also deliberately not always-on. The sync and the weekly report run once a week, growth recommendations once a month; nothing listens in the background, and there is no database and no server. A brain that thinks on a schedule costs almost nothing to keep, which is what makes handing it to a small business realistic.

Five commands — scan, report, dashboard, recommend, idea — read from six live sources: GitHub repositories, the Markdown vault, the local project folders (structure only, never file contents), Vercel deployments and attached domains, public RDAP for domain registrar and renewal, and Supabase for each project's database status.

Tokens are read-only and come from the environment or, failing that, from the credentials the gh and vercel CLIs already hold — nothing new to store. They are never written to a log, a snapshot, or the dashboard, and a missing token degrades the scan instead of failing it. The dashboard command emits a single self-contained HTML file that opens straight from disk: no server, no framework, no network request.

TypeScript · Node 22 Zero dependencies GitHub API Vercel API Supabase RDAP Claude (phrasing only) Swift (macOS wrapper)
Design Decisions

In the report, the model phrases. It does not infer.

A brain is only worth consulting if you can trust what it tells you, so the two jobs are separated strictly. In the weekly report, every finding is produced by deterministic code; the language model's only job is to turn those finished findings into readable prose and add a short opening paragraph — it never searches for findings and never adds one. Three guardrails hold that line:

There is also no numeric score per project — a single number invites you to optimize the number. Each project gets a state and a bottleneck instead. Hand-written files are never overwritten, and the data directory is never deleted.

The Brain

Where it does get to propose — and what fences that in

Recommendations are the one place the model genuinely reasons rather than rephrases, so that layer is built to fail safe. Underneath it sits a deterministic base derived from the findings, which costs nothing and always works; the AI layer is a single call returning JSON against a fixed schema. If the CLI isn't present or authenticated, the deterministic recommendations are written anyway and the command doesn't fail.

Structured outputs guarantee shape, not substance. When reasoning ate the token budget, the JSON came back well-formed with empty strings in the fields that hadn't been filled — and an empty goal was nearly written into the vault before it got caught. Every response is now checked for fields that are actually populated, not merely present, with a retry at double the budget.

The output is a living checklist inside each project's vault folder, and the ownership rule is one-directional: you tick the boxes in Obsidian, the dashboard only reads them. Your checkmarks are merged and never overwritten, hand-written items survive, and anything already on the list is shown to the model so it doesn't repeat itself. There's a hard cap of eight open items per project — without it, a weekly brain reliably grows a pile nobody opens. Each run also commits to a single focus sentence: one decision about what matters this week, at the top of the dashboard.

The Data

Snapshots are the part you can't rebuild

Every run appends a dated JSONL snapshot of every item, link, and event. Diffing each run against the previous one is what produces the events that actually matter — went_quiet, resumed, disappeared — none of which any single API can tell you, because they only exist as a change over time.

That makes the snapshot directory the one irreplaceable artifact in the project: everything else can be regenerated by rescanning, and history cannot be rescanned retroactively. It's treated accordingly, and the constraint is written into the codebase rather than remembered.

Challenges

Knowing what a free tier actually gives you

Traffic measurement is built and tested, and deliberately switched off. Every analytics provider evaluated gates the read API behind a paid plan — Umami behind Pro, Plausible behind Business, Vercel not exposing one at all — so rather than pretend, the integration ships inert, returns null everywhere, and is documented as unwired with the free alternative named for when it's revisited.

The open problem is profit and loss, and the hard part isn't the API — it's attribution. A hosting invoice doesn't know which project it belongs to. Rather than guess and produce numbers that look authoritative and aren't, that feature stays gated behind a concrete precondition: one project with real revenue.

Result

Proving itself on my own business first

Noema runs weekly against my real projects and has been accumulating snapshots since it went into use — every project on this page lives in its vault, including this site. It ships a small Swift wrapper so it opens as a macOS app instead of a terminal command, and a self-contained dashboard with a screen per project and a live relationship map that replaced a hand-maintained diagram, because a diagram you have to remember to update is out of date the moment you add a repo.

That's the deliberate first stage: prove the brain on my own data before installing it anywhere else. The path from here is a vault per business and a subscription around it — but that step is gated on this one working, which is why the current version is aimed squarely at a business of one.