@orchestraworks/worker 0.0.141 → 0.0.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,18 +41,19 @@ Run it once, as root on Linux or as an administrator on Windows, on a host that
41
41
  Each step reads what is there, changes only what is different, and prints `ok: <step>` or
42
42
  `changed: <step>`. The first failure stops the run and names the step. You can run it again.
43
43
 
44
- `<root>` is the machine-wide root: `/var/lib/sfdk/worker` on Linux, `%ProgramData%\sfdk\worker` on Windows.
44
+ `<root>` is the machine-wide root: `/var/lib/orchestra/worker` on Linux, `%ProgramData%\orchestra\worker` on Windows.
45
+ A host where an earlier release installed the worker keeps its root at `/var/lib/sfdk/worker` or `%ProgramData%\sfdk\worker`.
45
46
 
46
47
  | Step | When | What it does |
47
48
  |---|---|---|
48
- | preconditions | always | Refuses a host it is not written for. Refuses a host that has booted as a machine: a boot file or `<root>/state` is there. Refuses a running worker service. |
49
+ | preconditions | always | Refuses a host it is not written for. Refuses a host that has booted as a machine: a boot file or `<root>/state` is there. Refuses a running worker service, under its name or the name an earlier release used. |
49
50
  | directories | Windows | Creates `<root>`, `C:\software-factory` and its `etc` folder for SYSTEM and Administrators only. Users can also read and run `C:\software-factory`, which holds the programs on the machine path. A folder that is already there is kept as it is. |
50
51
  | package | always | Copies this release package to `<root>/package`. The service runs from there, because a self-update replaces the package directory. |
51
52
  | agent account | Linux | Creates the `agent` account, uid and gid 1000, home `/home`, and gives `/home` to it. Another account at uid 1000 is kept. |
52
53
  | harnesses | `--harness` | Installs the named harness families and their Node under the root. `none` or no flag installs none: a family installs itself on its first turn, in about a minute. |
53
- | service | always | Defines the service, `SfdkWorker` on Windows and `sfdk-worker.service` on Linux. It restarts after a failure. The step does not start it. |
54
+ | service | always | Removes the service an earlier release registered, then defines the service, `OrchestraWorker` on Windows and `orchestra-worker.service` on Linux. It restarts after a failure. The step does not start it. |
54
55
  | cloud | always | `azure`: at each boot, the start-up task runs `worker boot-files --cloud azure`, which writes the boot files from the VM's userData, and then the worker starts. `aws`: the worker starts at each boot, after the platform's user data, and an Azure start-up task or unit from an earlier run is removed. |
55
- | egress redirect | `--egress-redirect` | WinDivert and its inbound firewall rule on Windows, `iptables` on Linux. A Launcher machine does not need it. |
56
+ | egress redirect | `--egress-redirect` | WinDivert and its inbound firewall rule on Windows. On Linux it installs nothing: it checks that the kernel carries the nftables parts the worker's redirect needs, and loads `nf_conntrack`. A Launcher machine does not need it. |
56
57
  | Docker | `--docker` | Windows containers, or rootless Docker for the `agent` account. |
57
58
  | Node | `--node` | The agent's own Node, on the machine path. On Windows a new Node keeps the packages that `npm install -g` put in its folder. |
58
59
  | check | always | Runs `worker check --profile launcher` for `azure`, and `--profile enrolled` for `aws`. |
@@ -104,7 +105,7 @@ The machine must reach these hosts. The command does not test them:
104
105
  This command shows `"restartPending":false` when none is:
105
106
 
106
107
  ```powershell
107
- & "$env:ProgramData\sfdk\worker\package\worker.exe" check --profile launcher --output json
108
+ & "$env:ProgramData\orchestra\worker\package\worker.exe" check --profile launcher --output json
108
109
  ```
109
110
 
110
111
  6. Generalize with Sysprep:
@@ -177,6 +178,14 @@ The machine must reach these hosts. The command does not test them:
177
178
  If the image serves an app, end your own boot step with one request to the app. The first request after
178
179
  a boot is slow, so this request takes that delay instead of the first user.
179
180
 
181
+ ### The worker's service name
182
+
183
+ The worker's service is `OrchestraWorker` on Windows, `orchestra-worker.service` on Linux and
184
+ `ai.livingcomputers.orchestra.worker` on macOS. An install replaces the service an earlier release registered
185
+ as `SfdkWorker`, `sfdk-worker.service` or `ai.livingcomputers.sfdk.worker`. Change your own scripts that name
186
+ it. An image an earlier release built keeps its service after a self-update, and
187
+ its start-up task still starts it.
188
+
180
189
  ### The model key and other tokens
181
190
 
182
191
  Give the agent its model key in one of three ways. Each works on every machine, with or without our
@@ -187,9 +196,9 @@ egress edge. The edge and its Secrets are an addition, never needed for your own
187
196
  an environment read returns them, and the VM's startup data carries them. If that is not acceptable,
