Task: Design the report processing architecture

Table of Contents

This page documents a task in the Run a full report: scheduling, reporting and compute story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

State the target architecture for report processing across scheduling, reporting and compute: the phases of a run, the workflow that executes them, the data characteristics that shape the interfaces, and how each end of the pipeline is built and can be substituted. The design lands as a knowledge cluster, because it outlives the story.

2. Status

Field Value
State DONE
Parent story Run a full report: scheduling, reporting and compute
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-09-27

3. Acceptance

  • The cluster names every phase, its owner and what it consumes and produces.
  • The pipeline, the orchestration loop and the substitution mechanism are drawn as PlantUML interaction diagrams showing the NATS subjects, and the rendered images are read.
  • The document links the existing reporting, compute, scheduling, workflow, storage and ORE documents by org-roam id.

4. 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.)

5. 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
       

6. Notes

7. 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
     

8. PRs

PR Title
#2284 [reporting] Write the report processing architecture as a structure note and its notes
#2280 [reporting] Make the workflow clear in the two-mode design
#2279 [reporting] State the orchestration contract in the two-mode design
#2278 [reporting] Design the two-mode report pipeline

9. Review

Comment summary File Decision Notes
       

10. Result

Delivered first as Report execution modes, then replaced. A review found that document mis-shaped: its subject was a configuration mechanism rather than the architecture, and it was written as one page where the documentation convention asks for a structure note and atomic notes. The replacement is Report Processing, a cluster of nine pages, and the record of what it contains is on that task.

The first version stated the stage list with an owner for each, the storage arrangement that made the two modes interchangeable, the rule that step results are addressed by role rather than index, the full NATS contract hop by hop, and two PlantUML interaction diagrams whose rendered images were read. Most of that survives in the cluster; what changed is the frame and the wording.

The design's most useful output is not the diagram but the distance it measured, because that is what changes the plan:

  • The common tail already exists and works when the shell drives it, and does not exist for the workflow, for three reasons recorded in the design and owned by the ACME smoke-test story.
  • The ORE conversion is much less complete than "we have an XML layer" suggests. The bindings cover the whole ORE vocabulary, but the ORE Studio to binding mappers cover four document kinds — portfolio, currency config, calendar adjustments and conventions — and none of the four configuration documents the engine needs.
  • prepare_ore_package ships trades.msgpack and market_data.msgpack, where the wrapper's contract is Input/ore.xml plus six named files, so the step's name and the workflow's own description run ahead of its code.
  • Nothing reads the engine's output at all, and gathering is a blanket tenant dump rather than a resolution of what the selected trades need.

Three questions are left open on purpose rather than settled by assertion: where the export's inputs live between stages, whether the demo input binding is a stage or an absence, and what a run should do when no grid is present.

11. Added after review: the orchestration section

A review of the first PR asked whether ores.workflow was really in the design, given that a run coordinates four services. It was — as a participant in both diagrams and as the publisher of every step command — but the design treated the coordinator as given and never stated the contract with it. The document now carries an Orchestration section: the participant interface, the at-least-once dispatch that makes idempotency a requirement on every stage, the properties the engine gives against what the design needs, the two state machines and which is authoritative, and the three engine gaps the pipeline leans on. The contract itself is tasked separately as Define and enforce the orchestration contract.

12. Added after review: making the workflow clear

A second review asked whether the document made the workflow clear, and it did not. The orchestration section had stated the contract, but the document still opened with a stage table that reads like a chain of direct calls, and it never said what a workflow is here.

It now carries The workflow: how the stages are run, which states that a workflow is a definition registered in C++ at startup rather than seeded data, that build_steps is rebuilt on every dispatch and on recovery, that the chain is therefore a pure function of the start message, and that one registered definition serves both modes because the mode is an input to build_steps rather than a type of its own. The stage table now says outright that every stage is run by the engine and that the Owner column means who does the work, not who calls it. A third diagram, the dispatch loop, draws the mechanism once so the two mode diagrams can stay about the stages, and the "what the diagrams show" section now states that no stage calls another.

Emacs 29.3 (Org mode 9.6.15)