Skip to content

Commit da518b2

Browse files
authored
Map dbt upstream references
Add a public-safe dbt upstream source reference map and update PLAN.md with source-grounded compatibility methodology.
1 parent 65dabb5 commit da518b2

2 files changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# dbt Upstream Reference Map
2+
3+
This note maps dbt upstream source code to the dxt Zig ownership model. It is a
4+
planning reference, not a vendoring plan. dxt should keep using dbt execution and
5+
artifact schemas as validation oracles, but feature work should also name the
6+
upstream source files that define the behavior being matched.
7+
8+
Use dbt Core `1.latest` as the observed compatibility contract for M1/M2 parity:
9+
parse the same fixture or project with dbt and dxt, compare normalized JSON
10+
artifacts, and validate against pinned dbt schemas. Use dbt Core v2 / Fusion
11+
`main` as an architecture reference for performance, static analysis, Parquet
12+
metadata, adapter capability shape, and semantic-layer direction. Because v2 is
13+
alpha, it should not override v1 output parity unless the behavior is already
14+
observable in published artifacts or dbt Core-compatible outputs.
15+
16+
## Source Snapshots
17+
18+
- dbt Core v1 Python implementation: `dbt-labs/dbt-core` branch `1.latest`,
19+
commit `566b75d`.
20+
- dbt Core v2 / Fusion foundation: `dbt-labs/dbt-core` branch `main`, commit
21+
`9141939`.
22+
23+
Do not copy upstream code. Use these paths to identify behavior, artifact fields,
24+
validation cases, and ownership boundaries.
25+
26+
## Slice Method
27+
28+
Every compatibility slice should record:
29+
30+
- upstream v1 reference files and functions or classes;
31+
- upstream v2 / Fusion reference files and functions or structs, when relevant;
32+
- owning dxt Zig module or planned module;
33+
- affected dbt artifact maps and schema files;
34+
- native Zig tests for core logic;
35+
- Python/dbt oracle tests for CLI, filesystem, fixture, or artifact behavior;
36+
- schema validation gates;
37+
- stop conditions that prevent mixed mechanical and behavior changes.
38+
39+
## Reference Areas
40+
41+
| Compatibility area | Upstream v1 references | Upstream v2 / Fusion references | dxt owner |
42+
| --- | --- | --- | --- |
43+
| Project load and parse order | `core/dbt/parser/manifest.py::ManifestLoader.load`, `parse_project`, `load_and_parse_macros`, `load_macros`, `process_sources`, `process_refs`, `process_docs`, `process_metrics`, `process_unit_tests`, `cleanup_disabled`, `_backfill_direct_parents`, `write_manifest` | `crates/dbt-loader/src/loader.rs::load`, `load_inner`, `load_dbtignore`, `collect_paths`, `merge_vars`; `crates/dbt-parser/src/resolver.rs::resolve`, `resolve_inner`, `resolve_package_waves` | Current `src/project.zig`; future `src/project/loader.zig` orchestration with resource-specific work delegated to `config`, `fs`, `parse`, `jinja`, and `resolve` |
44+
| Parse-time node creation and config | `core/dbt/parser/base.py::ConfiguredParser`, `_create_parsetime_node`, `render_with_context`, `update_parsed_node_config`, `update_parsed_node_relation_names`, `render_update`, `add_result_node`, `parse_node` | `crates/dbt-parser/src/renderer.rs::render_sql_file_inner`, config resolver calls, disabled root-overlay handling, final status/config resolution | `src/project/config.zig`, `src/project/jinja.zig`, future `src/project/parse.zig` resource parsers and `src/project/compiler.zig` |
45+
| Macro parsing | `core/dbt/parser/macros.py::MacroParser`, `parse_macro`, `parse_unparsed_macros`, block types `macro`, `materialization`, `test`, `data_test` | `crates/dbt-parser/src/resolver.rs` macro resolution; `crates/dbt-parser/src/renderer.rs` macro dependency listener | Current macro scanning in `src/project.zig` plus `src/project/jinja.zig`; future `src/project/parse.zig` macro parser and `src/project/resolve.zig` namespace resolver |
46+
| Macro namespace and dispatch | `core/dbt/context/macros.py::MacroNamespace`, `_search_order`, `MacroNamespaceBuilder.add_macro`, `add_macros`, `build_namespace` | `crates/dbt-parser/src/resolver.rs` macro unit construction and package runtime config; adapter dispatch references in adapter/Jinja crates | `src/project/resolve.zig` for lookup semantics; future `src/project/jinja.zig` or `src/project/macro.zig` for executable namespace and dispatch |
47+
| YAML properties and resource patches | `core/dbt/parser/schemas.py::SchemaParser`, `SourceParser`, `PatchParser`, `ModelPatchParser`, `MacroPatchParser`; `core/dbt/parser/schema_yaml_readers.py::ExposureParser`, `MetricParser`, `SemanticModelParser`, `SavedQueryParser` | `crates/dbt-parser/src/resolver.rs::resolve_inner` resource order: sources, seeds, snapshots, groups, models, analyses, functions, exposures, semantic models, metrics, saved queries, data tests, unit tests | Current `src/project.zig` YAML routines and `src/project/parse.zig` helpers; future `src/project/parse.zig` plus narrower modules if needed |
48+
| Exposure, source, ref, metric dependency resolution | `core/dbt/parser/manifest.py::_process_refs`, `_process_sources_for_node`, `_process_sources_for_exposure`, `_process_metrics_for_node` | `crates/dbt-jinja-utils/src/node_resolver.rs::resolve_dependencies`; `crates/dbt-parser/src/resolver.rs` access validation, relation uniqueness, primary-key inference | `src/project/resolve.zig`; current higher-level orchestration still in `src/project.zig` |
49+
| Parse vs runtime Jinja context | `core/dbt/context/providers.py::ParseProvider`, `RuntimeProvider`, `ProviderContext.ref`, `source`, `execute`, `var`, `graph`, `env_var`, `selected_resources`, `generate_parser_model_context`, `generate_runtime_model_context`, `generate_parse_exposure`, `generate_parse_semantic_models` | `crates/dbt-parser/src/renderer.rs` execute=false render, static source recovery behind false branches, hook dependency rendering; `crates/dbt-parser/src/dbt_namespace.rs` parse-mode interception of `get_relation` and `get_columns_in_relation` | Current lexical `src/project/jinja.zig`; future parse context and compile/runtime context modules before M2 |
50+
| Manifest data model and maps | `core/dbt/contracts/graph/manifest.py::Manifest` maps for nodes, sources, macros, docs, exposures, metrics, groups, selectors, files, disabled, semantic_models, unit_tests, saved_queries, fixtures; `build_flat_graph`, `build_parent_and_child_maps`, lookup rebuilders, resource adders | `crates/dbt-schemas/src/schemas/manifest/manifest.rs::build_manifest`, `build_disabled_map`, `build_parent_and_child_maps`, path normalization, `nodes_from_dbt_manifest` | `src/project/types.zig`, `src/project/manifest.zig`, `src/project/resolve.zig` |
51+
| Selector grammar and methods | `core/dbt/graph/selector_spec.py`, `selector.py`, `selector_methods.py`, `cli.py`, `graph.py`, `queue.py`; methods include FQN, tag, group, access, source, exposure, metric, semantic_model, saved_query, unit_test, path, file, package, config, resource_type, test_name, test_type, state, result, source_status, version, selector | `crates/dbt-parser/src/resolver.rs` selector YAML loading; command flags in `crates/dbt-clap-core/src/commands.rs` | `src/project/selector.zig` and CLI validation in `src/root.zig`; future state/result/source-status work in `src/project/state.zig` |
52+
| Artifact schemas | `schemas/dbt/manifest/v12.json`, `schemas/dbt/run-results/v6.json`, `schemas/dbt/sources/v3.json`, `schemas/dbt/catalog/v1.json` | v2 still emits JSON for compatibility and adds Parquet artifacts per README; manifest builder in `crates/dbt-schemas/src/schemas/manifest/manifest.rs` | `src/project/manifest.zig`, future run/catalog/source writers and schema validators under tests/scripts |
53+
| Command surface | dbt v1 command behavior through parser/runner contracts and artifacts | `crates/dbt-clap-core/src/commands.rs::CoreCommand`, static-analysis flags and command parsing | `src/root.zig`, `src/main.zig`, future command-specific modules |
54+
| Adapter capability and SQL identity | v1 adapter behavior is distributed across adapters and context providers | `crates/dbt-adapter-core/src/lib.rs::AdapterType`, `quote_char`, static-analysis support matrix, microbatch capability; `crates/dbt-adapter-sql/src/ident.rs`, `statements.rs`, `types/*` | Future `src/project/adapter.zig`, `src/project/sql.zig`, and cross-database planner modules |
55+
| Fusion-style scalable artifacts | v1 JSON artifacts remain the base compatibility contract | README v2 notes JSON compatibility plus Parquet artifacts; `crates/dbt-index-core/src/ingest/ingest_state.rs`, `crates/dbt-index-core/src/db.rs` define metadata parquet directories and DuckDB views under `dbt.*` and `dbt_rt.*` | Future parse cache/state store, not M1 product behavior |
56+
| Semantic layer and metrics | `schema_yaml_readers.py::MetricParser`, `SemanticModelParser`, `SavedQueryParser`; `manifest.py::process_metrics`, semantic manifest validation and writer | `crates/dbt-schemas/src/schemas/semantic_layer/*`, `crates/dbt-schemas/src/schemas/manifest/semantic_model.rs`, `crates/dbt-parser/src/resolve/resolve_semantic_models.rs`, `crates/dbt-parser/src/resolve/validate_semantic_models.rs`, `crates/dbt-metricflow/*` | Future `src/project/semantic.zig`, semantic manifest writer, metric planner; M1 should keep empty maps schema-valid until implemented |
57+
58+
## Current dxt Baseline
59+
60+
- Product runtime is Zig and remains so.
61+
- Current implemented command surface is `parse`, `ls`, `version`, and help;
62+
`compile`, `build`, and `docs generate` are placeholders.
63+
- `src/project.zig` is still the facade plus remaining loader/resource parser
64+
orchestration. It owns high-level graph loading, installed-package resource
65+
loading, docs block parsing, macro block parsing, YAML source/exposure/model
66+
property parsing, model/seed parsing, generic-test materialization, warnings,
67+
and remaining resolver orchestration.
68+
- Existing extracted modules are `types`, `util`, `config`, `fs`, `jinja`,
69+
`resolve`, `parse`, `selector`, and `manifest`.
70+
- The test base includes native Zig tests for module-level helpers and pytest
71+
integration tests for CLI/artifact fixtures plus a pinned local Manifest v12
72+
schema slice.
73+
- M1 should not be treated as closed until the project has a reproducible
74+
public Jaffle Shop DuckDB parse gate, a dbt-vs-dxt oracle harness for the M1
75+
fixture ladder, and documented schema-slice expansion rules for fields beyond
76+
the current emitted manifest surface.
77+
- M2 implementation should wait until M1/M1A gates above are either complete or
78+
explicitly re-scoped. A source-grounded M2 preplan can proceed first because
79+
it will clarify parse-time Jinja, macro namespace, adapter dispatch, and
80+
compiled artifact boundaries without changing product behavior.
81+
82+
## Next Five Source-Grounded Slices
83+
84+
### 1. M1A Loader Facade Extraction
85+
86+
- Upstream references: v1 `ManifestLoader.load`; v2 `dbt-loader/src/loader.rs`,
87+
`dbt-parser/src/resolver.rs::resolve`.
88+
- dxt files: create `src/project/loader.zig`; shrink `src/project.zig` to call
89+
loader and manifest/selector facades.
90+
- Tests: native Zig smoke test for loader orchestration over an in-memory or
91+
temp fixture if practical; keep pytest fixture coverage unchanged.
92+
- Artifact validation: existing Manifest v12 slice for all parse fixtures.
93+
- Stop conditions: stop if extraction changes resource counts, selector output,
94+
manifest ordering, or diagnostics.
95+
96+
### 2. M1 Source and Exposure YAML Parser Ownership
97+
98+
- Upstream references: v1 `SourceParser`, `ExposureParser`,
99+
`_process_sources_for_exposure`; v2 `resolve_sources`, `resolve_exposures`.
100+
- dxt files: move source/exposure YAML parsing from `src/project.zig` into
101+
`src/project/parse.zig` or a follow-up `src/project/schema.zig`.
102+
- Tests: native tests for source tables, exposure owners, maturity, URL,
103+
`ref`, `source`, and unsupported dependency forms; pytest for fixture
104+
manifests and `ls source:` / `ls exposure:` behavior.
105+
- Artifact validation: Manifest v12 source/exposure entries, parent/child maps,
106+
and `depends_on.nodes`.
107+
- Stop conditions: do not add semantic metrics or new selector behavior in this
108+
extraction.
109+
110+
### 3. M1 Macro Block and Macro Patch Parity
111+
112+
- Upstream references: v1 `MacroParser`, `MacroPatchParser`,
113+
`MacroNamespaceBuilder`; v2 resolver macro phases and renderer macro
114+
dependency listener.
115+
- dxt files: move macro block parsing and macro property parsing ownership out
116+
of `src/project.zig`; extend `src/project/jinja.zig` only for lexical helpers.
117+
- Tests: native tests for macro/materialization/test/data_test block extraction,
118+
package-qualified macro IDs, argument patch merge, and namespace precedence.
119+
- Python/dbt oracle: compare macro manifest entries and model macro dependencies
120+
on synthetic package fixtures.
121+
- Artifact validation: Manifest v12 `macros` map and `depends_on.macros`.
122+
- Stop conditions: do not implement macro execution or adapter dispatch in the
123+
same slice.
124+
125+
### 4. M2 Parse-Time Jinja Context Boundary
126+
127+
- Upstream references: v1 `ParseProvider`, `RuntimeProvider`, provider methods
128+
for `ref`, `source`, `config`, `var`, `env_var`, `execute`, `this`, `graph`,
129+
`selected_resources`; v2 `renderer.rs` execute=false rendering,
130+
`dbt_namespace.rs` adapter introspection capture.
131+
- dxt files: future parse-context module plus `src/project/jinja.zig` scanner
132+
integration and eventual compiler module.
133+
- Tests: native tests for `execute`-guarded calls, unsupported `run_query` at
134+
parse time, var/env defaults, and hook dependency capture; pytest/dbt oracle
135+
for compiled SQL and manifest dependency parity.
136+
- Artifact validation: manifest `refs`, `sources`, `depends_on`, `config`, and
137+
later compiled SQL outputs.
138+
- Stop conditions: do not start warehouse execution or DuckDB adapter behavior
139+
until parse/compile context behavior has deterministic fixtures.
140+
141+
### 5. M1/M2 Artifact Schema Expansion
142+
143+
- Upstream references: v1 `Manifest` maps and artifact schemas
144+
`manifest/v12.json`, `run-results/v6.json`, `sources/v3.json`,
145+
`catalog/v1.json`; v2 `build_manifest` and JSON compatibility notes.
146+
- dxt files: `src/project/manifest.zig`, future run-results/source/catalog
147+
writer modules.
148+
- Tests: native deterministic JSON escaping/ordering tests plus pytest schema
149+
validation against pinned schema slices that grow only when dxt emits the
150+
corresponding fields.
151+
- Python/dbt oracle: normalize invocation IDs, timestamps, elapsed time,
152+
adapter responses, and absolute paths before comparison.
153+
- Stop conditions: never invent dbt field names; keep dxt-only metadata in a
154+
namespaced artifact outside dbt schemas.

