# Add your own capability

A backend with no matching capability needs a contract of its own. Split the package in two, so a module can import the contract without the driver:

vector\_index/contracts.py

```
"""What a module may import: the caller's Protocol, the reference and the spec."""

import abc
from typing import ClassVar, Protocol

from sandloom.driverkit import CapabilityRef, CapabilitySpec, InfraProvider


class VectorIndex(Protocol):
    async def nearest(self, vector: list[float], *, limit: int) -> list[str]: ...


class VectorIndexProvider(InfraProvider, VectorIndex):
    capability: ClassVar[str] = "vector_index"

    @abc.abstractmethod
    async def nearest(self, vector: list[float], *, limit: int) -> list[str]: ...


VECTOR_INDEX: CapabilityRef[VectorIndex] = CapabilityRef("vector_index.v1")

VECTOR_INDEX_SPEC = CapabilitySpec(
    name="vector_index",
    version="v1",
    provider_contract=VectorIndexProvider,
    features=frozenset({"exact"}),
    stability="experimental",
)
```

vector\_index/driver.py

```
"""The driver: a module may not import this."""

from vector_index.contracts import VectorIndexProvider


class MemoryVectorIndex(VectorIndexProvider):
    contract_version = "v1"
    supported_features = frozenset({"exact"})

    async def nearest(self, vector: list[float], *, limit: int) -> list[str]:
        # "exact": a linear scan of everything, never an approximation.
        return ["a", "b"][:limit]
```

pyproject.toml

```
[project.entry-points."sandloom.capabilities"]
vector_index = "vector_index.contracts:VECTOR_INDEX_SPEC"

[project.entry-points."sandloom.drivers"]
"vector_index.memory" = "vector_index.driver:MemoryVectorIndex"
```

- **Selecting it:** `INFRA={"vector_index":{"default":{"driver":"memory"}}}`.
- **Requiring it from a module:** `CapabilityRequirement("vector_index", features=frozenset({"exact"}))` in `define_module`. Startup then fails, without I/O, if it is missing.
- **Calling it from a module:** the reference carries the type, as long as your package ships a `py.typed` file. Without one, type checkers see `Any`.

  ```
  from sandloom.sdk.infra import capability  # sandloom: advanced infra
  from vector_index.contracts import VECTOR_INDEX

  nearest = await capability(VECTOR_INDEX).nearest([1.0], limit=5)
  ```
- **What a module may import:** `vector_index.contracts`. Importing `vector_index.driver` or its parent `vector_index`, which reaches the driver by attribute, fails [SANDLOOM-C004](<https://sandloom.dev/docs/reference/error-codes/#sandloom-c004>), because an entry point names that module.
- **In production:** `stability="experimental"` requires the accepted risk `experimental_capability` ([SANDLOOM-B023](<https://sandloom.dev/docs/reference/error-codes/#sandloom-b023>)). Use `"stable"` when you keep the contract stable yourself.
- **Reserved names:** the kernel defines `search`, `document_store`, `graph_store`, `workflow`, `lock` and `secrets`, so a package cannot declare them.

See also [Write a driver](<https://sandloom.dev/docs/infrastructure/write-a-driver/index.md>) and the [driver kit](<https://sandloom.dev/docs/infrastructure/driverkit/index.md>).
