A metric is a Function. Not two people’s SQL.
Two people bring two numbers for active customers, both defensible. Write the definition once as a Function that returns its rows.
The systems you already run, the objects your product declares, and the work your team gets back.
These marks name the kinds of system a source declaration reaches — a picture of the ecosystem, not a fixed menu, and nothing here implies a partnership.
Fewer arguments about the number. More acting on it.
One definition, not two queries
Active customer is declared once as a Function, so nobody’s private notebook copy competes with it.
The number arrives with its rows
A Function returns the records behind the figure, so two people compare rows instead of booking a meeting.
Broken feeds get an owner
A failing check opens work through an Action with an owner, not a dashboard quietly reading zero.
What teams build. On day one.
Four places this work turns into declared objects, governed reads, and reviewed changes.
Shared definitions
Two analysts, two SQL files, two numbers. One Function instead, in reviewed source, where changing it is a commit somebody has to approve.
Cross-system reconciliation
Compare billing against usage at one known version of each and get back the rows that disagree, not a count you then chase.
Freshness checks
An Automation runs the exception Function each morning, so a feed that changed shape shows up as work with an owner by nine.
Reports that reproduce
A read names the source versions it used, so rerunning last quarter’s report returns last quarter’s rows and a restatement is explainable.
How it runs. End to end.
The same path every product takes: connect what exists, declare what it means, then publish the reads and the changes.
- 01
Connect the systems, warehouse included
Your warehouse joins the operational tools as one more source Bijection only reads. Each is snapshotted on a schedule and published with a version number, and a Function reports which snapshot it used.
- 02
Declare the objects underneath
Customer, order and subscription are typed declarations with their links, so a definition is written against a model rather than against column names somebody renames next sprint.
- 03
Publish each definition as a Function
One name, typed parameters, a typed result, and its evidence returned with the answer. The dashboard panel, the internal application and the agent are three callers of one definition rather than three definitions.
- 04
Let agents call the same ones
An agent answering a question runs the Function an analyst would run. It cannot invent a third definition of active customer, and anything it wants to change goes through the ordinary reviewed Action.
Common questions.
No. Heavy modelling and historical analysis stay there, and the warehouse becomes one read-only source alongside the operational systems. What this owns is the definition layer over all of them, and the path by which a finding turns into a reviewed change — which is not something a table can do.
Not in the self-serve sense, and that is the limit worth knowing before you start. A dashboard panel reads exactly one governed Function: no chart builder, no ad-hoc grouping, no drag-and-drop exploration. You give up fast slicing, and in exchange two panels cannot quietly mean two different things by active customer.
Not from capture alone, and we will not claim otherwise: a column whose meaning changed upstream still loads without error. What you get is an exception Function running on a schedule and a version stamp on every result, so a number that went wrong has a first bad run instead of a month of silence.
Bring us a process.
We'll build it with you.
A business process, the systems it touches, and the rules it needs to follow.