188
197
  use route 2 or 3, or a Secret at our egress edge where one stands in front.
189
198
  2. **Baked into the image**, at machine scope, before Sysprep or generalizing. On Windows, that is the
190
- `Environment` value (a multi-string) of `HKLM\SYSTEM\CurrentControlSet\Services\SfdkWorker`. Keep
199
+ `Environment` value (a multi-string) of `HKLM\SYSTEM\CurrentControlSet\Services\OrchestraWorker`. Keep
191
200
  the entries that are there, and add or replace only yours. On Linux, it is a drop-in on
192
- `sfdk-worker.service`.
201
+ `orchestra-worker.service`.
193
202
  3. **The `onStartAgent` hook** writes the harness's own key file in the agent's home:
194
203
  `.claude/.credentials.json` for a Claude sign-in, `.codex/auth.json` for `codex`, or
195
204
  `.pi/agent/auth.json` for `pi`. The worker keeps a real value it finds there. A raw Claude API key has
@@ -205,7 +214,7 @@ The names:
205
214
  - `pi`: `ORCHESTRA_WORKER_OPENAI_API_KEY` or `ORCHESTRA_WORKER_CLAUDE_OAUTH_TOKEN`.
206
215
  `ORCHESTRA_WORKER_PI_PROVIDER` chooses the provider.
207
216
 
208
- Never restart `SfdkWorker` or `sfdk-worker.service` to load a key. A restart after the worker registered
217
+ Never restart `OrchestraWorker` or `orchestra-worker.service` to load a key. A restart after the worker registered
209
218
  stops the machine's work, and the platform parks the VM. The next message starts it again, 1 to 2
210
219
  minutes later.
211
220
 
package/docs/REFERENCE.md CHANGED
@@ -12,7 +12,7 @@ The worker exposes no API of its own. Every route it calls is the platform's.
12
12
 
13
13
  | path | what it holds |
14
14
  |---|---|
15
- | `cmd/worker/` | the one binary: `run`, `install`, `install-machine`, `boot-files`, `enroll`, `check`, `trust-nested`, `screen`, `version` |
15
+ | `cmd/worker/` | the one binary: `run`, `install`, `install-machine`, `boot-files`, `enroll`, `check`, `trust-nested`, `screen`, `redirect`, `version` |
16
16
  | `identity/` | the four identity exchanges — claim, refresh, reattach-challenge, reattach — the holder key, and the loop that keeps the machine token alive |
17
17
  | `broker/` | the protocol on the message broker: the connection, the register on every connect, the heartbeat and the status cadence, the pull of this machine's own work consumer, and the publisher every other package sends through |
18
18
  | `env/` | the machine-side environment the platform composes onto a launch, read from the names the contract declares |
@@ -21,7 +21,7 @@ The worker exposes no API of its own. Every route it calls is the platform's.
21
21
  | `process/` | the agent's setup and the harness process behind each session placement: the start, the stop and the last save a remove asks for, the startup fence over what a previous run left, and the stop of everything when the worker is told to stop |
22
22
  | `stream/` | the queue: every placement message and every prompt, steer and cancel pulled off this machine's work consumer, the ACP client that opens a session's harness conversation and runs its turns, each turn's events batched to the platform and published live, and the answer every placement message is owed |
23
23
  | `mount/` | the volumes the launch declares, placed on the lanes that mount them: the home volume first, because anything written under a mount point before the mount is hidden by it |
24
- | `network/` | the transparent redirect on the virtual-machine lanes, as the iptables rules the launch describes: what the worker's own uid reaches directly, and what every uid on the machine reaches through the egress edge |
24
+ | `network/` | the transparent redirect the launch describes, as the worker's own nftables table written over netlink with no program from the image: what the worker's own uid reaches directly, and what every uid on the machine reaches through the egress edge |
25
25
  | `shim/` | the in-guest transparent proxy: the listener the redirect lands on, the recovery of the destination each connection was actually for, the hop to the egress edge under the machine-identity proof, the WinDivert half that is the Windows redirect, and the loopback feed a separate shim reads this machine's token from |
26
26
  | `egress/` | what puts that proxy in place on the virtual-machine lanes: the edge's certificate authority in this machine's trust store, the inbound firewall rule Windows needs, the redirect itself, and the state line an operator reads off the machine's console |
27
27
  | `ingress/` | the machine's half of the preview tunnel: the connection this worker holds open to the preview gateway, the challenge and the signed upgrade that authenticate it, and the loopback pipe that carries each viewer request to a port this machine declared and refuses every other |
@@ -39,6 +39,8 @@ shapes the schema ships, and nothing here re-declares one.
39
39
 
40
40
  ## The commands
41
41
 
