Repository navigation
Expand file tree
/
Copy pathdocument.sysml
More file actions
614 lines (542 loc) · 28.8 KB
/
Copy pathdocument.sysml
File metadata and controls
614 lines (542 loc) · 28.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
// The architecture document itself, written in the notation and rendered by
// OpenSysML's own document generator (see the README for the command).
package OpenSysMLDocument {
private import DocumentQueries::*;
private import KerML::Root::Element;
private import ScalarValues::*;
// The document's query roots: a table's query is bound to a usage, so the
// containers it tabulates are named here as usages.
part analysisPipeline : OpenSysMLPipeline::AnalysisPipeline;
part passRegistry : OpenSysMLPipeline::PassRegistry;
part runtime : OpenSysMLPipeline::Runtime;
part analysisFramework : OpenSysMLPipeline::AnalysisFramework;
part viewEngine : OpenSysMLSurfaces::ViewEngine;
part documentPipeline : OpenSysMLSurfaces::DocumentPipeline;
// --- Queries the document runs over this model -----------------------
// A usage's definition, so a query can reach the parts declared in it.
calc def DefinitionOf :> Query {
in root : Element;
RelatedElements(
source = root,
relationshipKind = "typing",
direction = "outgoing",
maxDepth = 1
)
}
// Every unit a container declares, with the directory implementing it;
// the container's channels carry no package and drop out here.
calc def UnitsWithPackages :> Query {
in root : Element;
Project(
source = WhereFeature(
tolerate = true,
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
'feature' = "goPackage",
operator = "!=",
value = ""
),
properties = ("name", "goPackage")
)
}
// The validation passes, with the tier each one runs at.
calc def PassesWithTiers :> Query {
in root : Element;
Project(
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
properties = ("name", "level", "elementScoped")
)
}
// The runtime's budgets: the executors it also declares carry no envVar
// and drop out here.
calc def BudgetsWithBounds :> Query {
in root : Element;
Project(
source = WhereFeature(
tolerate = true,
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
'feature' = "envVar",
operator = "!=",
value = ""
),
properties = ("name", "counts", "envVar", "defaultBound", "exhaustion")
)
}
// The analysis engines: the framework's other parts carry no engineName
// and drop out here.
calc def EnginesWithAuthority :> Query {
in root : Element;
Project(
source = WhereFeature(
tolerate = true,
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
'feature' = "engineName",
operator = "!=",
value = ""
),
properties = ("engineName", "answers", "bounds", "authority", "replays", "needsProcess", "adapts")
)
}
// Every rendering kind the view engine recognizes, and whether it draws it.
calc def RenderingKinds :> Query {
in root : Element;
Project(
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
properties = ("kind", "supported")
)
}
// The surfaces over the pipeline: the toolchain's other parts carry no
// protocol and drop out here.
calc def SurfacesWithProtocols :> Query {
in root : Element;
Project(
source = WhereFeature(
tolerate = true,
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
'feature' = "protocol",
operator = "!=",
value = ""
),
properties = ("name", "entrypoint", "protocol")
)
}
// The markup languages a prose body may be written in; the pipeline's
// other parts carry no markupLanguage and drop out here.
calc def MarkupLanguages :> Query {
in root : Element;
Project(
source = WhereFeature(
tolerate = true,
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
'feature' = "markupLanguage",
operator = "!=",
value = ""
),
properties = ("name", "markupLanguage", "needsExternalTool")
)
}
// The conformance oracles, with the baseline each one ratchets.
calc def OraclesWithBaselines :> Query {
in root : Element;
Project(
source = WhereFeature(
tolerate = true,
source = WhereType(
source = OwnedElements(source = DefinitionOf(root = root)),
type = "PartUsage"
),
'feature' = "baseline",
operator = "!=",
value = ""
),
properties = ("name", "reference", "baseline")
)
}
// --- The document ----------------------------------------------------
part def ArchitectureDocument :> Document {
attribute redefines title = "OpenSysML Architecture";
rep language "markdown" /* OpenSysML analyses SysML v2 and KerML in one pass from text to a
* runnable graph. This document is generated from a model of that
* architecture rather than written alongside it: every diagram and table
* below is rendered from the same model the toolchain analyses, so a
* stage that moves in the code moves here too.
*/
part reading : Paragraph {
rep language "markdown" /* The model lives in
* [examples/self-model](https://github.com/Open-MBEE/OpenSysML/tree/main/examples/self-model)
* and the prose reference it illustrates is `docs/internals/architecture.md`.
*/
}
part pipeline : Section {
attribute redefines title = "The analysis pipeline";
rep language "markdown" /* Text becomes tokens, a tree, a symbol index, resolved names,
* types, diagnostics and finally an execution graph. Each stage owns
* one artifact and hands it on; nothing downstream reaches back.
*/
part structure : Diagram {
attribute redefines caption = "The stages and the artifacts that travel between them";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::pipelineStructure;
}
part stages : Table {
attribute redefines caption = "Each stage and the package that implements it";
calc rows : UnitsWithPackages {
in redefines root = analysisPipeline;
}
}
rep language "markdown" /* The tree is immutable once parsed and carries syntax only.
* Everything derived from it lives in a side table keyed by node or
* symbol, which is why resolution can be lazy and memoized without a
* stale tree to invalidate.
*/
rep language "markdown" /* The bundled standard library is loaded once per process from an
* embedded snapshot of its frozen index, written at go generate time
* and checked against the digest of the bundled files, the snapshot
* format and a checksum before it is trusted. A snapshot that fails
* any of those checks is ignored and the files are parsed as before,
* so the library files remain the source of truth and the snapshot
* is only a faster way to arrive at the same index.
*/
part libraryLoad : Diagram {
attribute redefines caption = "Loading the library: the snapshot when it matches the files, the files otherwise";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::libraryLoadFlow;
}
}
part checking : Section {
attribute redefines title = "Validation and execution";
rep language "markdown" /* Validation is a ladder of [](sysml:value:passRegistry.tierCount)
* tiers: syntax, name resolution, type, then constraint, with
* [](sysml:value:passRegistry.passCount) registered passes between them
* ([the table below](sysml:passes) lists every one). A blocking finding
* skips the document-scoped passes of the tiers above it, while a pass
* that names its subject still runs for the elements not downstream of
* the failure, so one broken declaration does not silence the rest of
* the document.
*/
part tierStates : Diagram {
attribute redefines caption = "The tier ladder, and where it halts";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::tierStates;
}
part passes : Table {
attribute redefines caption = "Every registered validation pass, its tier, and which ones gate themselves per element";
calc rows : PassesWithTiers {
in redefines root = passRegistry;
}
}
rep language "markdown" /* What runs is the lowered graph, never the syntax tree: actions
* execute in succession order, as tokens over the lowered graph, and
* states as run-to-completion event dispatch. Each kind of work has
* its own budget — nested calculation, for one, is bounded at
* [](sysml:value:runtime.calcDepth.defaultBound) by default and raised
* through [](sysml:value:runtime.calcDepth.envVar) — so a model that
* cannot finish reports which budget it exhausted rather than hanging
* the tool.
*/
part budgets : Table {
attribute redefines caption = "The runtime budgets, their defaults, and the error each reports when exhausted";
calc rows : BudgetsWithBounds {
in redefines root = runtime;
}
}
part exhaustion : Diagram {
attribute redefines caption = "Eight budgets, eight ways a run ends early";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::budgetExhaustion;
}
rep language "markdown" /* Beneath the executors sits the instance layer. A type's schema —
* its effective features, with redefinitions kept and connector ends
* appended — is built once per model from the semantic shape and
* shared by every object of the type. Making an object claims an
* identity and a feature value per schema entry, folding only
* constant defaults; everything else waits for its first read, when
* the case the feature is in decides how its value is made: a bound
* feature reads its far end, a selected variation binds its variant,
* a stated value is evaluated, a connector holds its connected ends,
* a composite makes its objects. Whatever a feature comes to hold
* passes multiplicity, type and uniqueness first, and a derived
* value lists itself on every value it read, so a later write to one
* of them sends it back to be derived again.
*/
part instanceLayer : Diagram {
attribute redefines caption = "The instance layer: schema once per type, objects on demand, values on first read";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::instanceLayer;
}
part featureRead : Diagram {
attribute redefines caption = "One feature read: the case the feature is in decides how its value is made";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::featureReadFlow;
}
part actionExecution : Diagram {
attribute redefines caption = "One action executed: lowered, stepped, scheduled, evaluated, read and written";
ref redefines source = OpenSysMLViews::actionExecution;
}
rep language "markdown" /* A calc whose body is scalar — an expression, or local
* declarations, returns and conditionals over scalars, calling other
* such calcs by position or by name and the library's scalar
* functions — is compiled on its first invocation into closures over
* an unboxed frame, kept in a side table on the context like every
* other derived fact. The evaluator remains the reference: the
* compiled tier must reproduce its values, errors and step charges
* exactly, a traced run or an invocation it cannot take goes to the
* evaluator whole, and an environment variable switches the tier off
* for bisecting.
*/
part calculation : Diagram {
attribute redefines caption = "Invoking a calc: compiled when it may be, on the evaluator otherwise";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::calcInvocationFlow;
}
part analysed : Diagram {
attribute redefines caption = "One document analysed end to end";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::analysisFlow;
}
}
part asking : Section {
attribute redefines title = "The analysis framework";
rep language "markdown" /* Every question a surface asks of a model — evaluate this, what can
* that behavior do, does this condition hold, is that set of
* conditions satisfiable, sweep this domain — goes through one
* contract. An engine declares the kinds it answers, the bounds it
* takes and the strongest evidence it can ever produce; it is asked
* whether it covers a question before any work is done, and a
* refusal is a typed reason, never a result. The registry is held by
* its owner rather than in a global, and dispatch records every
* engine consulted in the plan it returns.
*/
part structure : Diagram {
attribute redefines caption = "The framework: questions, engines, registry, dispatch, budget and workers";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::analysisFramework;
}
part engines : Table {
attribute redefines caption = "The engines this build registers, what each answers, and the strongest evidence it can produce";
calc rows : EnginesWithAuthority {
in redefines root = analysisFramework;
}
}
rep language "markdown" /* A selection says which engines a question reaches. Auto, the
* default, puts it to the strongest covering engine and moves on to
* the next when the answer is not covered; a name puts it to exactly
* one engine, whose refusal is then the answer; all puts it to every
* covering engine in name order and composes what they answered, a
* witness standing over the universal claim it refutes and the
* disagreement recorded. A run that faults stops the plan.
*/
part dispatch : Diagram {
attribute redefines caption = "Answering one question: selection, coverage, the run, and what the plan records";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::questionFlow;
}
rep language "markdown" /* An answer carries a claim and the strength of the evidence for it,
* on one scale: not covered, observed, witnessed, bounded, proved. A
* greater strength is never weaker evidence, an existential claim —
* a violation, a sensitivity, a satisfying assignment — has
* witnessed as its one strength, and an engine claiming more than
* its declared authority is a fault. The run and sweep engines
* observe; explore and solve prove when nothing cut them short and
* observe otherwise.
*/
part ladder : Diagram {
attribute redefines caption = "The evidence scale as a ladder";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::evidenceLadder;
}
rep language "markdown" /* Runs go concurrently, up to the jobs setting, each on a worker of
* its own. A worker holds model-derived state — resolver, semantic
* model and the runtime's memo tables — built on first use over the
* shared frozen index, and every run on it gets a fresh context of
* its own; the runtime's memo tables are not safe to share, so a
* worker is never lent between jobs. The exploration works a queue
* of schedule prefixes in plan order and sorts what it found, so the
* outcomes are the same at any job count. A snapshot captures a
* run's state between two steps and no part of the model it runs
* over.
*/
part exploring : Diagram {
attribute redefines caption = "Exploring a behavior's outcomes over a fleet of workers";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::exploreFlow;
}
part workers : Diagram {
attribute redefines caption = "A worker's life in a plan";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::workerLifecycle;
}
part marks : Diagram {
attribute redefines caption = "A snapshot is a mark between steps";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::snapshotLifecycle;
}
}
part surfaces : Section {
attribute redefines title = "Surfaces over one pipeline";
rep language "markdown" /* The REPL, the language server, the gRPC service, the stdio
* service, the command line, the MCP server for coding agents, the
* Jupyter kernel and the JSON-RPC commands a WebAssembly host runs
* are surfaces over one analysis pipeline: a release ships
* [](sysml:value:OpenSysMLSurfaces::opensysml.releasedCommandCount)
* commands, and [](sysml:value:OpenSysMLSurfaces::opensysml.wasmCommandCount)
* build for WebAssembly as well as natively. The service speaks gRPC
* and Connect from one protobuf schema; the Go, Python, Node, Rust
* and Java clients are hand-written over stubs generated from that
* schema, the Julia and MATLAB clients speak Connect-JSON over HTTP
* by the published wire contract, and
* [](sysml:value:OpenSysMLSurfaces::opensysml.mdk.pluginName) in Cameo
* and [](sysml:value:OpenSysMLSurfaces::opensysml.syson.pluginName)
* reach the service through the Java client — so a rule fixed in
* the engine is fixed everywhere at once. The service binds
* loopback unless -host names another address, and then only
* behind the bearer token in
* [](sysml:value:OpenSysMLSurfaces::opensysml.service.bearerTokenEnv),
* which every client reads the same way. The language server
* serves VS Code, Emacs and the notebook's cells alike, and the
* view engine writes
* [](sysml:value:OpenSysMLSurfaces::opensysml.forms.formCount)
* rendering forms, of which draw.io is read back as edits.
*/
part toolchain : Diagram {
attribute redefines caption = "The whole toolchain";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::toolchainStructure;
}
part commands : Table {
attribute redefines caption = "Every surface, with the command that serves it and the protocol it speaks";
calc rows : SurfacesWithProtocols {
in redefines root = OpenSysMLSurfaces::opensysml;
}
}
rep language "markdown" /* The MCP server serves the language server's tools, the one-shot
* service's and named REPL sessions — the tool groups
* [](sysml:value:OpenSysMLSurfaces::opensysml.mcp.toolGroups) — to a coding
* agent over stdio or Streamable HTTP at
* [](sysml:value:OpenSysMLSurfaces::opensysml.mcp.httpPath), guarded by the
* token in [](sysml:value:OpenSysMLSurfaces::opensysml.mcp.tokenEnv); the Jupyter kernel wraps the REPL and shows each
* answer in its own MIME form; the JSON commands build for
* WebAssembly and answer the service's RPCs over JSON-RPC frames
* without the networking packages, and one of them, sysml-wasm,
* ships with a release as
* [](sysml:value:OpenSysMLSurfaces::opensysml.wasm.releaseAsset).
*/
rep language "markdown" /* An editor reaches more than diagnostics: semantic tokens, quick
* fixes carrying their edits, suggestions for a name that did not
* resolve, and span-based edits whose result is re-parsed and re-analysed before it is accepted.
*/
part editor : Diagram {
attribute redefines caption = "The editor pipeline";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::editorPipeline;
}
}
part documents : Section {
attribute redefines title = "Documents and views";
rep language "markdown" /* A document is written in the notation: its queries compile to an
* immutable plan, the plan evaluates to a backend-agnostic tree
* carrying provenance on every node, and the output form is chosen
* last, so Markdown and PDF cannot disagree about the content. This
* document is one of them. [The kinds table](sysml:kinds) lists what a
* view may ask to be drawn, and [the prose table](sysml:prose) the
* markup a body may be written in; a body in
* [](sysml:value:documentPipeline.asciidocProse.markupLanguage) leaves the
* process for the converter named by
* [](sysml:value:documentPipeline.asciidocProse.toolEnv).
*/
part path : Diagram {
attribute redefines caption = "From a query in the model to a rendered artifact";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::documentPipeline;
}
part branches : Diagram {
attribute redefines caption = "The three forms a rendered document branches to";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::documentFlow;
}
part kinds : Table {
attribute redefines caption = "The rendering kinds a view can state, and which ones are produced";
calc rows : RenderingKinds {
in redefines root = viewEngine;
}
}
part prose : Table {
attribute redefines caption = "The markup languages a prose body may be written in, and which one leaves the process";
calc rows : MarkupLanguages {
in redefines root = documentPipeline;
}
}
rep language "markdown" /* ### Prose as one body
*
* The prose of a document need not be one `part : Paragraph` per
* paragraph: a KerML textual representation in Markdown or AsciiDoc
* expands in place, and its headings open the sections, so a
* subsection such as this one is written as a heading.
*
* #### Headings become sections
*
* The first heading met in a body is one level below its owner;
* here the body sits in the *Documents and views* section, so its
* `###` headings are that section's subsections and `####` their
* children. A heading that skips a level is a planning error, as is
* one in a paragraph body.
*
* #### Names and references
*
* Each section takes its explicit AsciiDoc id or a slug of its
* title, unique within the document, so [](sysml:headings_become_sections)
* resolves and the HTML carries an anchor for it, and the
* [pipeline](sysml:pipeline) section is one reference away.
*/
}
part identity : Section {
attribute redefines title = "Element identity";
rep language "markdown" /* An element's repository identity is an annotation, not a field on
* the tree: an explicit id when one is declared, otherwise one
* derived from the qualified name. The constraint tier checks the
* whole generated id space for collisions, and the RDF writer and
* reader carry the distinction between a declared and a derived id
* across a round trip.
*/
part path : Diagram {
attribute redefines caption = "The identity path, from the library to RDF and back";
attribute redefines direction = "LR";
ref redefines source = OpenSysMLViews::identityPath;
}
part roundTrip : Diagram {
attribute redefines caption = "Carrying an identity through a graph and back";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::identityRoundTrip;
}
rep language "markdown" /* Repository synchronisation diffs a local model against its
* repository graph keyed by effective id, so a rename is an update
* rather than a delete and a create. Ids are minted and deletes
* confirmed only on request, and a conflict is reported in the exit
* status rather than resolved. The one phase of the identity design
* not built is the notation extension submitted to OMG.
*/
part syncing : Diagram {
attribute redefines caption = "Diffing a local model against its repository";
attribute redefines direction = "TB";
ref redefines source = OpenSysMLViews::syncFlow;
}
}
part quality : Section {
attribute redefines title = "Invariants and oracles";
rep language "markdown" /* The architecture rules are requirements over the modelled parts,
* and the test suites that verify them are named in the model, so
* each rule points at the run that would catch its violation.
*/
part invariants : Diagram {
attribute redefines caption = "The architecture invariants and the parts they constrain";
ref redefines source = OpenSysMLViews::invariantTable;
}
part oracles : Table {
attribute redefines caption = "The conformance oracles and the baselines they ratchet";
calc rows : OraclesWithBaselines {
in redefines root = OpenSysMLSurfaces::opensysml;
}
}
}
}
}