Weld is graph-first. Generated files are an output of the graph and plan, not
the primary internal model.
Core Stages
Weld.Manifestloads and validates a repo-local manifest.Weld.Workspace.Discoveryfinds projects from manifest globs,blitz_workspace, or filesystem fallback.Weld.Workspaceloads each Mix project sequentially and normalizes dependencies.Weld.Graphstores project nodes, classified edges, publication roles, external deps, and violations.Weld.Planresolves one artifact boundary and computes the selected closure.Weld.Projectorgenerates the standalone Mix project (routing to Weld.Projector.Monolith for monolith artifacts), merged application module when needed, and lockfile.Weld.Verifiervalidates the generated project using a mode-specific gate.Weld.Releaseprepares and archives deterministic release bundles.
Graph Model
Projects are classified independently from publication role.
Classification:
:runtime:tooling:proof:ignored
Publication role:
:default:internal_only:separate{:optional, feature_id}
Internal edges are classified by execution meaning:
:runtime:compile:test:docs:tooling:dev_only
Views such as :package, :test, and :docs are computed by filtering those
edge kinds.
External dependencies are also normalized. If a selected workspace project
refers to an external package through :path, :git, or :github, the
manifest must declare the canonical publishable dependency shape. The graph and
plan operate on that normalized external edge, not the local transport detail.
Dependencies without a version requirement are permitted when opts includes
:git or :github.
Projection Modes
Package-Projection Mode (default)
Artifacts with mode: :package_projection (or no mode key) generate a
component-preserving layout under dist/hex/<package>/:
dist/hex/<package>/
mix.exs
projection.lock.json
lib/<otp_app>/application.ex
components/
apps/core/
apps/web/
core/contracts/
test/This keeps the source graph legible inside the generated package without turning the output into a second hand-maintained source tree.
Monolith Mode
Artifacts with mode: :monolith merge all selected packages into a single flat
project under dist/monolith/<package>/:
dist/monolith/<package>/
mix.exs
projection.lock.json
lib/<otp_app>/application.ex
lib/
(merged sources from all selected packages)
test/
<package_slug>/
(tests per selected package)
support/
<package_slug>/
(test support per selected package)
weld_helpers/
<slug>_test_helper.exs
config/
config.exs
dev.exs / test.exs / prod.exs
sources/
<slug>/config.exs (sanitized: workspace-app config calls stripped)
runtime_sources/
<slug>/config.exs (original, used at runtime bootstrap)
priv/
repo/migrations/ (single-repo layout)
weld_repos/<slug>/ (multi-repo layout)Key behaviors in monolith mode:
- File merging: conflicting source files are renamed with a
<slug>__prefix. Afile_remapslist in the projection result records all renames. - Config sanitization: static config copies strip workspace-app config calls
so they do not interfere with the merged config tree. Original files are kept
under
runtime_sources/for bootstrap reads at startup. - Migration merging: migrations with the same timestamp prefix are
re-stamped with a deterministic offset derived from
project_id,filename, and sort index. A.weld_remap.jsonrecords any renames. - Test helper synthesis: each selected package's
test_helper.exsis parsed,ExUnit.startcalls are extracted and merged, and a roottest/test_helper.exsis generated that dispatches to per-package helper fragments. - Explicit source-only test support: when monolith tests depend on
non-selected workspace projects,
monolith_opts[:test_support_projects]turns that source-only support set into an explicit manifest contract and the copied support code is staged undertest/support/weld_projects/. - Monolith application module: the generated
Applicationmodule bootstraps per-package config at startup usingConfig.Reader.read_imports!before starting any OTP application children, and the bootstrap app allowlist is derived only from staged bootstrap sources. - Test baseline gate: verification runs each selected package's own test suite first, then asserts the monolith test count is at least the baseline sum.
Constraints
- project probing stays sequential because
Mix.Project.in_project/4mutates global Mix state - file copying and verification are deterministic
- publish-unsafe external transports must be rewritten through manifest dependency declarations
- the generated artifact is normal Mix, not a custom runtime
- monolith mode rejects source files that use
Application.ensure_all_started/1orApplication.app_dir/1targeting a selected package's OTP app, as these assume standalone package identity that is lost in the merge