42
+ Each `ORCHESTRA_` machine variable this page names also has a former `SFDK_` spelling. Until the rename's compatibility period ends ([D50](../../docs/specs/2026-10-03_2446_orchestra_rename_spec.md)), the platform and the worker still write the former spelling beside the new one, and every reader takes the new name first and the former one when the new one is absent.
43
+
42
44
  - **`worker run`** claims this machine's identity — or reattaches, where its row is already bound to
43
45
  the key this machine holds — and then serves the machine. `run` hands the held identity, with the
44
46
  broker credential the claim co-issued, to the registrar seam in `cmd/worker/run.go`, which the
@@ -48,7 +50,7 @@ shapes the schema ships, and nothing here re-declares one.
48
50
  Before any of that, `run` starts what the launch describes: it places the declared volumes, puts
49
51
  the in-guest egress in place where the launch names an intercept set, opens the egress shim's token
50
52
  feed, and — on a machine the cloud can reclaim — watches for the notice that it is going away. Each
51
- is started only where it is described: a Kubernetes pod places its own volumes and its egress
53
+ is started only where it is described: an OpenSandbox pod places its own volumes and its egress
52
54
  sidecar installs its own redirect, so a launch there names neither. If one of those duties is
53
55
  installed and then dies, `run` ends rather than serving a machine the platform counts as healthy
54
56
  with no route off it; the service manager starts the worker again.
@@ -91,6 +93,13 @@ shapes the schema ships, and nothing here re-declares one.
91
93
  same answer. Nothing on a machine somebody owns needs privilege: network enforcement is outside the
92
94
  machine, at the egress edge and the directional security group.
93
95
 
96
+ **An install replaces the service an earlier release registered.** It first stops and deletes that
97
+ service in the scope this install registers in. On Windows, the earlier service is the `SfdkWorker`
98
+ service in system scope, or the `SfdkWorker` logon task in user scope. On Linux, the earlier service
99
+ is the `sfdk-worker.service` unit, and on macOS the `ai.livingcomputers.sfdk.worker` job. Then the install
100
+ defines `OrchestraWorker`, `orchestra-worker.service` or `ai.livingcomputers.orchestra.worker`. When the
101
+ removal fails, the install stops and defines nothing new. Change your own scripts that name the old ones.
102
+
94
103
  **The machine-wide service is the image role's, and the role is the whole of what asks for it.** An
95
104
  `image` gets it — a property list under `/Library/LaunchDaemons`, a unit under `/etc/systemd/system`,
96
105
  a Windows service — because the platform builds the image with nobody logged in to it and nobody
@@ -98,8 +107,10 @@ shapes the schema ships, and nothing here re-declares one.
98
107
  virtual-machine image is made by `worker install-machine` below, which our bakes run; the `image` role
99
108
  stays for a container image, whose own command is the worker.
100
109
 
101
- `--root` follows the scope the same way: `~/.sfdk/worker` (`%LOCALAPPDATA%\sfdk\worker` on Windows) for
102
- a `user` install, `/var/lib/sfdk/worker` (`%ProgramData%\sfdk\worker`) for the other two. A `user`
110
+ `--root` follows the scope the same way: `~/.orchestra/worker` (`%LOCALAPPDATA%\orchestra\worker` on
111
+ Windows) for a `user` install, `/var/lib/orchestra/worker` (`%ProgramData%\orchestra\worker`) for the other
112
+ two. Where the earlier release's root already holds the worker's identity or its install, the
113
+ install keeps that root instead. A `user`
103
114
  install writes its log under that root, at `log/worker.log`, because no service manager in that scope
104
115
  keeps one a person can read.
105
116
 
@@ -145,12 +156,14 @@ shapes the schema ships, and nothing here re-declares one.
145
156
  `--root` and installs under the machine-wide root. Each step reads the current state, changes only what
146
157
  differs, reads the result back and prints `ok: <step>` or `changed: <step>`; the first failure stops the
147
158
  run. So a second run on a converged host changes nothing, and a run that stopped part way is repaired by
148
- running it again. It refuses a host that has already booted as a machine — a boot file or `<root>/state`
149
- is there — because removing one is not a repair, and it refuses a running worker service. On Windows it
150
- creates `<root>`, the install root `C:\software-factory` and its `etc` folder for SYSTEM and
151
- Administrators alone, with Users also reading and running the install root, whose `bin` and `node` are
152
- on the machine path; a folder already there is kept, so a host that made one first keeps its
153
- permissions.
159
+ running it again. It refuses a host that has already booted as a machine, where a boot file or
160
+ `<root>/state` is there. Removing one is not a repair. It also refuses a running worker service,
161
+ under its name or the name an earlier release used. On Windows, the command creates three separate
162
+ directories: `<root>`, the install root `C:\software-factory`, and the `etc` directory in the install
163
+ root. Only SYSTEM and Administrators may use these three directories. Users may also read and run the
164
+ install root, whose `bin` and `node` directories are on the machine path. The command keeps a
165
+ directory that is already there, with that directory's permissions. The service step
166
+ removes a service with the earlier release's name, then defines the new one.
154
167
 
