spec-kit-runtime 1.0.1
Plugin runtime environment for Spec-Kit - Plugin container, message bus, and sandbox
License: MIT
Requires Python: >=3.11
Keywords: message-bus, plugins, runtime, sandbox, spec-kit

# spec-kit-runtime

Plugin runtime environment for the Spec-Kit ecosystem.

## Overview

This package provides the runtime infrastructure for loading, managing, and executing plugins in the Spec-Kit ecosystem. It includes:

- **Plugin Container**: Manages plugin lifecycle (discovery → load → activate → deactivate → unload)
- **Message Bus**: Pattern-based message routing with scoped delivery
- **Plugin Sandbox**: Restricted execution environment for untrusted plugins
- **Service Provider**: Dependency injection for plugin services
- **Security**: Path validation, input sanitization, code security

## Installation

```bash
pip install spec-kit-runtime
```

## Key Components

### PluginContainer

Manages complete plugin lifecycle:

```python
from spec_kit_runtime import PluginContainer
from pathlib import Path

# Create container
container = PluginContainer()

# Discover plugins
plugins = container.discover_plugins([
    Path(".specify/plugins"),
    Path("~/.specify/plugins").expanduser(),
])

# Load a plugin
plugin_info = container.discovered_plugins["design"]
container.load_plugin(plugin_info, config={"enabled": True})

# Activate
container.activate_plugin("design")

# Use plugin (via message bus)
result = container.send_message("design", command_message)

# Cleanup
container.shutdown()
```

### ScopedMessageBus

Pattern-based message routing with plugin isolation:

```python
from spec_kit_runtime import ScopedMessageBus

bus = ScopedMessageBus()
bus.start()

# Register plugin scope
bus.register_scope("design", [
    "command:design:*",
    "event:system:*",
])

# Subscribe to patterns
bus.subscribe_scoped("design", "command:design:generate", handler)

# Send messages
bus.send_scoped("design", command_message)

bus.stop()
```

### PluginSandbox

Restricted execution environment:

```python
from spec_kit_runtime import PluginSandbox

sandbox = PluginSandbox(
    allowed_imports=["json", "datetime", "pathlib"],
    restricted_builtins=["eval", "exec", "open"],
)

# Load plugin in sandbox
plugin = sandbox.load_plugin(plugin_info, config)
```

### ServiceProvider

Dependency injection for plugins:

```python
from spec_kit_runtime import ServiceProvider

provider = ServiceProvider()

# Register services
provider.register_service("plugin-id", IFileSystemService, fs_impl)
provider.register_service("plugin-id", IConfigService, config_impl)

# Get services
fs = provider.get_service(IFileSystemService)
```

## Plugin Loading Modes

### Normal Mode (sandbox=false)
- Direct Python import
- Full access to allowed modules
- Fastest execution
- Use for trusted plugins

### Sandboxed Mode (sandbox=true, default)
- RestrictedImporter limits imports
- RestrictedBuiltins blocks dangerous functions
- AST validation detects dangerous patterns
- Use for untrusted plugins

### Process-Isolated Mode (process_isolated=true)
- Separate Python process
- IPC communication
- Maximum isolation
- Use for completely untrusted plugins

## Security Features

### Import Restrictions
- 60+ dangerous modules blocked (os, subprocess, socket, etc.)
- Whitelist of safe standard library modules
- No dynamic import tricks allowed

### Builtin Restrictions
- eval, exec blocked
- open blocked (use IFileSystemService instead)
- compile, __import__ restricted

### AST Validation
- Detects dangerous code patterns
- Blocks metaclass manipulation
- Prevents attribute access exploits

### Path Security
- Path traversal protection
- Plugin ID sanitization
- Version format validation

## Message Patterns

Plugins communicate via message patterns:

| Pattern | Example | Description |
|---------|---------|-------------|
| `command:{plugin}:{action}` | `command:design:generate` | Execute action |
| `event:{plugin}:{name}` | `event:design:completed` | Notification |
| `request:{plugin}:{method}` | `request:config:get` | Request/response |
| `generator:{name}` | `generator:hld` | Content generation |
| `validator:{name}` | `validator:python` | Validation |
| `hook:{name}` | `hook:post_save` | Lifecycle hook |

## Architecture

```
┌─────────────────────────────────────────────────┐
│                 PluginContainer                  │
│  ┌───────────┐  ┌───────────┐  ┌───────────┐   │
│  │ Discovery │  │  Loader   │  │ Lifecycle │   │
│  └─────┬─────┘  └─────┬─────┘  └─────┬─────┘   │
│        │              │              │          │
│  ┌─────┴──────────────┴──────────────┴─────┐   │
│  │           ScopedMessageBus               │   │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐  │   │
│  │  │ Scope A │  │ Scope B │  │ Scope C │  │   │
│  │  └─────────┘  └─────────┘  └─────────┘  │   │
│  └──────────────────────────────────────────┘   │
│                       │                         │
│  ┌────────────────────┴────────────────────┐   │
│  │          ServiceProvider                 │   │
│  │  ┌─────────────────────────────────┐    │   │
│  │  │ Plugin Services (per-plugin)    │    │   │
│  │  └─────────────────────────────────┘    │   │
│  └──────────────────────────────────────────┘   │
└─────────────────────────────────────────────────┘
```

## Dependencies

- `spec-kit-contracts>=1.0.0` - Interface contracts
- `pyyaml>=6.0` - Configuration parsing

## License

MIT License - see LICENSE file for details.