Skip to content

Commit 0a2e164

Browse files
akoclaude
andcommitted
docs: add MDL syntax design guidelines, skill, and PR review check
Establishes shared design principles for new MDL syntax to ensure consistency across contributors. Adds a proposal with decision framework, a skill file for pre-design consultation, review checklist items in CLAUDE.md, and syntax design checks in the AI PR review workflow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a7c409f commit 0a2e164

4 files changed

Lines changed: 571 additions & 1 deletion

File tree

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# Design New MDL Syntax
2+
3+
This skill provides guardrails for designing new MDL statements. Read this **before** writing grammar rules, AST types, or executor code for any new MDL feature.
4+
5+
## When to Use This Skill
6+
7+
- Adding a new document type to MDL (e.g., scheduled events, message definitions, REST services)
8+
- Adding a new action type to microflows (e.g., new activity, new operation)
9+
- Extending existing syntax with new clauses or keywords
10+
- Reviewing a PR that adds or modifies MDL syntax
11+
- Resolving a syntax design disagreement
12+
13+
## Core Principles (Priority Order)
14+
15+
When principles conflict, higher-priority ones win.
16+
17+
### 1. Read Like English
18+
19+
MDL targets citizen developers and business analysts, not software engineers. Statements should read as natural English sentences.
20+
21+
- Use keyword words (`FROM`, `WHERE`, `IN`), not symbols (`->`, `|>`, `=>`)
22+
- Spell out full words (`MICROFLOW`, `ASSOCIATION`), not abbreviations (`MF`, `ASSOC`)
23+
- Use prepositions to clarify relationships: `GRANT READ ON Entity TO Role`
24+
25+
**Test**: Read it aloud. A business analyst should understand on first hearing.
26+
27+
### 2. One Way to Do Each Thing
28+
29+
Reuse existing patterns. Never create a second syntax for the same concept.
30+
31+
| Operation | Pattern | Example |
32+
|-----------|---------|---------|
33+
| Create | `CREATE [MODIFIERS] <TYPE> Module.Name (...)` | `CREATE PERSISTENT ENTITY Shop.Product (...)` |
34+
| Modify | `ALTER <TYPE> Module.Name <OPERATION>` | `ALTER ENTITY Shop.Product ADD (...)` |
35+
| Remove | `DROP <TYPE> Module.Name` | `DROP ENTITY Shop.Product` |
36+
| List | `SHOW <TYPE>S [IN Module]` | `SHOW ENTITIES IN Shop` |
37+
| Inspect | `DESCRIBE <TYPE> Module.Name` | `DESCRIBE ENTITY Shop.Product` |
38+
| Security | `GRANT/REVOKE <perm> ON <target> TO/FROM <role>` | `GRANT READ ON Shop.Product TO Shop.User` |
39+
40+
Do NOT use alternative verbs: `ADD` instead of `CREATE`, `REMOVE` instead of `DROP`, `LIST` instead of `SHOW`, `VIEW` instead of `DESCRIBE`.
41+
42+
### 3. Optimize for LLMs
43+
44+
- Keep patterns regular so one example is sufficient for generation
45+
- Statements must be self-contained (no implicit state from prior statements)
46+
- Use consistent keyword order: `<VERB> [MODIFIERS] <TYPE> <NAME> [CLAUSES] [BODY]`
47+
- Prefer flat statement sequences over deeply nested structures
48+
49+
### 4. Make Diffs Reviewable
50+
51+
- One property per line in multi-property constructs
52+
- Allow trailing commas
53+
- `DESCRIBE` output uses deterministic property order
54+
- Default values omitted unless non-obvious
55+
56+
### 5. Token Efficiency (Without Sacrificing Clarity)
57+
58+
- Omit noise words: `CREATE ENTITY` not `CREATE A NEW ENTITY`
59+
- Support `OR MODIFY` to avoid check-then-create
60+
- Allow type inference for obvious cases: `DECLARE $Count = 0`
61+
- Do NOT use symbols to save tokens at the cost of readability
62+
63+
## Design Workflow
64+
65+
Follow these steps when designing syntax for a new MDL feature.
66+
67+
### Step 1: Check Existing Patterns
68+
69+
Read the MDL Quick Reference: `docs/01-project/MDL_QUICK_REFERENCE.md`
70+
71+
Does an existing pattern cover this? If yes, extend it. Don't invent new syntax.
72+
73+
```
74+
New feature: "image collections"
75+
Existing pattern: CREATE/ALTER/DROP/SHOW/DESCRIBE
76+
Design: CREATE IMAGE COLLECTION Module.Name (...)
77+
DESCRIBE IMAGE COLLECTION Module.Name
78+
SHOW IMAGE COLLECTIONS [IN Module]
79+
```
80+
81+
### Step 2: Pick the Statement Shape
82+
83+
Every MDL statement fits one of these shapes:
84+
85+
```
86+
DDL: <VERB> [MODIFIERS] <TYPE> <QualifiedName> [CLAUSES] [BODY];
87+
DML: <ACTION> <TARGET> [CLAUSES];
88+
DQL: <QUERY-VERB> <TYPE>S [FILTERS];
89+
```
90+
91+
If your feature doesn't fit any shape, it may belong as a CLI command (`mxcli <subcommand>`) rather than MDL syntax.
92+
93+
### Step 3: Choose Keywords
94+
95+
1. Reuse existing keywords first (check reserved words in grammar)
96+
2. Use SQL/DDL verbs: `CREATE`, `ALTER`, `DROP`, `SHOW`, `DESCRIBE`, `GRANT`, `REVOKE`, `SET`
97+
3. Use Mendix terminology: `ENTITY` not `TABLE`, `MICROFLOW` not `FUNCTION`, `PAGE` not `VIEW`
98+
4. Prepositions clarify structure: `FROM`, `TO`, `IN`, `ON`, `BY`, `WITH`, `AS`, `WHERE`, `INTO`
99+
100+
### Step 4: Write the Property List
101+
102+
All property-bearing constructs use this format:
103+
104+
```mdl
105+
CREATE <TYPE> Module.Name (
106+
Property1: value,
107+
Property2: value,
108+
);
109+
```
110+
111+
Rules:
112+
- Parentheses `()` delimit property lists
113+
- Colon `:` separates key from value
114+
- Comma `,` separates properties
115+
- Trailing comma allowed
116+
- One property per line (single line acceptable for 1-2 properties)
117+
118+
### Step 5: Validate
119+
120+
Run these checks before finalizing syntax design:
121+
122+
1. **Read aloud test** — Does it read as English? Can a business analyst understand it?
123+
2. **LLM generation test** — Give one example to an LLM, ask for a variant. Does it get it right?
124+
3. **Diff test** — Change one property. Is the diff exactly one line?
125+
4. **Pattern test** — Does it follow CREATE/ALTER/DROP/SHOW/DESCRIBE? If not, why?
126+
5. **Roundtrip test** — Can `DESCRIBE` output be fed back as input?
127+
128+
## Anti-Patterns (DO NOT)
129+
130+
### Custom Verbs for Standard Operations
131+
132+
```mdl
133+
-- WRONG: custom verb
134+
SCHEDULE EVENT Shop.Cleanup ...
135+
REGISTER WEBHOOK Shop.OnOrder ...
136+
137+
-- RIGHT: standard CREATE
138+
CREATE SCHEDULED EVENT Shop.Cleanup (...)
139+
CREATE WEBHOOK Shop.OnOrder (...)
140+
```
141+
142+
### Implicit Module Context
143+
144+
```mdl
145+
-- WRONG: implicit state
146+
USE MODULE Shop;
147+
CREATE ENTITY Customer (...);
148+
149+
-- RIGHT: explicit qualified name
150+
CREATE ENTITY Shop.Customer (...);
151+
```
152+
153+
### Symbolic Syntax
154+
155+
```mdl
156+
-- WRONG: requires learning symbol meanings
157+
$items |> filter($.active) |> map($.name)
158+
159+
-- RIGHT: keyword-based
160+
FILTER $Items WHERE Active = true
161+
```
162+
163+
### Positional Arguments
164+
165+
```mdl
166+
-- WRONG: meaning unclear without docs
167+
CREATE RULE Shop Process Order ACT_ProcessOrder
168+
169+
-- RIGHT: labeled properties
170+
CREATE RULE Shop.ProcessOrder (
171+
Type: Validation,
172+
Microflow: Shop.ACT_ProcessOrder,
173+
);
174+
```
175+
176+
### Keyword Overloading
177+
178+
```mdl
179+
-- CAUTION: SET already means variable assignment in microflows
180+
-- Don't reuse it to mean property modification elsewhere unless established
181+
```
182+
183+
## Checklist
184+
185+
Before merging any PR that adds new MDL syntax, verify:
186+
187+
- [ ] Follows `CREATE`/`ALTER`/`DROP`/`SHOW`/`DESCRIBE` pattern
188+
- [ ] Uses `Module.Element` qualified names (no bare names)
189+
- [ ] Property lists use `( Key: value, ... )` format
190+
- [ ] Keywords are full English words (no abbreviations)
191+
- [ ] Statement reads as English (aloud test passed)
192+
- [ ] One example sufficient for LLM generation
193+
- [ ] Small change = one-line diff
194+
- [ ] No new keyword overloading
195+
- [ ] No implicit context dependency
196+
- [ ] `DESCRIBE` roundtrips to valid MDL
197+
- [ ] Grammar regenerated (`make grammar`)
198+
- [ ] Quick reference updated (`docs/01-project/MDL_QUICK_REFERENCE.md`)
199+
- [ ] Full-stack wired: grammar, AST, visitor, executor, DESCRIBE
200+
201+
## Related Resources
202+
203+
- Full design rationale: `docs/11-proposals/PROPOSAL_mdl_syntax_design_guidelines.md`
204+
- MDL Quick Reference: `docs/01-project/MDL_QUICK_REFERENCE.md`
205+
- Implementation workflow: `.claude/skills/implement-mdl-feature.md`
206+
- Existing syntax proposals: `docs/11-proposals/PROPOSAL_mdl_syntax_improvements.md`
207+
- Grammar file: `mdl/grammar/MDLParser.g4`