155
168
  The service runs from a copy of the release package at `<root>/package`, because the self-update
156
169
  replaces the directory the running binary sits in; the step compares that copy's `worker version`
@@ -178,7 +191,7 @@ shapes the schema ships, and nothing here re-declares one.
178
191
  this boot does not carry is removed, so a resumed VM never reads its previous launch's file. Each file
179
192
  is written under a staged name of its own, created new with its permissions before any byte, and
180
193
  renamed into place: on Linux at modes `0600`, `0600` and `0644`, the egress authority being the one the
181
- agent's programs read, and on Windows readable by SYSTEM and Administrators alone. On Windows it starts `SfdkWorker` last; on Linux systemd starts the worker's unit after this one ends.
194
+ agent's programs read, and on Windows readable by SYSTEM and Administrators alone. On Windows it starts `OrchestraWorker` last, or `SfdkWorker` on an image an earlier release built; on Linux systemd starts the worker's unit after this one ends.
182
195
  - **`worker enroll`** redeems the enrollment token this machine was given, prints the row it was
183
196
  issued, and then serves that machine. It does not stop at the redemption, because the holder key
184
197
  the redemption bound lives in this process.
@@ -213,11 +226,15 @@ shapes the schema ships, and nothing here re-declares one.
213
226
  A pending restart is reported and never refused: Sysprep refuses to generalize while one is pending.
214
227
  - **`worker trust-nested [--registry <host>]... [--root <dir>]`** lets the containers this machine
215
228
  runs trust the egress edge, which nothing does by default. It reads the authority from
216
- `SFDK_EGRESS_CA_FILE`, which the worker sets on every harness process and on the setup script;
229
+ `ORCHESTRA_EGRESS_CA_FILE`, which the worker sets on every harness process and on the setup script;
217
230
  writes it into dockerd's `certs.d` for the well-known registries and each one named; writes
218
231
  `k3d-registries.yaml` under the root, whose `ca_file` is the authority's path inside each k3d node;
219
232
  and prints the flags `docker run`, compose and `k3d cluster create` need. On a machine that names no
220
233
  authority, such as one with no edge in front of it, it says so, writes nothing and succeeds.
234
+ - **`worker redirect`** prints the redirect table this worker wrote, or says that none is installed;
235
+ **`worker redirect remove`** deletes it. Each runs with its caller's own rights, so without
236
+ `CAP_NET_ADMIN` the kernel refuses both, and each exits 0 on an answer and 1 on a failure. Off Linux
237
+ both refuse, naming the operating system. What the table holds is under the in-guest egress below.
221
238
  - **`worker version`** prints this binary's version, the release package it belongs to, and the
222
239
  protocol versions it speaks.
223
240
 
@@ -228,43 +245,46 @@ version it is not.
228
245
  ## The bootstrap a machine is started with
229
246
 
230
247
  Everything above assumes the worker already knows where its platform is. That is the one family of
231
- names it reads before it can speak to anything, so they are the worker's own rather than the
232
- contract's: the environment document owns the other `SFDK_` names the platform or the worker sets for a
233
- running machine and says these are outside its scope. They carry the same reserved prefix, so an environment
234
- cannot declare one; the only `SFDK_` names an environment may declare are the release settings
235
- `fwp/schema/environment-v1.json` lists under `customerDeclarable`, which the worker reads from its own
236
- environment in preference to the register answer. The platform composes what is listed here; a value it does not
237
- set is a concern this machine does not have.
248
+ names it reads before it can speak to anything. `fwp/schema/environment-v1.json` lists them in its
249
+ `bootstrap` list, apart from the other names the platform or the worker sets for a running machine. The
250
+ table below gives each in its former spelling. Each also has a name under `ORCHESTRA_WORKER_`, the
251
+ document's `name`, which the worker reads first; it reads the former spelling when the new one is absent
252
+ or blank. The two enrollment carriers are read under their former spelling alone for now. An
253
+ environment cannot declare a name under `SFDK_` or `ORCHESTRA_`, apart from the release settings the
254
+ document lists under `customerDeclarable`, which the worker reads from its own environment in preference to
255
+ the register answer. The platform composes what is listed here; a value it does not set is a concern this
256
+ machine does not have.
238
257
 
239
258
  | name | what it carries |
240
259
  |---|---|