PLAN.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,43 @@ Normalize:
251251
- Absolute paths where dbt emits them.
252252
- Adapter response fields known to differ.
253253

254+
## Source-Grounded Compatibility Method
255+
256+
dbt execution remains the artifact and behavior oracle, but future compatibility
257+
slices must also name the upstream source files that define the behavior being
258+
implemented. The public source map lives in
259+
`.agent/research/dbt-upstream-reference-map.md`.
260+
261+
Every compatibility slice must record:
262+
263+
- dbt Core v1 source references and, when relevant, dbt Core v2 / Fusion source
264+
references.
265+
- The owning dxt Zig module or planned module.
266+
- The dbt artifact maps and pinned schemas affected.
267+
- Native Zig tests for parser, selector, graph, manifest, Jinja, or adapter core
268+
logic.
269+
- Python/dbt oracle tests for CLI, filesystem fixtures, artifact parity, schema
270+
validation, and public-safety boundaries.
271+
- Stop conditions that keep mechanical extractions separate from behavior
272+
changes and prevent Python from crossing into product runtime behavior.
273+
274+
The next source-grounded M1/M2 slices are:
275+
276+
1. Extract loader orchestration into `src/project/loader.zig`, using v1
277+
`ManifestLoader.load` and v2 loader/resolver order as the reference map.
278+
2. Move source and exposure YAML parser ownership out of `src/project.zig`,
279+
using v1 `SourceParser`, `ExposureParser`, and source processing functions
280+
plus v2 source/exposure resolver phases.
281+
3. Move macro block and macro patch ownership toward parser/resolve modules,
282+
using v1 `MacroParser`, `MacroPatchParser`, and `MacroNamespaceBuilder` plus
283+
v2 macro resolution and dependency listener behavior.
284+
4. Start the M2 parse-time Jinja context boundary with explicit `execute=false`
285+
semantics, using v1 providers and v2 renderer/dbt namespace interception as
286+
references.
287+
5. Grow artifact schema coverage only alongside emitted fields, using v1 JSON
288+
schemas and v2 manifest builder behavior while keeping dxt-specific metadata
289+
out of dbt schemas.
290+
254291
## Fixture Ladder
255292

