From a6eea2f9bdfee29a74d4123eb6d02e19da3cc11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergej=20Ko=C5=A1=C4=8Dejev?= Date: Mon, 9 Nov 2026 16:11:56 +0100 Subject: [PATCH 1/2] docs: keep each edit and Code Mode fact in one place --- cli/src/main/resources/explain/edit.txt | 6 ++---- .../specificlanguages/mops/daemon/core/MpsWrite.kt | 5 +---- .../mops/daemon/CodeModeExtensions.kt | 5 +++-- .../mops/daemon/ConceptValidityGuard.kt | 4 ++-- docs/reference/explain/edit.md | 6 ++---- docs/test-running-design.md | 7 ++++--- examples/pages/editing.json.md | 7 ++++--- examples/pages/editing.md | 4 ++-- examples/pages/editing.nodes.md | 6 +++--- examples/pages/validation.md | 6 +++--- .../mops/protocol/ConstraintEnforcement.kt | 8 ++------ skills/mops/SKILL.md | 13 +++++++------ skills/mops/references/editing.json.md | 7 ++++--- skills/mops/references/editing.md | 4 ++-- skills/mops/references/editing.nodes.md | 6 +++--- skills/mops/references/validation.md | 6 +++--- 16 files changed, 47 insertions(+), 53 deletions(-) diff --git a/cli/src/main/resources/explain/edit.txt b/cli/src/main/resources/explain/edit.txt index ebe1f87d..f3c38c3e 100644 --- a/cli/src/main/resources/explain/edit.txt +++ b/cli/src/main/resources/explain/edit.txt @@ -57,10 +57,8 @@ NOTES target as "$root". The leading $ is the reference sigil — required when targeting an alias, and not part of the name. Constraints: edits are checked against MPS constraints, and every violation is - reported. --constraints MODE decides what a violation does: advisory evaluates - and reports but applies the batch anyway; best-effort (the default) blocks the - batch on a violation and warns about concepts it could not check; strict also - fails on a concept it could not check. See `mops edit model --help`. + reported. --constraints MODE decides whether a violation blocks the batch; the + modes are listed in `mops edit model --help`. DRILL DOWN edit.setProperty, edit.setReference, edit.addChild, edit.copyAsChild, diff --git a/daemon-core/src/main/kotlin/com/specificlanguages/mops/daemon/core/MpsWrite.kt b/daemon-core/src/main/kotlin/com/specificlanguages/mops/daemon/core/MpsWrite.kt index d4ad2738..dd419035 100644 --- a/daemon-core/src/main/kotlin/com/specificlanguages/mops/daemon/core/MpsWrite.kt +++ b/daemon-core/src/main/kotlin/com/specificlanguages/mops/daemon/core/MpsWrite.kt @@ -19,10 +19,7 @@ interface MpsWrite : MpsRead { * Applies one batch of Edit Operations as a unit under a [ConstraintEnforcement] policy. Atomicity is best-effort: * a failure before saving reverts the in-memory changes by reloading the affected models from disk, but saving is * not transactional, so a batch spanning several models can leave earlier models persisted if a later save fails. - * Violations are always reported. [ConstraintEnforcement.BEST_EFFORT] blocks the batch on any violation (nothing is - * saved); a concept whose language did not load is skipped and reported as a warning. [ConstraintEnforcement.ADVISORY] - * applies and saves the batch even with violations. [ConstraintEnforcement.STRICT] additionally aborts when a concept - * cannot be checked because its language did not load. + * Violations are always reported; [ConstraintEnforcement] says whether they block the batch. */ fun modelEdit(batch: EditBatch, constraints: ConstraintEnforcement = ConstraintEnforcement.BEST_EFFORT): ModelEditResponse diff --git a/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/CodeModeExtensions.kt b/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/CodeModeExtensions.kt index b10ad5fb..33395fbf 100644 --- a/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/CodeModeExtensions.kt +++ b/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/CodeModeExtensions.kt @@ -61,8 +61,9 @@ object CodeModeExtensions { } /** - * Runs an MPS command on the EDT, saves successful repository changes, and returns the closure value. When the - * closure or the save throws, every changed model is reloaded from disk before the failure propagates. Access: none. + * Implements `Project.command`: runs the closure as an MPS command on the EDT and returns its value. The + * `Project.command` entry of [CodeCatalog] (`help('Project.command')`) describes what it saves and what it reverts on + * failure. Access: none. */ @CodeModeExtension(MpsAccessLevel.NONE) @JvmStatic diff --git a/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt b/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt index 7cf775c8..7f413592 100644 --- a/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt +++ b/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt @@ -10,8 +10,8 @@ import org.jetbrains.mps.openapi.persistence.PersistenceFacade * language was never compiled. * * Read commands annotate such a node (`conceptValid = false`) rather than failing. The write path uses these helpers to - * abort under strict enforcement and to name the unloaded language when it reports a skipped check as a warning. Code - * Mode role and property lookups fail on such a node, because its concept has no roles or properties to look up. + * apply [com.specificlanguages.mops.protocol.ConstraintEnforcement] to such a node and to name its unloaded language. + * Code Mode role and property lookups fail on such a node, because its concept has no roles or properties to look up. */ object ConceptValidityGuard { diff --git a/docs/reference/explain/edit.md b/docs/reference/explain/edit.md index 3e795e4d..6b2df9fd 100644 --- a/docs/reference/explain/edit.md +++ b/docs/reference/explain/edit.md @@ -63,10 +63,8 @@ NOTES target as "$root". The leading $ is the reference sigil — required when targeting an alias, and not part of the name. Constraints: edits are checked against MPS constraints, and every violation is - reported. --constraints MODE decides what a violation does: advisory evaluates - and reports but applies the batch anyway; best-effort (the default) blocks the - batch on a violation and warns about concepts it could not check; strict also - fails on a concept it could not check. See `mops edit model --help`. + reported. --constraints MODE decides whether a violation blocks the batch; the + modes are listed in `mops edit model --help`. DRILL DOWN edit.setProperty, edit.setReference, edit.addChild, edit.copyAsChild, diff --git a/docs/test-running-design.md b/docs/test-running-design.md index fdcb8e49..382e67fc 100644 --- a/docs/test-running-design.md +++ b/docs/test-running-design.md @@ -135,9 +135,10 @@ synchronously when it opens a project; the test-mode platform skips that refresh from disk the project folder, the repository folders, and the module folders of the selection that are not inside another of these folders, and MPS reloads what changed. A recursive refresh checks only files loaded into memory, and a file loaded later keeps its stored timestamp, length, and content (IJPL-219404), so the worker first loads every file -the VFS has stored under these folders. The daemon refreshes its own persistent VFS the same way before each request. -IntelliJ's own version and corruption checks rebuild outdated or broken storage. mops adds no check of its own: deleting -the cache is the documented way out and costs one cold run. +the VFS has stored under these folders. The daemon refreshes its own persistent VFS the same way; when it refreshes is +in [Daemon request concurrency](daemon-request-concurrency.md). IntelliJ's own version and corruption checks rebuild +outdated or broken storage. mops adds no check of its own: deleting the cache is the documented way out and costs one +cold run. The load includes generated output folders: generation compares new output with the content the VFS holds and skips unchanged files, and it finds and deletes stale files through the VFS. Test-worker class loading reads `deps.cp` from diff --git a/examples/pages/editing.json.md b/examples/pages/editing.json.md index ead0fdaf..24d828b6 100644 --- a/examples/pages/editing.json.md +++ b/examples/pages/editing.json.md @@ -1,6 +1,7 @@ # JSON edits -Use batches when you want explicit edit operations and constraint diagnostics. This one-liner renames a node: +Use batches when you want explicit edit operations and constraint diagnostics. `mops explain edit` describes the +operations and what a batch does. This one-liner renames a node: ```sh {{rename-node}} @@ -21,5 +22,5 @@ Copy a member subtree into a class, preserving its references and assigning fres {{table:commands|Command}} -The default `best-effort` constraint mode blocks violations but warns and skips checking concepts whose languages are -unloaded. Constraint checks are distinct from a full model check. +`--constraints` decides whether a constraint violation blocks the batch; `mops edit model --help` lists the modes. +Constraint checks are distinct from a full model check. diff --git a/examples/pages/editing.md b/examples/pages/editing.md index a88ffb50..f70dcbea 100644 --- a/examples/pages/editing.md +++ b/examples/pages/editing.md @@ -6,5 +6,5 @@ references copied from mops output. {{table:approaches|Read}} Use JSON batches for explicit edit operations with constraint diagnostics; use Code Mode for traversal and custom logic. -Resolve and validate targets before mutations. Code Mode commands save on success, but do not roll back partial edits on -an exception. A constraint check does not replace a model check, build, or regression test. +Resolve and validate targets before mutations. `mops code help Project.command` describes what a Code Mode command saves +and what it reverts when it throws. A constraint check does not replace a model check, build, or regression test. diff --git a/examples/pages/editing.nodes.md b/examples/pages/editing.nodes.md index 6e794345..17dc55d1 100644 --- a/examples/pages/editing.nodes.md +++ b/examples/pages/editing.nodes.md @@ -9,9 +9,9 @@ Save a snippet as `task.groovy` and run `{{run-file}}`, or pass it on stdin: The following snippets are complete programs. `NODE_REF`, `CLASS_REF`, `TARGET_REF`, and `STATEMENTS_REF` are placeholders. Use a method node for the `body` child examples and a BaseLanguage `ClassifierType` node for the `classifier` reference examples. Reads and lookups belong in `project.read`; writes belong in `project.command`. Blocks -cannot nest. Successful commands save changes; a command that throws reloads changed models from disk, dropping its -model changes. Each invocation has fresh variables. Return useful data: strings print as text, maps/lists become JSON, -and native nodes/models/modules become serialized references. +cannot nest. `mops code help Project.command` describes what a command saves and what it reverts when it throws. Each +invocation has fresh variables. Return useful data: strings print as text, maps/lists become JSON, and native +nodes/models/modules become serialized references. {{table:nodes|Groovy program}} diff --git a/examples/pages/validation.md b/examples/pages/validation.md index eddf2843..9862868a 100644 --- a/examples/pages/validation.md +++ b/examples/pages/validation.md @@ -82,6 +82,6 @@ Run Code Mode, edits, make, tests, checks, and rendering sequentially for a proj `code help` can run concurrently. Stop existing daemons after upgrading mops. If a language is missing/unloaded, use `diagnose module` and `make module` before retrying concept lookup. For startup delays, `MOPS_DAEMON_STARTUP_TIMEOUT_SECONDS=600 mops daemon ping` extends the startup wait. -Test runs keep IntelliJ indexes between runs in the daemon home's `test-system-cache/` directory. If test results -contradict the sources, for example find-usages results that miss existing nodes, delete that directory while no test -runs and run the tests again. +Test runs keep IntelliJ indexes between runs in a test system cache; the skill printed by `mops skill path daemon` says +where it lives. If test results contradict the sources, for example find-usages results that miss existing nodes, delete +the cache while no test runs and run the tests again. diff --git a/protocol/src/main/kotlin/com/specificlanguages/mops/protocol/ConstraintEnforcement.kt b/protocol/src/main/kotlin/com/specificlanguages/mops/protocol/ConstraintEnforcement.kt index 0017c66a..90561b43 100644 --- a/protocol/src/main/kotlin/com/specificlanguages/mops/protocol/ConstraintEnforcement.kt +++ b/protocol/src/main/kotlin/com/specificlanguages/mops/protocol/ConstraintEnforcement.kt @@ -4,12 +4,8 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** - * How `mops edit model` treats **Constraints** and concepts it cannot check. - * - * - [ADVISORY]: evaluate constraints and report violations, but apply and save the batch anyway. - * - [BEST_EFFORT]: evaluate constraints; a violation blocks the batch (nothing is saved). A concept whose language did - * not load cannot be checked, so it is skipped and reported as a warning rather than failing. - * - [STRICT]: like [BEST_EFFORT] for violations, but a concept that cannot be checked aborts the batch. + * How `mops edit model` treats **Constraints** and concepts it cannot check. `mops edit model --help` describes each + * mode under `--constraints`. */ @Serializable enum class ConstraintEnforcement { diff --git a/skills/mops/SKILL.md b/skills/mops/SKILL.md index 79aaabbe..01c4bb95 100644 --- a/skills/mops/SKILL.md +++ b/skills/mops/SKILL.md @@ -56,9 +56,10 @@ Pitfalls when navigating and searching: - `find node-by-id` turns a node ID from a `.mps` file into full references. Those files spell default numeric IDs in an encoded base64 form, while mops prints decimal IDs; the command accepts both. -Read `mops examples editing` to choose JSON edit batches, Java insertion, or Code Mode. JSON batches report containment -constraint violations; Code Mode supports custom traversal and logic. Check edited models with `check model`, build with -`make module`, and run relevant tests with `test`. Constraint checks alone do not establish model or build correctness. +Read `mops examples editing` to choose JSON edit batches, Java insertion, or Code Mode. JSON batches apply explicit edit +operations and report constraint violations, as `mops explain edit` describes; Code Mode supports custom traversal and +logic. Check edited models with `check model`, build with `make module`, and run relevant tests with `test`. Constraint +checks alone do not establish model or build correctness. For test selection, build options, failure reports, and worker limitations, read `mops examples validation` or the [bundled validation recipes](references/validation.md). @@ -94,9 +95,9 @@ concurrently. Use `mops skill path daemon` for coordination and recovery guidanc ## Model access and results Put lookup and model reads inside `project.read { ... }`, and mutations inside `project.command { ... }`. Do not nest -these access blocks. A command saves after successful completion. When it throws, every changed model is reloaded from -disk, dropping its model changes; modules and models it created and module changes remain. Resolve and validate targets -before changing them. +these access blocks. `mops code help Project.command` describes what a command saves and what it reverts when it throws; +modules and models it created and module changes remain after a failure. Resolve and validate targets before changing +them. The program runs on the daemon request thread, outside any model access. `project.read` and `project.command` open access for the calling thread only, so a worker thread started by the program may open its own `project.read`. Join diff --git a/skills/mops/references/editing.json.md b/skills/mops/references/editing.json.md index f1d6b107..b231c233 100644 --- a/skills/mops/references/editing.json.md +++ b/skills/mops/references/editing.json.md @@ -1,6 +1,7 @@ # JSON edits -Use batches when you want explicit edit operations and constraint diagnostics. This one-liner renames a node: +Use batches when you want explicit edit operations and constraint diagnostics. `mops explain edit` describes the +operations and what a batch does. This one-liner renames a node: ```sh printf '%s\n' '{"operations":[{"op":"setProperty","target":"NODE_REF","name":"name","value":"Renamed"}]}' | mops edit model @@ -30,5 +31,5 @@ printf '%s\n' '{"operations":[{"op":"copyAsChild","target":"CLASS_REF","source": | Discover copying notation | `mops explain edit.copyAsChild` | | Export the batch schema | `mops explain --schema edit` | -The default `best-effort` constraint mode blocks violations but warns and skips checking concepts whose languages are -unloaded. Constraint checks are distinct from a full model check. +`--constraints` decides whether a constraint violation blocks the batch; `mops edit model --help` lists the modes. +Constraint checks are distinct from a full model check. diff --git a/skills/mops/references/editing.md b/skills/mops/references/editing.md index 0e6cc726..ee773255 100644 --- a/skills/mops/references/editing.md +++ b/skills/mops/references/editing.md @@ -13,5 +13,5 @@ references copied from mops output. | Build, check, and run tests after editing | `mops examples validation` | Use JSON batches for explicit edit operations with constraint diagnostics; use Code Mode for traversal and custom logic. -Resolve and validate targets before mutations. Code Mode commands save on success, but do not roll back partial edits on -an exception. A constraint check does not replace a model check, build, or regression test. +Resolve and validate targets before mutations. `mops code help Project.command` describes what a Code Mode command saves +and what it reverts when it throws. A constraint check does not replace a model check, build, or regression test. diff --git a/skills/mops/references/editing.nodes.md b/skills/mops/references/editing.nodes.md index 6d2292b8..0a33dcdd 100644 --- a/skills/mops/references/editing.nodes.md +++ b/skills/mops/references/editing.nodes.md @@ -9,9 +9,9 @@ printf '%s\n' 'project.read { project.projectModules.collect { it.moduleName } } The following snippets are complete programs. `NODE_REF`, `CLASS_REF`, `TARGET_REF`, and `STATEMENTS_REF` are placeholders. Use a method node for the `body` child examples and a BaseLanguage `ClassifierType` node for the `classifier` reference examples. Reads and lookups belong in `project.read`; writes belong in `project.command`. Blocks -cannot nest. Successful commands save changes; a command that throws reloads changed models from disk, dropping its -model changes. Each invocation has fresh variables. Return useful data: strings print as text, maps/lists become JSON, -and native nodes/models/modules become serialized references. +cannot nest. `mops code help Project.command` describes what a command saves and what it reverts when it throws. Each +invocation has fresh variables. Return useful data: strings print as text, maps/lists become JSON, and native +nodes/models/modules become serialized references. | Task | Groovy program | | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/skills/mops/references/validation.md b/skills/mops/references/validation.md index 2ecdd5ae..9788f2cd 100644 --- a/skills/mops/references/validation.md +++ b/skills/mops/references/validation.md @@ -104,6 +104,6 @@ Run Code Mode, edits, make, tests, checks, and rendering sequentially for a proj `code help` can run concurrently. Stop existing daemons after upgrading mops. If a language is missing/unloaded, use `diagnose module` and `make module` before retrying concept lookup. For startup delays, `MOPS_DAEMON_STARTUP_TIMEOUT_SECONDS=600 mops daemon ping` extends the startup wait. -Test runs keep IntelliJ indexes between runs in the daemon home's `test-system-cache/` directory. If test results -contradict the sources, for example find-usages results that miss existing nodes, delete that directory while no test -runs and run the tests again. +Test runs keep IntelliJ indexes between runs in a test system cache; the skill printed by `mops skill path daemon` says +where it lives. If test results contradict the sources, for example find-usages results that miss existing nodes, delete +the cache while no test runs and run the tests again. From fb89dec4af73c69d2b37e154a91208b183fce6f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergej=20Ko=C5=A1=C4=8Dejev?= Date: Mon, 9 Nov 2026 16:13:39 +0100 Subject: [PATCH 2/2] docs: point validation recipes to the daemon skill for the test system cache --- .../specificlanguages/mops/daemon/ConceptValidityGuard.kt | 2 +- examples/pages/editing.json.md | 2 +- examples/pages/validation.md | 6 +++--- skills/mops/references/editing.json.md | 2 +- skills/mops/references/validation.md | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt b/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt index 7f413592..6cfbdda4 100644 --- a/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt +++ b/daemon/src/main/kotlin/com/specificlanguages/mops/daemon/ConceptValidityGuard.kt @@ -10,7 +10,7 @@ import org.jetbrains.mps.openapi.persistence.PersistenceFacade * language was never compiled. * * Read commands annotate such a node (`conceptValid = false`) rather than failing. The write path uses these helpers to - * apply [com.specificlanguages.mops.protocol.ConstraintEnforcement] to such a node and to name its unloaded language. + * check such a node under [com.specificlanguages.mops.protocol.ConstraintEnforcement] and to name its unloaded language. * Code Mode role and property lookups fail on such a node, because its concept has no roles or properties to look up. */ object ConceptValidityGuard { diff --git a/examples/pages/editing.json.md b/examples/pages/editing.json.md index 24d828b6..0c5699ba 100644 --- a/examples/pages/editing.json.md +++ b/examples/pages/editing.json.md @@ -1,7 +1,7 @@ # JSON edits Use batches when you want explicit edit operations and constraint diagnostics. `mops explain edit` describes the -operations and what a batch does. This one-liner renames a node: +operations and how a batch applies them. This one-liner renames a node: ```sh {{rename-node}} diff --git a/examples/pages/validation.md b/examples/pages/validation.md index 9862868a..62619108 100644 --- a/examples/pages/validation.md +++ b/examples/pages/validation.md @@ -82,6 +82,6 @@ Run Code Mode, edits, make, tests, checks, and rendering sequentially for a proj `code help` can run concurrently. Stop existing daemons after upgrading mops. If a language is missing/unloaded, use `diagnose module` and `make module` before retrying concept lookup. For startup delays, `MOPS_DAEMON_STARTUP_TIMEOUT_SECONDS=600 mops daemon ping` extends the startup wait. -Test runs keep IntelliJ indexes between runs in a test system cache; the skill printed by `mops skill path daemon` says -where it lives. If test results contradict the sources, for example find-usages results that miss existing nodes, delete -the cache while no test runs and run the tests again. +Test runs keep IntelliJ indexes between runs in a test system cache. If test results contradict the sources, for example +find-usages results that miss existing nodes, read the skill printed by `mops skill path daemon`: it says where the cache +lives and when to delete it. diff --git a/skills/mops/references/editing.json.md b/skills/mops/references/editing.json.md index b231c233..b613c7e7 100644 --- a/skills/mops/references/editing.json.md +++ b/skills/mops/references/editing.json.md @@ -1,7 +1,7 @@ # JSON edits Use batches when you want explicit edit operations and constraint diagnostics. `mops explain edit` describes the -operations and what a batch does. This one-liner renames a node: +operations and how a batch applies them. This one-liner renames a node: ```sh printf '%s\n' '{"operations":[{"op":"setProperty","target":"NODE_REF","name":"name","value":"Renamed"}]}' | mops edit model diff --git a/skills/mops/references/validation.md b/skills/mops/references/validation.md index 9788f2cd..ed362a71 100644 --- a/skills/mops/references/validation.md +++ b/skills/mops/references/validation.md @@ -104,6 +104,6 @@ Run Code Mode, edits, make, tests, checks, and rendering sequentially for a proj `code help` can run concurrently. Stop existing daemons after upgrading mops. If a language is missing/unloaded, use `diagnose module` and `make module` before retrying concept lookup. For startup delays, `MOPS_DAEMON_STARTUP_TIMEOUT_SECONDS=600 mops daemon ping` extends the startup wait. -Test runs keep IntelliJ indexes between runs in a test system cache; the skill printed by `mops skill path daemon` says -where it lives. If test results contradict the sources, for example find-usages results that miss existing nodes, delete -the cache while no test runs and run the tests again. +Test runs keep IntelliJ indexes between runs in a test system cache. If test results contradict the sources, for example +find-usages results that miss existing nodes, read the skill printed by `mops skill path daemon`: it says where the cache +lives and when to delete it.