Skip to content

FUTURE_PROPOSALS

github-actions[bot] edited this page Oct 17, 2025 · 1 revision

Future Enhancement Proposals (Phase 3+)

Document Type: Feature Proposals & Roadmap
Status: 📋 Proposed - Awaiting Review & Implementation
Target: Phase 3 and beyond


Overview

This document outlines proposed enhancements for painlessMesh beyond the completed Phase 1 (v1.6.x) and Phase 2 (v1.7.0) implementations. These features represent the next evolution of OTA distribution and status monitoring capabilities.

Completed Features: See OTA_STATUS_ENHANCEMENTS.md for implemented options
Implementation Details: See IMPLEMENTATION_HISTORY.md for Phase 1-2 technical details


Table of Contents


Phase 3 Overview

Goal: Advanced features for enterprise and large-scale deployments

Key Themes:

  1. Production Safety - Zero-downtime updates with automatic rollback
  2. Massive Scale - Support for 100+ node meshes
  3. Real-time Monitoring - Sub-second telemetry and proactive alerting
  4. User Experience - Web-based dashboards and management interfaces

Prerequisites:

  • ✅ Phase 1 complete (v1.6.x)
  • ✅ Phase 2 complete (v1.7.0)
  • ✅ Stable mesh infrastructure
  • ✅ Testing framework established

OTA Enhancement Proposals

Option 1B: Progressive Rollout OTA

Status: 📋 Proposed
Priority: ⭐⭐⭐⭐⭐ High
Complexity: ⭐⭐⭐⭐ High
Timeline: 3-4 months

Description

Deploy firmware in controlled waves (canary → early adopters → all) with health monitoring between phases and automatic rollback on failures.

Key Features

1. Phased Rollout Strategy:

  • Wave 1 (Canary): 5% of nodes - Test on small subset
  • Wave 2 (Early Adopters): 20% of nodes - Expand if Wave 1 succeeds
  • Wave 3 (General Availability): 75% of nodes - Majority deployment
  • Wave 4 (Laggards): 100% of nodes - Complete rollout

2. Health Monitoring:

  • Track node uptime after update
  • Monitor memory usage, reboot loops, error rates
  • Compare health metrics pre/post update
  • Configurable health thresholds

3. Automatic Rollback:

  • Trigger rollback if health check fails
  • Revert to previous firmware version
  • Preserve critical node functionality
  • Alert administrators of failures

4. Manual Controls:

  • Pause rollout between waves
  • Skip waves for emergency deployments
  • Manually approve wave progression
  • Emergency rollback button

Architecture

class ProgressiveOTA {
private:
    painlessMesh& mesh;
    std::vector<float> wavePercentages;  // e.g., {0.05, 0.20, 0.75, 1.0}
    std::function<bool(uint32_t nodeId)> healthCheck;
    uint32_t currentWave = 0;
    std::set<uint32_t> updatedNodes;
    std::set<uint32_t> failedNodes;
    
public:
    ProgressiveOTA(painlessMesh& mesh) : mesh(mesh) {
        wavePercentages = {0.05, 0.20, 0.75, 1.0};  // Default waves
    }
    
    void setPhases(std::vector<float> phases) { wavePercentages = phases; }
    void setHealthCheck(std::function<bool(uint32_t)> check) { healthCheck = check; }
    
    void begin(TSTRING role, TSTRING hardware, TSTRING md5) {
        // Start Wave 1 (canary)
        deployWave(0, role, hardware, md5);
    }
    
    void deployWave(uint32_t wave, TSTRING role, TSTRING hardware, TSTRING md5) {
        auto nodes = mesh.getNodeList();
        size_t targetCount = nodes.size() * wavePercentages[wave];
        
        // Select nodes for this wave
        std::vector<uint32_t> waveNodes = selectNodesForWave(nodes, targetCount);
        
        // Deploy to selected nodes
        for (auto nodeId : waveNodes) {
            mesh.sendSingle(nodeId, createOTAAnnounce(role, hardware, md5));
        }
        
        // Schedule health check
        scheduleHealthCheck(wave, waveNodes);
    }
    
