Settings precedence & provenance
Five launch-relevant knobs share the same five-level precedence chain, highest priority first:
run override > node DSL > workflow DSL > env > default| Knob | Run override | Node field | Workflow field | Env | Default |
|---|---|---|---|---|---|
| Compression | CLI --compress / studio select | compress: (agent/judge; tool nodes are opt-in only) | compress: | ITERION_COMPRESS | on when a rewriter plugin is enabled and its binary present, else off |
| Auto-memory | CLI --auto-memory / studio select | auto_memory: (agent/judge) | auto_memory: | ITERION_AUTO_MEMORY | off (a run is hermetic by default — memory-and-knowledge.md) |
| Ambient context | CLI --ambient-context / launch API ambient_context / studio select | ambient_context: (agent/judge) | ambient_context: | ITERION_AMBIENT_CONTEXT | workspace: the repository's instruction files, not the operator's setup (ADR-119) |
| Permission gate | CLI --permission / studio select | permission: | permission: | ITERION_PERMISSION | off |
| Backend | CLI --backend / studio select | backend: | default_backend: | ITERION_DEFAULT_BACKEND | credential auto-detection (docs/backends.md) |
The first non-empty level wins. A non-empty value that fails to parse surfaces an error naming that level — it never silently falls through to a lower level the operator didn't pick (see permission.ResolveModeSourced).
Auto-memory is the exception to the error half: automemory.ParseMode maps anything it does not recognise to off, so ITERION_AUTO_MEMORY=banana resolves to off at the env level rather than raising. The preview normalizes before captioning (normalizedAutoMemoryEnv), so the dialog announces the mode the run will actually be in, and still distinguishes an unset variable (fall through to the default) from an explicit off.
The ambient context does not raise either, in a different way: an invalid ITERION_AMBIENT_CONTEXT is IGNORED (ambient.ResolveSourced skips it, the executor logs it once), so the run falls through to the workflow or the workspace default. The preview normalizes it the same way (normalizedAmbientContextEnv) and attributes the result to the level that actually decided it. A typed run override is rejected outright by runview.Launch/Resume and by the CLI, and a DSL value by the compiler (C184).
Where you see it
The studio Launch dialog captions each Run-settings select with the resolved value and its provenance:
effective: ask · from workflow
effective: off · from env
effective: on · from run overrideplus a warning when at least one node pins its own value — a run override never reaches those nodes:
effective: claw · from workflow · some nodes pin their own (override won't affect them)How it's wired
rewrite.ResolveWithDefaultSourcedandpermission.ResolveModeSourcedreturn the winning level alongside the mode — the same resolvers the runtime uses, so the caption can't drift from execution behavior.POST /api/runs/preview-costreturns an optionaleffectiveblock ({compress, auto_memory, permission, backend}, each{effective, source, node_pinned}) resolved below the run-override level — workflow → env → default. The studio layers the operator's own select on top client-side (that's the only wayrun overrideappears in a caption).- Node-level provenance is summarized as the
node_pinnedboolean rather than enumerated per node: the Launch dialog decides one run override, so "will my override take everywhere?" is the actionable question.
Scope (lite)
Provenance covers the four mode knobs. A permission allow:/ask:/deny: rule list does have a winning level — an agent/judge node's list REPLACES the workflow's of the same kind, and the run-level --permission-allow/... append to whichever won (permissions.md) — but the Launch dialog does not report it: rule-list provenance stays a deliberate non-goal for now.
Related: permissions.md · plugins.md (compression) · backends.md (auto-detection).
