Entity commissioning process reference

Table of Contents

1. Purpose

Commissioning an entity means bringing it to a fully operational and trustworthy state across every access layer: the generated code must match what the templates produce, the hand-written code must satisfy the per-layer criteria in the * Commissioning criteria by layer section, and the operator must be able to interact with the entity through every supported interface (Qt, shell) without regression.

The commission stories in sprint planning exist to drive this work to completion, one entity at a time. This reference document defines what "done" means at each layer and how to structure the work so it can be tracked mechanically.

The retired manual-tracking docs (Entity Coverage Matrix, Domain entity evaluation checklist, Entity Catalogue) were folded into this reference and into the per-component drift stories in 2026-09-03.

2. Entity meta-types

Two meta-types exist. They share most layers but differ in expected UI surface.

Meta-type Examples Characteristic
Domain entity currency, party, book Full CRUD UI, own MDI window, shell commands, manual chapter
Auxiliary type rounding_type, monetary_nature, party_type Lookup table; appears as a dropdown in a domain entity's detail dialog; may have its own MDI window but that is secondary

The * Commissioning criteria by layer section below documents which items apply to each meta-type (Always / If applicable / N/A per meta-type per item).

3. Commissioning criteria by layer

What done means at each layer. Ported whole from the retired Domain entity evaluation checklist (2026-09-03) so the criteria stay in one place. The Domain/Aux columns show whether an item applies to a domain entity or to an auxiliary (lookup) type: Always / Usually / If applicable / N/A. The What to look for column names the artefact or the check. See the criteria provenance notes at the end of this section.

3.1. DB layer

Item Description Domain Aux What to look for
Table exists DDL file exists for the entity Always Always projects/ores.sql/create/refdata/refdata_<entity>s_create.sql
tenant_id column Multi-tenancy isolation Usually Always tenant_id uuid not null — omit only for truly global domain entities (currencies, countries)
version column Optimistic locking Always Always version integer not null
modified_by column Audit: who edited Always Always modified_by text not null
performed_by column Audit: which service performed it Always Always performed_by text not null; set by trigger to ores_iam_current_service_fn()
change_reason_code column Change tracking Always Always change_reason_code text not null
change_commentary column Change tracking Always Always change_commentary text not null
valid_from / valid_to Temporal history Always Always valid_from timestamp with time zone not null, valid_to timestamp with time zone not null
CHECK: temporal order Prevents invalid ranges Always Always check ("valid_from" < "valid_to")
CHECK: natural key not empty Data integrity Always Always check ("iso_code" <> '') or equivalent
GIST exclusion constraint Prevents temporal overlaps Always Always exclude using gist (tenant_id WITH =, <key> WITH =, tstzrange(valid_from, valid_to) WITH &&)
Primary key Uniqueness Always Always (tenant_id, <natural_key>, valid_from, valid_to)
Version unique index Fast lookup of current version Always Always UNIQUE (tenant_id, <key>, version) WHERE valid_to = ores_utility_infinity_timestamp_fn()
Natural key unique index Fast lookup of current record Always Always UNIQUE (tenant_id, <key>) WHERE valid_to = ores_utility_infinity_timestamp_fn()
Tenant index Tenant-scoped scans Always Always INDEX (tenant_id) WHERE valid_to = ores_utility_infinity_timestamp_fn()
display_order column Dropdown ordering N/A Always display_order integer not null default 0
description column Human-readable meaning of code N/A Always description text not null
Insert trigger Version management + validation Always Always create or replace function ores_refdata_<entity>s_insert_fn()
Insert trigger: security definer + set search_path Prevents search-path injection attacks Always Always Function header must carry security definer and set search_path = public, pg_temp. Without both, a service role with a manipulated search path can shadow ores_*_tbl references and bypass validation. See Commission: country § Analysis; rule is in PostgreSQL architecture § Insert trigger patterns.
Soft-delete rule History-preserving delete Always Always on delete to ... do instead update ... set valid_to = current_timestamp
Validation function Allows parent entities to validate soft-FK Always Always create or replace function ores_refdata_validate_<entity>_fn(p_tenant_id uuid, p_value text)
Validation function: security definer + set search_path Independently secure for direct-call use Always Always Validate functions must carry both attributes independently of their callers. security definer does not propagate from caller to callee. See Commission: country § Analysis.
Validation function: bootstrap checks active rows Bootstrap pass-through must use valid_to filter Always Always The not exists bootstrap guard must include and valid_to = ores_utility_infinity_timestamp_fn(). Without it, a table with only soft-deleted rows skips the pass-through and fails with a misleading "Must be one of: (empty list)" error. See Commission: country § Analysis.
Entity-specific soft-FK validations Trigger validates referenced lookup values Always N/A new.rounding_type : ores_refdata_validate_rounding_type_fn(…)=
party_id soft-reference Party-scoped entity If applicable N/A Domain only; check party_id uuid not null and trigger validation
workspace_id soft-reference Workspace-scoped entity If applicable N/A Domain only
coding_scheme_code column Optional DQ coding scheme link If applicable N/A coding_scheme_code text (nullable); validated in trigger if present

