Workers
For the installation walkthrough, prerequisites, and readiness checks, start with Install and connect a worker. This reference explains lifecycle commands, verification, enrollment, and status in detail.
Pidgen runs work on workers that you operate. A worker is the pidgen-worker program, published
on PyPI as pidgen-worker separately from this CLI and
under its own licence, running on a machine you control. It connects to the
App Service with its own credential, never with your credentials.
pidgen worker is the front door: it installs and verifies the worker, creates the enrollment, and
hands over to pidgen-worker.
This page documents the CLI's side: install, enroll, start, stop, update and status. What runs on the machine is documented by the worker itself: Configure the worker (capacity and pool sizes), Coding agents (harnesses and subscriptions), Worker troubleshooting codes, and Run as a service under a service manager.
Set up a worker
Section titled “Set up a worker”$ pidgen setup [--runtime wheel] [--version <version>] [--label <label>] [--url <url>]pidgen setup is the guided path from a fresh machine to a verified worker running your Account's
work, and the CLI's one interactive command. It checks the machine (pidgen doctor), signs you in
with a device code, lets you choose an Account when you belong to several, asks which runtime
to install (currently wheel, with the licence notice), installs and verifies the worker (pidgen worker install, pidgen worker verify), enrolls and starts it (pidgen worker enroll, pidgen worker start --detach), waits until the App Service reports it connected, and proves it (pidgen worker doctor). Before enrolling it says whether your credential may enroll workers and, when it
may not, which roles can and how to sign in with a Personal API Token that has workers:enroll.
Guided container setup is planned. Use the wheel runtime for the complete installation, enrollment, and startup path through this CLI.
It prints each step as the pidgen command it runs, so the path can be scripted from the commands
on this page. Running it again resumes: a signed-in profile, an installed worker and an enrolled
host are skipped. Without a terminal it exits 2 with TERMINAL_REQUIRED and lists those commands
in error.details.commands (Commands).
Check this machine
Section titled “Check this machine”$ pidgen doctorBefore installing or enrolling, pidgen doctor tells you everything this machine needs, without
changing anything and without a worker installed. Its data.checks cover the Node.js version
(node), the server's health and API version (server), your credential, its Account role and
whether it may enroll workers (credential), and the worker runtimes (runtime): uv for the
wheel runtime, and docker with cosign for the container runtime.
The rest come from the server's worker release list, read with no credential. The CLI carries no harness knowledge of its own: the list names the coding-agent harnesses a worker can run and the command each is found by.
| Check | ok when |
Otherwise |
|---|---|---|
releases |
The release list was read | fail, naming the error and the route; skip when the server check failed |
harness:<kind> |
The harness's command is on PATH |
warn, or fail when no harness the list names is on PATH |
worker |
The installed release is the server's current |
warn when it is only supported or nothing is installed yet; fail when the server no longer accepts it or does not list it. The fix is pidgen worker install |
When the list is not read, harness and worker are skip. Each check is ok, warn, fail or
skip and names its fix, the command or address that resolves it. A failing check exits 1 with
DOCTOR_FAILED and the report in error.details; warnings exit 0 (Commands).
pidgen doctor is not pidgen worker doctor: the first diagnoses this machine and its connection
to Pidgen, the second runs the installed worker's own checks.
Install the worker
Section titled “Install the worker”$ pidgen worker install [--runtime wheel|container] [--version <version>] [--force] [--test]Waiting on the server and the first release.
pidgen worker install,pidgen worker enrollwith no worker installed, andpidgen doctorread the server's worker release list,GET /api/v1/workers/releases. A server without it answers404, soworker installand such an enroll exit 4 withNOT_FOUNDandpidgen doctorfails itsreleasescheck. Until the worker's first release is on PyPI, installing exits 5 withRELEASE_UNSUPPORTED; use--testfor a rehearsal from TestPyPI.
Installs the worker without enrolling it. It needs no credential and spends no enrollment, so a
machine can be prepared by someone without the role to enroll it, and a failed install costs
nothing on the server. It reads the release list from PIDGEN_API_URL or the profile's server,
else the hosted server, https://api.pidgen.ai.
- It reads the server's worker release list with no credential and no Account. The server names
release series, one per worker protocol it accepts:
current(install this) andsupported(still accepted), each with its wheel requirement,pidgen-worker~=X.Y.0. - It picks the series: the server's
current, or the series of--version. A version whose series the server does not accept exits 5 withRELEASE_UNSUPPORTED;error.details.acceptedlists the series it accepts. - It asks the package index for the series: PyPI, or TestPyPI with
--test. It takes the newest release of the series (or exactly--version), skipping yanked files, and that release's wheel for this machine: the CPython 3.12 wheel for Linux x86_64 or aarch64, or macOS on Apple silicon or Intel. Development builds (X.Y.Z.devN) are candidates only on TestPyPI. A series the index has no release of exits 5 withRELEASE_UNSUPPORTED. - When the install record already names that version, it does nothing and exits 0 with
installed: false.--forcereinstalls it. - It prints the worker's licence notice to standard error. Installing accepts the licence; there is no licence prompt and no flag.
- It verifies the release's artifact (below) before
anything runs. A missing or failing attestation or signature, or an artifact whose digest
differs from the index's, exits 5 with
PROVENANCE_INVALID, names what failed inerror.details.check, and leaves nothing installed. There is no way to skip verification.- Wheel: it fetches the wheel's PEP 740 attestation from the index, downloads the wheel, and verifies it.
- Container: it resolves the image tag the server names (
<repository>:X.Y) to the digest it points at withdocker buildx imagetools inspect, then runscosign verifyfor<repository>@<digest>. The image is always named by that digest from then on.
- Only then does it install the verified artifact. A failing install exits 1 with
INSTALL_FAILED.- Wheel:
uv tool install --python 3.12 <verified wheel>, which gives the worker its own environment on the interpreter the wheel was built for, anduv tool dir --binto find the installedpidgen-worker. - Container:
docker pull <repository>@<digest>, thendocker volume create pidgen-worker-homefor the worker home. Installing runs no container.
- Wheel:
--test installs a release rehearsal from TestPyPI, where X.Y.Z.devN builds are published before
a release. Its wheels are verified the same way, against the same publisher; nothing from TestPyPI
is accepted without that signature. The install record says index: testpypi, and pidgen worker update keeps looking
there until --test is dropped by a reinstall.
--runtime picks the form. Without it, an existing install record decides, then what the machine
has: uv means wheel, and otherwise docker with cosign means container. The CLI never
installs uv, Docker or cosign: when what the form needs is missing the command exits 2 with
RUNTIME_UNAVAILABLE and the install instructions in error.details.install.
Every command the CLI runs is composed by the CLI, printed to standard error ($ uv tool install …, $ cosign verify …, $ docker pull …) before it runs, and run with an argument list, never
through a shell. Its output goes to standard error, so standard output carries only the CLI result:
human-readable output for terminal stdout, or a JSON envelope for nonterminal stdout. Use
--format json or --format table to override that selection.
data is the install record plus installed:
| Field | Meaning |
|---|---|
form |
wheel or container |
version |
The installed release |
index |
testpypi for a --test install; absent for PyPI |
artifact |
The wheel requirement, pidgen-worker==<version>, or the image repository without a tag |
digest |
sha256:<hex> of the verified wheel, or the verified image's manifest digest |
identity |
The signer (issuer, subject) the attestation or signature named, which matched an accepted publisher |
verified_at, installed_at |
When it was verified and installed |
location |
The installed pidgen-worker, or the container's name, pidgen-worker |
file |
The verified wheel, kept under $PIDGEN_HOME/worker/ with its attestation so worker verify can re-check it; null for the container |
volume |
Container only: the Docker volume holding the worker home, pidgen-worker-home |
installed |
true when this run installed it; false for the no-op |
The record is written to $PIDGEN_HOME/run/pidgen-install.json, beside the detached worker's run
record. Later commands read it, so none of them needs --runtime.
Verify the installed worker
Section titled “Verify the installed worker”$ pidgen worker verifyRe-checks the installed worker against its record: the kept wheel still has the recorded digest,
or the image <reference>@<digest> is still present (docker image inspect) (digest), and its
attestation, or the image's cosign signature, still verifies against an accepted publisher
identity (provenance). It needs no Pidgen server; for the wheel, Sigstore's trust root is
loaded, and cached under $PIDGEN_HOME/cache/sigstore, as for an install. data is checks, each {id, status, summary, fix} as pidgen doctor reports them, plus the record; a failing check's fix is pidgen worker install --force. A failed check exits 5 with PROVENANCE_INVALID and the same checks and
record in error.details; no install record exits 4 with WORKER_NOT_INSTALLED.
Update the worker
Section titled “Update the worker”$ pidgen worker update [--version <version>] [--restart] [--test]Installs the newest release of the server's current series, or --version, in the recorded form
with the same verification as worker install (steps 1–3 and 5–7 above;
for a container, the cosign signature before docker pull), and updates the install record. It
looks on TestPyPI with --test, or when the installed worker came from there. It
needs an install record; without one it exits 4 with WORKER_NOT_INSTALLED. When the record
already names the release it does nothing and exits 0 with updated: false. Nothing updates on
its own: the worker is only updated when you run this command.
A worker started with --detach, or a running container, keeps running the old version until it
is restarted. --restart stops it after the install (SIGTERM, waiting for the global
--timeout) and starts it again with the same arguments (a container's are kept in its
ai.pidgen.worker.args label); a worker that does not stop in time exits 8 with TIMEOUT, the
new version installed and the old worker still running until it is restarted. If the new worker exits during the two-second startup check, the
CLI rolls back:
- It checks that the previous version's kept wheel still has the digest it was verified with, and
reinstalls it with
uv tool install --python 3.12 --reinstall <kept wheel>; for a container, it verifies the previous image's cosign signature again and pulls<reference>@<digest>. - It restores the previous install record and removes the new version's kept wheel.
- It starts the worker again, with the same arguments, on the previous version.
- It exits 1 with
UPDATE_ROLLED_BACK.error.detailshasversion(the release that did not start),previous_version,log_tail(the last log lines of the failed start),record(the restored install record),runningandworker(the restarted worker record, ornull).
When the previous version cannot be reinstalled — its kept wheel is missing or changed, its image
no longer verifies, or uv or docker pull fails — the command exits 1 with ROLLBACK_FAILED; run pidgen worker install --version <previous version> to install it again.
data is the new install record plus updated, previous_version, running (whether a detached
worker or the container runs), restarted and, after a restart, worker (the worker or container
record). The superseded version's kept wheel is
removed once the update succeeds.
Uninstall the worker
Section titled “Uninstall the worker”$ pidgen worker uninstall [--purge]Stops a detached worker or the running container (SIGTERM, then SIGKILL after the global
--timeout, since the worker is being removed), removes what the install put on the machine, by
the recorded form, then the install record, and exits 0:
- Wheel:
uv tool uninstall pidgen-worker, and the kept wheel and attestation. A worker that was already removed outside the CLI is not an error. Whenuvfails while the worker is still installed, it exits 1 withUNINSTALL_FAILEDand keeps the record. - Container: the stopped
pidgen-workercontainer (docker rm) and the pinned image (docker image rm <reference>@<digest>). A failing docker command exits 1 withDOCKER_FAILEDand keeps the record.
The worker home ($PIDGEN_HOME, ~/.pidgen by default), with the worker's credential, stays, so
installing again needs no new enrollment. --purge removes it too, and for a container also the
pidgen-worker-home Docker volume that holds the container's worker home; the CLI refuses with
PURGE_REFUSED (exit 5) and removes nothing when the worker home is your home directory or a
filesystem root. With no install record it exits 4 with WORKER_NOT_INSTALLED.
data is uninstalled (the removed install record), stopped ({record, forced} of the worker it
stopped, or null), removed (what was removed, such as tool pidgen-worker or
image <reference>@<digest>), purged and worker_home.
Enroll a worker
Section titled “Enroll a worker”$ pidgen worker enroll [--label <label>] [--install | --no-install] [-- args]One command takes a machine with a worker installed, or one it may install, to an enrolled worker. The install comes first, so the enrollment is created only once a verified worker is present:
- When
pidgen-workeris already onPATH(or atPIDGEN_WORKER_BIN), it skips to step 3. - Otherwise, with
--install, it runs the same install aspidgen worker install(above), with the same verification and the same commands printed to standard error: it reads the server's release list, picks thecurrentrelease, shows the worker's licence notice, verifies the wheel against the worker's release identity, and only then runsuv tool installon the verified file and writes the install record. Installing accepts the licence. It never asks:pidgen setupis the CLI's one interactive command, and it installs and verifies the worker withpidgen worker installbefore enrolling. A failed or refused install spends no enrollment.--installagrees in advance.--no-installnever installs. With no worker installed it exits 2 withWORKER_NOT_FOUND, makes no request, and namespidgen worker installinerror.details.install.command.- With neither flag, on a terminal or not, it exits 2 with
INSTALL_CONFIRMATION_REQUIRED, witherror.details.install, thereleaseand theeula, and namespidgen setupand--install. - The install fails as
pidgen worker installdoes: withoutuvit exits 2 withRUNTIME_UNAVAILABLE; a wheel that does not verify exits 5 withPROVENANCE_INVALIDand installs nothing; a failinguv tool installexits 1 withINSTALL_FAILED. - An install that leaves
pidgen-workeroffPATHexits 2 withWORKER_NOT_FOUNDand the install record inerror.details.installed; add its directory toPATHand enroll again.
- Only now it creates an enrollment in the current Account (
POST /api/v1/workers/enrollments, with--labelas its name). This needs the Account Owner or Administrator role, or a Personal API Token withworkers:enroll; any other caller exits 3 withFORBIDDENand no worker is enrolled (a worker installed in step 2 stays installed). The enrollment counts against the Account's worker allowance. - It runs
pidgen-worker enroll --token <one-time token> --server <server> --no-startfollowed by the arguments after--, which win over the CLI's own.<server>is the server the enrollment was created on. The worker exchanges the one-time token there for its credential and stores it. The one-time token expires after 24 hours and can be used once. Enrolling does not start the worker: runpidgen worker start --detach, which records the worker so thatworker status,worker stopandworker update --restartcan find it (pidgen setupdoes this for you). A failing worker exits 1 withENROLL_FAILEDand its status inerror.details.exit_code.
The enrollment response also lists install options (a container image and a Python package); the
CLI reports them in data.install but never runs them, and never runs any command string from a
server response. Every command the CLI runs is composed by the CLI and run with an argument list,
never through a shell. The install's and the worker's output go to standard error, so standard
output carries only the CLI result (an envelope in JSON mode). An enrollment the CLI created but could not hand to a worker is
not used and expires on its own.
pidgen worker enroll enrolls a pidgen-worker on this machine's PATH. Enrolling a worker
installed in the container form through pidgen worker enroll is planned.
The one-time token goes only to pidgen-worker. It is never printed, never in the envelope (success
or error), and never written to the CLI's configuration. The CLI never sees or keeps the worker
credential.
Run and check a worker
Section titled “Run and check a worker”| Command | Does |
|---|---|
pidgen worker start [-- args] |
Runs pidgen-worker in the foreground with inherited standard streams and the arguments that follow -- |
pidgen worker start --detach [-- args] |
Starts pidgen-worker in its own session and writes its output to the worker-manager log |
pidgen worker stop [--force] |
Stops the worker started with --detach; --force kills it if it does not stop before the global --timeout |
pidgen worker status [--host <host_id>] |
Shows the detached worker record, whether that process is still the recorded pidgen-worker, and the App Service's record of this worker (below) |
pidgen worker doctor [-- args] |
Runs pidgen-worker doctor --json and returns the report using the selected output format (an envelope in JSON mode); for this machine before a worker is installed, use pidgen doctor |
The CLI finds pidgen-worker on PATH, or at PIDGEN_WORKER_BIN. It sets PIDGEN_HOME for the worker,
using ~/.pidgen when the variable is unset, and removes PIDGEN_TOKEN from the worker's environment:
the worker never receives a person's credential. Worker commands are supported on Linux and macOS. A
missing worker or unsupported platform is a usage error.
Foreground worker start forwards SIGINT and SIGTERM and exits with the worker's status (or 128
plus the signal number). Because it is a foreground handoff, its standard streams belong to the
worker and the CLI does not print an output envelope.
With --detach, the CLI starts the worker in a new session with no terminal. Standard output and
standard error are appended to worker-manager.log under PIDGEN_WORKER_LOG_DIR, or under
$PIDGEN_HOME/logs when that variable is unset. The CLI records the process id, start time, log path,
and command in $PIDGEN_HOME/run/pidgen-worker.json. It waits two seconds before reporting success.
If the worker exits during that check, the command exits 1 with WORKER_EXITED and includes the
last 20 log lines in error.details.log_tail.
Only one recorded worker may run at a time. Another detached start exits 5 with
WORKER_ALREADY_RUNNING. A record is stale when its process is gone or its process is not the
recorded pidgen-worker; a detached start replaces such a record. worker status retains and reports a
stale record with running: false. worker stop sends SIGTERM and waits for the global --timeout
(120 seconds by default). It exits 8 with TIMEOUT if the process remains, or sends SIGKILL when
--force is present. With no running record, it exits 4 with WORKER_NOT_RUNNING.
A failed doctor exits 1 with DOCTOR_FAILED and includes the diagnostic report in error.details.
The worker documents its diagnostic codes in
Worker troubleshooting codes.
A detached worker is not restarted after a reboot. To keep it running across reboots, run
pidgen-worker under a service manager as described in
Run as a service.
In a container
Section titled “In a container”When the install record's form is container, the same commands act on one named container,
pidgen-worker, running the verified image by its digest, with the worker home in the Docker
volume pidgen-worker-home mounted at /pidgen (PIDGEN_HOME=/pidgen in the container). The
record decides; none of the commands takes --runtime.
| Command | Runs |
|---|---|
worker start [-- args] |
docker run --rm --interactive --name pidgen-worker --volume pidgen-worker-home:/pidgen --env PIDGEN_HOME=/pidgen <reference>@<digest> [args] in the foreground, forwarding SIGINT and SIGTERM, and exits with its status |
worker start --detach [-- args] |
The same with --detach instead of --rm --interactive; both label the container with its arguments (--label ai.pidgen.worker.args=<JSON>). It waits two seconds and reads the container's state; a container that has already stopped exits 1 with WORKER_EXITED and the last 20 lines of docker logs in error.details.log_tail |
worker stop [--force] |
docker kill --signal SIGTERM pidgen-worker, waits for the global --timeout, then docker rm pidgen-worker. A container still running exits 8 with TIMEOUT, or with --force is killed (docker kill) and removed |
worker status |
docker inspect --type container pidgen-worker: record is {container, id, image, volume, status, started_at, args} (or null when there is no container) and running |
worker doctor [-- args] |
docker exec pidgen-worker pidgen-worker doctor --json [args] in the running container |
A running container makes another start exit 5 with WORKER_ALREADY_RUNNING; a stopped one is
removed and replaced. stop and doctor exit 4 with WORKER_NOT_RUNNING when the container is
not running. A Docker daemon that cannot be reached exits 2 with RUNTIME_UNAVAILABLE; any other
failing docker command exits 1 with DOCKER_FAILED, its status and its error output in
error.details. Commands that change something are printed to standard error before they run.
The App Service's view
Section titled “The App Service's view”When a credential is configured, pidgen worker status also reads the Account's workers
(GET /api/v1/workers) and reports the one whose host id is this machine's host name, or the host
id given with --host. That route needs the Account Owner or Administrator role; no Personal API
Token scope reaches it.
data then has record, running and update as before, plus:
server:host_id(the host id looked for),enrolled,worker, and the service'sservice_protocolandaccepted_protocols.workeris the server's record of this worker —last_seen_at,connected,protocolandprotocol_state(current,outdated,unsupportedorunknown),build_version,revoked_at, andgit_credentials: per Project remote it serves, whether its last report found a local git credential (covered,missingorstale). It never includes the worker's credential.warnings: what could not be shown, each with acode,messageanddetails.
| Situation | Result |
|---|---|
| No server or no credential configured | Local only: data is {record, running, update} and no request is made |
| The server lists a worker with this host id | server.enrolled: true, server.worker is its record; an unrevoked record is preferred over a revoked one |
| No worker with this host id, or only a revoked one | server.enrolled: false, server.worker is null (or the revoked record); exit 0, not an error |
| The server cannot be reached, times out, or refuses | server: null and a warning carrying the error's code (NETWORK, TIMEOUT, FORBIDDEN, …); exit 0 |
| The configuration cannot be read | server: null and a warning with its code (CONFIG_INVALID, CONFIG_PERMISSIONS); exit 0 |
worker status always exits 0 once it has read the local record; only a usage error (an empty
--host) or an unsupported platform fails it. An install record that cannot be read is a
warning (INSTALL_RECORD_INVALID) with update.installed: null.
Is an update needed
Section titled “Is an update needed”update says whether the worker should be updated, and why:
| Field | Meaning |
|---|---|
installed |
The version the install record names, or null with no record |
current |
The server's current release, or null when the release list was not read |
needed |
true when reason is not null |
reason |
protocol_unsupported, protocol_outdated, newer_available, or null |
protocol_unsupported (the server will not give this worker work) and protocol_outdated (it
still will, for now) come from the server's record of the worker, its protocol_state.
newer_available comes from the release list: its current is newer than installed. The
protocol reasons win over newer_available. With a credential, after GET /workers, the CLI reads
the release list with no credential (GET /api/v1/workers/releases); a list that cannot be read
leaves current: null and adds a warning, and an unreachable server is not asked for it. Without a
credential nothing is requested, so current is null. Run pidgen worker update to update.
Human worker results name the operation and retain the install/run records, protocol and update state, verification checks and fixes, and any warnings in labeled sections. A successful local status read still exits 0 when the service is unreachable; the output explains that limitation and retains the warning. Diagnostic failures show their code, message, failed checks and fixes. Startup and update failures also retain supplied log tails and rollback/restart information.
$ pidgen worker status --format table$ pidgen worker verify --format table$ pidgen worker status --format jsonInstallation commands, verification progress and enrollment output keep their established stderr
streams. Foreground worker start inherits the worker's streams and status in every output format.
Provider subscriptions
Section titled “Provider subscriptions”A worker may hold several subscriptions per harness, in fallback order, and names its primary in
its node.yaml. pidgen worker subscriptions <worker> shows them as the worker last advertised them,
with each one's login, entitlement, quota and pause, and pidgen worker subscriptions use <worker> <harness> <label> asks the worker, through the App Service, to make one primary
(Commands). Switching from the App Service needs the Account's
multiple_subscriptions entitlement; pidgen-worker subscriptions use on the worker itself is
always allowed. Signing in to a harness and ordering subscriptions in node.yaml happen on the
worker: see Coding agents.
Human subscription results keep connection and advertisement state, primary and active labels,
login errors, entitlement, quota observations and pause windows. Quota summaries retain observation
ages alongside the complete timestamps and reset information. A change with outcome: unknown
keeps its detail and asks you to check subscriptions before retrying; the command's original exit
status is preserved.
Verifying where the worker came from
Section titled “Verifying where the worker came from”pidgen worker install, pidgen worker update and pidgen worker verify verify the wheel and the
container image as described here. Every worker wheel is uploaded with its PEP 740 attestation by
the release workflow; a wheel without one is refused with PROVENANCE_INVALID.
The CLI trusts a publisher identity it carries, not the server. Every worker release is signed through Sigstore by Pidgen's release process, and the CLI accepts a wheel or image only when that signature verifies against the identity it carries and covers exactly the artifact it downloaded. The server names only the series to install; the file and its digest come from the package index, and neither is trusted until the attestation verifies.
- The Python package. The CLI computes the sha256 of the exact wheel it downloaded, fetches that file's PEP 740 attestation from PyPI, verifies the attestation's Sigstore bundle, checks it was signed by the release identity, and checks that it attests this file's name and sha256.
- The container image. The CLI runs
cosign verify --certificate-oidc-issuer <issuer> --certificate-identity-regexp <subject> <image>@<digest>and accepts only a passing result for that digest; the image is then pulled by the digest, and only that digest is ever run.cosignmust be installed for the container runtime; without it the CLI exits 2 withRUNTIME_UNAVAILABLE(orCOSIGN_NOT_FOUNDwhen it disappears mid-command). Verifying the registry's signatures withoutcosignis planned.
Anything else is refused with exit 5 and PROVENANCE_INVALID. error.details.check names what
failed:
check |
Meaning |
|---|---|
attestation |
The artifact has no attestation or signature, or it is not a PyPI publish attestation |
signature |
The Sigstore bundle or cosign signature does not verify |
identity |
It was signed by an identity other than the worker's release workflow; details.accepted lists the accepted ones |
digest |
The signature covers a different file or digest than the one downloaded, or than the release names |
reference |
The image reference is not a plain repository reference |
There is no flag or setting that turns verification off.
Why the CLI does not bundle the worker
Section titled “Why the CLI does not bundle the worker”The worker is closed source and released on its own schedule, and the App Service decides which worker versions it accepts. The server's release list names the releases it accepts, and the CLI installs one only after verifying that the worker's release workflow signed it.