MagWorksManaged Intelligence

Layer 2 — mag-composition

Packages: @mag/composition-core, @mag/composition-prompt, @mag/composition-knowledge, @mag/composition-capability, @mag/composition-conversation.

In plain language

Between the substrate and the product sits a layer that executes nothing and renders nothing. It defines what a reusable component is — a prompt, a knowledge collection, a tool, a review — how it is versioned and governed, and how it binds to the substrate primitive that does the work. It also defines the grammar for composing components into a Capability: generate, route, act, review. Studio assembles these; the product's resolver compiles them; Magpie runs them. Because the layer belongs to no single application, the same components and the same grammar serve every Solution.

The mechanism

One base model (INV-COMP-01). Every component, of every family, conforms to the Composition Component Base Model: identity and classification (family, kind), ownership, lifecycle (draft → published → deprecated → archived), version, tags, runtime resolution, relationships, governance and audit. A published version is immutable; a change is a new version. New families and kinds are added by extending the enumerations through an ADR; the base shape does not fork per type.

Components reference; they never re-implement (INV-COMP-02, -04). A component's resolutionStrategy and runtimeBinding are one typed discriminated union whose binding shapes mirror exactly what the corresponding Magpie primitive accepts today. A Prompt Component holds metadata and a pointer or version reference — never prompt text (the validator rejects any body-like field). A Knowledge Component is an aggregate over one or more sources plus retrieval parameters. A inline strategy means a Layer-2-only declarative object with no substrate binding.

Zero substrate dependency (INV-COMP-03). The packages import nothing from @magpie/*. Magpie concepts are cited, not imported; a Magpie surface change is a governed update here, never silent drift. Dependency direction is one-way and lint-enforced.

The Capability authoring model (ADR-0006, -0007). A CapabilityDefinition declares ordered inputs, a CapabilityFlow of steps, outputs, publication and access metadata, and an evaluation namespace. Steps bind data symbolically — source: "input" or source: "step" with a path — and never construct the substrate's projection machinery.

The composition grammar. Four step roles:

Role What it composes Compiles to
generate a Prompt Component, a model, optional Knowledge a prompt node
route a deterministic verdict → next-step map, default required a condition node (ADR-0013)
tool a platform tool with dynamic inputs and static options a tool node (ADR-0015)
review a human decision with allowed roles a human-review node

Routing is deterministic: it consumes only a structured verdict from a prior step, never a transcript, and an unmatched verdict routes somewhere explicit. A routed capability declares one canonical output by listing its branch steps in preference order (first-present, ADR-0014), so readers never learn about branches.

Evaluation is a namespace on the version (ADR-0009 … 0012). evaluation: { primarySuiteId?, freshnessDays?, mode?: "advisory" | "required" } is version-scoped, frozen on publish, declarative and consumer-resolved: the layer validates the shape and attaches no behaviour. "blocking" was removed because it added no meaning beyond "required" and smuggled policy into an enum; stronger governance is a new explicit field, never a new mode value.

The resolution contract (ADR-0008). The resolver — the only code that knows both @mag/* and @magpie/* — lives downstream in the product. This layer specifies what it must satisfy: prompt component → prompt node with model precedence rules; knowledge binding → query-time retrieval feeding a named prompt variable; outputs → the terminal's output builder. The contract exists before more families are built so no family accrues divergent resolution behaviour.

Conversation components (@mag/composition-conversation) carry the presentation contract for conversational Solutions — the validated envelope of prose, presentation directives and state updates that a client such as the Front Door renders — with fail-closed vocabulary validation.

Design notes

  • Why a separate repository and version line (ADR-0001). Lockstep is right for the substrate because its packages are one coherent release; it is the wrong fit for a layer with a different cadence and consumer set.
  • Why a layer that executes nothing exists (constitution). "Magpie executes. mag-composition composes. Studio authors. Applications consume." Identity, metadata, versioning and discovery of reusable components need one owner that is neither the runtime nor any single app.
  • Why routing is a first-class step (ADR-0013). "Do not hide routing in compiler side channels. The composition grammar must be capable of expressing a routed workflow directly." The authored artifact must be the complete truth of a capability's control flow.
  • Why the tool step arrived when it did (ADR-0015). The runtime had been tool-capable for some time, but no authored Solution could reach it; the Studio write path refused six reserved tool.* identities rather than let one silently execute as a prompt. The grammar was added so tools could be lifted one governed tool at a time.

Sources

  • mag-composition/README.md and docs/architecture-constitution.md (INV-COMP-01…08).
  • mag-composition/docs/adr/00010015.
  • mag-composition/packages/composition-capability/src/, composition-core/src/.