# Capability Metadata


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## CapabilityMeta

The `CapabilityMeta` dataclass stores metadata about a capability,
including its name, version, and runtime state.

------------------------------------------------------------------------

### ResourceRequirements

``` python

def ResourceRequirements(
    requires_gpu:bool=False, platforms:List=<factory>, accelerators:List=<factory>
)->None:

```

*Binary hard-facts about what a capability needs to run (Phase 5a).*

Quantitative resource amounts (min_vram_mb, etc.) deliberately omitted
per CR-7’s reactive resource management reframing — capability authors
can’t reliably estimate model × dtype × quantization combinatorics, and
Blender- style variable-render capabilities can’t estimate at all. The
substrate uses these binary hard-facts purely for discovery filtering;
actual resource contention is handled reactively by CR-7’s eviction +
retry flow.

- `requires_gpu`: True if the capability needs any GPU; the substrate
  gates execution on a system monitor reporting one is present.
- `platforms`: e.g., \[“linux-x64”, “darwin-arm64”\]. Empty list means
  no platform constraint declared (assume universal compatibility).
- `accelerators`: e.g., \[“cuda”, “mps”, “cpu”\]. Informational;
  substrate doesn’t auto-select but consumers can filter on the values.

------------------------------------------------------------------------

### CapabilityMeta

``` python

def CapabilityMeta(
    name:str, version:str, description:str='', resources:Optional=None, config_schema:Optional=None,
    instance:Optional=None, enabled:bool=True, last_executed:float=0.0, config_schema_drift:bool=False,
    live_config_schema:Optional=None, structural_surface_drift:bool=False
)->None:

```

*Metadata about a capability.*

## CapabilityInstance (CR-10)

CR-10 introduces multi-instance capability support: a single discovered
capability can have multiple loaded instances differing by
configuration. `CapabilityInstance` is the per-instance runtime state,
keyed by `instance_id` in `CapabilityManager._instances` /
`CapabilityManager.instances`.

The `CapabilityMeta` continues to hold per-capability (per-name)
discovery + canonical-instance state; `CapabilityInstance` covers what
differs across multiple loads of the same capability: the proxy, the
config that initialized it, the enabled flag, last-executed timestamp,
and creation time.

**Naming conventions** (constrained-pattern, per CR-10 Q-resolution):

- Default: `instance_id == capability_name` — backward-compat for
  single-instance code paths.
- Named: caller passes a constrained string (`{alphanumeric, _, -}+`,
  len ≤ 64).
- Auto-generated: caller passes `new_instance=True` and the substrate
  produces `{capability_name}-{6-char hex}`.

The first instance loaded for a capability (default
`instance_id == capability_name`) is the “canonical” instance — code
reading `CapabilityMeta.instance` continues to see it. Multi-instance
loads after the first don’t disturb that canonical reference.

------------------------------------------------------------------------

### CapabilityInstance

``` python

def CapabilityInstance(
    instance_id:str, capability_name:str, config:Dict=<factory>, proxy:Optional=None, enabled:bool=True,
    last_executed:float=0.0, created_at:datetime=<factory>, config_hash:str='',
    max_concurrent_requests:Optional=None
)->None:

```

*Per-instance runtime state for a loaded capability (CR-10
multi-instance).*

Differs from CapabilityMeta in scope: - CapabilityMeta is
per-capability-name discovery + canonical-instance state. -
CapabilityInstance is per-load-call runtime state.

A capability loaded with no instance_id (default) gets
`instance_id == capability_name` and is the canonical instance
referenced by CapabilityMeta.instance. Multi-instance loads (instance_id
!= capability_name) add entries to CapabilityManager.instances without
changing the canonical reference.

------------------------------------------------------------------------

### CapabilityLoadSpec

``` python

def CapabilityLoadSpec(
    meta:Any, config:Optional=None, instance_id:Optional=None, new_instance:bool=False
)->None:

```

*One entry in `CapabilityManager.load_capabilities_concurrent`’s batch
input (CR-10).*

Mirrors the positional arguments of `load_capability` so the concurrent
helper can fan out load calls without repeating the per-spec instance_id
/ new_instance plumbing.

- `meta`: the discovered CapabilityMeta to load (must have a `.manifest`
  attached).
- `config`: initial configuration; falls through to
  persisted-or-schema-defaults when None (default-instance only;
  multi-instance starts fresh).
- `instance_id`: explicit instance_id (validated against
  \[A-Za-z0-9\_-\]{1,64}). None defaults to capability_name
  (single-instance backward compat).
- `new_instance`: when True with instance_id=None, auto-generate
  `{capability_name}-{6-hex}`.

### Example: Creating Capability Metadata

``` python
# Create capability metadata
meta = CapabilityMeta(
    name="example_capability",
    version="1.0.0",
    description="An example capability",
    config_schema={
        "type": "object",
        "properties": {
            "model": {"type": "string", "default": "base"},
            "device": {"type": "string", "enum": ["cpu", "cuda"]}
        }
    }
)

print("CapabilityMeta instance:")
print(meta)
print(f"\nName: {meta.name}")
print(f"Version: {meta.version}")
print(f"Config Schema: {meta.config_schema}")
print(f"Enabled: {meta.enabled}")
print(f"Instance: {meta.instance}")
```

``` python
# Test with minimal arguments
minimal_meta = CapabilityMeta(name="minimal", version="0.1.0")
print(f"Minimal CapabilityMeta: {minimal_meta}")

# Test equality
meta_copy = CapabilityMeta(name="minimal", version="0.1.0")
print(f"\nEquality test: {minimal_meta == meta_copy}")
```

    Minimal PluginMeta: PluginMeta(name='minimal', version='0.1.0', description='', author='', package_name='', category='', interface='', config_schema=None, instance=None, enabled=True, last_executed=0.0)

    Equality test: True

``` python
# Phase 5a: ResourceRequirements round-trips cleanly, and CapabilityMeta
# accepts it as an optional field (None for capabilities declaring no constraints).
res = ResourceRequirements(
    requires_gpu=True,
    platforms=["linux-x64", "darwin-arm64"],
    accelerators=["cuda", "mps"],
)
assert res.requires_gpu is True
assert "linux-x64" in res.platforms

# ResourceRequirements defaults: no GPU, empty platforms (universal), empty accelerators.
default_res = ResourceRequirements()
assert default_res.requires_gpu is False
assert default_res.platforms == []
assert default_res.accelerators == []

# CapabilityMeta accepts resources; defaults to None when unconstrained.
typed_meta = CapabilityMeta(
    name="whisper-local",
    version="1.0.0",
    description="Local Whisper-based STT",
    resources=res,
)
assert typed_meta.resources.requires_gpu is True

legacy_meta = CapabilityMeta(name="legacy", version="0.0.1")
assert legacy_meta.resources is None

print("✓ ResourceRequirements + CapabilityMeta integration")
```
