Task: Build the round-trip harness
Table of Contents
This page documents a task in the Model the ORE report configuration as entities story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
The harness turns round trip from a claim into a command. It is built once and every per-file-type task adds its type to it.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Model the ORE report configuration as entities |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-09-28 |
3. Acceptance
- One command imports a file, exports it, and reports whether the two documents are equal, naming the first difference when they are not.
- The harness runs over every file of a type in the vendored corpus and reports a count of files that round trip.
- A new file type is added to the harness without editing the harness itself.
4. Plan
- Read the two rigs that already exist. The binding walker
(
projects/ores.ore/core/include/ores.ore.core/xml/roundtrip.hpp) imports and exports the generated domain classes and counts documents with one hardcoded counter per kind:trades_mapped,currency_files,calendar_files,convention_files. That is the shape the harness replaces, because a kind is data and a new kind must not edit the walker. The credit simulation slice's two test files are the entity-level rig the harness generalises, and they already do the two things the binding walker cannot: compare the exported document with the imported one, and carry an expected value rather than an empty vector. - Define the seam. A document kind becomes a value: a name, its root element, the corpus glob, an import function from a file to the entities and an export function back, and a comparison. The walker owns the directory walk, the counts, the timings and the report of the first difference; a kind owns its mapper pair and nothing else.
- Register the kinds that already have a mapper, so the harness earns its place on its first run instead of being scaffolding for later work. Credit simulation is the first, and it is the register-through-the-harness proof.
- Report a difference, not a count. A file that imports and exports without throwing has not round tripped: it has only not failed. The harness compares the two documents as parsed documents and names the first path that differs, which is the assertion the credit simulation label finding showed was missing.
- Take the kinds in ascending corpus size, so a harness defect surfaces on 4 files rather than on the run document's 416. SIMM calibration is the smallest and needs its binding generated first, which is why it is not the first kind registered.
5. Measurements
| What | Value | Command | Commit | |
|---|---|---|---|---|
| Document kinds in the corpus census | 20 | evidence/round_trip_corpus.md |
cb7a6bad8e |
|
| Kinds the binding walker counts, one counter each | 4 | =grep -n "_files\ | _mapped" projects/ores.ore/core/include/ores.ore.core/xml/roundtrip.hpp= | e2bda9e108 |
Mappers in ores.ore.core |
13 | =ls projects/ores.ore/core/src/domain/*mapper*.cpp | wc -l= | e2bda9e108 |
| Kinds with an entity-level round trip today | 1, credit simulation | =ls projects/ores.ore/core/src/domain/ \ | grep credit_simulation= | e2bda9e108 |
| Run documents in the corpus | 416 | =find external/ore/examples -iname "ore*.xml" | wc -l= | e2bda9e108 |
| Files the harness walks for credit simulation | 14, all passing | the harness suite's walk.files and walk.passed |
this branch | |
Assertions in ores.ore.core.tests |
429951 in 564 cases | build/output/linux-clang-debug-make/publish/bin/ores.ore.core.tests |
this branch |
The commit column names the tree each number describes. The census numbers are from the commit the census was written at, not from this branch.
6. Notes
- The harness is not a new test framework. It is a registry plus a walker, and the walker is the same idea as the binding one, with the per-kind counters lifted into the registration so that adding a kind is a value rather than an edit.
- The binding walker stays. It proves the generated bindings read and write a document; the harness proves the entities do. Where a kind has both, both run: a binding defect and a mapper defect are different defects and a single test cannot attribute them.
- The first implementation compared the two documents as text and failed on all
14 credit simulation files. The differences were ORE's
t0"0.0"= against ourt0"0", and the indentation inside a =Dataelement: the same document, held differently. That is why the harness takes a comparison from the kind instead of comparing text, and why the credit simulation comparison moved out of its test into the mapper so that both callers share it. A generic comparison would have had to ignore text, which is how a lost value hides. - The harness's failure path has a test with a deliberately lossy mapper pair, because a rig that has only ever passed is not evidence that it checks anything.
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 |
|---|---|
| #2347 | [ore] Build the round-trip harness |
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
10. Result
Delivered in PR #2347.
The harness exists, credit simulation is registered through it, and all 14 files of that kind round trip. It owns the corpus walk, the count and the failure list; a kind owns its mapper pair and its comparison. A kind is a value, so the next one is a registration rather than a new rig.
Two things the work changed against the plan:
- The first implementation compared the two documents as text and failed every
credit simulation file. The differences were ORE's
t0"0.0"= against ourt0"0", and the indentation inside a =Dataelement. That is one document held two ways, so the comparison now comes from the kind, and the credit simulation comparison moved out of its test intocredit_simulation_diff.cppso that the test and the harness share one implementation. - Measuring the reference kinds, which the harness made possible for the first time, showed that none of them is one registration away. That measurement is on Round trip the shared reference configuration rather than here, because it is that task's subject.
Evidence: ores.ore.core.tests whole binary 429951 assertions in 564 test
cases; harness tags 17 assertions in 7 cases; credit simulation round-trip tags
44 assertions in 15 cases.