v0.2.58
LATESTTHE WORLD BOUNDARY
A DVT project has two worlds. sources.yml is the client's — systems DVT reads and never writes. Everything DVT lands is DVT's, recorded in the ledger. A relation is never both. The founder's demo showed what happens when the line blurs: seven federated models fed by client sources, and seven base views fed by… those models' own outputs, declared back as sources and depended on as if they were the client's. The catalog drew two disconnected layers; retract's declared-source protection would have shielded DVT's own tables from DVT. The founder's ruling — 'dvt should have failed to create them' — is now law: dvt parse refuses a model that reads a DVT-landed relation through source(), in dbt's own error shape, naming the model, the source, the owning model and the fix. config-checkup names the same state as repairable and config-fix rewrites the call to ref(), restoring lineage in one command. Identity is the relation (connection + landed name), never the bare name — a client table and a same-named model on another engine are two different things.
ADDED
- ▸The parse gate's second DVT validation (beside the ephemeral-federation refusal): a model reading a DVT-landed relation via source() fails the parse with exit 2 — nothing runs — and the error names the owning model and both remedies.
- ▸config-checkup reports every such model as a fixable finding, and the shadowing declaration itself as a manual item; config-fix rewrites the exact source('s','t') call to ref('owner') with a .bak, then the next checkup is clean.
FIXED
- ▸dvt run's own lines used two clocks — UTC on the per-model START/OK lines, local on the header and summary — so a single run read as three hours apart from itself. One clock now.
Get it: pip install dvt-core==0.2.58 · wheels on PyPI for macOS (arm64 + x86_64) and Linux x86_64, Python 3.10–3.14 — the full platform matrix.