241
- | `SFDK_CLAIM_ENDPOINT_URL` | the platform's origin, not a route: the paths belong to the protocol |
242
- | `SFDK_TRANSPORT_TRUST_ROOTS` | the certificate bundle this machine trusts, inline |
243
- | `SFDK_TRANSPORT_TRUST_ROOTS_FILE` | the same bundle as an absolute path, for a delivery that cannot carry the newlines; setting both is refused |
244
- | `SFDK_CLAIM_LOCATOR` | the machine row this worker claims as |
245
- | `SFDK_ENROLLMENT_TOKEN` | the show-once token an enrolling machine redeems; mutually exclusive with the locator |
246
- | `SFDK_ENROLLMENT_TOKEN_FILE` | the same token as an absolute path; setting both is refused |
247
- | `SFDK_HOLDER_KEY_ALGORITHM` | which of the protocol's two holder-key algorithms this registration declares |
248
- | `SFDK_SUBSTRATE` | which evidence this worker gathers, so an unknown value is refused rather than defaulted |
249
- | `SFDK_CLAIM_AUDIENCE` | who the presented caller-identity request was meant for; required on the virtual-machine lanes |
250
- | `SFDK_STS_ENDPOINT_URL` | the security-token endpoint the platform will send that request to |
251
- | `SFDK_SERVICE_ACCOUNT_TOKEN_FILE` | where the audience-bound projected token is mounted, on the Kubernetes lane |
252
- | `SFDK_TPM_DEVICE_PATH` | the chip's device path where it is not this operating system's default |
253
- | `SFDK_SUBSTRATE_TOKEN` | the `local` substrate's stand-in factor, inline |
254
- | `SFDK_SUBSTRATE_TOKEN_FILE` | the same factor as an absolute path; setting both is refused |
255
- | `SFDK_INTERCEPT_PORTS` | the destination ports whose traffic goes to the egress edge, comma separated; naming none installs no redirect |
256
- | `SFDK_INTERCEPT_BYPASS` | the shared services the worker's own uid reaches directly, as `[{"host": …, "port": …}]` — our broker and our gateway, and nothing broader |
257
- | `SFDK_INTERCEPT_SKIP_RANGES` | the private ranges the redirect never takes, for any uid on any port, as comma-separated CIDR ranges; a range that is not wholly private is refused |
258
- | `SFDK_EDGE_ENDPOINT_URL` | where the redirect sends this machine's traffic; its scheme is the whole TLS statement for that hop |
259
- | `SFDK_EGRESS_LISTEN_PORT` | where the redirect lands, which is the shim's own listen port |
260
- | `SFDK_EGRESS_IPV6` | `true` mirrors the redirect through `ip6tables` |
261
- | `SFDK_EGRESS_PROXY` | `on`, the default, or `off`; `off` tells each harness that no edge of ours stands in front of this machine, as on an enrolled one. The platform writes `off` into every Launcher machine's boot file, because no proxy entrance of ours stands in front of one yet |
262
- | `SFDK_RUNTIME_ENVIRONMENT` | a whole environment folded into one JSON object of string values, for a boot file whose lines cannot carry a line break; each pair is placed unless already set, except that a non-blank pair replaces a name that holds exactly the image's placeholder |
263
- | `SFDK_VOLUME_MOUNTS` | the volumes this launch declares, as one JSON document |
264
- | `SFDK_MACHINE_SLUG` | the machine's platform-minted slug: the leading label of its preview hostnames, and what the tunnel's upgrade signs |
265
- | `SFDK_TUNNEL_ENDPOINT_URL` | where the preview gateway serves its tunnel listener; its scheme is the whole TLS statement for that hop |
266
- | `SFDK_INGRESS_PORTS` | the loopback ports this machine projects through that tunnel, comma separated; with no reserved ports below, naming none holds no tunnel |
267
- | `SFDK_INGRESS_ANY_PORT_EXCEPT` | the reserved loopback ports, comma separated; set, the tunnel is held from start, forwards every other port whatever `SFDK_INGRESS_PORTS` says, and the worker registers `ingress-any-port` |
260
+ | `ORCHESTRA_WORKER_CLAIM_ENDPOINT_URL` | the platform's origin, not a route: the paths belong to the protocol |
261
+ | `ORCHESTRA_WORKER_TRANSPORT_TRUST_ROOTS` | the certificate bundle this machine trusts, inline |
262
+ | `ORCHESTRA_WORKER_TRANSPORT_TRUST_ROOTS_FILE` | the same bundle as an absolute path, for a delivery that cannot carry the newlines; setting both is refused |
263
+ | `ORCHESTRA_WORKER_CLAIM_LOCATOR` | the machine row this worker claims as |
264
+ | `ORCHESTRA_WORKER_ENROLLMENT_TOKEN` | the show-once token an enrolling machine redeems; mutually exclusive with the locator |
265
+ | `ORCHESTRA_WORKER_ENROLLMENT_TOKEN_FILE` | the same token as an absolute path; setting both is refused |
266
+ | `ORCHESTRA_WORKER_HOLDER_KEY_ALGORITHM` | which of the protocol's two holder-key algorithms this registration declares |
267
+ | `ORCHESTRA_WORKER_SUBSTRATE` | which evidence this worker gathers, so an unknown value is refused rather than defaulted |
268
+ | `ORCHESTRA_WORKER_CLAIM_AUDIENCE` | who the presented caller-identity request was meant for; required on the virtual-machine lanes |
269
+ | `ORCHESTRA_WORKER_STS_ENDPOINT_URL` | the security-token endpoint the platform will send that request to |
270
+ | `ORCHESTRA_WORKER_SERVICE_ACCOUNT_TOKEN_FILE` | where the audience-bound projected token is mounted, on the Kubernetes lane |
271
+ | `ORCHESTRA_WORKER_TPM_DEVICE_PATH` | the chip's device path where it is not this operating system's default |
272
+ | `ORCHESTRA_WORKER_SUBSTRATE_TOKEN` | the `local` substrate's stand-in factor, inline |
273
+ | `ORCHESTRA_WORKER_SUBSTRATE_TOKEN_FILE` | the same factor as an absolute path; setting both is refused |
274
+ | `ORCHESTRA_WORKER_INTERCEPT_PORTS` | the destination ports whose traffic goes to the egress edge, comma separated; naming none installs no redirect |
275
+ | `ORCHESTRA_WORKER_INTERCEPT_BYPASS` | the shared services the worker's own uid reaches directly, as `[{"host": …, "port": …}]` — our broker and our gateway, and nothing broader |
276
+ | `ORCHESTRA_WORKER_INTERCEPT_SKIP_RANGES` | the private ranges the redirect never takes, for any uid on any port, as comma-separated CIDR ranges; a range that is not wholly private is refused |
277
+ | `ORCHESTRA_WORKER_EDGE_ENDPOINT_URL` | where the redirect sends this machine's traffic; its scheme is the whole TLS statement for that hop |
278
+ | `ORCHESTRA_WORKER_EGRESS_LISTEN_PORT` | where the redirect lands, which is the shim's own listen port |
279
+ | `ORCHESTRA_WORKER_EGRESS_IPV6` | `true` also writes the worker's redirect table for IPv6 |
280
+ | `ORCHESTRA_WORKER_EGRESS_PROXY` | `on`, the default, or `off`; `off` tells each harness that no edge of ours stands in front of this machine, as on an enrolled one. The platform writes `off` into a Launcher machine's boot file only where the deployment names no public egress entrance |
281
+ | `ORCHESTRA_WORKER_LAUNCHER` | `true` on a machine a customer's Launcher created, written by that boot file alone; absent or `false` elsewhere. Such a machine with no `egress-redirect` file under the worker root runs the local egress port on loopback with no redirect |
282
+ | `ORCHESTRA_WORKER_RUNTIME_ENVIRONMENT` | a whole environment folded into one JSON object of string values, for a boot file whose lines cannot carry a line break; each pair is placed unless already set, except that a non-blank pair replaces a name that holds exactly the image's placeholder |
283
+ | `ORCHESTRA_WORKER_VOLUME_MOUNTS` | the volumes this launch declares, as one JSON document |
284
+ | `ORCHESTRA_WORKER_MACHINE_SLUG` | the machine's platform-minted slug: the leading label of its preview hostnames, and what the tunnel's upgrade signs |
285
+ | `ORCHESTRA_WORKER_TUNNEL_ENDPOINT_URL` | where the preview gateway serves its tunnel listener; its scheme is the whole TLS statement for that hop |
286
+ | `ORCHESTRA_WORKER_INGRESS_PORTS` | the loopback ports this machine projects through that tunnel, comma separated; with no reserved ports below, naming none holds no tunnel |
287
+ | `ORCHESTRA_WORKER_INGRESS_ANY_PORT_EXCEPT` | the reserved loopback ports, comma separated; set, the tunnel is held from start, forwards every other port whatever `ORCHESTRA_WORKER_INGRESS_PORTS` says, and the worker registers `ingress-any-port` |
268
288
 
