Back to portfolio

Case Study · Our own platform

What We Won't Let Our Own Software Do

Palanae is the business platform we build and run ourselves. The interesting decisions in it are not the features — they're the things it is structurally incapable of doing, and the reasons we made it that way.

0

Writes the AI can make

propose-only — enforced by a lint rule

6

Business nouns, fixed

everything else is a Fact, not a table

29/29

Tables with row-level security

isolation tested, not assumed

2,067

Automated tests, passing

across 213 files

About this case study

This one is different from the other two in our portfolio. Those describe work our founder did for an employer. This describes our own product — a platform we designed, built, own, and operate, with no client to answer to and therefore nobody but ourselves to blame for the shortcuts. Every number on this page is a measurement of our codebase, not a result delivered to a customer. We publish it because how a firm behaves when nobody is watching is a better signal than a testimonial.

At a glance

What it is
Palanae — a multi-tenant business platform StrAinge AI owns, builds, and operates
Why it's here
It's the clearest record of how we make engineering decisions, on a system where we answer to ourselves
Team
One engineer plus an AI build-and-review loop
Core thesis
Capture-first — structure what a business already produces, so the accumulated record becomes the asset
Entity graph
Six fixed business nouns; everything else lands in a Facts layer, never as new tables
AI trust model
Propose-only. No agent writes to the database. Its only output is a row in a review queue
Isolation
Row-level security on all 29 tables, tested in the failing direction
Deliberately not built
Payroll and general-ledger systems of record — permanently out of scope, by design

The premise

Business software doesn't usually fail on features

Ask anyone who has watched a CRM rollout die. It very rarely dies because the software couldn't do something. It dies because the people who were supposed to feed it stopped feeding it, and six months later the data inside is wrong often enough that nobody trusts it, and once nobody trusts it nobody opens it.

There are two well-worn ways to get there. The first is friction — you ask humans to type things into fields that benefit someone other than themselves, and eventually they stop. The second is distrust — you let an AI fill those fields instead, it is confidently wrong a handful of times in front of the wrong person, and everyone quietly goes back to the spreadsheet. Same empty system, different cause.

Palanae is our attempt at the third path, and the shape of it is the reason this page exists. Instead of asking people to enter data, it structures what a business already produces — the meeting that happened, the document that got sent, the decision that got made — so that the accumulated record becomes the asset. That's where the name comes from: the Palanaeum, a library you go to in order to find what is already known.

But capture-first only works if the captured record is trustworthy, and trustworthiness is not a feature you add. It comes from what the system is prevented from doing. Everything below is a constraint we chose, and — the part that actually matters — the mechanism that makes each one impossible to violate later, including by us, on a deadline, at eleven at night.

A rule that depends on everyone remembering it is not a rule. It's a preference with good intentions.

Constraint one

Six nouns, and we don't get to add a seventh

The question most platforms answer with a configuration screen, we answered once, up front, and then closed.

Every business, at every size, in every industry, deals in the same six things:

Parties
Anyone you deal with — customers, prospects, suppliers, employees
Events
Things that happened — meetings, emails, calls, deliveries
Commitments
A promise with terms — a quote, a contract, a purchase order, a subscription
Money
Invoices, payments, costs, recurring revenue
Things
The tracked unit — product, asset, equipment, inventory
Work
Tasks, jobs, production steps, projects

Modules aren't separate products built on top. They're views over that set:

CRM
Parties + Commitments + Events
Production forecast
Things + Work + Commitments
Accounting insight
Money + Parties + Commitments

The second module costs a fraction of the first, because the nouns already exist and only the view is new. That's the whole reason a very small team can ship something this broad.

Here's the constraint that makes it hold. The six nouns are fixed. Custom fields, industry specifics, the endless long tail of “can it also track…” — all of it lands in a Facts layer as typed, derived data. Never as new tables. Any proposal for a new top-level entity has to first argue why it isn't a Fact.

This is the discipline that keeps the schema small while the data stays open-ended. Skip it and you get a generic ontology engine that can model anything and does nothing well — which is how this category of product usually dies.

Deep dive · technical

Constraint two

The AI is structurally incapable of writing to the database

Not discouraged from it. Not audited afterward. It does not have the functions.

No agent in Palanae writes directly. Ever. Every action an AI wants to take lands in a review queue as a proposal, and a human approves it or doesn't.

That's a common enough promise. What's uncommon is how it's kept. We didn't write it in a policy document and trust ourselves to honor it. The agent code is not permitted to import the service layer's write functions at all. A lint rule forbids the import. Its only available output is a row in proposals.

And the lint rule itself is covered by a test that runs in the failing direction — a test that writes code violating the rule and asserts that the linter rejects it. If someone ever loosens the rule, that test fails, and continuous integration blocks the merge.

