You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds CPU and GPU development profiles in .horizon/cloud.yml, with public tooling images at ghcr.io/peters/horizon-development. The GPU profile requires a GPU allocation. Both recipes include the selected agent, browser engines, native desktop tools, component notices, and corresponding browser source archives. Application checkouts and runtime credentials are supplied separately.
The recipes preserve the Rust/CUDA environment through SSH and managed terminal sessions, use a UTF-8 locale, and expose persistent Cargo tools on PATH. Validation runs serially; test subprocesses ignore global Git settings and, when run as root, drop filesystem override capabilities so synthetic LFS and permission-denial fixtures remain meaningful.
Validation completed:
Both images build and pass worker capability/service checks, notice/source integrity checks, and anonymous pulls. Published tags are cpu-a525d30b and gpu-a525d30b; the current follow-up changes only validation and documentation, not image contents.
The complete local repository matrix passed on the current head: 43 successful test-suite summaries, no warnings, including blocking, strict, and advisory lint tiers. Independent local review found no actionable issues.
Independent clean-environment SSH, login-shell, managed-session, and offline tool-install checks pass in both images.
The final GPU image reached Ready on a real worker and imported committed source. Three actual GPU speech-inference runs produced the expected transcript. The native application selected a discrete hardware graphics adapter and passed Unicode input, resize, and Fit checks through a live native VNC panel. A two-minute recording was decoded and inspected; the application, viewer, and forwarding session were closed normally. This is bounded interaction and inference evidence, not microphone dictation or full persistence coverage.
Both browser engines passed creation, Unicode form input, output verification, and cleanup through public MCP tools in a normal managed worker session. The earlier standalone CLI attempt lacked the required session identity and is retained separately.
Current-head CI passed and the hosted review reported no findings, with a closer-look advisory while provider qualification remains incomplete. Remaining merge gates include CPU provider qualification and recovery evidence. Both profiles now omit the protected-agent capability because the provider runtime denies user namespaces; the installed CLI cannot be selected through these profiles. Independent exact-image checks confirm rejection before session creation. Broader protected-agent support remains unfinished under #813, with no protections bypassed. Local image checks and successful GPU lanes do not establish those remaining gates.
The GPU validation command explicitly links the collective communication library already present in the base image; an actual full application link passed. The complete GPU provider matrix passed with that command: 43 successful test-suite summaries, no warnings, and all lint tiers. The resulting executable was frozen, its running process hash verified, and a fresh native viewer continuously displayed the hardware-rendered Unicode/Fit/resize/restore smoke. Both final recordings were decoded and inspected; the application closed normally and the worker was deleted with provider absence verified. This is a cloud-helper workaround for missing upstream link metadata, not a claim that the ordinary build command is fixed.
Related to #813; this PR does not close the overall qualification issue or request a release.
CPU qualification remains blocked. The worker eventually reached Ready after repeated desktop transport startup timeouts. A task diagnostic configuration update reset the container; the restored configuration then presented a different SSH host key, which strict verification rejected. The provider reported a zero-sized Pod volume despite the profile requesting one; the filtered response did not retain the separate network-volume attachment field. Because the original raw storage response was not retained, the storage result cannot yet be attributed to creation or the diagnostic update. No CPU application smoke or restart-persistence pass is claimed. The worker was deleted and provider absence verified; the original host-key pin and failure evidence were retained.
Storage verification is being added in the focused prerequisite #832. CPU qualification will resume with that guard so the assigned storage is recorded and checked before source or agent credentials are transferred.
A fresh allocation using the #832 guard reproduced the storage problem before any configuration update: the profile requested 80 GB, but the provider reported a zero-sized Pod volume and no network-volume attachment. The guard rejected readiness before source or agent credentials were transferred, and the worker was deleted with absence independently verified. CPU qualification remains blocked until the provider allocation supplies the required persistent storage.
Pin CPU profile packages to an immutable Debian artifact source
.horizon/Dockerfile.cpu:9
These exact Debian package versions are resolved from the normal moving Bookworm repositories. Once Chromium receives its next security update, the mirror will typically remove this version, so a clean CPU-profile build will fail despite the profile being committed as the default development environment. Fetch these packages from a timestamped Debian snapshot (with the snapshot metadata/key verified), or retain them in an immutable artifact source.
Pin GPU profile packages to an immutable Debian artifact source
.horizon/Dockerfile.gpu:9
These exact Debian package versions are resolved from the normal moving Bookworm repositories. Once Chromium receives its next security update, the mirror will typically remove this version, so a clean GPU-profile build will fail even though this profile is intended to remain buildable on demand. Fetch these packages from a timestamped Debian snapshot (with the snapshot metadata/key verified), or retain them in an immutable artifact source.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🔵 Needs a closer look
Both images omit the persistent Cargo binary directory from PATH, making session-installed Rust tools unavailable.
Review effort: Balanced Findings: None
Previously missed (2)
In code that hasn't changed since last review
Add $CARGO_HOME/bin to PATH for installed tools
.horizon/Dockerfile.cpu:28
CARGO_HOME points at the persistent workspace, so cargo install writes executables to /workspace/cargo/bin, but that directory is absent from PATH. Tools installed during a cloud development session therefore cannot be invoked normally. Include $CARGO_HOME/bin in PATH while retaining /usr/local/cargo/bin for the preinstalled toolchain.
Add $CARGO_HOME/bin to PATH for installed tools
.horizon/Dockerfile.gpu:28
CARGO_HOME points at the persistent workspace, so cargo install writes executables to /workspace/cargo/bin, but that directory is absent from PATH. Tools installed during a cloud development session therefore cannot be invoked normally. Include $CARGO_HOME/bin in PATH while retaining /usr/local/cargo/bin for the preinstalled toolchain.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds CPU and GPU development profiles in
.horizon/cloud.yml, with public tooling images atghcr.io/peters/horizon-development. The GPU profile requires a GPU allocation. Both recipes include the selected agent, browser engines, native desktop tools, component notices, and corresponding browser source archives. Application checkouts and runtime credentials are supplied separately.The recipes preserve the Rust/CUDA environment through SSH and managed terminal sessions, use a UTF-8 locale, and expose persistent Cargo tools on PATH. Validation runs serially; test subprocesses ignore global Git settings and, when run as root, drop filesystem override capabilities so synthetic LFS and permission-denial fixtures remain meaningful.
Validation completed:
cpu-a525d30bandgpu-a525d30b; the current follow-up changes only validation and documentation, not image contents.Current-head CI passed and the hosted review reported no findings, with a closer-look advisory while provider qualification remains incomplete. Remaining merge gates include CPU provider qualification and recovery evidence. Both profiles now omit the protected-agent capability because the provider runtime denies user namespaces; the installed CLI cannot be selected through these profiles. Independent exact-image checks confirm rejection before session creation. Broader protected-agent support remains unfinished under #813, with no protections bypassed. Local image checks and successful GPU lanes do not establish those remaining gates.
The GPU validation command explicitly links the collective communication library already present in the base image; an actual full application link passed. The complete GPU provider matrix passed with that command: 43 successful test-suite summaries, no warnings, and all lint tiers. The resulting executable was frozen, its running process hash verified, and a fresh native viewer continuously displayed the hardware-rendered Unicode/Fit/resize/restore smoke. Both final recordings were decoded and inspected; the application closed normally and the worker was deleted with provider absence verified. This is a cloud-helper workaround for missing upstream link metadata, not a claim that the ordinary build command is fixed.
Related to #813; this PR does not close the overall qualification issue or request a release.
CPU qualification remains blocked. The worker eventually reached Ready after repeated desktop transport startup timeouts. A task diagnostic configuration update reset the container; the restored configuration then presented a different SSH host key, which strict verification rejected. The provider reported a zero-sized Pod volume despite the profile requesting one; the filtered response did not retain the separate network-volume attachment field. Because the original raw storage response was not retained, the storage result cannot yet be attributed to creation or the diagnostic update. No CPU application smoke or restart-persistence pass is claimed. The worker was deleted and provider absence verified; the original host-key pin and failure evidence were retained.
Storage verification is being added in the focused prerequisite #832. CPU qualification will resume with that guard so the assigned storage is recorded and checked before source or agent credentials are transferred.
A fresh allocation using the #832 guard reproduced the storage problem before any configuration update: the profile requested 80 GB, but the provider reported a zero-sized Pod volume and no network-volume attachment. The guard rejected readiness before source or agent credentials were transferred, and the worker was deleted with absence independently verified. CPU qualification remains blocked until the provider allocation supplies the required persistent storage.