<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0"
     xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xml:base="https://specificlanguages.com/">
  <channel>
    <title>Specific Languages</title>
    <link>https://specificlanguages.com/</link>
    <description>Recent content on Specific Languages</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>sergej@specificlanguages.com (Sergej Koščejev)</managingEditor>
    <webMaster>sergej@specificlanguages.com (Sergej Koščejev)</webMaster>
    <lastBuildDate>Fri, 02 Oct 2026 09:19:47 +0200</lastBuildDate>
    
    <atom:link href="https://specificlanguages.com/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>MPS Office Hours 🆓</title>
      <link>https://specificlanguages.com/services/mps-office-hours/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/services/mps-office-hours/</guid>
      <description>&lt;p&gt;You have a problem with MPS and you don&amp;rsquo;t know how to solve it. Worst of all, you don&amp;rsquo;t even know what words to use to
describe the problem, or what to look for in the forum or the documentation. But, you are sure that if you could demo it
for a few minutes to an expert, a hint would get you unstuck very quickly.&lt;/p&gt;
&lt;p&gt;Well, now you can do just that! I&amp;rsquo;m offering MPS Office Hours, a regular group call where you can demonstrate your
problem and get hints from myself or other present experts.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/services/mps-office-hours/"><![CDATA[ <p>You have a problem with MPS and you don&rsquo;t know how to solve it. Worst of all, you don&rsquo;t even know what words to use to
describe the problem, or what to look for in the forum or the documentation. But, you are sure that if you could demo it
for a few minutes to an expert, a hint would get you unstuck very quickly.</p>
<p>Well, now you can do just that! I&rsquo;m offering MPS Office Hours, a regular group call where you can demonstrate your
problem and get hints from myself or other present experts.</p>
<p>And if you don&rsquo;t have a problem yet but just want to watch and learn from others, you can, too!</p>
<p>Best of all, it&rsquo;s free!</p>
<blockquote>
<p>I wasn&rsquo;t expecting to participate in the Office Hours today. My plan was to just watch and learn. I&rsquo;m used to the
try-it-and-see and RTFM before asking for help. Still, I&rsquo;m glad that I did participate, got good feedback and
pointers. It&rsquo;s a valuable resource for the community.</p>
<p>&ndash; Nuba Princigalli</p>
</blockquote>
<h2 id="interested">Interested?</h2>
<p>Here are the important details:</p>
<ul>
<li>The call takes place <strong>every Monday and Thursday from 14:30 until 15:00</strong> CE(S)T (GMT+1 or +2, dependent on daylight
savings).</li>
<li>We meet on Google Meet. To avoid zoombombing, the link is not shared publicly but will be posted to the
<code>#office-hours</code> channel in the offical <a href="http://slack-mps.jetbrains.com">MPS Slack</a>.</li>
<li>Discussion related to MPS Office Hours also takes place in the <code>#office-hours</code> channel.</li>
<li>The office hours are <strong>not recorded</strong> currently but this may change in the future.</li>
<li>Attendance is <strong>free</strong> and the meeting is <strong>public</strong>. If you want a private consultation, <a href="https://specificlanguages.com/about/">contact me</a>.</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>MPS Advisory Service</title>
      <link>https://specificlanguages.com/services/mps-advisory-service/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/services/mps-advisory-service/</guid>
      <description>&lt;p&gt;Are you worried about unforeseen challenges of technical nature with MPS development? Afraid that you don&amp;rsquo;t know what