269
289
  **The worker reads that file itself, on every operating system, and no service manager is handed it.**
270
290
  Every `worker run` places each pair into its own environment before it serves, leaving alone any name
@@ -274,16 +294,17 @@ a placeholder the family facts list, whether or not an egress edge stands in fro
274
294
  customer's own token in `provisionSpec.env` reaches the harness; it rides the machine's startup data in
275
295
  plain text. systemd's
276
296
  `EnvironmentFile=` is deliberately not used: it processes backslash escapes in an unquoted value, so
277
- the two characters `\n` that carry a line break inside `SFDK_RUNTIME_ENVIRONMENT` would arrive as a bare
297
+ the two characters `\n` that carry a line break inside `ORCHESTRA_WORKER_RUNTIME_ENVIRONMENT` would arrive as a bare
278
298
  `n` and the certificate folded in there would hold no certificate at all. A machine with no file
279
299
  starts anyway — that is an enrolled machine's ordinary start — and a line that is not `NAME=VALUE`
280
300
  stops the start and is named.
281
301
 
282
302
  Where the file sits is the one thing that differs, and only because of who may write it. On a Linux
283
- machine the platform launched, cloud-init writes `/etc/sfdk/machine.env` from the user data and the run
303
+ machine the platform launched, cloud-init writes `/etc/orchestra/machine.env`, and `/etc/sfdk/machine.env` for a worker
304
+ of an earlier release, from the user data and the run
284
305
  reads it; on an Azure machine `worker boot-files` writes the same file from the VM's userData, and
