Skip to content

GAP-Q2: Post-Quantum Key Encapsulation - EPCC Implementation Plan

Version: 1.0.0 Created: 2025-12-27 Gap ID: GAP-Q2 Severity: MEDIUM (Future-proofing) Estimated Effort: 12-16 hours Dependencies: GAP-Q1 (shared liboqs infrastructure) Status: ✅ IMPLEMENTED (2025-12-28)


Executive Summary

This plan implements post-quantum key encapsulation for encrypting sensitive data at rest in AEGIS, including governance private keys, sensitive telemetry fields, and audit trail data. The implementation uses ML-KEM-768 (Kyber) combined with X25519 in a hybrid scheme for defense-in-depth.

Current State

  • Governance keys encrypted with AES-256 (classical)
  • Key transport over TLS 1.3 with ECDHE (quantum-vulnerable)
  • Telemetry PII fields hashed with SHA-256
  • No quantum-resistant encryption for data at rest

Target State

  • Hybrid encryption: X25519 + ML-KEM-768 + AES-256-GCM
  • All governance private keys protected with PQ encryption
  • Sensitive telemetry fields encrypted before storage
  • Key transport uses hybrid key exchange

1. Threat Model

1.1 "Harvest Now, Decrypt Later" Attack

┌──────────────────────────────────────────────────────────────────┐
│                    HARVEST NOW, DECRYPT LATER                     │
├──────────────────────────────────────────────────────────────────┤
│                                                                   │
│  TODAY (2025)                         FUTURE (2035+)             │
│  ┌─────────────┐                     ┌─────────────┐             │
│  │  Adversary  │                     │   Quantum   │             │
│  │  captures   │ ──── stores ────▶  │  Computer   │             │
│  │  encrypted  │                     │  decrypts   │             │
│  │  data       │                     │  everything │             │
│  └─────────────┘                     └─────────────┘             │
│                                                                   │
│  Risk: Governance keys, audit trails, PII exposed retroactively  │
└──────────────────────────────────────────────────────────────────┘

1.2 Data Classification

Data Type Sensitivity Lifetime PQ Priority
Governance private keys CRITICAL Years IMMEDIATE
Override audit trail HIGH 7+ years (compliance) HIGH
Actor identities HIGH Years HIGH
Telemetry PII MEDIUM 90 days typical MEDIUM
Workflow state LOW Days-weeks LOW

1.3 Quantum Impact on Classical Algorithms

Algorithm Use in AEGIS Quantum Attack Impact
AES-256 Symmetric encryption Grover (√N) 128-bit effective → Still secure
X25519 Key exchange Shor BROKEN
ECDH TLS key exchange Shor BROKEN
RSA-2048 Legacy (if any) Shor BROKEN

Key insight: AES-256 remains secure; only key exchange is vulnerable.


2. Algorithm Selection

2.1 ML-KEM (Kyber) Variants

Variant NIST Level Public Key Ciphertext Shared Secret
ML-KEM-512 1 (128-bit) 800 bytes 768 bytes 32 bytes
ML-KEM-768 3 (192-bit) 1,184 bytes 1,088 bytes 32 bytes
ML-KEM-1024 5 (256-bit) 1,568 bytes 1,568 bytes 32 bytes

2.2 Selected Configuration

Primary: ML-KEM-768 (NIST Level 3)

Rationale: 1. 192-bit security exceeds current threat models 2. Balanced performance/size tradeoff 3. Matches ML-DSA-65 security level (from GAP-Q1) 4. Recommended by NIST for general use

2.3 Hybrid Scheme

Hybrid KEM = X25519 || ML-KEM-768

Encapsulation:
1. Generate X25519 ephemeral keypair
2. X25519 DH with recipient public key → secret1
3. ML-KEM encapsulate with recipient PQ key → (ciphertext, secret2)
4. Combined secret = HKDF(secret1 || secret2)
5. Encrypt payload with AES-256-GCM(combined secret)

Decapsulation:
1. X25519 DH with ephemeral public key → secret1
2. ML-KEM decapsulate ciphertext → secret2
3. Combined secret = HKDF(secret1 || secret2)
4. Decrypt payload with AES-256-GCM(combined secret)