256293
Tier 0 synthetic fixtures:
@@ -576,3 +613,5 @@ Exit criteria:
576613
- Synthetic fixtures cover one model, model refs, seed refs, source refs, exposure refs to models and sources, combined source/model YAML, inline config/tag selection, config materialization selection, comma-intersection selection, YAML model properties and columns, emitted `unique`, `not_null`, `accepted_values`, and `relationships` generic test nodes, project macro artifacts and macro properties, configured `macro-paths` replacing the default macro directory, installed package macros with package-qualified calls and package-local macro calls, installed package models, seeds, sources, docs, exposures, package YAML model properties, root package config overrides, and package-qualified/package-local refs/sources, macro calls recorded in model and macro `depends_on.macros`, docs blocks with literal `doc` descriptions, disabled models, disabled ref diagnostics, unmatched model-property warnings, duplicate model and docs diagnostics, unsupported dynamic ref/doc diagnostics, missing doc diagnostics, malformed docs block diagnostics, unresolved package macro diagnostics, and unsupported unknown macro-call diagnostics.
577614
- The current M1 manual gate parses the public Jaffle Shop DuckDB project into a partial manifest with SQL models, CSV seeds, docs blocks, project macros, project `+docs.node_color` config, model/test `refs` and `sources` artifact fields, supported generic test nodes including the Jaffle `accepted_values` and `relationships` tests, and selector behavior for `dxt ls` covering whitespace unions, comma intersections, graph expansion, exact package selectors, dbt-style selector wildcards, multi-argv selector lists, and repeated `--select`/`--exclude` flags. Remaining M1 work includes package-provided generic tests/macros beyond the current narrow macro call surface and deeper Jaffle artifact parity.
578615
- Selector wildcard behavior is currently pinned to observed dbt Core 1.10 behavior. dbt Fusion preview currently differs for resource-type-prefixed wildcard selectors such as `model.<package>.*` and filename-suffix path selectors such as `path:*orders.sql`; a future Fusion-compatibility slice must decide whether to support a selector dialect switch or a compatible superset.
616+
- Compatibility planning now uses a source-grounded reference map under `.agent/research/dbt-upstream-reference-map.md`; future feature slices should name upstream dbt v1/v2 source references, dxt Zig owners, affected artifact fields, validation gates, and stop conditions before implementation.
617+
- Before starting M2 product implementation, close or explicitly re-scope the remaining M1/M1A gates: a reproducible committed Jaffle Shop DuckDB parse gate, a dbt-vs-dxt oracle harness for the M1 fixture ladder, and the behavior-preserving `src/project/loader.zig` extraction that keeps `src/project.zig` as a thinner facade.

0 commit comments

Comments
 (0)