Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d4456f1
feat: an end-of-task column impact summary and an offline HTML report
ralphstodomingo Nov 5, 2026
51eb5e4
fix: the impact summary reads the column answer as altimate-code send…
ralphstodomingo Nov 5, 2026
4fd7f37
feat: the impact report lists the cleared models by name
ralphstodomingo Nov 5, 2026
01eece2
fix: the report opens on WSL without wslview, and the summary logs as…
ralphstodomingo Nov 5, 2026
8265bcc
fix: the per-edit note gives Claude the column answer's numbers, and …
ralphstodomingo Nov 5, 2026
26a7a94
feat: the lineage pane opens only when asked
ralphstodomingo Nov 6, 2026
1e4adcb
fix: a cut-off altimate-code answer is a failure, not "no such model"
ralphstodomingo Nov 6, 2026
b25ec9b
feat: report built on demand, leading with what changed and who consu…
ralphstodomingo Nov 6, 2026
b401148
feat: the models a plan names, at the model level, before it is approved
ralphstodomingo Nov 6, 2026
8677383
fix: the report's consumers note and path hint say what is true
ralphstodomingo Nov 6, 2026
cc1b62d
Merge origin/main (1.4.1, 1.4.2, 1.5.0) into feat/column-impact-report
ralphstodomingo Nov 11, 2026
31512d3
feat: column graph beside the summary on the lineage report
ralphstodomingo Nov 11, 2026
ff5a49e
fix: dragging the column graph no longer selects its text
ralphstodomingo Nov 11, 2026
478c178
feat: the per-edit column lookup goes through the altimate CLI
ralphstodomingo Nov 11, 2026
64d63e4
feat: usage events for the lineage report through altimate-code telem…
ralphstodomingo Nov 11, 2026
d1bea72
feat: unlabelled edges where the engine can't tell how the value changes
ralphstodomingo Nov 11, 2026
02a843d
feat: `/lineage-report <model>.<column>` opens the report for any column
ralphstodomingo Nov 11, 2026
9f62178
fix: a click on a graph column counts when the pointer drifts a little
ralphstodomingo Nov 11, 2026
462251f
fix: an older altimate-code's missing column answer reads as "update …
ralphstodomingo Nov 12, 2026
6947714
fix: each session keeps its own manifest copies, so another session's…
ralphstodomingo Nov 12, 2026
a9bda04
fix: the report's path bar floats over the page instead of pushing it…
ralphstodomingo Nov 12, 2026
1cf43a2
fix: the report's graph reads at first sight, on a phone and from the…
ralphstodomingo Nov 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ Turn off recording and drafting with `altimate learn disable` in the project, or

The delegation path below runs only when the delegation skill or the `/altimate-code:altimate` command fires and invokes the locally installed altimate-code CLI.

## The lineage report

The column impact report is one HTML file that the plugin writes to the project's `target/.altimate-lineage/` and opens in your browser. The page loads nothing from the network: its content-security policy allows only its own inline script and style.

To learn whether the report gets used, the plugin asks the local altimate-code CLI (`altimate-code tool report-event`) to send one usage event, `lineage_report`, at each of these steps:
- the summary was shown;
- **Open report** was pressed;
- `/lineage-report` was run;
- the report was built, failed to build, or found no browser.

Each event carries the step and the Claude Code session id (`claude:<id>`) only: no model, column, file or project names. It goes through Altimate's usage telemetry, described in [Usage telemetry](#usage-telemetry), and that section's opt-out turns it off. With an altimate-code that predates the command, nothing is sent.

## Data flows when a task is delegated

| Data | Where it goes | Retention |
Expand Down Expand Up @@ -128,6 +140,8 @@ The plugin and the altimate-code CLI are professional developer tools, not direc

