Skip to content

Slot

Accepted

A Slot is a position in an Archetype where an Adapter or Module is plugged in. Slots are the mechanism by which Archetypes remain abstract over specific Adapter or Module choices while still being concrete enough to build from.

Why Slots

An Archetype that hard-codes “use Spring Data JPA” cannot accommodate a customer who needs jOOQ. An Archetype that hard-codes nothing is just a vague intention. Slots split the difference:

  • The Archetype declares what role needs to be filled (persistence, auth, observability, frontend framework, etc.)
  • The Slot declares what kind of thing fills it (Adapter category, required Capabilities, required Contract)
  • The user (or default) picks which specific Adapter or Module goes in the Slot during Spec Resolution

This is the standard interface-versus-implementation distinction, applied to Archetype composition.

What a Slot Declares

A Slot in an Archetype declaration has these fields:

  • slot_id — unique within the Archetype, namespaced (e.g., slot:rag-chatbot/llm-provider)
  • acceptsadapter or module
  • category — the broad category that fills this slot (e.g., persistence, auth, llm-provider)
  • required_contract — the Contract the filled entity must implement (e.g., contract:persistence/repository/v1)
  • required_capabilities — Capabilities the filled entity must provide (optional, beyond what the Contract requires)
  • default — the Adapter or Module to fill this Slot if the user doesn’t override
  • alternatives — pre-vetted alternatives the user can choose from in the form
  • description — human-readable explanation for the Build Approval summary

Adapter Slots vs Module Slots

Archetypes have both kinds:

{
"adapter_slots": [
{
"slot_id": "slot:rag-chatbot/llm-provider",
"category": "llm-provider",
"required_contract": "contract:llm/completion/v1",
"default": "adapter:ai/anthropic-sdk@latest",
"alternatives": [
"adapter:ai/openai-sdk@latest",
"adapter:ai/bedrock-sdk@latest"
]
}
],
"module_slots": [
{
"slot_id": "slot:rag-chatbot/document-ingestion",
"category": "document-ingestion",
"required_capabilities": [
"capability:ingestion/pdf/v1",
"capability:ingestion/html/v1"
],
"default": "module:ingestion/standard-corpus@1.0"
}
]
}

Both kinds are resolved by the same Resolver during Spec Resolution.

How Slots Get Filled

During Spec Resolution, the Resolver:

  1. Reads each Slot’s default
  2. If the user overrode the choice (in the form or conversation), uses the user’s choice
  3. Validates that the chosen Adapter or Module’s Manifest actually satisfies the Slot’s requirements (Contract implemented, Capabilities provided)
  4. Records the resolved selection in the Spec

If a user’s choice doesn’t satisfy the Slot’s requirements, Spec Resolution surfaces the mismatch and prompts the user for a different selection.

Slot Substitution

The point of the Contract requirement is that any Adapter implementing it should be substitutable. A Slot requiring contract:persistence/repository/v1 is filled equally well by Spring Data JPA, jOOQ, or any other Adapter implementing that Contract.

This is what enables the alternatives list, and what makes platform-level changes possible: deprecating an Adapter in favor of a new one with the same Contract doesn’t break Archetypes that referenced the old Adapter by Slot.

Slot Validation

Seam Validation checks that every Slot in the resolved Spec actually has a valid resolution. Specifically:

  • The selected Adapter/Module exists
  • Its declared Capabilities cover the Slot’s required Capabilities
  • Its Contract matches the Slot’s required Contract
  • It is compatible with the other Adapters and Modules resolved in other Slots
  • Its version is within the platform-supported range

Slot resolution failures at this stage indicate either a bug in the Archetype definition or a stale default; they do not indicate user error.

Why Capabilities and Contracts Are Both Used

A Slot can require either a Capability (a feature flag-style declaration) or a Contract (an interface shape) — typically both:

  • Capability says “this thing must be able to do X”
  • Contract says “this thing must expose interface Y”

Two Adapters can have the same Capability with different Contracts (incompatible APIs that both do the thing) or the same Contract with different Capabilities (same API but one supports more operations). Slots can match on either or both depending on how strict the substitution guarantee needs to be.