# Estate, experience, marketplace, and reporting services

These services keep protocol decisions and cached state separate from their
network boundaries. Folder classification and listing validation are pure
inventory operations. Estate access-list codes, restart-day conversion, and
experience permission extraction can likewise be evaluated without a live
grid. Network methods use the current simulator only when a packet or
capability request is required.

## Estate administration

`GridClient::estate()` returns a client-cached `EstateTools`; clones share the
same subscriptions, events, disposal state, and live-operation gate. Incoming
`EstateOwnerMessage`, covenant, and land-stat packets are bounded and decoded
into typed access-list, experience-list, estate-info, covenant, top-script, and
top-collider events. Estate owner messages retain their upstream method names,
parameter ordering, access-delta values, invoice UUID, and agent/session IDs.

Region schedules use the `RegionSchedule` capability. Daily schedules encode
as `D`; weekly schedules encode as `W` with `SMTWRFA` day letters, and times are
whole seconds. Simulator console commands subscribe for
`SimConsoleResponse` before posting to `SimConsoleAsync`; the HTTP response body
is intentionally ignored. The event wait observes both the caller's
cancellation token and the requested timeout.

Terrain uploads are staged in `AssetManager` before the owner message is sent.
The normal transfer-request and transfer-confirmation path then serves the
staged bytes, and a failed owner message removes the pending transfer.

Estate packet mutations and mutating capabilities are disabled by default.
Call `EstateTools::enable_live_mutations()` only after authenticating the
operator, checking estate-manager authority, showing the exact target and
operation, and obtaining confirmation. This gate covers access changes,
returns, teleports, restarts, terrain changes/uploads, console commands, and
region or estate settings. Test capabilities under the reserved `.invalid`
domain remain usable by offline fixtures without enabling live mutations.

## Experience preferences

Experience preferences use the simulator's named capabilities and preserve
the `experiences` (allow), `blocked` (block), and absent (forget) decisions.
Estate experience replies preserve the blocked, trusted, and allowed list
boundaries reported by the owner message. Requests and mutations propagate
cancellation and apply input/body limits before parsing or publishing state.

## Marketplace

`MarketplaceFolderClassifier` derives listing-root, listing, version, stock,
and content roles entirely from an inventory snapshot. It validates missing or
multiple version folders and counts direct stock items without performing
network I/O.

`MarketplaceManager` keeps listing-ID and inventory-folder indexes in sync and
publishes synchronized, changed, and error events after committing cache
updates. Fetch is read-only. Create, delete, activate, and deactivate use the
`MarketplaceListings` capability and are disabled for live endpoints until
`enable_live_mutations()` is called. Applications should confirm price,
quantity, folder identity, and listing state immediately before opting in.
Offline `.invalid` fixtures exercise the same payload code without contacting
a service.

## Abuse and user reports

`GridClient::user_reports()` fetches localized abuse categories from
`AbuseCategories`; language tags are restricted to ASCII letters, digits, and
hyphens before the `lc` query is appended. Reports select
`SendUserReportWithScreenshot` when a screenshot UUID is present and otherwise
use `SendUserReport`. Capability payloads preserve the upstream fields and
allow the simulator to infer its own region; failed capability submissions
fall back to the legacy `UserReport` packet.

Report submission is a privileged, privacy-sensitive action and is disabled
for live endpoints until `UserReportService::enable_live_submissions()` is
called. Obtain user confirmation, review the summary/details and identifiers,
and avoid logging report bodies. Null report types and oversized text or region
names are rejected. Discovery and submission propagate cancellation; recorded
`.invalid` fixtures remain available for offline payload verification.

## Validation

The focused suite uses synthetic packets and in-memory HTTP handlers. It covers
owner-message experience lists, exact console event/timeout behavior, restart
schedule conversion, experience permissions, marketplace classifications and
CRUD payloads/events, localized abuse categories, report capability selection,
exact report LLSD, cancellation, and live-operation gates. No live grid or
Internet service is required.
