@orchestraworks/worker 0.0.136 → 0.0.138

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/bin/worker.js CHANGED
@@ -53,11 +53,13 @@ function statusFor(code, signal) {
53
53
  }
54
54
 
55
55
  function run(binary) {
56
- const child = spawn(binary, process.argv.slice(2), { stdio: "inherit" });
57
-
56
+ let child;
57
+ // Listening at all is what stops Node ending the launcher on its own and orphaning the worker
58
+ // mid-shutdown: the launcher outlives the signal and exits on the child's exit instead. The listeners go
59
+ // in before the spawn: the binary runs from the moment spawn returns, and a signal that reached the
60
+ // launcher before its listeners would kill it. Node runs a listener from the event loop, so by then
61
+ // `child` is set.
58
62
  for (const signal of FORWARDED_SIGNALS) {
59
- // Listening at all is what stops Node ending the launcher on its own and orphaning the worker
60
- // mid-shutdown: the launcher outlives the signal and exits on the child's exit instead.
61
63
  process.on(signal, () => {
62
64
  if (child.exitCode === null && child.signalCode === null) {
63
65
  child.kill(signal);
@@ -65,6 +67,8 @@ function run(binary) {
65
67
  });
66
68
  }
67
69
 
70
+ child = spawn(binary, process.argv.slice(2), { stdio: "inherit" });
71
+
68
72
  child.on("error", (failure) => {
69
73
  console.error(`worker: ${failure.message}`);
70
74
  process.exit(1);
package/docs/REFERENCE.md CHANGED
@@ -204,7 +204,7 @@ set is a concern this machine does not have.
204
204
  | `SFDK_EGRESS_LISTEN_PORT` | where the redirect lands, which is the shim's own listen port |
205
205
  | `SFDK_EGRESS_IPV6` | `true` mirrors the redirect through `ip6tables` |
206
206
  | `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 |
207
- | `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 |
207
+ | `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 with `SFDK_EGRESS_PROXY=off` a pair replaces a name that holds exactly the image's egress placeholder |
208
208
  | `SFDK_VOLUME_MOUNTS` | the volumes this launch declares, as one JSON document |
209
209
  | `SFDK_MACHINE_SLUG` | the machine's platform-minted slug: the leading label of its preview hostnames, and what the tunnel's upgrade signs |
210
210
  | `SFDK_TUNNEL_ENDPOINT_URL` | where the preview gateway serves its tunnel listener; its scheme is the whole TLS statement for that hop |
@@ -213,7 +213,11 @@ set is a concern this machine does not have.
213
213
 
214
214
  **The worker reads that file itself, on every operating system, and no service manager is handed it.**
215
215
  Every `worker run` places each pair into its own environment before it serves, leaving alone any name
216
- that is already set, so a person's own foreground run still wins over the file. systemd's
216
+ that is already set, so a person's own foreground run still wins over the file. One name already set
217
+ is replaced: where the switch `SFDK_EGRESS_PROXY` is `off`, no edge replaces the image's placeholder
218
+ credential on the way out, so a value the launch declared replaces a name that holds exactly a
219
+ placeholder the family facts list. That is how a customer's own token in `provisionSpec.env` reaches the
220
+ harness on a Launcher machine; it rides the machine's startup data in plain text. systemd's
217
221
  `EnvironmentFile=` is deliberately not used: it processes backslash escapes in an unquoted value, so
218
222
  the two characters `\n` that carry a line break inside `SFDK_RUNTIME_ENVIRONMENT` would arrive as a bare
219
223
  `n` and the certificate folded in there would hold no certificate at all. A machine with no file
@@ -429,36 +433,36 @@ not an override: the variable never reaches the command, and a job running under
429
433
  first reference to it. Per-job configuration travels the prompt, the agent's instructions, or a file in the
430
434
  image.
431
435
 
436
+ The worker consumes every `ORCHESTRA_WORKER_<FIELD>` variable itself and drops it from every list,
437
+ `SFDK_EXTRA_PASSENV` included: those are the sign-in and settings the worker places for the harness, from the
438
+ `settings` table of `facts/families.json` (`docs/architecture/agent-runtime-images.md` § *The worker places
439
+ each harness's sign-in and settings*).
440
+
432
441
  Every family's harness process also gets `SFDK_SESSION_ID`, which the worker sets from the `sessionId` on
433
442
  `session_placement.apply`: the worker adds it itself, so it needs no `passEnv` entry, whatever the worker's
434
443
  own environment holds. The `script` family adds only the organization to the command it runs, as
435
444
  `ORCHESTRA_ORGANIZATION_ID` and `SFDK_ORGANIZATION_ID`, from its stored conversation metadata; its command inherits
436
445
  the session variable from the harness process. Neither grants egress authority.
437
446
 
438
- **On Windows that list is shorter than the operating system's own habits assume.** It is
439
- OS-independent, so a Windows job sees `PATH`, `HOME` and `USERPROFILE` and *not* `TEMP`, `APPDATA` or
440
- `ComSpec` — names a PowerShell one-liner reaches for without thinking (`$env:TEMP`). The list is not a
441
- filter over the environment: the worker *builds* the child's environment from it, so a name the platform
442
- set on the service and the family does not declare is simply gone by the time the command runs.
443
-
444
- **Three names are backfilled for Windows and none of them is on any family's list.** A backfill is the
445
- treatment for operating-system *plumbing* — a variable the machine needs to work at all, as opposed to
446
- configuration a customer chose — and it is if-absent, so a declared spelling always wins. Two come from
447
- libraries: Go's `os/exec` adds `SYSTEMROOT` whenever a caller sets an explicit environment, and libuv copies
448
- its own required-variable set into a spawned child from *this* process's environment — which is why `PATH`
449
- reaching the command is what lets `powershell.exe` and `taskkill.exe` resolve at all. The third is ours:
450
- **`PATHEXT`**, the list of extensions PowerShell treats as *executable*. With it unset the effective list
451
- collapses to `.CPL`, so a `curl.exe` PowerShell resolved on `PATH` is a **document** rather than a program
452
- and invoking it throws `CantActivateDocumentInPipeline` — before a process starts, before a packet leaves.
453
- Every network probe on the Windows lane came back `000`, which reads exactly like a blocked connection.
454
-
455
- The neighbours a reader expects beside it were **measured and left out**, each changing nothing on a Windows
456
- Server 2025 runtime AMI: `cmd.exe` and `.bat` files run from CreateProcess's own default without `ComSpec`,
457
- `%SystemRoot%` expands from the `SYSTEMROOT` `os/exec` already backfills, `SystemDrive` and `windir` are
458
- unused by realistic work, and a service's temp directory falls back to `C:\Windows\SystemTemp` without
459
- `TEMP` or `TMP`. Add a fourth name only with that kind of evidence. Machine plumbing is not configuration
460
- and must never be pushed into the prompt: a job cannot set `PATHEXT` for a shell that has already refused to
461
- start its first program.
447
+ **On Windows the operating system's own variables are added to that list.** The list is not a filter over
448
+ the environment: the worker *builds* the child's environment from it, so a name the platform set on the
449
+ service and the family does not declare is simply gone by the time the command runs. Windows programs
450
+ assume their own variables are there, so the worker adds them from its own environment to every harness,
451
+ and so to every hook and command the harness starts, and to the setup script: `WINDIR`, `SYSTEMROOT`,
452
+ `SYSTEMDRIVE`, `COMSPEC`, `PATHEXT`, `TEMP`, `TMP`, `PROGRAMDATA`, `ALLUSERSPROFILE`, `ProgramFiles`,
453
+ `ProgramFiles(x86)`, `ProgramW6432`, `CommonProgramFiles`, `CommonProgramFiles(x86)`, `CommonProgramW6432`,
454
+ `APPDATA`, `LOCALAPPDATA`, `USERNAME`, `USERDOMAIN`, `COMPUTERNAME`, `OS`, `PROCESSOR_ARCHITECTURE`,
455
+ `NUMBER_OF_PROCESSORS`, `PSModulePath` and `DriverData`. None of them carries a credential, and a name the
456
+ family or the launch already declares, in any spelling, is not added twice.
457
+
458
+ Two failures show why. With **`PATHEXT`** unset, PowerShell's list of executable extensions collapses to
459
+ `.CPL`, so a `curl.exe` it resolved on `PATH` is a **document** rather than a program and invoking it throws
460
+ `CantActivateDocumentInPipeline` — before a process starts, before a packet leaves. With **`WINDIR`** unset,
461
+ `Import-Module Storage` looks for its library under `C:\system32` rather than `C:\Windows\system32`, so
462
+ `Mount-DiskImage` and `Get-Volume` fail. On Windows the harness runs as the worker's own account, so the
463
+ per-user names (`TEMP`, `APPDATA`, `USERNAME`) are that account's own. Machine plumbing is not
464
+ configuration and must never be pushed into the prompt: a job cannot set `PATHEXT` for a shell that has
465
+ already refused to start its first program.
462
466
 
463
467
  Three more bounds a job author should know:
464
468
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestraworks/worker",
3
- "version": "0.0.136",
3
+ "version": "0.0.138",
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.136",
26
- "@orchestraworks/worker-linux-arm64": "0.0.136",
27
- "@orchestraworks/worker-darwin-x64": "0.0.136",
28
- "@orchestraworks/worker-darwin-arm64": "0.0.136",
29
- "@orchestraworks/worker-win32-x64": "0.0.136"
25
+ "@orchestraworks/worker-linux-x64": "0.0.138",
26
+ "@orchestraworks/worker-linux-arm64": "0.0.138",
27
+ "@orchestraworks/worker-darwin-x64": "0.0.138",
28
+ "@orchestraworks/worker-darwin-arm64": "0.0.138",
29
+ "@orchestraworks/worker-win32-x64": "0.0.138"
30
30
  }
31
31
  }