you don&amp;rsquo;t know?&lt;/p&gt;
&lt;p&gt;To help reduce the risk of your team getting stuck on a difficult issue, I offer MPS Advisory Service where I answer
your technical questions related to MPS with a response time of one business day.&lt;/p&gt;
&lt;h2 id=&#34;examples-of-topics-that-are-covered&#34;&gt;Examples of topics that are covered&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;How to implement a particular editing feature&lt;/li&gt;
&lt;li&gt;Understanding an error message and suggestions on how to best fix the underlying cause&lt;/li&gt;
&lt;li&gt;How to automate the build process&lt;/li&gt;
&lt;li&gt;How to best integrate MPS with a particular system or environment&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-is-not-covered&#34;&gt;What is not covered&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Developing production code – but I might create a small example to illustrate a point or a technique, if necessary.&lt;/li&gt;
&lt;li&gt;Maintaining or debugging existing code – but I could give you tips to help you do it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;
&lt;p&gt;The service is offered to you as a single person (a team lead, an architect, a CTO). You ask questions by email, I
reply to my best ability within one business day, but usually faster. If necessary and convenient, we may jump on a
videocall to understand the problem better, but the service is mostly asynchronous.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/services/mps-advisory-service/"><![CDATA[ <p>Are you worried about unforeseen challenges of technical nature with MPS development? Afraid that you don&rsquo;t know what
you don&rsquo;t know?</p>
<p>To help reduce the risk of your team getting stuck on a difficult issue, I offer MPS Advisory Service where I answer
your technical questions related to MPS with a response time of one business day.</p>
<h2 id="examples-of-topics-that-are-covered">Examples of topics that are covered</h2>
<ul>
<li>How to implement a particular editing feature</li>
<li>Understanding an error message and suggestions on how to best fix the underlying cause</li>
<li>How to automate the build process</li>
<li>How to best integrate MPS with a particular system or environment</li>
</ul>
<h2 id="what-is-not-covered">What is not covered</h2>
<ul>
<li>Developing production code – but I might create a small example to illustrate a point or a technique, if necessary.</li>
<li>Maintaining or debugging existing code – but I could give you tips to help you do it.</li>
</ul>
<h2 id="how-it-works">How it works</h2>
<p>The service is offered to you as a single person (a team lead, an architect, a CTO). You ask questions by email, I
reply to my best ability within one business day, but usually faster. If necessary and convenient, we may jump on a
videocall to understand the problem better, but the service is mostly asynchronous.</p>
<h2 id="terms">Terms</h2>
<ul>
<li>The service costs 3 000 EUR/month (30 days), paid in full in advance.</li>
<li>In case of vacations/holidays the duration of the service is extended.</li>
<li>To ensure a high quality of service I only take 2 clients in a given month.</li>
</ul>
<p>Interested? Contact me at <a href="mailto:sergej@specificlanguages.com">sergej@specificlanguages.com</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Less time, more agents</title>
      <link>https://specificlanguages.com/posts/2026-10/02-less-time-more-agents/</link>
      <pubDate>Fri, 02 Oct 2026 09:19:47 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-10/02-less-time-more-agents/</guid>
      <description>&lt;p&gt;This and the past week I have been busy with client work, and so I have been experimenting with delegating more of my
