commit 2b4974b561a4afcab58ca666acb987d48d024c94 Author: npc0-hue Date: Tue Aug 25 22:12:35 2026 +0800 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c737b0 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +# run + +Machine-side executor for scoped server operations. + +## Responsibilities + +- Register with platform and report heartbeat, version, capabilities, and capacity. +- Claim and execute jobs for server lifecycle, file/config work, backups, updates, and bounded database or command work. +- Collect server logs into local spool and upload acknowledged batches. +- Transfer artifacts with chunking, checksums, resume, throttling, and low priority. +- Optionally coordinate with a game client bridge when a specific game requires in-game commands or snapshots. + +## Required Directory Plan + +Implementation should use dedicated directories for: + +- `api/`: platform-facing HTTP/gRPC client adapters. +- `protocol/`: control, job, log, artifact, and game-client bridge DTOs. +- `domain/`: executor domain types. +- `runtime/`: local execution and server process orchestration. +- `spool/`: local durable log/job/artifact queues. +- `artifact/`: chunk transfer implementation. +- `logingest/`: log collectors and uploaders. +- `config/`: configuration structures and loading. +- `shared/`: small shared helpers. + +Logs and artifacts must have separate queues and priority controls. + +## Development Baseline + +Tooling: + +- Go 1.25.1. +- Module: `browser.local/run`. + +Commands: + +```bash +go test ./... +go run ./cmd/run +``` + +Runtime configuration: + +- `RUN_MODE`: local mode, default `smoke`. +- `RUN_PLATFORM_URL`: platform base URL, default `http://127.0.0.1:8080`. +- `RUN_ENDPOINT_ID`, `RUN_DISPLAY_NAME`, `RUN_VERSION`, `RUN_REGISTRATION_TOKEN`: worker identity and registration metadata. +- `RUN_PACKAGE_CONFIG`: optional path to a generated platform package config. When set, run validates the config, uses its `authKey` as the registration token, and sends server/component identity plus key generation during control hello. +- `RUN_WORKSPACE_ROOT`, `RUN_SPOOL_ROOT`: scoped local server workspace and separate local log/artifact queues. +- `RUN_MAX_JOBS`, `RUN_HEARTBEAT_INTERVAL_MS`, `RUN_POLL_INTERVAL_MS`, `RUN_RETRY_BACKOFF_MS`: worker capacity and scheduling controls. + +For local direct debugging, copy `run/.env.example` to `run/.env`, edit the values, and run: + +```bash +set -a +source .env +set +a +go run ./cmd/run +``` + +Use `RUN_MODE=worker` when you want the executor to register, heartbeat, claim jobs, and execute lifecycle templates. Use `RUN_MODE=smoke` for a one-shot config summary. + +Generated run and client-manager packages carry a secret-bearing JSON config created by platform. The config contains: + +- component kind: `run` or `client-manager`. +- server instance ID, plugin ID, optional run endpoint ID, optional client-manager profile key. +- target OS/architecture, redacted `secret://runtime-keys/.../current` ref, key generation, and the raw current auth key needed by the remote executable. + +The raw auth key is valid only while it matches the single current encrypted key stored in platform for that server/component. Resetting the run key or a client-manager key increments generation and makes older packages fail control hello authentication until the operator regenerates and redeploys the affected package. Local diagnostics and smoke summaries use fingerprints and secret refs, not raw keys. + +In Docker, `RUN_PLATFORM_URL` must be `http://platform:8080` because `platform` is the compose service name. Locally, keep it as `http://127.0.0.1:8080`. + +Current executable behavior includes smoke mode plus worker mode. Worker mode registers with platform, sends lightweight heartbeat metadata, claims lifecycle jobs, acknowledges leases, reports bounded progress, executes scoped `process.install`, `process.start`, and `process.stop` command templates inside per-server workspaces, polls cancellation, submits terminal results, and reconciles active jobs. + +Lifecycle templates are JSON files addressed by logical keys under the server workspace. They resolve to direct executable/argument vectors, not shell strings. Absolute paths, parent traversal, raw credentials, direct sockets, shell launchers, unsafe environment keys, and unsafe output are rejected or redacted. Plugin-declared Windows `.cmd` and `.bat` assets are launched through a bounded `cmd.exe` adapter and remain under the same process supervisor. Process identity journals are namespaced by Run endpoint, server, plugin, and component profile, so multiple Run services cannot overwrite one another; a restart migrates matching legacy state, reopens the persisted output files, reconciles the PID, and resumes stdout/stderr tailing. Process stdout/stderr is written to the log spool, and lifecycle result metadata is queued through artifact hooks so control heartbeat and job result submission stay independent from log and artifact work. + +## Runtime Profiles And Distribution Jobs + +Run resolves plugin-declared runtime profiles using server runtime bindings supplied by platform. Supported modes are: + +- `local-process`: run starts/stops the third-party server through scoped lifecycle action refs and tails stdout/stderr. +- `hosted-ftp-rcon`: run exposes only declared FTP/log/RCON adapters for hosted servers that cannot be started locally. +- `ftp-only`: run exposes declared FTP and log transfer surfaces without lifecycle or RCON control. +- `custom-client`: run coordinates with a plugin-declared companion client manager using a separate component key and profile ref. + +Profile resolution returns logical capabilities, transport keys, declared log sources, discovery probes, and missing binding keys. It must not return raw host paths, FTP credentials, SQL DSNs, RCON passwords, direct sockets, or component auth keys. + +Worker mode now dispatches distribution capabilities in addition to lifecycle work: + +- `run.self-update`: validates the update assignment, downloads by artifact ref, verifies checksum/signature hooks, stages the replacement, and reports rollback-safe status through a bounded result ref. +- `dependencies.check`: executes a typed plugin-declared probe using logical target keys such as `dependencies/java-21`. +- `dependencies.install`: executes only typed install plans addressed under `dependencies/install/...`; arbitrary shell snippets are rejected before execution. +- `logs.backfill`: advances historical log cursors for declared sources and returns a cursor/result artifact ref instead of embedding large log bodies in job results. + +Declared file log sources use a tailer with offset checkpoints and redaction before entries enter the durable log channel. FTP/rsync, SQL read, RCON command, and file transfer adapters are represented as bounded envelopes with scoped input or artifact refs. Long transfers remain lower priority than heartbeat, job ack/result, cancellation polling, reconcile, and log acknowledgement. + +Protected SQL, RCON, and management-program requests use a separate signed one-time input route after Run claims a single-attempt fenced job. Run rechecks approval, expiry, server/endpoint/fence, capability kind, and logical transport/target bindings before dispatching to a local handler. Request text, private connection configuration, and response bodies do not enter assignments, journals, or terminal results. Management-program stdout/stderr is redacted into the durable `management-program` log source rather than file execution logs. See [`protocol/protected-request.md`](protocol/protected-request.md).