# Resource Registry

The Resource Registry manages **resource types** and **resource
instances** in CleverAgents.  Resource types define schemas, sandbox
strategies, and handler implementations.  Resource instances are
registered entries that plans operate on during execution.

## Built-in Resource Types

CleverAgents ships with two built-in types, available without
registration:

| Type             | Kind     | Sandbox Strategy | Handler                        |
|------------------|----------|------------------|--------------------------------|
| `git-checkout`   | physical | `git_worktree`   | `GitCheckoutHandler`           |
| `fs-directory`   | physical | `copy_on_write`  | `FsDirectoryHandler`           |

Built-in types are registered idempotently at startup via
`ResourceRegistryService.bootstrap_builtin_types()`.

## Resource Type Fields

Each `ResourceTypeSpec` defines a resource type schema:

| Field              | Type                | Description                                          |
|--------------------|---------------------|------------------------------------------------------|
| `name`             | `str`               | Unique name (built-in: bare, custom: `namespace/name`) |
| `description`      | `str`               | Human-readable description                           |
| `resource_kind`    | `ResourceKind`      | `physical` or `virtual`                              |
| `sandbox_strategy` | `SandboxStrategy`   | Default sandbox isolation strategy                   |
| `user_addable`     | `bool`              | Whether users can register instances of this type    |
| `built_in`         | `bool`              | Whether this is a built-in type                      |
| `cli_args`         | `list[ResourceTypeArgument]` | CLI argument definitions for registration  |
| `parent_types`     | `list[str]`         | Allowed parent type names in the DAG                 |
| `child_types`      | `list[str]`         | Allowed child type names in the DAG                  |
| `handler`          | `str \| None`       | Handler ref in `module:Class` format                 |
| `capabilities`     | `dict[str, bool]`   | `read`, `write`, `sandbox`, `checkpoint` flags       |
| `auto_discovery`   | `dict \| None`      | Auto-discovery rules (see below)                     |
| `equivalence`      | `dict \| None`      | Virtual resource deduplication config                |

### Custom Types

Custom types are defined in YAML and registered via CLI or API:

```yaml
name: myteam/python-package
description: A Python package directory
resource_kind: physical
sandbox_strategy: copy_on_write
user_addable: true
cli_args:
  - name: path
    type: path
    required: true
    description: Path to the package root
parent_types:
  - git-checkout
child_types:
  - fs-directory
```

Register with: `agents resource type add path/to/type.yaml`

## Resource Instance Fields

Each `Resource` represents a registered asset:

| Field                | Type                  | Description                                  |
|----------------------|-----------------------|----------------------------------------------|
| `resource_id`        | `str` (ULID)          | Unique identifier                            |
| `name`               | `str \| None`         | Optional namespaced name                     |
| `resource_type_name` | `str`                 | Type this resource belongs to                |
| `classification`     | `PhysVirt`            | `physical` or `virtual`                      |
| `description`        | `str \| None`         | Human-readable description                   |
| `location`           | `str \| None`         | Filesystem path (physical resources)         |
| `sandbox_strategy`   | `SandboxStrategy \| None` | Per-resource sandbox override            |
| `content_hash`       | `str \| None`         | Hash of resource contents for change detection |
| `parents`            | `list[str]`           | Parent resource IDs in the DAG               |
| `children`           | `list[str]`           | Child resource IDs in the DAG                |
| `properties`         | `dict`                | Type-specific key-value properties           |
| `capabilities`       | `ResourceCapabilities`| `readable`, `writable`, `sandboxable`, `checkpointable` |
| `created_at`         | `datetime`            | Registration timestamp                       |
| `updated_at`         | `datetime`            | Last modification timestamp                  |

## Registry Service API

### Type Operations

| Method                  | Description                              |
|-------------------------|------------------------------------------|
| `bootstrap_builtin_types()` | Register built-in types (idempotent) |
| `register_type(config_path)` | Register a custom type from YAML    |
| `list_types(namespace=)` | List types, optionally filtered          |
| `show_type(name)`        | Get a type by name                      |

### Resource Operations

| Method                        | Description                          |
|-------------------------------|--------------------------------------|
| `register_resource(type_name, name=, location=, ...)` | Create and register an instance |
| `list_resources(type_name=)`  | List resources, optionally by type   |
| `show_resource(name_or_id)`   | Get by namespaced name or ULID       |

### DAG Operations