3.2. Codegen layer

Item Description Domain Aux What to look for
Domain entity model Codegen model for the C++ domain struct Always Always projects/ores.refdata/modeling/ores.refdata.<entity>.org, * C++ section
Entity model Codegen model for the ODB entity + mapper Always Always projects/ores.refdata/modeling/ores.refdata.<entity>.org, * SQL and * Repository sections
Both models consistent with DB schema Model fields match DB columns Always Always Compare model field names/types against DDL columns
No hand-crafted divergence Generated files match what codegen would produce Always Always If a generated file has been edited manually, flag as drift risk

3.3. Domain layer (C++)

Item Description Domain Aux What to look for
Domain struct Plain-data C++ struct Always Always projects/ores.refdata.api/include/ores.refdata.api/domain/<entity>.hpp
All business columns represented No column missing from struct Always Always Compare struct fields against DDL columns (temporal managed by trigger, not struct)
display_order field Present for aux types N/A Always int display_order = 0;
description field Present for aux types N/A Always std::string description;
recorded_at or equivalent Exposes insert timestamp (maps to DB valid_from) Always Always std::chrono::system_clock::time_point recorded_at;
Canonical C++ types No raw pointers, no inheritance Always Always std::string, std::optional<T>, boost::uuids::uuid, int, bool
No logic in struct Plain data only Always Always No methods beyond constructors; no business logic

3.4. Repository layer (C++)

Item Description Domain Aux What to look for
Entity class ODB-annotated wrapper Always Always ores.refdata.core/include/.../repository/<entity>_entity.hpp
Mapper class DB row ↔ domain struct conversion Always Always repository/<entity>_mapper.hpp
Repository class Data access object Always Always repository/<entity>_repository.hpp
list, count, save, delete, get Core CRUD operations Always Always All five methods present in repository header
get_history Temporal history query Always Always Method returning all versions for a given key
list_for_party Party-scoped list If applicable N/A Only for party-scoped domain entities
Tenant-scoped queries Queries filtered by tenant_id Usually Always WHERE clause includes tenant_id condition

3.5. Service layer (C++)

Item Description Domain Aux What to look for
Service class Business logic + authorization wrapper Always Always ores.refdata.core/include/.../service/<entity>_service.hpp
list, count, save, delete, get, get_history Full CRUD + history Always Always All six methods present in service header
list_for_party Party-scoped list If applicable N/A Domain only
Authorization checks Caller permission validated Always Always Authorization call before data access
NATS event firing on mutation Events published on save and delete Always Always NATS publish calls in save and delete implementations
Registered in the LISTEN/NOTIFY→NATS relay Entity's DB notify channel is republished to NATS Always Always grep <entity> projects/ores.<component>/service/src/app/application.cpp — expect an include, a register_mapping<...>, and a subscribe<...> block; this file is hand-maintained (no AUTO-GENERATED marker) and is easy to miss when commissioning a new entity. See Commission: party_type — party_type (and ~14 other entities) had a generated _changed_event.hpp but was never wired into this file, so eventing silently never fired despite the SQL trigger and service-layer publish call both being correct.

3.6. Messaging / JSON IO layer (C++)

Item Description Domain Aux What to look for
JSON struct rfl-based serialisation struct Always Always ores.refdata.api/include/.../domain/<entity>_json.hpp
IO handler domain ↔ JSON conversion Always Always domain/<entity>_json_io.hpp
Protocol header NATS message type definitions Always Always messaging/<entity>_protocol.hpp
Mutation message types Save/delete request + saved/deleted event Always Always save_<entity>, delete_<entity>, <entity>_saved, <entity>_deleted in protocol header
Query message types List, count, get, history Always Always list_<entity>s, count_<entity>s, get_<entity>, get_<entity>_history in protocol header

