rototo
DocsReference
Reference

SDK Resolution Reference

Runtime application code should resolve named variables and qualifiers through a loaded workspace handle. That keeps file parsing, lint, context validation, and selection semantics inside rototo instead of copying them into the app.

Context

Resolution uses a JSON object context:

use rototo::ResolveContext;

let context = ResolveContext::from_json(serde_json::json!({ "account": { "plan": "enterprise" } }))?;

context = {
    "account": {
        "plan": "enterprise",
    },
}
const context = {
  account: {
    plan: "enterprise",
  },
};
Map<String, Object> context = Map.of(
    "account",
    Map.of("plan", "enterprise")
);
resolveContext := map[string]any{
    "account": map[string]any{
        "plan": "enterprise",
    },
}

The JSON value must be an object.

Resolve A Variable

let resolution = workspace
    .resolve_variable("account-limits", &context)
    .await?;

println!("{} -> {}", resolution.value_key, resolution.value);

resolution = await workspace.resolve_variable(
    "account-limits",
    context,
)

print(f"{resolution.value_key} -> {resolution.value}")
const resolution = await workspace.resolveVariable(
  "account-limits",
  context,
);

console.log(`${resolution.valueKey} -> ${resolution.value}`);
VariableResolution resolution = workspace
    .resolveVariable("account-limits", context)
    .get();

System.out.println(resolution.valueKey() + " -> " + resolution.value());
resolution, err := workspace.ResolveVariable(
    ctx,
    "account-limits",
    resolveContext,
    nil,
)
if err != nil {
    return err
}

fmt.Printf("%s -> %v\n", resolution.ValueKey, resolution.Value)

VariableResolution contains:

FieldTypeMeaning
idstringVariable id.
value_keystringSelected value key.
valueJSON valueSelected value.

The TypeScript, Java, and Go SDKs expose value_key as valueKey.

Resolve A Qualifier

let resolution = workspace
    .resolve_qualifier("enterprise-account", &context)
    .await?;

println!("{}", resolution.value);

resolution = await workspace.resolve_qualifier(
    "enterprise-account",
    context,
)

print(resolution.value)
const resolution = await workspace.resolveQualifier(
  "enterprise-account",
  context,
);

console.log(resolution.value);
QualifierResolution resolution = workspace
    .resolveQualifier("enterprise-account", context)
    .get();

System.out.println(resolution.value());
resolution, err := workspace.ResolveQualifier(
    ctx,
    "enterprise-account",
    resolveContext,
    nil,
)
if err != nil {
    return err
}

fmt.Println(resolution.Value)

QualifierResolution contains:

FieldTypeMeaning
idstringQualifier id.
valuebooleanFinal qualifier result.

Context Validation Options

By default, SDK resolution validates context against schemas/context.schema.json when the workspace provides that schema.

To skip validation for a specific call:

use rototo::ResolveOptions;

let options = ResolveOptions { validate_context: false, };

let resolution = workspace .resolve_variable_with_options("account-limits", &context, options) .await?;

resolution = await workspace.resolve_variable(
    "account-limits",
    context,
    validate_context=False,
)
const resolution = await workspace.resolveVariable(
  "account-limits",
  context,
  { validateContext: false },
);
VariableResolution resolution = workspace
    .resolveVariable(
        "account-limits",
        context,
        ResolveOptions.validateContext(false)
    )
    .get();
resolution, err := workspace.ResolveVariable(
    ctx,
    "account-limits",
    resolveContext,
    &rototo.ResolveOptions{SkipContextValidation: true},
)

Skipping validation does not make missing context paths valid. A qualifier that reads a missing path can still fail resolution. This option only skips JSON Schema validation of the context object.

Workspace Loaded Without Runtime

Inspection loads a workspace without compiling a runtime model. Resolution from that handle fails with:

workspace was loaded without a runtime model; use Workspace::load with lint enabled

Use loaded runtime workspaces or refreshing workspaces for application runtime paths.

Rust Free Functions

The Rust crate also exports filesystem-oriented functions:

rototo::resolve_variable(workspace_root, "account-limits", context_json).await?;
rototo::resolve_variables(workspace_root, context_json).await?;
rototo::resolve_qualifier(workspace_root, "enterprise-account", context_json).await?;
rototo::resolve_qualifiers(workspace_root, context_json).await?;

These compile the runtime workspace from a local root for each call. They are handy for Rust tests and tools. Long-running services should prefer a loaded workspace.

Traces

The loaded SDK APIs return compact resolutions. The CLI and Rust free trace functions return explanation traces:

rototo::trace_variable_resolution(workspace_root, "account-limits", context_json).await?;
rototo::trace_qualifier_resolution(workspace_root, "enterprise-account", context_json).await?;

Use traces for tests, diagnostics, or observability where you need to explain why a value was selected.