Skip to content

R2 part 2: integration documents take ( ) properties and { } children; alter microflow fragments are begin … end (#754) - #776

Merged
ako merged 10 commits into
mainfrom
feature/754-rest-braces
Sep 28, 2026
Merged

ako merged 10 commits into
mainfrom
feature/754-rest-braces

Conversation

@ako

@ako ako commented Sep 28, 2026

Copy link
Copy Markdown
Owner

Part of #754 (phase 3.4, R2). This is the second PR for the issue, after #771 (flow blocks). It covers the integration documents: properties go in ( ) and children in { }. It also settles the alter microflow fragment question. Navigation/menus, the maps (Params: / DesignProperties: / ContentParams:) and database connections are listed at the end as the remainder.

What changes

Construct Canonical (new) Old spelling, still parses Code
REST operation operation GetUser ( Method: get, Path: '/u/{id}', Response: none ) operation GetUser { … } MDL-DEPR070
Agent attachment (create agent, alter agent … add) tool X ( … ), mcp service M.S ( … ), knowledge base K ( … ) … { … } MDL-DEPR071
Image collection create image collection M.I { image Logo ( File: 'logo.png' ) } ( image Logo from file 'logo.png', … ) MDL-DEPR072
Message definition collection / add definition / add member { definition D for M.E { A, M.E_B/M.B { C } } } the same with ( ) MDL-DEPR073
alter microflow / alter nanoflow fragment insert after $X begin … end;, replace <t> with begin … end; { … } MDL-DEPR074
  • The two spellings of each construct build the identical AST. The registry's Example/CanonicalExample equality test and a per-case reflect.DeepEqual test check this. No BSON path changed.
  • Each old form is a registered alias, marked /* @alias MDL-DEPR07x */ in the grammar. It warns under both mdl 0 and mdl 1, and fmt --upgrade rewrites it structurally from the parse tree: bracket swaps, commas dropped, and from file 'x' → ( File: 'x' ). Keyword case is preserved for BEGIN/END.
  • describe now prints the canonical forms for REST operations, agent attachments, image collections and message definitions.
    • Fixed along the way: describe printed an association that selects no member as M.A/M.B (), which never parsed. It is now M.A/M.B { }, and the new grammar accepts an empty member tree.
  • An image's new property list reads only File. An unknown key or a missing File is an error. This is new syntax, so there is no existing script to protect.
  • Docs are moved to the canonical forms: skills (then make sync-skills), docs-site, mxcli syntax entries, MDL_QUICK_REFERENCE.md, mdl-examples, CHANGELOG and the mxcli help text.
    • The .mdl files and the parseable markdown blocks were converted by applying only the visitor's own DEPR070–074 fixes.
    • The syntax-pattern blocks were edited by hand.
    • The image-collection reference page used IMAGE 'name' FROM FILE, which never parsed because a string is not an image name. It is corrected too.

Design choices the ADRs did not settle

  • Alter-fragment decision: yes, begin … end. It is recorded in the proposal's R2 list.
    • A fragment is imperative content, written exactly as the body of create microflow is (ADR-0012). The insert/replace/drop operations are the alter's declarative children and stay in its { }.
    • begin now ends an alter target, as { does. This is safe because describe's handles never contain begin: a loop prints it on its own line, and printedStatement already strips an error handler's begin (R2: on error begin … end error; while requires begin … end while under mdl 1 (#754, part 1) #771).
    • The terminator is end plus the operation's existing optional ;.
  • One warning per statement, not per element. A service with 20 brace operations gives one MDL-DEPR070, and its fix rewrites every pair. This is done in a single EnterStatement walk; message trees nest to depth 7. R2: on error begin … end error; while requires begin … end while under mdl 1 (#754, part 1) #771's handler code warns per handler; here the count would be noise.
  • Message definitions keep their commas. Attribute members are bare names, so they need a separator, the same as import/export mapping trees. Between definitions, which end in }, the comma is optional, and describe omits it.
  • Codes 070–074 come from the block assigned to this item.
  • Left unchanged, and not asked for by the issue:
    • Headers: ('K' = 'v') inside an operation, which the proposal's after-example writes as ( 'K': 'v' ).
    • An image collection's export level / comment clauses. Under R2 they would become ( … ) properties.

Test plan (what I ran)

  • make build
  • go test ./mdl/visitor/ ./mdl/upgrade/ ./mdl/deprecation/ ./mdl/grammar/ ./mdl/langver/ ./mdl/executor/ ./mdl/backend/... ./cmd/mxcli/...: all ok.
  • New tests:
    • mdl/visitor/r2_children_test.go: 8 cases (REST, agents, alter agent add, image collection, message collection, add definition, add member, alter microflow fragments). Each checks:

      • the canonical form under mdl 0 and mdl 1 with no warning;
      • the old form records its code once and builds a DeepEqual statement;
      • the recorded rewrite reaches the canonical form.

      Also covered: image key validation and an empty association tree.

    • mdl/executor/r2_children_describe_test.go: describe output for each document type re-parses with zero deprecations.

    • mdl/upgrade/r2_children_test.go: TestUpgrade_R2IntegrationDocumentBrackets, a mixed-case script with comments, idempotent.

    • Registry examples for DEPR070–074 are checked by the existing TestRegistryExamplesRecordTheirCode / TestUpgrade_EveryRegistryExample.

  • make test-integration-roundtrip (PedApp + TestApp): ok. No allowlist entry changed.
  • make test-integration-upgrade (execute-both property test over the converted mdl-examples): ok.
  • make check-skill-mdl: all checkable blocks pass.
  • make lint: passed.

Revert checks

  • Deprecation walk disabled (walk(ctx) commented out): TestR2Children_OldFormIsADeprecatedAlias, TestRegistryExamplesRecordTheirCode and TestUpgrade_EveryRegistryExample fail.
  • The four describers reverted to the old emitters: all four TestDescribe* R2 tests fail. REST, agent and image collection report MDL-DEPR070/071/072. Message definitions fail to re-parse on the empty () member, which is the control for the describe fix.

Not verified in Studio Pro: no BSON writer changed, and both spellings build the same statement, as the equality tests and the execute-both property test show.

Remaining for #754 (follow-up PRs)

  1. Navigation and menus: { } children without ;, and menu items as menu item 'Home' ( OnClick: show page M.P ) using R8: page actions as words, one spelling per keyword, lowercase keywords (#752) #773's action words.
  2. Maps: Params:, DesignProperties: and ContentParams: as ( key: value ).
  3. Database connections: ( Type: …, ConnectionString: … ) { query Q ( Sql: $$…$$, Returns: M.E ) }. This needs a design for query parameters and the column map inside ( ).

🤖 Generated with Claude Code

ako and others added 10 commits September 28, 2026 05:08
…en in { })

REST client operations and agent attachments take their properties in ( );
image collections and message definition collections put their children in
{ }. The old spellings keep parsing as registered deprecated aliases
MDL-DEPR070..073, recorded once per statement, with fmt --upgrade rewrites.
describe emits the canonical forms.

Part of #754.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A fragment is imperative flow, written as the body of create microflow is,
so insert after/before and replace … with take begin … end. The brace
fragment keeps parsing as MDL-DEPR074 with an fmt --upgrade rewrite. BEGIN
now ends an alter target, as { does; describe's handles never contain it.

Part of #754.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Converted with the visitor's own MDL-DEPR070..074 rewrites (no other
spelling touched), plus the syntax-pattern blocks by hand. Records the
alter-fragment decision in the beta syntax proposal.

Part of #754.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ere R3 puts them (#751)

R3 of the beta syntax freeze: `:` sets a model property, so every `alter`
takes the same `( Key: value, … )` list its `create` does, and a colon is
written in a property list or an attribute definition and nowhere else.

Canonical forms, parsed under mdl 0 and mdl 1; the old spellings keep
parsing as registered aliases that warn and that `fmt --upgrade` rewrites:

- MDL-DEPR060 alter settings <section> / configuration 'X' and
  create configuration: `Key = v, …` -> `( Key: v, … )`
- MDL-DEPR061 alter consumed|published odata service X set Key = v
  -> set ( Key: v, … ), exactly create's property list
- MDL-DEPR062 alter styling … set Class = 'x', 'P' = on -> set ( … )
- MDL-DEPR063 alter entity … set allow_create_change_locally = v
  -> set ( AllowCreateChangeLocally: v )
- MDL-DEPR064 association `type: Reference` / owner: / storage: -> no colon
- MDL-DEPR065 modify attribute A T -> modify attribute A: T
- MDL-DEPR101..103, the generic alter page/snippet/layout aliases, move
  from the executor's provisional table into the registry, with rewrites.

describe settings now writes the canonical lists, and the MDL mxcli
generates (testrunner, new-project hints) uses them. Docs, skills,
`mxcli syntax` and the quick reference follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fmt --upgrade rewrote `insert after $X{ … }drop …` to `$Xbegin … enddrop`,
which lexes as a variable and an identifier; the upgrade's re-parse refused it.
The fragment's words now get a space where the source had none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the"

The warning prints "Rewrite the <Structural>"; MDL-DEPR031 and 070-074 began
with "the" (or "each"), so it read "Rewrite the the fragment's …". A
registry test now refuses a leading "the".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#751)

fmt --upgrade promises to keep comments, but the MDL-DEPR103, -064, -060..063
rewrites replaced whole gaps: 'drop widget -- c\n a' became 'drop a',
'type: /* c */ Reference' became 'type Reference'. A gap that holds more than
whitespace now keeps its text; only the old token goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…list (#751)

The MDL-WIDGET renamed-property suggestion told users to write
`set 'Key' = 'Value'`, the spelling this PR deprecates as MDL-DEPR062.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	mdl/deprecation/deprecation.go
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