From the 2026-08-02 full-repo review (finding F-11).
Evidence: recipe.h (1848 LOC) is simultaneously the IR (Role/SymbolDecl/StateVariable/OutputDecl), the builder/validator (ConstitutiveModel, 308-1289), the pipeline assembler (emit_compute_function hardcodes pass registration, 703-739), the renderer (render_compute_function, 1687-1837), and — via the bottom-include of passes/internal/pass_bodies.h at line 1846 — the definition site of every pass body. recipe.h:4-27 includes every pass and emitter, so the advertised recipe→passes→code_emit layering exists in directory names but not in the dependency graph. Additionally, passes/pass.h:128-144 declares inline functions whose definitions only exist via recipe.h — IFNDR for a TU that includes a pass header directly and odr-uses them.
Impact: every consumer TU compiles the whole emit machinery; any pass-body change recompiles all recipe users; adding a lowering pass to the default pipeline requires editing the IR class (OCP violation at the seam users care about); the IR cannot be reused alone (relevant to the #108 front end and any future JSON-driven front end).
Proposal:
- Split:
recipe_ir.h (IR + builder/accessors) / pipeline+render header; keep recipe.h as a compatibility umbrella.
- Extract public
build_default_pipeline(ConstitutiveModel const&) -> PassManager and have emit_compute_function call it — the pipeline becomes extensible without forking the model class.
- Move non-template pass
run() bodies and render_compute_function into the STATIC library (CMakeLists.txt:150-156 already anticipates heavy code migrating there).
Effort: large but mechanical; best done before the API attracts external users. Related: #18, #108/#117 (front-end consumers of the pipeline seam).
From the 2026-08-02 full-repo review (finding F-11).
Evidence:
recipe.h(1848 LOC) is simultaneously the IR (Role/SymbolDecl/StateVariable/OutputDecl), the builder/validator (ConstitutiveModel, 308-1289), the pipeline assembler (emit_compute_functionhardcodes pass registration, 703-739), the renderer (render_compute_function, 1687-1837), and — via the bottom-include ofpasses/internal/pass_bodies.hat line 1846 — the definition site of every pass body.recipe.h:4-27includes every pass and emitter, so the advertised recipe→passes→code_emit layering exists in directory names but not in the dependency graph. Additionally,passes/pass.h:128-144declares inline functions whose definitions only exist via recipe.h — IFNDR for a TU that includes a pass header directly and odr-uses them.Impact: every consumer TU compiles the whole emit machinery; any pass-body change recompiles all recipe users; adding a lowering pass to the default pipeline requires editing the IR class (OCP violation at the seam users care about); the IR cannot be reused alone (relevant to the #108 front end and any future JSON-driven front end).
Proposal:
recipe_ir.h(IR + builder/accessors) / pipeline+render header; keeprecipe.has a compatibility umbrella.build_default_pipeline(ConstitutiveModel const&) -> PassManagerand haveemit_compute_functioncall it — the pipeline becomes extensible without forking the model class.run()bodies andrender_compute_functioninto the STATIC library (CMakeLists.txt:150-156 already anticipates heavy code migrating there).Effort: large but mechanical; best done before the API attracts external users. Related: #18, #108/#117 (front-end consumers of the pipeline seam).