AI without a system of record is just chat

AI without a system of record is just chat

I went digging into one of my streams a while back, a deadline maybe three weeks out, and found there was nothing tight behind it. No dated record of what had been agreed, no tracking against the date, just a lead who thought it was probably fine. It probably was fine. What bothered me was that I had no way of knowing without having the conversation, and I had around ten streams live at the time, so the same question applied another nine times and I could not afford to ask it another nine times.

The obvious read is that this is a capacity problem, and the fix is more people or more of my own time on delivery. I've come to think that's wrong. Doing this job well means two things: time-sensitive work moves on time, and I hold full situational awareness across every stream including the ones nobody has asked about this week. The first is visible and gets attention. The second degrades silently, and both failures I care about are symptoms of the same thing, which is that state lives in people's heads and in meeting audio rather than in a system.

I used theory of constraints as the lens when I built Sonde, and it applies just as cleanly here. The constraint is not delivery throughput, it is awareness: the rate at which what is true across ten streams can be collected, reconciled and made queryable. Every hour of extra delivery capacity added upstream of that constraint just produces more state that nobody can see. Most writing about AI at work optimises for generation, which is why it doesn't stick. The valuable automation is unglamorous, and it looks like sweeping, summarising, deduplicating and writing back.

What I tried first

Three things, in order, and all three failed for the same reason.

Sitting in a Claude window and asking was first. Every session starts cold, I re-supply the context by hand, the output is good and the retention is zero. Net effect on awareness after a few months: nil.

Meeting summaries were next. The volume of summaries becomes its own backlog, and a summary that isn't linked to a stream, a task and a decision is just a shorter recording. I had a folder of them and never read one twice.

Notes discipline by willpower was third. That works for about two weeks and does not survive a heavy week, which is precisely the week it needs to survive.

In all three cases the intelligence was fine and the state was missing. I wrote about AI operating systems as an idea eighteen months ago and the part I underweighted then is the boring part, which is where the state goes and who writes it.

Four layers

The thing I ended up with has four layers, and each only makes sense given the one below it.

The system of record is Notion, with four related databases. Daily notes, one page per day, which is the append target for everything that happens. Tasks, with assignee, reporter, status, due date, source link and a relation to a project. Meetings, one page each, with summary, actions, attendees by role and relations to projects. Projects, the canonical page per stream, holding current state, this week, an activity log, a decisions log, milestones, owner and a last-swept watermark.

The relations are the whole value. A task with no project relation is orphaned data, a meeting with no project relation cannot roll up, and enforcing relations at write time turned out to be most of the work. Every page is also designed to be read by an agent rather than only by a human, which means stable section headings, predictable structure and dated entries. Prose-only pages are unusable as machine state. The workspace stays the interface of record for humans too, because if the humans and the agents read different sources they will eventually disagree, and the humans will win and the system will die.

Connectors sit underneath: Slack, mail, calendar, documents, meeting transcription and a ticketing system. Slack is the one that matters most and the one I underestimated. Almost everything gets agreed there before it gets agreed anywhere formal, a scope change lands in a thread, a dependency gets accepted in a reply, a date moves in a message nobody thinks to write up, and the context that explains why a stream looks the way it does is sitting in a channel rather than in any document. State originates in Slack and in meetings, not in the tracker, and any system that expects people to type state into a tracker is fighting the grain of the organisation. Connectors are also where the reliability problems live, since the wrapper around an API frequently renames parameters and reshapes responses relative to the documented API. I now probe the actual response shape once before building anything on top of it, and build the parser against what I observed rather than what the docs implied.

Skills are the third layer, written procedures the agent loads on demand, and they're the highest-leverage part of this by a distance. Scheduling is the fourth: time-based runs for the loops that must happen whether or not anyone remembers, phrase-based triggering for on-demand work, and in-flow triggering where a trigger phrase written into a Slack message gets swept up later and processed, with an emoji reaction acting as both receipt and dedupe key. That last one is worth dwelling on, because it lets capture happen at the moment of thought, in the tool I already have open, with reconciliation happening asynchronously.

State lives in the workspace, connectors pull from where work actually happens, skills encode how each job is done, and schedules make it happen without me. Remove any one layer and the whole thing degrades back to chat.

Skills are software, not prompts

The difference between an assistant that is occasionally useful and a system I actually rely on is not model capability, it is whether the procedure is written down. A skill specifies when to trigger, what to gather, how to decide, what to write and what to never do. Once it's written it runs the same way every time, by anyone, and it can be reviewed and improved like code. Prompting is issuing an instruction, a skill is shipping a function, and almost everything interesting follows from taking that analogy literally.

