> ## Documentation Index
> Fetch the complete documentation index at: https://ahvn.top/llms.txt
> Use this file to discover all available pages before exploring further.

# Extensions

> Entity extensions, built-in system/prompt extensions, and developer registries for backends, handlers, and storage.

<Note>
  *Entity extensions add schemas. Developer registries add physical behavior. Both plug in without changing the workspace API.*
</Note>

<br />

## 1. Two Extension Layers

HeavenBase separates extension work into two layers that share the `hb.ext` import path but serve different authors:

| Layer               | Audience                        | What it adds                                       | Primary API                                                                   |
| ------------------- | ------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------- |
| Entity extension    | Application and package authors | Optional `Entity` classes and MetaSchema rows      | `ExtensionSpec`, `register_extension`, `ws.enable_extension`                  |
| Developer extension | Backend and compiler authors    | Backends, handlers, strategies, logical types, ops | `hb.ext.register_backend_builder`, `register_strategy`, `register_handler`, … |

Entity extensions publish structure through normal workspace registration. Developer extensions publish behavior through process-global registries that the workspace planner and handler seeding consume at runtime.

<br />

## 2. Built-In System and Prompt Extensions

HeavenBase ships one required built-in entity extension: `system`. Every `HeavenBase(...)` workspace enables it automatically, and default configuration also loads `prompt`.

The system implementation lives under `src/heavenbase/extensions/system/`; Prompt and Translation live under `src/heavenbase/extensions/prompt/`. Import `hb.Prompt`, `hb.Capsule`, and `hb.Toolkit` from `import heavenbase as hb`.

### 2.1. Built-In Entities

| Entity id         | Class         | Purpose                                               |
| ----------------- | ------------- | ----------------------------------------------------- |
| `sys-catalog`     | `Catalog`     | Concrete object discovery                             |
| `sys-metaschema`  | `MetaSchema`  | Structure, capabilities, extensions                   |
| `sys-prompt`      | `Prompt`      | Callable prompt rows from the `prompt` extension      |
| `sys-translation` | `Translation` | Prompt-bound translations from the `prompt` extension |
| `sys-capsule`     | `Capsule`     | Executable Capsule manifests                          |
| `sys-toolkit`     | `Toolkit`     | Toolkit manifests                                     |

`ConfigLayer` (`sys-config-layer`) exists in the same package but is not part of `system_entities()` and is not auto-enabled.

### 2.2. What Changed in the Architecture Optimization Pass

Capsule and Toolkit remain under the required `system` extension; Prompt and Translation live in the default-loaded `prompt` extension with the same root package API.

Lazy helpers such as `ensure_prompt_entities(ws)` call `ws.enable_extension("prompt")`; Capsule registry setup calls `ws.enable_extension("system")` when it needs system rows.

<br />

## 3. Entity Extension API

Define and register entity extensions before workspaces load them:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb
from heavenbase.ext import Extension, ExtensionSpec, register_extension


class AuditLog(hb.Entity):
    identifier = "audit-log"

    event = hb.field(hb.ShortText)


register_extension(
    Extension(
        ExtensionSpec(
            identifier="audit",
            name="Audit Log",
            desc="Optional audit rows.",
            entities=(AuditLog,),
            tags=("audit",),
        )
    )
)
```

`ExtensionSpec` fields:

| Field                     | Role                                                                         |
| ------------------------- | ---------------------------------------------------------------------------- |
| `identifier`              | Stable extension id (same naming rules as workspace ids)                     |
| `name`, `desc`, `version` | Human-readable metadata published to MetaSchema                              |
| `entities`                | Entity classes registered when the extension is enabled                      |
| `required`                | When `True`, the extension cannot be skipped (only `system` uses this today) |
| `tags`, `meta`            | Extra metadata for discovery and tooling                                     |

Enable an extension in one workspace:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
ws = hb.HeavenBase("demo", preset="debug")
spec = ws.enable_extension("audit")
print(spec.identifier)
print(ws.extensions())
```

Enable custom extensions on every new workspace through config:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# heavenbase.extensions.default: ["audit", "my-package"]
```

Entity extensions do not bypass storage planning. Enabled entities still go through `ws.register(...)` and normal routing.

<br />

## 4. Developer Extension Registries

Developer extensions register physical behavior in process-global registries exported from `hb.ext`:

| Registry         | Register function                                    | Used by                                            |
| ---------------- | ---------------------------------------------------- | -------------------------------------------------- |
| Backends         | `register_backend_builder`, `register_backend_class` | Config loading, storage placement, handler seeding |
| Handlers         | `register_handler`, `HandlerRegistry.register`       | Query compilation                                  |
| Strategies       | `register_strategy`                                  | Storage placement and handler lookup               |
| Logical types    | `register_logical_type`                              | Handler seeding and storage profiles               |
| Operations       | `register_op`                                        | JSON query parsing and handler seeding             |
| Storage profiles | `register_storage_profile`                           | Default field placement                            |

Handlers compile one logical operation into one `QueryFragment`. They do not execute IO; backends execute fragments.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb

def compile_ends_with(field_schema, value, ctx):
    def payload(row):
        return str(row.get(field_schema.name, "")).endswith(str(value))

    return hb.ext.QueryFragment(ctx.backend, "ends_with", field_schema.name, payload)


hb.ext.register_handler(
    "demo",
    hb.ShortText,
    "ends_with",
    "inmem",
    "suffix-index",
    compile_ends_with,
)
```

Provider-native handler plugins live in `heavenbase.handlers.plugins` and register through `register_handler_plugin`. Built-in seeding consumes registries and plugins instead of hard-coded provider lists.

<br />

## 5. Discover Capabilities

Users and extension UIs should discover choices through the public capability index instead of reading registry internals:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb

ws = hb.HeavenBase("demo", preset="debug")

hb.capabilities.logical_types()
hb.capabilities.strategies(hb.Vector)
hb.capabilities.backends(hb.Array, hb.SideTable, op="array_contains")
hb.capabilities.ops(hb.ShortText, hb.InlineColumn, backend="sqlite")

# Same methods on ws.capabilities(), filtered to configured backends
ws.capabilities.backends(hb.Vector, hb.VectorIndex, op="near")
```

Each option exposes `to_dict()` for building pickers or diagnostics, and workspace construction mirrors common registry metadata into `sys-metaschema`.

<br />

## 6. Validation Checklist

After adding an extension surface:

1. Register the component in the correct role package under `src/heavenbase/`.
2. Export it from the package `__init__.py` and top-level `heavenbase` when it is built in.
3. Add tests in `tests/test_extensions.py`, `tests/test_backends.py`, or a focused test module.
4. Run `rtk bash scripts/test.bash` from the HeavenBase repository root.

See `demos/developer/03_write_an_extension.py` for a minimal custom extension demo.

<br />

## Further Exploration

<Tip>
  **Related resources:**

  * [Extension System quickstart](/quickstart/extension-system) - First-run enablement and inspection
  * [Architecture](/introduction/architecture) - Core path and source layout
  * [Catalog](/features/catalog) - `Catalog` and `MetaSchema` discovery
  * [Backends](/features/backends) - Backend families and registration
  * [Routing](/features/routing) - Field placement that extensions must respect
  * [MCP toolkit reference](/reference/mcp-toolkit) - Capsule and Toolkit registry APIs
</Tip>

<br />
