The problem before
I run operations for a revenue team that manages campaigns against groups of existing customer accounts — which accounts to work, who works them, how many they can handle, what's already been done, and what counts as a win.
None of that lived in one place. It lived in exported spreadsheets, in a CRM that told you what was true now but not what had been decided then, and in people's heads. Building a campaign group meant someone assembling a list by hand. Planning capacity meant guessing from experience. Answering "why is this account in this group?" meant finding the person who built the list — and hoping they remembered.
The dangerous part is that this worked. Deals closed, campaigns ran. It worked the way a process works when skilled people keep quietly saving it — which looks identical to a healthy system right up until something changes.
What was relying on tribal knowledge
When I actually wrote it down, the list was uncomfortable:
- Which data field was the real one, when several looked plausible and disagreed.
- What "in the campaign" meant — I found three working definitions, all in use, all producing different counts.
- Whether a group's membership was allowed to change after work had started against it. (Everyone had an opinion. Nobody had a rule.)
- Which accounts were off-limits, and why.
- Whose numbers were trustworthy when reports didn't match.
- Who had capacity, and what the next six months of work actually required.
The tell was repetition: the same questions asked again and again, and — the one that finally made me build something — two people working from "the same list" that wasn't the same list.
Turning it into rules and workflows
The build started with definitions, not code. The most important one: a group is a frozen roster. It's created from criteria, on a date, and after people act on it, it never silently changes. Criteria can keep evolving — that's how the next group gets smarter — but a decision that's been acted on gets a timestamp, and membership only changes when a person changes it, with a logged reason. That single rule ended the "the list changed under me" class of problem.
From there:
- One source of truth per kind of data. The CRM stays authoritative for what it owns; the system mirrors it read-only and never edits what it doesn't own. Everything the system does own is explicit.
- Unsafe assumptions became named rules. Where the old process guessed ("blank probably means…"), the new one has a written rule, applied the same way every time — which meant we could argue about the rule once instead of everyone quietly making a different call forever.
- Separate workflows for separate jobs: running the day-to-day, planning capacity, building new groups, investigating problems, and admin/configuration each got their own lane, so daily operation can't quietly rewrite the machinery underneath it.
- The system tells you when it's lying. Data feeds carry staleness detection and mismatch flags. When an upstream source breaks, the dashboard says so — instead of presenting confident numbers built on a dead feed.
Not all of these rules were known up front. Some only became obvious after the system existed — we'd find a case where the software was doing exactly what we'd told it to do, and realize the rule itself was wrong or incomplete. My favorite example: two counts of the same campaign came back wildly different, and after a real investigation the answer was that both were technically correct — they were counting two different things nobody realized had been defined differently. The fix wasn't code. It was a definition. Those weren't really bugs. They were assumptions we hadn't made explicit yet, and finding them is a permanent part of running the thing.
Where AI came in
I'm an operations person, not a developer — no CS degree, no engineering background. AI wrote effectively all of the code. That's the part people find surprising, and honestly it's the least interesting part.
What AI didn't do is decide any of the rules. Every definition, every source-of-truth call, every "this needs a human" boundary came from doing the job. My working model: AI collapsed the distance between knowing what the system should do and having the system — but knowing what it should do was still most of the work.
Where human approval stayed
This was deliberate, and it's the part I'd defend hardest:
- Nothing writes to the system of record without a person approving it. The system prepares changes; a human reviews the batch and pulls the trigger.
- Review tools never pre-select decisions. If the org hasn't signed off on a rule, the tool doesn't default an answer — it presents the case and waits. Automating a judgment nobody agreed to is how "working" software quietly changes business logic.
- Membership changes are human decisions, logged with reasons. The system can flag that something looks wrong; it doesn't get to act on that opinion.
- Alerts propose, people dispose. Drift, gaps, and anomalies get surfaced to the people who own the call — the system's job ends at making the call easy to make. (And alerts de-duplicate themselves: a flag that fires means something new happened. An alert channel people learn to ignore is worse than no alerts at all.)
- The system knows what it can't see. Where it lacks the data to classify something confidently, it says so and routes the case to a person. Guessing is not one of its features — teaching the software to know what it doesn't know turned out to matter more than teaching it more rules.
What changed
- Questions that used to mean finding-the-person now mean opening a screen. The repeated-question tax basically went to zero.
- The system no longer creates competing versions of the same roster — the "two people, two lists" problem stopped coming up because there's one explicit roster to work from.
- When upstream data breaks, we find out from a flag, not from a bad decision three weeks later.
- Planning conversations start from shared numbers instead of dueling spreadsheets.
- The real test: a person central to the old way of working was out for an extended stretch — and the operation kept running. Under the old process, that absence was the outage.
- And the newest layer flips the direction entirely: with the foundations explicit, the system has started proposing — surfacing groups worth considering and drift worth a look — and people decide. We couldn't safely do that when the rules still lived in people's heads.
The build was never really about software. It was about making the operation stop depending on what people happened to remember.