Correctness · capability table for train 2026.11.26
No two engines have been compared on a train yet.
RunningLake is building a router that chooses a table format and an engine for each workload. Its rules already say which engines may run a job when a plan is checked; routing of live queries is not built. This page shows which engine pairs have been proven to return the same answers, and it claims only what two engines compared and agreed on. Today the evidence files record DuckDB running our corpus, alone. Nothing has been compared, so the matrix below makes no claim.
Writer to reader
Rows write a table, columns read it. The diagonal, a writer reading its own table, is not compared.
Iceberg
| Writes ↓ / reads → | DuckDB | Flink | Spark | StarRocks | Trino |
|---|---|---|---|---|---|
| DuckDB | not compared |
not run
not in v1 | asserted |
not run
not in v1 | asserted |
| Flink |
not run
not in v1 | not compared |
not run
not in v1 |
not run
not in v1 |
not run
not in v1 |
| Spark |
asserted
reader ran alone |
not run
not in v1 | not compared |
not run
not in v1 | asserted |
| StarRocks |
not run
not in v1 |
not run
not in v1 |
not run
not in v1 | not compared |
not run
not in v1 |
| Trino |
asserted
reader ran alone |
not run
not in v1 | asserted |
not run
not in v1 | not compared |
Hudi
| Writes ↓ / reads → | DuckDB | Flink | Spark | StarRocks | Trino |
|---|---|---|---|---|---|
| DuckDB | not compared |
refused
hudi-write-engines
|
refused
hudi-write-engines
|
refused
hudi-write-engines
|
refused
hudi-write-engines
|
| Flink |
refused
hudi-read-engines
| not compared |
not run
not in v1 |
not run
not in v1 |
not run
not in v1 |
| Spark |
refused
hudi-read-engines
|
not run
not in v1 | not compared |
not run
not in v1 | asserted |
| StarRocks |
refused
hudi-write-engines
|
refused
hudi-write-engines
|
refused
hudi-write-engines
| not compared |
refused
hudi-write-engines
|
| Trino |
refused
hudi-write-engines
|
refused
hudi-write-engines
|
refused
hudi-write-engines
|
refused
hudi-write-engines
| not compared |
DuckLake
| Writes ↓ / reads → | DuckDB | Flink | Spark | StarRocks | Trino |
|---|---|---|---|---|---|
| DuckDB | not compared |
refused
ducklake-read-engines
|
refused
ducklake-read-engines
|
refused
ducklake-read-engines
|
refused
ducklake-read-engines
|
| Flink |
refused
ducklake-write-engines
| not compared |
refused
ducklake-write-engines
|
refused
ducklake-write-engines
|
refused
ducklake-write-engines
|
| Spark |
refused
ducklake-write-engines
|
refused
ducklake-write-engines
| not compared |
refused
ducklake-write-engines
|
refused
ducklake-write-engines
|
| StarRocks |
refused
ducklake-write-engines
|
refused
ducklake-write-engines
|
refused
ducklake-write-engines
| not compared |
refused
ducklake-write-engines
|
| Trino |
refused
ducklake-write-engines
|
refused
ducklake-write-engines
|
refused
ducklake-write-engines
|
refused
ducklake-write-engines
| not compared |
How to read it
- agrees Two engines compared on this train and the answers matched. The only word that is a claim.
- disagrees Compared, and the answers differ. We treat a wrong answer as a P0 incident.
- refused A rule of the router, or our capability table, rules the pair out. A refusal is a constraint, not a failure.
- not run No evidence on this train yet.
- asserted Our capability table says so. No two engines were compared. Where the reader ran its own corpus alone, the cell says so; that proves nothing about agreement.
A refusal is not a failure
Some pairs are not offered on purpose. A refused cell reads the rule that refuses it and says what the rule means; nothing was run and nothing went wrong. It means the router's rules refuse the pair when a plan is checked; routing of live queries is not built.
hudi-write-engines- Hudi tables can only be written by Spark or Flink. Trino and StarRocks can read Hudi but cannot write it; DuckDB cannot read it at all.
ducklake-write-engines- DuckLake tables can only be written by DuckDB.
ducklake-read-engines- DuckLake tables can only be read by DuckDB — it is DuckDB's own format, and the other four engines have no reader for it. A table other engines must query is an Iceberg table; DuckLake promotes to Iceberg on growth.
hudi-read-engines- DuckDB cannot read Hudi at all — only the raw Parquet underneath it, which skips the timeline and returns pre-compaction rows. Spark, Trino, StarRocks and Flink read it; Trino reads MoR at snapshot fidelity, which hudi-mor-read-fidelity judges against the declared freshness SLA.
A refusal can also come from our capability table saying an engine cannot write or cannot read a format; such a cell names no rule.
What evidence means
A cell that claims agreement rests on an interop file, and every file has a tier. Every other cell says what it rests on: a rule, the capability table, or nothing yet.
execution- One engine ran the corpus. It shows the engine can do the work and compares nothing, so it never makes a cell agree.
differential- Two engines ran the same corpus and the answers were compared exactly. Deterministic results must match.
interop- One engine writes a table and another reads it, scenario by scenario. It is designed to cover position deletes, schema and partition evolution, time travel and compaction; none of those scenarios has produced a file yet.
The files that exist today:
-
Train
2026.11.26, tierexecution: DuckDB on Iceberg, a corpus of 39 cases, 37 executed, 0 failed. -
Train
2026.11.27, tierexecution: DuckDB on Iceberg, a corpus of 39 cases, 37 executed, 0 failed. -
Train
2026.11.46, tierexecution: DuckDB on Iceberg, a corpus of 171 cases, 169 executed, 0 failed. -
Train
2026.11.49, tierexecution: DuckDB on Iceberg, a corpus of 183 cases, 181 executed, 0 failed.
Where the evidence is
Evidence files are filed in our repository under conformance/evidence/<train>/ (interop files
under format/). A file carries its tier, the engine and format, the digest of the corpus or scenario
set it ran, and counts of cases executed, passed, failed and uncovered. This page is generated from those files, from our capability table and from the router's rules,
and shows nothing they do not hold. A cell that reads asserted rests on the capability
table alone.