| Method                          | Description                        |
|---------------------------------|------------------------------------|
| `link_child(parent, child)`     | Link a child to a parent           |
| `unlink_child(parent, child)`   | Remove a parent-child link         |
| `get_children(name_or_id)`      | Get direct children                |
| `get_resource_tree(name_or_id, depth=, type_filter=)` | Recursive tree traversal |

For DAG rules, cycle detection, type compatibility, and auto-discovery
details, see [Resource DAG](resource_dag.md).

## Discovery Behavior

### Auto-Discovery

Resource types can define auto-discovery rules that materialize child
resources automatically:

```yaml
auto_discovery:
  enabled: true
  rules:
    - type: fs-directory
      pattern: "*/"
    - type: fs-file
      pattern: "*"
```

When `auto_discover_children(resource_id)` is called:

1. The resource and its type are looked up.
2. Each discovery rule is evaluated:
   - The child type must exist in the registry.
   - The child type must be compatible with the parent type (per
     `child_types`).
3. New child resources are created with `auto_discovered = true`.
4. Links are created in the `resource_links` table.

Auto-discovery is triggered:
- When a resource is first registered
- When resource contents change
- On demand via CLI (`agents resource discover`)

### Local-Mode Discovery

In local mode (the default), discovery operates against the local
filesystem.  The registry creates placeholder resource entries based
on discovery rules; actual file enumeration is delegated to resource
handlers at sandbox creation time.

## Database Schema

### `resource_types` Table

| Column                    | Type          | Description                    |
|---------------------------|---------------|--------------------------------|
| `name`                    | `String(128)` | Primary key                   |
| `namespace`               | `String(64)`  | Namespace (or `builtin`)      |
| `description`             | `Text`        | Human-readable description    |
| `resource_kind`           | `String(16)`  | `physical` or `virtual`       |
| `sandbox_strategy`        | `String(32)`  | Default sandbox strategy      |
| `user_addable`            | `Boolean`     | User registration allowed     |
| `built_in`                | `Boolean`     | Built-in type flag            |
| `handler`                 | `String(256)` | Handler `module:Class` ref    |
| `args_schema_json`        | `Text`        | CLI args JSON                 |
| `allowed_parent_types_json` | `Text`      | Allowed parent types JSON     |
| `allowed_child_types_json`  | `Text`      | Allowed child types JSON      |
| `auto_discover_json`      | `Text`        | Auto-discovery config JSON    |
| `capabilities_json`       | `Text`        | Capabilities JSON             |
| `equivalence_json`        | `Text`        | Equivalence config JSON       |
| `source`                  | `String(256)` | Registration source           |
| `created_at`              | `String(30)`  | ISO-8601 timestamp            |
| `updated_at`              | `String(30)`  | ISO-8601 timestamp            |

### `resources` Table

| Column             | Type          | Description                         |
|--------------------|---------------|-------------------------------------|
| `resource_id`      | `String(26)`  | ULID primary key                    |
| `namespaced_name`  | `String(256)` | Optional namespaced name (unique)   |
| `namespace`        | `String(64)`  | Namespace extracted from name       |
| `type_name`        | `String(128)` | FK to `resource_types.name`         |
| `resource_kind`    | `String(16)`  | `physical` or `virtual`             |
| `location`         | `Text`        | Filesystem path                     |
| `description`      | `Text`        | Human-readable description          |
| `read_only`        | `Boolean`     | Read-only flag                      |
| `auto_discovered`  | `Boolean`     | Created by auto-discovery           |
| `sandbox_strategy` | `String(32)`  | Per-resource sandbox override       |
| `content_hash`     | `String(128)` | Content hash for change detection   |
| `properties_json`  | `Text`        | Type-specific properties JSON       |
| `metadata_json`    | `Text`        | Additional metadata JSON            |
| `created_at`       | `String(30)`  | ISO-8601 timestamp                  |
| `updated_at`       | `String(30)`  | ISO-8601 timestamp                  |

### `resource_links` Table

See [Resource DAG](resource_dag.md#database-schema) for link table
schema.

## Source

- Domain models: `src/cleveragents/domain/models/core/resource.py`,
  `resource_type.py`
- Service: `src/cleveragents/application/services/resource_registry_service.py`
- Migration: `alembic/versions/b1_001_resource_registry_tables.py`
- CLI: `src/cleveragents/cli/commands/resource.py`
- Specification: `docs/specification.md` — Resource Registry sections
