Skip to content

RFC: Self-describing syntax feature registry for LLM-friendly help discovery#172

Open
engalar wants to merge 6 commits intomendixlabs:mainfrom
engalar:research/recursive-help-discovery
Open

RFC: Self-describing syntax feature registry for LLM-friendly help discovery#172
engalar wants to merge 6 commits intomendixlabs:mainfrom
engalar:research/recursive-help-discovery

Conversation

@engalar
Copy link
Copy Markdown
Contributor

@engalar engalar commented Apr 10, 2026

Summary

  • Current help system is flat (26 monolithic .txt topics) — no drill-down, no structured output, no LLM-friendly discovery
  • Proposes a SyntaxFeature registry where each syntax construct self-registers with metadata (path, summary, keywords, example)
  • Enables mxcli syntax --json for one-shot LLM discovery, hierarchical drill-down, and single-file changes for new features

Key Design Decisions (seeking feedback)

  1. Registry vs enhanced .txt files — chose registry for single source of truth
  2. Separate syntax/ package — keeps syntax docs out of executor logic
  3. Path convention domain.concept.detail — e.g. workflow.user-task.targeting
  4. HELP <topic> in MDL REPL — requires grammar change, worth it?

Design Doc

See docs/11-proposals/syntax-feature-registry.md

Test plan

  • Review design doc for feasibility and scope
  • Discuss whether HELP <topic> grammar change is worthwhile
  • Validate path convention covers all existing syntax topics

🤖 Generated with Claude Code

…y help discovery

Current help system is flat (26 monolithic .txt topics) with no drill-down,
no structured output, and no way for LLMs to bridge from business concepts
to MDL syntax. Proposes a SyntaxFeature registry where each syntax construct
self-registers with metadata (path, summary, keywords, example), enabling:
- `mxcli syntax --json` for one-shot LLM discovery
- Hierarchical drill-down (workflow → user-task → targeting)
- Single-file changes when adding new features
@engalar engalar force-pushed the research/recursive-help-discovery branch from c7e5398 to 06afead Compare April 13, 2026 07:49
@github-actions
Copy link
Copy Markdown

AI Code Review

What Looks Good

The proposal document is well-structured and addresses a genuine pain point: the flat, monolithic help system that hinders LLM discovery and hierarchical navigation. The design thoughtfully considers:

  • LLM-centric workflow: Prioritizes --json output for single-shot discovery
  • Hierarchical organization: Uses domain.concept.detail path convention for intuitive drill-down
  • Migration strategy: Phased approach with backward compatibility during transition
  • Separation of concerns: Distinguishes between Skills (guidance) and Registry (discovery)
  • Single-file feature addition: Reduces friction for contributors adding new syntax topics

The document clearly articulates the problem, solution, trade-offs (registry vs enhanced .txt files), and implementation path. It aligns with the project's goals of improving LLM-friendly tooling while maintaining usability for human users.

Recommendation

Approve - This is a well-considered RFC/proposal document that requires no code changes at this stage. The design is sound, addresses real user needs, and follows appropriate processes for proposing significant enhancements. No issues were found in the proposal itself that would block moving forward to implementation phases. When the actual implementation occurs in subsequent PRs, it will need to undergo full checklist review for MDL syntax changes (particularly the HELP <topic> grammar modification) and full-stack consistency.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

engalar and others added 4 commits April 13, 2026 16:29
Registry core with workflow (12) and security (8) features registered,
--json output, hierarchical drill-down, legacy .txt fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
95 features registered across 7 domain files: domain-model (18),
microflow (13), page/snippet/fragment (16), navigation/settings/misc (12),
integration/odata/rest/sql/xpath (20), workflow (12), security (8).
Legacy topic aliases map old names to new registry paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
HELP WORKFLOW; HELP WORKFLOW USER TASK; HELP SECURITY ENTITY ACCESS;
all now query the syntax feature registry. Greedy path resolver
merges space-separated words into hyphenated registry paths.

