Repository navigation
Highlights
- The dock. The console's status strip is now one surface for everything live: the GPU's state and its controls (hold, keep, unpin, stop, restart), slot and service health, downloads, and a feed that merges the journal with the activity trail, with a two-row ticker and an unseen badge while collapsed. It works on phones too. The Image Gen pane's status line, the top image-mode banner, the Engine tab's device card and the Activity sidebar are gone (ADR-0042).
- The slot rail. Beside the Inference pane, every slot grouped by device with its state, tok/s, model and loaded memory; a row flashes when something happens to that slot.
- ComfyUI's editor answers on the LAN again at
http://<host>:8188, announced over mDNS, with[network].comfyui_listen = "loopback"to fence it (ADR-0041). - Upgrades start at 1.5.0. A 1.3.x or 1.4.x box steps through 1.5.0 first;
hal0 updatesays so and stops before downloading. - Twenty fixes from the 1.7 fix wave, among them: a random image seed that a browser holds exactly, image downloads from the current Hugging Face repos,
hal0 updateno longer claiming no slots need a restart, Open WebUI left stopped when its image upgrades, and approval cards that show which resource a gated call acts on. - Faster pull-request checks. A UI-only or docs-only change skips the Python matrix, and the Playwright suite runs as four shards.
- ComfyUI runs as the
hal0account inside theimgcontainer, not as root; the sudo wrapper accepts that one identity only. A data root laid down by hand under another account needs a one-timechgrp/chmod(see Breaking), and the engine restarts once (#3066).
Breaking
-
ComfyUI's editor is on the LAN again, and announced over mDNS.
http://<host>:8188opens ComfyUI's web UI from any machine on the network, and the Discovery (mDNS) card on the Services page announces it ashttp://<host>.local:8188beside Open WebUI, the way hal0 did before the host-net loopback fence. The newcomfyui_listenkey of[network]inhal0.tomlis the switch:"lan"(the default) or"loopback", which fences:8188to the box like every other slot and keeps the SSH-tunnel andHAL0_COMFYUI_PUBLIC_URLpaths. ComfyUI has no sign-in of its own, so"lan"is for a network you trust. The dashboard follows the live mode:GET /api/config/urlsaddscomfyui_lan, the editor button opens from anywhere while it is true, and the Engine tab's Network row readslistens on the LANorlistens on loopback. Every other slot still renders a loopback bind under host networking (ADR-0041, #3049). -
Upgrades start at 1.5.0.
manifest.jsondeclaresupgrade_from = ">=1.5.0", sohal0 updateon a 1.4.x box stops before it downloads anything, withsystem.update_upgrade_path_unsupportednaming both versions, and re-running the installer over a 1.4.x install stops before it changes anything. A 1.3.x or 1.4.x box steps through 1.5.0 by running its installer in place, the command the installer prints when it refuses (curl -fsSL https://hal0.dev/install.sh | sudo env HAL0_RELEASES_URL=https://github.com/hal0ai/hal0/releases/download/v1.5.0/stable.json bash), then updates again.hal0 update --targetcannot make that hop: it pins only the version the channel serves now. The upgrade guide's--target 1.5.0hop for 1.3.x boxes failed for the same reason once the channel moved past 1.5.0, and is replaced. A 1.5.0 nightly counts as a prerelease of 1.5.0, so it is below the floor too. The floor moves so the profile-centric conversion that 1.4.0 shipped (ADR-0029) can be deleted. -
The dock replaces four status surfaces. The footer is now the dock, the console's one status and event surface. The Image Gen pane's GPU status line, the top "image mode" banner, the Engine tab's GPU device card and its Stop image mode button, and the Slots page's Activity sidebar are gone. The dock's GPU segment and gpu tab carry the GPU's state and every GPU-mode button, its events tab carries the journal and the activity trail, and the slot rail carries the Inference tab's side column.
#slotsdeep links still work, and the agent card's Tool activity button opens the dock's events tab. The only GPU banner left at the top of a page is the blocked-gate one (ComfyUI's GPU gate has no credential); the first-run, update and demo banners are unchanged. See ADR-0042. -
ComfyUI runs as the
hal0account inside theimgcontainer, not as root. The container'soutput,input,user,custom_nodesand the newhomedirectories under the ComfyUI data root (/var/lib/hal0/models/comfyuion a standard install) must be writable by thehal0account. A data root hal0 created is (it ishal0:hal0 2775). One laid down by hand under another account, or on a share, needschgrp -R <hal0 group> <dir> && chmod -R g+ws <dir>on those directories once, as root; until then a render fails atSaveImagewithPermission deniedandhal0-api's journal logscomfyui.data_dir_not_writablewith the command. The models directory may stay read-only. (#3066)
Added
- The dock. One strip at the bottom of every page: the GPU segment (headline, detail and at most two buttons; click it for the gpu tab), the slots and services pip groups, the update chip and a
docktoggle with a+Nbadge for events that arrived while it was closed. Under the strip, a two-row ticker of the newest events. Expanded, the events tab merges journal lines (J) with activity actions (A) in one timeline, filtered by stream, severity, source, slot and search, with Export for the activity trail. The gpu tab shows the full status, every button that applies, including Restart engine, Logs and Open editor, and a facts grid. (ADR-0042) - The slot rail. On the Inference tab, every slot grouped by device with its state, tok/s, model and loaded GB, an
N / M readycount that equals the dock's, and a row that flashes when an event for that slot lands in the dock. - A two-column Generate tab. At a viewport of 1360 px and up, the form sits beside the results.
Changed
- The dock's expanded panes push the page up instead of covering it, and the downloads pane's height follows the dock's (
min(300px, 45vh)). - The dock is part of the phone layout; the footer used to be hidden at 720 px and below.
Fixed
hal0 update,hal0 update component openwebuiand the dashboard Retry button no longer start an Open WebUI you stopped when they upgrade its image. The new image is pinned and takes effect the next time you start it. (#3039)- Loading an image slot no longer fails with the LLM registry when the registry is unavailable; ComfyUI reads its weights from its own tree. (#3040)
- Guided
hal0 setupno longer prints a false warning for the ComfyUI extension or starts the image slot unasked; it leaves the Quadlet-generated image unit alone. (#3038) - Resuming a large model download no longer freezes the API while the partial file is re-hashed; the hashing now runs off the event loop. (#3031)
hal0 updateno longer says "no slots need restart" when slots will restart on their next load; the drift check runs before hal0-api restarts onto the new release, so the message now says so. (#3044)- The Services page no longer stalls the API while it checks whether Open WebUI's image button is wired; the check reads your checkpoint files, so it now runs off the request loop. (#3041)
- Image-model downloads name the current Hugging Face repos. Six catalog sources (the Qwen-Image, Qwen-Image-Edit, HunyuanVideo 1.5, Wan 2.1, Wan 2.2 and Stable Diffusion 1.5 repos) pointed at names Hugging Face has since renamed and only reached the files through a redirect. They now use the canonical names, with the same files and checksums. (#3042)
- A random image seed is one a browser holds exactly.
/v1/images/generationswithoutextra_body.seeddrew up to 263, and a JavaScript client rounded the_hal0.meta.seedit got back, so reusing it rendered a different image. The draw is now below 253. (#3073) - An image render that fails on text ComfyUI sent back no longer answers a bare 500. When ComfyUI returned a lone surrogate such as
"\ud800"in theprompt_idor the/historyoutputs, the error repeated it unchanged and could not be sent; the caller now gets the usual502 dispatch.upstream_failederror with the text cleaned. (#3069) - ComfyUI render progress now shows on boxes where an HTTP proxy is set in the environment. (#3074)
hal0 doctornames a gateway remedy that works whenhermes-gatewayis masked. The "Hermes gateway is disabled and not running" row now sayssudo systemctl unmask hermes-gateway.service && sudo hal0 agent install hermes(unmask --runtimefor a runtime mask), the same ashal0 agent install hermes, instead of anenable --nowthat fails. (#3030)- On a box that requires sign-in, a streaming route now notices when its client disconnects. The auth stream guard used to drop the disconnect, so
request.is_disconnected()never turned true behind it. (#3068) - The image starter recommendation no longer picks a model the box's own memory check refuses on 16–18 GB machines. (#3076)
Security
- The
imgcontainer no longer runs ComfyUI as root. The slot's Quadlet unit carriesUser=<hal0 uid>:<hal0 gid>plus the account's host groups (video,render, and any shared model-store group), so a ComfyUI process, custom node or editor workflow writes its read-write mounts as thehal0account and lands onhal0's privileges if it escapes the container, instead of on uid 0. The sudo-grantedhal0-systemctlwrapper accepts[Container] User=for exactly that one value, read on the root side:0:0, a name, or any other account is refused. The models mount moved from/root/comfy-models(the image's/rootis not traversable ashal0) to/opt/hal0-models; aextra_model_paths.yamlwhosebase_pathstill names the old mount is hal0's own and is rewritten on the first load, any otherbase_pathis left alone.$HOMEis a persistenthomedirectory under the data root (ROCm's kernel caches now survive a restart), and ComfyUI's temp directory is under the container's/tmp. (#3066) - Approval cards show which resource a gated call acts on. The dashboard's approvals modal and Approvals card cut a gated MCP call's arguments off at 120 characters in the agent's own key order, so a long argument placed first could hide the
model_id,nameorslotthe call deletes, unloads or edits. Each approval now carriestarget_args, the arguments that pick the resource; the cards show those first and in full, every other argument on its own row, and the complete argument JSON one click away. (#3052) hal0-agentenv secret-keysopens the agent secrets vault through the same no-follow descriptor walk as the vault writers, so the hal0 account can no longer redirect it with a symlink to list the key names of a root-only file. (#3014)- The installer now starts every Python helper in isolated mode, so running it as root from a directory a service account can write no longer imports modules planted there. (#3010)
Migrations
- Restart the image engine once so ComfyUI drops to the
hal0account. A runningimgcontainer keeps the identity it started with, so after this update runhal0 slot restart imgonce (or press Restart engine on the Engine tab); the first load also movesextra_model_paths.yamlto the new models mount. If the ComfyUI data root was laid down by hand under another account, make itsoutput,input,userandcustom_nodesdirectories writable by thehal0account first (see Breaking). (#3066) - Restart the image engine once for the LAN editor. A running
imgcontainer keeps the loopback bind it started with, so after this updatehttp://<host>:8188is still refused from other machines until you runhal0 slot restart imgonce (or press Restart engine on the Engine tab). Then turn the Discovery (mDNS) card on the Services page on, or off and on, if you wanthttp://<host>.local:8188announced. To keep the old posture instead, setcomfyui_listen = "loopback"under[network]in/etc/hal0/hal0.tomlbefore the restart.