MPS ecosystem work to my agents.&lt;/p&gt;
&lt;p&gt;I have this initiative to merge the mbeddr platform into MPS-extensions that has been cooking on a back-burner for a
long time but that I really want to get done eventually. I decided to ask Astra to help me orchestrate it: review what&amp;rsquo;s
there, suggest next steps. I don&amp;rsquo;t trust it enough to let it work completely on its own (I worry that there are not
enough guardrails in the projects), but I have an idea of an overall workflow I would like to follow: align the Gradle
builds of both projects so that I can &amp;ldquo;transplant&amp;rdquo; mbeddr platform into MPS-extensions by simply copy-pasting a
subfolder there, then perform the actual transplant using git-filter-repo to preserve history.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-10/02-less-time-more-agents/"><![CDATA[ <p>This and the past week I have been busy with client work, and so I have been experimenting with delegating more of my
MPS ecosystem work to my agents.</p>
<p>I have this initiative to merge the mbeddr platform into MPS-extensions that has been cooking on a back-burner for a
long time but that I really want to get done eventually. I decided to ask Astra to help me orchestrate it: review what&rsquo;s
there, suggest next steps. I don&rsquo;t trust it enough to let it work completely on its own (I worry that there are not
enough guardrails in the projects), but I have an idea of an overall workflow I would like to follow: align the Gradle
builds of both projects so that I can &ldquo;transplant&rdquo; mbeddr platform into MPS-extensions by simply copy-pasting a
subfolder there, then perform the actual transplant using git-filter-repo to preserve history.</p>
<p>This is roughly the third or fourth time that I come back to this effort and this time I think Astra can do a good job
of keeping me on track – it&rsquo;s nice to be able to ask it about the current status and get a report in a few minutes.
Helps a lot when context switching back to it after some unrelated work. I also like that the Codex app lets me ask a
model to start a new Codex thread. This is very similar to the usual subagent functionality, but the threads are
directly visible in the UI just like the threads that I started myself, and I can talk to them (as well as the model
that spawned them) and directly watch what they are doing.</p>
<p>Separately, I asked Astra to help me with the <a href="https://github.com/specificlanguages/mops">mops</a> presentation I am going
to give in a week at <a href="https://langdevcon.org">LangDev</a> in Málaga. I have already tried mops on a few related tasks and
keep encountering some rough edges that I would like to polish. There&rsquo;s also a missing feature: running tests. It turns
out to open another can of worms because there are several ways of running tests in MPS: from Ant, from MPS in-process,
and from MPS out-of-process (for performance reasons, I assume). And each approach is characterized by a slightly
different code path, slightly different way of choosing tests to run, slightly different environment setup, slightly
different reporting of failures, and slightly different pitfalls. All of the slight differences then multiply to give a
noticeable headache.</p>
<p>Another gap I discovered, and I also mentioned it previously, is that I am reaching the point where adding features to
mops or improving the existing features seems to give diminishing returns (for agents, not for humans). What&rsquo;s becoming
more important are agent skills for guidance. Fortunately, JetBrains has been busy adding some of their own skills for
MPS development as part of their
<a href="https://www.jetbrains.com/help/mps/2026.1/mps-projectional-agent-toolkit.html">Projectional Agent Toolkit</a>. Their
skills are written with their MCP tooling in mind, but they contain much useful information about general MPS
development, and so Astra was able to adapt them to use <code>mops</code> right away. I think that we should establish a
tool-independent skills repository for MPS, similar to my
<a href="https://specificlanguages.com/posts/2026-09/18-mps-api-research/">mps-api-research</a> repo (which has got its first contributed research
notes, by the way!), but this is yet another initiative that I don&rsquo;t have capacity for right now, so it will have to
wait, probably until after LangDev.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Building a shared knowledge base of MPS internals</title>
      <link>https://specificlanguages.com/posts/2026-09/18-mps-api-research/</link>
      <pubDate>Fri, 18 Sep 2026 08:42:59 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-09/18-mps-api-research/</guid>
      <description>&lt;p&gt;I have published an agent skill (a reusable set of instructions for coding agents) for researching MPS APIs, paired with