    void scheduleHealthCheck(uint32_t wave, std::vector<uint32_t> nodes) {
        mesh.addTask(
            TASK_MINUTE * 5,  // Wait 5 minutes after deployment
            TASK_ONCE,
            [this, wave, nodes]() {
                bool allHealthy = true;
                for (auto nodeId : nodes) {
                    if (!healthCheck(nodeId)) {
                        failedNodes.insert(nodeId);
                        allHealthy = false;
                    }
                }
                
                if (allHealthy && wave < wavePercentages.size() - 1) {
                    // Proceed to next wave
                    deployWave(wave + 1, role, hardware, md5);
                } else if (!allHealthy) {
                    // Rollback entire deployment
                    rollbackDeployment();
                }
            }
        );
    }
    
    void rollbackDeployment() {
        // Trigger rollback to previous firmware
        for (auto nodeId : updatedNodes) {
            mesh.sendSingle(nodeId, createRollbackCommand());
        }
        
        Log(ERROR, "Progressive OTA rollback triggered!\n");
    }
};

Usage Example

ProgressiveOTA ota(mesh);

// Configure waves (5%, 20%, 100%)
ota.setPhases({0.05, 0.20, 1.0});

// Define health check
ota.setHealthCheck([&](uint32_t nodeId) -> bool {
    // Check if node is responding
    if (!mesh.isConnected(nodeId)) return false;
    
    // Check node hasn't rebooted multiple times
    if (getRebootCount(nodeId) > 2) return false;
    
    // Check memory is healthy
    if (getFreeMemory(nodeId) < 10000) return false;
    
    return true;
});

// Start progressive rollout
ota.begin("sensor", "ESP32", firmwareMD5);

// Manually approve next wave (optional)
// ota.approveNextWave();

// Emergency rollback (optional)
// ota.rollbackAll();

Benefits

  • Zero-downtime updates - Never update all nodes simultaneously
  • Early failure detection - Catch issues before mesh-wide deployment
  • Automatic rollback - Minimize impact of bad firmware
  • Production-safe - Tested approach used by major platforms

Challenges

  • Complexity - Requires state management, health monitoring
  • Time - Slower updates (hours vs minutes)
  • Node selection - How to choose canary nodes?
  • Rollback mechanism - Requires dual-boot or firmware storage

Target Use Cases

  • Critical infrastructure requiring high availability
  • Production deployments with zero-downtime requirements
  • Organizations with risk-averse policies
  • Meshes with diverse hardware/configurations

Option 1C: Peer-to-Peer Distribution

Status: 📋 Proposed
Priority: ⭐⭐⭐ Medium
Complexity: ⭐⭐⭐⭐⭐ Very High
Timeline: 4-6 months

Description

Viral propagation where updated nodes become distribution sources, enabling exponential scaling for very large meshes (100+ nodes).

Key Features

1. Viral Propagation:

  • Updated nodes store firmware in flash
  • Updated nodes become OTA senders
  • Exponential distribution speed: 1→2→4→8→16...
  • Reduces load on original sender

2. Firmware Storage:

  • Requires +200-500KB flash per node
  • ESP32 preferred (larger flash capacity)
  • ESP8266 possible with external flash
  • Automatic cleanup after mesh-wide update

3. Smart Routing:

  • Nodes prefer downloading from nearest neighbor
  • Load balancing across multiple sources
  • Avoids redundant transmissions
  • Network topology awareness

4. Chunk Coordination:

  • Nodes track which chunks they have
  • Request missing chunks from any source
  • Parallel chunk downloads
  • BitTorrent-like swarm behavior

Architecture

class P2POTA {
private:
    painlessMesh& mesh;
    bool isSeedNode = false;
    bool hasCompleteFirmware = false;
    std::vector<bool> chunkBitmap;     // Track which chunks we have
    std::set<uint32_t> activeSources;   // Nodes offering firmware
    
public:
    void handleOTAAnnounce(const OTAAnnounce& announce) {
        if (hasMatchingFirmware(announce.md5)) {
            // We already have this firmware, become a source
            isSeedNode = true;
            advertiseFirmware(announce);
        } else {
            // We need this firmware, start downloading
            findSources(announce);
            startDownload(announce);
        }
    }
    
    void findSources(const OTAAnnounce& announce) {
        // Query neighbors for firmware availability
        auto neighbors = mesh.getNodeList();
        for (auto nodeId : neighbors) {
            sendSourceQuery(nodeId, announce.md5);
        }
    }
    
    void handleSourceAdvertisement(uint32_t sourceId, TSTRING md5) {
        activeSources.insert(sourceId);
        
        // Prefer nearby sources (lower hop count)
        if (getHopCount(sourceId) < 3) {
            // Download from this source
            requestChunksFrom(sourceId);
        }
    }
    
