Task: Configure every seeded report from the ORE examples
Table of Contents
This page documents a task in the Configure every seeded report from the ORE examples story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Give every report ACME is seeded with the configuration it needs to run, so the chain executes it rather than failing before it starts.
A report is scoped to a root portfolio. The configuration names that portfolio, and the run resolves it to every book beneath it – that resolution is the population the run executes over, and it needs a method that answers it.
Concretely: go through the reports acme_demo seeds, take the analytics each one
implies from the external/ore examples, and create the configuration each needs,
scoped to the root portfolio that report belongs to.
Some reports have no meaningful portfolio scope – a data-quality or system-health report is about the installation, not about a book – so the task also decides what "scope" means for those, or records that they deliberately carry none.
2. Status
| Field | Value |
|---|---|
| State | BACKLOG |
| Parent story | Configure every seeded report from the ORE examples |
| Now | The scope half is settled, and a pricing run showed that ORE recognises the analytic codes. That run stopped because the package carries no quotes for the run's as-of date. |
| Waiting on | Market data at the run's as-of date, then a run per analytic family. |
| Next | Make the gathered market data cover the as-of date, then run one report per family and record the engine's verdict for each code. |
| Last touched | 2026-10-25 |
- Every report definition
acme_demoseeds for ACME either carries a configuration that resolves to at least one book, or is recorded as deliberately unscoped with the reason it has no scope. - A configuration is built from the
external/oreexample that matches the report's analytics: its observation model, market data type and analysis switches (NPV, cashflow, curves, sensitivity, simulation, XVA, stress) come from that example rather than being guessed. - A report names a root portfolio, and a SQL method returns every book under that root. The run uses that method as its scope, so a report added beneath the root is picked up without editing the configuration.
- The configuration is created where its definition is created, so their ids line up by construction.
3. Plan
(Implementation strategy. Written when work starts; key decisions
are distilled into the parent story's * Decisions at close, but the
plan itself stays — it is the historical record of what we did.)
4. Measurements
Every number this task claims about a tree, with the command that produced it
and the commit it was measured at. A number without both is not a measurement,
because a clean-up record describes a tree and trunk moves under a branch: a
consumer count, a gate's component count and a suite's size all change with no
code changing, and the reader of a bare number cannot tell which tree it came
from. Where the raw output matters, put it in an evidence/ file beside the
task and name that file in the Command column.
| What | Value | Command | Commit |
|---|---|---|---|
5. Notes
What the chain does today. report_execution_handler::gather_trades resolves
the configuration by definition id and then requires a scope:
const auto config = config_repo.find_by_definition_id(tenant_ctx, req.definition_id); if (!config) { /* "risk_report_config not found for definition " */ } const auto book_ids = config_repo.resolve_book_ids(tenant_ctx, config_id); if (book_ids.empty()) { /* "no books or portfolios in scope" */ }
A configuration alone is therefore not enough: it must resolve to at least one book, or the run fails one step later with a different message.
Why this cannot be a seed. A static seed cannot reference a definition, because
ores_reporting_publish_report_definitions_from_dq_fn in
projects/ores.sql/create/reporting/reporting_publish_from_dq_create.sql inserts
gen_random_uuid() for every definition it publishes, so the ids differ in every
tenant. The configuration has to be created in that function, where the
definition it names is being created.
Nothing in the tree inserts a risk report configuration today: the only populate hit is an unrelated FSM lifecycle file.
How this differs from the minimal unblock. C39230E7 asks for at least one
configuration so a run can be attempted at all. This task is the full pass –
every seeded report, each built from the matching external/ore example.
Open questions.
- Ordering. Definitions are published during the bundle step. Do the party's portfolios and books exist by then? If not, a configuration created there resolves to nothing and fails exactly as today, only later.
- The root relation. A method returning every book under a root portfolio needs a defined parent/child relation between the two. Whether that is a column on the portfolio, one on the book, or an existing hierarchy decides the method's shape, so it is the first thing to settle.
What the proof settled, and what it did not. Read on 2026-10-25, after the report ran on a database built from nothing.
Settled:
- Scope. Every one of the 78 definitions resolves to at least one book through
its configuration (measured: 78 of 78, 46 portfolio scope rows, no unscoped
definition). The root relation exists as a portfolio parent, and
ores_trading_get_book_ids_by_portfolio_fnexpands a root to its subtree;ores_reporting_resolve_book_ids_for_config_fnuses it, and the run took 20 books fromGlobal Portfolio. - Ordering and the id relation. The configuration is created in
ores_reporting_publish_risk_report_configs_from_dq_fn, alongside the definition, so the ids line up by construction. The party's portfolios exist by then, which is why the scope publishes.
Not settled, and the reason this task stays open:
- The switches may not come from the examples. The vendored examples use
eleven analytic types:
npv,cashflow,curves,xva,simulation,sensitivity,stress,calibration,scenario,creditcurves,amc. The seed switches on codes no example names:portfolio_details,saccr,pfe,parametric_var,historical_var,credit_curves,pnl_explain.ores.oreholds no table mapping a platform code to an ORE type, so the code is passed to the engine as written. - What the second run showed. "Board Risk Dashboard" (
npv,saccr,parametric_var) was triggered on the same database. ORE named all three:PRICING,PARAMETRIC_VARandSA_CCR. So the engine does recognise these codes; the doubt about them was wrong. It then failed each one withFailed to build market: There are no quotes available for date October 23rd, 2026, so the failure is the market data the package carries, not the switch. The instance went to failed and the result carried the engine's own message, which is the verdict fix holding on a real report. - Only
portfolio_detailshas a passing run. The pricing families need market data for the run's as-of date before anything can be said about their switches.
Next on this task. Two things, in order. First, make the gathered market data
cover the run's as-of date, which is what stopped the second run. Then run one
report per analytic family and record the engine's verdict for each code. The
holding party's definitions cover portfolio_details, npv, saccr,
parametric_var and cashflow; the legal entities' definitions cover
curves, credit_curves, sensitivity, simulation, pfe, xva and
historical_var, and reaching those needs a run grant for the entity's party.
Close this task when every code has either a passing run or a mapping.
6. Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario)
that verify this task. Link
new ones here as they're created; the scenario doc itself links back
via its "Verifies task" field.
| Scenario | State | Notes |
|---|---|---|
7. PRs
| PR | Title |
|---|---|
8. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|