Grammar extended: helpStatement accepts optional identifierOrKeyword*.
AST HelpStmt gains Topic []string field.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Delete 25 .txt files, embedded FS, switch statement, showKeywords/
showTypes/showDeleteBehaviors functions, and reservedKeywords/
attributeTypes/deleteBehaviors data. All topics now served from
the syntax feature registry with full alias map for backward compat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@engalar
Copy link
Copy Markdown
Contributor Author

engalar commented Apr 13, 2026

Implementation Complete — Syntax Feature Registry

All 4 phases from the proposal are now implemented and verified.

What was built

Phase Scope Commits
1 Registry core + --json + workflow/security features b8996ef
2 Migrate all 25 help topics → 99 registered features c5e756b
3 HELP <topic> command with greedy path resolver fb61478
4 Delete help_topics/, embedded FS, legacy code (-2956 lines) 1b793f5

Feature inventory: 99 features across 21 domains

Domain Count Domain Count
domain-model 15 microflow 13
workflow 13 page 9
security 8 sql 5
navigation 4 errors 4
snippet 4 fragment 4
settings 3 odata 3
rest 3 business-events 2
java-action 2 xpath 2
integration 1 oql 1
search 1 structure 1
move 1

Test report — 18 scenarios, all passing

# Scenario Input Result
1 No args → help text mxcli syntax Shows topic list and examples
2 Full JSON index mxcli syntax --json Valid JSON, 99 features parsed
3 Top-level domain list mxcli syntax workflow 13 workflow features listed
4 Drill down to sub-topic mxcli syntax workflow user-task 2 features (user-task + targeting)
5 Leaf node detail mxcli syntax workflow user-task targeting Full detail: syntax, example, version, keywords
6 JSON single feature mxcli syntax security entity-access --json Valid JSON with keywords, see_also
7 Legacy alias: entity mxcli syntax entity → domain-model.entity (5 features)
8 Plural alias: microflows mxcli syntax microflows → microflow (13 features)
9 Variant alias: be mxcli syntax be → business-events (2 features)
10 REPL: HELP (no topic) HELP; Original command overview
11 REPL: HELP WORKFLOW HELP WORKFLOW; 13 workflow features
12 REPL: multi-word path HELP WORKFLOW USER TASK; Resolves to workflow.user-task
13 REPL: 4-word path HELP DOMAIN MODEL ENTITY CREATE; Resolves to domain-model.entity.create
14 Unknown topic (CLI) mxcli syntax foobar "Unknown topic" + help
15 Unknown topic (REPL) HELP FOOBAR; "No syntax help found" + hint
16 Full domain hierarchy mxcli syntax domain-model 15 features, 3 levels deep
17 Legacy: keywords/types/delete mxcli syntax keywords Alias resolves, detail shown
18 JSON feature count mxcli syntax --json | jq length 99

Key design decisions

  • Greedy path resolver: HELP WORKFLOW USER TASK → tries workflow-user-task (no match) → workflow (match) + user-task (match) → workflow.user-task. Works for any depth.
  • Backward compat: 28 aliases map old topic names (entity, microflows, be, nav, etc.) to new registry paths.
  • Single file per feature domain: Adding a new feature = one Register() call in the right features_*.go file. No switch case, no .txt file, no topic list update.

Typical LLM flow

# 1. Get full index (cache in context)
mxcli syntax --json

# 2. Match keywords → find relevant path
# 3. Drill down for detail
mxcli syntax workflow user-task targeting --json

@engalar
Copy link
Copy Markdown
Contributor Author

engalar commented Apr 13, 2026

Drill-Down Evidence: From Business Question to Exact Syntax

Each scenario starts from a vague business question. The user doesn't know the registry path — they discover it step by step.


Chain A: "Who can approve this user task?"

Step 1 — Don't know where to start → mxcli syntax

Top-level topics:
  domain-model    - Entities, associations, enumerations, constants...
  microflow       - Microflow/nanoflow creation and activities
  workflow        - Workflows, user tasks, decisions, parallel splits  ← this one
  security        - Roles, access control, demo users
  ...