    void requestChunksFrom(uint32_t sourceId) {
        // Find missing chunks
        for (size_t i = 0; i < chunkBitmap.size(); i++) {
            if (!chunkBitmap[i]) {
                sendChunkRequest(sourceId, i);
                break;  // One at a time to avoid congestion
            }
        }
    }
    
    void handleChunkReceived(uint32_t chunkId, TSTRING data) {
        // Store chunk
        writeChunkToFlash(chunkId, data);
        chunkBitmap[chunkId] = true;
        
        // Check if we have all chunks
        if (std::all_of(chunkBitmap.begin(), chunkBitmap.end(), [](bool b) { return b; })) {
            hasCompleteFirmware = true;
            isSeedNode = true;  // We can now serve others
            
            // Reboot into new firmware after serving others for a bit
            scheduleReboot();
        } else {
            // Request next missing chunk
            requestNextChunk();
        }
    }
};

Performance Analysis

Update Speed (150 chunks, 10KB/chunk = 1.5MB firmware):

Mesh Size Unicast Broadcast P2P P2P Speedup
10 nodes 60s 20s 30s Similar to broadcast
50 nodes 300s 30s 40s 1.3x faster
100 nodes 600s 40s 50s 12x faster
500 nodes 3000s 60s 70s 40x faster

Why P2P is faster at scale:

  • Broadcast limited by single sender's bandwidth
  • P2P leverages multiple senders simultaneously
  • Exponential growth: Each updated node helps others

Challenges

1. Memory Requirements:

  • ESP8266: ~80KB RAM, ~1-4MB flash - Challenging
  • ESP32: ~320KB RAM, ~4-16MB flash - Feasible

2. Complexity:

  • Chunk coordination across many nodes
  • Preventing transmission loops
  • Handling partial updates
  • Flash wear concerns

3. Network Congestion:

  • Many simultaneous transmissions
  • Need traffic shaping/throttling
  • QoS considerations

4. Security:

  • Firmware integrity verification
  • Preventing malicious nodes from distributing bad firmware
  • MD5 alone may not be sufficient

Target Use Cases

  • Very large deployments (100+ nodes)
  • ESP32-based meshes with sufficient flash
  • Scenarios where update speed is critical
  • Meshes with good interconnectivity

Option 1D: MQTT-Integrated OTA

Status: 📋 Proposed
Priority: ⭐⭐⭐ Medium
Complexity: ⭐⭐⭐ Medium
Timeline: 2-3 months

Description

Standardized MQTT interface for triggering and managing OTA operations, enabling cloud-based firmware management and integration with external OTA tools.

Key Features

1. MQTT Command Interface:

  • Trigger OTA via MQTT publish
  • Query OTA status via MQTT
  • Cancel/pause OTA operations
  • Rollback commands

2. Cloud Integration:

  • Store firmware in cloud storage (S3, Azure Blob)
  • Trigger updates from cloud dashboard
  • Track update progress in real-time
  • Integration with CI/CD pipelines

3. Firmware Distribution:

  • Download firmware from URL
  • Stream firmware chunks over MQTT
  • Cache firmware locally
  • Automatic cleanup

4. OTA Lifecycle Management:

  • Schedule updates (e.g., 2 AM on weekends)
  • Maintenance windows
  • Update approvals/gate keeping
  • Audit logging

Architecture

class MqttOTA {
private:
    painlessMesh& mesh;
    PubSubClient& mqttClient;
    String commandTopic = "mesh/ota/command";
    String statusTopic = "mesh/ota/status";
    
public:
    void begin() {
        mqttClient.subscribe(commandTopic.c_str());
        mqttClient.setCallback([this](char* topic, byte* payload, unsigned int length) {
            handleMqttMessage(topic, payload, length);
        });
    }
    
    void handleMqttMessage(char* topic, byte* payload, unsigned int length) {
        DynamicJsonDocument doc(1024);
        deserializeJson(doc, payload, length);
        
        String command = doc["command"];
        
        if (command == "start_ota") {
            startOTA(doc);
        } else if (command == "cancel_ota") {
            cancelOTA();
        } else if (command == "query_status") {
            publishStatus();
        } else if (command == "rollback") {
            rollbackFirmware();
        }
    }
    