We will update this document in this repository and revise the effective date when our practices change. Material changes to Altimate-wide practices are governed by the master [Privacy Policy](https://www.altimate.ai/privacy).

**Next release:** added [The lineage report](#the-lineage-report): the offline report page, and the usage events the altimate-code CLI sends for it.

**November 10, 2026:** added [Workspace rules](#workspace-rules) (the workspace-rules hooks and `/altimate-code:rules` in plugin 1.5.0), and the rules telemetry the altimate-code CLI sends.

## Contact
Expand Down
14 changes: 14 additions & 0 deletions plugins/altimate-code/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to this plugin will be documented in this file.

## [Unreleased]

### Added
- End-of-task column impact: after a task that changed a dbt model, a band sums up each changed column's downstream reach from `impact_analysis`. The task's start copies `target/manifest.json` aside, so the answer reflects the SQL before the task.
- An offline HTML report, built when **Open report** or `/lineage-report` asks for it: what changed and what to expect downstream in plain words, who consumes it from dbt exposures, then upstream and downstream lineage, two levels by default, and click-to-highlight paths.
- `/lineage-report <model>.<column>` opens the same report for any column, with no task behind it: where the column comes from first, then where its value goes. It reads the project's manifest as it is now, writes its own file beside the task's report, and an unknown model or column gets a plain error.
- When a plan goes up for approval, a line above the dialog gives the downstream models, tests and exposures of each model the plan names.
- Usage events for the report, through altimate-code's telemetry (`tool report-event`): the summary shown, **Open report** pressed, `/lineage-report` run, and the report built, failed or with no browser. The step and the session id only, off under the telemetry opt-out. See PRIVACY.md.
- The report draws the column lineage as a graph beside the summary: upstream on the left, downstream on the right, opened to fit, with zoom and pan. A click lights a column's path, "more levels" adds one, and a level of more than 12 models folds into one box. The page allows only its own inline script and style. An edge carries a label only when the engine told how the value changes (same, renamed, calculated, aggregated); the rest are dashed and unlabelled, and a note under the graph says so. A click on a column counts even when the hand drifts a few pixels (up to 12) before letting go; a longer drag still pans.

### Changed
- The per-edit impact note no longer shows as a toast and band; it still goes to Claude's context with the edit's result. A lookup that missed its time or failed still shows a toast.
- The per-edit column lookup goes through the altimate CLI instead of the MCP server, so it raises no permission prompt in accept-edits mode and a large column answer arrives whole.

## [1.5.0] — 2026-11-10

### Added
Expand Down
7 changes: 5 additions & 2 deletions plugins/altimate-code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,17 @@ The side pane and band need a Claude Code build with hooks modules and `altimate

## Lineage beside the chat

The plugin's lineage pane follows the dbt model Claude reads or edits (by Read, Edit, a shell command that names or finds its `.sql` file, or a `dbt_lineage` call), read from `target/manifest.json` with no model calls. A project with no manifest still gets its graph, read from the models' `ref()` and `source()` calls; columns, dashboards and column reach then need `dbt parse` or `dbt compile`. From a monorepo's root, `/lineage <model>` finds the dbt project below it that has the model:
The plugin's lineage pane follows the dbt model Claude reads or edits (by Read, Edit, a shell command that names or finds its `.sql` file, or a `dbt_lineage` call), read from `target/manifest.json` with no model calls. The end-of-task summary's **Open lineage** opens it too. A project with no manifest still gets its graph, read from the models' `ref()` and `source()` calls; columns, dashboards and column reach then need `dbt parse` or `dbt compile`. From a monorepo's root, `/lineage <model>` finds the dbt project below it that has the model:

- **The graph.** The model's whole lineage as boxes and arrows, like dbt-lineage-viewer: every level upstream on the left and downstream on the right, every model, every name in full, dashboards (exposures) marked ◆. The pane is a window onto the drawing. A graph too big for Claude Code to draw in a pane is shown as folders instead, and the header says so; `v` switches to the other views. Scroll it up and down with the mouse, touchpad or arrow keys, pan it with `h` and `l` (or ◀ ▶), and `f` brings the model back to the middle. Links between models on the same level, or that skip a level, are not drawn. Press a model to follow it. With a column picked, the models and dashboards that read it are highlighted and the rest dimmed.
- **Views for big projects.** `v` cycles the graph, **ends only** (the sources and dashboards the model sits between; "via N" counts the models between them on the shortest path), **folders** (sources, staging, intermediate, marts and dashboards as one box each, with counts, in dbt layer order: a source-to-mart chain on one screen) and the text **list** of upstream and downstream. A pane narrower than 48 columns shows the list. The pane keeps up to 500 models upstream, and through altimate-code (a manifest over 4 MiB) up to 500 downstream too; past that the header says which side was cut.
- **What the answer is about.** Once the session has seen a dbt project, after each answer the models Claude named are listed under the header (IN THE ANSWER), each a press away. When Claude answered without reading any model that turn (from what it read earlier), the pane follows the first model it named, so the lineage shown matches the answer.
- **Columns.** Each output column with its source columns and how it is derived, from altimate-code's `dbt_lineage`, read from the compiled manifest (`dbt compile`). The plugin's calls are read-only, so altimate-code never starts the project's dbt adapter for them.
- **Column reach.** `c` picks a column; the pane shows the downstream models whose SQL reads it and the dashboards on them, from `impact_analysis` (it traces each downstream model's compiled SQL, renames included). Models that name the column only in a filter or join, or that could not be traced (no compiled SQL), are listed apart, and the count is then a lower bound.
- **Impact first.** Before an edit to a model's SQL lands, the plugin checks what reads the model and the reach of every column the edit touches (up to three, merged). It tells a touched column from the model's own lineage (what the pane already read, or `dbt_lineage` through the CLI), so a column `schema.yml` leaves out still counts. It shows the result as a toast, adds it to Claude's context with the edit's result, and leaves a band above the prompt with the severity (impact_analysis' thresholds) and counts.
- **Impact first.** Before an edit to a model's SQL lands, the plugin checks what reads the model and the reach of every column the edit touches (up to three, merged). It tells a touched column from the model's own lineage (what the pane already read, or `dbt_lineage` through the CLI), so a column `schema.yml` leaves out still counts. It adds the result to Claude's context with the edit's result. You see the summary at the end of the task, not a note per edit; a toast says so when the lookup missed its time or failed and the edit went ahead without it.
- **End-of-task summary.** When a task (one prompt and Claude's work on it) changed a model, by an edit or a shell command git sees, a band above the prompt says what changed and how far it reaches: each changed column (up to three per model) with the columns, models and end columns downstream that carry its value, the models that may carry it and those cleared, next to the model-level count, and a line when some models could not be read. The trace reads a copy of `target/manifest.json` taken when the task started, so a recompile mid-task does not change the answer. These lookups go through the CLI, so they raise no permission prompt.
- **The report, on demand.** **Open report** or `/lineage-report` builds an offline HTML report of the last task that changed a model and opens it in the browser (`target/.altimate-lineage/report.html`). It leads with what changed, before and after, what to expect downstream in plain words, and who consumes it: the dbt exposures on the model or downstream, grouped by whether they read a model the value reaches, and a plain statement when the project declares none. Only declared exposures appear: other BI tools and backend services do not. Under that are two levels upstream and downstream (more on request), and a click on any column lights up its path. Nothing is written until you ask. What it reads was kept when the task ended (`task-manifest.<session>.json`, `last-task.json`), so asking later, after other turns or a restart, still describes that task, and it says if a file has changed since. Each session keeps its own copy of the manifest, and copies a day old are removed. A later task that changes a model replaces it. The band's button goes when the next turn starts; `/lineage-report` keeps working.
- **Before a plan.** When Claude puts a plan up for approval, the plugin looks for the models the plan names and adds one line above the dialog with each one's downstream models, tests and exposures, at the model level. It holds nothing back and spends no model tokens. The band shows the same once the dialog closes, until the task's summary takes over. It goes by the names in the plan's text, so a model it mentions may not be one it changes, and "the staging models" finds nothing. Leaving plan mode with shift+tab shows nothing.
- **Warehouse lineage.** When a connected MCP server offers Altimate's `table_lineage` (Snowflake) or `databricks_table_lineage`, the pane adds what the warehouse's query history shows for the model's table. The plugin calls a tool of that name on whichever connected server offers it, itself and without a permission prompt, and sends it the model's `database.schema.table`. It does so only when you ask for the model (`/lineage`, a press in the pane, or `r`), never when the pane follows one of Claude's reads.
- **Claude's own lineage calls.** A `dbt_lineage` result is drawn as a list of edges colored by how each column is derived; ctrl+o keeps the original output under it.

Expand Down
Loading
Loading