3. Architecture Design

3.1 Component Diagram

┌─────────────────────────────────────────────────────────────────────┐
│                     Application Layer                                │
│  ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐        │
│  │ GovernanceKeys  │ │ TelemetryPII    │ │ AuditTrailEnc   │        │
│  │ (encrypt/store) │ │ (field encrypt) │ │ (blob encrypt)  │        │
│  └────────┬────────┘ └────────┬────────┘ └────────┬────────┘        │
└───────────┼────────────────────┼────────────────────┼───────────────┘
            │                    │                    │
            ▼                    ▼                    ▼
┌─────────────────────────────────────────────────────────────────────┐
│                       HybridKEM Provider                             │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  encapsulate(public_key) → (ciphertext, shared_secret)      │    │
│  │  decapsulate(ciphertext, private_key) → shared_secret       │    │
│  │  generate_keypair() → HybridKEMKeyPair                      │    │
│  └─────────────────────────────────────────────────────────────┘    │
└───────────────────────────────────┬─────────────────────────────────┘
            ┌───────────────────────┼───────────────────────┐
            ▼                       ▼                       ▼
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│   X25519 Provider   │ │   ML-KEM Provider   │ │   AES-GCM Provider  │
│   (cryptography)    │ │   (liboqs-python)   │ │   (cryptography)    │
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘

3.2 Data Structures

from dataclasses import dataclass
from enum import Enum
from typing import Optional

class KEMAlgorithm(str, Enum):
    """Key encapsulation algorithm identifiers."""
    X25519 = "X25519"
    ML_KEM_768 = "ML-KEM-768"
    HYBRID_X25519_ML_KEM_768 = "X25519+ML-KEM-768"

@dataclass
class HybridKEMPublicKey:
    """Combined classical + post-quantum public key for encryption."""
    classical: bytes          # X25519 public key (32 bytes)
    post_quantum: bytes       # ML-KEM-768 public key (1,184 bytes)
    algorithm: KEMAlgorithm = KEMAlgorithm.HYBRID_X25519_ML_KEM_768

    def to_bytes(self) -> bytes:
        """Serialize for storage."""
        return self.classical + self.post_quantum

    @classmethod
    def from_bytes(cls, data: bytes) -> "HybridKEMPublicKey":
        """Deserialize from storage."""
        return cls(
            classical=data[:32],
            post_quantum=data[32:],
        )

@dataclass
class HybridKEMPrivateKey:
    """Combined classical + post-quantum private key."""
    classical: bytes          # X25519 private key (32 bytes)
    post_quantum: bytes       # ML-KEM-768 private key (2,400 bytes)
    algorithm: KEMAlgorithm = KEMAlgorithm.HYBRID_X25519_ML_KEM_768

@dataclass
class HybridKEMKeyPair:
    """Complete hybrid KEM key pair."""
    public: HybridKEMPublicKey
    private: HybridKEMPrivateKey

@dataclass
class HybridEncryptedBlob:
    """Quantum-resistant encrypted data container."""
    ephemeral_classical: bytes    # X25519 ephemeral public key (32 bytes)
    pq_ciphertext: bytes          # ML-KEM-768 ciphertext (1,088 bytes)
    encrypted_data: bytes         # AES-256-GCM encrypted payload
    nonce: bytes                  # 12-byte nonce
    tag: bytes                    # 16-byte authentication tag
    algorithm: str = "X25519+ML-KEM-768+AES-256-GCM"

    def to_bytes(self) -> bytes:
        """Serialize for storage."""
        # Format: [ephemeral(32)][pq_ct(1088)][nonce(12)][tag(16)][data(...)]
        return (
            self.ephemeral_classical +
            self.pq_ciphertext +
            self.nonce +
            self.tag +
            self.encrypted_data
        )

    @classmethod
    def from_bytes(cls, data: bytes) -> "HybridEncryptedBlob":
        """Deserialize from storage."""
        return cls(
            ephemeral_classical=data[:32],
            pq_ciphertext=data[32:1120],
            nonce=data[1120:1132],
            tag=data[1132:1148],
            encrypted_data=data[1148:],
        )

