Story: Standardise the curve configuration's parameters on the one contract

Table of Contents

This page documents a story in Sprint 29. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

1. Goal

A curve configuration is drawn like every other configuration that comes off an ORE document. Its leaves are documented once, in the ORE parameter contract, keyed by curveconfig.xsd and XPath; its sections and entry elements come from data; and a person reads and changes a curve's leaves with the shared switch, documentation panel, value in force and control that a product parameter, an engine run setting and a convention term already use. Nothing about a curve section is restated in code.

2. Status

Field Value
State DONE
Parent sprint Sprint 29
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-30

3. Acceptance

  • Every leaf of curveconfig.xsd that ORE reads has a documentation entry in the ORE parameter contract, keyed by its schema and XPath, with a value set, or a recorded reason it is not documented.
  • The curve sections and their entry elements are read from the curve_section data, so no screen holds a table that names them.
  • A curve definition's leaves are drawn with the shared leaf parts: the Simple and Advanced switch, the documentation panel, the value in force and the control its value set gives.
  • The curve configuration page follows the configuration screen standard: Details, one tab per section in the declared order, Used by and History, with a curve entry drawn as a collection row.
  • A write whose value lies outside its leaf's value set is refused on the server, so every client gets the same answer.

4. Tasks

Task State Start End Description
Scaffold story: Standardise the curve configuration's parameters on the one contract DONE 2026-10-26 2026-10-26 Story scaffolding rides this task: documents, sprint wiring, and the scaffold PR. Close it before merging that PR.
Bring curveconfig.xml onto the one contract DONE 2026-10-27 2026-10-27 Initial task for: Standardise the curve configuration's parameters on the one contract
Document the curve configuration leaves in the one contract DONE 2026-10-26 2026-10-27 Give every leaf of curveconfig.xsd that ORE reads a documentation entry and a value set in the ORE parameter contract, extracted from the ORE source and the guide with provenance per row, so a curve screen can read its words from data rather than hold them.
Give the curve configuration leaves their value sets DONE   2026-10-27 Link every documented curve configuration leaf to a value set: a currency, a calendar, a day counter or an index draws on a refdata catalogue, a value an ORE parser maps takes that parser's list, and the rest take their type, so a screen draws the control from it and the write path can refuse a value outside it.
Draw the curve configuration page with the shared leaf parts DONE 2026-10-27 2026-10-27 Give the curve configuration a page that follows the configuration screen standard: Details, one tab per section in the declared order, Used by and History, each curve entry drawn as a collection row whose leaves use the shared switch, documentation panel, value in force and control. The sections come from curve_section, so the page restates nothing about a family.
Map the curve configuration columns to their leaves DONE 2026-10-29 2026-10-29 The value-set guard already exists: ores_reporting_value_in_set_fn is the one rule and a generated trigger joins a column-to-leaf map to it. No map covers the curve tables, so a curve value in a typed column is unchecked. Add the map and attach the trigger, so a curve value outside its leaf's set is refused on write.
Draw the nested collections of a curve entry DONE 2026-10-29 2026-10-30 A curve entry holds child elements of its own: Segments, Quotes, BootstrapConfig, Report, VolatilityConfig and their parts. The page names each block and stops there. Give each block the collection shape the configuration screen standard states, so its rows are read with the same leaf parts.
Let a person change a curve parameter DONE 2026-10-28 2026-10-28 The curve configuration page reads a document of thirty-four families and writes nothing. A write must change one leaf without dropping the rows the page does not draw, refuse a value outside its leaf's set, and follow the lifecycle the configuration screen standard states. Give the page its edit path once the guard covers the curve tables.
Let a signed-in person open a curve configuration DONE 2026-10-27 2026-10-27 The curve page is merged, but a person who signs in cannot open it: the read of a curve document is refused, and the address refuses the identifier the ORE import mints. Grant the reads a person's screen needs, accept the identifiers the import writes, and test both.
Draw the curves tab of the curve configuration DONE 2026-10-27 2026-10-27 The page draws one tab per section, nineteen of them and usually fifteen empty. Replace them with the shape the product pricing screen uses for its products: one Curves tab, a searchable rail of curves grouped by the section that declares them, and the chosen curve's parameters in a workbench beside it.
Show a curve's documentation once DONE 2026-10-27 2026-10-27 The workbench draws a leaf's help under its value and the same sentence again in the documentation panel, because for a curve the guide supplies one sentence as both help and description. The documentation belongs in the panel it is collapsed under, as the leaf standard states, so the row shows the label and the value and nothing else.
Carry the curve and report screens through the UX review DONE 2026-10-27 2026-10-28 The owner's review of the two screens: a curve's documentation shows its help twice and never lists the values a closed list accepts; the report page calls its first tab Definition and carries a latest-run card that the runs tab already covers; the report's configurations deserve a tab with a sentence per kind; and a multi-party reader sees copies of the same report with no party on the row.
Document the curve segment and quote leaves DONE 2026-10-29 2026-10-29 The curve configuration chapter documents every segment and quote leaf in prose and XML listings, but the term extractor reads only the parameterisation chapter, so 15 segment leaves and 3 quote leaves reach the contract with no words. The screen cannot draw a leaf the contract does not describe. Curate those leaves from the chapter that documents them, so the contract covers every leaf a segment holds.
Retire the curve parameter paths the schema does not declare DONE 2026-10-30 2026-10-30 The parameter contract keys a curve leaf by its XPath, and every reader resolves that path against the document. Five paths name an element their parent does not declare: four from a block the extractor attributes to the wrong sibling class, and one the ORE schema omits where the ORE code reads it. A path that matches nothing describes a leaf no document holds.
Draw the quotes a curve segment holds DONE   2026-10-30 A segment is mostly its quotes, and the page draws none of them: a quote's value is the Quote element's own text rather than a named child, and the list element that holds it varies by segment kind, so the collection rule the segments use does not carry over. Give the quotes their own shape and draw them under the segment that holds them.
Generate the curve collection wiring DONE 2026-10-30 2026-10-30 The page's section wiring is generated from the projection, but the child collections are a hand-written table in the BFF, because a segment leaf's path depends on the kind the row states and the wiring has no shape for that. Teach the generator to read import_segments and the quotes that follow each kind, and emit the rules the BFF now holds, so the store, the generator and the page are one source again.
Collect the snags from testing the curve screens DONE 2026-10-30 2026-10-30 The curve screens were walked in a browser, and the walk left a QA scenario a person can repeat plus the defects it found.
Record the leaves a segment inherits DONE 2026-10-30 2026-10-30 A segment reads six leaves from its base class before its own, and the extractor took a class's base from the same file it read. Read the base map across every file, so the contract carries the six and a segment stops showing its conventions as a gap.
Guard the shell's command units DONE 2026-10-30 2026-10-30 Two branches wired the legal entity unit, the merge kept both registrations, and ores.shell stopped at start-up. State the guard's two rules over the source, so the next merge fails a check instead of a person.
Curate the shared segment leaves DONE 2026-10-30 2026-10-30 Task for: Standardise the curve configuration's parameters on the one contract

