Applied MASD
Table of Contents
- Summary
- Detail
- Logical space → entity models and the four-layer architecture
- Metatypes, facets, archetypes, and transforms
- Physical space → technical spaces, profiles, and templates
- Projections and the two codegen routes
- Variability → facet_catalogue.org and element-scope binding
- The facet catalogue
- The currency reference implementation and backout strategy
- Automation spectrum
- The six principles, applied
- See also
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 (
.orgauthored files undermodeling/). - 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_headerarchetype binds todomain_entity; it does not apply toenumerationorjunction. - 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:
currencyis a logical entity with metatypedomain_entity.- A developer runs
compass codegen generate --model ores.refdata.currency.org --profile domain. - The transform (
ores.codegen) reads the model, confirms the metatype isdomain_entity. - It resolves the
domainfacet fromfacet_catalogue.org. - The
domainfacet contains three archetypes that bind todomain_entity:domain::entity_header→currency.hppdomain::json_io_header→currency_json_io.hppdomain::json_io_implementation→currency_json_io.cpp
- 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_header → currency.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 bygenerator.py. - The Mustache template directory under
projects/ores.codegen/library/templates/— the archetype catalogue, where each.mustachefile 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--addressfilter 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'sores.*binding is its supported set (what it can generate); the CLI--addressis the target set (what to generate this run; default = full supported set). What generates = target ∩ supported. Target ∩ supported = ∅ for an entity → warning.--profileis 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 |
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.
- Commission
currencyby hand — every layer written without generator involvement.currencyis the reference implementation. - Identify the SRPPs — the entity evaluation checklist formalises what "fully commissioned" means at each layer; patterns identical across all checklist items are extraction candidates.
- Encode each SRPP as a Mustache archetype parameterised by the entity model.
- Register the archetypes in facet_catalogue.org.
- Verify zero drift — run the generator against the
currencymodel and diff against the hand-written files; a zero diff confirms faithful extraction. - 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
- Focus Narrowly — the generator produces mechanical layers (C++ plumbing, SQL DDL, Qt boilerplate) but never domain logic inside a service class.
- Integrate Pervasively —
ores.codegenis invoked viacompass, emits files that slot into CMake targets and the existing layout, and carries the standard licence header and editor modeline. - Evolve Gradually — each new profile is added when a second real entity needs it; commissioning surfaces SRPPs, which become archetypes, which become profiles.
- Govern Openly — all templates, models, and profiles sit in the open repo under the same review as production code.
- Standardise Judiciously — Mustache, JSON, and Python at the core; artefacts conform to project conventions.
- Assist and Guide — the automation spectrum above; ORE Studio currently operates between Level 2 and Level 3.
See also
MASD methodology (knowledge)
- MASD — the methodology and conceptual model this document applies.
- Logical Space, Physical Space, Technical Space, Facet, Variability — the individual concept docs.
ORE Studio physical and system model
- ORE Studio Technical Spaces — the concrete TS→Part→Facet→Archetype model.
- ORE Studio Variability Model — facet_catalogue.org, model types, activation.
- System Model — the four-layer architecture as physical-space instances.
- Component architecture — API/core/service split across components.
- Entity lifecycle — layer ordering and conventions for a full-stack entity.
ORE Studio tooling
- ores.codegen — the generator; inputs, templates, profiles, recipes.
- ores.codegen architecture — directory layout and template system.
- ores.refdata entity evaluation checklist — the "fully commissioned" fitness function.
- Domain Type Creator — the skill that generates all facets of an entity.