Task: Join trades with typed links
Table of Contents
This page documents a task in the Record trade activities and trade links story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Every relation between two trades that a process did not create is a typed, directed link, and it holds nothing.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Record trade activities and trade links |
| Now | Nothing. |
| Waiting on | Nothing. A link holds nothing and needs no run. |
| Next | Nothing. |
| Last touched | 2026-10-08 |
3. Acceptance
- trade_link joins two trades with enforced foreign keys and a type from trade_link_type, and records the trade activity stamp that made it.
- trade_link_type names the from and to roles and the economic effect, seeded from the link catalogue (novation, exercise, roll and the rest).
- Nothing in the tree carries a successor trade id.
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 |
|---|---|---|---|
| pgTAP, the trade links, under the test DDL role | 8 of 8 | pg_prove test/trading_trade_links_test.sql |
b7dba42f59 |
| pgTAP, every trading file, under the test DDL role | 8 files, 94 tests, pass | pg_prove test/trading_*_test.sql |
b7dba42f59 |
| create files unreachable from the schema roots | 0 (was 4) | reachability probe over \\ir and \\i from the top-level .sql files |
7d98c723ea |
constraints on ores_trading_trade_links_tbl |
4: both ends, the activity, and the anchor party pin | \\d |
017bb3dc48 |
| link type rows the populate writes | 12 | select count(*) from ores_trading_trade_link_types_tbl |
ae49575dda |
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
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
10. Result
trade_link joins two trades under a type from trade_link_type, with
both ends enforced, the type validated against the seeded catalogue, and
the activity that made it recorded. The link holds no amount, no state and
no cash flow, and the tree still carries no successor trade id.
Three defects surfaced only when the database was rebuilt, and none of them was visible from the C++. The two link tables had generated create files that no aggregator listed, so the tables had never existed. The link copied its party from the from trade and pinned it to nothing, so the copy could drift from its source. And the link had no party isolation policy, so a session restricted to a set of parties read every link in its tenant. All three are fixed here.
The tables are wired into the schema, the party is pinned to the from trade's key, the party isolation policy matches the sibling trade tables, and a link may not join a trade to itself.