Task: Build the curve blueprint screens
Table of Contents
This page documents a task in the Rework the market data feeds into a market data service with adapters — the remaining work story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
The curve blueprint list and record work against the service, using the history dialog, standard widgets and UX patterns.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Rework the market data feeds into a market data service with adapters — the remaining work |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-28 |
3. Acceptance
- The list and record render from real reads, with the standard tabs, dialogs and history.
- The badged values and the Market data card follow the signed-off prototype and the standards.
4. Plan
Four units, each ending in something to check.
- The reads and the BFF exposure. The list contract of
ir_curve_bootstrap_configgains the columns the screen searches, filters and sorts on (RS-LIST-04, RS-LIST-05, RS-LIST-07), and the pillar'sbootstrap_config_idis filterable so one blueprint's pillars are a filtered read rather than a page the screen narrows. Both kinds joinREFDATA_RECORDS, and the generic record route forwards the filters an address states asf.<member>. Two reads the generic path cannot serve are added to the curve routes: the oresmd URI of a set of series ids, and the build itself (marketdata.v1.ops.compute_curve), which had a handler and no route. - The web screens.
CurveBlueprintsPageandCurveBlueprintPageover the shared parts:RecordList,RecordGate,RecordHeader,useRecordTabs,RecordDetails,PartsPanel,RecordTimeline,RecordDialog,RemoveRecordDialog,RecordPicker. The five tabs are Details, Pillars, Check, Published sets and History. The card,AREA_CARDSand the menu entry follow the prototype's table. - The check flow. The six checks are the screen's own reading of the recipe
and are answered from what it read; the points come from
compute_curve; the forwards and the findings are the screen's arithmetic on those points, said as such. A recipe that fails a check stops before the market is read. The pure readings live incurveBlueprintCheck.tsso they are asserted without a browser. - The badges. Six code domains join the badge seed with one badge definition
per code and a mapping from each code, following
tenor_kind's shape.
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 |
|---|---|---|---|
| BFF suite | 1107 tests pass, 81 files | npm run test --workspace @ores/bff |
8630e8b097 |
| Web suite | 2281 tests pass, 181 files | npm run test --workspace @ores/web |
8630e8b097 |
| Wire protocol suite | 225 tests pass, 23 files | npm run test --workspace @ores/wire-protocol |
8630e8b097 |
| Web typecheck | clean, every workspace | npm run typecheck |
df4c37fb3a |
| Refdata C++ suites | core: 5637 assertions in 474 cases; api: 598 in 83 | publish/bin/ores.refdata.core.tests, .api.tests |
f98fa38218 |
| Docs checks | 39 components pass | ./projects/ores.codegen/validate_docs.sh |
0e2f638e1b |
| Lint | filetags and generator markers valid | compass lint |
0e2f638e1b |
| Live walk-through | evidence/curve_blueprint_live_walkthrough.txt |
evidence/curve_blueprint_walkthrough_seed.sql |
21b4ad0e92 |
6. Notes
6.1. What the units delivered
- The reads and the BFF exposure.
ir_curve_bootstrap_configdeclares the list contract its screen needs:currency_codeandindex_tenorare searchable,currency_codeandcurve_family_roleare filterable,discount_curve_config_idis filterable, and five columns are sortable. The pillar'sbootstrap_config_idis filterable, so the Pillars tab is one filtered read. Both kinds are inREFDATA_RECORDSwith their generated subjects, write schemas and the permissions the handlers check, and the generic record route forwards filters asf.<member>. Two reads join the curve routes: the oresmd URI of a set of series ids, and the build itself (marketdata.v1.ops.compute_curve, which had a handler and no route). - The web screens.
CurveBlueprintsPageandCurveBlueprintPageon the shared parts, at/market-data/curve-blueprints, with Details, Pillars, Check, Published sets and History. Add, Edit and Copy are the standard record dialog, and the output series is chosen there with the record picker over the series the party holds. The pillar's sequence is completed from its end tenor rather than typed. Two field kinds were added to the shared table instead of built in the screen: a picker over a list the screen supplies (the tenor ladder, a currency's funding blueprints), and the parts panel's.complete, for a part whose parent decides a field. - The check flow. The six checks, the forwards and the findings are one pure
module (
curveBlueprintCheck.ts) with 18 assertions; the points come from the build route; the tab never shows an unrun check as passed and a recipe that fails a check stops before the market is read. - The badges. Six domains, 17 badge definitions and 17 mappings in the system seed, and the same rows in the three artefact seeds the catalogue publishes to a tenant from.
6.2. The decision reversed mid-task
The task opened with the rule that the server mints the output series. It does
not, and it cannot: a curve's oresmd URI carries the index name
(DISCOUNT/RATE/USD/USD-SOFR-FOMC) and the config holds the currency and the
index tenor and not the index, so no operation can compose the identity the
record is keyed by. On 2026-10-28 the owner decided the other way: the output
series is chosen when the blueprint is created, with the standard record
picker over the series the party holds. Add and Copy now create the record
through the store like every other kind, the journeys and the design note carry
the reversal, and the minting rule is struck where it appeared – in
journey_maintain-the-curve-blueprints.org, in
doc/prototypes/market_data/curve-blueprints.org and in the model's own note.
The candidate for later is a series created from the same dialog, which is what
the Qt window did inline.
6.3. What is missing, and why the screen says so
- The curve code is not searchable on the server. The first column and the display handle are the output series' URI, which lives in another component's table; the list contract can search the currency and the index tenor, and that is what the search covers.
- The published sets are filtered on the page.
list_published_curveshas nobootstrap_config_idfilter, so the tab reads the party's sets and picks this blueprint's. The journey records the same gap. - The check is the screen's. No operation validates a recipe, so a recipe that fails its checks can still be saved, and the result is held by the person who ran it and not against the version.
- A schedule-resolved pillar does not build. The live build refuses a
1Fpillar ('1F is not a period, a date, ON, TN, SN or a continuation'), so the Check tab draws the server's words for the seeded FOMC recipe; the FOMC key derivation incompute_curveis a separate gap. - Retire. The record has no status, so the page draws the state it can infer ("no set in use since …") and offers no action.
- The as-of is a text field. The standard's field table has no instant kind, so
the Check tab takes the instant in one line of text, held in the address as
?asof, and says nothing it cannot. Adding the kind is the capture the journey names.
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 list, the record page with its five tabs, the four dialogs, the record picker, the check and the badge catalogue are built on the standard infrastructure and verified against the provisioned Acme database. A blueprint cannot be created from the screen yet, because nothing mints the output series it is created with; the page states that in the list's note and the gap is recorded above.
Delivered by PRs #4006 and #4009.