    void startOTA(JsonDocument& doc) {
        String role = doc["role"];
        String hardware = doc["hardware"];
        String md5 = doc["md5"];
        String firmwareUrl = doc["url"];
        
        // Download firmware from URL
        downloadFirmware(firmwareUrl, [&](bool success) {
            if (success) {
                // Start OTA distribution
                mesh.offerOTA(role, hardware, md5, getChunkCount(), false, true, true);
                
                // Publish status
                publishStatus("started", 0);
            } else {
                publishStatus("failed", 0);
            }
        });
    }
    
    void publishStatus(String status, uint8_t progress) {
        DynamicJsonDocument doc(512);
        doc["status"] = status;
        doc["progress"] = progress;
        doc["timestamp"] = millis();
        doc["updated_nodes"] = getUpdatedNodeCount();
        doc["total_nodes"] = mesh.getNodeList().size();
        
        String payload;
        serializeJson(doc, payload);
        
        mqttClient.publish(statusTopic.c_str(), payload.c_str());
    }
};

MQTT Topics

Commands (Subscribe):

mesh/ota/command

Command Format:

{
  "command": "start_ota",
  "role": "sensor",
  "hardware": "ESP32",
  "md5": "abc123...",
  "url": "https://storage.example.com/firmware/sensor-v2.0.bin",
  "options": {
    "broadcast": true,
    "compressed": true,
    "progressive": false
  }
}

Status (Publish):

mesh/ota/status

Status Format:

{
  "status": "in_progress",
  "progress": 45,
  "timestamp": 1234567890,
  "updated_nodes": 15,
  "total_nodes": 50,
  "estimated_completion": 120
}

Benefits

  • Cloud-based OTA management
  • Integration with existing MQTT infrastructure
  • Automated CI/CD pipeline integration
  • Centralized logging and monitoring

Target Use Cases

  • Organizations with MQTT infrastructure
  • Cloud-managed deployments
  • CI/CD integrated workflows
  • Remote management scenarios

Status Monitoring Proposals

Option 2B: Mesh Status Service

Status: 📋 Proposed
Priority: ⭐⭐⭐⭐ Medium-High
Complexity: ⭐⭐⭐ Medium
Timeline: 2-3 months

Description

Query-based status collection with centralized aggregation at root node, providing on-demand mesh-wide status via RESTful API or MQTT.

Key Features

1. Centralized Status Aggregation:

  • Root node collects status from all nodes
  • On-demand vs periodic collection
  • Status caching with TTL
  • Historical data retention (optional)

2. RESTful API:

  • HTTP endpoints on root node
  • JSON response format
  • Query individual or all nodes
  • Filter by node ID, role, health

3. Status Queries:

  • /status - All nodes
  • /status/{nodeId} - Specific node
  • /health - Health summary
  • /topology - Mesh structure

4. Advanced Filtering:

  • Query by node role
  • Filter by health status
  • Sort by metrics (memory, uptime)
  • Pagination for large meshes

Architecture

class StatusService {
private:
    painlessMesh& mesh;
    AsyncWebServer server(80);
    std::map<uint32_t, NodeStatus> statusCache;
    uint32_t cacheTTL = 60000;  // 60 seconds
    
public:
    void begin() {
        // Set up HTTP endpoints
        server.on("/status", HTTP_GET, [this](AsyncWebServerRequest *request) {
            handleAllStatus(request);
        });
        
        server.on("/status/*", HTTP_GET, [this](AsyncWebServerRequest *request) {
            handleNodeStatus(request);
        });
        
        server.on("/health", HTTP_GET, [this](AsyncWebServerRequest *request) {
            handleHealthSummary(request);
        });
        
        server.begin();
    }
    
    void handleAllStatus(AsyncWebServerRequest *request) {
        // Check cache freshness
        if (isCacheStale()) {
            refreshCache();
        }
        
        // Build JSON response
        DynamicJsonDocument doc(8192);
        JsonArray nodes = doc.createNestedArray("nodes");
        
        for (auto& [nodeId, status] : statusCache) {
            JsonObject node = nodes.createNestedObject();
            node["nodeId"] = nodeId;
            node["uptime"] = status.uptime;
            node["freeMemory"] = status.freeMemory;
            node["health"] = calculateHealth(status);
        }
        
        String response;
        serializeJson(doc, response);
        request->send(200, "application/json", response);
    }
    
