fix(grid-agent): move setup into YAML preferences (#135)
This commit is contained in:
@@ -13,11 +13,11 @@ grid or LLM:
|
||||
|
||||
```sh
|
||||
cargo build --locked --release -p metacrate-grid-agent
|
||||
target/release/metacrate-grid-agent --config config/grid-agent.example.json --check-config
|
||||
target/release/metacrate-grid-agent --config config/grid-agent.example.json --run-once
|
||||
target/release/metacrate-grid-agent --config config/grid-agent.example.yml --check-config
|
||||
target/release/metacrate-grid-agent --config config/grid-agent.example.yml --run-once
|
||||
```
|
||||
|
||||
`--check-config` parses files, resolves secret files/environment, validates all
|
||||
`--check-config` parses YAML and any legacy referenced secret files, validates all
|
||||
bounds and TLS files, then exits before constructing the grid or LLM clients.
|
||||
The example is fake/offline mode (`integrated=false`, `split=false`) and all
|
||||
credential-looking values are placeholders.
|
||||
@@ -26,16 +26,16 @@ For live foreground or an embedded TUI, build intentionally:
|
||||
|
||||
```sh
|
||||
cargo build --locked --release -p metacrate-grid-agent --features live-grid
|
||||
target/release/metacrate-grid-agent --config /path/to/grid-agent.json
|
||||
target/release/metacrate-grid-agent --config /path/to/grid-agent.json --tui
|
||||
target/release/metacrate-grid-agent --config /path/to/config.yml
|
||||
target/release/metacrate-grid-agent --config /path/to/config.yml --tui
|
||||
```
|
||||
|
||||
Set `integrated=true` for the foreground and embedded-TUI commands. Set
|
||||
`split=true` for a headless service, then run the same binary as the TUI client:
|
||||
|
||||
```sh
|
||||
metacrate-grid-agent --config /path/to/grid-agent.json
|
||||
metacrate-grid-agent --config /path/to/grid-agent.json --tui-client
|
||||
metacrate-grid-agent --config /path/to/config.yml
|
||||
metacrate-grid-agent --config /path/to/config.yml --tui-client
|
||||
```
|
||||
|
||||
The TUI client and service must use the same control address and operator token.
|
||||
@@ -46,12 +46,11 @@ the default file is used only when it already exists:
|
||||
|
||||
| Platform | Configuration | Non-secret state |
|
||||
|---|---|---|
|
||||
| Linux/Unix | `$XDG_CONFIG_HOME/metacrate/grid-agent.json`, otherwise `$HOME/.config/metacrate/grid-agent.json` | `$XDG_DATA_HOME/metacrate/grid-agent`, otherwise `$HOME/.local/share/metacrate/grid-agent` |
|
||||
| macOS | `$HOME/Library/Application Support/MetaCrate/grid-agent.json` | `$HOME/Library/Application Support/MetaCrate/grid-agent` |
|
||||
| Windows | `%APPDATA%\MetaCrate\grid-agent.json` | `%LOCALAPPDATA%\MetaCrate\grid-agent` |
|
||||
| Linux/Unix | `$XDG_CONFIG_HOME/metacrate/config.yml`, otherwise `$HOME/.config/metacrate/config.yml` | `$XDG_DATA_HOME/metacrate/grid-agent`, otherwise `$HOME/.local/share/metacrate/grid-agent` |
|
||||
| macOS | `$HOME/Library/Application Support/MetaCrate/config.yml` | `$HOME/Library/Application Support/MetaCrate/grid-agent` |
|
||||
| Windows | `%APPDATA%\MetaCrate\config.yml` | `%LOCALAPPDATA%\MetaCrate/grid-agent` |
|
||||
|
||||
`METACRATE_AGENT_STORAGE_PATH` overrides the state directory. Relative paths in
|
||||
a JSON document resolve relative to that document where specified; service
|
||||
Relative paths in a YAML document resolve relative to that document where specified; service
|
||||
deployments should use absolute paths.
|
||||
|
||||
## Endpoint, grid identity, and authority
|
||||
@@ -59,11 +58,11 @@ deployments should use absolute paths.
|
||||
`llm.endpoint_url` is the exact OpenAI-compatible chat-completions URL. It is
|
||||
not a base URL: MetaCrate does not append a path, discover models, select a
|
||||
provider, or rewrite query parameters. `llm.api_key` is sent as the bearer key
|
||||
only to that exact origin; redirects are refused. Prefer
|
||||
`METACRATE_AGENT_LLM_API_KEY_FILE` over inline JSON or direct environment text.
|
||||
only to that exact origin; redirects are refused. Set `llm.model` when the
|
||||
endpoint requires a model name. These values live in the private `config.yml`.
|
||||
|
||||
Live modes require `grid.login_url`, `grid.avatar_name`, and a password from
|
||||
`METACRATE_AGENT_GRID_PASSWORD_FILE`. `authorized_avatar_uuids` contains exact
|
||||
Live modes require `grid.login_url`, `grid.avatar_name`, and `grid.password`.
|
||||
`authorized_avatar_uuids` contains exact
|
||||
grid UUIDs, never display names. Text claiming an authorized identity grants no
|
||||
authority. Public chat can request bounded informational work and safe public
|
||||
LSL delivery; movement, teleport, building, roaming changes, and administration
|
||||
@@ -72,19 +71,22 @@ or a narrowly bound scheduler grant as documented in the policy matrix.
|
||||
|
||||
## Configuration contract and migration
|
||||
|
||||
The JSON root uses `"schema_version": 1`. Omitting it is accepted as legacy
|
||||
The YAML root uses `schema_version: 1`. Omitting it is accepted as legacy
|
||||
version 1. Any other value fails before startup with a migration message. There
|
||||
is no automatic in-place migration: copy the file, update the copy using the
|
||||
release notes/example, validate the copy, then atomically select it. Unknown
|
||||
fields fail closed. Installers never overwrite or migrate operator files.
|
||||
|
||||
Precedence, lowest to highest, is:
|
||||
Resolution order is:
|
||||
|
||||
1. bounded built-in defaults;
|
||||
2. JSON configuration;
|
||||
3. secret files named by JSON;
|
||||
4. environment-referenced secret files;
|
||||
5. direct environment values.
|
||||
2. the platform `config.yml` or explicit `--config` document;
|
||||
3. legacy secret files referenced by that document.
|
||||
|
||||
Process environment variables do not override connection, mode, or authority.
|
||||
Migrate an existing `.env` once with `metacrate-grid-agent --import-env
|
||||
/path/to/.env`, inspect it using `--preferences`, then remove the old file under
|
||||
the operator's retention policy. JSON remains readable only for migration.
|
||||
|
||||
Mode, endpoints, credentials, authorization UUIDs, TLS, storage, queue/resource
|
||||
limits, reconnect policy, behavior, and interaction settings are restart-only.
|
||||
@@ -120,9 +122,8 @@ Rust's portable metadata API cannot prove arbitrary Windows ACL semantics, and
|
||||
FAT/network filesystems may not enforce them. Treat an unverifiable filesystem
|
||||
as unsuitable for unattended secrets.
|
||||
|
||||
Rotate one credential at a time: write a new restricted file beside the old
|
||||
one, atomically replace or repoint the `_FILE` setting, run `--check-config`,
|
||||
then restart. Revoke the old credential only after readiness. Control observer
|
||||
Rotate one credential at a time in `--preferences` (or an ACL-restricted copy
|
||||
of `config.yml`), save, run `--check-config`, then restart. Revoke the old credential only after readiness. Control observer
|
||||
and operator tokens must differ from each other and from grid/LLM credentials.
|
||||
|
||||
## Linux systemd
|
||||
@@ -130,16 +131,15 @@ and operator tokens must differ from each other and from grid/LLM credentials.
|
||||
The hardened example is
|
||||
[`../packaging/metacrate-grid-agent/systemd/metacrate-grid-agent.service`](../packaging/metacrate-grid-agent/systemd/metacrate-grid-agent.service).
|
||||
Create the unprivileged `metacrate-agent` identity, copy (do not overwrite) an
|
||||
operator configuration to `/etc/metacrate/grid-agent.json`, create
|
||||
`/var/lib/metacrate/grid-agent`, and copy the environment-file example. The
|
||||
environment file contains only secret *paths*. Put the actual secret files in
|
||||
`/etc/metacrate/secrets`, owned by the service identity with mode `0600`.
|
||||
operator configuration to `/etc/metacrate/config.yml` and create
|
||||
`/var/lib/metacrate/grid-agent`. Keep the configuration owned by the service
|
||||
identity with mode `0600`; do not put credentials in the unit environment.
|
||||
|
||||
Install the unit, inspect the sandbox, validate, then start:
|
||||
|
||||
```sh
|
||||
sudo systemd-analyze security packaging/metacrate-grid-agent/systemd/metacrate-grid-agent.service
|
||||
sudo -u metacrate-agent /usr/local/bin/metacrate-grid-agent --config /etc/metacrate/grid-agent.json --check-config
|
||||
sudo -u metacrate-agent /usr/local/bin/metacrate-grid-agent --config /etc/metacrate/config.yml --check-config
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now metacrate-grid-agent.service
|
||||
```
|
||||
@@ -150,19 +150,18 @@ writes only under the state directory.
|
||||
|
||||
## Windows service operation
|
||||
|
||||
Run the same `.exe`, JSON, control TCP protocol, and shutdown path. Portable
|
||||
Run the same `.exe`, YAML, control TCP protocol, and shutdown path. Portable
|
||||
foreground operation in PowerShell is the baseline:
|
||||
|
||||
```powershell
|
||||
& 'C:\Program Files\MetaCrate\metacrate-grid-agent.exe' --config 'C:\ProgramData\MetaCrate\grid-agent.json' --check-config
|
||||
& 'C:\Program Files\MetaCrate\metacrate-grid-agent.exe' --config 'C:\ProgramData\MetaCrate\grid-agent.json'
|
||||
& 'C:\Program Files\MetaCrate\metacrate-grid-agent.exe' --config 'C:\ProgramData\MetaCrate\config.yml' --check-config
|
||||
& 'C:\Program Files\MetaCrate\metacrate-grid-agent.exe' --config 'C:\ProgramData\MetaCrate\config.yml'
|
||||
```
|
||||
|
||||
For unattended use, configure a maintained Windows service wrapper (for
|
||||
example WinSW) to launch exactly that command as a dedicated low-privilege
|
||||
account and to translate SCM Stop into Ctrl-C/console control before its timeout.
|
||||
Keep secrets in separate ACL-restricted files and expose only `_FILE` paths in
|
||||
the wrapper environment. Configure restart-on-failure, not unconditional rapid
|
||||
Keep `config.yml` ACL-restricted to the service identity. Configure restart-on-failure, not unconditional rapid
|
||||
restart. Validate as the service identity before registration. The wrapper must
|
||||
not capture environment values or command output into a world-readable log.
|
||||
The supplied PowerShell installer replaces only the executable and never state.
|
||||
|
||||
Reference in New Issue
Block a user