Complete governed reporting execution and publication

This commit is contained in:
2026-08-04 02:23:24 +02:00
parent a81151391b
commit 8337aec19a
29 changed files with 3611 additions and 81 deletions
+30
View File
@@ -14,12 +14,28 @@ existing parent revision. Editing creates a new immutable revision and
requires the currently observed revision number. Existing runs continue to
reference the historical revisions they used.
Each definition also records system, tenant, group, or user governance scope,
whether it is inherited, and whether lower scopes may run, reuse, or automate
it. A child may tighten but never broaden any effective ancestor limit. System
definitions require system governance permission; tenant definitions are bound
to the active tenant; group and user definitions require the matching subject
unless a Reporting administrator performs the operation. Policy is consulted
for view, edit, run, reuse, and automation decisions.
Datasets may bind a static fixture, a pinned Dataflow output, or a capability
published by a source-owning module. Do not expose another module's ORM or an
unbounded SQL connection as a report source. Configure an explicit schema,
freshness policy, source fingerprint expectations, purpose, privacy,
retention, and a row-policy provider where source access alone is not enough.
On PostgreSQL installations, Reporting compiles bounded semantic filters,
grouping, measures, calculated measures, ordering, offsets, and limits into a
parameterized PostgreSQL plan over the already authorized provider rows. Field
paths and values are bound parameters and result limits remain mandatory. Pivot
plans retain the safe provider-neutral engine fallback. SQLite development and
other database engines use the same typed semantics through the bounded runtime
engine.
## Access and publication
Tenant-visible definitions are readable by principals with Reporting read
@@ -32,6 +48,20 @@ the Reporting publication-target contract. The target receives one immutable
execution payload and an idempotency key. It must return bounded evidence and
must not expose credentials in that evidence.
Reporting ships two optional adapters. `reporting.publication.files` calls
`files.artifact_store` and stores an idempotent managed artifact with execution,
revision, output-hash, and file-version evidence. `reporting.publication.mail`
calls `mail.notificationDelivery` and submits an idempotent report notice to the
Mail outbox. The latter does not bypass Mail profile, credential, or transport
policy. Adapter availability is evaluated at runtime, so Reporting remains
usable with neither Files nor Mail installed.
Drill contexts expire after 20 minutes, are bound to the creating account, store
only token and context hashes, and must match the original execution output and
source fingerprints. Resolution re-runs definition and row-level authorization.
Treat a fingerprint mismatch as a required report rerun, not as a recoverable
client warning.
## Cross-module provider governance
Source modules register `reporting.report_provider.<provider-id>` capabilities;
+23 -7
View File
@@ -83,6 +83,10 @@ Reporting does not own:
outcomes.
- `reporting.chart_renderer` renders provider-neutral visual models with an
accessible table fallback.
- `reporting.publication.files` adapts immutable results to Core's
`files.artifact_store` boundary without importing Files internals.
- `reporting.publication.mail` adapts report notices to Core's
`mail.notificationDelivery` boundary without importing Mail internals.
- `reporting.read_model:*` capabilities can expose bounded source-owned rows.
- `reporting.publication_target:*` capabilities can accept immutable result
payloads without Reporting importing the target module.
@@ -125,14 +129,22 @@ row-policy provenance, blocking quality plans, definition hashes, executor
version, output hash, diagnostics, and authorized rows are retained with the
execution. Failed runs also retain evidence.
The query engine deliberately implements a typed expression and semantic
The query layer deliberately implements a typed expression and semantic
query language rather than `eval`, arbitrary SQL, stored procedures, or
runtime scripts. It supports detail, grouped summary, pivot, dimensions,
runtime scripts. PostgreSQL installations receive parameterized semantic plans
for filters, grouping, measures, calculated aggregates, sorting, and bounds;
other engines and pivots use the equivalent bounded runtime evaluator. It
supports detail, grouped summary, pivot, dimensions,
hierarchies, common aggregates, calculated measures, filters, sorting,
pagination, totals, and a provider-neutral visualization model. A saved chart
that is incompatible with an ad-hoc query degrades to its mandatory table
fallback instead of failing a valid report run.
Aggregate drill-through uses an expiring actor-bound context hash. Resolution
rechecks all definition and row-policy decisions, verifies the source
fingerprints against the original execution, preserves the complete dimension
path, and returns only authorized contributors.
Direct export supports UTF-8 CSV and JSON. CSV cells that spreadsheet software
could interpret as formulas are escaped. Additional formats and delivery
destinations use an optional publication capability and preserve idempotent
@@ -142,7 +154,10 @@ unsupported executable behavior remains.
The WebUI uses the platform module loader and common controls. It exposes a
report catalogue, parameter and semantic-query controls, result visualization
and table views, history/provenance, saved views, schedules, and downloads.
and table views, accessible bar/column/line/area/pie/donut/metric charts,
drill-through, access explanations, history/provenance, saved views, schedule
management, Files/Mail publication management, downloads, and a Dashboard
widget contribution.
The global `/reports` route is owned only by Reporting. `/reporting` is a
documented compatibility path. Campaign's module-local aggregate view remains
at `/campaigns/reports`; when both modules are enabled, the same safe aggregate
@@ -151,7 +166,8 @@ contract.
## Remaining Product Depth
The architecture boundary is implemented. Further work is additive product
depth: richer visualization providers, drill-through navigation, packaged
domain report catalogues, XLSX/PDF formatting through optional providers, and
target-environment evidence for a maturity claim above `vertical_slice`.
The architecture boundary and first operational vertical are implemented.
Further work is additive product depth: packaged domain report catalogues,
XLSX/PDF formatting through optional renderer providers, selector-backed Mail
profile configuration, external publication connectors, and target-environment
evidence for a maturity claim above `vertical_slice`.
+22
View File
@@ -13,6 +13,13 @@ engine. A successful result shows its authorized row count, visualization,
and table. When a saved chart does not match an ad-hoc query, Reporting shows
the accessible table fallback instead of changing or rejecting the query.
Summary and pivot rows expose a detail action. Selecting it creates a short-lived,
account-bound drill context, rechecks the report, semantic model, dataset, row
policy, and source fingerprint, and then displays only the authorized contributing
rows. The path above the table records every aggregate dimension used for the
drill. If the source changed, run the report again rather than treating stale
aggregate and detail states as equivalent.
## Inspect evidence
The right panel lists previous runs and definition/source pins. Select an
@@ -21,6 +28,10 @@ the exact definition and output. Warnings explain freshness, inferred schema,
or provider diagnostics. A failed quality gate records a failed execution and
does not publish a result.
The **Effective access** explanation states when dimensions, measures, source
rows, or actions were removed by Policy. A result with no hidden elements says
so explicitly; catalogue visibility never grants access to protected detail.
## Save and export
Use **Save current view** to keep the current query under your account. Saved
@@ -32,6 +43,17 @@ Users with scheduling permission can create an hourly, daily, weekly, or
30-day interval from the current revision, parameters, and query. Scheduled
runs continue to use those exact pins until the schedule is edited.
The Schedules panel can pause or resume each schedule with optimistic revision
checking. Users with publication permission can publish a successful execution
to Files or Mail. Files stores CSV, JSON, or accessible HTML through managed
artifact storage. Mail submits a bounded report notice through its durable
outbox and requires a usable profile, sender, and recipient. Unavailable targets
remain explained but cannot be selected as a valid destination. Publication
history records the target, result, time, output hash, and provider evidence.
When Dashboard is enabled, the **Reports** widget lists active reports without
copying result data into Dashboard. Its item limit is configurable per widget.
## Run a module report
Module reports retain their source module's access rules. Select the source