    void refreshCache() {
        // Request status from all nodes
        auto nodes = mesh.getNodeList();
        for (auto nodeId : nodes) {
            requestStatus(nodeId);
        }
    }
    
    void requestStatus(uint32_t nodeId) {
        // Send status request message
        StatusRequest req;
        req.to = nodeId;
        mesh.sendPackage(&req);
    }
    
    void handleStatusResponse(const StatusResponse& response) {
        // Update cache
        statusCache[response.from] = {
            .uptime = response.uptime,
            .freeMemory = response.freeMemory,
            .health = response.health,
            .timestamp = millis()
        };
    }
};

Usage Example

Query All Nodes:

curl http://mesh-root.local/status

Response:

{
  "nodes": [
    {
      "nodeId": 123456,
      "uptime": 3600,
      "freeMemory": 45000,
      "health": "healthy",
      "lastSeen": 1234567890
    },
    {
      "nodeId": 789012,
      "uptime": 1800,
      "freeMemory": 38000,
      "health": "warning",
      "lastSeen": 1234567885
    }
  ],
  "timestamp": 1234567890,
  "totalNodes": 2
}

Query Specific Node:

curl http://mesh-root.local/status/123456

Benefits

  • On-demand queries (no periodic overhead)
  • RESTful API familiar to developers
  • Easy integration with dashboards
  • Centralized status management

Target Use Cases

  • Applications needing centralized monitoring
  • Dashboard integrations
  • Health check systems
  • Administrative tools

Option 2C: Telemetry Stream

Status: 📋 Proposed
Priority: ⭐⭐⭐⭐⭐ High
Complexity: ⭐⭐⭐⭐ High
Timeline: 3-4 months

Description

Continuous low-bandwidth telemetry with delta encoding, anomaly detection, and proactive alerting for real-time critical monitoring.

Key Features

1. Delta Encoding:

  • Only transmit changed values
  • 80-90% bandwidth reduction
  • Configurable thresholds
  • Periodic full snapshots

2. Anomaly Detection:

  • Statistical anomaly detection
  • Threshold-based alerting
  • Pattern recognition
  • Predictive alerts

3. Real-time Streaming:

  • Sub-second latency
  • Continuous updates
  • Minimal overhead
  • Buffering for offline nodes

4. Proactive Alerting:

  • Automatic alert generation
  • Alert severity levels
  • Alert aggregation
  • Integration with notification systems

Architecture

class TelemetryStream {
private:
    painlessMesh& mesh;
    std::map<uint32_t, TelemetryState> lastState;
    uint32_t streamInterval = 1000;  // 1 second
    
public:
    void begin() {
        mesh.addTask(
            TASK_MILLISECOND * streamInterval,
            TASK_FOREVER,
            [this]() { collectAndStreamTelemetry(); }
        );
    }
    
    void collectAndStreamTelemetry() {
        TelemetryState current = collectCurrentState();
        
        // Calculate deltas
        TelemetryDelta delta = calculateDelta(lastState[mesh.getNodeId()], current);
        
        // Only transmit if significant changes
        if (delta.hasSignificantChanges()) {
            streamDelta(delta);
        }
        
        // Check for anomalies
        if (detectAnomaly(current)) {
            generateAlert(current);
        }
        
        lastState[mesh.getNodeId()] = current;
    }
    
    TelemetryDelta calculateDelta(const TelemetryState& prev, const TelemetryState& current) {
        TelemetryDelta delta;
        
        // Memory change
        int memoryDiff = (int)current.freeMemory - (int)prev.freeMemory;
        if (abs(memoryDiff) > 1000) {  // 1KB threshold
            delta.memoryDelta = memoryDiff;
        }
        
        // Message rate change
        uint32_t messageRateDiff = current.messageRate - prev.messageRate;
        if (messageRateDiff > 10) {  // 10 msg/s threshold
            delta.messageRateDelta = messageRateDiff;
        }
        
        return delta;
    }
    
    bool detectAnomaly(const TelemetryState& current) {
        // Statistical anomaly detection
        if (current.freeMemory < 10000) return true;  // Low memory
        if (current.messageRate > 1000) return true;  // Message flood
        if (current.rebootCount > 3) return true;     // Reboot loop
        
        return false;
    }
    
    void generateAlert(const TelemetryState& state) {
        Alert alert;
        alert.severity = calculateSeverity(state);
        alert.message = generateAlertMessage(state);
        alert.timestamp = millis();
        
        // Send alert via high-priority channel
        mesh.sendBroadcast(alert.toJson(), true);  // High priority
    }
};

