Metadata-Version: 2.4
Name: capdag
Version: 1.285.0
Summary: Core cap URN and definition system for MACHFAB cartridges
Author: https://github.com/machinefabric
License-Expression: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: opsx-py>=1.20.114
Requires-Dist: tagged-urn>=1.27.122
Requires-Dist: cbor2>=5.4.0
Requires-Dist: python-pest>=0.1.1
Requires-Dist: httpx>=0.24
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"

# capdag-py

Python implementation of the capdag (Cap SDK) - Core cap URN and definition system for MACHFAB cartridges.

This library provides the fundamental cap URN system used across all MACHFAB cartridges and candidates. It defines the formal structure for cap identifiers with flat tag-based naming, wildcard support, and specificity comparison.

## Features

- **MediaUrn**: Media type definition using tagged URN format with "media" prefix
- **CapUrn**: Cap identifiers with required `in` and `out` direction specs
- Semantic matching with wildcard support
- Specificity-based selection for finding best matching capabilities
- Full compatibility with the Rust reference implementation

## Installation

```bash
# Install in development mode
pip install -e .

# With development dependencies
pip install -e ".[dev]"
```

## Dependencies

- **tagged-urn**: Flat tag-based URN system (Python implementation)

## Usage

```python
from capdag import (
    MediaUrn,
    CapUrn,
    CapUrnBuilder,
    MEDIA_STRING,
    MEDIA_OBJECT,
    MEDIA_VOID,
)

# Create media URNs
string_urn = MediaUrn.from_string(MEDIA_STRING)
print(string_urn.is_text())  # True
print(string_urn.is_scalar())  # True

# Create cap URNs
cap = CapUrnBuilder() \
    .in_spec(MEDIA_STRING) \
    .out_spec(MEDIA_OBJECT) \
    .tag("op", "generate") \
    .tag("ext", "pdf") \
    .build()

print(cap.to_string())  # cap:ext=pdf;in="media:textable";generate;out="media:record;textable"

# Matching semantics
request = CapUrn.from_string('cap:generate;in=media:textable;out="media:record;textable"')
print(cap.accepts(request))  # True

# Specificity
print(cap.specificity())  # Higher score = more specific
```

## Testing

Tests mirror the Rust implementation with matching TEST### numbers for cross-tracking:

```bash
# Run all tests
pytest tests/

# Run specific test files
pytest tests/test_cap_urn.py
pytest tests/test_media_urn.py

# Run with coverage
pytest --cov=capdag tests/
```

### Test Coverage

The implementation includes comprehensive tests covering:

#### CapUrn Tests (TEST001-TEST052) - 52 tests ✅
- TEST001-TEST039: Core CapUrn functionality, parsing, serialization, matching
- TEST040-TEST052: Advanced matching semantics and direction handling

#### MediaUrn Tests (TEST057-TEST078, TEST304-TEST306) - 25 tests ✅
- TEST057-TEST078: MediaUrn parsing, type checking, matching, specificity
- TEST304-TEST306: Additional media URN constant validation

#### Cap Tests (TEST108-TEST116) - 9 tests ✅
- TEST108-TEST116: Cap creation, arguments, stdin, output, metadata, serialization

#### Manifest Tests (TEST148-TEST155) - 8 tests ✅
- TEST148-TEST155: Manifest creation, serialization, multiple caps, optional fields

#### Response Tests (TEST168-TEST170) - 3 tests ✅
- TEST168-TEST170: Response wrapper for JSON, primitives, and binary data

#### Standard Caps Tests (TEST307-TEST312) - 6 tests ✅
- TEST307-TEST312: Standard URN builders for capabilities

#### Validation Tests (TEST051-056) - 14 tests ✅
- TEST051-056: Input validation, argument checking, validation rules
- RULE1-RULE10: Comprehensive validation rule enforcement

#### Schema Validation Tests (TEST163-167) - 10 tests ✅
- TEST163-167: JSON schema validation for arguments and outputs

#### Caller Tests (TEST156-162, TEST274-283) - 21 tests ✅
- TEST156-162: StdinSource variants and debugging
- TEST274-283: CapArgumentValue creation and handling

#### Registry Tests (TEST135-147) - 17 tests ✅
- TEST135-147: Registry creation, caching, URL encoding, configuration

**Total: 165/308 passing tests (54% complete)**

## Architecture

### MediaUrn

Media URNs use the "media" prefix and describe data types using tags:

```
media:<markers>[;key=value]*
```

Examples:
- `media:bytes` - Binary data
- `media:textable` - Text, single value
- `media:bytes;ext=pdf` - PDF document (binary)

### CapUrn

Cap URNs use the "cap" prefix and require `in` and `out` direction specs:

```
cap:in="<media-urn>";out="<media-urn>"[;key=value]*
```

Examples:
- `cap:in="media:void";test;out="media:void"` - No-op test capability
- `cap:in="media:bytes;ext=pdf";generate-thumbnail;out="media:bytes;ext=png;image;thumbnail"` - PDF thumbnail generator

### Matching Semantics

Matching follows tagged URN semantics with direction-aware rules:

- **Input matching**: `cap_input.accepts(request_input)` - Does the cap's input requirement accept the request's data?
- **Output matching**: `cap_output.conforms_to(request_output)` - Does the cap's output conform to the request's expectation?
- **Missing tags** are treated as wildcards (less specific, can handle any value)
- **Specificity**: Direction specs contribute their MediaUrn tag count; more tags = more specific

## Development

The Python implementation follows these principles:

1. **Production code only** - No placeholders, TODOs, or stopgaps
2. **Root cause fixes** - Issues are fixed at their source, not worked around
3. **Python conventions** - Follows Pythonic patterns while maintaining semantic compatibility
4. **Test-driven** - Tests expose issues and track completion
5. **Cross-language compatibility** - Tests numbered to match Rust reference implementation

## License

MIT

## Reference

- Rust reference implementation: [capdag](../capdag)
- Tagged URN Python: [tagged-urn-py](https://github.com/machinefabric/tagged-urn-py)
- Tagged URN Rust: [tagged-urn-rs](https://github.com/machinefabric/tagged-urn-rs)