5. Decisions

  • A save echoes the stored document and writes only the families it touched, decided 2026-10-28. A curve configuration is thirty-four families and the screen draws one entry at a time, so a document assembled from the screen would drop the rows it never read. The route reads the document, changes the named leaves and writes back those families, so a change to one curve leaves the other families at their versions. This also moved the edit (task CA40C9B0) ahead of the nested drawing (task 894F3A64): the echo is safe without it, and the contract documents 22 of the forty-odd leaves a segment holds.
  • A curve configuration's leaf is a parameter, decided 2026-10-26. Three words the leaf standard already spends do not serve this kind, and a fourth was rejected when the convention leaf was named.

    Candidate Why it was not chosen
    setting Reserved to the engine run settings, the ORE Setup block, by Configuration screen standard: "The word is not used for a parameter of any other configuration."
    term The conventions' word, and it collides with term structure, which is exactly what curveconfig.xml configures.
    field Rejected when the convention leaf was named: "field is the record standard's word for any record and says nothing about ORE."
    entry Already the row: curve_definition is "one curve entry", and curve_section.entry_element names the entry element.
    option Already a thing inside a volatility config: the call or the put.
    attribute A leaf is an element or an attribute, so this word cannot name both.

    Parameter wins because the code already calls it that: the contract table is ore_parameter, its docstring says "A parameter an ORE document accepts … a row documents one leaf of one ORE document", the configuration standard defines Parameter as "one leaf of an ORE document", and the generator that writes convention terms as contract rows is convention_parameter_rows.py.

    The cost is one amendment. The ORE element and leaf screen standard defines Parameter narrowly, as "a leaf of a product or of the document's global parameters". The first task widens it to cover a curve configuration. No screen prints the word for this kind yet, so the amendment changes a definition, not a screen.

  • The element type is the ORE entry element, read from curve_section, decided 2026-10-26. That table already holds the container and the element its entries use: YieldCurves holds YieldCurve, Correlations holds Correlation. Its own model records nineteen sections across the seventy-six curveconfig.xml documents ORE ships; that count is the entity's claim, not a measurement this story has taken, and the extractor re-measures it in the first task. This is the shape the convention kind already has — a declaration in data that a screen reads and does not restate. curve_section is to this story what convention_kind was to Draw every ORE leaf the same way.
  • The discriminator is not modelled yet, and the documentation does not wait for it. CurveType decides which leaves a yield curve may carry, and refdata holds no curve type today: yield_curve_config is one flat row of the union. The contract keys a leaf by its schema and XPath, and the XPath does not depend on the discriminator, so the documentation proceeds without it. Whether the discriminator joins the key as the element pair that OL-DOC-05 allows belongs to the task that moves the metadata into data.
  • This story does not own the structural refactor of the document. The curve_configuration_document is still one aggregate carrying 34 families, and that is Apply the same shape to the curve configuration document. The two tasks meet at the same document and do not block each other, because the contract is keyed by schema and XPath and not by the aggregate.
  • The column a leaf travels in is generated from the projection, decided 2026-10-27. A curve entry is spread over curve_definition and one family table, and the projection that reads and writes curveconfig.xml is the only code that knows which column holds which element. The screen reads that fact from bff/src/curve-sections.generated.ts, which generate_curve_section_parameters.py writes out of the projection and checks against curveconfig.xsd: 250 columns of 22 tables across the 19 sections. The alternative, deriving the column from the element's name, is wrong for CurveId (a curve_id) and for YieldCurveDayCounter (a day_counter), and a hand-written table would drift from the projection in silence. The guard task emits the same map for the trigger, so one source serves both.
  • The curve page reads before it writes, decided 2026-10-27. A curve configuration is one document of thirty-four families and a save writes it whole, so a page that drew the leaves of one section and saved would drop every row it does not draw. No guard covers the curve tables yet either. The page therefore reads, and two tasks carry the rest: the nested collections and the write, which waits for the guard so that no client can store a value outside its leaf's set.

6. Out of scope

  • Changing curveconfig.xml, the ORE XSD, or the generated ORE model.
  • The structural split of the document by family, which the refactor task owns.
  • Renaming a table, a configuration type code or an API route. The documentation and the screen words change; the model does not.

Emacs 29.3 (Org mode 9.6.15)