Implement credential-safe programs smoke gate (#97)
Some checks failed
Native code generation / deterministic (push) Failing after 2m12s
Imaging and meshing gate / native (push) Failing after 5m40s
JPEG 2000 feature / linux (push) Successful in 2m50s
Native Rust workspace compile / compile (push) Failing after 56s
Skia feature / linux (push) Successful in 31m24s

This commit is contained in:
2026-08-11 17:04:40 +00:00
parent 66f10baa1b
commit a9e2711447
18 changed files with 2216 additions and 25 deletions

101
docs/live-grid-smoke.md Normal file
View File

@@ -0,0 +1,101 @@
# Live-grid program smoke gate
The final programs gate has two credential-free modes and one explicitly gated
live mode. None of these tests silently skip. `--audit-only` fails unless the
pinned source manifest maps to all nine original native Rust programs and every
`TestClient` source command maps to the generated, implemented, and runtime
registries. `--fake` executes every smoke stage against the deterministic
backend and writes the same JSONL evidence shape as a live run.
```sh
cargo run -p libremetaverse-programs --bin live-grid-smoke -- --audit-only
cargo run -p libremetaverse-programs --bin live-grid-smoke -- \
--fake --evidence /tmp/metacrate-smoke-fake.jsonl
```
## Credential and side-effect boundary
Live mode is intended for a dedicated test account on OpenSim or another
protocol-compatible grid. It loads these values from the process environment,
falling back to the workspace `.env` file:
```text
GRID_USER=First Last
GRID_PASSWORD=...
GRID_LOGIN_URL=https://compatible-grid.example/login
```
`GRID_LOGIN_URL` is used directly as the LLSD login endpoint; the harness does
not substitute a Second Life login host or path. The login request includes the
OpenSim response options for avatar search, classified fee, currency label,
destination guide, profile service, and search, in addition to the standard
inventory and viewer options. Capability readiness is evaluated using OpenSim
core surfaces (`EventQueueGet`, inventory descendants, simulator features,
viewer assets, textures, and avatar search); Second Life voice capabilities are
not required. Agent, object, inventory, and asset packet consumers are installed
before authentication so the harness captures OpenSim's one-time login and scene
bootstrap packets instead of treating a late subscription as an empty region.
After the event queue is live, the harness repeats OpenSim's idempotent
`CompleteAgentMovement` transition request reliably before waiting for the scene
cache. Simulator identity is validated directly from the transport-decoded
OpenSim region handshake, and the return teleport uses its numeric region handle
instead of assuming the mutable Second Life-style simulator-name cache exists.
The complete command deliberately requires a separate flag and literal
confirmation for each permitted side effect:
```sh
cargo run -p libremetaverse-programs --bin live-grid-smoke -- \
--evidence /tmp/metacrate-smoke-live.jsonl \
--allow-live-login --confirm-live-login LOGIN \
--allow-public-chat --confirm-public-chat CHAT \
--allow-agent-movement --confirm-agent-movement MOVE \
--allow-reversible-inventory \
--confirm-reversible-inventory CREATE-MOVE-TO-TRASH
```
This sends one self instant message and one clearly marked local-chat message,
pulses forward movement for 250 milliseconds, teleports back to the starting
simulator and position, and creates one uniquely named folder before moving it
to Trash. The folder is not permanently deleted. The harness has no flags or
code paths for currency spending, asset upload, permanent deletion,
estate/parcel changes, or actions aimed at another user.
OpenSim does not necessarily route a self-addressed instant message back to the
sending avatar. The IM gate therefore requires the encoded
`ImprovedInstantMessage` datagram to cross the client's live UDP packet-sent
boundary and records any inbound self echo as an additional metric. The local
chat gate still requires an exact inbound simulator echo, so both operations are
executed and neither is silently skipped.
## Sanitized evidence
The newly created JSONL file contains exactly nine ordered records:
1. source/program/command completeness;
2. login;
3. event queue, capabilities, simulator, and object cache readiness;
4. self-IM and local-chat echo;
5. movement stop and return teleport;
6. folder creation and move to Trash;
7. object discovery and properties;
8. bounded texture download;
9. clean logout and zero active tasks.
The texture transfer is performed against the live grid and counted in the
sanitized evidence, but the harness disables the library's on-disk asset cache
before login. Asset bytes are held only in memory for validation and are not
retained after the process exits.
Each record contains schema and sequence numbers, a Unix timestamp, the Rust
package version, the source commit embedded at build time, a static status, and
numeric metrics. It contains no account name, password, login/capability URL,
session identifier, simulator name, object or asset UUID, or message text. The
writer scans every serialized record for configured credential values and
secret-bearing URL/token/password markers, flushes each stage, synchronizes at
completion, and refuses to overwrite an existing evidence file.
If an operational stage fails, the harness records that failure and still
attempts and records logout. A successful live gate requires all nine records
to have `status: "ok"`; fake success is evidence for deterministic behavior,
not evidence of a live login.

View File

@@ -3,9 +3,10 @@
The `test-client` binary is a native Rust multi-client shell. It does not load
the former C# executable or start a CLR process. The command registry owns the
implemented system, communication, inventory, appearance, asset, movement,
object, parcel, estate, grid, agent, friends, groups, directory, and statistics
commands. `pending_test_client_commands()` now reports only the two explicitly
owned voice-native adapters (`ParcelVoiceInfo` and `VoiceAcountCommand`).
object, parcel, estate, grid, agent, friends, groups, directory, statistics,
and voice-capability commands. `pending_test_client_commands()` is empty, and
the completeness audit compares the source, generated, implementation, and
runtime registries.
## Social, directory, and statistics behavior
@@ -92,7 +93,7 @@ cargo test -p libremetaverse-programs --test test_client_services_cli
The world gate drives every command owned by the movement/object/land/grid
issue, checks the exact fake backend calls, round-trips a linkset through
import, and validates generated assets. The services gate drives every one of
the 28 remaining non-voice commands in a single offline session, verifies the
destructive-operation guards, and proves the pending inventory contains only
the two explicitly owned voice adapters.
import, and validates generated assets. The services gate drives every
remaining service and voice-capability command in a single offline session,
verifies the destructive-operation guards, proves voice account values stay
redacted, and proves the pending inventory is empty.