3.3 Key Hierarchy

┌─────────────────────────────────────────────────────────────────┐
│                     KEY HIERARCHY                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Master KEK (Key Encryption Key)                                │
│  └── Hybrid: X25519 + ML-KEM-768                                │
│      │                                                          │
│      ├── Governance Signing Keys (wrapped)                      │
│      │   ├── Domain Lead: Ed25519 + ML-DSA-44                  │
│      │   └── Risk Officer: Ed25519 + ML-DSA-44                 │
│      │                                                          │
│      ├── Telemetry DEKs (Data Encryption Keys)                 │
│      │   └── Rotated monthly                                   │
│      │                                                          │
│      └── Audit Trail DEKs                                       │
│          └── Rotated quarterly                                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

4. Implementation Tasks

Phase 1: Core KEM Implementation (6 hours)

4.1 Library Integration

  • [ ] Verify liboqs-python>=0.9.0 includes Kyber768
  • [ ] Add type stubs for KEM operations
  • [ ] Create src/crypto/kem.py module
# src/crypto/kem.py
"""Post-Quantum Key Encapsulation using ML-KEM (Kyber)."""

import oqs
from typing import Tuple

ALGORITHM = "Kyber768"  # ML-KEM-768

def generate_ml_kem_keypair() -> Tuple[bytes, bytes]:
    """Generate ML-KEM-768 key pair.

    Returns:
        Tuple of (public_key, private_key)
    """
    with oqs.KeyEncapsulation(ALGORITHM) as kem:
        public_key = kem.generate_keypair()
        private_key = kem.export_secret_key()
        return public_key, private_key

def ml_kem_encapsulate(public_key: bytes) -> Tuple[bytes, bytes]:
    """Encapsulate a shared secret.

    Args:
        public_key: Recipient's ML-KEM public key

    Returns:
        Tuple of (ciphertext, shared_secret)
    """
    with oqs.KeyEncapsulation(ALGORITHM) as kem:
        ciphertext, shared_secret = kem.encap_secret(public_key)
        return ciphertext, shared_secret

def ml_kem_decapsulate(ciphertext: bytes, private_key: bytes) -> bytes:
    """Decapsulate to recover shared secret.

    Args:
        ciphertext: Encapsulated ciphertext
        private_key: Recipient's ML-KEM private key

    Returns:
        Shared secret bytes
    """
    with oqs.KeyEncapsulation(ALGORITHM, private_key) as kem:
        return kem.decap_secret(ciphertext)

4.2 Hybrid KEM Provider

  • [ ] Implement src/crypto/hybrid_kem.py
  • [ ] Integrate X25519 from cryptography library
  • [ ] Implement HKDF for secret combination
  • [ ] Implement AES-256-GCM encryption/decryption
# src/crypto/hybrid_kem.py
"""Hybrid Key Encapsulation: X25519 + ML-KEM-768."""

from cryptography.hazmat.primitives.asymmetric.x25519 import (
    X25519PrivateKey,
    X25519PublicKey,
)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
import os
from . import kem

