Flavour / infra / overlay / execution boundary¶
Status: implemented. This note records why the boundary sits where it does. For the supported fields, use the Flavour manifest reference.
The problem¶
Four concerns look alike in code, because each ends up patching an in-memory spec dict. They are different:
- A flavour is a deployment preset. It sets protocol, observability and control plugin selection, and tool exposure.
- Infra holds endpoints, API-key variable names, the tool name-to-implementation mapping, and model wire names.
- An overlay is a small YAML file merged on top of a manifest. The agent spec holds LLM inference parameters, tools, skills, and memory.
- Execution holds the engine queue, LLM cache policy, streaming, and parallel tool calls.
Cache is the awkward case. It is shaped like infrastructure: it is an InfraMiddleware in the engine's infra pipeline (runtime/src/mas/runtime/engine/infra_pipeline.py). But whether it is on is a per-run choice, not a fixed property of the environment.
Example: one run records with the cache on, another replays. Both use the same flavour and infra. Only the execution settings differ.
Decision¶
- Execution is not a flavour concern. Queue depth, LLM disk-cache policy, streaming, and parallel tool dispatch live in
kind: RuntimeEngine(infra/v1). The runtime resolves it from workspaceruntime_refsor--runtime-ref. Agent, MAS, and Overlay manifests may not carry these settings. Offline LLM turns use thellm_cachemiddleware recorded against a live provider, not a flavour field. - Endpoints are infra. The
infra.schema.yamlkinds (InfraBundle,LLMProxy,ToolProvider,ToolRegistry, ...) own endpoints, API-key variable names, wire names, and tool mapping. A flavour may not carryinfra_refsorinfra_ref. - A flavour carries posture only.
FlavourSeparationValidator(ctl/src/mas/ctl/validate/separation.py) rejectsspec.llm,spec.skills,spec.prefer_local,spec.infra_refs, andspec.infra_ref. Inference parameters and skills are Agent concerns.prefer_localduplicated workspace infra tuning and was removed. -
Overlay is the one patch mechanism. Flavours and agents use the same JSON merge-patch semantics.
merge_overlay(ctl/src/mas/ctl/overlay/merge.py) dispatches on the overlay'sspec.target.kind:Agenttomerge_agent_overlay.MAStomerge_mas_overlay.Flavourtomerge_flavour_overlay.Infrato a plain merge-patch.
merge_flavour_overlayis deliberately narrow. It rejects any patch key that is not a property of the Flavour schema. An overlay therefore cannot reintroduce model or skill state through a flavour. 5.observabilityandcontroluse one shape everywhere. Each is a closed plugin list, such as[native]or[native, {otel: {output_path: traces/otel}}]. Seefragments/observability-binding.schema.yamlandfragments/control-binding.schema.yaml. An overlay can choose which known plugins run and set their few sanctioned options. It cannot invent a plugin id or pass arbitrary plugin configuration. The--events*CLI flags apply as a Flavour overlay patch onobservability(ctl/src/mas/ctl/cli/obs_flags.py).
Consequences¶
Each concern has one owner and one mechanism.
| Concern | Owner | Mechanism |
|---|---|---|
| Endpoints, API keys, model wire names, tool name-to-implementation mapping | Infra (infra/v1: InfraBundle, LLMProxy, ToolProvider, ...) |
--infra-ref or workspace infra_refs only. Never Agent, MAS, or overlay YAML. |
| Protocol, observability and control plugin selection | Flavour | --flavour NAME, optionally patched by an overlay with target.kind: Flavour. |
| LLM inference parameters, tools, skills, memory | Agent spec / overlay | merge_agent_overlay, CLI overlay builders. |
| Engine queue, LLM disk-cache policy, streaming, parallel tool calls | RuntimeEngine (infra/v1) |
Workspace runtime_refs, --runtime-ref. |
| Trace replay and batch concurrency | Experiment design, schedule, bench_emulation (mas-lab only) |
experiment.md |