NXSelf
A reporting service where the numbers are computed and only the sentences are generated.
2026 · Solo build — the data model, the privacy design, and the generation boundary.
The problem
Generated reports are useful right up until someone checks a total and finds it wrong. A model asked to both count and explain will occasionally do neither reliably, and a confident wrong figure is worse than no report.
What it does
A service that splits the two jobs cleanly: arithmetic is deterministic, prose is generated. Counts, totals, rates, cadence and state transitions are computed in code with no model call; the model receives settled state and turns it into language.
Engineering decisions
Arithmetic is deterministic, prose is generated
Every number in a report is computed before any model is involved, and the model sees the finished state plus a bounded sample of evidence. It can phrase things badly; it cannot get a total wrong. Drawing that line early is what makes the output trustworthy enough to send to anyone.
The identifier is a hash, and the phone number is never the key
Records are joined across sources on a phone number, which makes it the most sensitive value in the system. The subject identifier is a keyed hash of the normalized number; the recoverable value is encrypted separately. Raw numbers are never database keys, log values, URL parameters, or model input — so a leaked log or a stored prompt doesn't leak a contact list.
A closed action space that won't compile if it grows
Classification runs against a fixed set of action types, and adding a new one fails the build until it's handled everywhere. That's deliberate friction: an open-ended category would quietly absorb anything unfamiliar and report it as normal.
Where it landed
- Report totals are verifiable, not model-generated
- No raw phone number in any key, log, URL or prompt
- New categories can't be silently absorbed — they break the build first