285
306
  `<root>\machine.env` on Windows. No install by a person writes there. A `worker` install that registers a service writes
286
- `<root>/machine.env` under the worker's own root — `C:\ProgramData\sfdk\worker\machine.env` on a default
307
+ `<root>/machine.env` under the worker's own root — `C:\ProgramData\orchestra\worker\machine.env` on a default
287
308
  machine-wide Windows install — because an install that registers the worker in one person's own session
288
309
  cannot write under `/etc`. A Linux run reads both, the machine-wide one first. The platform's user data writes that file on a machine
289
310
  it launched, and a person enrolling one writes it or exports the same names in the shell that runs
@@ -303,8 +324,8 @@ rather than woken, and its row is fresh with it.
303
324
 
304
325
  ## The in-guest egress
305
326
 
306
- On the virtual-machine lanes this worker's own process is the transparent proxy, and it puts three
307
- things in place in one order that is not interchangeable:
327
+ Wherever the launch names an intercept set, this worker's own process is the transparent proxy, and
328
+ it puts three things in place in one order that is not interchangeable:
308
329
 
309
330
  1. **The edge's certificate authority into this machine's trust store**, from the file the launch
310
331
  wrote (or, where that file is not there, from the URL it names). Windows reads the machine
@@ -315,9 +336,23 @@ things in place in one order that is not interchangeable:
315
336
  2. **The listener**, bound before any rule exists, so no connection is ever sent to a port with
316
337
  nothing behind it. On Windows an inbound firewall rule is written first as well: the rewritten
317
338
  packet arrives as an inbound connection, which Windows Server blocks by default.
318
- 3. **The redirect** — `iptables` on Ubuntu, WinDivert on Windows. The two WinDivert files are loaded
319
- by absolute path from `<root>\bin`, where `install-machine --egress-redirect` places them, and never through the
320
- operating system's own search order: opening the driver installs and starts a kernel service.
339
+ 3. **The redirect** — the worker's own nftables table on Linux, WinDivert on Windows. The two
340
+ WinDivert files are loaded by absolute path from `<root>\bin`, where `install-machine --egress-redirect`
341
+ places them, and never through the operating system's own search order: opening the driver installs and starts
342
+ a kernel service.
343
+
344
+ On Linux the worker runs no program from the image to install its redirect, so an image needs neither
345
+ `iptables` nor `nft`. It writes one table, `orchestra_worker`, in the `ip` family and, where the launch
346
+ declares IPv6, in `ip6` too, over netlink through `github.com/google/nftables`, in one transaction the
347
+ kernel takes whole or not at all. Each bypassed host is resolved once, when the table is written, and
348
+ the rules hold the addresses it resolved to then. The kernel needs nftables for each family in play
349
+ (`CONFIG_NF_TABLES` with `CONFIG_NF_TABLES_IPV4` or `_IPV6`), `CONFIG_NFT_NAT` and `CONFIG_NFT_REDIR`,
350
+ built in or as modules; a kernel missing one fails the install, and the error names the part.
351
+
352
+ The table is written once, at the start, and the running worker never writes it again, so a table
353
+ `worker redirect remove` deleted stays deleted until the next start; `worker redirect` prints it as
354
+ `nft list table` would. A worker updated in place from a release that installed `iptables` rules keeps
355
+ those rules, which `worker redirect remove` does not touch.
321
356
 
322
357
  Each accepted connection's original destination is recovered (`SO_ORIGINAL_DST` on Linux, the
323
358
  redirect's own proxy-port map on Windows; a recovery that misses is refused rather than sent to the
@@ -332,13 +367,24 @@ this worker calls it before it holds the token the edge would identify it by; an
332
367
  service, which answers the evidence that call presents. Nothing is uid-wide, so the object store
333
368
  stays intercepted and this worker's own content pulls meet the platform's rule at the edge.
334
369
 
335
- The redirect takes its Windows form on Windows and its `iptables` form everywhere else, whatever the
370
+ The redirect takes its Windows form on Windows and its nftables form everywhere else, whatever the
336
371
  substrate. A pod with an egress sidecar runs only the certificate step: the sidecar installs that
