Why I built it
I run several ventures alongside a full-time applied-AI role, and several client engagements at a time on top of that. At some point this year I noticed I could not reliably answer a simple question about my own work: what actually happened last week, and what did I decide, versus what I remembered deciding. Status reports drift from the work they describe. Memory drifts faster than status reports. What I needed was something that recorded the event once, at the moment it happened, and never let a downstream view fall out of sync with it.
That is the whole idea behind Astram (அஸ்திரம், "weapon" or "armament" — the arsenal itself): one append-only event log, and every tracker, board, and cockpit view I look at is derived from that log. Nothing is hand-edited. If a number on a dashboard is wrong, the fix is never to edit the dashboard. The fix is to find the event that is missing or wrong, correct that, and re-derive the view from it.
One event, one coordinate, no free text
Every event in the log carries two coordinates.
- A (process, step) pair, foreign-key-enforced against a table of processes and process steps, so an event has to belong to something real rather than a free-text label that can drift into six different spellings of the same status.
- A (type, subtype) pair, foreign-key-enforced against a closed, sixteen-value enum: assumption, blocker, contention, decision, delivered, finance, focus, meeting, note, received, risk, shipped, signal, snooze, status-update, wonder.
The second one is the part I would defend hardest. A free-text status field is comfortable, and it lies by omission — nothing stops "status: mostly done" from meaning six different things across six projects. A closed enum forces every event into one of sixteen honest buckets before it is allowed to exist at all. As of my last direct count against the table, zero events sit with an unresolved coordinate. Not "most." Zero. That is exactly the kind of claim I would want to check narrower than its name before believing, and here it holds up — every row is coordinate-resolved, not scaffolding waiting to be typed later.
By August 2026 that table held more than 6,900 events. The count only grows day to day, so I would treat any number I give you here as a floor on the day I measured it, not a live figure.
Five lenses, one stream
The interesting design decision is not the log itself — append-only event logs are not novel. It is that every view I actually work from is a different altitude on the same stream, not a separate silo holding its own copy of the data.
- Dhinam (தினம், "the day") — the live cockpit: today's calendar, the day's activity feed, open contentions, gaps needing attention. This one is deliberately not a sixth lens sitting alongside the other four on equal footing — it is a filtered slice of "right now," the way a dashboard widget surfaces a database without becoming a new kind of table.
- Thittam (திட்டம், "the plan") — governance. What is happening and when. Every material event lands here first, and trackers, portfolios, and gate decisions are all rendered off this lens.
- Iyanthiram (இயந்திரம், "the machinery") — execution. How the work actually gets done, across six departments — engineering, sales, marketing, vendor procurement, finance, measurement — each running its own loop and reporting events back up into the plan.
- Viyugam (வியூகம், "strategy," closer to "formation") — why, and toward what. Values, long-horizon direction, the goals everything downstream is supposed to serve.
- Thottam (தோட்டம், "the garden") — synthesis. Where patterns get precipitated out of lived work and hardened into principles, feeding back into strategy and into how the machinery builds next.
Five ways of reading one stream, asking five different questions — why, what and when, how, what did we learn, and what is true right now. None of them owns a private copy of the data. That is the property I actually wanted: no drift between what is stored and what is shown, because there is only one thing stored.
What derive-never-hand-edit actually costs
I would rather state the cost plainly than let the design sound free.
Deriving every view means the tooling that builds each one has to run correctly, every time, on every machine — and that is a harder bar than it sounds. One installer in the arsenal still references a starter file set that drifted out from under it: it expects five files to exist and only two of them do on a fresh checkout. That installer runs first in an unconditional chain, so on a clean machine today it fails outright, and several other components never install behind it. I found this while testing something unrelated, and it had been silently true for long enough that nobody had run a genuinely fresh install to notice.
I am not including that as a show of humility. It is the actual shape of the tradeoff: a system with one source of truth is only as good as the tooling that keeps deriving views from it, and that tooling needs the same maintenance discipline as the log itself. When the discipline slips, the gap does not show up as a wrong number on a dashboard — it shows up as a step that silently never runs at all.
What I am not claiming
The storage layer is migrating from Markdown files to Postgres. Markdown was the original system of record; as the arsenal has grown past what plain files can serve well, I have been moving write authority to a database. I am not going to tell you that migration is finished, because my own documentation and my own recent engineering notes disagree with each other about exactly that point, and I only noticed the disagreement while writing this piece. One source says Markdown is still authoritative and Postgres mirrors it. A more recent note says the cutover has already happened. I have not resolved which is current, and picking whichever version reads better here would be precisely the mistake the whole system exists to prevent — a report that outruns the effect it describes, the kind of gap I would only trust after running a second measurement, not before.
If you are building something like this yourself, plan for that seam to stay uncomfortable longer than you would like. A live storage migration and a clean narrative about your own architecture rarely finish on the same day.
What I do now
- Every session that touches project files ends with a logged event before I call it done — not optional, checked.
- I verify a claim about the log by reading the log itself, never by reading a tool's printed message claiming it wrote something.
- I keep the sixteen-value enum closed. If a new kind of event does not fit, that is an argument for a seventeenth value, not for a free-text escape hatch.
- I treat any count I quote from the log as a floor from the day I measured it, and I say so, rather than let it read as current.
- I regenerate a dashboard when it is wrong. I do not hand-edit one, ever, no exceptions, even under deadline pressure.