One writer per table. Four different loops need to create tasks: meeting sync, end of day shutdown, inbox triage and the morning briefing. Early on each one did its own thing, and the result was four subtly different task formats, inconsistent deduplication, three different due-date conventions and relation links formatted three ways. The fix was a single canonical task-writer skill that owns the entire write contract, covering deduplication against existing tasks, assignee and reporter routing, project matching, due-date policy, visibility and relation URL formatting. Every other loop does extraction only and hands over a context bundle. Changing the due-date policy is now a one-file change instead of a four-file change, the deduplication logic exists once so it's actually good rather than four times mediocre, and any new loop that needs to create tasks inherits correctness for free. This is exactly the argument for extracting a shared module, and it's worth saying so plainly, because most people don't yet think of agent procedures as software.

The mechanism that makes it enforceable rather than aspirational is invocation by reference. A calling skill doesn't reimplement the writer, it says create this via the task-writer with this bundle, and the agent loads and follows that procedure. It's composition without duplication, and it's the same instinct behind agents and subagents in Claude Code, applied to procedures rather than to context windows.

Descriptions are routing, not documentation. A skill's description determines whether the right procedure fires when a request arrives in whatever phrasing it actually arrives in. I write descriptions as lists of real trigger phrases including the lazy ones, because nobody says "execute the meeting notes synchronisation workflow", they say "do my notes". Adjacent skills need explicit boundaries or they cannibalise each other, so one of my two prose-editing skills says outright that it isn't for cutting exec comms to the bone and names the sibling that owns that job. The negative clause does as much routing work as the positive ones. Bad routing is worse than a missing skill because it produces confident output from the wrong procedure.

Everything must survive being run twice. Scheduled agents are distributed systems with at-least-once delivery, and if you don't design for duplicates you will drown in them. Each project page carries a last-swept timestamp with a freshness guard that turns a redundant run into a no-op, which means several people can run the same sweep on the same morning without duplicating anything. Emoji reactions on Slack messages work as receipt and dedupe key at once, visible to humans and queryable by machine, and they live on the source object rather than in a side table. Deduplication happens again at task-write time. The onboarding procedure that creates a new person's databases and config row is written to be safe to re-run, because anything a human might run twice will be run twice.

Scale by marking not-applicable, never by skipping. My research procedure has to handle both a trivial add-on request and a full platform evaluation. The tempting design is to let the small case skip sections, which is wrong, because the outputs stop being comparable and comparability is most of the value of a template. Every output carries every section, and small cases mark sections explicitly not applicable. An empty section should be visibly a judgement, not an omission.

Resist the mega-skill. Two separate skills operate on a draft, one that makes it sound like me and one that cuts it to the bone. They have different inputs and different failure modes and I need them in different combinations, so a single "improve this draft" skill would do both averagely and be uncontrollable. One procedure, one job, composable.

The voice skill only works because I wrote the specification from real samples of my own writing rather than from adjectives. "Direct and warm" is not a specification. A list of constructions I never use is, and the banned list does more work than any amount of description.

Team mode falls out of the same design. Skills read the running user's identity and anchor contacts from a config database rather than hard-coding a person, so anyone can run any skill and get their own scope, and access control is inherited from the underlying tools rather than reinvented. Each person's sweep sees exactly what that person could already see, and nobody needs a god-mode credential. That's the difference between a personal hack like OpenClaw, which I built for myself on a cheap droplet, and something a team can adopt.

A day in the loop

The briefing runs early on weekdays and reads the calendar, open tasks, project pages as refreshed by the overnight sweep, overnight mail and Slack, and yesterday's handoff block. It writes into today's daily note and posts a summary back into Slack: what matters today, what moved overnight, what is at risk, what needs a decision. It also doubles as a daily integrity check, because if the briefing is thin the record is stale, and that is itself information.

Meeting prep follows, filtered through a skip list of recurring meetings that never need it. The skip list matters far more than it sounds, since prep for everything is noise and noise gets the whole section ignored.

Meeting notes sync is the main intake valve and usually runs at the end of the day. Transcripts come in, a summary per meeting goes into the daily note, action items are extracted and written as tasks through the single writer, and project pages get updated where a meeting contained a material change of state. A decision made verbally at two in the afternoon exists as a linked, queryable record by six.

Task enrichment searches Slack, mail and the workspace for the latest activity on every open task and proposes dated context updates and status changes. Tasks with no activity anywhere get flagged as zombies, which is the pruning mechanism. Review happens five tasks at a time, and the batch size is deliberate: large batches get skimmed and rubber-stamped, which destroys the value of the approval gate entirely.

Shutdown runs late afternoon over today's transcripts and, importantly, my sent Slack messages and mail rather than received ones, because outbound is where commitments live. It captures anything I promised in passing, reports slippage against this morning's stated priorities, and writes a handoff block for tomorrow.

