QueryAudit
One query as an audit trail sees it: who asked (read the principal from context; Wow does not own identity), what shape of query on which model version, under which restrictions, and what came back. It never carries a filter value, so no personal data from the query reaches the audit log.
Parameters
computes fingerprint on first read.
Properties
the query's entry, as the caller set it.
the error code of a failed query (ErrorInfo.errorCode and, when it states one, the rule code of its first binding error).
A hash of the submitted query's shape (queryShapeOf: operators, fields, value counts, sort, projection, groups, metrics and the paging kind and size), with every value, search text, alias and cursor left out, so equal shapes group together. Computed on first read, so an observer that never reads it (a metrics observer, say) does not pay for it.
the masked fields of the model the response carries, read from the admitted (canonical) projection so an alias cannot hide one; empty for a count, an aggregation or a query rejected before admission.
the queried model, or null when the query was rejected before its schema loaded.
the content hash of the model's capabilities (QueryModelSchema.version).
the aggregate queried.
how the query ended.
the QueryPolicy classes that restricted the query (those that returned anything but match-all).
the fields the caller's scope restricts (tenantId, ownerId, ...), not their values.