Task: Add junction to model_types on ores.cpp.domain/generator/repository.org
Table of Contents
This page documents a task in the Retire legacy codegen profile system; add junction support to physical-space codegen story. It captures the goal, current status, acceptance, and any notes or results.
Goal
Add junction to #+model_types: on:
projects/ores.codegen/library/templates/ores.cpp.domain.orgprojects/ores.codegen/library/templates/ores.cpp.generator.orgprojects/ores.codegen/library/templates/ores.cpp.repository.org
(currently all three declare #+model_types: schema domain_entity —
add junction to each, matching the space-separated list format already
used elsewhere, e.g. ores.sql.schema.org's domain_entity junction
schema table). Deliberately not touching ores.cpp.service.org,
ores.cpp.protocol.org, or ores.cpp.qt.org — see the parent story's
Decisions for why junction stays out of scope for those.
Each .org file states in its own body that the .mustache sibling is
a tangled artefact — after editing the .org, re-tangle via compass
build --direct tangle_codegen_templates (or
projects/ores.lisp/src/ores-build-codegen-templates.el directly) so
the actual .mustache file used by the generator picks up the change.
Once tangled, attempt compass codegen entity generate
tenor_convention_resolution --dry-run (the junction model at
projects/ores.marketdata/modeling/ores.marketdata.tenor_convention_resolution.org,
id E1F5A9C3-6D2B-4E8A-B7F1-3C9D5A2E6B48) and record exactly what
happens: does it attempt to render the templates at all now (proving the
model_types gate was the only blocker), or does it fail immediately
with a template error (proving the templates themselves need adapting —
the next task)? Either outcome is useful information for the next task;
write it into this task's Notes/Result rather than silently fixing
forward into template changes here — keep this task scoped to "can the
graph select these facets for a junction at all", the template-content
fix is the next task's job.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Retire legacy codegen profile system; add junction support to physical-space codegen |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-07-13 |
Acceptance
- All three facet
.orgfiles declarejunctionin#+model_types:. - Re-tangled
.mustachefiles reflect no other change (the tangle itself should be a no-op diff on the template content, since only the.orgkeyword changed, not the mustache source block). compass codegen entity generate tenor_convention_resolution --dry-runattempts (successfully or with a specific, recorded error) to render the domain/generator/repository facets, proving the physical-space graph now considers junction eligible for them.- Regenerating the same sample of existing
domain_entitymodels used in the deletion task still produces zero diff (this task should not change anything about howdomain_entitymodels generate).
Plan
- Added
junctionto#+model_types:on the three facet.orgfiles (nowschema domain_entity junction, matching the space-separated format used byores.sql.schema.org). - Re-tangled via
compass build --direct tangle_codegen_templates— confirmed the sibling.mustachefiles came out byte-identical (the.orgkeyword edit doesn't touch the mustache source block). - Note: the junction model this task's own Goal points at,
tenor_convention_resolution, now lives underprojects/ores.refdata/modeling/(id E1F5A9C3-6D2B-4E8A-B7F1-3C9D5A2E6B48) — it moved fromores.marketdatatoores.refdatasometime after this task was scoped. Same id, so no ambiguity, just a stale path in the Goal text. - Ran
compass codegen entity generate tenor_convention_resolution --dry-run, then (to see actual rendered content, not just target paths) without--dry-runtoo. The model_types gate was the only blocker — the graph now happily selects domain/generator/repository for a junction and mustache renders every template without error. But the output paths and several includes came out literally containing unresolved\{component_dir\}=/\{component_core_dir\}=/\{component_include\}=/\{component_core\}=/\{generator_facet_name\}placeholders — e.g. the repository header landed at literal pathprojects/\{component_core_dir\}/include/ores.\{component_core\}/repository/...and contains#include "ores./domain/tenor_convention_resolution.hpp"(empty component segment). - Root-caused in
core.py'sresolve_output_path(): it has two separate branches keyed onmodel_type— thedomain_entitybranch (line ~687) computes and substitutes all of\{component_dir\},\{component_core_dir\},\{component_service_dir\},\{component_include\},\{component_core\},\{component_service\},\{cache_component*\},\{generator_facet_name\}, plus the common\{component\}=/\{entity_plural\}=/=\{entity\}=/=\{EntityPascal\}= ones; thejunctionbranch (line ~732) only substitutes\{component\}=/\{junction_name\}=/=\{entity\}=/=\{EntityPascal\}=. The domain/generator/repository facet templates' output-path patterns and#includelines use the richer placeholder set the junction branch never fills in, so they survivestr.replace()untouched and land literally in the output. Field-level content otherwise looked correct (the domain struct's members, doc comments, and the repository's natural-key-based finder/remove methods — noprimary_key-shaped single-id method appeared, which is right for a junction with no synthetic PK) — this is a path/include-substitution gap specifically, not a wholesale template-shape mismatch. Reverted the throwaway generated output (all of it landed under the literalprojects/\{component_dir\}=/\{component_core_dir\}= paths, easy to spot andrm -rf) — this task is investigation-only, not the fix. - Regenerated
book(refdata, domain_entity) after the.orgchange: zero diff, confirming this task didn't perturb existing domain_entity generation.
Notes
resolve_output_path()'s junction branch needing the same
component_dir/component_core_dir/component_service_dir/component_include/
component_core/component_service/generator_facet_name substitutions as
the domain_entity branch (reading them off the junction model's own
component=/=subcomponent=/=component_include=/etc. keys, same as
domain_entity does) is the concrete, scoped fix for the next task
("Fix domain/generator/repository Mustache templates for junction-shaped
data") to make first — it's a Python data-plumbing gap, not a Mustache
template-content gap, and looks like a small, mechanical change (the
domain_entity branch's logic can likely be shared/factored rather than
duplicated, since junction models can carry the same
=component=/=subcomponent shape). Whether the templates then also need
Mustache-level branching for junction-specific fields (composite
left/right key, no synthetic id) is a separate question that task
should still verify once paths/includes resolve correctly and the
output can actually be diffed against something meaningful.
Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario, run
through the QA Validation Runner panel) 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 |
|---|---|---|
PRs
| PR | Title |
|---|---|
| #1585 | [codegen] Add junction to model_types on domain/generator/repository facets |
Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
Result
junction added to #+model_types: on ores.cpp.domain.org,
ores.cpp.generator.org, ores.cpp.repository.org; re-tangled with no
mustache-content diff. The physical-space graph now selects these three
facets for a junction model, and generation against
tenor_convention_resolution renders every template without error —
proving the model_types gate was the only thing stopping generation
from being attempted. It found a real, precisely-scoped gap instead:
resolve_output_path()'s junction branch in core.py doesn't
substitute \{component_dir\}=/\{component_core_dir\}=/
\{component_include\}=/\{component_core\}=/=\{generator_facet_name\}=
the way the domain_entity branch does, so those placeholders survive
literally into output paths and #include lines. Field-level content
(struct members, natural-key-based finder methods, no spurious
synthetic-PK method) otherwise looked correct. Investigation output
reverted — not committed. Regenerating book confirms zero diff for
existing domain_entity generation. Full detail in * Plan=/=* Notes
above for the next task to pick up directly.