Story: Codegen unified model — Phase 3: unify temporal/non-temporal templates

Table of Contents

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

Goal

The C++ template library has two parallel families for domain types:

Temporal (versioned, full audit trail) Non-temporal (read-only, no audit columns)
cpp_domain_type_entity.hpp.mustache cpp_domain_type_entity_non_temporal.hpp.mustache
cpp_domain_type_entity.cpp.mustache cpp_domain_type_entity_non_temporal.cpp.mustache
cpp_domain_type_mapper.hpp.mustache cpp_domain_type_mapper_non_temporal.hpp.mustache
cpp_domain_type_mapper.cpp.mustache cpp_domain_type_mapper_non_temporal.cpp.mustache
cpp_domain_type_repository.hpp.mustache cpp_domain_type_repository_non_temporal.hpp.mustache
cpp_domain_type_repository.cpp.mustache cpp_domain_type_repository_non_temporal.cpp.mustache

Six template pairs, 12 files total. Every bug fix or enhancement must be applied twice. When one family diverges from the other, non-temporal entities silently get outdated patterns.

This story merges each pair into a single template controlled by an is_temporal boolean in the unified model. Temporal behaviour is enclosed in {{#is_temporal}} / {{/is_temporal}} Mustache conditional blocks. The profiles non-temporal-domain, non-temporal-repository, and non-temporal are retired; the domain, repository, and all-cpp profiles handle both.

This story can run in parallel with Phase 2: single model file per entity because it touches templates and profiles, not model files.

See Codegen architecture analysis and unified model roadmap for context.

Status

Field Value
State ABANDONED
Parent sprint Sprint 22
Now Superseded by deletion: the entire non-temporal family (SQL + C++ facets, archetypes, templates) was removed during the single-model consolidation because no entity used it. Nothing to merge.
Waiting on A real non-temporal entity to be commissioned — at which point temporality returns as an is_temporal variability point, verifiable against that entity.
Next Re-add is_temporal variability to the unified create/domain/repository templates when first needed (not before — an unverifiable branch is worse than its absence).
Last touched 2026-06-28

Acceptance

  • Six _non_temporal template files are deleted.
  • The corresponding temporal templates each contain {{#is_temporal}} blocks covering audit-column generation, version-bump logic, and history queries.
  • All existing temporal entities produce zero diff against their current output.
  • All existing non-temporal entities produce zero diff against their current output.
  • profiles.json no longer contains non-temporal-domain, non-temporal-repository, or non-temporal profiles.
  • The all-cpp profile correctly generates both temporal and non-temporal entities based on the is_temporal field (defaulting to true if absent).
  • All models that previously required non-temporal profiles have is_temporal: false in their model file.
  • CI passes. Site builds cleanly.

Tasks

Task State Start End Description
Task: Diff temporal and non-temporal template pairs; write merge plan ABANDONED     Moot: the non-temporal family was deleted (unused), so there are no pairs to merge.
Task: Merge template pairs and add is_temporal conditionals ABANDONED     Moot: superseded by deletion. The is_temporal variability point will be added when a non-temporal entity is first commissioned (see Decisions).
Task: Verify zero diff and retire non-temporal profiles ABANDONED     Superseded: the non-temporal* profiles and the six (in fact 21) non-temporal template/archetype/facet files were removed during the single-model consolidation.

Decisions

  • Delete-first, not merge-first (2026-06-28). The non-temporal family was entirely unused: no model declared it, nothing generated the created_at shape, and under --address the non-temporal facets were silently default-enabled for every domain entity (a latent collision). Rather than merge two families where one had no users, the whole non-temporal family was deleted during the single-model consolidation (21 template/archetype/facet files + the non-temporal* profile entries in generate.py). Temporality becomes an is_temporal variability point on the single model + unified templates, added only when a genuinely non-temporal entity is first commissioned and the is_temporal=false branch can be verified against it. This story's original "merge six pairs" plan is therefore moot; the residual work is the deferred is_temporal variability above.
  • is_temporal defaults to true. All existing temporal models are unaffected — they do not need the field added. Only non-temporal models need is_temporal: false. This is the safer default because temporal is the common case.
  • Merge into the temporal template, not a neutral template. The temporal template is the superset. Wrapping temporal-only sections in {{#is_temporal}} is simpler than creating a third neutral template and routing both families to it.

Out of scope

  • cpp_domain_type_class_non_temporal.hpp.mustache — the non-temporal domain class template. Evaluate during Task 1 whether to include in the merge.
  • sql_schema_non_temporal_create.mustache — a separate SQL concern, not part of the C++ template family.
  • Qt templates — Qt does not have a temporal/non-temporal split.

Emacs 29.3 (Org mode 9.6.15)