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.
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
| Name | File | Description |
|---|---|---|
BootRunResult | boot.ts | Union: {status:"ran"} | {status:"skipped", reason} | {status:"failed", reason} |
runBootOnce() | boot.ts | Main entry: executes BOOT.md, returns BootRunResult |
BOOT_FILENAME | boot.ts | Constant: "BOOT.md" |
GatewayRequestContext | server-methods/types.ts | 25+ field context: deps, cron, broadcast, nodeRegistry, etc. |
GatewayWsClient | server/ws-types.ts | WebSocket client: socket, connect, connId, presenceKey |
SessionMappingSnapshot | boot.ts (internal) | Session restore snapshot for state recovery |
LifecyclePhase | session-lifecycle-state.ts | Phase: "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
| Field | Type | Purpose |
|---|---|---|
deps | ReturnType<typeof createDefaultDeps> | Shared dependency injection container |
cron | CronService | Scheduled task manager |
cronStorePath | string | Persistent storage path for cron state |
execApprovalManager | ExecApprovalManager | Tool execution approval workflow |
pluginApprovalManager | ExecApprovalManager<...> | Plugin approval workflow |
loadGatewayModelCatalog | () => Promise<ModelCatalogEntry[]> | Lazy model catalog loader |
getHealthCache | () => HealthSummary | null | Cached health summary accessor |
broadcast | GatewayBroadcastFn | Broadcast events to all connected clients |
broadcastToConnIds | GatewayBroadcastToConnIdsFn | Targeted broadcast to specific connections |
nodeRegistry | NodeRegistry | Mobile/desktop node capability registry |
chatAbortControllers | Map<string, ChatAbortControllerEntry> | Active chat abort controllers |
incrementPresenceVersion | () => number | Presence 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
| Parameter | Type | Default | Description |
|---|---|---|---|
boot.filename | string | "BOOT.md" | Bootstrap instruction file name |
workspaceDir | string | ~/.openclaw | Workspace root directory |
cronStorePath | string | .cron-state | Cron persistent state path |
healthCheckInterval | number | 30000 | Health 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