# Virtual report-source execution seam

Status: implementation contract for `nexuscrm-analytics`

Date: 2026-07-18

Issue: `nexuscrm-pingcap-pack#3926`

## Spike result

The current report dispatcher has three execution paths: static join templates,
stored Custom Report Types, and a physical single-object query. The neutral
`HistoryQuery` / `HistoryQueryFactory` contract exists, but `ReportService` has
no way for an installed product to register a non-physical row source. Calling
the physical path with such a token treats it as a table name.

The executable spike was added at `ReportService` with a non-CRM
`WorkItemTimeline` source. Before the implementation, this command failed to
compile because the registration, request/result contract, and paged execution
boundary did not exist:

```text
cd nexuscrm-analytics && go test ./...

service.RegisterVirtualReportSource undefined
service.RunReportDefinitionPage undefined
contract.VirtualReportSourceRegistration undefined
```

The smallest missing primitive is therefore one boot-time registration and one
dispatcher branch. It is not a second report engine and it is not a
history-specific executor.

## Ownership and single source of truth

The registry owns exactly one fact: which in-process executor handles a neutral
source token. Product code authors registrations during lifecycle composition.
Registration is immutable after boot, duplicate tokens fail, and an existing
physical object, static source, or synthetic CRT token cannot be shadowed. An
exact virtual registration is also checked through the stored CRT resolver at
execution; a deployed CRT with the same token is a configuration conflict and
fails closed before the virtual executor runs.

The registry does not own object or field shape. Metadata remains authoritative
for schemas, the permission service remains authoritative for object/FLS/RLS
decisions, and each source remains responsible for executing its declared
query shape. A future Field History registration must execute through the
existing neutral `QueryHistory` read path over `_System_AuditLog`; it must not
introduce another audit store or permission path.

## Neutral execution contract

A registration declares:

- one exact source token and parent object;
- the available columns and every static field-level security dependency;
- joins and derived columns;
- supported filters, grouping, joins, derivation, and pagination;
- whether every returned row requires a dynamic field dependency, as history
  rows do when their `Field` value selects the protected parent field.

`ReportService` normalizes and carries the report definition, runtime filters,
grouping, aggregates, selected joins, selected derived columns, limit, offset,
user, and request context to the source. Unsupported or undeclared references
are errors. The virtual path never uses the physical report path's
`DegradeOnError` retries, because dropping a virtual filter or column can weaken
both query meaning and authorization.

The source does not return record payloads or detached report-visible values.
Each row carries only parent/join record IDs, and each output entry identifies a
field declared by the column's FLS dependencies. `ReportService` batches those
IDs by object, reloads the requested fields through the platform-owned
`QueryWithSpec` path, and projects only the authoritative rows that survive its
normal RLS/FLS pipeline. A `MetadataOnly` column can project only the
authoritative record `Id`; it cannot be used to relabel a hidden field. Every
requested non-optional join is mandatory evidence. Every join identifies its
authoritative foreign-key field on the parent or a required supporting join;
`ReportService` reloads that field through `QueryWithSpec` and requires it to
equal the returned joined-record ID. A registered optional join may omit its
access record only when that field is empty and the joined value carries no
detached evidence; only then does the engine return `null`. A present,
unreadable, unavailable, mismatched, or otherwise contradicted relationship
fails closed. Dynamic field references must name fields on the parent
object and are checked through normal FLS before values are released. The
source's unpaginated total is valid only after it applies the same filters as
the returned page. Missing permissions, record IDs, authoritative rows,
declared record fields, dynamic field evidence, or output columns fail closed.

Product-owned derived content follows the same rule: a registered derived
column may provide a pure deriver, but the source returns only its ordered
history projections. `ReportService` reloads and authorizes every input before
passing the projected values to that deriver. Derived history inputs and any
off-anchor history projection require explicit static field dependencies; the
dynamic-row dependency exception cannot authorize them. L0 therefore owns the
evidence and permission mechanism without compiling product pairing or
calculation semantics, and product code cannot return a detached derived
payload. Registered derivers are stateless and concurrency-safe.

History-backed values use the same provenance rule. The source returns one
history row ID, and every non-derived public-history field projection in that
report row must reference that exact ID. A derived column may identify other
same-parent history evidence only with explicit static FLS dependencies.
`ReportService` batches all evidence IDs through the existing neutral
`QueryHistory` authority and
accepts only rows that survive its parent RLS, tracked-field interval, and FLS
checks. History filters reuse `queryspec.Predicate` and are lowered only for the
closed `Id`, `Field`, `CreatedDate`, and `CreatedById` metadata subset. Derived
report meaning, including how an application pairs transitions or calculates a
duration, remains product-owned content and is not compiled into this L0 seam.

Cancellation uses the caller's `context.Context` without replacement. The
non-CRM conformance test blocks in a source until cancellation and requires
`context.Canceled` to propagate.

## Acceptance evidence

`virtual_report_source_test.go` is the non-CRM consumer. It proves that:

- filtering is applied by the registered source;
- grouping shape and derived/join descriptors reach the source;
- offset/limit pagination returns the expected page;
- parent and joined-record access plus field FLS are checked for every returned
  row;
- joined-record IDs are bound to reloaded relationship fields, and a missing
  optional join becomes null only after that field proves absence;
- every released value is projected from its declared access-checked record;
- history values are reloaded through `QueryHistory` and bound to the same
  access-checked parent record;
- metadata-only columns cannot relabel history value payloads;
- undeclared filters, denied fields, and missing access evidence fail closed;
- duplicate registration fails; and
- cancellation reaches the source.

The Salesforce registrations and report-type content remain separate L1 work
under `nexuscrm-pingcap-pack#3751` and `#3752`.