.github/workflows/ai-review.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@ jobs:
102102
- Check doctype test files above for existing test coverage of the feature area
103103
- Flag if the PR re-documents already-shipped features as new
104104
105+
## MDL syntax design (for new or modified MDL syntax)
106+
If the diff adds or modifies MDL syntax (grammar rules, keywords, statement types), check:
107+
- Follows standard CREATE/ALTER/DROP/SHOW/DESCRIBE pattern — no custom verbs for CRUD operations
108+
- Uses Module.Element qualified names everywhere — no bare names, no implicit module context
109+
- Property lists use ( Key: value, ... ) format with colon separators, one per line
110+
- Keywords are full English words — no abbreviations, no symbols for domain operations
111+
- Statement reads as English — a business analyst can understand the intent
112+
- No keyword overloading — each keyword has one consistent meaning
113+
- Diff-friendly — adding one property produces a one-line diff
114+
- Consistent with existing MDL patterns (check docs/01-project/MDL_QUICK_REFERENCE.md)
115+
105116
## Full-stack consistency (for MDL features)
106117
New MDL commands or language features must be wired through the full pipeline. If the diff adds any MDL feature, check:
107118
- Grammar rule added to MDLParser.g4 (and MDLLexer.g4 if new tokens)
@@ -153,7 +164,7 @@ jobs:
153164
messages: [
154165
{
155166
role: "system",
156-
content: "You are a code reviewer for a Go CLI project (mxcli) that reads/modifies Mendix application projects. Key patterns: ANTLR4 grammar → AST → visitor → executor → BSON writer. New MDL features MUST be wired through the full pipeline (grammar → AST → visitor → executor → LSP → DESCRIBE roundtrip). Generated ANTLR parser files (mdl/grammar/parser/) are noise — note but skip. The project context includes the full CLAUDE.md with architecture details and the review checklist. Review against the checklist thoroughly but concisely."
167+
content: "You are a code reviewer for a Go CLI project (mxcli) that reads/modifies Mendix application projects. Key patterns: ANTLR4 grammar → AST → visitor → executor → BSON writer. New MDL features MUST be wired through the full pipeline (grammar → AST → visitor → executor → LSP → DESCRIBE roundtrip). New MDL syntax must follow design guidelines: reads as English (target audience is citizen developers), uses standard CRUD verbs (CREATE/ALTER/DROP/SHOW/DESCRIBE), consistent property format (Key: value), qualified names (Module.Element), no keyword overloading, no symbolic syntax. Generated ANTLR parser files (mdl/grammar/parser/) are noise — note but skip. The project context includes the full CLAUDE.md with architecture details and the review checklist. Review against the checklist thoroughly but concisely."
157168
},
158169
{
159170
role: "user",

CLAUDE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,16 @@ When reviewing pull requests or validating work before commit, verify these item
230230
- [ ] Check `mdl-examples/doctype-tests/` for existing test coverage of the feature area
231231
- [ ] Verify the PR doesn't re-document already-shipped features as new
232232

233+
### Syntax design for MDL features
234+
New or modified MDL syntax must follow the design guidelines:
235+
- [ ] **Design skill consulted** — read `.claude/skills/design-mdl-syntax.md` before designing syntax
236+
- [ ] **Follows standard patterns** — uses `CREATE`/`ALTER`/`DROP`/`SHOW`/`DESCRIBE`, not custom verbs
237+
- [ ] **Reads as English** — a business analyst understands the statement on first reading
238+
- [ ] **Qualified names** — uses `Module.Element` everywhere, no implicit module context
239+
- [ ] **Property format** — uses `( Key: value, ... )` with colon separators, one per line
240+
- [ ] **LLM-friendly** — one example is sufficient for an LLM to generate correct variants
241+
- [ ] **Diff-friendly** — adding one property is a one-line diff
242+
233243
### Full-stack consistency for MDL features
234244
New MDL commands or language features must be wired through the full pipeline:
235245
- [ ] **Grammar** — rule added to `MDLParser.g4` (and `MDLLexer.g4` if new tokens)
@@ -343,6 +353,7 @@ Regenerate after modifying `MDLLexer.g4` or `MDLParser.g4`: `make grammar`. See
343353
## IMPORTANT: Before Writing MDL Scripts or Working with Data
344354

345355
**Read the relevant skill files FIRST before writing any MDL, seeding data, or doing database/import work:**
356+
- `.claude/skills/design-mdl-syntax.md` - **READ before designing new MDL syntax** - Design principles, decision framework, anti-patterns, checklist
346357
- `.claude/skills/write-microflows.md` - Microflow syntax, common mistakes, validation checklist
347358
- `.claude/skills/create-page.md` - Page/widget syntax reference
348359
- `.claude/skills/alter-page.md` - ALTER PAGE/SNIPPET in-place modifications (SET, INSERT, DROP, REPLACE, SET Layout)

0 commit comments

Comments
 (0)