3.7. Qt layer

Item Description Domain Aux What to look for
MDI list window Top-level window in MDI area Always If applicable ores.qt.refdata/include/ores.qt/<Entity>MdiWindow.hpp
Detail dialog Single-record edit/view Always If applicable <Entity>DetailDialog.hpp
History dialog Temporal history for a record Always If applicable <Entity>HistoryDialog.hpp
Controller Wires windows to service Always If applicable <Entity>Controller.hpp
Client model Qt model/view data model Always If applicable Client<Entity>Model.hpp
Dropdown populated in parent dialog Aux type appears as a combo box choice N/A Always Check parent entity's DetailDialog.cpp for a combo box loading this type
Import dialog Bulk import support If applicable N/A Import<Entity>Dialog.hpp — not all entities have this
List window loads post-NATS Manual verification Always If applicable Open app, navigate to entity MDI window, records appear
Detail dialog edit + save round-trip Manual verification Always If applicable Edit a field, save, reopen — change persisted
History dialog shows correct history Manual verification Always If applicable After edit, history dialog shows two versions
Delete preserves history Manual verification Always If applicable Delete record; history dialog still shows prior versions
NATS eventing cross-session Manual verification Always If applicable Mutation in client A appears in client B without refresh

3.8. Shell layer (ores.shell interactive REPL)

Item Description Domain Aux What to look for
Submenu registered Entity has a dedicated submenu in the REPL Always If applicable projects/ores.shell/src/app/commands/<entity>s_commands.cpp registered in menu
list command Lists records from service Always If applicable list case in the commands file
add / save command Creates or updates a record Always If applicable add or save case
remove / delete command Deletes a record Always If applicable remove or delete case
history command Shows temporal history Always If applicable history case
Post-NATS service wiring Commands call service via NATS, not directly Always If applicable Service calls use NATS client, not direct repository

3.9. Scripted shell layer (ores.shell)

Item Description Domain Aux What to look for
list subcommand Non-interactive list Always If applicable Subcommand registered and implemented
add / save subcommand Non-interactive create/update Always If applicable Subcommand registered and implemented
remove / delete subcommand Non-interactive delete Always If applicable Subcommand registered and implemented
Post-NATS service wiring Commands call service via NATS Always If applicable Same as REPL

3.10. HTTP layer

Item Description Domain Aux What to look for
GET list route REST list endpoint Always If applicable GET /refdata/<entity>s in routes file
POST save route REST create/update endpoint Always If applicable POST /refdata/<entity>s
DELETE batch route REST batch delete endpoint Always If applicable DELETE /refdata/<entity>s
GET history route REST history endpoint Always If applicable GET /refdata/<entity>s/:id/history
Routes registered Routes wired into the HTTP server Always If applicable Entry in projects/ores.http.core/src/routes/

3.11. Wt web UI layer

Item Description Domain Aux What to look for
List widget Wt list component Always If applicable projects/ores.wt.service/include/.../app/<entity>_list_widget.hpp
Detail dialog Wt edit component Always If applicable <entity>_dialog.hpp
Wired into Wt app Widget registered in application Always If applicable Reference in Wt app class
List + edit round-trip Manual verification Always If applicable Open Wt app, list entity, edit, save — change persisted

3.12. Manual

Item Description Domain Aux What to look for
Entity chapter Dedicated chapter in user guide Always If applicable doc/manual/user_guide/<entity>.org or equivalent
What and why Entity described for a user, not a developer Always If applicable First section: what this entity is, when to use it
Qt MDI window documented List window walkthrough Always If applicable Screenshot or description of columns and actions
Qt detail dialog documented Field-by-field documentation Always If applicable Table of fields with type, validation, and meaning
Qt history dialog documented History usage explained Always If applicable How to view and interpret change history
Shell commands documented All shell commands with examples Always If applicable #+begin_example blocks showing command + output
Aux type documented in parent chapter Valid values listed and explained N/A Always Subsection in parent entity chapter: table of codes + descriptions
Indexed from manual root Chapter reachable from table of contents Always If applicable Entry in doc/manual/user_guide/index.org or equivalent
Site builds cleanly No broken links or missing files Always Always make site passes without error

3.13. Criteria provenance

4. Codegen system overview

Every entity in ores.refdata (and other components) has an org model file in projects/ores.refdata/modeling/ores.refdata.{entity}.org. The codegen system reads these models and, for each profile requested, renders Mustache templates and writes the output to the corresponding project directory.