Delta Encoding Example

Full State (200 bytes):

{
  "nodeId": 123456,
  "uptime": 3600,
  "freeMemory": 45000,
  "messageRate": 50,
  "connections": 3,
  ...
}

Delta Update (30 bytes):

{
  "nodeId": 123456,
  "Δmem": -1500,
  "Δrate": +5
}

Bandwidth Savings: 85%

Benefits

  • Real-time monitoring (<1s latency)
  • 80-90% bandwidth reduction via delta encoding
  • Proactive anomaly detection
  • Scalable to 100+ nodes

Target Use Cases

  • Real-time critical monitoring
  • Large-scale deployments
  • Predictive maintenance
  • High-frequency data collection

Option 2D: Health Dashboard

Status: 📋 Proposed
Priority: ⭐⭐⭐ Medium
Complexity: ⭐⭐⭐⭐⭐ Very High
Timeline: 4-6 months

Description

Complete web-based monitoring solution with embedded web server, real-time visualization, interactive topology display, and management interface.

Key Features

1. Web-Based UI:

  • Responsive web interface
  • Real-time updates via WebSockets
  • Interactive topology visualization
  • Mobile-friendly design

2. Visualization:

  • Network topology graph
  • Memory usage charts
  • Message rate graphs
  • Historical trends

3. Management Interface:

  • Trigger OTA updates
  • View/clear alerts
  • Configure settings
  • Node diagnostics

4. Embedded Web Server:

  • Runs on root node
  • Serves static assets
  • WebSocket for real-time data
  • RESTful API backend

Technology Stack

Frontend:

  • HTML5/CSS3/JavaScript
  • Chart.js for graphs
  • D3.js for topology visualization
  • WebSockets for real-time updates

Backend:

  • AsyncWebServer (ESP32)
  • WebSocket protocol
  • JSON REST API
  • SPIFFS for assets

Benefits

  • User-friendly visual interface
  • No external dependencies
  • Runs entirely on mesh
  • Real-time monitoring

Challenges

  • High complexity (full web app)
  • Large assets (~200KB)
  • ESP32 required (ESP8266 insufficient)
  • Performance considerations

Target Use Cases

  • User-facing applications
  • Local network management
  • Visual monitoring needs
  • Educational/demo purposes

Implementation Priority

High Priority (Phase 3 Immediate)

  1. Progressive Rollout OTA (1B) ⭐⭐⭐⭐⭐

    • Production-critical feature
    • High demand from enterprise users
    • Timeline: 3-4 months
  2. Telemetry Stream (2C) ⭐⭐⭐⭐⭐

    • Real-time monitoring need
    • Scalability improvement
    • Timeline: 3-4 months

Medium Priority (Phase 3 Secondary)

  1. Status Service (2B) ⭐⭐⭐⭐

    • Centralized monitoring
    • RESTful API integration
    • Timeline: 2-3 months
  2. MQTT OTA (1D) ⭐⭐⭐

    • Cloud integration
    • CI/CD workflows
    • Timeline: 2-3 months

Lower Priority (Phase 4+)

  1. Peer-to-Peer OTA (1C) ⭐⭐⭐

    • Very large mesh support
    • High complexity
    • Timeline: 4-6 months
  2. Health Dashboard (2D) ⭐⭐⭐

    • Visual monitoring
    • Educational value
    • Timeline: 4-6 months

Timeline Estimates

Phase 3A (Months 1-4)

  • Progressive Rollout OTA (1B)
  • Telemetry Stream (2C)

Phase 3B (Months 5-7)

  • Status Service (2B)
  • MQTT OTA (1D)

Phase 4 (Months 8-12+)

  • Peer-to-Peer OTA (1C)
  • Health Dashboard (2D)

Total Timeline: 12-18 months for all features


Contributing

Interested in implementing these proposals?

  1. Review this document and OTA_STATUS_ENHANCEMENTS.md
  2. Open a GitHub issue to discuss implementation approach
  3. Create design document with detailed specification
  4. Submit proof-of-concept PR for feedback
  5. Implement tests and documentation
  6. Submit final PR for integration

Contact:


Document Version: 1.0
Last Updated: October 2025
Status: Living document - updated as proposals evolve

Clone this wiki locally