Applied MASD

Table of Contents

Summary

This document is the applied counterpart to MASD. Where the knowledge docs describe the methodology as an observation of the external world, this one shows how ORE Studio instantiates each concept: how the logical space maps to authored entity models and the four-layer architecture, how the physical space maps to technical spaces, profiles, and Mustache templates, and how variability maps to facet_catalogue.org. ORE Studio ports MASD's ideas to LLMs and NLP rather than to a formal meta-meta-model: the underlying concepts are encoded in skills and recipes an LLM can understand and apply.

Detail

Logical space → entity models and the four-layer architecture

ORE Studio's logical entities are authored as literate org-mode model files under each component's modeling/ directory. Most reference-data entities are value types — immutable records identified by a code rather than an object identity (see the entity types in Logical Space).

ORE Studio does not expose a formal M3 meta-meta-model. Instead:

  • The implicit meta-model is the entity model file schema (.org authored files under modeling/).
  • MASD's meta-layer and meta-component concepts are physically instantiated as ORE Studio's four architectural layers and ores.* CMake targets.
  • Skills and recipes encode the meta-rules an LLM applies when authoring a new model — the equivalent of a formal meta-language in classical MDE.
MASD meta-concept ORE Studio instance (physical)
meta-layer a layer (e.g. the domain layer)
meta-component a component (e.g. ores.refdata.api)
meta-facet a facet (e.g. the domain facet of C++ TS)
meta-archetype an archetype (e.g. currency.hpp domain header)

The four layers (foundation / infrastructure / domain / application) and the components within them are therefore physical-space instances of the meta-layer and meta-component concepts. This is documented from the architecture perspective in System Model.

Metatypes, facets, archetypes, and transforms

This section explains the core MASD vocabulary as it applies in ORE Studio, working from first principles with a concrete example at each step.

Entity

An entity is a concept in the logical model — something the domain cares about. Examples: currency, country, book. An entity is what a developer authors in an org-mode model file under modeling/. It is a logical object: it has fields and relationships, but no language, no file, no namespace yet.

Metatype

Every entity has a metatype — the classification of what kind of entity it is. The metatype is not a property of the entity in the domain sense; it is metadata about the entity that the code generator uses to decide which archetypes to apply.

Examples of metatypes in ORE Studio:

Metatype Meaning
domain_entity A full domain object: has fields, persists to a table, is exposed via a service. currency, country, book are all domain_entity.
junction An association entity joining two domain entities (no independent identity).
enumeration A closed, named set of values. book_status is an enumeration.
field_group A reusable cluster of fields shared across entities; produces no standalone artefacts.
component A CMake component descriptor; generates build scaffolding rather than domain artefacts.

The metatype is distinct from the entity's identity. currency is the entity; domain_entity is its metatype. Saying "currency is a type" is true in the programming-language sense but wrong in the MASD sense — in MASD, currency is an instance of the metatype domain_entity.

A note on UML stereotypes. In UML, a stereotype is the mechanism for attaching metadata to a model element — you annotate an element with <<value>> to indicate it is a value type. In ORE Studio we do not use UML or stereotypes: models are authored in org-mode and metadata is conveyed through the file's frontmatter (#+options, property drawers, and heading keywords). The concept we care about is the metatype; the mechanism we use is org-mode frontmatter. Do not use "stereotype" to mean "metatype" — they refer to different things.

Transform

A transform is a model-to-text operation that takes a logical entity and produces physical artefacts. In ORE Studio the transform engine is ores.codegen (projects/ores.codegen). It reads the entity's model file, resolves its metatype, selects the applicable archetypes, and renders each one to a file on disk. The act of running the generator for a given entity and profile is one transform execution.

Facet

A facet is a named grouping of related archetypes within a technical space. Think of it as a package or namespace in physical space — not a subdivision of the technical space itself, but a classification of artefacts by the role they play for an entity.

Example: the domain facet groups every archetype that contributes to the domain representation of an entity in C++: the struct header, the JSON I/O header, the JSON I/O implementation. The repository facet groups the archetypes for persistence: entity, mapper, repository (header and implementation for each). These are distinct roles, so they are distinct facets.

Facets are defined in facet_catalogue.org (projects/ores.codegen/library/).

Archetype

An archetype is a single template within a facet — the generating function for exactly one output file. Each archetype:

  • Belongs to exactly one facet.
  • Binds to one or more metatypes: it only fires when the entity's metatype matches. The domain::entity_header archetype binds to domain_entity; it does not apply to enumeration or junction.
  • Is parameterised by the logical model: the entity's name, fields, namespace, and relationships are substituted at render time.
  • Produces one output file — the artefact — per entity it is applied to.

Worked example: currency

Putting it together with a concrete case:

  1. currency is a logical entity with metatype domain_entity.
  2. A developer runs compass codegen generate --model ores.refdata.currency.org --profile domain.
  3. The transform (ores.codegen) reads the model, confirms the metatype is domain_entity.
  4. It resolves the domain facet from facet_catalogue.org.
  5. The domain facet contains three archetypes that bind to domain_entity:
    • domain::entity_headercurrency.hpp
    • domain::json_io_headercurrency_json_io.hpp
    • domain::json_io_implementationcurrency_json_io.cpp
  6. The transform renders each archetype against the model, producing three artefacts on disk.