The three critical variables that determine output paths are set in the entity model (* C++ / ** Flags section):

Variable Set in Example (refdata) What it controls
component top-level #+component: refdata SQL output, Qt component dir
component_include :component_include: refdata.api API/include paths for domain, generator, protocol, nats-eventing
component_core :component_core: refdata.core Core paths for repository, service, nats-handler

Critical rule: if component_include or component_core is missing from the entity model, generator.py silently falls back to component (e.g. refdata). This resolves to projects/ores.refdata/ (not an active project directory) and writes files into an untracked directory. Git sees no diff against HEAD — a false-clean result. Every entity model must have both fields set explicitly. See Codegen model safety guardrails for the planned guard.

4.1. How to run codegen

# Run a single profile for one entity (recommended for targeted sync)
./projects/ores.codegen/codegen.sh regenerate \
    --component refdata --profile qt \
    --entity rounding_type

# Run a single profile for all entities in a component (generates everything)
./projects/ores.codegen/codegen.sh regenerate \
    --component refdata --profile qt

When running --component without --entity (once that flag lands; see Codegen developer experience improvements):

4.2. Post-run cleanup

After running --component mode, discard out-of-scope generated files:

# Revert tracked files modified for non-target entities
git checkout HEAD -- projects/ores.qt/refdata/

# Remove untracked new files generated for entities not in target set
git status --short | grep '^?' | awk '{print $2}' | xargs rm -f

5. Codegen output map

Complete map of profile → template → output file, using rounding_type in refdata as the reference (component=refdata, component_include=refdata.api, component_core=refdata.core).

5.1. sql profile

Supported model types: domain_entity, junction, schema, table

Template Output path
sql_schema_domain_entity_create projects/ores.sql/create/refdata/refdata_rounding_types_create.sql
sql_schema_notify_trigger projects/ores.sql/create/refdata/refdata_rounding_types_notify_trigger_create.sql
sql_schema_domain_entity_drop projects/ores.sql/drop/refdata/refdata_rounding_types_drop.sql
sql_schema_notify_trigger_drop projects/ores.sql/drop/refdata/refdata_rounding_types_notify_trigger_drop.sql

⚠ Known issue (open): The sql profile also fires sql_schema_domain_entity_create for domain_entity models alongside the newer sql_schema_create for table models. Entities that have both a _table.json and a domain_entity model have two codegen paths to the same file. See Codegen model safety guardrails (C1 concern).

5.2. domain profile

Supported model types: schema, domain_entity

Template Output path
cpp_domain_type_class.hpp projects/ores.refdata/api/include/ores.refdata.api/domain/rounding_type.hpp
cpp_domain_type_json_io.hpp projects/ores.refdata.api/include/ores.refdata.api/domain/rounding_type_json_io.hpp
cpp_domain_type_json_io.cpp projects/ores.refdata.api/src/domain/rounding_type_json_io.cpp
cpp_domain_type_table.hpp projects/ores.refdata.api/include/ores.refdata.api/domain/rounding_type_table.hpp
cpp_domain_type_table.cpp projects/ores.refdata.api/src/domain/rounding_type_table.cpp
cpp_domain_type_table_io.hpp projects/ores.refdata.api/include/ores.refdata.api/domain/rounding_type_table_io.hpp
cpp_domain_type_table_io.cpp projects/ores.refdata.api/src/domain/rounding_type_table_io.cpp

⚠ Known path inconsistency (open): The class template uses projects/ores.{component}/api/ → projects/ores.refdata/api/ (correct, follows the actual directory layout). The six secondary templates use projects/ores.{component_include}/ → projects/ores.refdata.api/ (a non-existent top-level directory). Git sees those six files as untracked, giving a false-clean diff. Status: pre-existing bug; deferred to Refactor ores.codegen C++ generation.

5.3. generator profile

Supported model types: schema, domain_entity

Template Output path
cpp_domain_type_generator.hpp projects/ores.refdata.api/include/ores.refdata.api/generators/rounding_type_generator.hpp
cpp_domain_type_generator.cpp projects/ores.refdata.api/src/generators/rounding_type_generator.cpp

5.4. repository profile

Supported model types: schema, domain_entity

