Main lost the batch members a consumer uses

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

Fixed by #4138. The plan slot states the bond issue and its four child rows, the writer keeps sending them through put_bond_issue_composite_request, and the generated batch is untouched. ores.synthetic.service builds and the trade population cases pass.

Original proposal:

Decide where the rows a bond needs beside its instrument belong, and get them there through a model. Then make a regeneration fail before it can drop something a hand-written consumer reads.

637f5527e2 added five members to instrument_batch.hpp by hand, and ores.synthetic reads them. b3a78b33ba regenerated the header from the trade type catalogue, which declares none of them, and the members were gone. Main no longer compiles: trading_trade_population_writer.cpp:395 reads slot.instruments.bond_issues, and trade_population_planner.cpp:301 writes it.

2. Why

The estate has no way to say "a generated type carries this row family beside its instrument". The batch is generated from ores.trading.trade_type_catalogue, one array per trade type's instrument, so a member that is not an instrument has no home in the model. A hand edit was the only route, and the next regeneration removed it.

Nothing caught the break at merge time. The drift gate compares generated output with the models, so it agrees with the regeneration: the file matches its models and the models never had the members. Whether a consumer still compiles is a fact about the consumer, and no gate reads it.

The gate then made it worse. Its default mode regenerates in place, so running it in another worktree rewrote that worktree's trading headers before reporting. That behaviour is captured separately, and it is why this defect felt like a tree problem rather than a main problem: two restores of the tree do not fix a break that is committed.

Two candidates, and the choice is a design one:

  • model the carried rows: teach the catalogue to state the rows a trade type carries beside its instrument, so the generator emits bond_issues and its four children again. Keeps the writer's single atomic send.
  • hand the issue over separately: put_bond_issue_composite already exists, so synthetic could send the issue and the instruments as two interactions. Drops the members from the batch and keeps the generated type strictly per-instrument.

3. References

  • projects/ores.trading/api/include/ores.trading.api/domain/instrument_batch.hpp — the generated type, and the five members b3a78b33ba removed.
  • projects/ores.codegen/library/templates/cpp_trade_type_batch.hpp.mustache — the template, whose {{#batch}} list comes from the catalogue.
  • projects/ores.synthetic/core/src/service/trade_population_planner.cpp and .../trading/trading_trade_population_writer.cpp — the consumer.
  • 637f5527e2 (festive dijkstra) and b3a78b33ba (prime origin).

4. See also

Emacs 29.3 (Org mode 9.6.15)