# ADR-005: Extension Framework

## Status

Accepted

## Context

Provisioning required a flexible extension mechanism to support:

1. **Custom Providers**: Organizations need to add custom cloud providers beyond AWS, UpCloud, and local
2. **Custom Task Services**: Users need to integrate proprietary infrastructure services
3. **Custom Workflows**: Complex organizations require custom orchestration patterns
4. **Third-Party Integration**: Need to integrate with existing toolchains and systems
5. **User Customization**: Power users want to extend and modify system behavior
6. **Plugin Ecosystem**: Enable community contributions and extensions
7. **Isolation Requirements**: Extensions must not compromise system stability
8. **Discovery Mechanism**: System must automatically discover and load extensions
9. **Version Compatibility**: Extensions must work across system version upgrades
10. **Configuration Integration**: Extensions should integrate with configuration-driven architecture

The system needed an extension framework that provides:

- Clear extension API and interfaces
- Safe isolation of extension code
- Automatic discovery and loading
- Configuration integration
- Version compatibility management
- Developer-friendly extension development patterns

## Decision

Implement a **registry-based extension framework** with structured discovery and isolation:

### Extension Architecture

#### Extension Types

1. **Provider Extensions**: Custom cloud providers and infrastructure backends
2. **Task Service Extensions**: Custom infrastructure services and components
3. **Workflow Extensions**: Custom orchestration and deployment patterns
4. **CLI Extensions**: Additional command-line tools and interfaces
5. **Template Extensions**: Custom configuration and code generation templates
6. **Integration Extensions**: External system integrations and connectors

### Extension Structure

```plaintext
extensions/
├── providers/              # Provider extensions
│   └── custom-cloud/
│       ├── extension.toml  # Extension manifest
│       ├── kcl/           # KCL configuration schemas
│       ├── nulib/         # Nushell implementation
│       └── templates/     # Configuration templates
├── taskservs/             # Task service extensions
│   └── custom-service/
│       ├── extension.toml
│       ├── kcl/
│       ├── nulib/
│       └── manifests/     # Kubernetes manifests
├── workflows/             # Workflow extensions
│   └── custom-workflow/
│       ├── extension.toml
│       └── nulib/
├── cli/                   # CLI extensions
│   └── custom-commands/
│       ├── extension.toml
│       └── nulib/
└── integrations/          # Integration extensions
    └── external-tool/
        ├── extension.toml
        └── nulib/
```plaintext

### Extension Manifest (extension.toml)

```toml
[extension]
name = "custom-provider"
version = "1.0.0"
type = "provider"
description = "Custom cloud provider integration"
author = "Organization Name"
license = "MIT"
homepage = "https://github.com/org/custom-provider"

[compatibility]
provisioning_version = ">=3.0.0,<4.0.0"
nushell_version = ">=0.107.0"
kcl_version = ">=0.11.0"

[dependencies]
http_client = ">=1.0.0"
json_parser = ">=2.0.0"

[entry_points]
cli = "nulib/cli.nu"
provider = "nulib/provider.nu"
config_schema = "schemas/schema.ncl"

[configuration]
config_prefix = "custom_provider"
required_env_vars = ["CUSTOM_PROVIDER_API_KEY"]
optional_config = ["custom_provider.region", "custom_provider.timeout"]
```plaintext

### Key Framework Principles

1. **Registry-Based Discovery**: Extensions registered in structured directories
2. **Manifest-Driven Loading**: Extension capabilities declared in manifest files
3. **Version Compatibility**: Explicit compatibility declarations and validation
4. **Configuration Integration**: Extensions integrate with system configuration hierarchy
5. **Isolation Boundaries**: Extensions isolated from core system and each other
6. **Standard Interfaces**: Consistent interfaces across extension types
7. **Development Patterns**: Clear patterns for extension development
8. **Community Support**: Framework designed for community contributions

## Consequences

### Positive

- **Extensibility**: System can be extended without modifying core code
- **Community Growth**: Enable community contributions and ecosystem development
- **Organization Customization**: Organizations can add proprietary integrations
- **Innovation Support**: New technologies can be integrated via extensions
- **Isolation Safety**: Extensions cannot compromise system stability
- **Configuration Consistency**: Extensions integrate with configuration-driven architecture
- **Development Efficiency**: Clear patterns reduce extension development time
- **Version Management**: Compatibility system prevents breaking changes
- **Discovery Automation**: Extensions automatically discovered and loaded

### Negative