337
- lane's redirect and runs its own shim, which reads the token from the loopback feed below. A pod with
338
- no sidecar, as a customer's Launcher creates, names an intercept set and this worker installs the
339
- redirect itself.
340
-
341
- The private ranges `SFDK_INTERCEPT_SKIP_RANGES` names are never redirected, for any uid on any port:
372
+ lane's redirect and runs its own shim, which reads the token from the loopback feed below. A Launcher
373
+ machine, a Launcher pod included, names an intercept set: where `install-machine --egress-redirect`
374
+ wrote the file `egress-redirect` under the worker root this worker installs the redirect itself, and
375
+ where it did not, as on an image built before that file existed, the worker binds the local egress port
376
+ on loopback alone and each harness reaches it through the proxy names. The machine's token stays in
377
+ this worker either way.
378
+
379
+ The local egress port resolves a destination's name once. Where every address it answers is in a range
380
+ `SFDK_INTERCEPT_SKIP_RANGES` names or is a compiled-in exemption, the port dials that address itself;
381
+ otherwise it forwards the request to the edge by name. `NO_PROXY` lists the same ranges and exemptions
382
+ for a tool that reads ranges, and then names the host of `ORCHESTRA_EGRESS_CA_URL`, so a harness fetches
383
+ the edge's certificate directly rather than through an edge that may refuse it. On an Azure machine the
384
+ compiled-in exemptions are the metadata service and the platform's host address `168.63.129.16`, which
385
+ skip the redirect on Windows and on Linux.
386
+
387
+ The private ranges `ORCHESTRA_WORKER_INTERCEPT_SKIP_RANGES` names are never redirected, for any uid on any port:
342
388
  the rules return them ahead of the redirect, a nested container reaches them through its bridge, and
343
389
  the Windows filter excludes each range beside the single destinations.
344
390
 
@@ -483,21 +529,22 @@ artifacts:
483
529
 
484
530
  The worker does not *merge* an environment into a harness process: the family's `passEnv` enumeration in
485
531
  `facts/families.json` **is** that process's complete environment. An environment cannot declare an
486
- `SFDK_` name for it, because `SFDK_` is reserved apart from the four `SFDK_WORKER_*` release settings, which
532
+ `ORCHESTRA_` or `SFDK_` name for it, because both are reserved apart from `ORCHESTRA_FDK_` names and the seven
533
+ `ORCHESTRA_WORKER_*` settings, which
487
534
  reach the worker and never a harness process. A derived image that bakes a name the list does not carry, such as `ENV JOB_TARGET=…`, gets **silence**,
488
535
  not an override: the variable never reaches the command, and a job running under `set -u` aborts on the
489
536
  first reference to it. Per-job configuration travels the prompt, the agent's instructions, or a file in the
490
537
  image.
491
538
 
492
539
  The worker consumes every `ORCHESTRA_WORKER_<FIELD>` variable itself and drops it from every list,
493
- `SFDK_EXTRA_PASSENV` included: those are the sign-in and settings the worker places for the harness, from the
540
+ `ORCHESTRA_EXTRA_PASSENV` included: those are the sign-in and settings the worker places for the harness, from the
494
541
  `settings` table of `facts/families.json` (`docs/architecture/agent-runtime-images.md` § *The worker places
495
542
  each harness's sign-in and settings*).
496
543
 
497
- Every family's harness process also gets `SFDK_SESSION_ID`, which the worker sets from the `sessionId` on
544
+ Every family's harness process also gets `ORCHESTRA_SESSION_ID`, which the worker sets from the `sessionId` on
498
545
  `session_placement.apply`: the worker adds it itself, so it needs no `passEnv` entry, whatever the worker's
499
546
  own environment holds. The `script` family adds only the organization to the command it runs, as
500
- `ORCHESTRA_ORGANIZATION_ID` and `SFDK_ORGANIZATION_ID`, from its stored conversation metadata; its command inherits
547
+ `ORCHESTRA_ORGANIZATION_ID`, from its stored conversation metadata; its command inherits
501
548
  the session variable from the harness process. Neither grants egress authority.
502
549
 
503
550
  **On Windows the operating system's own variables are added to that list.** The list is not a filter over
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestraworks/worker",
3
- "version": "0.0.141",
3
+ "version": "0.0.143",
4
4
  "type": "module",
5
5
  "description": "The Orchestra worker.",
6
6
  "license": "Apache-2.0",
@@ -22,10 +22,10 @@
22
22
  "docs/REFERENCE.md"
23
23
  ],
24
24
  "optionalDependencies": {
25
- "@orchestraworks/worker-linux-x64": "0.0.141",
26
- "@orchestraworks/worker-linux-arm64": "0.0.141",
27
- "@orchestraworks/worker-darwin-x64": "0.0.141",
28
- "@orchestraworks/worker-darwin-arm64": "0.0.141",
29
- "@orchestraworks/worker-win32-x64": "0.0.141"
25
+ "@orchestraworks/worker-linux-x64": "0.0.143",
26
+ "@orchestraworks/worker-linux-arm64": "0.0.143",
27
+ "@orchestraworks/worker-darwin-x64": "0.0.143",
28
+ "@orchestraworks/worker-darwin-arm64": "0.0.143",
29
+ "@orchestraworks/worker-win32-x64": "0.0.143"
30
30
  }
31
31
  }