a &lt;a href=&#34;https://github.com/specificlanguages/mps-api-research&#34;&gt;repository&lt;/a&gt; to serve as a knowledge base where your agent can
both find previously researched information and contribute new findings through pull requests.&lt;/p&gt;
&lt;p&gt;Why write a skill at all? When working with agents on &lt;a href=&#34;https://github.com/specificlanguages/mops&#34;&gt;&lt;code&gt;mops&lt;/code&gt;&lt;/a&gt;, my CLI for
MPS, I found that doing thorough research before implementing a feature saved time on both coding and debugging. But I
needed to define what thorough research entails. Without a detailed prompt, the agents would miss aspects that are
obvious to an MPS developer, such as checking whether a method requires a read or write lock, or must be called on a
particular thread. And since I wanted &lt;code&gt;mops&lt;/code&gt; to support multiple MPS versions, I needed to know whether and how the APIs
that I rely on change between MPS versions.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-09/18-mps-api-research/"><![CDATA[ <p>I have published an agent skill (a reusable set of instructions for coding agents) for researching MPS APIs, paired with
a <a href="https://github.com/specificlanguages/mps-api-research">repository</a> to serve as a knowledge base where your agent can
both find previously researched information and contribute new findings through pull requests.</p>
<p>Why write a skill at all? When working with agents on <a href="https://github.com/specificlanguages/mops"><code>mops</code></a>, my CLI for
MPS, I found that doing thorough research before implementing a feature saved time on both coding and debugging. But I
needed to define what thorough research entails. Without a detailed prompt, the agents would miss aspects that are
obvious to an MPS developer, such as checking whether a method requires a read or write lock, or must be called on a
particular thread. And since I wanted <code>mops</code> to support multiple MPS versions, I needed to know whether and how the APIs
that I rely on change between MPS versions.</p>
<p>The skill started as a small Markdown file that was very specific to mops and to the directory layout on my laptop. In
particular, I originally designed the skill to store the findings directly in the <code>mops</code> repository. When I needed the
same kind of research in the context of another project, I decided to separate the skill and its findings from <code>mops</code>
and turn them into a shared knowledge base.</p>
<p>To make contributing easier, I recommend cloning the repository rather than copying the skill itself. After cloning it,
<a href="https://github.com/specificlanguages/mps-api-research#usage">link or copy the skill</a> to your agent&rsquo;s global skills
directory (<code>~/.agents/skills</code> or <code>~/.claude/skills</code>).</p>
<p>Invoke the skill from the context of your project (for example, I use it in <code>mops</code> or <code>mps-build-backends</code>) with a
question whenever you need to understand something about MPS internals, such as:</p>
<p><code>$mps-api-research how do I run an MPS unit test programmatically?</code></p>
<p>The skill first searches the existing notes. If they do not answer the question, it examines the relevant MPS sources or
binaries and turns its findings into a project-independent research note. With your authorization, the agent can then
contribute the note to the repository through a pull request.</p>
<p>There are already research notes that answer questions, such as:</p>
<ul>
<li><a href="https://github.com/specificlanguages/mps-api-research/blob/main/docs/concept-name-resolution.md">How does one look up a concept by name?</a></li>
<li><a href="https://github.com/specificlanguages/mps-api-research/blob/main/docs/external-file-runtime-refresh.md">Will a headless MPS instance automatically pick up file system changes? Will it reload classes? How do I make it do it?</a></li>
<li><a href="https://github.com/specificlanguages/mps-api-research/blob/main/docs/language-runtime-loading.md">How does one diagnose why a certain language refuses to load?</a></li>
<li><a href="https://github.com/specificlanguages/mps-api-research/blob/main/docs/test-execution.md">How does one run a unit test programmatically?</a></li>
</ul>
<p>In the current form the <code>mps-api-research</code> repository and skill are likely to be mostly useful for people who work on
MPS infrastructure (a small audience, admittedly) but I believe that a similar approach could be used for collecting
more user-facing MPS documentation (similar to the <a href="https://mbeddr.com/mps-platform-docs/">mps-platform-docs</a> website
that Alexander Pann started in the pre-AI days).</p>
<p>If your agent has to investigate an MPS API, try the skill, and consider contributing the resulting note so that the
next person does not have to repeat the research.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Improving mops</title>
      <link>https://specificlanguages.com/posts/2026-09/14-improving-mops/</link>
      <pubDate>Mon, 14 Sep 2026 18:10:53 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-09/14-improving-mops/</guid>
      <description>&lt;p&gt;Last week I was improving &lt;a href=&#34;https://github.com/specificlanguages/mops/&#34;&gt;mops&lt;/a&gt;, my open-source CLI for working with MPS