Template Output path
cpp_domain_type_entity.hpp projects/ores.refdata.core/include/ores.refdata.core/repository/rounding_type_entity.hpp
cpp_domain_type_entity.cpp projects/ores.refdata.core/src/repository/rounding_type_entity.cpp
cpp_domain_type_mapper.hpp projects/ores.refdata.core/include/ores.refdata.core/repository/rounding_type_mapper.hpp
cpp_domain_type_mapper.cpp projects/ores.refdata.core/src/repository/rounding_type_mapper.cpp
cpp_domain_type_repository.hpp projects/ores.refdata.core/include/ores.refdata.core/repository/rounding_type_repository.hpp
cpp_domain_type_repository.cpp projects/ores.refdata.core/src/repository/rounding_type_repository.cpp

5.5. service profile

Supported model types: schema, domain_entity

Template Output path
cpp_service.hpp projects/ores.refdata.core/include/ores.refdata.core/service/rounding_type_service.hpp
cpp_service.cpp projects/ores.refdata.core/src/service/rounding_type_service.cpp

5.6. protocol profile

Supported model types: domain_entity, schema

Template Output path
cpp_protocol.hpp projects/ores.refdata.api/include/ores.refdata.api/messaging/rounding_type_protocol.hpp

5.7. nats-eventing profile

Supported model types: domain_entity, schema

Template Output path
cpp_nats_changed_event.hpp projects/ores.refdata.api/include/ores.refdata.api/eventing/rounding_type_changed_event.hpp

5.8. nats-handler profile

Supported model types: domain_entity, schema

Template Output path
cpp_nats_handler.hpp projects/ores.refdata.core/include/ores.refdata.core/messaging/rounding_type_handler.hpp

5.9. qt profile

Supported model types: domain_entity only

Template Output path
cpp_qt_client_model.hpp projects/ores.qt/refdata/include/ores.qt/ClientRoundingTypeModel.hpp
cpp_qt_client_model.cpp projects/ores.qt/refdata/src/ClientRoundingTypeModel.cpp
cpp_qt_mdi_window.hpp projects/ores.qt/refdata/include/ores.qt/RoundingTypeMdiWindow.hpp
cpp_qt_mdi_window.cpp projects/ores.qt/refdata/src/RoundingTypeMdiWindow.cpp
cpp_qt_detail_dialog.hpp projects/ores.qt/refdata/include/ores.qt/RoundingTypeDetailDialog.hpp
cpp_qt_detail_dialog.cpp projects/ores.qt/refdata/src/RoundingTypeDetailDialog.cpp
cpp_qt_history_dialog.hpp projects/ores.qt/refdata/include/ores.qt/RoundingTypeHistoryDialog.hpp
cpp_qt_history_dialog.cpp projects/ores.qt/refdata/src/RoundingTypeHistoryDialog.cpp
cpp_qt_controller.hpp projects/ores.qt/refdata/include/ores.qt/RoundingTypeController.hpp
cpp_qt_controller.cpp projects/ores.qt/refdata/src/RoundingTypeController.cpp
qt_detail_dialog_ui projects/ores.qt/refdata/ui/RoundingTypeDetailDialog.ui
qt_history_dialog_ui projects/ores.qt/refdata/ui/RoundingTypeHistoryDialog.ui

6. Drift classification

Every difference between what codegen produces and what is in the repository must be classified before any fix is applied. The direction of the fix depends on the category.

Category Definition Fix direction Examples
Template gap Template does not support a feature that the code correctly has Fix template has_change_reason_cache not in controller template; UiPersistence missing; version history method not generated
Template bug Template produces structurally wrong output Fix template Wrong include guard prefix; wrong NATS channel name; wrong field name
Code bug Code diverged from what the template produces, incorrectly Fix code Wrong field name in protocol access (result->rounding_types vs result->types); typo in string literal
Cosmetic drift Formatting difference only; no semantic difference Accept drift Include ordering (user before system); constructor initialiser style; connect() arg alignment
Model-driven improvement Template update from org model produces better output (doc, naming) Accept new output @brief rewrite from model; example values capitalised; display_order = 0 default init
Out-of-scope Drift in a file belonging to a different entity or component Discard Files for entities not in the target set generated by --component run

Rule: never accept drift silently. Every category must be recorded in the task's * Review or * Notes table with a "Decision" column entry.

7. Known open path issues (as of 2026-06-25)

