Boot — Startup Orchestration

Gateway Initialization Pipeline

The Boot subsystem orchestrates Gateway startup — executing the one-shot bootstrap sequence from BOOT.md, negotiating mobile node capabilities, coordinating health checks, and restoring session state from previous runs.

3
Boot Statuses
1
Boot File
4+
Lifecycle Phases
25+
Context Fields

Initialization TypeScript One-Shot Critical Path

What Is This & Why Does It Exist?

A Gateway that isn’t properly initialized can’t serve traffic safely. The Boot subsystem ensures all dependencies are ready, the workspace is configured, and health monitoring is active before the first client connects.

💡 Real-world analogy

Think of Boot as a spacecraft pre-launch checklist. runBootOnce() is mission control running through every system: fuel (credentials), navigation (routing tables), life support (health checks), and comms (WebSocket bindings). The BOOT.md file is the mission-specific runbook. If any check fails, the launch is scrubbed (BootRunResult.status: "failed") rather than risking a flawed mission.

Table of Contents

Architecture

The Boot subsystem reads workspace configuration, executes the bootstrap file, initializes the GatewayRequestContext, and signals readiness to the health monitor.

flowchart TB
    subgraph Trigger
        FIRST["First Connection / Server Start"]
    end

    subgraph Boot["Boot Orchestrator"]
        READ["Read BOOT.md
from workspaceDir"] EXEC["Execute Bootstrap
Instructions"] CTX["Build GatewayRequestContext
25+ fields"] RESTORE["Restore Session State
SessionMappingSnapshot"] end subgraph Health["Health System"] HC["Health Check"] HV["Health Version Counter"] CACHE["Health Summary Cache"] end subgraph Deps["Dependencies"] CRON["CronService"] NODE["NodeRegistry"] BROAD["Broadcast Functions"] LOG["SubsystemLogger"] end FIRST --> READ READ -->|"missing/empty"| SKIP["BootRunResult: skipped"] READ -->|"found"| EXEC EXEC -->|"success"| CTX EXEC -->|"error"| FAIL["BootRunResult: failed"] CTX --> RESTORE CTX --> HC HC --> HV HC --> CACHE CTX --> CRON CTX --> NODE CTX --> BROAD CTX --> LOG

Data Flow

sequenceDiagram
    participant Server as Gateway Server
    participant Boot as runBootOnce()
    participant FS as Filesystem
    participant Agent as Agent Runtime
    participant Health as Health Monitor
    participant Ctx as GatewayRequestContext

    Server->>Boot: runBootOnce(cfg, deps, workspaceDir)
    Boot->>FS: readFile(workspaceDir + "/BOOT.md")
    alt file missing or empty
        FS-->>Boot: null / empty
        Boot-->>Server: {status: "skipped", reason: "missing"|"empty"}
    else file found
        FS-->>Boot: BOOT.md contents
        Boot->>Agent: execute bootstrap instructions
        Agent-->>Boot: execution complete
        Boot->>Ctx: build GatewayRequestContext
        Ctx->>Health: initializeHealthCache()
        Health-->>Ctx: HealthSummary
        Boot-->>Server: {status: "ran"}
    end
    Note over Server: Gateway now ready for connections

Key Types & Functions

NameFileDescription
BootRunResultboot.tsUnion: {status:"ran"} | {status:"skipped", reason} | {status:"failed", reason}
runBootOnce()boot.tsMain entry: executes BOOT.md, returns BootRunResult
BOOT_FILENAMEboot.tsConstant: "BOOT.md"
GatewayRequestContextserver-methods/types.ts25+ field context: deps, cron, broadcast, nodeRegistry, etc.
GatewayWsClientserver/ws-types.tsWebSocket client: socket, connect, connId, presenceKey
SessionMappingSnapshotboot.ts (internal)Session restore snapshot for state recovery
LifecyclePhasesession-lifecycle-state.tsPhase: "start" | "end" | "error"
HealthSummary(health module)Cached health status returned by getHealthCache()
NodeRegistry(node module)Registry of connected mobile/desktop nodes
CronService(cron module)Scheduled task service for periodic operations

GatewayRequestContext Fields

FieldTypePurpose
depsReturnType<typeof createDefaultDeps>Shared dependency injection container
cronCronServiceScheduled task manager
cronStorePathstringPersistent storage path for cron state
execApprovalManagerExecApprovalManagerTool execution approval workflow
pluginApprovalManagerExecApprovalManager<...>Plugin approval workflow
loadGatewayModelCatalog() => Promise<ModelCatalogEntry[]>Lazy model catalog loader
getHealthCache() => HealthSummary | nullCached health summary accessor
broadcastGatewayBroadcastFnBroadcast events to all connected clients
broadcastToConnIdsGatewayBroadcastToConnIdsFnTargeted broadcast to specific connections
nodeRegistryNodeRegistryMobile/desktop node capability registry
chatAbortControllersMap<string, ChatAbortControllerEntry>Active chat abort controllers
incrementPresenceVersion() => numberPresence version counter for change tracking

Code Examples

Running the Boot Sequence

import { runBootOnce, BootRunResult } from './boot';

const result: BootRunResult = await runBootOnce({
  cfg: openClawConfig,
  deps: createDefaultDeps(),
  workspaceDir: '/home/user/.openclaw',
  agentId: 'main',
});

switch (result.status) {
  case 'ran':
    console.log('Boot completed successfully');
    break;
  case 'skipped':
    console.log(`Boot skipped: ${result.reason}`);
    break;
  case 'failed':
    console.error(`Boot failed: ${result.reason}`);
    process.exit(1);
}

Building Request Context

const context: GatewayRequestContext = {
  deps: createDefaultDeps(),
  cron: new CronService(),
  cronStorePath: path.join(workspaceDir, '.cron-state'),
  loadGatewayModelCatalog: async () => loadModelCatalog(cfg),
  getHealthCache: () => healthSummaryCache,
  logHealth: { error: (msg) => logger.error('health', msg) },
  logGateway: createSubsystemLogger('gateway'),
  incrementPresenceVersion: () => ++presenceVersion,
  getHealthVersion: () => healthVersion,
  broadcast: (event) => wsClients.forEach(c => c.socket.send(event)),
  broadcastToConnIds: (ids, event) => { /* targeted send */ },
  nodeRegistry: new NodeRegistry(),
  chatAbortControllers: new Map(),
  // ... 10+ more fields
};

Configuration

ParameterTypeDefaultDescription
boot.filenamestring"BOOT.md"Bootstrap instruction file name
workspaceDirstring~/.openclawWorkspace root directory
cronStorePathstring.cron-stateCron persistent state path
healthCheckIntervalnumber30000Health check polling interval (ms)

Deep-Dive Focus Pages

▶ Startup Sequence Focus

Step-by-step walkthrough of the Gateway startup sequence from process launch to ready state.

📱 Capability Negotiation Focus

How Android/iOS nodes register capabilities and how the Gateway negotiates feature sets.

💚 Health Checks Focus

Health monitoring, version tracking, and the HealthSummary cache system.

Directory Map

Source files for Boot
src/gateway/
├── boot.ts                        ← runBootOnce, BootRunResult, BOOT_FILENAME
├── server/
│   └── ws-types.ts                ← GatewayWsClient (WebSocket client type)
├── server-methods/
│   └── types.ts                   ← GatewayRequestContext (25+ fields)
├── session-lifecycle-state.ts     ← LifecyclePhase, persistGatewaySessionLifecycleEvent
└── protocol/
    └── index.ts                   ← ConnectParams, HelloOk, PROTOCOL_VERSION