Fixed call chain
buildReportInput() receives a RecordReader. A Report definition, Calculation, Page, Download, local view, and static runtime receive neither a reader nor a path.
ReportScope
runs exhausts every selected Run. slots is the complete core-only denominator and preserves included, not-recorded, invalid, and excluded. An included slot has its Attempt ID, origin, locator, and Member kind, but no business facts.
FactRequirement
{ observedAt, value } with media type application/json. One owner/name has one value. Its parser never receives bytes, paths, or blobs. The build phase validates transport only; execution calls a synchronous parser once for each owner and requirement combination.
ReportPlan
ReportInput
ChannelRead state—read | unavailable | unsupported | invalid—and completeness. A consumer receives fact-free context plus readRun(runId, fact) and readAttempt(includedSlot, fact), which validate its declared inputs. Separate requirement objects cannot reuse an ID.
The context’s sample is a ReportSample projection without recordRoot. A Calculation, Page, or Download cannot obtain a Record path from public fields.
Calculation
allowPartial preserves the complete denominator and actual observed count. requireComplete requires both durable collection and decoding to be complete.
Page
Download
defineReportDownloadPath("downloads/..."). Its bytes are produced completely in the single execution phase and never recomputed during export.
ReportExecution
input-invalid, and execution-failed. executeReport() runs every consumer at most once. Local view displays failure locally, while export performs a whole-execution preflight.
Calculation results retain their originating Calculation and correspond one-to-one with plan order.
StaticAssetManifest
manifest.json and does not list itself in entries. Every other file has exactly one entry. A static directory contains only already-generated pages, host data, downloads, and the exporter’s built-in runtime, base styles, and fonts.
Page and host-data filenames follow plan order. Built-in resources live only under runtime/; user downloads live only under downloads/. Routes and output paths use canonical ASCII segments of at most 240 bytes. Their comparison key is bytewise ASCII lowercase. NiceEval checks exact/key duplicates and directory-prefix conflicts before creating the temporary directory.
exportStaticReport({ execution, out }) requires an absent out. It never replaces a directory, executes Report code, reads a Record, accesses the network, or looks up an arbitrary user path.