So the guarantee doesn't rest on anyone's memory or on a reviewer catching it. A developer under deadline pressure cannot casually violate it, because the violation doesn't compile cleanly through the pipeline. That's the difference between a principle and a constraint.

There's a philosophical objection worth answering, because clients raise it: if the AI drafts the change and the human just clicks approve, is the human really deciding? Our answer is that the human's approval is the authorization; the AI is the executor — the same relationship you have with the Save button. What matters isn't who moves the bytes. It's whether a human reviewed this specific change, or knowingly pre-approved a class of changes. So autonomy is a per-action-class setting, deliberately, and the question stops being philosophical and starts being a configuration a customer owns.

Constraint three

Every inferred value shows its work

An AI-derived number that can't be traced back to its source is a rumor with good formatting.

Every value the AI derives carries four things with it: its source, a confidence, a timestamp, and the specific run that produced it. Click an inferred claim and you land on the line of the transcript it came from.

Just as important is where those values live. An inferred value sits beside the human-entered one. It never overwrites it. You can always see what a person said and what the machine concluded, side by side, and tell them apart at a glance.

This is the direct answer to the distrust failure mode. When someone finds a wrong inferred value — and they will, because that is what inference does — the question “where did this come from?” has an immediate, checkable answer instead of a shrug. One traceable mistake costs you a correction. One untraceable mistake costs you the user.

AI-filled fields don't die of inaccuracy. They die of unaccountability.

Constraint four

The work we've permanently refused

Two obvious adjacencies that we will not build, written down before anyone could ask us to.

Palanae is never the payroll or general-ledger system of record. Not “not yet.” Not “unless a big enough customer asks.” It's written into the architecture document as a permanent boundary.

Both look like natural next steps, and neither is. Payroll means multi-state tax filing liability, moving other people's money, bonding requirements, and an entirely different insurance posture. Being the accounting system of record means audit obligations. Those aren't features — they're a different company, with different regulators and a different risk profile.

So we integrate with whatever payroll and accounting systems a business already has, and we own the intelligence layer on top. The reason we're telling you about a boundary rather than a capability is that a firm that has never told you what it won't do hasn't thought hard enough about what it will. Scope discipline is not modesty. It's the thing that keeps a small team's work good.

Deep dive · technical

The through-line

How a rule becomes something you can't break

Every constraint above has a mechanism underneath it. Here are the four we use.

Make the wrong thing unavailable. The propose-only guarantee isn't a code review checklist — the write functions simply aren't importable from agent code. The cheapest rule to enforce is one that can't be expressed.

Test in the failing direction. It isn't enough to test that correct code passes. We write tests that produce incorrect code and assert that the tooling rejects it. Otherwise you find out your guard rail was disabled six weeks ago and everything still looked green.

Fail closed. When a security-relevant setting is missing or empty, the answer is deny — never allow. This sounds obvious and is very frequently gotten backwards, because “absence means permissive” is the behavior that makes local development convenient. Our access layer denies every request when its secret is absent, and that's tested too.

Isolate by default, then go try to break it. Palanae is multi-tenant, so one customer seeing another's data is the unrecoverable failure. All 29 of 29 tables have row-level security enabled, and the test suite includes tests whose entire purpose is to attempt cross-tenant reads and assert that they come back empty. We also verify that the database role the application connects as cannot bypass those policies — because a permission granted years ago in a migration is exactly the kind of thing that silently undoes a security model.

The current tally: 2,067 automated tests across 213 files, all passing, with a separate database-integration suite on top of that which these numbers do not include. And 53 schema migrations, each one reviewed and applied deliberately rather than auto-run on deploy.

Why this matters to you

What you're actually evaluating when you hire someone to build software

Most of what you're buying when you hire a firm to build something is invisible on the day it ships. Two systems can look identical in a demo and be nothing alike eighteen months later, when one of them has quietly accumulated eleven ways to write to the same table and the other still has one.

You can't easily inspect that in advance. What you can do is look at how a firm treats the system where it has no client, no deadline pressure from outside, and nobody to impress — and see whether the discipline is real there.

That's the entire argument for this page. We took the harder path on our own product in four specific places, we can point at the mechanism enforcing each one, and none of them were free. If we build something for you, this is the standard it gets built to.

1

Constrain the model first

Decide what the system is not allowed to represent before you decide what it does. A small, fixed entity graph with a typed extension layer beats a configurable one that can model anything and explains nothing.

2

Machines enforce, documents describe

If a rule matters, something automated has to reject its violation. A rule that lives only in a document is already broken; you just haven't found out yet.

3

Let AI draft, never commit

The productive place for a model is producing a proposal a human accepts or rejects. Keep the authority with the person and the throughput with the machine — and make the boundary structural, not procedural.

4

Say what you won't do

A written, permanent scope boundary is worth more than a long capability list. It tells you where the thinking has actually been done.

Want this standard applied to your systems?

Start with a conversation about what you're running now and where it's costing you.

Book a Free Consultation