core/sdk/dang/README.md
The engine embeds one copy of the Dang runtime per supported Dang major
version and routes each module to the version matching its engineVersion,
so existing modules keep the language semantics they were written against.
../dang_sdk.go (package sdk) — the dispatcher. dangSDK owns all
version-agnostic core.SDK behavior and picks a dangImpl per call via
dangImplFor, comparing the module's engineVersion against the
MinimumDangV*ModuleVersion constants in engine/version.go.shared/ (package dangshared) — version-agnostic plumbing (nested-client
proxy server, client metadata, error conversion). Must never import
github.com/vito/dang of any major.v2/ (package dangv2) — the living implementation, importing
github.com/vito/dang/v2. All feature work happens here. New Dagger
features always require a new engineVersion, which always routes to the
newest major — so frozen majors never need feature work.v1/ (package dangv1) — frozen snapshot for modules with
engineVersion < v0.21.5 (Dang v1: .{ } is selection). Byte-identical to
the living package at snapshot time, modulo package clause, doc comments,
and dang import paths.release/v1 in vito/dang), tag a patch
(e.g. v1.0.x), bump go.mod.core, dagql, engine API churn) will
break frozen packages at compile time; apply the same mechanical fix to all
copies.vN+1.0.0 on a module path with the new major suffix; keep
a maintenance branch for the now-frozen prior major. On that maintenance
branch, rename the tree-sitter grammar's exported C symbols with a _vN
suffix (see pkg/dang/danglang/danglang.go on release/v1): C symbols
share one global namespace, so two majors with identical symbol names
fail to link into the same binary. The canonical tree_sitter_dang names
always stay with the living major so editor integrations keep working.cp -r v2 v3),
then in v3/ rewrite the dang import paths to the new major and the
package clause to dangv3. v2/ is now frozen — update its package doc to
say so (see v1/sdk.go for the wording).MinimumDangV<N+1>ModuleVersion = "<next unreleased dagger version>"
to engine/version.go.dangImplFor (../dang_sdk.go) with one
new case.go get github.com/vito/dang/v<N+1>@v<N+1>.0.0.core/integration/testdata/modules/dang/ to the new gate version so the
main suite exercises the living major, and add a pinned regression module
for any syntax whose meaning changed (see legacy-selection/).toolchains/*, cmd/codegen, modules/markdownlint)
are pinned to the released engine version (the released CLI rejects
configs newer than itself), so they route to the previous major until the
next dagger release ships. Keep them syntax-neutral across the boundary, or
bump them right after the release.engineVersion in a ModuleSource normalizes to the
current engine version (→ newest major); pre-semver configs normalize to
v0.11.9 (→ oldest major).