pub trait Adapter: Send + Sync {
// Required methods
fn name(&self) -> &'static str;
fn manifest_files(&self) -> &'static [&'static str];
fn lock(&self, ctx: &AdapterCtx) -> AdapterResult<LockOutcome>;
fn build(&self, ctx: &AdapterCtx) -> AdapterResult<BuildSpec>;
fn plan(&self, ctx: &AdapterCtx, intent: &PlanIntent) -> AdapterResult<Plan>;
fn confirm(&self, ctx: &AdapterCtx) -> AdapterResult<ConfirmReport>;
fn diff(
&self,
ctx: &AdapterCtx,
against: &DiffRef,
) -> AdapterResult<DiffReport>;
fn sbom(&self, ctx: &AdapterCtx, format: SbomFormat) -> AdapterResult<Sbom>;
// Provided methods
fn quirks_registry(&self) -> Vec<AdapterQuirkEntry> { ... }
fn dispatcher_reflection(&self) -> Vec<DispatcherVariant> { ... }
}Expand description
The canonical SDLC trait. Each ecosystem adapter implements one.
Required Methods§
Sourcefn name(&self) -> &'static str
fn name(&self) -> &'static str
Short ecosystem identifier (e.g. "cargo", "npm", "bundler").
Used for routing operator commands + matching manifests.
Sourcefn manifest_files(&self) -> &'static [&'static str]
fn manifest_files(&self) -> &'static [&'static str]
Manifest filenames this adapter recognizes — the first one found in the workspace dispatches to this adapter. Examples:
- cargo:
["Cargo.toml"] - npm:
["package.json"] - bundler:
["Gemfile"]
Sourcefn lock(&self, ctx: &AdapterCtx) -> AdapterResult<LockOutcome>
fn lock(&self, ctx: &AdapterCtx) -> AdapterResult<LockOutcome>
gen lock <path> — resolve the manifest to a fresh lockfile.
May read the network (this is the resolver invocation).
Idempotent: re-running with no manifest changes is a no-op.
Sourcefn build(&self, ctx: &AdapterCtx) -> AdapterResult<BuildSpec>
fn build(&self, ctx: &AdapterCtx) -> AdapterResult<BuildSpec>
gen build <path> — manifest + lockfile → typed build-spec.
MUST be hermetic. Reads from disk only. Substrate’s
mkBuildSpec wrapper invokes this from inside the nix
sandbox; any network call breaks IFD.
Sourcefn plan(&self, ctx: &AdapterCtx, intent: &PlanIntent) -> AdapterResult<Plan>
fn plan(&self, ctx: &AdapterCtx, intent: &PlanIntent) -> AdapterResult<Plan>
gen plan <path> — given an intent (bump X, enable feature Y),
produce the diff of what would change. Read-only. Used by
pre-bump confirmation flows.
Sourcefn confirm(&self, ctx: &AdapterCtx) -> AdapterResult<ConfirmReport>
fn confirm(&self, ctx: &AdapterCtx) -> AdapterResult<ConfirmReport>
gen confirm <path> — verify spec invariants:
- every lockfile entry has a manifest declaration
- every transitive dep has a hash
- features resolve consistently across the workspace
- source URLs are valid (no
?branch=query leaks, etc.) Returns a typed report rather than panicking.
Sourcefn diff(&self, ctx: &AdapterCtx, against: &DiffRef) -> AdapterResult<DiffReport>
fn diff(&self, ctx: &AdapterCtx, against: &DiffRef) -> AdapterResult<DiffReport>
gen diff <path> <ref> — diff current state vs a reference
(file path, git rev, or “previous”).
Sourcefn sbom(&self, ctx: &AdapterCtx, format: SbomFormat) -> AdapterResult<Sbom>
fn sbom(&self, ctx: &AdapterCtx, format: SbomFormat) -> AdapterResult<Sbom>
gen sbom <path> — software bill of materials in the given
format. Pure function of the build-spec.
Provided Methods§
Sourcefn quirks_registry(&self) -> Vec<AdapterQuirkEntry>
fn quirks_registry(&self) -> Vec<AdapterQuirkEntry>
gen quirks list — typed registry of upstream third-party
package quirks the adapter knows about. Each adapter’s quirks
shape is its own (CrateQuirk for Cargo, future NpmQuirk for
npm, GemQuirk for Bundler) — the trait surface stays uniform
via the opaque serde_json::Value envelope.
Default quirks_registry returns empty — adapters with a
registry override to expose it. Substrate consumers can
introspect every ecosystem’s quirks through a single call.
The CANONICAL surface for adding a new quirk is the adapter’s own typed registry; this trait method is the operator-facing
- tooling-discovery surface.
Sourcefn dispatcher_reflection(&self) -> Vec<DispatcherVariant>
fn dispatcher_reflection(&self) -> Vec<DispatcherVariant>
Reflection over the adapter’s typed quirk enum — kebab-case
serde tags + per-variant field names. Surfaces what
#[derive(TypedDispatcher)] knows mechanically without
exposing the concrete enum type through the trait.
Used by gen dispatchers list (operator visibility) and by
substrate-side coverage tests that assert every kind in this
reflection has a matching helpers arm in the matching
substrate/lib/build/<ecosystem>/quirk-apply.nix. Default
implementation returns an empty Vec — adapters whose Quirk
enum hasn’t yet adopted #[derive(TypedDispatcher)] simply
disappear from the catalog (no false coverage claims).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".