Task: Key identifiers, party roles and additional fields by the anchor
Table of Contents
This page documents a task in the Split the trade into an anchor and its components story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Every identifier of a trade, ORE's Trade/@id included, is a trade_identifier row; the other parties' roles and the additional fields are rows keyed by the trade; all three reference the anchor with a database foreign key.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Split the trade into an anchor and its components |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-03 |
3. Acceptance
- trade_identifier is keyed by (trade, scheme), with value and issuer; the scheme is a trade_id_type code and ORE is one of them.
- trade_party_role is keyed by (trade, role) and holds only roles other than the counterparty, which the anchor holds.
- trade_additional_field is keyed by (trade, order) with name and value.
- All three reference the anchor with an enforced foreign key, carry the anchor's party for row-level security, and have no workspace.
- Build, ctest, pgTAP and the local check set pass.
4. Plan
trade_identifierandtrade_party_roleare reshaped in place: nothing outside generated code writes them, so they move onto the anchor without a table beside them.trade_additional_fieldis new, beside the envelope's additional field table, which the ORE import still writes until its own task.- Keys: identifier (trade, scheme); party role (trade, role); additional field (trade, ordinal). Each has an enforced foreign key to the anchor and a party copy pinned to it for row-level security, and none has a workspace.
- The scheme is a
trade_id_typecode, checked against the catalogue rather than a check list; the catalogue gainsOREforTrade/@id. - A party role refuses
Counterparty: the anchor holds the counterparty. - The ORE envelope view joined the
Counterpartyrole, so it could never return a row again. Nothing read it, so it goes, with its test. The old identifier and party role pgTAP tests, which tested the wide trade's shapes and already stopped at their fixtures, are replaced by one test of the three tables.
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 |
|---|---|---|---|
6. Notes
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 |
|---|---|
| #2578 | [trading] Key identifiers, party roles and additional fields by the anchor |
9. Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 1 | Local review: trading_sample_data_populate.sql still writes the old identifier and party role shapes |
populate script | Decline | The script is not wired into any populate run; a backlog capture already holds the decision to wire or delete it. |
| 2 | Local review: the issuer has no foreign key | ores.trading.trade_identifier.org |
Accept as is | It may name a party or a counterparty, so no single table can check it; unchanged from before. |
| 3 | ctest: a party role domain test still expected the counterparty role | domain_trade_party_role_tests.cpp |
Accept | The test sets and checks a calculation agent. |
10. Result
trade_identifieris keyed by (trade, scheme) with value and issuer; the scheme is atrade_id_typecode, andOREis one, forTrade/@id.trade_party_roleis keyed by (trade, role) and refuses the counterparty role, which the anchor holds.trade_additional_fieldis keyed by (trade, ordinal) with name and value.- All three reference the anchor with an enforced foreign key, carry the anchor's party pinned to it with tenant and party row-level security, and have no workspace. The tenant purger removes every version of each.
- The unused ORE envelope view and the stale identifier and party role pgTAP tests are removed.
- Verified: build clean (
linux-clang-debug-make); ctest 89/90 on the full run, the one failure (a stale assertion) fixed andores.trading.*3/3 on the rerun; db recreate clean; pgTAP 55/55; codegen pytest 1120; drift shows only the knowntrade_service.cppdiff; sweep, paste blocks, reachability, permissions, populate references, CMake, inventory, ER strict, SQL hygiene, shell scripts, lint, structure notes, misspell and site page clean.