If the metatype were enumeration instead, the domain facet would apply a different (smaller) set of archetypes — only those that bind to enumeration.

Profile

A profile is an ORE Studio convenience: a named composite that selects multiple facets to activate in a single run. --profile all-cpp activates the domain, generator, repository, service, and protocol facets simultaneously. Profile is not a core MASD concept — MASD talks about facet activation through the variability model; ORE Studio surfaces this as named profiles for ease of use on the command line.

Terminology summary

Term Definition Example
Entity A logical model concept; something the domain cares about. currency, country
Metatype The classification of what kind of entity it is; a type of a type. domain_entity, enumeration
Facet A named grouping of related archetypes within a technical space; a package in physical space. domain, repository, sql
Archetype A template within a facet producing exactly one output file; binds to specific metatypes. domain::entity_headercurrency.hpp
Transform The model-to-text operation that applies archetypes to a logical entity to produce artefacts. Running ores.codegen
Artefact A concrete output file produced by an archetype for a specific entity. currency.hpp
Profile ORE Studio shorthand: a named selection of facets to activate together at invocation time. --profile all-cpp
Physical space binding Element-scope activation via ores.* property-drawer properties; overrides the profile default for a specific entity. :ores.cpp.qt.enabled: false
Technical space The language/platform ecosystem hosting the physical artefacts. C++, SQL, Qt

Terms to avoid and their replacements:

Avoid Use instead Why
type (for metatype) metatype A type is currency; the metatype classifies it as domain_entity.
stereotype metatype Stereotype is a UML mechanism; ORE Studio uses org-mode frontmatter.
layer facet (for a grouping) or technical space (for C++/SQL/Qt) "Layer" is informal and ambiguous.
tier metatype group Invented non-MASD word.

Physical space → technical spaces, profiles, and templates

ORE Studio's physical space is the concrete TS→Part→Facet→Archetype instantiation, indexed in ORE Studio Technical Spaces (with per-TS detail in C++ Technical Space, SQL Technical Space, and Other Technical Spaces). In the C++ TS the canonical parts are include/ and src/; the SQL TS has a single implicit part because its artefacts are not split by compile-time role.

ORE Studio has no compiled Physical Metamodel. The PMM's role is played by two artefacts:

  • facet_catalogue.org (projects/ores.codegen/library/facet_catalogue.org) — the profile catalogue that names every facet and its activation conditions; read directly by generator.py.
  • The Mustache template directory under projects/ores.codegen/library/templates/ — the archetype catalogue, where each .mustache file is one archetype, wrapped in a literate org document that tangles it and documents it.

Projections and the two codegen routes

ores.codegen is a Model-to-Text projector: it takes a model, applies Mustache archetypes parameterised by a profile, and produces physical artefacts. It runs in two routes that share the same machinery but take their input from different sources:

Route Where the model comes from Format Where the model lives
Authored A human (or LLM) writes it. .org projects/ores.<group>/modeling/
Automated A script derives it from already-generated artefacts. .json build/output/codegen/ (gitignored)

The authored route is the common case: domain entities, lookup tables, junctions, and components are maintained by hand in literate org-mode, because the model carries intent other readers need (descriptions, custom-method prose, generator expressions). The org-mode migration story tracks moving the entire authored set off legacy JSON.

The automated route applies when the model is merely derived. The canonical example is the PlantUML ER diagram: a parse stage reads the generated SQL DDL and produces an intermediate JSON model; a render stage feeds it to a Mustache archetype and emits ores_schema.puml. That intermediate model is regenerated every run, carries nothing a human edits, and lives under build/output/ so it stays out of the input tree. projects/ores.codegen/models/ holds authored input only.

Variability → facet_catalogue.org and element-scope binding

ORE Studio does not maintain a formal VMM. Instead facet_catalogue.org serves as its profile catalogue, mapping every profile name (domain, repository, sql, =qt=…) to the templates it activates and the model types they apply to. Three activation scopes are supported:

  • Product scope — composite alias profiles (all, all-cpp, non-temporal) group multiple facets into a named shortcut for invocation time.
  • Component scope — the component manifest (manifest.py) controls discovery roots; an optional --address filter may be supplied at invocation time to restrict generation.
  • Element scope — entity model files declare ores.* properties in their :PROPERTIES: drawer. This is the supported/target set model: the entity's ores.* binding is its supported set (what it can generate); the CLI --address is the target set (what to generate this run; default = full supported set). What generates = target ∩ supported. Target ∩ supported = ∅ for an entity → warning. --profile is removed from the CLI; the entity's binding IS the profile.

    Address syntax follows Dogen's :masd.cpp.enabled: convention, with specificity-ordered resolution (more-specific overrides less-specific):

:PROPERTIES:
:ID: ...
:ores.cpp.enabled: true
:ores.cpp.qt.enabled: false
:END:

The above → supported set = all C++ except Qt. Entities with no ores.* properties: supported set = model-types filter (backward-compatible). The TS→facet map lives in a * Technical spaces section of facet_catalogue.org. All resolution logic is isolated in codegen/physical_space.py with its own unit tests.

For the full treatment — model types, profile catalogue, activation semantics, and the MASD→ORE Studio mapping — see ORE Studio Variability Model.

The facet catalogue

Each facet is generated by one or more ores.codegen profiles and documented by a literate template org file.

C++ technical space

Facet Profile Literate source Archetypes Purpose
Domain --profile domain cpp_domain 3 Temporal domain struct and JSON I/O
Generator --profile generator cpp_domain 2 Test-data generator (sample-value builder)
Repository --profile repository cpp_repository 12 Entity, mapper, repository (temporal + non-temporal)
Messaging --profile protocol cpp_messaging 6 NATS event, handler, protocol types, service
Service application --profile service cpp_service_app 12 Application, host, config options/parser, entry point
Qt UI --profile qt cpp_qt 10 MDI window, controller, detail/history dialogs, client model
Component --profile component cpp_component 6 Umbrella header, export macros, test main, stubs
Model types --profile model-types cpp_model_types 2 Enum class, field-group struct
Table part of --profile domain cpp_table 4 libfort table adapter and I/O

Per-facet references: Type definition facet, Entity lifecycle (repository and service), Service application facet, ORE Studio Messaging Reference (protocol), Qt facet.

SQL technical space

Facet Profile Literate source Archetypes Purpose
Schema --profile sql sql_schema 9 DDL create/drop, notify trigger, junction tables
Service --profile service-sql sql_service 4 Service users, DB grants, IAM accounts and roles
Populate --profile populate sql_populate 13 Reference-data seed scripts

See SQL facet.

CMake, Assets, and Doc technical spaces

Facet Profile Literate source Archetypes Purpose
CMake build --profile cmake cmake 8 Component root, src variants, tests, modeling target
Assets --profile assets assets 4 Qt Designer UI forms, PlantUML ER diagram, shell vars
Documentation --profile doc doc 20 Agile and knowledge docs, skills, recipes, runbooks

See Build facet, Assets facet, Documentation facet.

Manually authored facets

These facets are authored rather than generated, and documented for parity: Shell facet, CLI facet, HTTP facet, Wt facet.

The key attributes of a logical element live in the domain facet — regular C++ defining the domain struct. Each element lives on its native component (e.g. account in ores.iam) and is created via the Domain Type Creator skill, which bundles several facets together; other facets refer to the domain type files to extract the information they need.

The currency reference implementation and backout strategy

ORE Studio applies MASD's reference-implementation backout strategy directly: rather than designing an abstract generator first, it extracts the generator from a proven hand-written entity.

  1. Commission currency by hand — every layer written without generator involvement. currency is the reference implementation.
  2. Identify the SRPPs — the entity evaluation checklist formalises what "fully commissioned" means at each layer; patterns identical across all checklist items are extraction candidates.
  3. Encode each SRPP as a Mustache archetype parameterised by the entity model.
  4. Register the archetypes in facet_catalogue.org.
  5. Verify zero drift — run the generator against the currency model and diff against the hand-written files; a zero diff confirms faithful extraction.
  6. Extend to new entities — commissioning a new entity reduces to authoring its model and running the generator.

Commissioning currency produced the canonical SRPP catalogue for reference-data entities: the C++ domain struct with rfl-based JSON I/O, the repository entity/mapper/CRUD trilogy, the NATS service and protocol types, the SQL DDL and trigger scripts, and the full Qt UI (10 C++ archetypes plus 2 .ui archetypes in the Assets TS).

Automation spectrum

ORE Studio's position on the MASD methodology's automation spectrum:

Level Description ORE Studio status
0 Stub generation only Exceeded
1 One layer generated (e.g. SQL only) Exceeded
2 Multiple layers generated; some manual editing Achieved for SQL, domain
3 Full entity generated with no manual editing Partial (SQL + domain + protocol)
4 Product-line generation: new entity = new model Not yet reached

The immediate goal is Level 3 for the complete entity stack, using currency as the fitness function.

The six principles, applied

  1. Focus Narrowly — the generator produces mechanical layers (C++ plumbing, SQL DDL, Qt boilerplate) but never domain logic inside a service class.
  2. Integrate Pervasivelyores.codegen is invoked via compass, emits files that slot into CMake targets and the existing layout, and carries the standard licence header and editor modeline.
  3. Evolve Gradually — each new profile is added when a second real entity needs it; commissioning surfaces SRPPs, which become archetypes, which become profiles.
  4. Govern Openly — all templates, models, and profiles sit in the open repo under the same review as production code.
  5. Standardise Judiciously — Mustache, JSON, and Python at the core; artefacts conform to project conventions.
  6. Assist and Guide — the automation spectrum above; ORE Studio currently operates between Level 2 and Level 3.

See also

MASD methodology (knowledge)

ORE Studio physical and system model

ORE Studio tooling

Emacs 29.1 (Org mode 9.6.6)