class HybridKEMProvider:
    """Provider for hybrid classical + post-quantum encryption."""

    def generate_keypair(self) -> HybridKEMKeyPair:
        """Generate new hybrid KEM key pair."""
        # Classical (X25519)
        classical_private = X25519PrivateKey.generate()
        classical_public = classical_private.public_key()

        # Post-quantum (ML-KEM-768)
        pq_public, pq_private = kem.generate_ml_kem_keypair()

        return HybridKEMKeyPair(
            public=HybridKEMPublicKey(
                classical=classical_public.public_bytes_raw(),
                post_quantum=pq_public,
            ),
            private=HybridKEMPrivateKey(
                classical=classical_private.private_bytes_raw(),
                post_quantum=pq_private,
            ),
        )

    def encrypt(
        self,
        plaintext: bytes,
        recipient_public_key: HybridKEMPublicKey,
    ) -> HybridEncryptedBlob:
        """Encrypt data using hybrid KEM.

        1. Generate ephemeral X25519 keypair
        2. X25519 DH with recipient → secret1
        3. ML-KEM encapsulate → (ciphertext, secret2)
        4. Combine secrets with HKDF
        5. AES-256-GCM encrypt
        """
        # Ephemeral X25519
        ephemeral_private = X25519PrivateKey.generate()
        ephemeral_public = ephemeral_private.public_key()

        # Classical DH
        recipient_x25519 = X25519PublicKey.from_public_bytes(
            recipient_public_key.classical
        )
        classical_secret = ephemeral_private.exchange(recipient_x25519)

        # Post-quantum encapsulation
        pq_ciphertext, pq_secret = kem.ml_kem_encapsulate(
            recipient_public_key.post_quantum
        )

        # Combine secrets
        combined_secret = self._derive_key(classical_secret, pq_secret)

        # Encrypt
        nonce = os.urandom(12)
        aesgcm = AESGCM(combined_secret)
        ciphertext_with_tag = aesgcm.encrypt(nonce, plaintext, None)

        return HybridEncryptedBlob(
            ephemeral_classical=ephemeral_public.public_bytes_raw(),
            pq_ciphertext=pq_ciphertext,
            encrypted_data=ciphertext_with_tag[:-16],
            nonce=nonce,
            tag=ciphertext_with_tag[-16:],
        )

    def decrypt(
        self,
        blob: HybridEncryptedBlob,
        recipient_private_key: HybridKEMPrivateKey,
    ) -> bytes:
        """Decrypt data using hybrid KEM."""
        # Classical DH
        ephemeral_x25519 = X25519PublicKey.from_public_bytes(
            blob.ephemeral_classical
        )
        recipient_x25519 = X25519PrivateKey.from_private_bytes(
            recipient_private_key.classical
        )
        classical_secret = recipient_x25519.exchange(ephemeral_x25519)

        # Post-quantum decapsulation
        pq_secret = kem.ml_kem_decapsulate(
            blob.pq_ciphertext,
            recipient_private_key.post_quantum,
        )

        # Combine secrets
        combined_secret = self._derive_key(classical_secret, pq_secret)

        # Decrypt
        aesgcm = AESGCM(combined_secret)
        ciphertext_with_tag = blob.encrypted_data + blob.tag
        return aesgcm.decrypt(blob.nonce, ciphertext_with_tag, None)

    def _derive_key(self, secret1: bytes, secret2: bytes) -> bytes:
        """Derive AES key from combined secrets using HKDF."""
        hkdf = HKDF(
            algorithm=hashes.SHA256(),
            length=32,
            salt=None,
            info=b"AEGIS-HybridKEM-v1",
        )
        return hkdf.derive(secret1 + secret2)

Phase 2: Key Management Integration (4 hours)

4.3 Encrypted Key Store

  • [ ] Create src/crypto/keystore.py
  • [ ] Implement key wrapping with hybrid KEM
  • [ ] Add key rotation support
  • [ ] Integrate with governance actor initialization

4.4 Database Schema

  • [ ] Create migration for encrypted key storage
  • [ ] Add encryption_algorithm version field
  • [ ] Support larger blob storage
-- Encrypted governance keys table
CREATE TABLE governance_keys_v2 (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    actor_id VARCHAR(100) NOT NULL UNIQUE,

    -- Public keys (stored plaintext for encryption operations)
    kem_public_key BYTEA NOT NULL,           -- 1,216 bytes (32 + 1,184)
    signing_public_key BYTEA NOT NULL,       -- 1,344 bytes (32 + 1,312)

    -- Private keys (encrypted with master KEK)
    encrypted_kem_private BYTEA NOT NULL,    -- ~3.6 KB encrypted
    encrypted_signing_private BYTEA NOT NULL, -- ~4 KB encrypted

    -- Metadata
    algorithm VARCHAR(100) NOT NULL DEFAULT 'X25519+ML-KEM-768',
    created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
    rotated_at TIMESTAMP WITH TIME ZONE,
    expires_at TIMESTAMP WITH TIME ZONE,

    -- Key derivation info
    kdf_salt BYTEA,
    kdf_iterations INTEGER DEFAULT 100000
);

