# Node Runtime Startup

Status: P193 source contract.

Oysterun service startup requires Node.js >=20. The public commands remain:

```text
oysterun service:start
oysterun service:restart
oysterun service:restart --restore-sessions
oysterun service:install
```

The npm `oysterun` command itself still uses `#!/usr/bin/env node`, so the
invoking shell must be able to start Node before JavaScript code can run.
Service scripts add a second runtime preflight for Host-managed paths.

## Resolution Order

Service installation intentionally resolves a Node migration in this order:

1. `OYSTERUN_NODE_BIN`, when it is set to an executable file.
2. `command -v node`.
3. `which node`.
4. Common install paths:
   - `/opt/homebrew/bin/node`
   - `/usr/local/bin/node`
   - `$HOME/.local/bin/node`
   - `$HOME/bin/node`

The resolved executable must report Node.js >=20 through `--version`. Missing,
non-executable, unparsable, or older Node runtimes fail before Host startup.
Diagnostics include the attempted/resolved path and version, but do not dump raw
environment variables or credentials.

After service installation, managed start, restore-aware restart, update, and
offline installed-package recovery treat the persisted absolute Node/npm
identity as authoritative. A shell-visible Node may bootstrap the public CLI
or identity reader, but it is not promoted to service identity. The reader
immediately re-executes probes with the persisted Node and matching absolute
`npm-cli.js`; a missing, moved, or mismatched persisted identity fails before
restore capture, package mutation, or Host stop.

## LaunchAgent Behavior

macOS LaunchAgents do not source interactive shell files such as `.zshrc`,
`.profile`, nvm, asdf, or volta initialization scripts. During
`oysterun service:install`, Oysterun writes the resolved Node path into the
LaunchAgent as `OYSTERUN_NODE_BIN`. Service install also resolves the npm CLI
owned by that Node installation and atomically persists the combined identity
described in `docs/routec/dev/host_update_runtime_identity.md`.

The LaunchAgent `PATH` and the pid-file/direct Host `PATH` are generated by
the provider resolver documented in
`docs/routec/dev/provider_command_resolution.md`. Both include the resolved
Node directory and resolved Claude/Codex directories without sourcing shell
profiles or maintaining a second hard-coded provider candidate list.

If that path later disappears or stops being executable, the service fails with
a bounded diagnostic. Reinstall/update the service or set `OYSTERUN_NODE_BIN`
to a valid Node.js >=20 executable before retrying.

## Update And Restart Jobs

Host Preferences update/restart jobs do not rely on `oysterun` being discoverable
on `PATH`. Package staging and activation run the persisted absolute matching
npm CLI through the absolute Host Node; PATH-selected npm is forbidden. They
schedule restart through an absolute Node executable and the absolute `bin/oysterun.mjs`
path while preserving the active stack through
`OYSTERUN_RELEASE_STACK` and `OYSTERUN_STACK`.

The canonical provider launch-path resolver also supplies the lifecycle tool
environment, including `/usr/sbin` and `/sbin` on macOS. Listener ownership is
OS-specific and numeric-only: macOS uses absolute system `lsof`; Linux uses its
supported `ss` or `fuser` route. An unavailable or ambiguous detector fails
closed while the healthy Host remains running.
