A commercial client is almost never known by the name on their ABN registration. The optometrist on the main street is registered to a holding company. The takeaway shop bills through a family trust. The insurance branch trades under a national brand and is registered to a two-word entity nobody outside the accountant's office has ever said aloud.
So a screen that shows the operator the registered entity is asking them to translate, dozens of times a day, from a name they have never used. Biloh resolves that once, in one place, and applies it everywhere an operator reads a business name.
Which name goes where?
The split is by reader, not by screen:
| Who is reading | Which name | Why |
|---|---|---|
| You, triaging your own work | Trading name, legal name beneath | Recognition. You need to know who this is in under a second. |
| Your client, on a tax invoice | Registered legal entity | Compliance. A tax invoice identifies the entity being billed. |
| A statement or outbound email | Registered legal entity | It is a financial document addressed to a legal person. |
| Your accounting system | Registered legal entity | It must reconcile against the same entity your books use. |
The two rules point in opposite directions, and both are correct. The mistake is to let one leak into the other.
What decides the operator-facing name?
A single resolver, in one module, that every operator surface imports:
- Trading name, if one is recorded and it is a real name.
- Otherwise the legal name.
- Otherwise a neutral placeholder, so a row is never blank.
Whichever name is not chosen becomes a muted second line — the entity is demoted, never lost. That second line matters more than it looks: it is what lets you match a row against a bank feed or an accounting export without opening the client record.
What counts as "a real name"?
Two cases are filtered out before a name is chosen.
Blank is not a name. A trading name that is empty or only whitespace falls through to the legal name.
Placeholder text is not a name. Operators routinely seed a client while chasing their real details — "Example Boutique (legal entity TBC — pending business details)". That text must never be presented as a business name, and it must certainly never reach a tax invoice. The check is word-boundary anchored so genuine names are not caught: a business called Ascendant Trading or Spending Group is unaffected, while a value ending "… TBC" or containing "pending ABN" is treated as absent. The same rule already drives a warning before an invoice is sent and an anomaly signal on the client record — there is one definition of placeholder text on the platform, not three.
When are both names the same name?
Often — and printing it twice is noise on every row.
The suppression test normalises before comparing: lowercase, strip entity-form words (pty, ltd, limited, incorporated, the trustee for), then strip every non-alphanumeric character. A.S. EXAMPLE PTY. LIMITED and A S EXAMPLE PTY LIMITED both reduce to the same key, so one line is shown. Two genuinely different names never collide, because the trading name of a business is not a punctuation variant of its entity.
On a real book of 63 commercial and residential clients, this arithmetic held: roughly a fifth had no trading name at all and fell back cleanly, another fifth had a trading name identical to the legal name and were printed once, and the remainder were the ones where the two names were genuinely different — the rows an operator could not previously identify at a glance.
Can a tenant change it?
Yes, on every plan, with no code change:
directory.entity_display_name_preference—trading_first(default) orlegal_firstdirectory.show_legal_name_secondary— whether the second line appears
A business whose books and conversations both run on registered entity names flips the first one. A business that wants a denser list turns off the second. Both are editable in Settings and by an AI assistant over MCP, at the same depth.
Neither is tier-gated, and that is deliberate. An operator who cannot identify the client on their own invoice is not missing a premium feature — they are looking at a broken product, and there is no plan on which the wrong name is the right answer.
What stops the two rules from crossing?
A test, not a convention.
A structural test asserts both directions on every build: the operator surfaces must import the shared resolver, and the tax-invoice, statement, outbound-email and accounting-mirror paths must not — and must still be reading the legal name. A trading name reaching a tax-invoice recipient line is a compliance defect, not a cosmetic one, so the guard runs in both directions rather than trusting whoever edits those files next.
Why did this need saying at all?
Because the rule already existed in the codebase around forty times, hand-written at each call site, with no single home — and the invoice list was the one surface that never received a copy. It was not a wrong rule; it was an unowned one. An unowned rule is correct until the day something is built without it, and then it is silently wrong on exactly one screen.
The fix was to give the rule one home, register that home, and lock the boundary. The general form of that pattern is in one home, locked in both directions.