field-note11 min read
Building a company operating system
Last note I scored us at 29 and said Demand was the constraint. So I built the demand system. Here is what I looked at first, the documents it came from, the order it got built in, and what it actually does. It is live, the score moved to 31, and you can log into it.
Last note I scored Senpai at 29 out of 100 and said the problem was Demand. Zero of five capabilities running, with Delivery and Money sitting at zero behind it. Three domains in a row, and together they are the whole path from a stranger to a paid invoice.
So I built the demand system. Not a plan for it. The thing.
It is live now. You can log in at os.senpaifutures.com with the token senpai-os-demo, and you can run the index on your own company at senpaifutures.com/company-systems-index. If you take it, you will show up in there.
I am figuring this out as I go and putting it up as I do. This is the start of the system, not the finished shape of it.
What I looked at first
I spent a while reading what a company operating system currently means before writing anything. It splits three ways.
Framework tooling. Ninety.io and the rest, built around EOS and Traction. Real businesses, narrow: they digitise one consulting methodology.
All-in-one work platforms. Notion, ClickUp, Monday, and a long tail of startups claiming the category. Most are a database with opinions. The 2026 pitch is uniformly “AI-powered unified system”, which is what a category says when nobody in it has a technical position.
Internal tool builders. Retool, Airtable, Jestor. They sell you the parts and you assemble it yourself.
What struck me is that searching this space returns comparison listicles, not engineering writing. Nobody is publishing how they built one. That is either an opening or a sign the category is not real, and the only way to find out is to build one and see whether anyone pays.
One decision came out of that reading and it shaped everything after. A company OS that plugs into a separate CRM for its customer data has given up the thing it exists for, which is seeing the whole business in one place. Demand and Delivery are two of my eight domains and CRM is most of what they do. So this is the CRM. What I defer is scope, not shape.
What I already had
I have been writing Senpai’s operating system down as documents for weeks. Eight of them.
| Document | What it settles |
|---|---|
SYSTEMS_REGISTER.md |
The 41 capabilities across eight domains, and where we stand on each |
ETHOS.md |
The values, and what we do when holding one costs money |
VOICE.md |
How Senpai writes, and fifteen things it does not do |
POSITIONING_AND_CONTENT.md |
The slot we occupy, who we talk to, what we publish |
MARKETING_SYSTEM.md |
How people find out about us, and how they become ready |
SALES_SYSTEM.md |
Leads to close, by track, with the qualification and the scripts |
PARTNERSHIPS.md |
Five partner types, what we trade, what we never trade |
FUNDING.md |
Grants, funds and tenders, with every funder assessed twice |
Those are not background reading. They are the schema.
The pipeline stages come straight out of the sales system. Tracks A to G are its segments. The partner types come from the partnerships document. The 41 capabilities are seeded into the database from the register. When I hit a design question during the build, the answer was usually already written down, with the reason next to it.
That is the actual argument for writing things down before building them, and I did not expect it to pay off this directly.
The build, in order
The index came first
It measures everything else, so building it first means the system reports on its own progress from day one. It is also the artifact, and the number was already published, so putting it in software makes that figure something the system maintains instead of something I recalculate by hand until it goes stale.
Eight domains. 41 capabilities. Each one scored on a single question: does it run without me.
DESIGNED ──► BUILT ──► RUNNING
it is written it works somebody else uses it,
down regularly, without me
That third state is the one most self-assessments skip, and it is the only one that counts. A document is not a system. Working software nobody has used is not a system either.
Then the lead magnet, which broke a table
The pipeline had a problem I only saw once it existed: no inlet. The only way a lead got in was me typing it. I had four real sources of leads, an Abuja ecosystem sweep, LinkedIn inbound, the site’s email capture, the contact form, and none of them connected to anything.
The diagnostic fixes that. A stranger runs the index on their own company, watches the score move as they answer, and trades the per-domain breakdown for an email. The lead then arrives carrying a problem they named themselves, which beats any contact form for qualification.
Except the index was one table, and a row held both what a capability is and what state ours is in. That works for exactly one company. A stranger’s answers had nowhere to go.
So the table split in two: a shared catalogue of what each capability is, and per-subject state of who has what. Senpai became subject zero. Every diagnostic run is another subject.
41 rows is a migration. That same split after partners, engagements and a funding register hang off the table is a weekend. Doing it when the need appeared instead of when it hurt is the best decision in this build.
It was also nearly free, and the reason matters. The scoring logic sits in an engine that takes data in and hands data back, holding no database connection of its own. It never knew whose capabilities it was counting. So the public diagnostic is the same code scoring a different subject, not a second version of the same idea.
Then double entries, and the ceiling behind them
The diagnostic filed its first lead and the flaw showed up immediately.
An email address was getting copied into every table that needed one. The lead had one. The diagnostic run had one. Whatever I built next would have added a third.
That produces two failures. Somebody who runs the index today and turns up in my DMs next week is two unlinked rows, so where did this person first hear about us has no answer. And every new artifact adds another place a person is half-known, so the system slowly loses the ability to see its own customers.
The missing thing was not a column. There was no table for a person I know.
organisations the durable thing
├── contacts people there. one row, ever
├── leads their state in the pipeline
└── runs a diagnostic they took
A lead stopped being a copy of a person and became a pipeline state attached to one. Every route in resolves through the same door now, so arriving twice makes one contact with two interactions.
Two details in there earn their place. What an organisation is to us sits on the organisation, and how we are approaching them sits on the lead, because the same organisation can be a partner one month and a buyer the next, and one field cannot hold both. And where I first met somebody is never overwritten, because attribution that records the last touch is worse than no attribution.
What the system actually does
Concretely, this is what is running on that server.
The index. Eight domains, 41 capabilities, each with what it has to do and what state we are in. I can move a capability from the screen, and it refuses to let me mark one running without an evidence link. The score recomputes from the database, so the number on this site and the number in the system cannot drift apart.
The pipeline. Leads moving through new, contacted, qualifying, mapped, proposed, then won, lost or disqualified. Each carries a next action and a date. There is one screen called Today that answers the only question this thing has to answer well: who am I supposed to contact, and what do I owe them.
Every lead also carries a track, A through G, and those are not labels. They come from the sales system, where each one is a different buyer with a different cycle, a different price and a different way of deciding.
| Who | Why it is filed separately | |
|---|---|---|
| A | Shops and small businesses | Days to close, low value, and the referral engine in a market that buys on trust |
| B | Established businesses | Weeks, real money, and the work that builds the strongest case studies |
| C | NGOs and funded programmes | Months, committee decisions, and procurement that asks for a track record |
| D | Government | Quarters, politics, and worth entering through a partner instead of cold |
| E | Startups | Fast, and only worth chasing when the founder is not technical |
| F | Talent placement | Days, and the fastest door-opener we have |
| G | Ecosystem partners | Not buyers at all. Channels, measured on leads produced and never on revenue |
Filing a lead under the wrong track means running the wrong play on them, quoting the wrong number, and waiting the wrong length of time before deciding it is dead. That is why the diagnostic asks rather than guesses.
Contacts and organisations. Who we know, where they work, and where each person came from.
This is the part that matters most, because the point of all of it is getting clients. A company that cannot list the people it knows cannot sell to them. In 2021 I had two thousand community members and no way to answer who any of them were, and that is a large part of why none of it turned into a business. Every lead, run and future engagement now points at a contact instead of carrying its own copy of a name, so the list gets more useful every time somebody touches us rather than more confused.
A company page. One organisation, and everything about them in one place: the people there, every lead they have ever been, and their whole history from the record.
The public diagnostic. The catalogue is public, anyone can start a run, the score is live while they answer, and completing it captures a contact and files a lead.
The record. Every state change is an event with an actor and a timestamp, appended and never edited. There is no update and no delete on that table, because a log I can edit is not evidence.
And three rules the system enforces on me, in the engine, where a form cannot get around them:
A capability cannot be marked running without evidence. A lead that closes as lost or disqualified must say why, because the sales system targets a disqualification rate above 50% and that number means nothing if the reasons are missing. And an open lead must carry a next action and a date, because a lead nobody scheduled is a lead nobody will contact. Leads created without one are allowed and counted separately, so the gap shows up instead of hiding.
There is also one question at the end of the diagnostic that decides what happens next. Which describes you best, with the tracks, and “none of these, I am just curious” at the bottom. Everyone who finishes becomes a contact, because holding an email costs nothing. Only somebody who says they are an organisation becomes a lead. That is qualification happening at the top of the funnel where it is cheapest, and it keeps the pipeline from filling with people who were never buyers.
What moved
The index reads 31. Two points, and I want to be exact about where they came from.
Marketing and content is running. Not because I deployed something, but because there is a loop that turns without me holding it together. The site publishes on a cadence. Every field note routes to the diagnostic. The diagnostic writes to a backend that records who arrived, when, and what they scored. That is a marketing system in regular use producing output, which is the definition, so I am counting it.
I had this wrong in a first draft of this note and scored it built. That was false modesty, and false modesty in an instrument is the same failure as flattery: both make the number stop describing the company.
Sales process and pipeline is built, not running. It is deployed, it works, I can move a lead through it from the screen. No real lead has gone through it yet, and until one does, the thing is a working machine nobody has used.
Nurture is built. Capture is wired and nothing sends.
Business development, and grants and tenders, are still only written down. Nobody has been contacted and nothing has been submitted.
So Demand is 5 designed, 3 built, 1 running, and the company is 31 out of 100.
Two points is not a triumph and it is not nothing. It is what one capability crossing the line actually looks like, which is the whole reason for having three states instead of a checkbox. If deploying counted as running, the number would jump every time I shipped and stop telling me anything. If publishing regularly did not count, the number would never move and stop telling me anything for the opposite reason.
Where this goes
It is a work in progress and it is running. Next is filling the pipeline with the Abuja sweep, getting the diagnostic in front of people, and finding out whether any of this turns into a conversation and then a first sale.
The number to watch is not 31. It is whether Sales process and pipeline crosses from built to running, because that one only moves when a real lead goes through it, and a real lead going through it is the whole point of building any of this.
Go and look at an operating system that is genuinely at the beginning. Come back in three months and check whether it moved.
os.senpaifutures.com · token senpai-os-demo · run your own index
Stay updated
We are building the digital infrastructure Africa needs, and publishing the whole thing as it happens. Field notes from inside the work, research, case studies, and the decisions that turned out wrong. Roughly weekly.
No pitch, and one click to leave.
SENPAI is a social impact design and technology company in Nigeria. We publish what we learn from the work, including the parts that did not go to plan.
Bring us a problem