Semanticus
Documentation

Lineage & Impact

Trace any field from its data source down to the report visuals that use it, see exactly what breaks before you change it, and find what is genuinely safe to remove. Built offline from your model, available in the Studio and over MCP.

Two questions this tab answers. Forward: "if I change or remove this, what downstream breaks?" Reverse: "which objects can I delete with zero impact?" The reverse question is the hard one, because a model-only "unused" check over-reports (a descriptive column a report displays looks unused, since no measure references it). Report-aware analysis closes that gap.

In the Studio

The Lineage & Impact tab renders the dependency graph with a force-directed view plus DAG and tree layouts, and a drill-down that expands node by node from data source to table to column or measure to report, page, visual and the exact field. On the force graph, click a node to select it and light up everything it touches, click another to walk the graph node by node, click empty space to step back out, and Reset restores the default view. Two modes toggle: Impact highlights everything downstream of a selected object, and Safe-to-remove lists the deletion candidates. Nodes carry a reference count, an impacted count and, for the safe-to-remove sweep, the tri-state verdict with a "blocked by" badge naming what still uses an object.

The Lineage and Impact tab showing upstream and downstream dependencies for the selected object.

Assess a proposed change

Impact Assessment starts with the change you intend to make, not just the object you selected. It reports the affected model objects and report visuals, explains anything it could not inspect, and produces an evidence record that Change Plan and workflows can carry into review. Cloud report discovery is supported; unreadable reports are listed with a reason and are never treated as safe.

Over MCP

The same lineage is a tool surface, so your own AI Assistant can answer "what breaks if I drop Sales[Discount]?" or "list the safely removable measures".

get_lineage                            # the offline lineage graph: nodes + directed edges
impact_of measure:Sales/Margin         # forward: everything that breaks if this changes
get_dependencies <objRef>              # what an object's DAX consumes (check before editing)
get_dependencies <objRef> direction=dependents   # what references it (check before delete / rename)
unused_objects                         # reverse safe-to-remove sweep (tri-state verdicts)
remove_safe_objects                    # delete the verified-safe set in ONE undoable step (Pro for >1)
analyze_reports <pbip-folder>           # report-aware: which fields each local report uses

get_lineage builds the graph offline from the model (TOM): data source to table, table to column and measure, DAX dependency edges, and foreign-key to primary-key relationships. For the star schema itself, model_graph_summary is the cheap first call and get_model_graph the full graph.

Impact of a change

Before you edit or delete a measure or column, impact_of returns everything that breaks transitively: the DAX dependents (measures, calculated columns and tables, calculation items, KPIs, RLS) plus, for a column, the relationships, hierarchies and sort-by columns that use it, with a breadth-first depth and counts by kind. get_dependencies (direction dependsOn) lists what an object's DAX consumes, and get_dependents lists what references it, so "check dependents before delete" is one call.

Safe-to-remove, conservatively

unused_objects is the reverse sweep: every measure and column that nothing references, as a deletion-candidate list. It is deliberately conservative and gives a tri-state verdict per item so it never overstates safety:

VerdictMeaning
safeNothing in the model references it. A column used by a relationship, hierarchy, sort-by or RLS filter is never listed here.
used by an unused objectReferenced only by other dead objects, surfaced with what blocks it, so you can retire the chain together.
cautionA dependent report could not be read, so the object is not declared safe.
Never a false "safe"

Safe-to-remove fails loud rather than guessing. If a report cannot be read, the verdict degrades to caution instead of claiming the object is unused. On its own the model-only sweep cannot see report usage, so a field used only by a published report will still appear as a candidate until you add report analysis. Verify report usage before you delete.

Report-aware lineage

Picking the reports to analyze no longer means hand-typing paths and workspace GUIDs. A Browse button opens the host folder picker for local project folders, and the workspace box becomes a picker that lists your workspaces by name and auto-selects the one that matches the open model, with an escape hatch to enter an id manually. A live progress channel streams per-report advancement ("Analyzing N of M") so a multi-report run never looks frozen, and stale responses from a model switch or a mid-flight edit are invalidated so an analysis can never target the previous model's workspace.

analyze_reports closes the model-only blind spot for local reports: point it at a Power BI project folder in PBIR format and it parses which model fields each report actually uses, then recomputes the safe-to-remove sweep excluding anything a report displays. Field references are reconciled to the open model by name, so the model must be the one the reports bind to.

For published reports, analyze_cloud_reports does the same against the live service and list_reports finds which published reports bind to the open model. Because the Fabric report-definition API has no read-only scope, the cloud path requires a write-capable Fabric scope and an explicit consent=true (the behaviour stays read-only: Semanticus never modifies a report). Any report it cannot read (a paginated report, an encrypted sensitivity label, a download error) is reported as unreadable with a reason, never silently dropped, so "safe" is never overstated.

Remove what is safe, in one step

The sweep has an act half. On the tab, every removal candidate row carries a free delete (with a verdict-aware confirm, and it is undoable), and the header offers Remove all N safe to remove. Over MCP the same act is remove_safe_objects. Either way, the engine does not trust a stale screen: the safe set is recomputed server-side and every item is re-verified at the moment of deletion, so an item whose verdict changed since your scan (something now references it, a report displays it) is skipped with a plain reason, never deleted stale. The still-safe set is deleted as one undoable transaction, a single audit record carries the removed and skipped evidence, and dry_run rehearses the whole sweep, including the would-be removed and skipped lists, without touching anything.

Removing one item at a time is free (the same per-item delete as delete_object); removing more than one in a single step is Pro, and the refusal names the free path.

Free

Lineage, impact and safe-to-remove analysis are in the free tier, and so is removing items one at a time. See Pro for the one-click bulk engine that removes or applies a reviewed batch in one undoable transaction.