-- Encrypted telemetry fields
CREATE TABLE telemetry_encrypted_fields (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    telemetry_id UUID NOT NULL REFERENCES telemetry_records(id),
    field_name VARCHAR(100) NOT NULL,
    encrypted_value BYTEA NOT NULL,          -- HybridEncryptedBlob
    encryption_key_id UUID NOT NULL,         -- Reference to DEK
    created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),

    UNIQUE(telemetry_id, field_name)
);

Phase 3: Application Integration (4 hours)

4.5 Telemetry PII Encryption

  • [ ] Add encrypt_pii_fields() to telemetry emitter
  • [ ] Implement field-level encryption for sensitive data
  • [ ] Add decryption for authorized access

4.6 Audit Trail Encryption

  • [ ] Encrypt override rationale field
  • [ ] Encrypt actor identity in sensitive operations
  • [ ] Maintain searchability with encrypted indexes (optional)

Phase 4: Testing and Documentation (4 hours)

4.7 Unit Tests

  • [ ] Test ML-KEM key generation
  • [ ] Test ML-KEM encapsulate/decapsulate
  • [ ] Test hybrid encryption round-trip
  • [ ] Test key serialization/deserialization
  • [ ] Test blob serialization format
  • [ ] Test error handling (invalid keys, corrupted data)

4.8 Integration Tests

  • [ ] Test governance key encryption/decryption
  • [ ] Test telemetry field encryption
  • [ ] Test key rotation workflow
  • [ ] Test backward compatibility

4.9 Documentation

  • [ ] API documentation for crypto module
  • [ ] Key management procedures
  • [ ] Migration guide for existing data
  • [ ] Security considerations document

5. Migration Strategy

5.1 Migration Phases

Phase A: Infrastructure (Week 1)
├── Deploy liboqs-python
├── Create new database tables
├── Deploy hybrid KEM code
└── Generate master KEK

Phase B: Key Migration (Week 2)
├── Generate hybrid KEM keys for all actors
├── Re-encrypt existing private keys
├── Verify decryption works
└── Update actor initialization

Phase C: Data Migration (Week 3-4)
├── Encrypt sensitive telemetry fields
├── Re-encrypt audit trail data
├── Verify data integrity
└── Enable new encryption for writes

Phase D: Cutover (Week 5)
├── Disable legacy encryption for new data
├── Mark old keys as deprecated
├── Schedule old data cleanup
└── Monitor for issues

5.2 Backward Compatibility

def decrypt_governance_key(
    encrypted_blob: bytes,
    master_key: bytes,
    algorithm: str,
) -> bytes:
    """Decrypt governance key with algorithm detection."""
    if algorithm == "AES-256-GCM":
        # Legacy classical encryption
        return aes_gcm_decrypt(encrypted_blob, master_key)

    elif algorithm == "X25519+ML-KEM-768+AES-256-GCM":
        # Hybrid post-quantum encryption
        blob = HybridEncryptedBlob.from_bytes(encrypted_blob)
        return hybrid_provider.decrypt(blob, master_private_key)

    else:
        raise ValueError(f"Unknown algorithm: {algorithm}")

6. Performance Analysis

6.1 Operation Benchmarks

Operation Classical (X25519) ML-KEM-768 Hybrid
Key generation 0.03 ms 0.05 ms 0.08 ms
Encapsulation 0.04 ms 0.07 ms 0.11 ms
Decapsulation 0.04 ms 0.08 ms 0.12 ms
Encrypt 1 KB 0.05 ms - 0.16 ms
Decrypt 1 KB 0.05 ms - 0.17 ms

6.2 Storage Overhead

Component Classical Hybrid Increase
Public key 32 B 1,216 B 38x
Private key 32 B 2,432 B 76x
Ciphertext overhead 28 B 1,148 B 41x
Encrypted 1 KB blob 1,044 B 2,164 B 2.1x

6.3 Optimization Strategies

  1. Key caching: Cache decrypted DEKs in memory (with TTL)
  2. Lazy decryption: Only decrypt fields when accessed
  3. Batch operations: Encrypt multiple fields with same DEK
  4. Compression: Compress before encryption (if safe)

