Generate the empty instrument batch from the protocol

Table of Contents

This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.

1. What

(One paragraph: the idea.)

2. Why

(Motivation, problem being solved, related context.)

3. References

4. See also

5. What happened

Booking a trade was refused by the trading service as a bad request:

Failed to decode trading.v1.ops.book_trade: Failed to parse field 'instruments'

The request never reached the booking rule. Main had added two families to the instrument batch — equity_basket_constituents and equity_swap_periods — and the BFF's emptyBatch(), which states every array a bond booking does not fill, did not name them. The wire refuses a request that omits a declared member, so every booking, of every family, failed with a 502 the screen could only report as "the server refused the request".

Nothing failed to compile. The C++ declared the arrays, the TypeScript had a list, and the two drifted silently.

6. Why it is a class and not an incident

Three faults of one shape reached review today:

Where The declaration The hand-written mirror
Booking instrument_batch in C++ emptyBatch() in the BFF
Handler permissions a handler's permission check the permission seed
Code lists a modelled entity the tenant's copied lists

Each was found by running something and reading a refusal, never by a build. The instrument batch is the worst of the three, because it is not a seed that one environment misses: it is every booking, in every environment, at once.

7. What is asked for

Generate the empty batch from the protocol, as completeListRequest is already generated from the list descriptors: one source of truth for the members a request must carry, and an empty value per member type. Then a family added to the batch is a build change and not a runtime refusal, and nobody has to remember a list that lives in another language.

The same lever, if it works here, is the pattern for the other two rows: a generated seed for the permission codes a handler checks, and a generated comparison for the code lists a tenant copies.

8. What would settle it

Whether the TypeScript can be generated from the C++ declarations at build time — the codegen already reads models for both languages, so the question is whether the wire's field list is exposed to it — or whether a check that compares the two lists is the affordable half-step, failing the build when they differ.

Emacs 29.3 (Org mode 9.6.15)