smallbox

CompanyGraph · the system, drawn

System anatomy.

The companion page, From data to checked claims, shows this system in time — the stages a number crosses on its way to becoming something a reader may meet. This page shows the same system in space: the parts, the boundaries between them, and the exact shape of the data that crosses each line. Everything below is the deployed structure of CompanyGraph, the stock-analysis platform Smallbox built and runs — drawn from the real code, not an idealized slide. One thing to watch for: in every drawing, the accent colour marks a refusal — the places where the system says no.

01The whole system.

CompanyGraph is one product built as a small fleet: a single backend that composes pages, and subsystems that each own one kind of truth — company identity and financials, observation definitions and their firing, editorial content, images, email, accounts, translation. The two frontends — the public website and the internal admin — call the backend and nothing else.

websitethe reader surfaceadminthe operator surfacebackend onlythe backend — the composition seamlinks between truths · page composition · per-user state · the reports pipelinetyped contracts — references by idstocksidentity · financialsindustry frameworkobservationsdefinitions · scoringfiring at 70contentarticles · glossaryeditorial pagesimagesimage bytesand categoriesemailtemplates · queuedeliveryidentityaccounts —the sole storetranslationthe capability totranslate, on demandproduct truths never call each otherlogging — every box on this map ships its errors and a startup heartbeat to one place

Three wiring laws hold this map, and each prevents a specific kind of rot.

  • Frontends call the backend only. Page meaning is composed in exactly one place, so no surface can grow its own private opinion of what the product means.
  • Every call crosses in a typed contract, and references cross as ids. The backend compiles against each subsystem’s published client, so a subsystem changing its shape is a compile error in the caller — not a silent misparse at runtime, weeks later.
  • Product truths never call each other. Stocks knows nothing of observations; content knows nothing of stocks. No hidden dependency web forms, so any one box can be extracted, replaced, or rebuilt without archaeology. The designed exception is capability calls — a box may hand images bytes, ask translation for language, ship errors to logging — because a capability holds no product meaning to leak.

The live, fleet-wide version of this map — both products, every box, every line — is at /architecture. This page stays inside CompanyGraph and goes deeper: what the boxes hold, and what the data crossing the lines actually looks like.

02Inside every box: the same five layers.

Every service on the map is built the same way inside — five layers, and the honest way to describe each one is by what it refuses to do. The controller speaks HTTP and nothing else. The facade sequences the work, turns entities into the shapes a page needs, and holds the clients that talk to other services — but decides nothing. Business services decide — rules, validation, calculation — and never see HTTP. The repository is the only place that touches storage. And the domain is deliberately not a fifth stop on that chain — it is the shared material the middle layers trade in: business services decide with domain objects, the repository loads and saves them, the facade maps them into page shapes. It stays free of storage mechanics and presentation.

controllerspeaks HTTP — routes, request and response shapes, status codesnever business rulesnever data accessfacadesequences the work · turns entities into page shapesholds the typed clients that call other servicesnever decides validitynever business mathbusiness servicesthe rules — validation, authorization, calculationnever HTTPnever page shapesrepositoryevery read and write — the only place that touches storagenever business rulesdomainthe persistent shape of the business, kept purenever storage mechanicsnever presentationdecides with itloads and saves itthe same five layers in every box on the map — and page shapes are born in the facade, only there

Two habits keep the cake honest: the shapes pages consume are born in the facade and only there, and nothing anonymous crosses a layer edge — every crossing is a named shape. The payoff compounds. A change has one home, a bug has one place to live, and because the cake repeats identically in every service, learning one box teaches you all of them.

03The anatomy of a claim.

This is the centre of the system, and the reason the rest of the structure exists. A number does not become a sentence in one step — it moves through six stored shapes, and each hop is a check with its own durable record.

