Task: Close the rates round trip
Table of Contents
This page documents a task in the Rework the rates instruments to the instrument table rule story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Every rates product the importer writes can be exported again, and the family's carrier and codec are either the generated per-entity protocols or the one recorded exception.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Rework the rates instruments to the instrument table rule |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-09 |
3. Acceptance
- InflationSwap, BalanceGuaranteedSwap and FlexiSwap round-trip through the mapper: an import writes the fact row and the export writes the element back.
- The three products have round-trip cases with literal expected values.
- The rates carrier and its codec are either generated from the models or carry a recorded reason why the carrier stays hand-written and the codec is the only hand-written surface left.
- The hand-written rates variant and the payload container are gone, or their retention is recorded.
4. Plan
- The three products. Read the import paths of
InflationSwap,BalanceGuaranteedSwapandFlexiSwapand the exporter's dispatch, and write the reverse mapper each one is missing. They take the header and the fact row, as the six existing reverse mappers do. - Cases. One round-trip case per product with literal expected values, at the shape unit 3 left the family in.
- The carrier's disposition. Compare the hand-written rates carrier and codec against the generated per-entity protocols. Replace them if the generated path carries the legs and the shared children; otherwise record why the carrier stays hand-written and make the codec the only hand-written surface left.
- Removal. Either way, the hand-written rates variant and the payload container are gone, or their retention is recorded with its reason.
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 | |
|---|---|---|---|---|
| ORE core suite with the InflationSwap case | all passed, the corpus directory round trip included | compass test run -- -R ore.core |
uncommitted (working tree over fc09a30ec2) |
|
| Hand-written rates variant and wire codec still in the tree | none | =grep -rln "rates_instrument_variant\ | instrument_payload" projects –include=*.cpp –include=*.hpp= | same |
6. Notes
- This task changes no schema, so it is independent of unit 4 and can run beside it on its own branch.
- It is the first half of story acceptance clause 4; unit 8 is the proof.
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 |
|---|---|
| #3044 | [ore,trading] Export the inflation swap, and record why two products stay out |
9. Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 1 | The CPI leg is checked for type only | xml_ir_mapper_roundtrip_tests.cpp | Accepted | The case checks the CPI leg's currency too. The corpus directory round trip covers Inflation_CPI_Swap.xml: it is not in the known export gaps and the suite passes. |
| 2 | The unexported products are dropped silently | exporter.cpp | Declined | They are not dropped: an unmatched trade goes out as its type and envelope, and export_portfolio_unmapped_trade_keeps_its_type_and_envelope covers it. A louder log is out of scope. |
| 3 | Documents not reviewed in depth | none | Noted | Documentation validation is clean. |
10. Result
One of the three products is closed. The other two are blocked on model fields, and the carrier question was already answered by earlier units.
- InflationSwap has a reverse mapper, an exporter dispatch entry and a round-trip case with literal values: the two legs' types, the currency, and the schedule's start and end dates. The product states nothing beyond its legs, so the export is complete.
- FlexiSwap and BalanceGuaranteedSwap have no reverse mapper. I wrote
both and removed them. The schema requires fields the model does not hold.
A flexi swap needs its option long or short and its lower notional bounds;
the code would have written the enum's default in place of the document's
Short. A balance-guaranteed swap needs its reference security and at least one tranche; with none, the corpus walk could not re-readIR_BalanceGuaranteedSwap.xml, a document that exported as a bare trade before. The two products stay unexported, as they were. The taskCarry the FlexiSwap and BalanceGuaranteedSwap fieldsadds the missing model fields and exports both. - The carrier and the codec needed no change here. The hand-written rates
variant and the hand-written payload codec are gone: unit 3 removed the
variant, and the export carries typed batches generated from the trade-type
catalogue. The remaining hand-written parts are
swap_instrument_data, the struct that groups a header with its facts and children, and the ORE mapper. The grep in Measurements shows no reference left. - The stale
swap_instrument_databox in the API class diagram now shows the struct as it is.
The acceptance holds for InflationSwap, for the carrier and for the removal. It did not hold for the other two products when this task closed; the follow-up task closes them.