projects. The most important addition was &amp;lsquo;code mode&amp;rsquo;: the ability to execute Groovy scripts in the context of an MPS
project.&lt;/p&gt;
&lt;p&gt;Here is an example Groovy script that returns the names of all Java classes in a project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; conceptName &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;jetbrains.mps.baseLanguage.ClassConcept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; project&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;read&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; concept &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; project&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;concept&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;conceptName&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; names &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  mops&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;search&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;eachInstanceOf&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;concept&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; project&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;scope&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; node &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    names &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; node&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;properties&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; names
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note &lt;code&gt;project.read&lt;/code&gt; method for executing code in a read action, &lt;code&gt;project.concept&lt;/code&gt; for looking up concepts by name, as
well as &lt;code&gt;mops.search.eachInstanceOf&lt;/code&gt; for executing an instance search.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-09/14-improving-mops/"><![CDATA[ <p>Last week I was improving <a href="https://github.com/specificlanguages/mops/">mops</a>, my open-source CLI for working with MPS
projects. The most important addition was &lsquo;code mode&rsquo;: the ability to execute Groovy scripts in the context of an MPS
project.</p>
<p>Here is an example Groovy script that returns the names of all Java classes in a project:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-groovy" data-lang="groovy"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> conceptName <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;jetbrains.mps.baseLanguage.ClassConcept&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">return</span> project<span style="color:#f92672">.</span><span style="color:#a6e22e">read</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">def</span> concept <span style="color:#f92672">=</span> project<span style="color:#f92672">.</span><span style="color:#a6e22e">concept</span><span style="color:#f92672">(</span>conceptName<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">def</span> names <span style="color:#f92672">=</span> <span style="color:#f92672">[]</span>
</span></span><span style="display:flex;"><span>  mops<span style="color:#f92672">.</span><span style="color:#a6e22e">search</span><span style="color:#f92672">.</span><span style="color:#a6e22e">eachInstanceOf</span><span style="color:#f92672">(</span>concept<span style="color:#f92672">,</span> project<span style="color:#f92672">.</span><span style="color:#a6e22e">scope</span><span style="color:#f92672">)</span> <span style="color:#f92672">{</span> node <span style="color:#f92672">-&gt;</span>
</span></span><span style="display:flex;"><span>    names <span style="color:#f92672">&lt;&lt;</span> node<span style="color:#f92672">.</span><span style="color:#a6e22e">properties</span><span style="color:#f92672">[</span><span style="color:#e6db74">&#39;name&#39;</span><span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> names
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><p>Note <code>project.read</code> method for executing code in a read action, <code>project.concept</code> for looking up concepts by name, as
well as <code>mops.search.eachInstanceOf</code> for executing an instance search.</p>
<p>And here is how you execute it, say, against MPS-extensions:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>mops --project-root=code --mps-home=&#39;.../mps/2025.1.3&#39; --java-home=&#39;.../jbr&#39; code run .../mops/examples/concept-names.groovy
</span></span></code></pre></div><p>Since it is tedious to figure out the right <code>--mps-home</code> and <code>--java-home</code> parameters, I have also implemented a
<code>mops wrapper</code> subcommand which can guess their values for common Gradle builds and write a wrapper script for launching
<code>mops</code> in the context of the project.</p>
<p>I think the Groovy scripting interface is going to become more important in the future. For agents, Groovy is a good fit
because they are already quite adept at writing it, and editing models from Groovy is likely to be easier than
alternatives. For humans, it could provide an easier-to-run alternative to MPS Console scripts and a convenient way to
export data. Groovy also makes it easy to add language-specific functionality and helps keep the script readable (as
illustrated by the direct access to the <code>name</code> property above).</p>
<p>I am still iterating on both the functionality and the best way to expose it. I have added Java parsing (under
<code>mops.parsing.java</code>) and build script reloading (<code>mops.editing.build.reloadModulesFromDisk</code>). I want it to be easy to
add further extensions, such as parsing other languages (KernelF, or even structure and editor languages), or executing
an intention.</p>
<p>These changes were motivated by trying to get <code>mops</code> to a state where it could autonomously reproduce an issue reported
against MPS-extensions and write an automated test for it. I am of course discovering bugs along the way and fixing
them. (Did you know that headless MPS will save your models only when explicitly asked, and will <em>not</em> save the
project&rsquo;s list of modules <em>even if</em> explicitly asked? Well, I know now.) I am reaching the point where the tools are in
place and my focus will have to shift to helping agents use them, which means I am going to turn to skill writing at
some point in the near future.</p>
<p>I must admit, I am not entirely happy with the code quality of mops because I am letting agents (Codex/Astra these days)
write most of it. It does have tests, but some are of questionable utility. The code is not modularized the way I would
like, and despite having prompted most of the code into existence, I am not that familiar with it. I am however
deliberately trading off code quality for exploration at the moment (also known as taking on technical and cognitive
debt). After we reach <del>AGI</del> the state where mops can write editor tests on its own, I plan to pause and clean things
up.</p>
<p>I will be talking about mops at LangDev (confirmed) and at the MPS Community Meetup (pending acceptance). Let me know if
you are going to attend one of these events and want to meet for a chat.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Deduplication continued</title>
      <link>https://specificlanguages.com/posts/2026-09/07-deduplication-continued/</link>
      <pubDate>Mon, 07 Sep 2026 12:08:08 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-09/07-deduplication-continued/</guid>
      <description>&lt;p&gt;Continuing on my deduplication adventures that I wrote about
&lt;a href=&#34;https://specificlanguages.com/posts/2026-08/31-how-do-you-best-use-ai-to-find-duplicate-models/&#34;&gt;previously&lt;/a&gt;. It turns out, the client
does not need any structural similarity checks, and it is enough to just check the names for duplicates.&lt;/p&gt;
&lt;p&gt;As I wrote previously, I was unable to get the agent to look for duplicates without tooling. However, I must admit I
didn&amp;rsquo;t try too hard either. I probably could have altered the prompt or disabled all the tools but the problem is, I
wouldn&amp;rsquo;t be able to trust the reply too much. What if the model overlooks a clear duplicate? What if it hallucinates one
that is not there? Well, this last problem can be solved by asking the model for a proof and checking it by a
deterministic script. But as soon as deterministic scripts enter the picture, why not do more work in such a script and
only use the AI for the parts that cannot be automated?&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-09/07-deduplication-continued/"><![CDATA[ <p>Continuing on my deduplication adventures that I wrote about
<a href="https://specificlanguages.com/posts/2026-08/31-how-do-you-best-use-ai-to-find-duplicate-models/">previously</a>. It turns out, the client
does not need any structural similarity checks, and it is enough to just check the names for duplicates.</p>
<p>As I wrote previously, I was unable to get the agent to look for duplicates without tooling. However, I must admit I
didn&rsquo;t try too hard either. I probably could have altered the prompt or disabled all the tools but the problem is, I
wouldn&rsquo;t be able to trust the reply too much. What if the model overlooks a clear duplicate? What if it hallucinates one
that is not there? Well, this last problem can be solved by asking the model for a proof and checking it by a
deterministic script. But as soon as deterministic scripts enter the picture, why not do more work in such a script and
only use the AI for the parts that cannot be automated?</p>
<p>Thinking about the problem some more, I decided to ask the model to write a &ldquo;canonicalizing&rdquo; script: I give it a list of
German/English names such as &lsquo;DSGVO&rsquo;, &lsquo;Datenschutz-Grundverordnung&rsquo;, or &lsquo;GDPR&rsquo;, and out comes &ldquo;general data protection
regulation&rdquo;. This turns out to be a very simple deterministic script, all the difficulty lies in the data: you have to
have a German-English dictionary and a glossary of abbreviations.</p>
<p>So the hard problem is now reduced to providing this dictionary. And this is a task that should nowadays be solvable
even by a rather simple language model: &ldquo;Given the task of searching for duplicate names, this list of English/German
names, and this current dictionary/glossary, what entries are missing in the dictionary?&rdquo;</p>
<p>Overall, the reason for using a deterministic script rather than an LLM seems to be analogous to the reason to use a
machine instead of a human: machines are faster and more reliable than humans, but need some initial investment and
ongoing maintenance by humans. Deterministic scripts are faster and more reliable than LLMs but need some initial
investment and maintenance (by humans, but perhaps even LLMs would be enough?)</p>
<p>Anyway, the next step would be to set this up as a simple workflow/check, including regular dictionary updates and some
machinery to mark duplicates as acceptable.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>How do you best use AI to find duplicate models?</title>
      <link>https://specificlanguages.com/posts/2026-08/31-how-do-you-best-use-ai-to-find-duplicate-models/</link>
      <pubDate>Mon, 31 Aug 2026 11:43:59 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-08/31-how-do-you-best-use-ai-to-find-duplicate-models/</guid>
      <description>&lt;p&gt;A client of mine is modeling components in MPS. They are a large, multinational manufacturing company, so they have
hundreds to thousands of them. Some are fully fleshed out, some are just stubs that have nothing but a name. The
modeling task is split across several teams, and two teams may end up modeling the same component, for example, one that
they need as a dependency.&lt;/p&gt;
&lt;p&gt;How do we detect these duplicates? It sounds like a fairly simple problem, just collect them and check for similar
names. It is, however, made complicated by the fact that one team may choose to model the components in English while
another models them in German. Or one team uses an abbreviation and the other spells out the full name. Language
translation is something that large language models have always been good for, so it feels obvious that AI could be part
of the solution. But what should be its place exactly?&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-08/31-how-do-you-best-use-ai-to-find-duplicate-models/"><![CDATA[ <p>A client of mine is modeling components in MPS. They are a large, multinational manufacturing company, so they have
hundreds to thousands of them. Some are fully fleshed out, some are just stubs that have nothing but a name. The
modeling task is split across several teams, and two teams may end up modeling the same component, for example, one that
they need as a dependency.</p>
<p>How do we detect these duplicates? It sounds like a fairly simple problem, just collect them and check for similar
names. It is, however, made complicated by the fact that one team may choose to model the components in English while
another models them in German. Or one team uses an abbreviation and the other spells out the full name. Language
translation is something that large language models have always been good for, so it feels obvious that AI could be part
of the solution. But what should be its place exactly?</p>
<p>I decided to start simple: let&rsquo;s export all components to a text file, feed the file to the LLM and ask it if it sees
any duplicates. In fact, even simpler: let&rsquo;s just export the component <em>names</em>, paste them in, and ask the LLM to
canonicalize them by translating from German to English and expanding abbreviations where possible.</p>
<p>Sounds trivial? Well, not so fast. One does not simply paste a 3,000-line file into a Copilot prompt. Copilot just stows
it away in some session-specific directory and tells the agent where it is. This is basically the same as @-mentioning
it in the prompt. The result is that the LLM only sees the file name and instead of trying to produce an answer from
context, it reads a few hundred lines to understand what it&rsquo;s up against, then rolls up its sleeves and starts writing
Python scripts. Just like a real, lazy programmer: it&rsquo;s far more interesting to spend a day writing a script that takes
a minute to run, than producing an answer in five minutes. (Of course, being a lazy programmer myself, I kind of
empathize and agree with the approach. Especially since my goal is to automate this and run it repeatedly, so I welcome
deterministic scripts.)</p>
<p>Interestingly, in the scripts it writes, it <em>will</em> include a small German-English dictionary, based on the actual words
it encounters in the input. So this gave me another idea: structure the workflow so that we do as much mechanical work
as possible outside of the LLM, and only give the LLM a simple, focused translation task. This kind of goes against The
Bitter Lesson (which says that general-purpose methods will outperform special-purpose human-engineered approaches given
enough compute), but I guess that lesson applies only as a macro trend, not on a micro scale.</p>
<p>All this was just dealing with the names. Who knows, maybe in the end just using some structural similarity score will
fare better. We&rsquo;ll see next time.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>mops demo recording</title>
      <link>https://specificlanguages.com/posts/2026-07/16-mops-demo-recording/</link>
      <pubDate>Thu, 16 Jul 2026 17:34:59 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-07/16-mops-demo-recording/</guid>
      <description>&lt;p&gt;If you missed today’s mops demo, the recording is
&lt;a href=&#34;https://drive.google.com/file/d/1O4kRz9rHrrbDLe4Rjt2FMzSSYkNBDlbm/view?usp=drivesdk&#34;&gt;now available&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We covered the functionality, architecture, and future plans for mops, as well as why mops was created and how it is
different to other approaches.&lt;/p&gt;
&lt;p&gt;If you have any comments or questions, just reply to this email.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-07/16-mops-demo-recording/"><![CDATA[ <p>If you missed today’s mops demo, the recording is
<a href="https://drive.google.com/file/d/1O4kRz9rHrrbDLe4Rjt2FMzSSYkNBDlbm/view?usp=drivesdk">now available</a>.</p>
<p>We covered the functionality, architecture, and future plans for mops, as well as why mops was created and how it is
different to other approaches.</p>
<p>If you have any comments or questions, just reply to this email.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>mops demo this Thursday at 14:30 CEST</title>
      <link>https://specificlanguages.com/posts/2026-07/13-mops-demo-this-thursday/</link>
      <pubDate>Mon, 13 Jul 2026 22:10:00 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-07/13-mops-demo-this-thursday/</guid>
      <description>&lt;p&gt;I would like to invite you to the demo of mops (MPS OPerationS), a command-line tool for working with MPS projects. As I
have mentioned a few times, I believe that a command-line tool is more versatile than an MCP server, and I have tried to
design mops to be useful not only to agents but also to humans.&lt;/p&gt;
&lt;p&gt;In the demo I will show how mops works, how it can be used by agents and humans, and where I would like to take it.
There will also be time to answer your questions.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-07/13-mops-demo-this-thursday/"><![CDATA[ <p>I would like to invite you to the demo of mops (MPS OPerationS), a command-line tool for working with MPS projects. As I
have mentioned a few times, I believe that a command-line tool is more versatile than an MCP server, and I have tried to
design mops to be useful not only to agents but also to humans.</p>
<p>In the demo I will show how mops works, how it can be used by agents and humans, and where I would like to take it.
There will also be time to answer your questions.</p>
<p>The demo will take place in the usual MPS Office Hours Google Meet on Thursday, July 16th, at 14:30 CEST. The meeting
will be recorded.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>MPS pre-commit hooks</title>
      <link>https://specificlanguages.com/posts/2026-06/29-mps-pre-commit-hooks/</link>
      <pubDate>Mon, 29 Jun 2026 14:56:38 +0200</pubDate>
      <author>sergej@specificlanguages.com (Sergej Koščejev)</author>
      <guid>https://specificlanguages.com/posts/2026-06/29-mps-pre-commit-hooks/</guid>
      <description>&lt;p&gt;I have started a repository with pre-commit hooks for MPS,
&lt;a href=&#34;https://github.com/specificlanguages/mps-pre-commit-hooks&#34;&gt;specificlanguages/pre-commit-hooks&lt;/a&gt;, designed for use with
&lt;a href=&#34;https://pre-commit.com&#34;&gt;pre-commit&lt;/a&gt; or &lt;a href=&#34;https://prek.j178.dev&#34;&gt;prek&lt;/a&gt; (preferred).&lt;/p&gt;
&lt;p&gt;MPS pre-commit hooks are Python scripts that do not launch MPS but inspect files directly. This makes them complementary
to MPS model checks. Hooks are much faster but they cannot check domain logic. Rather, they focus on checking the basic
shape of the project for consistency.&lt;/p&gt;
&lt;p&gt;For example, hooks can check for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zero-length XML files (caused by MPS misresolving deleted/modified conflicts),&lt;/li&gt;
&lt;li&gt;modules present in the repository but missing from the MPS project,&lt;/li&gt;
&lt;li&gt;modules present in the MPS project but missing on disk,&lt;/li&gt;
&lt;li&gt;modules present in the repository but not mentioned in any MPS build script,&lt;/li&gt;
&lt;li&gt;models present on disk but not mentioned in any model root (e.g. leftover generator models),&lt;/li&gt;
&lt;li&gt;modules whose file/directory name does not match their name in MPS,&lt;/li&gt;
&lt;li&gt;path variables used in &lt;code&gt;modules.xml&lt;/code&gt; or &lt;code&gt;libraries.xml&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;and so on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am currently setting up the mbeddr platform build to use them (see PR
&lt;a href=&#34;https://github.com/mbeddr/mbeddr.core/pull/3466&#34;&gt;mbeddr/mbeddr.core#3466&lt;/a&gt;). On this repository they only take about a
second or so to run, and detect many consistency issues that have accumulated over the years.&lt;/p&gt;</description>
      <content:encoded xml:base="https://specificlanguages.com/posts/2026-06/29-mps-pre-commit-hooks/"><![CDATA[ <p>I have started a repository with pre-commit hooks for MPS,
<a href="https://github.com/specificlanguages/mps-pre-commit-hooks">specificlanguages/pre-commit-hooks</a>, designed for use with
<a href="https://pre-commit.com">pre-commit</a> or <a href="https://prek.j178.dev">prek</a> (preferred).</p>
<p>MPS pre-commit hooks are Python scripts that do not launch MPS but inspect files directly. This makes them complementary
to MPS model checks. Hooks are much faster but they cannot check domain logic. Rather, they focus on checking the basic
shape of the project for consistency.</p>
<p>For example, hooks can check for:</p>
<ul>
<li>zero-length XML files (caused by MPS misresolving deleted/modified conflicts),</li>
<li>modules present in the repository but missing from the MPS project,</li>
<li>modules present in the MPS project but missing on disk,</li>
<li>modules present in the repository but not mentioned in any MPS build script,</li>
<li>models present on disk but not mentioned in any model root (e.g. leftover generator models),</li>
<li>modules whose file/directory name does not match their name in MPS,</li>
<li>path variables used in <code>modules.xml</code> or <code>libraries.xml</code>,</li>
<li>and so on.</li>
</ul>
<p>I am currently setting up the mbeddr platform build to use them (see PR
<a href="https://github.com/mbeddr/mbeddr.core/pull/3466">mbeddr/mbeddr.core#3466</a>). On this repository they only take about a
second or so to run, and detect many consistency issues that have accumulated over the years.</p>
<p>If you are interested in trying them out, install <a href="https://prek.j178.dev">prek</a> and add a <code>.pre-commit-config.yaml</code> to
your repository with this contents:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">repos</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">repo</span>: <span style="color:#ae81ff">https://github.com/specificlanguages/mps-pre-commit-hooks</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">rev</span>: <span style="color:#ae81ff">v0.1.0</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">hooks</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-orphan-modules</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-unbuilt-modules</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-missing-modules</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-orphan-models</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-orphan-mpsr-files</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-zero-sized-xmls</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-module-naming</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mps-check-path-variables</span>
</span></span></code></pre></div><p>Then run <code>prek install</code> in the repository to have the hooks run on the files changed in a commit. If you want to run
hooks on all files, run <code>prek run -a</code>.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
