Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ model-level rule and point at the deferred set.

The MDE course requires the compiler to be built with Ecore, Xtext, OCL,
QVT-Operational and Acceleo, so `emf/` holds a second, hand-written Java
implementation (Maven and Tycho, JDK 21, no Eclipse IDE). It is deprecated
implementation (Maven and Tycho, JDK 21, no Eclipse IDE to build, but
loadable in Eclipse for the course's examiners). It is deprecated
from the day it lands and deleted at its sunset:

- **The root stays TypeScript.** Every pom, module, check, ledger and decision
Expand Down
11 changes: 6 additions & 5 deletions docs/mde/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ One directory per deadline, named after the course's own task numbering.

| Directory | Deliverable | Overleaf project | State |
|---|---|---|---|
| [`task-0-proposal/`](task-0-proposal/) | Task 0 — project description, the proposal that must be approved before work starts | `6aa2ba0c3920baa59ec20901` | mirrored 2026-09-11 |
| [`task-0-proposal/`](task-0-proposal/) | Task 0 — project description, the proposal that must be approved before work starts | `6aa2ba0c3920baa59ec20901` | re-mirrored 2026-09-14, after the joint-implementation revision |
| `task-1-metamodelling/` | Task 1 — domain analysis, modelling decisions, the two metamodels and their diagrams, example models | — | not started |
| `task-2-transformations/` | Task 2 — the model-to-model transformation, its rules and limitations, evidence it runs | — | not started |
| `task-3-code-generation/` | Task 3 — the model-to-text transformation, the generated code, evidence it loads | — | not started |
Expand Down Expand Up @@ -48,7 +48,6 @@ documents whose parts are sections rather than chapters.
main.tex root document: preamble, \tableofcontents, \input list
Title/ title page and the University of Twente logo
Sections/ one file per section, numbered in reading order, appendix last
listings/ verbatim inputs for \lstinputlisting — models and generated files
*.sty, *.cfg vendored LaTeX packages, see below
```

Expand Down Expand Up @@ -96,11 +95,13 @@ Taken from the DoSA report, so that the four reports read as one series:
- Headings are Title Case. Sections carry a `\label{sec:…}` and are
cross-referenced as `Section~\ref{…}`; the appendix is `\appendix` plus one
section, so its parts number `A.1`, `A.2` and so on.
- Tables are floats: `\begin{table}[ht]`, centred, `\hline` rules, caption
**below** the table, `\label{tab:…}`.
- Tables are floats: `\begin{table}[!htbp]`, centred, `\small`, ragged-right
`p` columns, `\hline` rules, caption **below** the table, `\label{tab:…}`.
- Front matter is numbered in roman and the body in arabic, with a table of
contents between them.
- Code listings are called **Example**, not Listing (`\lstlistingname`).
- Every cross-reference is a live PDF link; `hyperref` colours them.
- Every cross-reference is a live PDF link; `hyperref` colours them. Prose never
says "the table below" or "the next section": it names the target with
`Table~\ref{…}` or `Section~\ref{…}`.
- Files reproduced from the generator's intended output carry no commentary of
any kind, because the real ones will not.
6 changes: 3 additions & 3 deletions docs/mde/task-0-proposal/Sections/01-problem.tex
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
\section{Problem Statement}
\label{sec:problem}

A Kubernetes service is described by a workload, service, account, network
A Kubernetes application is described by a workload, service, account, network
policy, ingress routes, monitoring rules and disruption budget. These resources
repeat the same facts in different schemas. A port can occur in four files; a
dependency determines both an address and an egress rule.

Manual copies can drift while remaining syntactically valid. The cluster may
accept every file even though a service cannot reach its database or its metrics
accept every file even though an application cannot reach its database or its metrics
are no longer collected. The selected problem is therefore to generate a
consistent Kubernetes deployment set from one abstract service model.
consistent Kubernetes deployment set from one abstract application model.
10 changes: 5 additions & 5 deletions docs/mde/task-0-proposal/Sections/02-solution.tex
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
\section{Solution}
\label{sec:solution}

The domain-specific language records workloads, ports, dependencies, routes,
The domain-specific language records processes, ports, dependencies, routes,
storage, secrets, health and operational requirements once, without naming
Kubernetes resources or vendor fields.

For a version release, CI provides the Service Intent model, per-workload
For a version release, CI provides the Project Intent model, per-process
environment files, an image lock mapping image names to immutable digests, and
versioned platform data. The platform data defines namespace and label rules,
resource and security defaults, ingress and storage classes, the service
register, alert catalogue and cluster capabilities. The generator does not read
resource and security defaults, ingress and storage classes, the register
of unmanaged surfaces, alert catalogue and cluster capabilities. The generator does not read
live cluster state or retrieve secret values.

A model-to-model transformation turns these inputs into a \emph{Resolved
Expand All @@ -18,7 +18,7 @@ \section{Solution}
policy peers, routes, secret references, monitoring rules and configuration
hashes. Renderers therefore make no deployment decisions.

The model-to-text step writes a per-service \emph{Deliverable Set}: a
The model-to-text step writes a per-application \emph{Deliverable Set}: a
\texttt{kustomization.yaml} and its YAML and JSON resources. After validation,
release CI deploys that version with \texttt{kubectl apply -k}. Platform changes
remain confined to versioned generator inputs and rules.
42 changes: 26 additions & 16 deletions docs/mde/task-0-proposal/Sections/03-source-language.tex
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
\section{Source Language}
\label{sec:sourcelanguage}

One source file represents a domain and its services. The table summarises the
language. Example~\ref{lst:auth} in Appendix~\ref{app:rendered} shows the
\texttt{auth} domain.
One source file represents a project and its applications. Table~\ref{tab:source_language}
summarises the language.

\begin{table}[ht]
\begin{table}[!htbp]
\centering
\begin{tabular}{p{0.22\linewidth}p{0.68\linewidth}}
\small
\begin{tabular}{>{\raggedright\arraybackslash}p{0.24\linewidth}>{\raggedright\arraybackslash}p{0.68\linewidth}}
\hline
\textbf{Concern} & \textbf{Model content} \\
\hline
Ownership and release & Domain, responsible team and parts released together. \\
Workloads & Container image and execution mode for each runnable part. \\
Placement and scale & Resource, architecture and capability needs; replica count. \\
Exposure and routing & Host, audience and path-to-workload mapping. \\
Connections & Named provided ports and outgoing service dependencies. \\
Health and cutover & Probes, allowed startup time and replacement strategy. \\
Observability & Metrics surface and alert class. \\
Storage and writes & Volume properties and paths writable under a read-only root. \\
Secrets & Allowed paths, keys, access modes and delivery methods. \\
Ownership and release &
Who owns the project, and which of its processes are released together as one application. \\
Processes &
The processes that run, packaged as container images, and whether they are one-time executions or long-running. \\
Placement and scale &
How much memory and CPU a process needs, which machines can host it, and how many instances run simultaneously. \\
Exposure and routing &
The web address an application answers on, who may reach it, and which process handles each URL path. \\
Connections &
The network ports a process offers, and the other applications it needs to reach. \\
Health and cutover &
The checks that tell the platform a process is running and ready, and how an old version is replaced by a new one. \\
Observability &
Where the platform collects measurements from a process, and how urgently a failure should alert someone. \\
Storage and writes &
The disks a process stores data on, what recovery entails, and which folders it has access to. \\
Secrets &
Which secrets a process may read from the vault, and whether they arrive as environment variables, files, or otherwise. \\
\hline
\end{tabular}
\caption{Concerns Defined by the Source Language}
\label{tab:source_language}
\end{table}

The model contains service requirements rather than Kubernetes kinds, proxy
fields or machine names. Platform mechanisms are derived in the next stage.
The model contains application requirements rather than Kubernetes kinds, proxy
fields or machine names. Platform mechanisms are derived in the next stage, described in
Section~\ref{sec:architecture}.
37 changes: 16 additions & 21 deletions docs/mde/task-0-proposal/Sections/04-generated-code.tex
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
\section{Generated Code}
\label{sec:generatedcode}

The generator emits one versioned release bundle per service. Its resources and
principal derivations are listed below. Appendix~\ref{app:rendered} contains the
hand-written target for the \texttt{auth} example.
The generator emits one versioned release bundle per application. Its resources and
principal derivations are listed in Table~\ref{tab:generated_resources}.

\begin{table}[ht]
\begin{table}[!htbp]
\centering
\begin{tabular}{p{0.22\linewidth}p{0.56\linewidth}c}
\small
\begin{tabular}{>{\raggedright\arraybackslash}p{0.24\linewidth}>{\raggedright\arraybackslash}p{0.68\linewidth}}
\hline
\textbf{Output} & \textbf{Principal derivation} & \textbf{Example} \\
\textbf{Output} & \textbf{Principal derivation} \\
\hline
\texttt{Namespace} and indexes &
Domain name, fixed labels and resolved output paths &
\ref{lst:namespace}, \ref{lst:kust-root}, \ref{lst:kust-auth} \\
A named partition of the cluster for the project, and the index files listing what to deploy. \\
Workload resources &
Locked image, placement, probes, cutover, ports, identity, configuration and replicas &
\ref{lst:workload}, \ref{lst:serviceaccount}, \ref{lst:pdb} \\
The definitions that start and restart processes, give each an identity, and keep enough instances running during maintenance. \\
\texttt{NetworkPolicy} &
Default deny, dependency edges, exposed surfaces and audience &
\ref{lst:networkpolicy} \\
Firewall rules stating which processes may talk to which, with everything else blocked. \\
\texttt{IngressRoute} &
Routes, path specificity, content policy, audience and host &
\ref{lst:ingressroutes} \\
The web-proxy rules sending incoming requests for an address and path to the right process. \\
Monitoring and alerts &
Scrape surface and alert class resolved through the rule catalogue &
\ref{lst:servicemonitor}, \ref{lst:prometheusrules} \\
Instructions to collect measurements, and the conditions under which an alert fires. \\
Secret resources &
Grants, workload identity and environment, file or direct delivery &
\ref{lst:vaultpolicy}, \ref{lst:vaultrole} \\
Permissions in the vault granting each process exactly the secrets it was allowed. \\
Backup and sweep jobs &
Volume durability and storage engine & n/a \\
Scheduled jobs copying data somewhere safe, or cleaning up data that may be discarded. \\
\hline
\end{tabular}
\caption{Generated Resources and Their Principal Derivations}
Expand All @@ -39,5 +33,6 @@ \section{Generated Code}

The transformation computes limits, startup probes, route precedence and policy
peers. For \texttt{auth}, about 90 source lines determine ten files containing
about 890 lines. The appendix is a manual oracle. The implemented generator must
reproduce it, validate the result and provide one Kustomize entry point for CI.
about 890 lines. Hand-written expected files kept in the repository are the oracle. Both
implementations (Section~\ref{sec:tooling}) must reproduce them, validate the result and provide one
Kustomize entry point for CI.
12 changes: 6 additions & 6 deletions docs/mde/task-0-proposal/Sections/05-metamodels.tex
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
\section{Metamodels}
\label{sec:metamodels}

The three pipeline layers have separate metamodels:
The three pipeline layers of Section~\ref{sec:solution} have separate metamodels:

\begin{enumerate}
\item \textbf{Service Intent}: \emph{Domain}, \emph{Service},
\emph{Workload}, \emph{Exposure}, \emph{Route}, \emph{Placement},
\item \textbf{Project Intent}: \emph{Project}, \emph{Application},
\emph{Process}, \emph{Exposure}, \emph{Route}, \emph{Placement},
\emph{Probe}, \emph{Dependency}, \emph{Secret Grant} and \emph{Volume}.
\item \textbf{Resolved Deployment}: concrete resources and relationships with
every derived value, identity and output path present.
\item \textbf{Deliverable Set}: typed Kubernetes and extension resources,
each with its path, content and producing adapter.
\end{enumerate}

UML class diagrams document each metamodel. The implementation uses TypeScript
types and \texttt{zod} runtime schemas, as discussed in
Section~\ref{sec:tooling}.
UML class diagrams document each metamodel. Each metamodel is defined twice,
separately: in Ecore with OCL constraints, and as TypeScript types and
\texttt{zod} runtime schemas, as discussed in Section~\ref{sec:tooling}.
12 changes: 8 additions & 4 deletions docs/mde/task-0-proposal/Sections/06-architecture.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@ \section{Architecture}

\begin{enumerate}
\item \textbf{Read and validate.} A \texttt{zod} schema validates the YAML
wire format, which a mapper converts to the Service Intent model. Keeping
wire format, which a mapper converts to the Project Intent model. In the
EMF implementation (Section~\ref{sec:tooling}), an Xtext grammar parses the same file and OCL
constraints validate the resulting model. Keeping
wire and domain types separate allows the syntax to evolve independently.
\item \textbf{Resolve.} Named rules combine the source with the release lock
\item \textbf{Resolve.} Named rules, written in TypeScript and as a QVT-OM
transformation, combine the source with the release lock
and versioned environment and platform data. They materialise all values
needed to deploy without reading live cluster state.
\item \textbf{Render.} An adapter for each resource family builds typed
objects. One serialiser writes YAML or JSON. Adapters do not make platform
objects. One serialiser writes YAML or JSON; in the EMF implementation, Acceleo
templates write the same files. Adapters do not make platform
decisions or assign paths.
\end{enumerate}

Rules return diagnostics with stable codes and source locations, allowing one
run to report several errors and tests to identify the failed rule. Module
dependency checks prevent renderers from importing source or resolution logic.
With fixed inputs, repeated runs must produce identical bytes. CI validates the
bundle and applies its service-level Kustomize entry point on each version
bundle and applies its application-level Kustomize entry point on each version
release.
22 changes: 13 additions & 9 deletions docs/mde/task-0-proposal/Sections/07-tooling.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ \section{Tooling Choice}
\texttt{zod} provides runtime validation, inferred static types and an exported
JSON Schema for editor support.

This differs from the prescribed Ecore, ATL or QVT-OM, and Acceleo stack. Those
tools provide established modelling languages, but add an Eclipse and JVM
toolchain not otherwise used by the deployment workflow. Here that cost does not
improve the model or the evidence.
The project is a joint implementation. The prescribed stack of Ecore, Xtext,
OCL, QVT-OM and Acceleo implements the same pipeline a second time, written
separately from the TypeScript code; neither is generated from the other. Both
are checked against the same committed expected outputs of
Section~\ref{sec:generatedcode}: the parsed model, the
Resolved Deployment, the generated files and the error codes reported for
invalid models. Agreement between the two follows from both matching these
outputs.

The substitution preserves the modelling stages: UML diagrams and executable
schemas define metamodels, tested functions implement model-to-model rules, and
typed builders plus one serialiser implement model-to-text generation. Models,
rules, generated artifacts and execution evidence remain in scope. Since the
named technologies are explicit, this change requires approval.
The EMF tools run headless through Maven for most of the project, so CI checks
them on every change without an IDE. The projects remain loadable in Eclipse
Modeling Tools: examiners can import them, open the metamodels, validate the
example models against the OCL constraints, and run the QVT-OM transformation
and the Acceleo generator from committed launch configurations.
12 changes: 8 additions & 4 deletions docs/mde/task-0-proposal/Sections/08-deliverables.tex
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
\section{Planned Deliverables}
\label{sec:deliverables}

Subject to approval, the deliverables are UML metamodel diagrams and executable
schemas with example models; tested resolution rules with limitations and
diagnostics; and source models with generated YAML and JSON. Evidence includes
schema validation, a CI-style \texttt{kubectl apply -k} deployment to a local
The deliverables are UML metamodel diagrams, Ecore metamodels with OCL
constraints and an Xtext grammar, and the equivalent \texttt{zod} schemas, with
example models; resolution rules in QVT-OM and TypeScript, tested, with
limitations and diagnostics; and source models with YAML and JSON generated by
Acceleo templates and by the TypeScript renderer. Evidence includes schema and
OCL validation, parity between the two implementations (Section~\ref{sec:tooling}) on every
example, a
CI-style \texttt{kubectl apply -k} deployment to a local
cluster and deterministic repeated runs.
49 changes: 0 additions & 49 deletions docs/mde/task-0-proposal/Sections/09-appendix.tex

This file was deleted.

Loading
Loading