This is the glossary you reach for when "what counts as backbone here?" or "why is this custom object showing up under Opportunity?" comes up.
The enabled objects are the ones Stood Flows actively manages. By default for a Salesforce graph that's:
Lead
Opportunity
Case
Account
Contact
Campaign
You can enable additional custom objects to be treated the same way — their record types get rows, their volumes get scanned, their related custom objects get pulled into the lineage. The toggle is in the objects panel (click an empty object cell in the KPI table or use the objects section in graph settings).
A custom object that you enable behaves identically to a standard one. The "standard" vs "custom" distinction is purely about the default seed list and the existence of BusinessProcess records on it (Lead/Opportunity/Case/Campaign).
Objects that are not enabled still surface in two contexts:
As related custom objects with their own column in the KPI Custom Objects group, when they have a lookup or master-detail relationship back to an enabled object.
As referenced entities in Apex SOQL/DML and I/O traffic, where they're shown but not given full RT treatment.
For every enabled object, Stood Flows pulls every record type (including inactive ones) with developer name, label, business process binding, and the picklist value sets that go with that BP.
A record type only gets a row in the KPI table if it's bound to a business process (or if the object has no BP at all, in which case all RTs get rows). Inactive RTs are kept — they're often the most interesting (high complexity, zero usage = retire candidate).
A business process on Lead/Opportunity/Case/Campaign is a named ordering of picklist values (LeadSource → status, StageName for Opp, Status for Case, Status for Campaign Member). Stood Flows reads the BP definitions, expands the stage order, and uses them to:
Drive the s0…s4 per-stage volume columns in the KPI table.
Anchor the Ghosts split (final-negative stages).
Group RTs in the KPI table under their BP label.
When two RTs share a BP, they appear as separate rows but share the same s-column layout.
Refresh-time logic, walked once and persisted:
Start with the enabled objects.
For each, describe the object via Tooling API to enumerate child relationships (lookup and master-detail).
For each child custom object: record (parent, child, relationshipType). If a row count is available, attach volume.
For each child, recurse — pulling its children too — up to a depth limit, dropping anything that becomes circular or hits an unrelated standard object.
The result is stored under customObjectRelationships in the version snapshot and drives the Custom Objects column group in the KPI table.
Each custom-object column header carries an icon:
🔗 — lookup relationship from parent to child
⇄ — master-detail relationship from parent to child
The column name is the object label (not the API name). Hover for the full API name.
OpportunityLineItem and CampaignMember are standard child objects with significant volume. They're shown as a combined Items column rather than per-object — partly because they're always there for every Opportunity / Campaign RT and partly to keep the table readable. The number is the total related rows in scope.
Other standard relationships (OpportunityContactRole, AccountContactRelation, etc.) aren't volume-tracked by default; you can pull them via the Apex tab if they show up as DML targets.
Record types are the right unit of analysis because almost all Salesforce permissions, layouts, automation, and reporting are scoped to them. A single Opportunity object can hide six businesses depending on its RT mix — they share data but nothing else. Treating each as a row in the KPI table is what lets you compare them head-to-head.
When you start adding tags, anchoring issues, or generating Apex packages, you're typically operating per (object, RT) cell. That's the unit. Everything else aggregates up to it or drills down from it.
A custom object you expected to see is missing from the KPI custom-objects columns:
Is it actually reachable from an enabled object via a relationship? If not, enable an intermediate object or treat the CO as a separate analysis.
Did the relationship come into existence after your last Refresh? Re-run Refresh to pick it up.
Is the relationship blocked by perms? The connected sf user needs read access to both parent and child.
A custom object appearing in too many columns:
It probably has lookups from several enabled objects. Each lookup gets its own column entry. That's accurate — the CO is genuinely related to all of them.
A custom object appearing with 0 everywhere:
It exists with relationships, but has no rows. Common for staging tables. Use it as evidence that the table can be retired.