Two questions every engineer inheriting a legacy estate asks, and neither one has a grep-shaped answer. They span an ETL job, a schema, an ORM layer, a service, and eight years of commit history at the same time. EKOS compiles all of that into one evidence-backed ledger and answers from it — every claim traceable to the line it came from. This deck is real output from real runs, unedited, including the places it doesn't work yet.
A real estate is an ETL repository, a SQL schema, a columnar warehouse, a backend in one language, a frontend in another, a CI config, and a git history — each of which has a tool that reads it well and nothing that reads them together. So the answer to a cross-boundary question lives in an engineer's head, and that engineer left.
A code indexer sees the code. A lineage tool sees the warehouse. Neither sees the Kettle XML, and no one sees all three at once.
"If I edit step 2 of this 12-step pipeline, what downstream steps and tables am I touching?"
"What does this system contain, who owned which parts, and which parts had exactly one owner?"
Every object, relationship, and claim in EKOS carries evidence pointing back to a real file, line, or commit. Nothing in the deterministic path is inferred; the opt-in LLM tier is layered on top of the compiled data, never in place of it, and never silently. When a relationship isn't backed by real compiled evidence, the diagram says so instead of drawing a line that doesn't exist.
%% No real compiled relationship yet connects these layers to each other.
That comment is generated output, not a caveat added to this slide. The system's posture toward its own gaps is the product.
→ tools/call ekos_impact { "id": "f7238521-...", "direction": "dependents", "max_hops": 5 } ← result { "count": 5, "hops": [ { "hop": 1, "name": "...ktr:4", "via": "FeedsInto" }, { "hop": 2, "name": "...ktr:6", "via": "FeedsInto" }, { "hop": 3, "name": "...ktr:8", "via": "FeedsInto" }, { "hop": 4, "name": "...ktr:7", "via": "FeedsInto" }, { "hop": 5, "name": "...ktr:3", "via": "FeedsInto" } ]}
Directed and kind-filtered — dependents answers "what
do I break," dependencies answers "what do I depend on." The step order
is recovered from real Kettle XML, not from a naming convention or a guess.
filters: - status = 'active' + status = 'active' AND region = 'EU' sources, sinks, joins, aggregates, calculates, unmapped: unchanged
The exact reassurance a migration needs and code review can't give: the two pipelines are compiled to the same intermediate representation, so the diff is over logic, not over text in two different languages.
This ran as a real end-to-end benchmark, not a demo script — a real Pentaho job and a real SQL redraft through the full pipeline, queried only through the MCP tools. Coverage: zero unmapped nodes on either side, every explanation step evidenced.
→ tools/call ekos_dependents { "id": "a77168f6-..." } ← result { "target": { "kind": "Table" }, "dependents_count": 0, "dependencies_count": 0 }
A real .ktr in the same
workspace writes exactly this table. But the SQL Table object and
the Pentaho Sink node referencing it by name aren't yet resolved to
one identity with an edge between them.
Worth knowing before you rely on cross-format impact for a table that only Pentaho touches. It's on the record because a tool you can't calibrate is a tool you can't use for a deploy decision.
The git analyser compiles change patterns into real
graph relationships: files that consistently change together become
CoupledWith edges — hidden coupling no import graph shows — and
authorship over a path becomes OwnedBy. Commit messages get
semantic labels, so "which changes were breaking" is a query rather than an afternoon of
scrolling.
On a system whose authors are gone, this is the closest thing to a rationale record that still exists — and unlike a wiki, it can't be stale, because it is the history.
Files that change together, whether or not they reference each other.
Who actually touched this path — and which modules only ever had one person.
EKL supports AS OF <timestamp>: ask what the system looked like before the change.
// a real auth module Plausible.Auth.Password → exactly its 3 real functions // a real controller PlausibleWeb.AuthController → exactly 9 real dependency edges
Counts that merely look plausible are the failure mode of every "AI reads your codebase" tool. These were read out of the compiled ledger and then checked against the real source, line by line.
The compiled result also names its own uncertainty: a real ClickHouse
dependency with no schema recovered renders as
"ClickHouse Database (config only, no tables compiled)" — a
genuinely different fact from "no dependency," and kept visibly different.
| Gap | Status |
|---|---|
| SQL Table ↔ Pentaho Sink identity | Not resolved to one identity — cross-format impact returns 0 for these tables |
| Identity over-merging | 6 of 15 real ClickHouse tables merged into one by the resolver; found live, reported openly |
| Data ownership / lifecycle | Blocked on a Table→File link and per-file (not per-commit) ownership derivation |
| Deployment view | No Terraform/K8s extractors — CI/CD pipelines only |
| Frontend → Backend edges | Deliberately unattempted; route/fetch matching is lower confidence than the rest |
| ClickHouse schema without a live connection | Config-only, and labeled as such rather than inferred |
Two real SQL parser gaps in this list were closed after being found this way. The rest are open, and the honest label is what makes the working parts trustworthy.
# compile the estate into one ledger $ ekos init $ ekos build && ekos recover && ekos resolve && ekos compile && ekos commit # what breaks if I touch this? $ ekos mcp serve # ekos_impact / ekos_dependents / ekos_transformation_diff # what did this look like before the change? $ ekos ekl "... AS OF 2026-01-01"