Live demo — data resets daily at 03:00 UTC. Nothing you enter is saved. Server UI →

Assert

YAML-driven test orchestration for hardware validation

Station Tools

Central Services

APIs

AI Assistant (MCP)

Connect your AI assistant to this station

Select your AI client below for setup instructions.

Run this command once in your terminal to register this station with Claude CLI:

mcp add --transport http assert-demo-station https://api.demo.esharp.se:7004/mcp
Station: demo-station  •  MCP endpoint: https://api.demo.esharp.se:7004/mcp
Assert 2.2.7

What's new

2.2.7 2026-09-18
  • ### Fixed
  • The station UI shipped without Bootstrap, so the sidebar rendered unstyled** - default fonts,
  • underlined links. `App.razor` asks for `lib/bootstrap/dist/css/bootstrap.min.css`; the file was
  • never committed, because `.gitignore` carried an unanchored `dist/` rule meant for the install
  • packages that `build-install-packages.ps1` writes. Unanchored, it matches a directory named `dist`
  • at any depth, and the only one in this repository is the vendored Bootstrap. Every CI-built image
  • therefore shipped a UI whose stylesheet 404'd, while it looked correct on any machine that happened
  • to have the folder on disk - which is every developer's.
  • The rule is anchored to the repository root now, and the one file the UI references is committed.
  • The rest of the upstream dist stays out: 8 MB of source maps, RTL variants and a JS bundle nothing
  • loads.
2.2.6 2026-09-18
  • ### Software Update can be re-applied
  • Being up to date no longer disables the button.** It always did, but the guard was invisible
  • while the version check was broken: the check could not succeed, so "positively up to date" never
  • happened and the button was always live. Fixing the check in 2.2.5 turned the guard on for the
  • first time, and it read as the button breaking.
  • Up to date is not a reason to refuse. Re-applying is how a station whose images were pruned is
  • repaired, or one whose state is in doubt is re-synced, and it is safe by construction: it loads the
  • version the station's own server already says it should run. The button now reads
  • Re-apply v«x.y.z»** in that state, quieter than a real update, so nobody presses it expecting
  • something new.
2.2.5 2026-09-18
  • ### Software Update comes from the station's own server, not from our registry
  • The update check asked GHCR, which a customer cannot reach.** The station read the version label
  • off the `:latest` image in our private registry, so the Config page reported
  • `Update check unavailable: 401 (Unauthorized)`. It was not a misconfiguration: a station installed
  • from its server's image bundle has **no registry credential by design**, and a customer has no
  • access to our repository at all, so the check could never have worked on the installs the product
  • now recommends. It asks Orchestra which version it hands out - which is also the right question,
  • because the version a station should run is the one its own server serves.
  • The update itself did `docker login` and `docker compose pull`**, with the same impossibility.
  • It now loads the image bundle from the station's server, streamed straight into `docker load`, and
  • pins `IMAGE_TAG` to what it loaded - without which the restart would bring back the old images and
  • report success. A registry pull remains the fallback for a station that does have a credential.
  • Together these make Software Update work on an air-gapped bench, and on every station that has no
  • credential because it never needed one.
2.2.4 2026-09-18
  • ### A station needs the Docker Engine, not Docker Desktop
  • Windows is pointed at WSL2 + Docker Engine**, not at Docker Desktop. A station runs Linux
  • containers; the Engine is Apache 2.0 and free for commercial use at any company size, and Docker
  • Desktop is a GUI and a packaged VM around that same Engine - which on Windows is a WSL2 VM anyway.
  • Sending people straight to WSL2 removes the middle layer and the subscription, and makes a Windows
  • bench the same install as a Linux one, running the same bootstrap. Desktop is still named, because
  • a machine that already has it need do nothing, but as a thing that works rather than a thing to buy.
  • The two jobs Docker Desktop was quietly doing are now stated.** Under WSL the installer prints
  • them, because both fail silently: `systemd=true` plus a `[boot]` command in `/etc/wsl.conf`, or a
  • rebooted bench never comes back; and `networkingMode=mirrored` in `.wslconfig` if the server has to
  • reach the bench, because WSL NATs by default and only Windows itself can see the station.
  • The Linux install also starts the daemon with `service docker start` where there is no systemd,
  • which is the usual state of a WSL distro.
2.2.3 2026-09-18
  • ### Docker
  • On Linux the bootstrap installs Docker** from `get.docker.com` when it is missing - the same
  • source the central deploy already uses for the server, so a bench and a server are provisioned the
  • same way. Where the socket then exists but the user cannot reach it, that is a group problem and
  • not a daemon problem, and it now says so: a new group applies only to a new login session, so it
  • names `newgrp docker` rather than telling anyone to start a daemon that is already running.
  • On Windows it does not install anything**, and that asymmetry is deliberate: Docker Desktop
  • needs elevation and usually a reboot, and its licence is paid above 250 employees or $10M revenue
  • (either threshold alone). Installing a commercially licensed product on someone's bench is their
  • decision. The message now gives both routes with the licence stated plainly: `winget install --id
  • Docker.DockerDesktop`, or - for a company over the threshold - `wsl --install` and then this
  • station's Linux line inside WSL, which installs **Docker Engine**. That subscription covers Docker
  • Desktop only; Engine is Apache 2.0 and free for commercial use at any size, so nobody is pushed
  • into a licence by installing a station.
An unhandled error has occurred. Reload

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.