Skip to content

Fix retained Windows cold-start readiness - #54

Merged
gitcommit90 merged 1 commit into
mainfrom
fix/windows-cold-start-ready
Aug 2, 2026
Merged

Fix retained Windows cold-start readiness#54
gitcommit90 merged 1 commit into
mainfrom
fix/windows-cold-start-ready

Conversation

@gitcommit90

@gitcommit90 gitcommit90 commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • prevent retained OCI workspace maintenance from synchronously waking WSL before the HTTP control plane listens
  • keep provisioning, Files/Cowork access, Terminal, and fleet reconciliation authoritative for runtime storage readiness
  • allow a bounded three-minute Windows cold-runtime startup window while preserving the 30-second budget elsewhere
  • cut synchronized desktop version 0.0.36

Acceptance ledger

  1. A retained Windows installation can cold boot with WSL stopped and expose its local 1Helm HTTP control plane without first blocking on retained OCI directory maintenance.
  2. Windows desktop startup permits a bounded cold-WSL readiness window; other platforms retain their existing budget.
  3. Channel runtime storage remains initialized and verified by the operations that actually need it.

Verification

  • npm run typecheck
  • npm run build
  • npm run test:onboarding-browser (20 passed)
  • npm test (native-world 127 passed; complete Node suite 117 tests, 115 passed + 2 expected Chrome-unavailable skips)
  • git diff --check

Summary by CodeRabbit

  • Bug Fixes

    • Improved cold-start reliability on Windows WSL environments.
    • Deferred workspace storage setup until required, reducing startup delays.
    • Extended Windows server readiness time to three minutes while retaining the 30-second limit on other platforms.
  • Updates

    • Updated the default channel machine image to version 0.0.36.
    • Updated release documentation and version metadata.

Signed-off-by: Joseph Yaksich <gitcommit90@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The release updates cold-start behavior for retained channel workspaces, extends Windows server readiness to three minutes, and changes channel-machine image references and package metadata to version 0.0.36.

Changes

Cold-start behavior and release updates

Layer / File(s) Summary
Lazy runtime workspace initialization
src/server/agents.ts, src/server/index.ts, test/autonomy-platform.mjs
ensureChannelWorkspace can skip runtime storage initialization. Startup uses this mode for retained channel workspaces, with regression coverage for workspace metadata creation.
Platform-specific server readiness
desktop/main.cjs, test/desktop.mjs, CHANGELOG.md
Windows uses a three-minute server readiness timeout. Other platforms retain the 30-second timeout.
0.0.36 release and image references
package.json, README.md, src/server/channel-computers.ts, src/server/db.ts, test/channel-computers.mjs, CHANGELOG.md
Package metadata, image defaults, documentation, migration defaults, tests, and release comparison links now reference 0.0.36.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • gitcommit90/1Helm#40: Shares the OCI migration and channel workspace initialization areas extended by this change.
  • gitcommit90/1Helm#33: Shares channel workspace initialization and Windows startup readiness handling.
  • gitcommit90/1Helm#41: Shares channel-machine image version updates across runtime, documentation, database, and tests.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: fixing retained Windows cold-start readiness.