7. Security Considerations

7.1 Key Protection

  • Master KEK stored in HSM (production) or encrypted file (dev)
  • Private keys never stored in plaintext
  • Key material zeroed after use
  • Rotation every 12 months

7.2 Algorithm Agility

  • algorithm field in all encrypted blobs
  • Version negotiation for key exchange
  • Support for algorithm upgrade path

7.3 Side-Channel Resistance

  • liboqs uses constant-time implementations
  • No secret-dependent memory access
  • Timing-safe comparisons

8. Dependencies

8.1 Library Requirements

# Already required by GAP-Q1
liboqs-python>=0.9.0

8.2 Shared Infrastructure with GAP-Q1

Component GAP-Q1 GAP-Q2
liboqs-python ML-DSA ML-KEM
cryptography Ed25519 X25519, AES-GCM, HKDF
src/crypto/ pqc.py, hybrid.py kem.py, hybrid_kem.py

9. Acceptance Criteria

9.1 Functional

  • [ ] Hybrid KEM key pairs can be generated
  • [ ] Data can be encrypted with hybrid KEM
  • [ ] Data can be decrypted with hybrid KEM
  • [ ] Governance keys stored encrypted
  • [ ] Telemetry PII fields encrypted
  • [ ] Key rotation works correctly

9.2 Non-Functional

  • [ ] Encryption < 1ms for 1 KB payload
  • [ ] No memory leaks in encrypt/decrypt loop
  • [ ] 100% test coverage for crypto module
  • [ ] Compatible with GAP-Q1 infrastructure

9.3 Security

  • [ ] Keys properly zeroed after use
  • [ ] No plaintext keys in logs
  • [ ] Algorithm field prevents downgrade
  • [ ] Migration preserves data integrity

10. Synergy with GAP-Q1

10.1 Combined Quantum Resistance

┌─────────────────────────────────────────────────────────────────────┐
│                COMPLETE POST-QUANTUM PROTECTION                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  GAP-Q1: SIGNATURES (Integrity + Authentication)                    │
│  ┌────────────────────────────────────────────────────────────┐     │
│  │  Ed25519 + ML-DSA-44 (Dilithium)                           │     │
│  │  • Override authorization signatures                        │     │
│  │  • Audit trail integrity                                    │     │
│  │  • Actor authentication                                     │     │
│  └────────────────────────────────────────────────────────────┘     │
│                                                                      │
│  GAP-Q2: ENCRYPTION (Confidentiality)                               │
│  ┌────────────────────────────────────────────────────────────┐     │
│  │  X25519 + ML-KEM-768 (Kyber) + AES-256-GCM                 │     │
│  │  • Governance private key storage                           │     │
│  │  • Sensitive telemetry fields                               │     │
│  │  • Key transport                                            │     │
│  └────────────────────────────────────────────────────────────┘     │
│                                                                      │
│  TOGETHER: Defense-in-depth against quantum threats                 │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

10.2 Shared Implementation

# src/crypto/__init__.py
"""AEGIS Cryptographic Primitives - Post-Quantum Ready."""

# GAP-Q1: Signatures
from .pqc import generate_ml_dsa_keypair, ml_dsa_sign, ml_dsa_verify
from .hybrid import HybridSignatureProvider, HybridSignature

# GAP-Q2: Encryption
from .kem import generate_ml_kem_keypair, ml_kem_encapsulate, ml_kem_decapsulate
from .hybrid_kem import HybridKEMProvider, HybridEncryptedBlob

__all__ = [
    # Signatures (GAP-Q1)
    "generate_ml_dsa_keypair",
    "ml_dsa_sign",
    "ml_dsa_verify",
    "HybridSignatureProvider",
    "HybridSignature",
    # Encryption (GAP-Q2)
    "generate_ml_kem_keypair",
    "ml_kem_encapsulate",
    "ml_kem_decapsulate",
    "HybridKEMProvider",
    "HybridEncryptedBlob",
]

11. References

Standards

Libraries

Research


Changelog

Version Date Author Changes
1.0.0 2025-12-27 Claude Code Initial implementation plan