The nightly sweep reads each project's Slack channels since that project's watermark and rewrites current state, this week, activity and decisions. A separate weekly pass on Sunday owns the destructive work the nightly pass deliberately skips: pruning, structural cleanup, zombie project detection. Nightly is high-frequency and additive, weekly is low-frequency and destructive, and mixing them is how automated systems either never clean up or clean up something they shouldn't have. Same reason you separate a fast append path from a slow compaction pass.

None of these loops is impressive alone. The value is that each one's output is another's input, so shutdown writes the handoff the briefing reads, the sweep refreshes the pages the briefing and the weekly update read, and meeting sync feeds the activity log the sweep promotes into decisions. It's a pipeline, and the throughput is set by the weakest stage.

Nothing sends

No mail, no Slack messages, no calendar invites. Anything leaving the building is prepared as a draft for me to place. Filing to shared records proposes and waits for explicit per-item confirmation, and confidentiality triage happens before anything is proposed, because some correspondence belongs in a shared project record and some must stay private.

The reasoning is arithmetic rather than timidity. The failure mode of autonomous outbound comms is unrecoverable, you cannot un-send, and an asymmetric downside justifies a confirm step that costs seconds. The consequence I'll admit to is that I remain the bottleneck on every write path that touches another person, which caps how much of this can ever be automated. That ceiling is a choice, not a technology problem.

What broke

Trigger collision came first, two skills with overlapping descriptions, the wrong procedure firing and producing confident, well-formatted, wrong output. Explicit negative clauses in the descriptions fixed it.

Mega-skills came next, one skill doing extraction, decision-making and writing, impossible to test and impossible to reuse, where every change risked all three behaviours.

Four writers on one table produced inconsistent data, which is worse than missing data because it looks fine.

Building a connector parser from documented API shapes rather than observed responses cost me an afternoon and generalises to a rule I now apply everywhere: never build on an interface you haven't personally watched respond.

Prep generated for every calendar item including recurring stand-ups devalued the signal until I stopped reading any of it. Restraint is a feature.

Letting the model hold state is the recurring temptation and the most damaging one. Every time state stays in the conversation rather than being written to the record, it evaporates and the loop breaks silently. I now treat the model as stateless by policy, even when it isn't.

Stale record with confident output is the subtle one. When the record is behind, the briefing is authoritative and wrong, which is worse than absent, so freshness is now part of the output and an unswept record says so.

Additive-only automation was the last. Tasks and pages accumulated, the record turned into noise and trust dropped, which is what the weekly destructive pass exists to prevent. Systems that only accumulate die of their own weight.

What actually changed

I haven't measured any of this formally, so treat what follows as an estimate rather than a stopwatch reading, but I'd put it at three to four hours a day. Part of that is straightforward elapsed time, and the weekly management update is the cleanest example, since it used to be the most expensive recurring hour of my week and it was expensive because it was a reconciliation exercise, and now that the record is current it's a query.

The larger part is the gap between the time a task takes and the time I spend on it. A piece of work that runs for an hour across a handful of prompts costs me maybe ten minutes of dedicated thinking and instruction, and the other fifty happen without me in the loop. That gap is where the real leverage is, because once my involvement per task drops to minutes I can hold several streams in flight at once, and running things in parallel is what actually scales rather than any individual task getting faster.

Surprise happens less often too, which is the specific failure this targets. Not zero. Leads hold the detail more often when probed, because there's somewhere to look before the conversation happens. None of the time comes back out of the calendar, which is still meeting-majority, it comes out of the reconstruction work around meetings, and it's a saving on remembering rather than a saving on writing.

The honest limit is that the system is very good at knowing what happened and mediocre at knowing what matters. Prioritisation is still entirely mine, and anyone selling you the second thing is selling something else.

If you want to build something similar, the ordering matters more than the tooling. Build the system of record before the automation, because automation on top of an unstructured record produces confident noise. Pick one recurring thing you do badly and late, and automate that loop only. Instrument the intake first, since getting state in from meetings and chat is worth more than any generation capability. Write the procedure down the second time you do it rather than the tenth, extract the shared write path the first time two procedures write to the same place, make every scheduled thing safe to run twice before you schedule it, and include a destructive pass from day one. Expect to spend more time on skill design than on prompts, because that ratio is the signal you're doing it right.


I write about this stuff every week. If you want to keep up with what's changing in Claude Code, Cursor and AI dev tooling, along with the Go and infrastructure work I do, the newsletter is where it all goes first.

Join the newsletter - it's free

I also do consulting on AI implementation and technical strategy. If you're working through something specific, get in touch.

Subscribe

Get new posts directly to your inbox
You've successfully subscribed to Kyle Redelinghuys
Great! Next, complete checkout to get full access to all premium content.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.

What I'm building and learning, weekly

Claude Code configs, Go patterns, real costs and the tools I build to solve my own problems. One email, every week.

Now check your email to confirm your subscription.