Task: Move the rates family's shared children onto the bond shapes
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
The cap/floor strikes and schedules and the swaption's option block sit on the shapes the bond pilot built, with their registration in the root that owns them and their text-typed dates and collections retyped.
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
- The cap/floor strikes are rows of instrument_strikes and its schedules are rows of instrument_schedules and instrument_schedule_dates, written by the import and read by the export.
- The swaption's option data is rows of instrument_options and its four children, with premium_amount, premium_currency, premium_pay_date, exercise_prices and settlement_fixing_date typed rather than text, and instrument_option_exercise_fees.start_date typed as a date.
- The rates header's Delete cascade names the shared children, so a header delete closes them.
- instrument_schedules.owner_role's check lists the rates family's owner roles beside trs_funding, repo, ascot_swap, option and trs.
- The children's registration sits in the root that owns them, not in registrar_bond.cpp.
- The ORE round trip keeps a cap/floor's strikes and schedules and a swaption's option block.
4. Plan
Stage 1, merged as PR #2986, is the family's ownership of the children: the header's cascade, the catalogue's child arrays, and the schedule owner role.
- The shapes. The bond pilot's
instrument_strike,instrument_schedule,instrument_schedule_date,instrument_optionand its keyed children are the target. The family writes to them; it does not widen them. - The retyping, finding R5, decided. ORE states
PremiumAmount,PremiumPayDate,ExercisePricesand the option premiums'SettlementFixingDateasxs:string, and the schema copied the string. The storage is typed and the boundary converts, as the family'send_datedoes:premium_amountbecomesnumeric(28, 10),premium_pay_dateand bothsettlement_fixing_datecolumns becomedate. exercise_prices, the fourth child. The column holds a list in a string and the option block has three keyed children where the design's entity table names four.instrument_option_exercise_priceis the fourth: the trade, the ordinal, the exercise date and the price, asinstrument_option_premiumis keyed. The text column is dropped.premium_currencystaystext, because a currency code is text in every other table here and soft-FKs toores_refdata_currencies_tbl.- The registration root, finding R11. Move the shared children's
registration out of
registrar_bond.cppinto the root that owns them. - The mapper.
swap_instrument_datagains one vector per child;forward_capfloorfills the strikes and the schedules,forward_swaptionfills the option block, and the reverse mappers read them back. The import handler calls thesave_strike,save_scheduleandsave_option_blockhelpers the bond path already has, withowner_roleswapfor a leg's schedule andoptionfor the exercise dates. - The export. The export service reads the child tables for the rates
trade ids into the batch arrays and
as_swapgathers them by trade id. - The proof. A cap/floor round trip that keeps its strikes and schedules, and a swaption round trip that keeps its option block.
- Order. The cap/floor first, end to end, with a build and the round trip between it and the swaption.
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 |
|---|---|---|---|
| Build | exit 0, no errors, no warnings | ./compass.sh build --preset linux-clang-debug-make -j 2 |
ceced2447a |
| Codegen suite | 1301 passed, 0 failed | pytest projects/ores.codegen/tests -q |
ceced2447a |
| Drift, cmake, inventories, reachability | all clean, no writes | the four check scripts, run bare | ceced2447a |
| Database recreate | exit 0, 348 s, fingerprint 041671e4685afdc7 |
./compass.sh db recreate -y -k |
ceced2447a |
ores.trading.api.tests |
370 assertions in 82 cases | the suite binary | ceced2447a |
ores.trading.core.tests |
954 assertions in 141 cases | the suite binary | ceced2447a |
ores.ore.core.tests |
482259 assertions in 627 cases | the suite binary | ceced2447a |
| The unit's three cases | 66 assertions in 3 cases | ./ores.ore.core.tests "mapper_roundtrip_capfloor_shared_children,mapper_roundtrip_swaption_option_block,mapper_roundtrip_swaption_exercise_price_children" |
ceced2447a |
| Branch shape | 3 commits, no merge commits | git log --merges --oneline origin/main..HEAD is empty |
ceced2447a |
6. Notes
- Unit 4 must land before the corpus round trip of unit 8: a cap/floor's strikes and schedules are not stored at all today, and the option block's dates are text, so the trip cannot be lossless until they are.
- It must also land before the composite key of unit 5, so the key is added once, to tables that are final.
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
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
10. Result
The rates family writes the shared children the bond pilot built, and they
survive the round trip. The cap/floor states its strikes as
instrument_strikes rows and its underlying swap's schedule as
instrument_schedules and instrument_schedule_dates rows; the swaption
states its option block as instrument_options and four keyed children,
including instrument_option_exercise_price, the fourth child the design's
entity table names and the models never had. The option block's text dates
and its price list are typed: premium_amount is a decimal,
premium_pay_date and both settlement_fixing_date columns are dates, and
exercise_prices is the child rather than a string. The header's cascade
names all eight children, and their registration sits in
registrar_rates.cpp rather than the bond family's root (finding R11).
Three residuals, all deliberate:
- The database-level end-to-end proof is unit 8's. The acceptance's
"written by the import and read by the export" is proved by the mapper
round trips and by the wiring compiling, not by importing a rates trade
into the database and exporting it. The corpus round trip at the new shape
is already the task
Prove the rates round trip over the corpus, which is where that proof belongs, and duplicating it here would prove it twice. - Bonds now carry their exercise prices through the fourth child. The
instrument_optionshape is shared with the bond family, so retyping the option block and droppingexercise_priceswould have silently dropped bond prices; the bond writer and reader convert at the boundary and write and read the child instead. This is a behaviour change for the bond family and is called out in the PR. The price list pairs token i with exercise date i, so a document stating more prices than dates loses the tail. split_numbersis duplicated in the ORE mapper and the import handler, in two components' anonymous namespaces. Not worth a shared API yet.
An earlier attempt at this unit bundled a cherry-pick of a trunk hotfix and
two merge commits; both are gone, and the branch is three commits on
ceced2447a with a clean history. The first database recreate failed because
the branch's base predated the trunk seed hotfix, which is what rebasing onto
current trunk fixed; no trunk fix is carried in this unit.