# Munky local runtime

Munky owns these services. An application such as Attesko embeds the released package and calls
its local HTTP contract; it does not copy the learning engine or build Munky server source.
The runtime package is separate from the cloud API and from either product installer.

## What the package contains

| File | Purpose |
| --- | --- |
| `website-task.mjs` | Local authenticated Namecheap/Railway inspection; no DNS mutation entry point |
| `core.mjs` | Local identity, learning, task authority, execution and independent receipts |
| `model-host.mjs` | Supervision of the separately packaged Ollama process |
| `company-relay.mjs` | Separate process for company networking and isolated browser work |
| `company-coordinator.mjs` | Company-owned coordination and selected work assignments |
| `drizzle/` | Local database baseline and migration journal |
| `node_modules/` | Pinned Playwright drivers; no browser profile or downloaded browser |
| `runtime-manifest.json` | SHA-256 inventory of packaged files |

The archive does not contain model weights, Node, Postgres binaries, customer data or credentials.
Applications must supply a compatible Node 22+ runtime and PostgreSQL toolchain. Model weights need
their own license, integrity and admission checks. Packaging a supervisor does not qualify a model.

## Start and stop the local core

Start a child process with a private stdin pipe:

```text
node core.mjs start --product attesko-os --data-dir PRIVATE_DIRECTORY \
  --migrations PACKAGE_DIRECTORY/drizzle --pg-bin POSTGRES_BIN_DIRECTORY \
  --parent-pid ACTUAL_PARENT_PID
```

Use `munky-os` for the personal product. Use separate data directories for the two products.
The first stdin line is JSON containing `transportToken`, a freshly generated 32–256 character
base64url token. Never pass it in argv, a URL, logs or browser storage. The core prints one
`local-core-ready` JSON record with its loopback `baseUrl`. It checks the actual parent PID and
stops when the parent exits. The private data directory is owned by the OS user and mode 0700.

Requests use `x-attesko-local-token`. This is an existing wire identifier; the runtime owner is
Munky. `/ready` and `/local/v1/stop` require that token. The CLI `status` and `stop` commands use the
same private stdin token and `--data-dir`. Do not expose the local port through Railway or a proxy.

The core starts private local Postgres, applies its schema, and persists its authority and receipts.
Starting a local core does not prove OS-level network denial. Product acceptance must separately
exercise the packaged app with networking denied and independently verify the requested effects.

## Network and model processes

`company-relay.mjs ACTUAL_PARENT_PID` receives a 64-character hexadecimal `transportToken` on its
first stdin line. It listens only on loopback and rejects browser Origin headers. The parent supplies
its resulting address and token as `networkRelay` when starting a core that needs company or browser
work. Network operations remain in this separate process; company transport checks the pinned
certificate and browser work uses explicitly configured authenticated sessions.

`model-host.mjs ACTUAL_PARENT_PID` starts `ollama/ollama` relative to its own package directory. It
supervises only its own process group. The product must configure model storage and network denial
before starting it. There is no remote-provider fallback in this helper.

## Company service

On a company-owned Mac, initialize a private service directory:

```sh
node company-coordinator.mjs init --directory PRIVATE_DIRECTORY --host PRIVATE_IP --port 9443
node company-coordinator.mjs serve --directory PRIVATE_DIRECTORY
```

Initialization writes private owner credentials and a pinned TLS identity. Keep `owner.json` on the
owner's machine. `pair` produces a short-lived pairing secret for one device. `devices`, `revoke`,
`pause`, `resume`, `assign`, `assignments`, `archived` and `cancel` manage selected company work.
Assignments still need exact device-side authority and an independent result check; sharing work
never grants unrestricted control of another Mac.

Packaged macOS login-service commands are `service-install`, `service-status` and `service-remove`.
Removing the login service preserves its data. The service is not a public cloud endpoint.

## Build and acceptance

Run `pnpm build:local-runtime` in MunkyAPI. The archive and checksum manifest are written to
`packages/server/assets/`. The build excludes source repositories, credentials, models and user
state. Products pin the archive SHA-256 and verify the internal file inventory before installation.

The runtime has real local file and controlled-browser regression evidence. General native app
control and representative task-model qualification remain unfinished. Failed research models are
not made eligible by a successful runtime build.

## Website inspector (0.17.0)

Run `node website-task.mjs` as a child process with one JSON object on private stdin:
`{action:"inspect", brief, credentials:{namecheap:{apiUser,apiKey,userName,clientIp},railway:{token,tokenType}}}`.
The brief uses the website-task schema from the integration guide. `tokenType` is `account` or
`project`; the Railway service link must include project, service and environment IDs. No ambient
CLI credentials, endpoint overrides or mutation actions are accepted. Keep credentials in native
secure storage and never in process arguments, logs, task memory or observation data.

Stdout returns `{ok:true,result}` with the advisory assessment and provider statuses, or
`{ok:false,error}` with a bounded code and nonzero exit status. Input is limited to 32 KiB, provider
responses to 2 MiB and each request to 15 seconds. The host must enforce an overall timeout.
The brief remains on the computer; only provider requests go to their respective services.
Missing custom domains or mail metadata block inspection. A ready review does not authorize a
write, prove a certificate is ready or establish that the site serves the expected content.
This entry point requires Node only; it does not start Postgres or a language model.

## Direct text decision storage (0.18.0)

Runtime 0.18.0 includes the additional direct-SMS choice storage migration. Earlier runtime archives
remain unchanged. SMS still requires the separately configured transport and verified contact;
this release does not add observation, a model, or DNS execution to the Mac website inspector.