Step 2 — Enter workflow → mxcli syntax workflow

  workflow                                 Multi-step business processes...
  workflow.alter                           Modify an existing workflow...
  workflow.call-microflow                  Call a microflow as a workflow activity
  workflow.decision                        Decision activity...
  workflow.user-task                       User task — assigns work to users  ← this one
  workflow.user-task.targeting             Control who can pick up a user task  ← or directly this

Step 3 — Drill into user-task → mxcli syntax workflow user-task

  workflow.user-task                       User task — assigns work to users with outcomes
  workflow.user-task.targeting             Control who can pick up a user task  ← answer here

Step 4 — Get the answer → mxcli syntax workflow user-task targeting

workflow.user-task.targeting
════════════════════════════
Control who can pick up a user task — microflow or XPath based
Requires: Mendix 9.0.0+

Syntax:
  TARGETING MICROFLOW Module.MF
  TARGETING XPATH '<xpath-expression>'

Example:
  USER TASK Approve 'Approve request'
    TARGETING XPATH '[HR.Employee/Role = "Manager" and Active = true()]'
    OUTCOMES 'Done' { };

4 steps: vague question → topic → sub-topic → exact syntax with working example.


Chain B: "How do I grant a role access to entity data?"

Step 1mxcli syntax security

  security                                 Application security: roles, access control, demo users
  security.entity-access                   Grant or revoke entity-level access  ← found it
  security.microflow-access                Grant or revoke execution rights on microflows
  security.module-role                     Create and manage module-level security roles
  ...

Step 2mxcli syntax security entity-access

security.entity-access
══════════════════════
Syntax:
  GRANT <role> ON <module>.<entity> (<rights>) [WHERE '<xpath>'];
  Rights: CREATE, DELETE, READ *, READ (<attr>,...), WRITE *, WRITE (<attr>,...)

Example:
  GRANT Shop.Admin ON Shop.Customer (CREATE, DELETE, READ *, WRITE *);
  GRANT Shop.User ON Shop.Customer (READ *) WHERE '[Active = true()]';

2 steps. The summary line "Grant or revoke entity-level access" is enough to identify the right feature.


Chain C: "Import data from an external database into Mendix"

Step 1mxcli syntax sql

  sql                                      External SQL queries against PostgreSQL, Oracle, SQL Server
  sql.connect                              Connect to external databases with credential isolation
  sql.generate                             Auto-generate Database Connector MDL from schema
  sql.import                               Import rows from external DB into Mendix app database  ← this
  sql.query                                Execute SQL queries and browse schema

Step 2mxcli syntax sql import

sql.import
══════════
Syntax:
  IMPORT FROM <alias> QUERY '<sql>'
    INTO Module.Entity MAP (col AS Attr, ...)
    [LINK (col TO Assoc ON Attr, ...)]
    [BATCH n] [LIMIT n];

Example:
  IMPORT FROM source QUERY 'SELECT name, email FROM employees'
    INTO HR.Employee MAP (name AS Name, email AS Email);

2 steps. Summary lines are the discovery mechanism — no need to know the path upfront.


LLM flow (programmatic)

LLMs don't drill down interactively. They get the full index in one call:

mxcli syntax --json   # 99 features with keywords, cached in context

Then match the business question against keywords:

  • "who can approve" → matches ["targeting", "assignee", "who can execute"]workflow.user-task.targeting
  • "grant access" → matches ["grant", "entity access", "row-level security"]security.entity-access

One index call + keyword matching = direct path. No drill-down needed.

…help topic

- Move topicAliases to syntax package so HELP <topic> works in REPL (was broken: HELP entity returned "No syntax help found")
- Add duplicate path detection in Register() (panic on duplicate)
- Register missing 'test' help topic (replaced deleted test.txt)
- Fix capitalize() for UTF-8 safety
- Add unit tests for resolveHelpPath and ResolveAlias
- Add TestAliasTargetsExist to verify all aliases point to valid paths
- Add doctype-test for HELP command

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@engalar engalar marked this pull request as ready for review April 13, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant