4.9 KiB
Grid-agent architecture foundation
The grid agent is a workspace-owned Rust library and small service binary. Its
core depends on Tokio for scheduling and bounded channels. Its live-grid
feature owns the existing libremetaverse composition root for grid protocol
managers; the default offline graph does not compile live transports. It does
not create a second login, UDP, capabilities, inventory, or world client. It contains no
CLR/.NET loading, sidecar, subprocess adapter, provider SDK, native ABI, or
platform-specific core path.
Ownership and bounds
AgentService::start is the sole task-creation point. It validates the complete
configuration before allocating channels, calling a backend, or permitting
network access. ServiceHandle then exclusively owns cancellation, both join
handles, the control sender, and observable receiver.
| Resource | Owner | Hard/configured bound | Backpressure/termination |
|---|---|---|---|
| Grid-event queue | coordinator receives; backend sends | 8,192 / grid_event_queue |
async send or cancellation |
| Control queue | coordinator receives; handle sends | 256 / control_queue |
async send; closed after stop |
| Observable queue | handle receives; coordinator/backend send | 8,192 / observable_queue |
async send or cancellation |
| Backend task | ServiceHandle.tasks[0] |
exactly one | shared cancellation token, joined first |
| Coordinator task | ServiceHandle.tasks[1] |
exactly one | shared cancellation token, joined second |
| Body / message | typed boundary owners | 8 MiB / 64 KiB hard ceilings, with lower configured limits | rejected before enqueue |
| Conversation / tool calls | request owner | 256 messages / 64 calls, with lower configured limits | rejected before request |
| Authorized avatars | immutable AgentConfig set |
1,024 hard ceiling, lower configured limit | malformed, nil, duplicate, and wildcard input rejected |
| Configuration / secret file | loader | 64 KiB / 16 KiB | regular non-symlink file only |
BoundedText and BoundedVec make message and collection ceilings part of the
type. Dynamic configuration can lower these absolute ceilings but cannot raise
them. Backend error text is not forwarded; observations publish a fixed bounded
diagnostic.
State machine and shutdown
The explicit service states are starting -> running <-> paused -> stopping -> stopped, with failed reserved for task failure. The offline backend publishes
BackendReady, after which the coordinator enters running. A shutdown control,
direct handle shutdown, backend failure, closed owner queue, or handle drop
triggers the same cancellation token.
Orderly shutdown first cancels, joins the backend, and then joins the
coordinator. Each join has the validated shutdown timeout. A late task is
aborted and awaited before return. A partially polled shutdown future only
borrows each join handle, so cancelling that future leaves every task in the
handle's fixed ownership slots for a retry or final drop. Dropping the handle
cancels and aborts all remaining owned tasks, so no task is detached. A
feature-enabled live adapter drops its
LibremetaverseClientOwner last, invoking the existing client ownership
shutdown.
Trust boundaries
- JSON configuration and environment text are untrusted. Unknown fields, oversized files, invalid booleans, conflicting modes, non-HTTP(S) URLs, URL fragments, malformed/noncanonical/nil UUIDs, wildcard authorization, multiline secrets, and unsafe limits fail before startup.
SecretStringandEndpointUrlare the only credential-bearing value types. Secrets are never serializable or printable. Endpoint diagnostics replace user information, passwords, and the complete query.- Grid input crosses
GridBackendonly through boundedGridEventvalues. Thelive-gridfeature suppliesLibremetaverseClientOwner; live implementations must own it and reuse its client and managers. - World changes cross only
WorldMutator::apply, which always receives the proposed call and an explicitPolicyDecision. This issue supplies no live mutation implementation. - Signals and console output belong to the binary. The reusable core relies on no terminal, Unix socket, Unix signal, separator, or fixed platform path.
Dependency diagram
metacrate-grid-agent binary (portable Ctrl-C + config path)
|
v
AgentService -> bounded Tokio channels/tasks -> injected GridBackend
| |
v v
typed config/events/policy boundaries live-grid feature boundary
| |
+-----------------> libremetaverse-types +--> libremetaverse::GridClient
The package has no build script or direct native dependency. The focused
dependency_policy test rejects subprocess launch sites, unsafe/native ABI
source, build scripts, and unreviewed direct dependency names in this package.