- **Complexity Increase**: Additional layer of abstraction and management
- **Performance Overhead**: Extension loading and isolation adds runtime cost
- **Testing Complexity**: Must test extension framework and individual extensions
- **Documentation Burden**: Need comprehensive extension development documentation
- **Version Coordination**: Extension compatibility matrix requires management
- **Support Complexity**: Community extensions may require support resources

### Neutral

- **Development Patterns**: Different patterns for extension vs core development
- **Quality Control**: Community extensions may vary in quality and maintenance
- **Security Considerations**: Extensions need security review and validation
- **Dependency Management**: Extension dependencies must be managed carefully

## Alternatives Considered

### Alternative 1: Filesystem-Based Extensions

Simple filesystem scanning for extension discovery.
**Rejected**: No manifest validation or version compatibility checking. Fragile discovery mechanism.

### Alternative 2: Database-Backed Registry

Store extension metadata in database for discovery.
**Rejected**: Adds database dependency complexity. Over-engineering for extension discovery needs.

### Alternative 3: Package Manager Integration

Use existing package managers (cargo, npm) for extension distribution.
**Rejected**: Complicates installation and creates external dependencies. Not suitable for corporate environments.

### Alternative 4: Container-Based Extensions

Each extension runs in isolated container.
**Rejected**: Too heavy for simple extensions. Complicates development and deployment significantly.

### Alternative 5: Plugin Architecture

Traditional plugin architecture with dynamic loading.
**Rejected**: Complex for shell-based system. Security and isolation challenges in Nushell environment.

## Implementation Details

### Extension Discovery Process

1. **Directory Scanning**: Scan extension directories for manifest files
2. **Manifest Validation**: Parse and validate extension manifest
3. **Compatibility Check**: Verify version compatibility requirements
4. **Dependency Resolution**: Resolve extension dependencies
5. **Configuration Integration**: Merge extension configuration schemas
6. **Entry Point Registration**: Register extension entry points with system

### Extension Loading Lifecycle

```bash
# Extension discovery and validation
provisioning extension discover
provisioning extension validate --extension custom-provider

# Extension activation and configuration
provisioning extension enable custom-provider
provisioning extension configure custom-provider

# Extension usage
provisioning provider list  # Shows custom providers
provisioning server create --provider custom-provider

# Extension management
provisioning extension disable custom-provider
provisioning extension update custom-provider
```plaintext

### Configuration Integration

Extensions integrate with hierarchical configuration system:

```toml
# System configuration includes extension settings
[custom_provider]
api_endpoint = "https://api.custom-cloud.com"
region = "us-west-1"
timeout = 30

# Extension configuration follows same hierarchy rules
# System defaults → User config → Environment config → Runtime
```plaintext

### Security and Isolation

- **Sandboxed Execution**: Extensions run in controlled environment
- **Permission Model**: Extensions declare required permissions in manifest
- **Code Review**: Community extensions require review process
- **Digital Signatures**: Extensions can be digitally signed for authenticity
- **Audit Logging**: Extension usage tracked in system audit logs

### Development Support

- **Extension Templates**: Scaffold new extensions from templates
- **Development Tools**: Testing and validation tools for extension developers
- **Documentation Generation**: Automatic documentation from extension manifests
- **Integration Testing**: Framework for testing extensions with core system

## Extension Development Patterns

### Provider Extension Pattern

```nushell
# extensions/providers/custom-cloud/nulib/provider.nu
export def list-servers [] -> table {
    http get $"($config.custom_provider.api_endpoint)/servers"
    | from json
    | select name status region
}

export def create-server [name: string, config: record] -> record {
    let payload = {
        name: $name,
        instance_type: $config.plan,
        region: $config.zone
    }

    http post $"($config.custom_provider.api_endpoint)/servers" $payload
    | from json
}
```plaintext

### Task Service Extension Pattern

```nushell
# extensions/taskservs/custom-service/nulib/service.nu
export def install [server: string] -> nothing {
    let manifest_data = open ./manifests/deployment.yaml
    | str replace "{{server}}" $server

    kubectl apply --server $server --data $manifest_data
}

export def uninstall [server: string] -> nothing {
    kubectl delete deployment custom-service --server $server
}
```plaintext

## References

- Workspace Isolation (ADR-003)
- Configuration System Architecture (ADR-002)
- Hybrid Architecture Integration (ADR-004)
- Community Extension Guidelines
- Extension Security Framework
- Extension Development Documentation
