Task: Finish the bond pilot
Table of Contents
This page documents a task in the Clean ores.trading to the component clean standard story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Finish what the sprint 25 bond pilot left. The pilot proved its claim
for the bond products and the trade envelope: the zero-loss gate read 0
lost and 0 unexplained over 1566 documents, and the mapper is a
hand-written 1694-line bond_instrument_mapper.cpp over a hand-written
container of 241 and 425 lines. The unfinished part was never written
down as tasks, which is why it is still open.
This task owns the family-level correctness items. PR 4 owns the identity keys and the security split, because those touch every family.
2. Status
| Field | Value |
|---|---|
| State | BACKLOG |
| Parent story | Clean ores.trading to the component clean standard |
| Now | Not yet started. |
| Waiting on | PR 4 merged, so the security keys are stable. |
| Next | Re-model the bond future against the current schema. |
| Last touched | 2026-09-26 |
3. Acceptance
bond_futuresmatches the current ORE schema.instruments.xsddeclaresbondFutureDatawithContractName,ContractNotional,LongShort,ApplyConversionFactorandUseFuturePrice. The table holds 15 pre-v17 columns today, several of them NOT NULL, and the two v17 members have nowhere to go. The 13 contract terms either move to the shared security entity of PR 4 or are recorded as dropped with the reason.- The design's
instrument_underlyingstable is built, or recorded as out of scope with the reason. It was specified and never created. - The eight
bondDataelements with no column are resolved: CreditGroup, VolatilityCurveId, PriceQuoteMethod, PriceQuoteBaseValue, PriceType, Payer, CreditRisk and SubType. Each either has a column or a recorded decision. - Deleting a bond instrument over the shell removes the header row and the fact rows and the issue it owns, or refuses with a stated reason. Today the delete sends one message and leaves the rest behind.
- Adding a bond is one transaction. Today it is three saves with no transaction.
- A stated element whose value equals its type default survives export.
The abandoned task
A3DA0BB5records the case: a bond future states SettlementDirty, FairPrice and ExpiryLag, and the export drops all three. The fix is a presence flag per optional member, which is a modelling and codegen change toores.trading.bond_futurerather than a mapper edit. - The zero-loss gate reads zero over the whole bond corpus of about 50 documents, not over the two that were run live.
check_component_drift.py --component trading-cpp --dry-runreports nothing, and the suites pass.
4. Plan
4.1. 1. Re-model the bond future against the current schema
The synced XSD is the ground truth, and the current table is older than it. Model the five declared members, resolve the contract terms against PR 4's security entity, and drop the NOT NULL columns ORE does not require. Regenerate.
4.2. 2. Decide the underlyings table
Read the design section that specifies it
(design_bond_relational_model.org) and either build it as a shared
instrument-keyed table or record why the product does not need one. The
sprint 25 decision log says the mapper's container carries the schedule
and underlyings whole because no column can hold them, and that the
shared tables are their destination. That decision is currently
unimplemented.
4.3. 3. Resolve the eight residue elements
task F8D78E13 aligned bond_issue with ORE and removed what ORE does
not have. Eight bondData elements went the other way: ORE has them and
we have no column. Decide each against the current XSD, then model it or
record it.
4.4. 4. Fix the delete and add paths
The delete is in
projects/ores.shell/trading/src/app/commands/trading/bond_instrument_commands.cpp,
around line 361. It sends one delete for the header. Make the service
delete the family rows it owns, or refuse and say why. Make the add path
one transaction in the service layer.
4.5. 5. Add the presence flag
A stated element with a default value cannot be told from an absent one today, so the reverse mapper tests the value rather than the presence. Model a presence flag per optional member where ORE distinguishes them, and prove it with the bond future case from the abandoned task.
4.6. 6. Run the corpus sweep
python3 scripts/ore_mapper_roundtrip_diff.py python3 scripts/ore_schema_column_drift.py
Extend the round trip to every bond document under
external/ore/examples/, not two of them, and record the count.
4.7. 7. Record
Record the closure of the bond items and update the story's checklist rows the work touches.
5. Notes
- The pilot's recorded results are in the sprint 25 task bodies. The
zero-loss claim is
B753AD00and the round trip isD2D32410. Read both before re-measuring, so a difference is attributable. - The design page is stale in three places: it names
ores_trading_schedules_tblwhere the code hasinstrument_schedules, it says the issue holdsmaturity_dateanddescriptionafterF8D78E13removed both, and its conversion target columns areunderlying_uriandweightwhere the code hasunderlying_idandconversion_ratio. Correct the page or record the differences. - Two generated SQL files cite
doc/knowledge/architecture/trading_bond_relational_model.org, which does not exist. Correct the model that emits the citation. BondPositionis the family's uncovered product by evidence: the ORE schema declares nopositionData, so it has no document to import and no fact table. The suite asserts the absence. Do not add one.- The Qt bridge task
3E14AEC0is moot: the qt tree was deleted ataf67db3062.
6. Test Scenarios
| Scenario | State | Notes |
|---|---|---|
7. PRs
| PR | Title |
|---|---|
| Finish the bond pilot |
8. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|