statement row — what the company reportedline item · value · currency · fiscal datea formula reads the statementsobservation firing — one formula's reading, scoredtypeKey · score 0–100 · as-ofbelow 70 nothing is stored — fired rows onlyrecomputed independently, in codeevidence packet — the check, written downclaim · verifier family · confirmed / unsure / mismatchcalculation trail · as-ofchecks roll up per observation typetrust record — how firmly the system may stand behind itlevel: untrusted / audited / reproduciblereason · frozen check counts · limits · definition versionthe level is computed from the checks — never set by handan editorial pass routes itplacement — what a reader may meet, and as whatzone: not suitable / supporting only / headlineapproved caption · rollout flag · overlap cluster“trust it?” and“show it?” aredifferent questionsTHE RENDER GATE — ALL FOUR AT ONCEplaced ∧ caption approved ∧ rollout on ∧ level = reproduciblea rendered claim — one labelled line a reader meetsapproved caption · status label · as-of

A statement row is what the company reported, tagged with its fiscal date. An observation firing is one formula’s reading of those statements, scored 0–100 — and 70 is a hard line: below it, the row is not even stored. An evidence packet is the check written down: the claim, which verifier recomputed it, whether the recompute agreed, the calculation trail, the as-of date. A trust record answers a different question — not “did this company’s number check out” but “how firmly may the system stand behind this observation as a class”. Its level is computed from the recorded checks; nobody sets it by hand, and a formula change resets it automatically.

Then comes the decision people expect to be the same question, and isn’t: placement. Whether a reader should meet a claim — and as what — is editorial. A figure can recompute perfectly, hold the highest trust level, and still be kept off the page because its name promises a verdict the arithmetic does not support: graham-number reproduces exactly and stays unsuitable, because the name reads as valuation advice. “Can we rely on it?” and “should a reader meet it, as this?” are answered by different shapes on purpose.

The gate at the bottom of the drawing is literal code, not policy prose: a claim renders only when all four conditions hold at once. Checked-but-not-shown is a normal, healthy state of this system — and the full ledger of what is trusted how far, including everything still untrusted, is public at the observation trust ledger.

04How a report is written.

A report looks like the most “AI” part of the product. It is where the structure is strictest. The writing stage never sees a raw firing — it sees evidence packets: claims that already carry their check, their status, and their date. That wall is drawn literally below, because it is the load-bearing decision.

checked evidenceverified figures + trailsstructural descriptionsfired interpretationsrecorded gapsraw firingsunchecked engine outputthe writer never sees a raw firingBOUNDED MACHINES — ONE JOB EACHthe deterministic channelno model involvedfigures recomputed in codepictures selected in code, as typed specsgaps recorded as datathe language channelone bounded model call per jobthe worldview prepended, verbatimonly declared evidence — absence stays absenceone narrow task · forbidden moves stateda parser that fails loudly, never guessesits own storage slot — outputs never blend“cannot see” is a valid answernew capability = a new machine, never a bigger promptthe report bodyevery line carries its registerverified figurearithmetic shownstructural readinglabelled as a readingcannot yet seestated as a gapgated renderthe reader

The pipeline runs in two channels. Everything numerical is deterministic: figures are recomputed in code, and every picture in a report is selected in code from typed specifications — a chart is data chosen by rules, never model output. The model is used only where judgement over language is genuinely needed, and there it works one bounded job at a time: the worldview prepended verbatim, the evidence it may know declared up front, one narrow task, the moves it must not make stated, a parser that fails loudly instead of guessing, and its own storage slot — so one machine’s output can never silently blend into another’s.

Register is enforced end to end. A verified figure renders solid, with its arithmetic. A structural reading is labelled as a reading and drawn muted. What the system cannot see is stated as a gap rather than smoothed over — a picture is prominence, so a picture may never promote a reading into a fact. And the growth rule that keeps all of this true over time: new capability is added as a new bounded machine, never by making an existing prompt bigger.

The system says it for itself.

None of this asks to be taken on faith. CompanyGraph publishes its own receipts, live, in its own voice: how it handles claims, the claim loop in time, the trust ledger with every observation’s current level and limits, and a dated record of corrections — the times it was wrong, what let the error in, and what guards it now. The structure on this page is what makes those pages possible.

This is one system Smallbox built.

Anatomy like this is not a diagram exercise — it is what makes a codebase changeable by one person, years in. The same structural discipline is what Smallbox brings to a system you already have.