Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
372a9c4
Diagram survey spec: diagrams build visual-syntax literacy, not just …
mzargham Oct 1, 2026
46cdd8f
Diagram survey spec: correct tool count to 5 (DEMA SysML2Tools was mi…
mzargham Oct 1, 2026
a501371
diagram-tool-gaps.md: G-D001 was already resolved; the register entry…
mzargham Oct 1, 2026
2655e5d
diagram-generation-strategy plan: tick checkboxes to match reality, a…
mzargham Oct 1, 2026
687c289
Phase 1: compile the per-chapter diagram survey (decisions/diagram-su…
mzargham Oct 1, 2026
dd8f38a
sysml-diagrams skill: state the sysml-toolkit criterion explicitly; f…
mzargham Oct 1, 2026
61a9c1e
render.py: add render_toolkit_interconnection() via sysml-toolkit's r…
mzargham Oct 1, 2026
cc67753
Add tests for render_toolkit_interconnection() against the real ch05 …
mzargham Oct 1, 2026
1b27caf
Ch5 03-interfaces: render the interconnection figure via sysml-toolki…
mzargham Oct 1, 2026
db50071
render.py: fix interconnection diagram layout and tighten path valida…
mzargham Oct 1, 2026
80efd94
tests: fix vacuous port-name assertion; cover layout and path-validat…
mzargham Oct 1, 2026
bdaa544
Ch5 03-interfaces: drop internal skill citation from cell 16's comment
mzargham Oct 1, 2026
ee3c792
Regenerate ch05-interconnection figure with the ortho/label-wrap layo…
mzargham Oct 1, 2026
87646f9
DL-086: record Phase 1 completion, the Ch5 sysml-toolkit upgrade, and…
mzargham Oct 1, 2026
4e285ae
Sidebar: stop repeating the chapter title on its own index/conclusion…
mzargham Oct 1, 2026
3c50106
Add Phase 2 implementation plan: 16 diagrams across Ch1-4,6-8,10, plu…
mzargham Oct 1, 2026
b265c80
Provision OpenSysML's render-capable CLI; implement render_action_flo…
mzargham Oct 1, 2026
fc97f6c
Fix tamper-detection test's hardcoded darwin-arm64 pin (review findin…
mzargham Oct 1, 2026
906265c
Ch1: add the tutorial's first two structure diagrams (edgeless, then …
mzargham Oct 1, 2026
1341f30
Ch4: add the tutorial's first action-flow diagram, and a scoped struc…
mzargham Oct 1, 2026
227b03e
Ch7: add the tutorial's first state diagrams (base Cycle, and the typ…
mzargham Oct 1, 2026
d328269
Fix model_to_dot() drawing a requirement's subject as part composition
mzargham Oct 1, 2026
8441c2c
Merge Task 5: Ch4 action-flow and structure diagrams
mzargham Oct 1, 2026
36ab3b8
Merge Task 8: Ch7 state diagrams
mzargham Oct 1, 2026
590cf14
Extend model_to_dot()'s subject-skip to the whole Requirement/Case fa…
mzargham Oct 1, 2026
f888dcd
Fix build_interconnection_intent() drawing an unrelated element's all…
mzargham Oct 1, 2026
822d3f0
Soften model_to_dot() docstring's overclaim and strengthen Ch3 test
mzargham Oct 1, 2026
83c288f
Merge model_to_dot() requirement/case-subject fix
mzargham Oct 1, 2026
3b31455
Ch2: add a structure diagram orienting the reader before the judgment…
mzargham Oct 1, 2026
221baec
Re-render Ch2 structure diagram against fixed model_to_dot()
mzargham Oct 1, 2026
5d93fb7
Ch3: add a structure diagram orienting the reader before the threshol…
mzargham Oct 1, 2026
f1afc1f
Fix ensure_ascii diff noise: restore raw UTF-8 § in two pre-existing …
mzargham Oct 1, 2026
5c1359c
Re-render Ch3 structure diagram against fixed model_to_dot()
mzargham Oct 1, 2026
121a464
Ch5: add the chapter's remaining structure diagram (nb01, unscoped)
mzargham Oct 1, 2026
fb89825
Merge build_interconnection_intent() allocation-scoping fix
mzargham Oct 1, 2026
c1ffbe8
Re-render Ch5 structure diagram against fixed model_to_dot()
mzargham Oct 1, 2026
c88d66b
Merge Task 3: Ch2 structure diagram (re-rendered against fixed model_…
mzargham Oct 1, 2026
ff7f2dd
Merge Task 4: Ch3 structure diagram (re-rendered against fixed model_…
mzargham Oct 1, 2026
e63ca54
Merge Task 6: Ch5 remaining structure diagram (re-rendered against fi…
mzargham Oct 1, 2026
303dfd4
Ch8: add a structure diagram grounding the heatGenCheck sibling-usage…
mzargham Oct 1, 2026
5ce7e2d
Re-render Ch8 structure diagram against fixed model_to_dot()
mzargham Oct 1, 2026
91defb8
Ch10: add a whole-model structure diagram orienting the reader before…
mzargham Oct 1, 2026
70c69e5
Re-render Ch10 structure diagram against fixed model_to_dot()
mzargham Oct 1, 2026
7dcf26a
Merge Task 10: Ch10 whole-model structure diagram
mzargham Oct 1, 2026
08f94f3
Correct Ch8 diagram caption: rated/weak are typed by ResistanceCoil, …
mzargham Oct 1, 2026
3038b9d
Merge Task 9: Ch8 structure diagram
mzargham Oct 1, 2026
7cf7a46
Ch6: add four diagrams (action-flow, interconnection x2, structure), …
mzargham Oct 1, 2026
b3247f6
Ch6: fix pacing-rule violations at all four diagram insertions
mzargham Oct 1, 2026
6f8b6ad
Fix Ch6 interconnection narration and re-render against both render.p…
mzargham Oct 1, 2026
bfcb54f
Fix nb01 cell-20 false equivalence and remove two new em-dashes in nb03
mzargham Oct 1, 2026
92dde9b
Merge Task 7: Ch6 action-flow, two interconnection, and structure dia…
mzargham Oct 1, 2026
1d3e976
DL-087: Phase 2 diagram implementation complete
mzargham Oct 1, 2026
a3e658a
Ch5: fix index.md/conclusion.md naming the superseded interconnection…
mzargham Oct 1, 2026
e46c5c2
DL-088: pre-PR user-testing pass, 29 reports, zero blocking issues
mzargham Oct 1, 2026
0b3151b
Three cosmetic fixes from the pre-PR user-testing pass
mzargham Oct 2, 2026
f108562
Fix notebook title duplication and rewrite Ch8-10 headings to match C…
mzargham Oct 2, 2026
0317236
Fix model_to_dot(): skip false composition edge for package-owned Par…
mzargham Oct 2, 2026
a10f695
Add tests for model_to_dot() package-composition and specialization-e…
mzargham Oct 2, 2026
6568ba5
Document new edge behavior and fix a latent generator-exhaustion bug
mzargham Oct 2, 2026
37017a1
Merge model_to_dot() notation fix: package-composition bug + speciali…
mzargham Oct 2, 2026
6f4db15
Re-render Ch2/Ch3/Ch5/Ch8/Ch10 structure diagrams against the model_t…
mzargham Oct 2, 2026
9edfed6
Fix Ch8 caption: heatGenCheck is not drawn as a sibling under any own…
mzargham Oct 2, 2026
c262a39
DEFERRED.md D-037: OpenSysML's -render CLI drops flow pins and state-…
mzargham Oct 2, 2026
e278064
DL-089: pre-PR triage of DL-087/DL-088's open findings, plus two defe…
mzargham Oct 2, 2026
393f305
F1: revert cell-0 YAML frontmatter across all 32 chapter notebooks
mzargham Oct 2, 2026
7acfa85
F3: Ch8-01 heading names the actual construct, assert constraint
mzargham Oct 2, 2026
6bb9b17
F2: sync Ch8/9/10 Ingredients tables to current notebook headings
mzargham Oct 2, 2026
bef93bb
F4: correct D-037's action-flow call sites and evidence files
mzargham Oct 2, 2026
4ab30ee
F5: trim three captions to the style guide's 20-word sentence ceiling
mzargham Oct 2, 2026
1ea9d54
F1: lift cell-0 H1 heading into page title via short_title metadata
mzargham Oct 2, 2026
02e5d0b
F5: redo three caption trims without self-reference or over-compression
mzargham Oct 2, 2026
3c7c335
Ch8-01: fix caption/bridge false uniqueness claim about specializatio…
mzargham Oct 2, 2026
11017fe
Merge audit-remediation: fix F1-F5 regressions found in un-reviewed d…
mzargham Oct 2, 2026
ac90917
DL-090: audit-remediation record -- the harness-bypass incident, the …
mzargham Oct 2, 2026
a01b4b9
toaster-recipe: document the H1-heading + short_title notebook-title …
mzargham Oct 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/sysml-diagrams/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Use one default pipeline for each figure type. Read only the relevant recipe in
| Question / figure type | Default pipeline | Why |
|---|---|---|
| What is the system made of? Definition and decomposition view | `model_to_dot()` (in-house, `src/toaster/render.py`) → Graphviz SVG | Draws the whole model's containment graph from a full `model.query()`, not one root's direct children — a real-fixture rerun of the diagram trade study (`decisions/diagram-study-real-fixtures.md`) found the OMG pilot fails on all real chapter content (qualified-name `allocate` targets), and rendering a single root via OpenSysML's `#tree:` form only shows that root's own direct features, one level deep. |
| How do parts connect through ports? Interconnection view | Model query → `render_interconnection()` (in-house, `src/toaster/render.py`; the same real-fixture study found the actual third-party SysMLD tool cannot index real content at all) → Graphviz SVG | Draws part connectivity, port identity (as edge labels), and allocations, with zero dependency on a tool proven unreliable on real content. Where dedicated port boxes (not just labeled edges) matter pedagogically, sysml-toolkit is the alternative — it drew real port names correctly on every real fixture tested. |
| How do parts connect through ports? Interconnection view | Model query → `render_interconnection()` (in-house, `src/toaster/render.py`; the same real-fixture study found the actual third-party SysMLD tool cannot index real content at all) → Graphviz SVG | Draws part connectivity, port identity (as edge labels), and allocations, with zero dependency on a tool proven unreliable on real content. **Use sysml-toolkit instead specifically when port identity itself is the chapter's own pedagogical point** (e.g. a chapter introducing or exercising a conjugated port) — it draws real port names as their own boxes, not folded into one edge label, confirmed on every real fixture tested (`decisions/diagram-study-real-fixtures.md`). Otherwise default to the in-house renderer: a chapter using interconnection only to show an allocation or a connection, where port identity is not itself the point, does not need the extra external-binary dependency (`decisions/diagram-survey.md`, Ch5-vs-Ch6 example). |
| What happens next? Action-flow view | OpenSysML CLI, `-render #action:element -render-form dot` → Graphviz SVG | Confirmed directly against real chapter content (Ch6's `ApplyHeat` action): exit 0, real action-flow notation. No in-house action-flow renderer exists yet. |
| How does behavior change with events? State-transition view | OpenSysML CLI, `-render #state:element -render-form dot` → Graphviz SVG | The real-fixture study confirmed this directly against Ch7's real `Cycle` state machine — 100% success across both OpenSysML render forms. The OMG pilot (this table's earlier default) fails on all real chapter content; do not use it. |
| Who sends what, in what order? Sequence view | OpenSysML sequence query → DOT → Graphviz SVG | White background, relationship-consistent rendering, no Mermaid dependency. Provisional: no chapter's real model has a `FlowUsage` yet, so this pipeline has not been exercised against real content. Fallback: PlantUML if `opensysml -render-form dot` unsupported for sequences (confirmed at WP-1 and documented below). |
Expand Down
138 changes: 89 additions & 49 deletions .claude/skills/sysml-diagrams/references/recipes.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,120 @@
# Rendering recipes

Run from the tutorial repository root. `$SYSML` is the pinned OpenSysML CLI, `$PILOT_JAR` and `$PILOT_LIBRARY` identify the matched pilot bundle, and `$PLANTUML_JAR` identifies the pinned standalone renderer. `model.sysml` is the chapter-generated snapshot. Replace example qualified names with the chosen subject. Write outputs to an ignored `build/figures/` directory.
**Corrected 2026-10-01** (this file was not updated when `decisions/log.md` `DL-057`
corrected `sysml-diagrams/SKILL.md`'s own renderer-choice table, so it kept describing the
OMG pilot and SysMLD/sysml2d as the defaults for two view types after both were confirmed
to fail entirely on real content, `decisions/diagram-study-real-fixtures.md`; Phase 1's own
survey, `decisions/diagram-survey.md`, caught the gap). **Never use the OMG pilot or
SysMLD/sysml2d for real chapter content.** Run from the tutorial repository root. `$SYSML`
is the pinned OpenSysML CLI; `model.sysml` is the chapter-generated snapshot. Replace example
qualified names with the chosen subject. Write outputs to an ignored `build/figures/`
directory.

## Definition and decomposition — in-house, `model_to_dot()`

## Definition and decomposition — official pilot

Load all required source files and the matched standard library into one pilot session. Validate, then render the qualified subject with `TREE`. In the pilot Java API, use `process(source, true)` to index a loaded source, followed by `viz(names, views, styles, help)`. The equivalent notebook operation in a pilot kernel is `%viz --view TREE Qualified::Subject`.

The small Java harness shipped with this skill accepts:
```python
from toaster.render import model_to_dot, containment_subgraph, render_dot

```sh
java -Djava.awt.headless=true -cp "$PILOT_JAR" \
"$DIAGRAM_SKILL/scripts/PilotFigure.java" "$PILOT_LIBRARY" \
build/figures/decomposition.svg TREE TB \
ToasterStudy::ElectricToaster -- model.sysml
dot_source = model_to_dot(model, title="Decomposition")
# Or, once the full model is too large to be a legible single figure:
scoped = containment_subgraph(model, "ToasterDemo::Toaster", relations=("composition", "typing"), depth=2)
dot_source = model_to_dot(model, title="Decomposition", elements=scoped)
render_dot(dot_source, "build/figures/decomposition.svg")
```

Use a top-to-bottom arrangement for decomposition; show one structural level per teaching question. Read the diagram as a view of model containment and composition, keeping usages distinct from their definitions. Exposing an abstract definition alone should not imply an instantiated system.

Expected check: the selected system and intended children appear with the correct ownership. Include multiplicities and inherited members when they matter; select the pilot’s `SHOWINHERITED`, `NODEMULTIPLICITY`, or `EDGEMULTIPLICITY` styles as appropriate, then inspect the result. The default fixture establishes basic structure rendering, not every style combination.

## Interconnection — SysMLD, with model-derived intent
Nodes are `PartDefinition`s (dashed border if abstract); edges are composition (diamond
arrowhead, owner to usage) and typing (dashed open arrow, usage to its type). `elements=None`
(the default) draws the whole `model.query()` result — right for a small model where
"everything" is itself a legible view. Use `containment_subgraph()`'s `root`/`depth` to scope
once the model grows too large, picking the root that actually reaches the content the chapter
teaches (`decisions/diagram-study-real-fixtures.md`'s own "wrong root chosen" finding: a usage's
qualified name does not own anything itself, only its *type* does, so the chapter's own new
content may sit at a different root than the familiar top-level one). **Known gap:** this
function has no node/edge handling for `RequirementDefinition`, `ItemDefinition`,
`ActionDefinition`/`ActionUsage`/`perform`, `SatisfyRequirementUsage`, `AllocationUsage`,
`ConstraintUsage`, or specialization (`:>`) — only `PartDefinition` and `PartUsage` composition/
typing. Do not propose this recipe for a notebook cell whose real content is one of those; no
diagram type in this tutorial currently covers them (`decisions/diagram-survey.md`'s own
repeated finding, Chapters 2/3/8/9/10).

Expected check: the selected elements and intended children appear with the correct ownership,
and nothing the chapter hasn't yet taught (a later chapter's own structure) leaks into an
earlier chapter's figure.

## Interconnection — in-house `render_interconnection()`, or sysml-toolkit when port identity is the point

**Default: `render_interconnection()`** (in-house, `src/toaster/render.py`), zero dependency on
a third-party tool:

Use SysMLD as the layout and SVG engine. The notebook supplies the semantic projection, just as a plotting cell supplies arrays to Matplotlib. The starting inputs are the validated model, a selected system or subsystem, and small presentation settings.

Extract these facts using OpenSysML’s model API or an available semantic query engine:
```python
from toaster.render import build_interconnection_intent, render_interconnection

| Projected fact | Source and mapping |
|---|---|
| Subject | Selected part definition or usage, with model identity. |
| Part nodes | Selected owned part usages; labels derive from usage name and type. |
| Ports | Port usages in each part’s context, including required inherited features; keep identity and type. |
| Connection edges | Resolved connection identity and endpoint feature paths. Preserve connector kind and any flow direction separately from drawing orientation. |
| Boundary connections | The selected subject’s external ports and their internal endpoints. |
intent = build_interconnection_intent(model, "ToasterDemo::Toaster", depth=1)
render_interconnection(intent, "build/figures/interconnection.svg")
```

Construct the compact intent schema consumed by `sysmld interconnection`: `subject`, `model_files`, `aliases`, `nodes`, `edges`, optional `boundary_inputs`, and presentation settings. Node and edge identifiers map back to the projected facts. For an ordinary binary connection, derive `from` and `to` from its endpoint owners and `source_label` / `target_label` from the corresponding port names. `from`/`to` is a layout convention for an undirected connection; it does not assert a physical flow direction. Use `label_mode: "both"` when both connection names and port labels are needed.
`build_interconnection_intent()` extracts parts, flows, and allocations from the model via
`model.query()`/`to_api_json()` — nothing is hand-authored, so there is no second,
separately-maintained model to drift out of sync (the exact risk `decisions/log.md` `DL-055`
found SysMLD/sysml2d's own intent-file approach carries, and which that tool's own indexer bug
now independently blocks on real content regardless). Port identity is drawn as an edge label,
not a dedicated box.

Keep the projection in memory until writing generated `interconnection.json`. The rendering sequence is:
**Use sysml-toolkit instead specifically when port identity itself is the chapter's own
pedagogical point** (e.g. a chapter introducing or exercising a conjugated port, per
`decisions/diagram-survey.md`'s Ch5 recommendation):

```sh
sysmld interconnection build/figures/interconnection.json
sysmld render build/figures/interconnection.sysmld
sysmld validate build/figures/interconnection.sysmld --strict
sysmlv2 viz model.sysml --view interconnection --element ToasterDemo::Toaster -o build/figures/interconnection.puml
java -Djava.awt.headless=true -jar "$PLANTUML_JAR" -tsvg build/figures/interconnection.puml
```

Start with direction, node widths, rank spacing, and label detail. Add explicit rank/order or port-face settings only when the figure needs them. Preserve the generated intent and layout as inspectable artifacts.
Confirmed on every real fixture tested (`decisions/diagram-study-real-fixtures.md`): draws real
port names (e.g. `durationIn`, `durationOut`) as their own boxes inside the owning part, not
folded into one edge label the way OpenSysML's own interconnection export does. Otherwise, a
chapter using interconnection only to show a connection or an allocation — where port identity
is not itself the point — does not need the extra external-binary dependency; default to
`render_interconnection()`.

Before rendering, assert that selected relationships and endpoints match the projected nodes and ports. After composing, check that the layout preserves those identities and connections. The tested composer generates port IDs from part pairs: repeated connections between the same pair, shared ports, and unconnected ports require particular care. For those cases, use explicit `.sysmld` elements and connections generated from the same facts, with stable per-port/per-connection IDs, rather than assuming the compact composer preserves them. Inspect the relevant schema before doing so.
Before rendering, assert that selected relationships and endpoints match the model's own real
parts, ports, and connections — never author a separate relationship model by hand for either
pipeline.

This recipe specifies the projection contract; it does not supply a general SysML-to-SysMLD adapter. Implement the small query/projection required by the chapter and test its actual supported constructs. Keep full semantic validation in the model engine, and inspect any disagreement with SysMLD’s textual reference index.

## Action flow — OpenSysML and PlantUML
## Action flow — OpenSysML

```sh
"$SYSML" model.sysml \
-render '#action:ToasterStudy::Toast' \
-render-form plantuml -o build/figures/actions.puml
java -Djava.awt.headless=true -jar "$PLANTUML_JAR" \
-tsvg build/figures/actions.puml
-render '#action:ToasterDemo::ToastBread' \
-render-form dot -o build/figures/actions.dot
dot -Tsvg build/figures/actions.dot -o build/figures/actions.svg
```

Expected output: the declared actions, initial/final nodes, and successions. Check decisions, guards, forks, joins, and object flows whenever the selected model contains them. The basic toaster trial exercises a linear sequence.
Confirmed directly against real chapter content (`decisions/diagram-study-real-fixtures.md`;
Ch6's `ApplyHeat` action, exit 0, real action-flow notation). No in-house action-flow renderer
exists yet. Expected output: the declared actions, initial/final nodes, and successions. Check
decisions, guards, forks, joins, and object flows whenever the selected model contains them —
every real chapter fixture tested so far exercises only a linear sequence.

Use the same model view to control scope; use PlantUML presentation directives for font, orientation, and spacing. Apply those directives programmatically to generated output or through a renderer configuration. Preserve action names and edge meaning. Distinguish a structural action-flow figure from an actual execution trace.
Distinguish a structural action-flow figure from an actual execution trace.

## State transition — official pilot
## State transition — OpenSysML

```sh
java -Djava.awt.headless=true -cp "$PILOT_JAR" \
"$DIAGRAM_SKILL/scripts/PilotFigure.java" "$PILOT_LIBRARY" \
build/figures/states.svg STATE TB \
ToasterStudy::ToastCycle -- model.sysml
"$SYSML" model.sysml \
-render '#state:ToasterDemo::Cycle' \
-render-form dot -o build/figures/states.dot
dot -Tsvg build/figures/states.dot -o build/figures/states.svg
```

Show states and transitions for one behavioral question. Preserve initial entry and, when present, event triggers, guards, effects, and entry/do/exit compartments. Change orientation or split nested behavior into another figure when labels become crowded.
Confirmed directly against real chapter content (`decisions/diagram-study-real-fixtures.md`):
100% success across both OpenSysML render forms on Ch7's real `Cycle` state machine, and the
mutation-control test (retargeting a transition) correctly changes the rendered output. Show
states and transitions for one behavioral question. Preserve initial entry and, when present,
event triggers, guards, effects, and entry/do/exit compartments. Change orientation or split
nested behavior into another figure when labels become crowded.

Check each transition’s source and target. For the study fixture, `idle → heating` branches to `ready` or `cancelled`. A changed target must change the corresponding arrow. Generated pilot hyperlinks contain session-specific identifiers; appearance or normalized semantic comparisons are more useful than raw byte identity.
Check each transition's source and target against the real model, not an assumed shape — a
changed target must change the corresponding arrow.

## Sequence — OpenSysML and Mermaid

Expand Down
4 changes: 3 additions & 1 deletion .claude/skills/toaster-recipe/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ The 7 cells below are the **required skeleton**. Additional markdown+code pairs
| **Seam** | Markdown | Exactly one sentence, addressing in behavior that the written construct, the tool that loaded it, and the rendered result are three distinct things the reader has just watched connect. Never names Tall or "the three worlds" (AGENTS.md 1.10) — see "Tall's three worlds" below. |
| **Exercise pointer** | Markdown | One sentence: "Try the chapter exercise in `exercises/ch{N}/exercise.ipynb`: [one-line description]." No embedded code. |

**Cell 0's own heading must be level 1 (`#`, not `##`), and the notebook's own `metadata` must carry `"short_title": "ChN-NN"`.** mystmd lifts a cell-0 level-1 heading into the page's own title and removes it from the body; any other heading level renders twice — once as an implicit page title, once again in the body (a real, found defect; `decisions/log.md` DL-090). `short_title` drives the sidebar/TOC label (`ChN-NN`, e.g. `Ch1-01`); the page banner and the in-body heading both show the real heading text instead.

### Construction zone — model increment pattern (construct-introducing notebooks only)

All 13 construction notebooks use SysML string fragments (Editor API gaps — see DEFERRED.md
Expand Down Expand Up @@ -182,7 +184,7 @@ are relaxed for this content (see that skill for the exact grouping and why).

Identify required cells by content type, not by cell index — additional narration cells may be interspersed.

- [ ] **Concept statement present:** exactly one sentence starting "This notebook introduces"
- [ ] **Concept statement present:** exactly one sentence starting "This notebook introduces"; cell 0's own heading is level 1 (`#`), and the notebook's `metadata` carries `short_title: "ChN-NN"`
- [ ] **Context cell present:** one paragraph with link to prior notebook (where applicable)
- [ ] **Model increment cell present (construct-introducing notebooks only):** two-phase — (1) `TOASTER_INCREMENT` assigned and printed as reflection (Pattern A: `str(editor.apply())`; Pattern B: SysML fragment string); (2) full cumulative loaded from `models/chXX-cumulative.sysml`; `assert model.ok`. Judgment/depth/navigation/analysis notebooks: cell-02 loads cumulative only, no TOASTER_INCREMENT.
- [ ] **Negative control present:** short bad_source inline; `assert not bad.ok`; markdown names the error type
Expand Down
Loading
Loading