Story: Codegen developer experience improvements

Table of Contents

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

Carried from Sprint 22 as a not-yet-started BACKLOG story.

1. Goal

Fix two of the codegen regenerate workflow's friction points: a component run silently skips models whose type the address does not support, and an entity filter restricts a run to the named entities.

2. Status

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

3. Background

The three issues were surfaced during three separate codegen sessions in the commission_currency sprint:

  • task_sync_cpp_messaging_codegen_currency_auxiliaries — first observation of the component-wide over-generation and untracked-file cleanup burden.
  • task_sync_qt_codegen_currency_auxiliaries — second observation of over-generation (Qt profile); also first observation of the 13 spurious ERROR lines from qt profile against refdata-cpp (5 table + 8 junction models).
  • Both tasks — the impossibility of expressing "regenerate only currency entities" in a single command without listing all three entity names explicitly.

The --entity filter shortcoming was previously captured in codegen –component run generates all entities not just the target. The profile/type ERROR downgrade was captured in Downgrade profile/model-type incompatibility from error to skip in –component mode. This story groups both with the related entity-group feature into one deliverable.

4. Acceptance

  • A component run produces no ERROR or WARNING for models whose type the address does not support; those models are silently skipped.
  • codegen.sh regenerate accepts an entity filter and generates only the named entities, writing no other files to disk.
  • All existing codegen runs without the new flags produce identical output to before.
  • codegen.sh –help and the profile documentation list the new filter flag.

5. Tasks

Task State Start End Description
Downgrade address/model-type incompatibility to skip in –component mode DONE 2026-07-26 2026-07-27 In generator.py, detect model-type/address incompatibility in –component mode and skip silently (DEBUG log) rather than emitting ERROR and incrementing the error counter. Keep ERROR for explicit single-entity invocations.
Add –entity filter flag to codegen.sh regenerate DONE 2026-07-27 2026-07-29 Implement an –entity (or –entities) flag that restricts a –component run to the named entities only. No other entity files are generated or written to disk.
Task: Add entity group / tag system to model and codegen CLI BACKLOG     Design and implement a group annotation (e.g. :group: in entity org files or a groups section in the component manifest). Expose –group flag on codegen.sh regenerate. Define the initial currency group in ores.refdata.
Fix refdata entity model drift: update to latest format and regenerate DONE 2026-07-29 2026-07-30 Several refdata entities' checked-in generated code has drifted from what current codegen templates/models produce (discovered while verifying zero-diff for the literate-template-block-commentary task: country_repository.cpp, country_service.cpp, ClientCountryModel.cpp, CountryDetailDialog.cpp, CountryMdiWindow.cpp, country_protocol.hpp, country_handler.hpp all show diffs on regen even with unmodified templates). Update every refdata entity org model to the latest format/conventions, regenerate all of them, and commit the resulting drift so the tree is clean before further template work lands.
Fix synthetic entity model drift: update to latest format and regenerate DONE 2026-07-30 2026-07-30 Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.synthetic domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after.
Fix marketdata entity model drift: update to latest format and regenerate DONE 2026-07-30 2026-07-30 Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.marketdata domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after.
Fix dq entity model drift: update to latest format and regenerate DONE 2026-07-30 2026-07-30 Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.dq domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after.
Fix scheduler entity model drift: update to latest format and regenerate DONE 2026-07-31 2026-07-31 Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.scheduler domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after.
Fix workspace entity model drift: update to latest format and regenerate ABANDONED   2026-10-05 Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.workspace domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after.
Name the capture when a task has no sprint story DONE   2026-10-07 compass pr create refuses a task whose story is a backlog capture with only No story.org next to task. The workflow is that a capture is promoted into the sprint before it takes a task or a PR, so say that, name the capture, and give the promote command.
Read every result section before refusing a merge DONE   2026-10-07 A task doc with an empty * Result heading above a written one made compass pr merge refuse with 'result section is empty' while the prose sat directly below it. Read every section and treat the result as present when any carries prose, and name the duplicate.
Make the drift check script executable DONE   2026-10-07 check_component_drift.py is mode 644, so the literal command the documents give exits 126 with no output. Give it the execute bit and, if a gate can, keep it.

6. Decisions

The remainder is carried in Add entity groups and finish the remaining codegen work.

  • Wording updated at sprint 23 pull-in (2026-07-11). Originally written against --profile=/–component=; reworded to --address to match the CLI after Resolve codegen model unification blockers' B5 landed. If that story's B4 (collapse refdata=/=refdata-cpp) lands first, --component refdata-cpp collapses to --component refdata — update examples accordingly when picking up this story's first task.
  • Error vs. skip boundary. Incompatible-type encounters are an error only when the caller explicitly names an entity (--entity rounding_type --address ores.cpp.qt on a table model). In --component mode the codegen discovers entities automatically and must handle heterogeneous types gracefully.
  • Group granularity. The group concept should live in the entity model (org file property or a manifest section), not in the codegen CLI, so that it is co-located with the model and does not require CLI changes when the group membership changes.
  • –entity vs. –group. Both flags are needed. --entity is for ad-hoc one-off targeting without modifying the model. --group is for repeatable domain-scoped regeneration that reflects how the business thinks about entity ownership.
  • counterparty's logo/flag facet already existed; it just wasn't wired up. The "Bring counterparty's Qt logo/flag picker under codegen" backlog item assumed the facet needed building from scratch. It didn't – :flag_icon_column: already drives it (currency uses it); counterparty's model was simply missing the property. Adding it and regenerating restored the feature byte-for-byte. party had the identical gap, fixed the same way. That backlog item's premise is stale; worth re-triaging before picking it up.
  • scheduler's job_definition is hand-diverged across every layer, not just SQL. Unlike party (hand-maintained SQL only, other facets safe to regen), job_definition's domain column shapes (tenant_id=/=schedule_expression=/=is_active) don't match the hand-written struct's actual types (std::optional<boost::uuids::uuid>=/=cron_expression=/=bool), so even domain/repository-entity/mapper regen would emit wrong types. Its repository and messaging layers are also hand-maintained, with cross-component consumers (ores.reporting). No facet is currently safe to regenerate; the model file documents the exclusion in full rather than a full regen being attempted. Needs a proper resync (fixing column shapes, re-adding the hand-written operations to the generated surface) before any facet can be regenerated.

7. Out of scope

  • Changing which profiles support which model types (that is a profile design question, not a DX question).
  • Per-entity profile overrides (specifying a different profile for individual entities within a component run).
  • Automatic discovery of which entities in a component have drifted (that belongs to the refactor_codegen_cpp story).

Emacs 29.3 (Org mode 9.6.15)