Description check ✅ Passed The description covers the outcome, acceptance items, release version, and verification evidence, although some template checkboxes and headings are omitted.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/windows-cold-start-ready

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/server/index.ts`:
- Around line 2290-2295: Move the startChannelComputerReconciler() invocation to
execute only after server.listen() has successfully opened the HTTP listener.
Keep the existing channel workspace initialization unchanged, and ensure no
reconciler timer or OCI inspection can run before the listener is ready.

In `@test/autonomy-platform.mjs`:
- Around line 203-212: Update the regression test around ensureChannelWorkspace
to insert channel_computers metadata for the channel with backend='oci',
ensuring the OCI path is selected regardless of host platform. Replace
assert.doesNotThrow with an assertion that runtime storage remains untouched
after calling ensureChannelWorkspace(channelId, { initializeRuntimeStorage:
false }), while preserving the existing workspace root_ref assertion.

In `@test/desktop.mjs`:
- Line 122: Extend the assertions in test/desktop.mjs to verify that
waitForServer uses SERVER_READY_TIMEOUT_MS as its default timeout, not merely
that the constant is declared. Assert the waitForServer default parameter or
cover equivalent delayed-response behavior while preserving the existing
platform-specific timeout check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3deb8fcc-1ca2-49a4-83c9-b9ce099e16e8

📥 Commits

Reviewing files that changed from the base of the PR and between 1a228b6 and 3c0bf51.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • CHANGELOG.md
  • README.md
  • desktop/main.cjs
  • package.json
  • src/server/agents.ts
  • src/server/channel-computers.ts
  • src/server/db.ts
  • src/server/index.ts
  • test/autonomy-platform.mjs
  • test/channel-computers.mjs
  • test/desktop.mjs

Comment thread src/server/index.ts
Comment on lines +2290 to +2295
// Retained OCI storage is already authoritative. In particular, a cold
// Windows login can take minutes to wake WSL, and that maintenance must
// never hold the HTTP control plane behind a synchronous startup probe.
// Provisioning, Files/Cowork access, Terminal, and the fleet reconciler
// initialize or verify runtime directories when they actually need them.
ensureChannelWorkspace(Number(channel.id), { initializeRuntimeStorage: false });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 12 \
  '\b(startChannelComputerReconciler|ensureOciChannelWorkspaceDirs|ensureChannelWorkspace|spawnSync)\b' \
  src/server

Repository: gitcommit90/1Helm

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- server startup ---'
sed -n '2265,2325p' src/server/index.ts

printf '%s\n' '--- reconciler symbols and call sites ---'
rg -n -C 18 \
  'export function startChannelComputerReconciler|function startChannelComputerReconciler|startChannelComputerReconciler\(|ensureOciChannelWorkspaceDirs|function ensureOciChannelWorkspaceDirs|export function ensureOciChannelWorkspaceDirs' \
  src/server/channel-computers.ts src/server/index.ts src/server/agents.ts

printf '%s\n' '--- related runtime-storage calls in the reconciler module ---'
rg -n -C 8 \
  'wake|initialize|runtime|workspace|spawnSync|spawn\(|exec|ensure.*Dirs|reconcil' \
  src/server/channel-computers.ts

Repository: gitcommit90/1Helm

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- reconciler execution path ---'
sed -n '730,835p' src/server/channel-computers.ts
sed -n '1420,1588p' src/server/channel-computers.ts

printf '%s\n' '--- connector awaited before listen ---'
rg -n -C 24 \
  'function startPhotonConnector|export function startPhotonConnector|export async function startPhotonConnector|startPhotonConnector\(' \
  src/server

printf '%s\n' '--- exact startup ordering ---'
python3 - <<'PY'
from pathlib import Path
p = Path("src/server/index.ts").read_text()
for needle in ("startChannelComputerReconciler();", "server.listen(", "await startPhotonConnector()"):
    print(needle, p.find(needle))
PY

Repository: gitcommit90/1Helm

Length of output: 33142


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

index = Path("src/server/index.ts").read_text()
computers = Path("src/server/channel-computers.ts").read_text()

startup = index[index.index("startChannelComputerReconciler();"):index.index("server.listen(", index.index("startChannelComputerReconciler();"))]
reconciler = computers[computers.index("async function reconcileOne"):computers.index("export async function reconcileChannelComputers")]
helper = computers[computers.index("function ensureWindowsOciHelperInstalled"):computers.index("/**\n * Create OCI channel workspace dirs")]

checks = {
    "reconciler starts before listener": index.index("startChannelComputerReconciler();") < index.index("server.listen("),
    "listener is after awaited Photon startup": index.index("await startPhotonConnector()") < index.index("server.listen("),
    "first tick uses a delayed timer": "setTimeout(() => { reconcileStartupTimer = null; tick(); }, INITIAL_RECONCILE_MS)" in computers,
    "reconcileOne inspects isolated computer before later provisioning": "inspection = await inspectIsolated(computer)" in reconciler and reconciler.index("inspection = await inspectIsolated(computer)") < reconciler.index("await provisionChannelComputer"),
    "Windows helper installation uses synchronous WSL execution": "spawnSync(wsl, [\"--distribution\", runtime" in helper,
}
for name, value in checks.items():
    print(f"{name}: {value}")

print("startup sequence:")
for token in ("startChannelComputerReconciler();", "await startPhotonConnector()", "server.listen("):
    print(f"  {token}: {index.index(token)}")
PY

Repository: gitcommit90/1Helm

Length of output: 543


Start the reconciler after server.listen()

If Photon startup takes more than two seconds, the reconciler's initial timer can fire before the listener opens. Its OCI inspection can synchronously invoke the Windows WSL helper and wake WSL. Move startChannelComputerReconciler() after server.listen() to preserve cold-start readiness.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server/index.ts` around lines 2290 - 2295, Move the
startChannelComputerReconciler() invocation to execute only after
server.listen() has successfully opened the HTTP listener. Keep the existing
channel workspace initialization unchanged, and ensure no reconciler timer or
OCI inspection can run before the listener is ready.

