Skip to content

Commit 9cc0921

Browse files
akoclaude
andcommitted
docs: add proposal for version-aware agent support
Proposes a 6-layer architecture for making mxcli version-aware at the MDL level: 1. Version Feature Registry (YAML, single source of truth) 2. SHOW FEATURES / SHOW DEPRECATED MDL commands 3. Executor pre-checks with actionable error messages 4. VER-prefixed linter rules (unsupported, deprecated, upgrade hints) 5. Skills for AI agent version awareness 6. Automated registry updates from reflection data diffs Covers three use cases: generating MDL for a specific version, validating before BSON write, and upgrading apps to leverage new features. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8bc2177 commit 9cc0921

File tree

1 file changed

+381
-0
lines changed

1 file changed

+381
-0
lines changed
Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
# Proposal: Version-Aware Agent Support
2+
3+
**Status:** Draft
4+
**Date:** 2026-04-02
5+
6+
## Problem Statement
7+
8+
Three use cases require mxcli to be version-aware at the MDL level:
9+
10+
1. **Generate**: An AI coding agent creates MDL for a Mendix project but doesn't know which features are available in the project's version. It writes `CREATE VIEW ENTITY` for a 9.x project and gets a cryptic BSON error.
11+
12+
2. **Validate**: A user runs an MDL script that uses 11.0+ syntax on a 10.24 project. The script executes, writes corrupt BSON, and the error only surfaces when Studio Pro tries to open the project.
13+
14+
3. **Upgrade**: A customer wants to migrate from 10.24 to 11.6 and leverage new capabilities. They need to know what patterns can be modernized and what new features become available.
15+
16+
Today, version knowledge is scattered across:
17+
- `sdk/mpr/version/version.go` (6 hardcoded features)
18+
- Comments in MDL example scripts (`-- @version: 11.0+`)
19+
- CLAUDE.md documentation (prose, not machine-readable)
20+
- Implicit knowledge in the BSON writers (version-conditional serialization)
21+
22+
There is no way for an agent or user to **query** what's available, no **pre-flight check** before writing, and no **upgrade advisor** for migration.
23+
24+
## Design Principles
25+
26+
1. **Single source of truth** -- One structured data format defines version capabilities. Everything else reads from it.
27+
2. **Machine-readable first** -- An AI agent should be able to query capabilities, not read prose.
28+
3. **Queryable at runtime** -- `SHOW FEATURES` returns capabilities for the connected project's version.
29+
4. **Fail-fast with actionable messages** -- Error before writing BSON, not after Studio Pro crashes.
30+
5. **Incremental updates** -- Adding a new version's capabilities should be a data change, not a code change.
31+
6. **Reuse existing infrastructure** -- Linter rules, skills, executor commands follow established patterns.
32+
33+
## Architecture
34+
35+
```
36+
Version Feature Registry
37+
(sdk/versions/*.yaml)
38+
|
39+
+--------------+--------------+
40+
| | |
41+
SHOW FEATURES Executor Linter
42+
(MDL command) Pre-checks Rules (VER0xx)
43+
| | |
44+
v v v
45+
Agent queries Error before Upgrade
46+
capabilities BSON write recommendations
47+
```
48+
49+
### Layer 1: Version Feature Registry
50+
51+
A structured YAML file per major version, embedded via `go:embed`:
52+
53+
```
54+
sdk/versions/
55+
mendix-9.yaml
56+
mendix-10.yaml
57+
mendix-11.yaml
58+
```
59+
60+
Each file defines features, their introduction version, syntax, deprecations, and upgrade hints:
61+
62+
```yaml
63+
# sdk/versions/mendix-10.yaml
64+
major: 10
65+
supported_range: "10.0..10.24"
66+
lts_versions: ["10.24"]
67+
mts_versions: ["10.6", "10.12", "10.18"]
68+
69+
features:
70+
domain_model:
71+
entities:
72+
introduced: "10.0"
73+
mdl: "CREATE PERSISTENT ENTITY Module.Name (...)"
74+
view_entities:
75+
introduced: "10.18"
76+
mdl: "CREATE VIEW ENTITY Module.Name (...) AS SELECT ..."
77+
notes: "OQL stored inline on OqlViewEntitySource (Oql field)"
78+
calculated_attributes:
79+
introduced: "10.0"
80+
mdl: "CALCULATED BY Module.Microflow"
81+
entity_generalization:
82+
introduced: "10.0"
83+
mdl: "EXTENDS Module.ParentEntity"
84+
85+
microflows:
86+
basic:
87+
introduced: "10.0"
88+
show_page_with_params:
89+
introduced: null
90+
available_in: "11.0+"
91+
workaround: "Pass data via a non-persistent entity or microflow parameter"
92+
send_rest_request:
93+
introduced: "10.1"
94+
notes: "Query parameters require 11.0+"
95+
96+
pages:
97+
page_parameters:
98+
introduced: null
99+
available_in: "11.0+"
100+
pluggable_widgets:
101+
introduced: "10.0"
102+
widgets:
103+
- ComboBox
104+
- DataGrid2
105+
- Gallery
106+
- Image
107+
notes: "Widget templates are version-specific; MPK augmentation handles drift"
108+
design_properties_v3:
109+
introduced: null
110+
available_in: "11.0+"
111+
notes: "Atlas v3 design properties (Card style, Disable row wrap)"
112+
113+
security:
114+
module_roles:
115+
introduced: "10.0"
116+
demo_users:
117+
introduced: "10.0"
118+
119+
integration:
120+
rest_client:
121+
introduced: "10.1"
122+
notes: "Full BSON format requires 11.0+"
123+
database_connector:
124+
introduced: "10.6"
125+
notes: "EXECUTE DATABASE QUERY BSON format requires 11.0+"
126+
business_events:
127+
introduced: "10.0"
128+
129+
workflows:
130+
basic:
131+
introduced: null
132+
available_in: "9.0+"
133+
134+
deprecated:
135+
- id: "DEP001"
136+
pattern: "Persistable: false on view entities"
137+
replaced_by: "Persistable: true (auto-set)"
138+
since: "10.18"
139+
severity: "info"
140+
141+
upgrade_opportunities:
142+
from_10_to_11:
143+
- feature: "page_parameters"
144+
description: "Replace non-persistent entity parameter passing with direct page parameters"
145+
effort: "low"
146+
- feature: "design_properties_v3"
147+
description: "Atlas v3 design properties available for richer styling"
148+
effort: "low"
149+
- feature: "association_storage"
150+
description: "New association storage format (automatic on project upgrade)"
151+
effort: "none"
152+
```
153+
154+
### Layer 2: MDL Commands
155+
156+
#### `SHOW FEATURES`
157+
158+
Lists all features available for the connected project's Mendix version:
159+
160+
```sql
161+
SHOW FEATURES;
162+
```
163+
164+
Output:
165+
```
166+
| Feature | Available | Since | Notes |
167+
|------------------------|-----------|--------|------------------------------------------|
168+
| Persistent entities | Yes | 10.0 | |
169+
| View entities | Yes | 10.18 | OQL stored inline on source object |
170+
| Page parameters | No | 11.0+ | Use non-persistent entity workaround |
171+
| Pluggable widgets | Yes | 10.0 | ComboBox, DataGrid2, Gallery, Image |
172+
| Design properties v3 | No | 11.0+ | Atlas v3 required |
173+
| REST client | Partial | 10.1 | Query parameters require 11.0+ |
174+
| Database connector | Partial | 10.6 | EXECUTE DATABASE QUERY requires 11.0+ |
175+
| Business events | Yes | 10.0 | |
176+
| Workflows | Yes | 9.0 | |
177+
```
178+
179+
#### `SHOW FEATURES ADDED SINCE <version>`
180+
181+
Shows what becomes available when upgrading:
182+
183+
```sql
184+
SHOW FEATURES ADDED SINCE 10.24;
185+
```
186+
187+
Output:
188+
```
189+
| Feature | Available In | Description | Effort |
190+
|----------------------|-------------|------------------------------------------|--------|
191+
| Page parameters | 11.0 | Direct page parameter passing | Low |
192+
| Design properties v3 | 11.0 | Atlas v3 Card style, Disable row wrap | Low |
193+
| REST query params | 11.0 | Query parameter support in REST clients | Low |
194+
| Portable app format | 11.6 | New deployment format | None |
195+
```
196+
197+
#### `SHOW DEPRECATED`
198+
199+
Lists deprecated patterns in the current project:
200+
201+
```sql
202+
SHOW DEPRECATED;
203+
```
204+
205+
### Layer 3: Executor Pre-Checks
206+
207+
Before writing BSON, the executor checks version compatibility and produces actionable errors:
208+
209+
```go
210+
// In cmd_entities.go, before creating a view entity:
211+
if s.IsViewEntity {
212+
pv := e.reader.ProjectVersion()
213+
if !pv.IsAtLeast(10, 18) {
214+
return fmt.Errorf(
215+
"CREATE VIEW ENTITY requires Mendix 10.18+ (project is %s)\n"+
216+
" hint: upgrade your project or use a regular entity with a microflow data source",
217+
pv.ProductVersion,
218+
)
219+
}
220+
}
221+
```
222+
223+
This pattern already exists informally in the codebase (version-conditional BSON writing). The proposal formalizes it with:
224+
225+
1. A `CheckFeature(feature, version)` function that returns a user-friendly error
226+
2. Pre-checks at the start of each executor command
227+
3. Consistent error format with hints
228+
229+
### Layer 4: Linter Rules (VER prefix)
230+
231+
New linter rule category `VER` for version-related checks:
232+
233+
| Rule | Name | Description |
234+
|------|------|-------------|
235+
| VER001 | UnsupportedFeature | Feature used that's not available in project version |
236+
| VER002 | DeprecatedPattern | Deprecated pattern that has a modern replacement |
237+
| VER003 | UpgradeOpportunity | Pattern that can be simplified on a newer version |
238+
239+
**VER001** runs during `mxcli check` and `mxcli lint`:
240+
```
241+
[VER001] CREATE VIEW ENTITY requires Mendix 10.18+ (project is 10.12.0)
242+
at line 42 in script.mdl
243+
hint: upgrade to 10.18+ or use a microflow data source
244+
```
245+
246+
**VER003** runs during `mxcli lint --upgrade-hints`:
247+
```
248+
[VER003] Page MyModule.EditCustomer uses non-persistent entity for parameter passing
249+
This pattern can be replaced with page parameters in Mendix 11.0+
250+
effort: low
251+
```
252+
253+
### Layer 5: Skills (AI Agent Guidance)
254+
255+
One skill file: `.claude/skills/version-awareness.md`
256+
257+
```markdown
258+
# Version Awareness
259+
260+
## Before Generating MDL
261+
262+
Always check the project's Mendix version before writing MDL:
263+
264+
SHOW STATUS; -- shows connected project version
265+
SHOW FEATURES; -- shows available features
266+
267+
## Version-Conditional Patterns
268+
269+
If a feature is not available, use the documented workaround:
270+
271+
SHOW FEATURES WHERE name = 'page_parameters';
272+
-- If not available, use non-persistent entity pattern instead
273+
274+
## Upgrade Workflow
275+
276+
When migrating to a newer version:
277+
278+
SHOW FEATURES ADDED SINCE 10.24; -- what's new
279+
SHOW DEPRECATED; -- what to update
280+
mxcli lint --upgrade-hints -p app.mpr -- automated suggestions
281+
```
282+
283+
This skill is small and stable -- it teaches the agent to **query** mxcli rather than embedding version knowledge in the skill itself. The version data lives in the registry.
284+
285+
### Layer 6: Keeping Data Current
286+
287+
The version registry needs updates when Mendix releases new versions. Proposed pipeline:
288+
289+
1. **Automated**: `mxcli diff-schemas 11.5 11.6` compares reflection data between versions, outputs added/removed types and properties as a diff report.
290+
291+
2. **Semi-automated**: An agent reads the diff report + Mendix release notes and proposes updates to the YAML registry. Human reviews and merges.
292+
293+
3. **On-demand**: `mxcli update-features` downloads the latest registry from a central source (GitHub release asset), similar to how `mxcli setup mxbuild` downloads tooling.
294+
295+
4. **Community**: The `-- @version:` directives in MDL test scripts serve as executable documentation. If a test fails on a version, the directive gets updated — and that update feeds back into the registry.
296+
297+
## Implementation Plan
298+
299+
### Phase 1: Version Feature Registry + SHOW FEATURES (foundation)
300+
301+
1. Create `sdk/versions/` package with YAML loader and `go:embed`
302+
2. Create YAML files for Mendix 9, 10, 11 (initial feature set from existing knowledge)
303+
3. Implement `SHOW FEATURES` command in executor
304+
4. Implement `SHOW FEATURES ADDED SINCE <version>` variant
305+
5. Wire into AST/grammar: add `FEATURES` keyword to MDLParser.g4
306+
307+
**Deliverable**: Agent can query `SHOW FEATURES` and get machine-readable output.
308+
309+
### Phase 2: Executor Pre-Checks (fail-fast)
310+
311+
1. Add `CheckFeatureAvailable(feature string)` method to Executor
312+
2. Add version checks to CREATE VIEW ENTITY, CREATE REST CLIENT, CREATE PAGE (with Params), EXECUTE DATABASE QUERY
313+
3. Produce error messages with version requirement, current version, and workaround hint
314+
4. Test: run MDL scripts with version-gated features on older projects
315+
316+
**Deliverable**: Unsupported features fail immediately with actionable error instead of corrupting BSON.
317+
318+
### Phase 3: Linter Rules (VER category)
319+
320+
1. Implement VER001 (UnsupportedFeature) -- reads from version registry
321+
2. Implement VER002 (DeprecatedPattern) -- reads deprecated list from registry
322+
3. Wire into `mxcli lint` and `mxcli check`
323+
4. Add SARIF output support for CI integration
324+
325+
**Deliverable**: `mxcli lint -p app.mpr` reports version issues.
326+
327+
### Phase 4: Upgrade Advisor
328+
329+
1. Implement VER003 (UpgradeOpportunity) linter rule
330+
2. Implement `SHOW DEPRECATED` command
331+
3. Implement `SHOW FEATURES ADDED SINCE` with effort estimates
332+
4. Implement `mxcli lint --upgrade-hints --target-version 11.6`
333+
334+
**Deliverable**: Migration planning from any version to any newer version.
335+
336+
### Phase 5: Skills + Agent Integration
337+
338+
1. Create `.claude/skills/version-awareness.md`
339+
2. Update `.claude/skills/check-syntax.md` to include version pre-check
340+
3. Update `mxcli init` to include version-awareness skill in project setup
341+
4. Test: AI agent generates valid MDL for both 10.24 and 11.6 projects
342+
343+
**Deliverable**: AI agents automatically adapt to project version.
344+
345+
### Phase 6: Automated Registry Updates
346+
347+
1. Implement `mxcli diff-schemas <from> <to>` using reflection data
348+
2. Create agent workflow: diff-schemas output + release notes -> YAML update PR
349+
3. Implement `mxcli update-features` for on-demand downloads
350+
4. Add to nightly CI: verify registry matches reflection data
351+
352+
**Deliverable**: Registry stays current with minimal manual effort.
353+
354+
## Relationship to BSON Schema Registry Proposal
355+
356+
This proposal complements `BSON_SCHEMA_REGISTRY_PROPOSAL.md`:
357+
358+
- **Schema Registry** handles **structural** version differences (field names, defaults, encoding) at the BSON level
359+
- **This proposal** handles **feature-level** version differences (what MDL commands are available) at the user/agent level
360+
361+
The version feature registry (YAML) is simpler and more immediately useful than the full schema registry. It can be built first and later integrated with the schema registry as that matures.
362+
363+
```
364+
User/Agent Layer This Proposal "What can I do?"
365+
|
366+
MDL Layer Executor pre-checks "Will this work?"
367+
|
368+
BSON Layer Schema Registry "How do I serialize this?"
369+
```
370+
371+
## Open Questions
372+
373+
1. **YAML vs JSON for registry?** YAML is more readable for humans editing it; JSON is easier to parse. Could use YAML as source, compile to embedded JSON at build time.
374+
375+
2. **Granularity of features?** Per-statement (`CREATE VIEW ENTITY`), per-property (`Params:` on pages), or per-concept (`view_entities`)? Probably per-concept with per-property notes.
376+
377+
3. **Should SHOW FEATURES work without a connected project?** Could accept `SHOW FEATURES FOR VERSION 10.24` without needing an MPR file. Useful for planning.
378+
379+
4. **How to handle patch-level differences?** Most changes are at the minor level, but some patch releases introduce fixes. Use minor as the default, with patch-level overrides where needed.
380+
381+
5. **Should the upgrade advisor be interactive?** E.g., `mxcli upgrade --from 10.24 --to 11.6 --dry-run` that shows a migration plan and optionally applies changes.

0 commit comments

Comments
 (0)