Issue Status Owner story
Domain secondary templates (json_io, table, table_io) write to projects/ores.refdata.api/ (untracked) instead of projects/ores.refdata/api/ Open — false-clean diffs; files untracked so git shows no diff Refactor ores.codegen C++ generation
sql profile dual-fires old and new SQL templates on domain_entity models Open — parallel SQL codegen paths exist Codegen model safety guardrails
No guard in generator.py when component_include falls back to component Open — produces false-clean untracked output Codegen model safety guardrails
13 spurious ERROR lines when running qt profile against refdata-cpp (table + junction models) Open — noise but not a real failure Codegen developer experience improvements
--component runs generate all entities; no --entity filter Open — requires manual cleanup Codegen developer experience improvements
Qt output paths used dot notation (ores.qt.{component}) instead of slash Fixed in PR #1311 Closed
Entity models missing .api segment in domain_include=/=protocol_include Fixed in PR #1311 for the 3 auxiliary entities Closed

8. Standard commission story structure

A commission story should have exactly the following tasks. The table below is the canonical task list; mark N/A for items genuinely not applicable to the entity with a brief reason.

# Task Applies to Notes
1 Appraise: score all layers using the evaluation checklist Always First task; findings drive the rest
2 Verify and fix SQL Always DDL criteria from checklist; security-definer, bootstrap guard, GIST exclusion
3 Sync codegen: sql profile Always Zero-diff or sign-off every delta
4 Sync codegen: domain profile Always Watch for false-clean (secondary templates write to untracked path)
5 Sync codegen: repository profile Always  
6 Sync codegen: service profile Always  
7 Sync codegen: generator profile Always  
8 Sync codegen: protocol profile Always  
9 Sync codegen: nats-eventing profile Always  
10 Sync codegen: nats-handler profile Always  
11 Sync codegen: qt profile Domain always; Aux if Qt window exists 12 output files per entity
12 Verify and fix shell commands Always list, add/save, remove, history; post-NATS wiring
13 Verify Qt UI end-to-end Domain always; Aux if Qt window exists MDI list, detail, history, delete, eventing
14 Write documentation Always Manual chapter, shell recipe, NATS message reference
15 File Wt and HTTP gap captures Always Backlog only — not in-sprint tasks

Tasks 3–11 (codegen sync) are often grouped into one or two tasks per sprint for efficiency, but must each produce a signed-off diff table (zero diff or explicit accept/fix decision per file).

8.1. Codegen sync task acceptance criteria

A codegen sync task for any profile is complete when:

  1. Output location check (do this first, before diffing): every generated file lands in the correct split project directory, not in the monolith:

    Profile Expected root Wrong root (monolith — do NOT write here)
    domain (class template) projects/ores.{component}/api/ (same path, check secondary templates)
    domain (secondary: json_io, table, table_io) projects/ores.{component_include}/ projects/ores.{component}/api/
    generator projects/ores.{component_include}/ projects/ores.{component}/api/
    repository projects/ores.{component_core}/ projects/ores.{component}/core/
    service projects/ores.{component_core}/ projects/ores.{component}/core/
    protocol projects/ores.{component_include}/ projects/ores.{component}/api/
    nats-eventing projects/ores.{component_include}/ projects/ores.{component}/api/
    nats-handler projects/ores.{component_core}/ projects/ores.{component}/core/
    qt projects/ores.qt/{component}/ (no split variant; single path)

    For refdata (component_include=refdata.api, component_core=refdata.core):

    • API headers → projects/ores.refdata.api/include/ores.refdata.api/
    • Core headers → projects/ores.refdata.core/include/ores.refdata.core/

    If a file appears as untracked under projects/ores.refdata/ after running codegen, the output went to the wrong location. Check component_include / component_core in the entity model (* C++ / ** Flags).

  2. Every generated file either: a. Produces zero diff against the corresponding hand-written file in the monolith (projects/ores.{component}/{api,core}/), or b. Has its delta classified (category from the drift table above) and the decision recorded (fix template / fix code / accept).
  3. All "fix template" decisions have a corresponding template commit.
  4. All "fix code" decisions have a corresponding code commit with justification.
  5. All "accept" decisions are recorded in the task's * Notes or * Review table.
  6. No generated files for non-target entities have been left modified.
  7. The build passes (no C++ regressions).

8.2. Commit discipline

  • One commit per logical fix (template fix, code fix, or model update).
  • Never amend commits on a branch under review.
  • Never use git add -A — add files individually to avoid committing generated files for unrelated entities.

9. See also

Emacs 29.3 (Org mode 9.6.15)