Comment on lines +203 to +212
test("retained OCI channel metadata can initialize without synchronously touching runtime storage", () => {
seed();
const channelId = run("INSERT INTO channels (name,slug,kind,topic,purpose,status,created) VALUES ('retained-cold-start','retained-cold-start','channel','','','active',?)", now()).lastInsertRowid;
const botId = run("INSERT INTO bots (name,model,prompt,created) VALUES ('retained-cold-agent','mock','Resident.',?)", now()).lastInsertRowid;
const agentId = run("INSERT INTO agents (bot_id,kind,name,status,created) VALUES (?,'channel','retained-cold-agent','ready',?)", botId, now()).lastInsertRowid;
run("INSERT INTO agent_channels (agent_id,channel_id,bound_at) VALUES (?,?,?)", agentId, channelId, now());
run("INSERT INTO agent_profiles (agent_id,purpose,instructions,updated) VALUES (?,'Cold start','Resident.',?)", agentId, now());
assert.doesNotThrow(() => agents.ensureChannelWorkspace(channelId, { initializeRuntimeStorage: false }));
assert.equal(q1("SELECT root_ref FROM channel_workspaces WHERE channel_id=?", channelId).root_ref, `channels/${channelId}`);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

printf '%s\n' 'Relevant files:'
git ls-files | rg '(^|/)(src/server/agents\.ts|test/autonomy-platform\.mjs)$'
printf '%s\n' 'Relevant symbols and references:'
rg -n -C 8 'ensureChannelWorkspace|channelUsesRuntimeStorage|initializeRuntimeStorage|channel-computer|runtime storage|OCI' src/server/agents.ts test/autonomy-platform.mjs

Repository: gitcommit90/1Helm

Length of output: 35958


🏁 Script executed:

git ls-files | rg '(^|/)(src/server/agents\.ts|test/autonomy-platform\.mjs)$'
rg -n -C 8 'ensureChannelWorkspace|channelUsesRuntimeStorage|initializeRuntimeStorage|channel-computer|runtime storage|OCI' src/server/agents.ts test/autonomy-platform.mjs

Repository: gitcommit90/1Helm

Length of output: 35909


🏁 Script executed:

printf '%s\n' 'Channel storage implementation:'
ast-grep outline src/server/channel-storage.ts
printf '%s\n' 'Channel computer implementation:'
ast-grep outline src/server/channel-computers.ts
printf '%s\n' 'Relevant definitions and schema references:'
rg -n -C 12 'function channelUsesRuntimeStorage|export .*channelUsesRuntimeStorage|channel_computers|runtime_storage|oci|computer' src/server/channel-storage.ts src/server/channel-computers.ts src/server/db.ts test/autonomy-platform.mjs

Repository: gitcommit90/1Helm

Length of output: 50374


🏁 Script executed:

printf '%s\n' 'Storage and initialization logic:'
sed -n '1,90p' src/server/channel-storage.ts
sed -n '200,235p' src/server/channel-computers.ts
sed -n '60,84p' src/server/agents.ts
printf '%s\n' 'Test setup and seed definition:'
rg -n -C 15 'function seed|export function seed|HELM_CHANNEL_COMPUTER_BACKEND|process\.platform|autonomy-platform' src/server/db.ts test/autonomy-platform.mjs package.json
printf '%s\n' 'Test file metadata:'
sed -n '1,22p' test/autonomy-platform.mjs

Repository: gitcommit90/1Helm

Length of output: 13806


🏁 Script executed:

printf '%s\n' 'OCI directory initialization and test-observable effects:'
sed -n '350,430p' src/server/channel-computers.ts
sed -n '430,525p' src/server/channel-computers.ts
printf '%s\n' 'Exports usable by a regression test:'
rg -n '^export (async )?(function|const)|^export \{' src/server/channel-computers.ts src/server/channel-storage.ts | rg 'ensureOci|channelUsesRuntime|channelComputer|configuredChannelBackend'

Repository: gitcommit90/1Helm

Length of output: 9992


Make the regression test select the OCI path explicitly.

Insert channel_computers metadata with backend='oci'. Without this row, the test uses the host default and selects the Apple path on macOS.

Assert that runtime storage remains untouched after ensureChannelWorkspace(channelId, { initializeRuntimeStorage: false }). assert.doesNotThrow is insufficient because ensureChannelWorkspace catches runtime initialization errors.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/autonomy-platform.mjs` around lines 203 - 212, Update the regression
test around ensureChannelWorkspace to insert channel_computers metadata for the
channel with backend='oci', ensuring the OCI path is selected regardless of host
platform. Replace assert.doesNotThrow with an assertion that runtime storage
remains untouched after calling ensureChannelWorkspace(channelId, {
initializeRuntimeStorage: false }), while preserving the existing workspace
root_ref assertion.

Comment thread test/desktop.mjs
assert.match(source, /handleSquirrelEvent/);
assert.match(source, /setAppUserModelId\("com\.squirrel\.1Helm\.1Helm"\)/, "Windows uses Squirrel's stable taskbar identity");
assert.match(source, /DATA_NAMESPACE = "1Helm-OCI-v1"/, "the clean-slate build uses a fresh durable application-data namespace");
assert.match(source, /SERVER_READY_TIMEOUT_MS = process\.platform === "win32" \? 3 \* 60_000 : 30_000/, "Windows gives a bounded cold WSL host enough time without weakening other desktop startup budgets");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert that waitForServer uses the timeout constant.

The current assertion verifies only the declaration. A regression to waitForServer(origin, timeoutMs = 30_000) would still pass.

Add an assertion for the default parameter or test the delayed-response behavior.

This assessment compares the assertion with the supplied desktop/main.cjs implementation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/desktop.mjs` at line 122, Extend the assertions in test/desktop.mjs to
verify that waitForServer uses SERVER_READY_TIMEOUT_MS as its default timeout,
not merely that the constant is declared. Assert the waitForServer default
parameter or cover equivalent delayed-response behavior while preserving the
existing platform-specific timeout check.

@gitcommit90
gitcommit90 merged commit 3b7ebd7 into main Aug 2, 2026
6 of 7 checks passed
@gitcommit90
gitcommit90 deleted the fix/windows-cold-start-ready branch August 2, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant