OpenWork Runtime Feasibility on Linux Host (Railway-first) — PLT-1071

Date: 2026-03-07
Author: Cursor agent session
Issue: PLT-1071
Project: OpenWork Platform Integration

Summary Recommendation

Use downloaded sidecars for the first hosted Labs release shape (labs.brainforge.ai) and treat bundled + external as non-viable defaults.

However, do not green-light a user-facing Labs rollout yet: OpenWork host health checks pass, but OpenCode proxy paths needed for session creation + SSE currently return 500 in this environment. That is a release blocker.

Environment + Method

Validation was run in a Linux container/VM context using the published openwork CLI:

  • Node v22.22.1
  • openwork-orchestrator 0.11.135
  • Workspace path: /tmp/openwork-smoke-workspace
  • Runtime shape: openwork serve / openwork start --check --check-events

Smoke scope executed:

  1. Host health endpoint
  2. Workspace discovery and config read/write
  3. OpenCode session create proxy
  4. OpenCode SSE proxy
  5. Sidecar strategy matrix (downloaded, bundled, external)

Sidecar Strategy Matrix

StrategyResultEvidence
downloadedPass (orchestrator checks)Checks: ok, resolved binaries in sidecar cache (.../opencode/1.2.20/..., .../0.11.135/...)
bundledFailBundled opencode binary missing. Build with pnpm --filter openwork-orchestrator build:bin:bundled.
externalFailopencode / openwork-server external bins not present; run exits with Run failed even with --allow-external

Interpretation:

  • downloaded is the only viable default strategy for Railway-style Linux feasibility right now.
  • bundled requires a custom build/publish pipeline for matching Linux binaries.
  • external requires pre-installed binaries on the host image (not true by default in Railway-like PaaS).

Hosted Runtime Smoke Checklist (Pass/Fail)

Run shape: openwork serve ... --sidecar-source downloaded --opencode-source downloaded

CheckStatusNotes
GET /health✅ Pass (200)OpenWork host reports healthy
GET /workspaces✅ Pass (200)Workspace enumerated
GET /workspace/:id/config✅ Pass (200)Workspace config readable
PATCH /workspace/:id/config✅ Pass (200)Writes persisted to .opencode/openwork.json
GET /w/:id/opencode/health❌ Fail (500)Proxy path returns internal_error
POST /w/:id/opencode/session❌ Fail (500)Session creation via proxy fails
GET /w/:id/opencode/event (SSE)❌ Fail (500)SSE proxy fails before stream starts

Captured status matrix:

{
  "workspace_id": "ws_454240741b7c",
  "statuses": {
    "health": 200,
    "workspaces": 200,
    "workspace_config_get": 200,
    "opencode_health_proxy": 500,
    "session_create_proxy": 500,
    "sse_event_proxy": 500,
    "workspace_config_patch": 200
  }
}

OpenWork server request logs during the same run show:

  • GET /opencode/health 500 ... (opencode)
  • POST /w/ws_.../opencode/session 500 ... (opencode)
  • GET /w/ws_.../opencode/event 500 ... (opencode)

Storage + Volume Findings

OPENWORK_DATA_DIR and OPENWORK_SIDECAR_DIR are actively used and should be mounted for hosted stability:

  • Data dir created audit + opencode config state (example: audit/ws_...jsonl)
  • Sidecar dir caches versioned binaries (example: opencode/1.2.20, 0.11.135/linux-x64)

Cold/warm check timing (same workspace + same cache):

  • Cold run: ~4958 ms
  • Warm run: ~2868 ms

This supports mounting a persistent sidecar cache volume to reduce repeated startup/download overhead.

Blockers for labs.brainforge.ai

  1. Functional blocker: OpenCode proxy routes used by session + SSE return 500 in hosted runtime validation.
  2. Packaging blocker (fixed in repo): Docker packaging previously pinned openwork-orchestrator@0.11.22, which is no longer available on npm.
  3. Ops blocker: Railway CLI is not available in this VM, so direct Railway deploy verification requires a follow-on run in a Railway-configured environment.

For Phase 1 Labs feasibility rollout:

  • Keep runtime isolated from Platform (separate service/domain).
  • Use:
    • OPENWORK_SIDECAR_SOURCE=downloaded
    • OPENWORK_OPENCODE_SOURCE=downloaded
    • pinned orchestrator version 0.11.135 (or a newer explicitly tested version)
  • Mount persistent volumes:
    • /data for orchestrator state + sidecar cache
    • /workspace (or equivalent cloned workspace strategy)
  • Add startup smoke gate in deploy pipeline:
    • openwork start --check --check-events ...
    • plus explicit API checks for /opencode/health, session create, SSE (currently failing)

Follow-on Work Required

  1. Reproduce and fix OpenCode proxy 500 behavior in the deployed sidecar combination.
  2. Re-run the full smoke checklist in actual Railway environment after fix.
  3. Only then mark Labs runtime as go for internal users.