From the 2026-08-02 full-repo review (finding F-10).
Evidence: targets/target.h:39 offers only emit(). Accepted recipe domains differ radically per backend: NumSimMaterialTarget rejects scalar inputs / multi-state / tensor state (numsim_material.cpp:87-143, 181-236); MooseMaterialTarget rejects stateful inputs, evolution-without-local-Newton, >1 tangent (moose_material.cpp:456-509); StandaloneCxx accepts nearly everything. A generic driver (e.g. recipe_registry_gen) can only find out by catching std::runtime_error — the direct cause of the registry-generator abort issue.
Proposal (additive, non-breaking): [[nodiscard]] virtual auto can_emit(ConstitutiveModel const&) const -> std::expected<void, std::string>; default implementation may conservatively return success ("try emit"). Concrete targets refactor their existing guard blocks to feed both can_emit and emit from one place, keeping the excellent reject-loudly messages.
The "reject loudly, never silently drop" policy itself is right and should stay — this only makes rejection queryable. Related: #93 (factory formalization), registry-abort issue.
From the 2026-08-02 full-repo review (finding F-10).
Evidence:
targets/target.h:39offers onlyemit(). Accepted recipe domains differ radically per backend: NumSimMaterialTarget rejects scalar inputs / multi-state / tensor state (numsim_material.cpp:87-143, 181-236); MooseMaterialTarget rejects stateful inputs, evolution-without-local-Newton, >1 tangent (moose_material.cpp:456-509); StandaloneCxx accepts nearly everything. A generic driver (e.g.recipe_registry_gen) can only find out by catchingstd::runtime_error— the direct cause of the registry-generator abort issue.Proposal (additive, non-breaking):
[[nodiscard]] virtual auto can_emit(ConstitutiveModel const&) const -> std::expected<void, std::string>;default implementation may conservatively return success ("try emit"). Concrete targets refactor their existing guard blocks to feed bothcan_emitandemitfrom one place, keeping the excellent reject-loudly messages.The "reject loudly, never silently drop" policy itself is right and should stay — this only makes rejection queryable. Related: #93 (factory formalization), registry-abort issue.