Task: Hold a composite's legs as trades
Table of Contents
This page documents a task in the Let the blotter read a page, not the book — the remaining work story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
A package states which trades it groups. Today a composite leg states that in free text: constituent_trade_id is a text column whose generator writes a noun, so every leg the demonstration holds names CD and no leg names a trade. The package also cannot say what shape it is: kind and template_code live on structures and have no home on the composite.
This task gives the composite the columns a package needs: each leg is a uuid reference to a constituent trade, with the role it plays; the composite states the deal kind and template; and a trade sits in at most one composite at a time, which is the rule structure_member already states. No service writes these columns yet. The completion does, in the next task.
2. Status
| Field | Value |
|---|---|
| State | BACKLOG |
| Parent story | Let the blotter read a page, not the book — the remaining work |
| Now | Not yet started. |
| Waiting on | Nothing. This task goes first: every later task reads the columns it adds. |
| Next | Begin with the two models, then regenerate the component file lists. |
| Last touched | 2026-11-03 |
3. Acceptance
- A composite leg names a constituent trade by uuid, with a foreign key to
ores_trading_trades_tbland a current-only index. - A trade is a constituent of at most one composite at a time, and the store refuses a second.
- A composite states the deal kind and template, and a leg states its role.
- The generator and the repository tests write and read a leg that names a real trade.
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 |
|---|---|---|---|
| Composite leg rows, and current ones | 10, 0 | select count(*), count(*) filter (where valid_to = ores_utility_infinity_timestamp_fn()) from ores_trading_composite_legs_tbl |
23f46a8a0a |
| Distinct constituent values | 1, and it is CD |
select constituent_trade_id, count(*) from ores_trading_composite_legs_tbl group by 1 |
23f46a8a0a |
| Composite instrument rows, current ones, distinct trades | 10, 0, 5 | select count(*), count(*) filter (where valid_to = ores_utility_infinity_timestamp_fn()), count(distinct trade_id) from ores_trading_composite_instruments_tbl |
23f46a8a0a |
| Structures and structure members | 60, 115 | select (select count(*) from ores_trading_structures_tbl), (select count(*) from ores_trading_structure_members_tbl) |
23f46a8a0a |
6. Notes
- The row today points at a word.
ores.trading.composite_leg.orgdeclaresconstituent_trade_idastextand generates it withfaker::word::noun(), which is whereCDcomes from. The demonstration holds ten leg rows and not one of them names a trade. - The export already reads composite legs:
trade_export_service.cppcollects them for every composite instrument id it exports. A uuid reference is what lets that read resolve a constituent to the trade it names. - The rule this task copies is written on
ores.trading.structure_member.org: the row is keyed by the trade, so a trade sits in at most one structure at a time. The composite leg takes the same rule, with a current-only unique index on(tenant_id, constituent_trade_id). kindandtemplate_codeare the structure's words for the deal shape and have no home on the composite. They move tocomposite_instruments, and the leg'srolemoves to the leg row, so a package states the shape it was given without reading its legs.- Regenerate the component file lists after the models change:
projects/ores.compass/venv/bin/python projects/ores.codegen/scripts/regenerate_cmake_component_files.py.
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 |
|---|---|
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|