Task: Prove the run end to end and keep it repeatable
Table of Contents
This page documents a task in the Prove the report grid run end to end — the remaining work story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Run the ACME definition against a freshly recreated database, record the instance's FSM walk, the compute job and the retrieved output, and keep the run as a check that can be repeated.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Prove the report grid run end to end — the remaining work |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-25 |
3. Acceptance
- The instance travels pending, running and completed through the FSM guard, witnessed on a database built from nothing.
- The evidence is recorded on the task, including the compute job and where its output landed.
- The run is repeatable from the recorded steps.
4. Plan
Run the chain the way an operator does: recreate the database, provision it
from acme_demo, trigger a definition the session's party owns, and watch the
instance, the batch and the result. Every step that could differ across
environments is read from the database rather than assumed, because the previous
attempts failed on data shape rather than on code.
The chain was found sound where it was suspected: the config lookup resolves the
binding to the risk configuration row before resolving scope, so the scope
returns books. The investigation that mattered was the failure path, described
under * Notes.
The repeatable artefact is a recipe, not a bespoke script, because the run needs prose steps between the commands: How do I prove a report runs end to end?.
5. Measurements
Every number this task claims about a tree, with the command that produced it
and the commit it was measured at. The data-shape numbers below were measured at 8a7478393e; the run outcomes and engine time were measured on this branch, and the rows behind them are named under * Notes.
| What | Value | Command | Commit |
|---|---|---|---|
| report definitions after provision | 78 | select count(*) from ores_reporting_report_definitions_tbl where valid_to > now() |
8a7478393e |
| definitions whose config resolves to books | 78 of 78 | resolve_book_ids_for_config_fn(d.tenant_id, r.id, d.id) over risk_report_configs.configuration_id = bindings.configuration_id |
8a7478393e |
| portfolio scope rows | 46 | select count(*) from ores_reporting_risk_report_config_portfolios_tbl where valid_to > now() |
8a7478393e |
| book scope rows | 0 | select count(*) from ores_reporting_risk_report_config_books_tbl where valid_to > now() |
8a7478393e |
| books under each Global Portfolio | 20, 8, 8 | ores_trading_get_book_ids_by_portfolio_fn |
8a7478393e |
| trades owned by the holding party | 8 | select count(*) from ores_trading_trades_tbl where party_id = ... |
8a7478393e |
| reports run through the grid | 4 completed, 2 failed as designed | instance and result tables | this branch |
| engine time for PORTFOLIO_DETAILS | 10000 ms | Output/runtimes.csv of the first run |
this branch |
6. Notes
What the chain does, confirmed. gather_trades resolves the definition's
binding to the central configuration row, then reads the risk_report_configs
row whose configuration_id holds it, then resolves scope with the risk
configuration id and the definition id. Joining on the central id returns no
scope for every definition, which is what made the first reading look like a
failure. It was a wrong join, not a defect.
A working run. Instance 97e9d3c2 walked pending, running, running and
completed in nine seconds. The batch closed with one workunit, the result had
outcome 1 and server state 5, and the output archive held log.txt,
runtimes.csv, pricingstats.csv, counterparties.csv and the tradewise
analytics. The engine logged Built Portfolio. Initial size = 8, size now 8,
built 0 failed trades, so the package the chain builds is ORE-readable and the
engine proceeds past Build Portfolio.
The defect the proof exposed. A job whose engine failed was recorded as
Success. ORE writes runtimes.csv, pricingstats.csv, log_structured.json
and todaysmarketcalibration*.csv whether or not the analytic it was asked for
ran, and judge_engine_run treated any file other than log.txt as evidence
that the run worked. It returned success before it ever read the log. The same
broken package that returned outcome 1 before the change returns outcome 3 after
it, carrying ORE's own line:
The engine's analytic failed. The engine reported: Error in ORE analytics: Failed to run analytics PORTFOLIO_DETAILS
The fix reads the engine's own verdict: a line whose message carries Error in
ORE analytics fails the run whatever else it wrote, while a run that wrote
analytics and logged no such verdict still succeeds. The file-based rule stays
for the case where nothing but the log was written.
The job behind the evidence. The last run on this branch, after the fix, left these rows. They are the ones a reader can look up.
| Field | Working run | Failed-analytic run |
|---|---|---|
| instance | 25922e99-e541-44ca-ab22-c6b7ddbc558a |
none, dispatched as a batch |
| batch | 19027790-54ca-47fd-91e8-72513fc3162a |
845ef18e-d63f-45e7-a92d-d6ea6b4abe09 |
| workunit | 93dc76f9-319c-44ef-9612-acc3ef858b5c |
9b79957b-d61e-45ad-8bbf-2d45111b35ca |
| result | 40adfb82-f1d3-4f61-894c-71a3fc73a480 |
f1c44665-6af7-4fd1-859d-5a424dd924c2 |
| outcome | 1 | 3 |
| output | compute/output/40adfb82-f1d3-4f61-894c-71a3fc73a480.tar.gz |
compute/output/f1c44665-6af7-4fd1-859d-5a424dd924c2.tar.gz |
| reporting key | reporting/runs/25922e99-e541-44ca-ab22-c6b7ddbc558a/output.tar.gz |
none |
The gap that remains. Seven of the eight bonds in the run have no reference data the engine can build, so the engine warns and prices nothing for them. The chain completes and the run is honest about its output, but a pricing analytic will produce no numbers until the bond reference data reaches the package. This is recorded here rather than fixed, because it belongs to the instrument export rather than to the chain.
Where it runs. The proof uses the five local wrapper hosts of this environment. The LAN hosts serve other environments and were a release or two behind, so a run there would prove a different tree. They are not part of this environment's grid, so they are not part of this proof.
| Host | Wrapper image before the deploy | Environment it serves |
|---|---|---|
| goedel (192.168.1.199) | 0.0.28-467fa878e5 |
brave_hopper, bright_faraday |
| Newton (192.168.1.22) | 0.0.28-467fa878e5 |
brave_hopper |
| LAPTOP-9OUEFKO5 (192.168.1.11) | 0.0.27-5418a8db36 |
brave_hopper, bright_faraday |
7. Test Scenarios
| Scenario | State | Notes |
|---|---|---|
8. PRs
9. Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 1 | fatal_messages says deduplicated but only drops adjacent repeats |
ores.ore/core/src/log/engine_run_verdict.cpp | Accepted | Deduplication is now by containment, so the structured warning that restates the ALERT line collapses into it. |
| 2 | The structured-warning fixture is inert, so the dedup branch is untested | ores.ore/core/tests/log_engine_run_verdict_tests.cpp | Accepted | The fixture now carries an ALERT line, the structured warning, and a repeat of the ALERT, and asserts one message. |
| 3 | The new header paragraph contradicts the one above it | ores.ore/core/include/…/engine_run_verdict.hpp | Accepted | Rewritten as one statement: files decide unless the engine states a failed analytic. |
| 4 | * See also carries internal id-links; the recipe standard allows external only |
the recipe | Accepted | The section is gone; the runbook, provisioning recipe and memory are referenced in the body. |
| 5 | The line-splitting loop is duplicated between the two helpers | ores.ore/core/src/log/engine_run_verdict.cpp | Accepted | One for_each_message walks the log; both helpers use it. |
| 6 | The failure message repeats "The engine reported" | the verdict and its test | Accepted | The message is now "The engine's analytic failed." followed by the engine's lines. |
| 7 | A magic .tests literal hidden in the .env loop |
CMakeLists.txt | Accepted in part | The suffix is a named ORES_TEST_SUBJECT_SUFFIX. The wider concern, that the test namespace is invisible to nats purge, is captured in Purge the streams a test run creates. |
| 8 | The tangled script cannot run: no login, and literal placeholders | the recipe | Accepted | Step 2 states that compass shell -f signs in from .env, names the placeholders as the command does, and step 5 now downloads the output with compute download-output. |
| 9 | Measurements cite a working tree, not a commit | this task | Accepted | The column names the base commit and says this branch changes no schema and no seed. |
| 10 | The test run shares the developer database, and the gate recreates it | .env and the gate |
New finding | Captured in Give the test run its own database and The check gate recreates the developer database. |
| 11 | The wrapper log says "produced no analytics" for a failed analytic | ores.compute/wrapper/src/app/application.cpp | Accepted | It now says "Engine run failed for". |
| 12 | A log-only run that states a failed analytic still says "no analytics" | ores.ore/core/src/log/engine_run_verdict.cpp | Accepted | The engine's verdict is read before the files, whatever they are, and a test covers a log-only failure. |
| 13 | The evidence names instances but no batch, workunit, result or output location | this task | Accepted | * Notes now names every id and both output locations for the working run and the failed one. |
| 14 | Recipe step 1 cannot supply the ids step 2 needs | the recipe | Accepted | It selects the tenant and the party, and says to take the row whose party the shell signed in as. |
| 15 | The header still reads as two contradictory statements; a dummy out-parameter; a comment repeated in CMake | verdict and build | Accepted | One statement in the header, the walker returns its line count, and the CMake rationale sits in one place. |
| 16 | The record contradicts the code, overstates what was run, and carries stale dates | this task, the story, the recipe | Accepted | The quoted message, the scripted-run claim, the measurement provenance and the dates are corrected, and the recipe's table cell is escaped so org does not subscript it. |
| 17 | The PR-record commit lacks the Environment and Co-Authored-By trailers | git | Noted | compass pr create writes that commit itself; the fix belongs in the tool, not in a rewrite of the branch. |
10. Result
The run works end to end, and the failure path now reports failure.
- A recreated database is runnable after one provision. The recreate leaves
schema and staged artefacts only.
bootstrap setup ... --profile acme_demopublishes 78 report definitions, 46 portfolio scope rows and both ORE engine packages. Every one of the 78 definitions then resolves to books, through the risk configuration row rather than the central one. - Four report runs completed through the grid. Each walked pending, running
and completed, each left
reporting/runs/<instance>/output.tar.gzin storage, and each closed a compute batch whose external reference is the instance id, with outcome 1 and server state 5. - The engine reads the package the chain builds. ORE logged
Built Portfolio. Initial size = 8, size now 8, built 0 failed tradesand ran PORTFOLIO_DETAILS for ten seconds. - A failed analytic is now a failed result.
judge_engine_runread the files alone, and ORE's bookkeeping files made every failed run look successful. The function now fails a run whose log carries the engine's ownError in ORE analyticsverdict. The same broken package returns outcome 1 before the change and outcome 3 after it, with the engine's message on the result, and a working run still returns outcome 1. - The run is repeatable. How do I prove a report runs end to end? records the steps and its script tangles into the shell library. The generated script, with the two ids substituted, ran an instance to completion, and a fourth run confirmed the working path after the verdict fix.
- Re-verified after review. The branch was rebuilt, the database recreated and
provisioned again. Instance
25922e99completed in ten seconds with outcome 1, and the package with no portfolio, dispatched as batche2e-broken-portfolio-5, returned outcome 3 carrying "The engine's analytic failed." The rows the earlier runs left behind were replaced when the gate recreated the database, which is captured above.