# ADR-008: Resource System

**Status:** Accepted  
**Date:** 2026-02-16  
**Supersedes:** None  
**Author(s):** Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>  
**Approver(s):** Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>

## Context

CleverAgents must operate on a wide variety of artifacts — git repositories, filesystem directories, databases, APIs, configuration files, documentation, and more. Each resource type has different read/write semantics, different sandboxing strategies, and different merge behaviors. The system needs a uniform abstraction that makes resources discoverable, linkable to projects, bindable to tools, and sandboxable — while accommodating the inherent diversity of resource types.

## Decision

CleverAgents uses a **typed resource system** with a resource registry, independently registered resource types, and per-type sandbox strategies. Resources are first-class entities with namespaced names, ULID identifiers, and DAG-based relationships. Resource types define the schema, sandbox strategy, and merge behavior for each category of artifact.

## Design

### Resource Model

Each resource is an independently registered entity with:

- **Identity**: `resource_id` (ULID), `name` (namespaced, e.g., `local/api-service-repo`), `resource_type` (reference to a registered type).
- **Location**: `uri` or `path` pointing to the physical artifact.
- **Metadata**: `description`, `tags`, custom key-value properties.
- **Access control**: `read_only` flag (can be overridden at the project level).
- **Relationships**: DAG edges to other resources (e.g., a git checkout depends on a git repository).

### Resource Types

Resource types are independently registered entities that define the schema and behavior for a category of resources. Built-in types include:

| Type | Sandbox Strategy | Description |
|------|-----------------|-------------|
| `git-checkout` | `git_worktree` | A checked-out git working tree |
| `git` | `none` | A bare or remote git repository |
| `fs-directory` | `copy_on_write` | A filesystem directory |
| `fs-mount` | `copy_on_write` or `overlay` | A mounted filesystem |
| Database types | `transaction_rollback` | Custom database resource types |
| API types | `none` | Custom API endpoint types |

Resource types are registered via YAML configuration and managed through the `agents resource-type` CLI commands.

### Resource Registry

The resource registry is a persistent catalog of all registered resources. Resources are registered via `agents resource add --config <FILE>` and linked to projects via `agents project link`. A resource can be linked to multiple projects.

### DAG Relationships

Resources form a directed acyclic graph. For example, a `git-checkout` resource depends on a `git` resource. The DAG is used for:

- Determining sandbox creation order (dependencies sandboxed first).
- Resolving resource discovery queries ("what resources does this project provide?").
- Ensuring cleanup happens in the correct order.

### Resource Bindings

Tools declare resource slots specifying what types of resources they need and how they access them. At tool activation time, slots are bound to concrete resources through one of three modes:

- **Contextual binding** (default): Resolved from the plan's project context.
- **Static binding**: Hardcoded to a specific resource by name.
- **Parameter binding**: Passed as an argument at invocation time.

### Sandbox Strategies Per Resource Type

Each resource type defines its default sandbox strategy. Per-resource overrides are possible. The five strategies are:

1. **git_worktree**: Creates a git worktree with a plan-specific branch. Rollback via git reset.
2. **filesystem_copy** (copy_on_write): Copies the directory. Rollback via restoring snapshot.
3. **overlay**: Overlay filesystem mount. Rollback via discarding overlay.
4. **transaction_rollback**: Database transaction with rollback capability.
5. **none**: No isolation. Used for read-only resources or resources that cannot be sandboxed.

## Constraints

- Every resource must have a registered resource type. Untyped resources are not permitted.
- Resource names follow the namespace system (`[[server:]namespace/]name`).
- Resources are independently registered and exist outside of any project. Projects link to resources; they do not define them inline.
- A resource linked to a project with `project_read_only: true` must not be modified by any tool invoked within that project, even in sandbox.
- DAG relationships must be acyclic. Circular dependencies are rejected at registration time.

## Consequences

### Positive
- A uniform abstraction handles diverse artifact types (git repos, filesystems, databases, APIs) through the same management interface.
- Per-type sandbox strategies ensure appropriate isolation without requiring per-resource configuration.
- Independent registration enables resource sharing across multiple projects.
- DAG relationships enable correct ordering of sandbox creation and cleanup.

### Negative
- The type registration system adds setup overhead before resources can be used.
- Custom resource types (databases, APIs) require implementing sandbox strategy adapters.
- The DAG tracking adds complexity to resource management.

### Risks
- Resource types that cannot be sandboxed (`none` strategy) create a safety gap for plans that assume isolation.
- The resource registry could become stale if physical artifacts move or are deleted without updating registrations.

## Alternatives Considered

None — specification-driven requirement. The typed resource system with registry, DAG relationships, and per-type sandbox strategies is prescribed by the specification as the foundation for tool resource bindings and sandboxed execution.

## Compliance

- **Type validation**: Registration commands reject resources without a valid registered type.
- **DAG cycle detection**: Registration and linking operations validate that no cycles are introduced.
- **Sandbox strategy tests**: Each sandbox strategy has integration tests verifying isolation, modification, rollback, and cleanup.
- **Binding resolution tests**: Unit tests verify that all three binding modes (contextual, static, parameter) resolve correctly for each resource type.
- **BDD scenarios**: Behave features exercise multi-resource, multi-type plan execution including sandbox creation, tool binding, and result merging.

## Related ADRs

| ADR | Title | Relationship |
|-----|-------|-------------|
| [ADR-002](ADR-002-namespace-system.md) | Namespace System | Resources are identified and resolved via the universal naming convention |
| [ADR-009](ADR-009-project-model.md) | Project Model | Projects aggregate and scope the resources available to plans |
| [ADR-011](ADR-011-tool-system.md) | Tool System | Tools declare resource bindings that determine which resources they operate on |
| [ADR-015](ADR-015-sandbox-and-checkpoint.md) | Sandbox and Checkpoint | Per-resource-type sandbox strategies isolate resource modifications |

## Acceptance

### Votes For

| Voter | Comment |
|-------|---------|
| Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> | Typed resources with DAG relationships and per-type sandbox strategies provide the right abstraction for safe manipulation |

**Total: 1**

### Votes Against

| Voter | Comment |
|-------|---------|

**Total: 0**

### Abstentions

| Voter | Comment |
|-------|---------|

**Total: 0**
