# SysML v2 in ASysT — lessons

✅ **THIS IS THE COURSE THAT SHIPS** (owner instruction, 2026-08-11): *"what I wanted to have in the
release was the other one, the one we started just with the comments, that is the one I would have liked
to publish, not the big package of lessons that I cannot make sense of."* It is the model a customer meets
on the launcher, under the name `SysML v2 in ASysT — lessons`.

**Only one course ever reaches a customer** (owner instruction, 2026-08-10): *"from now on I only want the
new lesson on the field; the second one should remain valid in dev for reference."* That rule is unchanged
— two launcher rows both offering "lessons" make a first-time user guess which one is the course. What was
corrected on 2026-08-11 is **which model sits on which side of it**: until then the five-file animal-shelter
course was the one that travelled, and the owner opened the release and landed in the model they did not
want. The other model stays tracked as `Demo/Learn_SysmlV2` and no longer travels; the mechanism is the
exclusion list in `scripts/demo-ship-filter.mjs`, and the coverage its absence costs is written down in
`WORKSPACE_MODEL_BLIND_SPOTS`.

⚠ **Two owner rules govern the course that ships, so they govern THIS file and this model now.** They came
here with the name:

- **the name must not over-claim** (2026-08-10): *"it is a bit presumptuous to call it SysML v2 — a better
  name would be 'SysML v2 in ASysT lessons'."* This course teaches the language **as this tool draws it**,
  and it is not the OMG specification in nine parts. `modelName` in the manifest is the string a customer
  reads on the launcher tile and in the Explorer header, so that is where the claim is made or withdrawn.
- **no count of lessons appears anywhere a reader sees** (2026-08-07): *"the number of lessons may vary."*
  Not on a box, not in a note, not in a view's documentation, and not in this file. A count written into
  prose is a count that goes wrong the day a lesson is added — so the lessons are named, never counted.

This is a self-contained ASysT model. It does not modify the other one.

- `Model/00_Overview.sysml` owns the course root package.
- `Model/01_Lesson_1.sysml` owns Lesson 1 and its examples.
- `Model/02_Lesson_A.sysml` owns Lesson A — see below.
- Opening the folder in ASysT lands on the saved `lesson-1-source-and-model` rendering.
- The locked source box is live: ASysT reads its text from `01_Lesson_1.sysml`.
- The canvas capture in `Evidence/` was produced by the real ASysT frontend; the annotation behavior is
  guarded by the `comment-note.spec.ts` browser regression.

Lesson 1 keeps the canvas small and demonstrates the complete source-to-picture annotation path in ASysT:

| Written in `.sysml` | Belongs to the model? | Real ASysT canvas |
|---|---:|---|
| `// explanation` | No | Never appears |
| `/* ... */` | Yes — anonymous Comment | Folded comment node |
| `part def Pump` | Yes | `Pump` box |
| named/localized `doc /* ... */` inside `Pump` | Yes — Documentation | Documentation compartment plus folded `«doc»` node |
| `rep ... language "Python" /* ... */` | Yes — TextualRepresentation | Folded `«rep»` node linked to `Pump` |
| `comment ... about Pump, Valve /* ... */` | Yes — Comment with two annotations | One folded `«comment»` node with two dashed links |
| `comment ... about Pump::pressure /* ... */` | Yes — Comment linked to a feature | Dashed link that crosses into `Pump` and ends on the `pressure` row |

There is no `showComments` switch in SysML. A view selects model content with `expose`, while its rendering
decides the notation. In ASysT, a `comment ... about Pump` is intended to appear automatically when `Pump`
is on the board; the comment itself must not be added to `expose`.

The official table's complete textual set is supported. The documentation compartment is an alternative
graphical notation for anonymous owned documentation, not another textual declaration:

| Official textual form | Model element? | Official graphical notation | Current ASysT result |
|---|---:|---|---|
| `/* ... */` | Yes — Comment | Folded-corner anonymous comment | Drawn; no invented `«comment»` label |
| `comment Name /* ... */` | Yes — Comment | Named folded-corner `«comment»` node | Drawn |
| `comment Name about Pump, Valve /* ... */` | Yes — multi-target Comment | Comment node plus one dashed link per visible target | Drawn with both links |
| `locale "fr_BE" /* ... */` / comment locale | Yes — Comment | `«comment»` node showing locale | Drawn with locale |
| `doc /* ... */` | Yes — Documentation | Documentation compartment | Drawn in owner; avoids duplicate anonymous node |
| `doc Name locale "fr_BE" /* ... */` | Yes — Documentation | Named/localized folded `«doc»` node | Drawn with name and locale |
| `rep Name language "Python" /* ... */` | Yes — TextualRepresentation | Folded `«rep»` node with language | Drawn and linked to owner |
| `language "Python" /* ... */` | Yes — TextualRepresentation | Anonymous folded `«rep»` node | Drawn and linked to owner |

The browser regression for this lesson-sized notation set also proves that a named view completes its
opening sequence; linked comments no longer leave it stuck on “Preparing the canvas”.

## Lesson A — finding your way around

Lesson 1 teaches how prose written in a `.sysml` file reaches the picture. **Lesson A teaches the tool
itself**: how a reader gets from one board to the next and back again. It is a package, `Learn_SysML::Lesson_A`,
and its subject is a small pumping station that exists only so there is something to open.

**Reach it** from the `Lesson_A` box on the course's own board: `⋯` → `📦 Open package as General View`.

The teaching text is **not** in the `.sysml`. It is a note on each of three boards, because it describes
buttons rather than model meaning — presentation, not SysML. Each note lives in that board's
`default.asystrendering`, so it is on screen the moment a reader arrives, with no click:

| Board | Rendering | What its note says |
|---|---|---|
| the lesson's package board | `Lesson_A/general/default` | the four chapters, all played on the `WaterStation` box |
| inside `WaterStation` | `Lesson_A/WaterStation/internal-structure/default` | what the wiring is, and the two ways back |
| `StationStatus` | `Lesson_A/StationStatus/state-machine/default` | what the machine is, and the two ways back |

The four chapters, and the state each is in:

| # | Chapter | Reader presses | State |
|---|---|---|---|
| 1 | Open the code editor | — | **placeholder** — the feature is being built elsewhere; the chapter names no button yet |
| 2 | Show what is inside the box, and fold it back | `⋯` → `⤢ Expose more` twice, then `⊟ Fold more` twice | played on the running app 2026-08-17 |
| 3 | Go inside it | `⋯` → `📦 Drill in — open the internal structure` | played; the way back is the frame's `⊖` or `← Back` |
| 4 | See what it does over time | `⋯` → `🔄 Open state machine` | played; the way back is the frame's `⤴ Lesson_A` or `← Back` |

⚠ **A note names a control, so a renamed control makes the lesson wrong** — and nothing would say so. Every
button quoted in the three notes was read off the running application rather than from documentation, and
the two exits differ on purpose: `⊖ Out to definition` exists only to leave an internal structure, and a
state machine's frame carries `⤴ <package>` instead. Naming the wrong one sends a reader hunting for a
button that is not on their screen — the exact failure this lesson exists to prevent.
