@rse/specbook 1.2.4 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,6 +72,15 @@
72
72
  # - All artifacts have a unique 2-word name (e.g. "Context View") and a
73
73
  # corresponding unique 2-letter identifier.
74
74
  #
75
+ # - The artifacts are ordered coarse to fine wherever a granularity
76
+ # relation exists (REQS from the Solution Vision down to the Use
77
+ # Cases, UXUI from the Interaction Concept down to the Visual
78
+ # Design) and by concern otherwise (DATA structure/behavior/access,
79
+ # the ARCH viewpoints), while the back-reference rule below settles
80
+ # the rest. E.g. the Domain Workflows (summary level: many actors,
81
+ # many sittings) precede the Use Cases (user-goal level: one actor,
82
+ # one sitting), which reference back into the workflow activities.
83
+ #
75
84
  # - All object references are strictly back-references, i.e., later
76
85
  # objects reference earlier ones. Only the "referenced" coverage
77
86
  # constraints and the diagram node sets (e.g. the inputs of a "hub"
@@ -107,6 +116,12 @@
107
116
  nodes: "[[REQS:*]], [[DATA:*]], [[APIS:*]], [[UXUI:*]], [[ARCH:*]], [[TEST:*]]"
108
117
  deep: true
109
118
  qualified: true
119
+ ordered: true
120
+ nest:
121
+ kind: true
122
+ crossing: target
123
+ config:
124
+ graph-columns-max: 2
110
125
  props:
111
126
  - name: LOGO
112
127
  desc: The logo of the specification.
@@ -211,6 +226,10 @@
211
226
  resting on a premise are known and revisited once it turns out to be false. The
212
227
  artifact complements the Solution Vision: the vision states what the solution aims
213
228
  for, the premises state what it takes as given on the way there.
229
+
230
+ The premises are not constraints: a constraint is imposed on the solution and belongs
231
+ to the Non-Functional Requirements or the Domain Rules, whereas a premise lies outside
232
+ the control of the solution.
214
233
  optional: true
215
234
  refs: >
216
235
  - ISO/IEC/IEEE 29148:2018: Systems and software engineering -- Life cycle processes -- Requirements engineering (2018),
@@ -226,8 +245,8 @@
226
245
  nodes: "[[PREMISE:*]]"
227
246
  properties:
228
247
  - TYPE
229
- - LIKELIHOOD
230
- - IMPACT
248
+ - FAILURE-LIKELIHOOD
249
+ - FAILURE-IMPACT
231
250
  config:
232
251
  size-node-width-max: 440
233
252
  size-node-height-scale: 1.75
@@ -259,23 +278,24 @@
259
278
  behave as agreed), or `Risk` (an uncertain event which, if it occurs,
260
279
  harms the achievement of the vision).
261
280
  value: enum(Assumption,Dependency,Risk)
262
- - name: LIKELIHOOD
281
+ - name: FAILURE-LIKELIHOOD
263
282
  desc: >
264
283
  The likelihood that the premise fails, i.e. that the assumption turns out
265
284
  to be false, the dependency is not honored, or the risk occurs: `Low`,
266
- `Medium`, or `High`.
285
+ `Medium`, or `High`. It rates the failure and not the premise itself, so
286
+ `Low` says that the premise most probably holds.
267
287
  value: enum(Low,Medium,High)
268
- - name: IMPACT
288
+ - name: FAILURE-IMPACT
269
289
  desc: >
270
290
  The severity of the `CONSEQUENCE` for the solution once the premise fails:
271
- `Low`, `Medium`, or `High`, so that the product of likelihood and impact
272
- ranks the premises by the attention they need.
291
+ `Low`, `Medium`, or `High`, so that the product of the failure likelihood
292
+ and the failure impact ranks the premises by the attention they need.
273
293
  value: enum(Low,Medium,High)
274
294
  - name: CONSEQUENCE
275
295
  desc: >
276
296
  What concretely follows for the solution if the premise fails, stated
277
297
  as a 1-2 sentence description of the harm (e.g. `attendees cannot enter
278
- the event`), justifying the `IMPACT` rating.
298
+ the event`), justifying the `FAILURE-IMPACT` rating.
279
299
  - name: MITIGATION
280
300
  desc: >
281
301
  What is done to lower the likelihood or the impact of the failure or to
@@ -327,7 +347,7 @@
327
347
  diagram:
328
348
  type: hub
329
349
  center: self
330
- nodes: "[[TERM:*]], [[PREMISE:*]], [[RULE:*]], [[DM.ENTITY:*]], [[PERSONA:*]]"
350
+ nodes: "[[TERM:*]], [[PREMISE:*]], [[RULE:*]], [[DM.ENTITY:*]], [[ROLE:*]], [[PERSONA:*]]"
331
351
  labeled: true
332
352
  qualified: true
333
353
  config:
@@ -338,8 +358,9 @@
338
358
  desc: >
339
359
  The kind of concept the term denotes: `Entity` (a thing of the domain,
340
360
  usually materialized by a DATA-MODEL entity), `Actor` (a party acting in
341
- the domain, be it a human role usually embodied by a PERSONA or an external
342
- system), or `Activity` (a process or procedure of the domain).
361
+ the domain, be it a human role or an external system, usually played as a
362
+ ROLE of the User Personas), or `Activity` (a process or procedure of the
363
+ domain).
343
364
  value: enum(Entity,Actor,Activity)
344
365
  - name: SYNONYMS
345
366
  desc: >
@@ -379,11 +400,16 @@
379
400
  id: UP
380
401
  file: 04-REQS-UP-User-Personas.md
381
402
  desc: >
382
- The *archetypal* user profiles representing distinct user groups, capturing their goals,
383
- needs, behaviors, and context, complemented by the non-user stakeholders whose interests
384
- the solution has to serve.
403
+ The roles the parties play towards the solution and the *archetypal* user profiles
404
+ embodying them: a role names the part played (by a human or by an external system) and
405
+ is the actor of the Use Cases and the Domain Workflows and the unit in which the
406
+ Authorization Model grants rights, while a persona represents a distinct user group
407
+ holding one or more roles, capturing its goals, needs, behaviors, and context,
408
+ complemented by the non-user stakeholders whose interests the solution has to serve.
385
409
  optional: true
386
410
  refs: >
411
+ - Cockburn: Writing Effective Use Cases (2001),
412
+ https://www.informit.com/store/writing-effective-use-cases-9780201702255
387
413
  - Cooper: The Inmates Are Running the Asylum, 2nd ed. (2004),
388
414
  https://www.informit.com/store/inmates-are-running-the-asylum-why-high-tech-products-9780672326141
389
415
  - Cooper et al.: About Face: The Essentials of Interaction Design, 4th ed. (2014),
@@ -391,15 +417,60 @@
391
417
  - Pruitt/Adlin: The Persona Lifecycle: Keeping People in Mind Throughout Product Design (2006),
392
418
  https://www.sciencedirect.com/book/9780125662512/the-persona-lifecycle
393
419
  diagram:
394
- type: grid
395
- nodes: "[[PERSONA:*]]"
396
- properties:
397
- - TYPE
398
- - ROLE
420
+ type: graph
421
+ nodes: "[[ROLE:*]], [[PERSONA:*]]"
422
+ labeled: true
423
+ qualified: true
399
424
  config:
400
425
  size-node-width-max: 440
401
- grid-columns-max: 4
402
426
  children:
427
+ - kind: ROLE
428
+ desc: >
429
+ A single role, named with the canonical name of the part a party plays towards
430
+ the solution (e.g. `Moderator`, matching its GLOSSARY term of type `Actor`) and
431
+ described in a concise (1-2 sentence) paragraph by the responsibility the role
432
+ carries, plus a 1-sentence rationale ("why") stating why the part is cut this way.
433
+ A role is the name of a part and not of a person: the personas embodying it act in
434
+ exactly this part and hold exactly the rights the Authorization Model grants to it
435
+ (plus those of the roles it `INHERITS`), while a persona holding several roles
436
+ holds the union of them.
437
+ format:
438
+ maxTableColumns: 5
439
+ referenced:
440
+ - "[[*]]"
441
+ diagram:
442
+ type: hub
443
+ center: self
444
+ nodes: "[[ROLE:*]], [[TERM:*]], [[PERSONA:*]], [[ACTIVITY:*]], [[USE-CASE:*]],
445
+ [[CV.ENTITY:*]]"
446
+ labeled: true
447
+ qualified: true
448
+ config:
449
+ size-node-width-max: 440
450
+ size-node-height-scale: 1.75
451
+ props:
452
+ - name: TYPE
453
+ desc: >
454
+ Whether the role is played by a `Person`, i.e. a human part embodied by at
455
+ least one persona, or by a `System`, i.e. an external system acting towards
456
+ the solution (e.g. a registration system calling the machine-facing
457
+ interface), which no persona embodies.
458
+ value: enum(Person,System)
459
+ - name: TERM
460
+ desc: >
461
+ Reference to the GLOSSARY term of type `Actor` the role plays, anchoring
462
+ the role in the ubiquitous language.
463
+ value: "[[TERM:*]]"
464
+ optional: true
465
+ - name: INHERITS
466
+ desc: >
467
+ Comma-separated references to the other ROLE objects this role holds in
468
+ addition to its own (a role hierarchy, e.g. a manager inheriting the
469
+ rights of a moderator), where an inherited permission is not restated in
470
+ the Authorization Model.
471
+ value: list([[ROLE:*]])
472
+ optional: true
473
+ acyclic: true
403
474
  - kind: PERSONA
404
475
  desc: >
405
476
  An archetypal user profile, named with a per-artifact unique first name of the
@@ -409,8 +480,6 @@
409
480
  line. Non-user stakeholders are modeled as personas of type `Stakeholder`.
410
481
  format:
411
482
  maxTableColumns: 5
412
- referenced:
413
- - "[[ROLE:*]]"
414
483
  props:
415
484
  - name: TYPE
416
485
  desc: >
@@ -433,9 +502,14 @@
433
502
  The age in years of the persona.
434
503
  value: /^[0-9]+$/
435
504
  optional: true
436
- - name: ROLE
505
+ - name: ROLES
437
506
  desc: >
438
- The role of the persona.
507
+ Comma-separated references to the ROLE objects the persona embodies, i.e.
508
+ the parts it plays towards the solution and hence the rights it acts with,
509
+ so that every `User` persona holds at least one role; omitted for a
510
+ `Stakeholder` persona playing no part towards the solution itself.
511
+ value: list([[ROLE:*]])
512
+ optional: true
439
513
  - name: TERMS
440
514
  desc: >
441
515
  Comma-separated references to the GLOSSARY terms the persona embodies, i.e.
@@ -637,6 +711,28 @@
637
711
  several requirements otherwise) which is verifiable against its `METRIC`, written
638
712
  with exactly one keyword `MUST`, `SHOULD`, or `COULD` matching its `PRIORITY`, plus
639
713
  a 1-sentence rationale ("why").
714
+
715
+ The requirement is answered by the architecture, never the other way round: a
716
+ Quality Perspectives tactic addresses it through its mechanism, a Design Decisions
717
+ decision is driven by it as a force, and an Operations View concern fulfills it
718
+ through its procedure, so every requirement is referenced from at least one of
719
+ them (a `WONT` requirement, which the architecture rightly ignores, is the tolerated
720
+ exception the lint warning cannot tell apart) and its hub diagram shows what
721
+ answers it.
722
+ referenced:
723
+ - "[[TACTIC:*]]"
724
+ - "[[DECISION:*]]"
725
+ - "[[CONCERN:*]]"
726
+ diagram:
727
+ type: hub
728
+ center: self
729
+ nodes: "[[NR.REQUIREMENT:*]], [[FR.REQUIREMENT:*]], [[PREMISE:*]], [[RULE:*]],
730
+ [[TACTIC:*]], [[DECISION:*]], [[CONCERN:*]], [[TEST-CASE:*]]"
731
+ labeled: true
732
+ qualified: true
733
+ config:
734
+ size-node-width-max: 440
735
+ size-node-height-scale: 1.75
640
736
  props:
641
737
  - name: PRIORITY
642
738
  desc: >
@@ -822,6 +918,10 @@
822
918
  The workflow is at summary level, above the user-goal level of the Use Cases: it
823
919
  spans several actors and several sittings, and its activities leave the
824
920
  step-by-step interaction with the solution to the use cases referencing them.
921
+ An activity and a use case relate n:m -- an activity is covered by several use
922
+ cases, a use case spans several activities, and an activity performed outside the
923
+ solution is covered by none at all -- so the workflow is no mere sequence of use
924
+ cases and cannot be assembled from them.
825
925
  automaton:
826
926
  nodes: ACTIVITY
827
927
  edges: HANDOFF
@@ -835,17 +935,19 @@
835
935
  edgeSource: FROM
836
936
  edgeTarget: TO
837
937
  onlyConnected: true
838
- properties:
839
- - ACTOR
938
+ qualified: true
939
+ nest:
940
+ properties:
941
+ - ACTOR
840
942
  config:
841
943
  size-node-width-max: 440
842
944
  props:
843
945
  - name: ACTORS
844
946
  desc: >
845
- Comma-separated references to the User Personas objects taking part in the
846
- workflow, in the order of their first appearance, so that every `ACTOR` of
847
- an activity is listed here.
848
- value: list([[PERSONA:*]])
947
+ Comma-separated references to the User Personas ROLE objects taking part
948
+ in the workflow, in the order of their first appearance, so that every
949
+ `ACTOR` of an activity is listed here.
950
+ value: list([[ROLE:*]])
849
951
  - name: OWNER
850
952
  desc: >
851
953
  Reference to the User Personas object (usually a `Stakeholder`) accountable
@@ -895,12 +997,12 @@
895
997
  props:
896
998
  - name: ACTOR
897
999
  desc: >
898
- Reference to the User Personas object performing the activity, or
899
- `System` for an activity the solution performs on its own (e.g.
1000
+ Reference to the User Personas ROLE object performing the activity,
1001
+ or `System` for an activity the solution performs on its own (e.g.
900
1002
  sending the invitations) or `Time` for a waiting period ending with
901
1003
  a deadline; several parties are given only for an activity they
902
1004
  perform jointly, as a change of the acting party is a handoff.
903
- value: list([[PERSONA:*]], enum(System,Time))
1005
+ value: list([[ROLE:*]], enum(System,Time))
904
1006
  - name: INITIAL
905
1007
  desc: >
906
1008
  Whether the activity is the initial one, i.e. the single activity
@@ -969,11 +1071,13 @@
969
1071
  - Jacobson/Spence/Bittner: Use-Case 2.0: The Guide to Succeeding with Use Cases (2011),
970
1072
  https://www.ivarjacobson.com/publications/white-papers/use-case-20-e-book
971
1073
  diagram:
972
- type: grid
973
- nodes: "[[USE-CASE:*]]"
1074
+ type: graph
1075
+ nodes: "[[USE-CASE:*]], [[ROLE:*]]"
1076
+ labeled: true
1077
+ qualified: true
1078
+ onlyConnected: true
974
1079
  config:
975
- size-node-height-scale: 4
976
- grid-columns-max: 4
1080
+ size-node-width-max: 440
977
1081
  children:
978
1082
  - kind: USE-CASE
979
1083
  desc: >
@@ -987,12 +1091,16 @@
987
1091
  The use case is at user-goal level: a goal the actor completes in one sitting,
988
1092
  neither a summary of many sittings and actors (which belongs to a Domain Workflow
989
1093
  as a whole, or to a User Journey when seen by a single persona) nor a single
990
- interaction (which belongs to a scenario as one of its steps).
1094
+ interaction (which belongs to a scenario as one of its steps). Its `ACTIVITIES`
1095
+ relate it n:m to the Domain Workflow activities -- a use case spans several
1096
+ activities and an activity is covered by several use cases -- so the two decompose
1097
+ the same domain independently instead of nesting into each other.
991
1098
  diagram:
992
1099
  type: hub
993
1100
  center: self
994
- nodes: "[[USE-CASE:*]], [[PERSONA:*]], [[STEP:*]], [[ACTIVITY:*]],
995
- [[FR.REQUIREMENT:*]], [[RULE:*]], [[TRANSITION:*]]"
1101
+ nodes: "[[USE-CASE:*]], [[ROLE:*]], [[PERSONA:*]], [[STEP:*]], [[ACTIVITY:*]],
1102
+ [[FR.REQUIREMENT:*]], [[RULE:*]], [[TRANSITION:*]], [[PERMISSION:*]],
1103
+ [[PRINCIPLE:*]], [[CV.ENTITY:*]]"
996
1104
  labeled: true
997
1105
  qualified: true
998
1106
  config:
@@ -1001,9 +1109,18 @@
1001
1109
  props:
1002
1110
  - name: ACTOR
1003
1111
  desc: >
1004
- Reference to the PERSONAS object denoting the primary actor pursuing the
1005
- goal.
1006
- value: "[[PERSONA:*]]"
1112
+ Reference to the User Personas ROLE object denoting the primary actor
1113
+ pursuing the goal, i.e. the part played and not the person playing it, so
1114
+ that a use case is written once per role and not once per persona.
1115
+ value: "[[ROLE:*]]"
1116
+ - name: PERSONAS
1117
+ desc: >
1118
+ Comma-separated references to the User Personas objects taking the
1119
+ `ACTOR` role in this use case, i.e. the archetypes for which its flow is
1120
+ worked out in the Dialog Storyboard and the Test Cases; omitted when every
1121
+ persona holding the role pursues the goal alike.
1122
+ value: list([[PERSONA:*]])
1123
+ optional: true
1007
1124
  - name: JOURNEYS
1008
1125
  desc: >
1009
1126
  Comma-separated references to the User Journey STEP objects the use case
@@ -1132,10 +1249,13 @@
1132
1249
  diagram:
1133
1250
  type: hub
1134
1251
  center: self
1135
- nodes: "[[DM.ENTITY:*]]"
1252
+ nodes: "[[DM.ENTITY:*]], [[FR.REQUIREMENT:*]], [[USE-CASE:*]]"
1136
1253
  edges: "[[RELATION:*]]"
1254
+ labeled: true
1255
+ qualified: true
1137
1256
  config:
1138
1257
  size-node-width-max: 440
1258
+ size-node-height-scale: 1.75
1139
1259
  props:
1140
1260
  - name: REQUIREMENTS
1141
1261
  desc: >
@@ -1144,6 +1264,16 @@
1144
1264
  tracing the requirements into the data model.
1145
1265
  value: list([[FR.*]])
1146
1266
  optional: true
1267
+ - name: USE-CASES
1268
+ desc: >
1269
+ Comma-separated references to the USE-CASES objects whose scenarios
1270
+ create, read, update, or delete instances of the entity, tracing the use
1271
+ cases into the data model, so that every entity shows where its data
1272
+ comes from and where it goes; omitted for an entity no actor goal touches
1273
+ (e.g. a purely system-maintained one, justified by its `REQUIREMENTS`
1274
+ alone).
1275
+ value: list([[USE-CASE:*]])
1276
+ optional: true
1147
1277
  - name: TERMS
1148
1278
  desc: >
1149
1279
  Comma-separated references to the GLOSSARY terms the entity materializes,
@@ -1290,6 +1420,7 @@
1290
1420
  - FINAL
1291
1421
  config:
1292
1422
  size-node-width-max: 440
1423
+ size-node-height-scale: 1.75
1293
1424
  props:
1294
1425
  - name: ENTITY
1295
1426
  desc: >
@@ -1354,11 +1485,12 @@
1354
1485
  local: true
1355
1486
  - name: ACTOR
1356
1487
  desc: >
1357
- Comma-separated references to the PERSONAS objects able to trigger
1358
- the transition, and/or `System` for a transition the solution
1359
- triggers on its own or `Time` for one triggered by the passing of
1360
- time (e.g. an expiry); omitted when the trigger is irrelevant.
1361
- value: list([[PERSONA:*]], enum(System,Time))
1488
+ Comma-separated references to the User Personas ROLE objects able
1489
+ to trigger the transition, and/or `System` for a transition the
1490
+ solution triggers on its own or `Time` for one triggered by the
1491
+ passing of time (e.g. an expiry); omitted when the trigger is
1492
+ irrelevant.
1493
+ value: list([[ROLE:*]], enum(System,Time))
1362
1494
  optional: true
1363
1495
  - name: GUARD
1364
1496
  desc: >
@@ -1378,9 +1510,12 @@
1378
1510
  Comma-separated references to the USE-CASES objects whose
1379
1511
  scenarios trigger the transition, i.e. in which a scenario step
1380
1512
  causes the state change, tracing the transition into the use
1381
- cases exercising it; omitted for a transition no use case
1382
- triggers (e.g. one triggered by `Time` or by the system alone).
1383
- value: list([[USE-CASE:*]])
1513
+ cases exercising it, or, where not every scenario of a use case
1514
+ triggers it, to the very `SCENARIO` objects doing so, tracing
1515
+ the transition into the step-by-step flows causing it; omitted
1516
+ for a transition no use case triggers (e.g. one triggered by
1517
+ `Time` or by the system alone).
1518
+ value: list([[USE-CASE:*]], [[SCENARIO:*]])
1384
1519
  optional: true
1385
1520
 
1386
1521
  - kind: DATA
@@ -1388,13 +1523,13 @@
1388
1523
  id: AM
1389
1524
  file: 13-DATA-AM-Authorization-Model.md
1390
1525
  desc: >
1391
- The access rights of the solution, bundled into the roles a person acts in and stating for
1392
- each role the operations it may perform on each entity, confined to the lifecycle states
1393
- of the entity and to a further condition where necessary, so that "who may do what on
1394
- which entity in which state" is answered in one place instead of being scattered over the
1395
- actors of the state transitions, the actors of the use cases, and the prose of the domain
1396
- rules. The model is closed: an operation not granted to a role is forbidden, exactly like
1397
- a move not listed as a state transition.
1526
+ The access rights of the solution, granted to the roles of the User Personas and stating
1527
+ for each role the operations it may perform on each entity, confined to the lifecycle
1528
+ states of the entity and to a further condition where necessary, so that "who may do what
1529
+ on which entity in which state" is answered in one place instead of being scattered over
1530
+ the actors of the state transitions, the actors of the use cases, and the prose of the
1531
+ domain rules. The model is closed: an operation not granted to a role is forbidden,
1532
+ exactly like a move not listed as a state transition.
1398
1533
  optional: true
1399
1534
  refs: >
1400
1535
  - Ferraiolo/Kuhn: Role-Based Access Controls, 15th National Computer Security Conference (1992),
@@ -1409,6 +1544,7 @@
1409
1544
  type: graph
1410
1545
  nodes: "[[ROLE:*]], [[DM.ENTITY:*]]"
1411
1546
  edges: "[[PERMISSION:*]]"
1547
+ edgeSource: ROLE
1412
1548
  edgeTarget: ENTITY
1413
1549
  onlyConnected: true
1414
1550
  qualified: true
@@ -1416,103 +1552,73 @@
1416
1552
  size-node-width-max: 440
1417
1553
  graph-channel-width-max: 340
1418
1554
  children:
1419
- - kind: ROLE
1555
+ - kind: PERMISSION
1420
1556
  desc: >
1421
- A single role, named with the canonical name of the domain role it grants (e.g.
1422
- `Moderator`, matching its GLOSSARY term of type `Actor`) and described in a concise
1423
- (1-2 sentence) paragraph by the responsibility the role carries, plus a 1-sentence
1424
- rationale ("why") stating why the rights are bundled this way. A role is the unit
1425
- in which rights are granted to a person: the personas embodying it hold exactly
1426
- its `PERMISSION` objects (plus those of the roles it `INHERITS`), while a persona
1427
- holding several roles holds the union of their permissions.
1428
- diagram:
1429
- type: hub
1430
- center: self
1431
- deep: true
1432
- nodes: "[[ROLE:*]], [[PERSONA:*]], [[TERM:*]], [[DM.ENTITY:*]], [[RULE:*]]"
1433
- labeled: true
1434
- qualified: true
1435
- config:
1436
- size-node-width-max: 440
1437
- size-node-height-scale: 1.75
1557
+ A single right of a role on a single entity, named with a short (2-5 word) verb
1558
+ phrase of what the role may do (e.g. `Decide Pending Messages`) and described by
1559
+ a 1-sentence description of the right, in particular of the reach of its
1560
+ `CONDITION`. One permission covers one entity: the operations it grants, the
1561
+ states of the entity in which they are granted, and the condition under which
1562
+ they are granted, so that the permissions of all roles form the access matrix of
1563
+ roles against entities. Any operation, state, or condition not covered by a
1564
+ permission of the role (or of a role it `INHERITS`) is forbidden.
1565
+ format:
1566
+ maxTableColumns: 8
1438
1567
  props:
1439
- - name: ACTORS
1568
+ - name: ROLE
1440
1569
  desc: >
1441
- Comma-separated references to the User Personas objects embodying the
1442
- role, i.e. the personas acting with exactly its rights, so that every
1443
- persona holds at least one role and its rights are stated here rather than
1444
- implied by its `ROLE` description, and/or to the GLOSSARY terms of type
1445
- `Actor` denoting the external systems holding the role (e.g. a registration
1446
- system calling the machine-facing interface), as an external system is no
1447
- persona.
1448
- value: list([[PERSONA:*]], [[TERM:*]])
1449
- - name: TERM
1570
+ Reference to the User Personas ROLE object the permission is granted to,
1571
+ so that the permissions of a role are found by its references.
1572
+ value: "[[ROLE:*]]"
1573
+ - name: ENTITY
1574
+ desc: Reference to the DATA-MODEL entity the permission is granted on.
1575
+ value: "[[DM.ENTITY:*]]"
1576
+ - name: OPERATIONS
1577
+ desc: >
1578
+ Comma-separated operations the role may perform on the entity: the
1579
+ generic `Create`, `Read`, `Update`, and `Delete`, and/or references to
1580
+ the STATE-MODEL transitions of the entity the role may trigger (a state
1581
+ change is not an `Update`: it is granted by its transition only), where
1582
+ every role named as `ACTOR` of a transition holds a permission granting
1583
+ it.
1584
+ value: list(enum(Create,Read,Update,Delete), [[TRANSITION:*]])
1585
+ - name: STATES
1586
+ desc: >
1587
+ Comma-separated references to the STATE-MODEL states of the entity in
1588
+ which the operations are granted (`Create` needs none, as a creation
1589
+ enters the initial state); omitted when granted in every state or when
1590
+ the entity has no lifecycle.
1591
+ value: list([[STATE:*]])
1592
+ optional: true
1593
+ - name: CONDITION
1594
+ desc: >
1595
+ The condition which, beyond the role and the `STATES`, has to hold for
1596
+ the operations to be granted, stated as a 1-sentence statement of what
1597
+ has to hold, typically the ownership of the instance (e.g. `The attendee
1598
+ is the sender of the message.`), a confinement to certain attributes
1599
+ (e.g. `The update is confined to the presenter alert.`), or a
1600
+ configuration of the surrounding entity; omitted when the role and the
1601
+ states alone grant the operations.
1602
+ optional: true
1603
+ - name: RULES
1450
1604
  desc: >
1451
- Reference to the GLOSSARY term of type `Actor` the role grants, anchoring
1452
- the role in the ubiquitous language.
1453
- value: "[[TERM:*]]"
1605
+ Comma-separated references to the DOMAIN-RULES objects justifying or
1606
+ bounding the permission, i.e. the rules whose statement grants or limits
1607
+ the right.
1608
+ value: list([[RULE:*]])
1454
1609
  optional: true
1455
- - name: INHERITS
1610
+ - name: USE-CASES
1456
1611
  desc: >
1457
- Comma-separated references to the other ROLE objects whose permissions
1458
- this role holds in addition to its own (a role hierarchy, e.g. a manager
1459
- inheriting the rights of a moderator), where an inherited permission is
1460
- not restated.
1461
- value: list([[ROLE:*]])
1612
+ Comma-separated references to the USE-CASES objects whose scenarios
1613
+ exercise the permission, i.e. in which a scenario step performs one of
1614
+ the granted operations, or, where not every scenario of a use case does
1615
+ so, to the very `SCENARIO` objects doing so, including the exceptional
1616
+ scenarios in which the solution refuses an operation at the boundary of
1617
+ the permission, tracing the permission into the step-by-step flows
1618
+ exercising and enforcing it; omitted for a permission exercised outside
1619
+ any use case (e.g. through the configuration).
1620
+ value: list([[USE-CASE:*]], [[SCENARIO:*]])
1462
1621
  optional: true
1463
- acyclic: true
1464
- children:
1465
- - kind: PERMISSION
1466
- desc: >
1467
- A single right of the role on a single entity, named with a short (2-5
1468
- word) verb phrase of what the role may do (e.g. `Decide Pending Messages`)
1469
- and described by a 1-sentence description of the right, in particular of
1470
- the reach of its `CONDITION`. One permission covers one entity: the
1471
- operations it grants, the states of the entity in which they are granted,
1472
- and the condition under which they are granted, so that the permissions
1473
- of all roles form the access matrix of roles against entities. Any
1474
- operation, state, or condition not covered by a permission of the role (or
1475
- of an inherited one) is forbidden.
1476
- format:
1477
- maxTableColumns: 7
1478
- props:
1479
- - name: ENTITY
1480
- desc: Reference to the DATA-MODEL entity the permission is granted on.
1481
- value: "[[DM.ENTITY:*]]"
1482
- - name: OPERATIONS
1483
- desc: >
1484
- Comma-separated operations the role may perform on the entity: the
1485
- generic `Create`, `Read`, `Update`, and `Delete`, and/or references
1486
- to the STATE-MODEL transitions of the entity the role may trigger
1487
- (a state change is not an `Update`: it is granted by its transition
1488
- only), where every persona named as `ACTOR` of a transition holds
1489
- a role granting it.
1490
- value: list(enum(Create,Read,Update,Delete), [[TRANSITION:*]])
1491
- - name: STATES
1492
- desc: >
1493
- Comma-separated references to the STATE-MODEL states of the entity
1494
- in which the operations are granted (`Create` needs none, as a
1495
- creation enters the initial state); omitted when granted in every
1496
- state or when the entity has no lifecycle.
1497
- value: list([[STATE:*]])
1498
- optional: true
1499
- - name: CONDITION
1500
- desc: >
1501
- The condition which, beyond the role and the `STATES`, has to hold
1502
- for the operations to be granted, stated as a 1-sentence statement
1503
- of what has to hold, typically the ownership of the instance (e.g.
1504
- `The attendee is the sender of the message.`), a confinement to
1505
- certain attributes (e.g. `The update is confined to the presenter
1506
- alert.`), or a configuration of the surrounding entity; omitted
1507
- when the role and the states alone grant the operations.
1508
- optional: true
1509
- - name: RULES
1510
- desc: >
1511
- Comma-separated references to the DOMAIN-RULES objects justifying
1512
- or bounding the permission, i.e. the rules whose statement grants
1513
- or limits the right.
1514
- value: list([[RULE:*]])
1515
- optional: true
1516
1622
 
1517
1623
  - kind: APIS
1518
1624
  name: Interface Model
@@ -2050,7 +2156,7 @@
2050
2156
  diagram:
2051
2157
  type: hub
2052
2158
  center: self
2053
- nodes: "[[PRINCIPLE:*]], [[PERSONA:*]], [[STEP:*]], [[PATTERN:*]]"
2159
+ nodes: "[[PRINCIPLE:*]], [[PERSONA:*]], [[STEP:*]], [[USE-CASE:*]], [[PATTERN:*]]"
2054
2160
  labeled: true
2055
2161
  qualified: true
2056
2162
  config:
@@ -2068,16 +2174,32 @@
2068
2174
  desc: >
2069
2175
  Comma-separated references to the User Personas objects whose experience
2070
2176
  the principle governs, omitted for a principle governing the experience of
2071
- all users alike.
2177
+ all users alike; this scopes the principle only, its origin is the
2178
+ `MOTIVATED-BY` and its realization the `USE-CASES`.
2072
2179
  value: list([[PERSONA:*]])
2073
2180
  optional: true
2074
2181
  - name: MOTIVATED-BY
2075
2182
  desc: >
2076
2183
  Comma-separated references to the User Journey step objects whose
2077
2184
  `PAIN-POINT` or `OPPORTUNITY` the principle answers, so that a principle is
2078
- grounded in the observed experience rather than in taste alone.
2185
+ grounded in the observed experience rather than in taste alone; this is the
2186
+ origin of the principle (why it exists), while the `USE-CASES` are its
2187
+ realization (where it can be checked).
2079
2188
  value: list([[STEP:*]])
2080
2189
  optional: true
2190
+ - name: USE-CASES
2191
+ desc: >
2192
+ Comma-separated references to the USE-CASES objects whose scenario steps
2193
+ exhibit the behavior the principle prescribes (e.g. a `Moderation-Gated
2194
+ Visibility` surfaces in the step where the submitted message is acknowledged
2195
+ but not yet public), or, where not every scenario of a use case does so, to
2196
+ the very `SCENARIO` objects doing so, tracing the principle into the
2197
+ step-by-step flows against which its realization is checked, while the
2198
+ concrete user interface realizing it stays with the Dialog Patterns and the
2199
+ Dialog Storyboard; omitted for a principle governing no use case flow in
2200
+ particular.
2201
+ value: list([[USE-CASE:*]], [[SCENARIO:*]])
2202
+ optional: true
2081
2203
  - name: TRADE-OFF
2082
2204
  desc: >
2083
2205
  The competing concern the principle deliberately subordinates, stated so
@@ -2512,6 +2634,7 @@
2512
2634
  inbound: Inbound
2513
2635
  outbound: Outbound
2514
2636
  both: Bidirectional
2637
+ via: VIA
2515
2638
  qualified: true
2516
2639
  properties:
2517
2640
  - KIND
@@ -2550,8 +2673,20 @@
2550
2673
  sides initiate), independent of the direction the exchanged information
2551
2674
  flows in, which the `DATA` property describes (e.g. a datastore the
2552
2675
  solution reads from is `Outbound`, as the solution initiates, while the
2553
- data flows in).
2676
+ data flows in). For a mediated entity (see `VIA`), where the mediator
2677
+ initiates every interaction, the direction of the data flow instead.
2554
2678
  value: enum(Inbound,Outbound,Bidirectional)
2679
+ - name: VIA
2680
+ desc: >
2681
+ Reference to the entity mediating the exchange with this one, when the
2682
+ solution and the entity have no direct technical interaction at all,
2683
+ but a person or system in between carries the data (e.g. a manager
2684
+ uploading the file exported by an external system), so the context
2685
+ diagram marks the edge as `via` that entity instead of suggesting an
2686
+ online integration; omitted for a directly interacting entity.
2687
+ value: "[[CV.ENTITY:*]]"
2688
+ optional: true
2689
+ acyclic: true
2555
2690
  - name: TERMS
2556
2691
  desc: >
2557
2692
  Comma-separated references to the GLOSSARY terms the entity appears as in
@@ -2571,13 +2706,21 @@
2571
2706
  optional: true
2572
2707
  - name: ACTORS
2573
2708
  desc: >
2574
- Comma-separated references to the User Personas objects acting behind the
2575
- entity: a `Person` entity is the boundary-level role class and the referenced
2576
- personas are its archetypes, while an `Organization` entity may reference
2577
- the `Stakeholder` personas representing it, so the entity aggregates the
2578
- personas instead of re-stating them; omitted when no persona stands behind
2579
- the entity.
2580
- value: list([[PERSONA:*]])
2709
+ Comma-separated references to the User Personas ROLE objects acting
2710
+ behind the entity: a `Person` entity is the boundary-level class of the
2711
+ `Person` roles acting through it, while a `System` entity may reference
2712
+ the `System` role it plays, so the entity aggregates the roles instead of
2713
+ re-stating them; omitted when no modeled role stands behind the entity.
2714
+ value: list([[ROLE:*]])
2715
+ optional: true
2716
+ - name: USE-CASES
2717
+ desc: >
2718
+ Comma-separated references to the USE-CASES objects whose interaction
2719
+ crosses the boundary at this entity (the use cases a `Person` entity
2720
+ performs, or the ones exchanging data with a `System` or `Service`
2721
+ entity), so the use case responsible for an entity is found without a
2722
+ text search; omitted when no modeled use case touches the entity.
2723
+ value: list([[USE-CASE:*]])
2581
2724
  optional: true
2582
2725
  - name: PREMISES
2583
2726
  desc: >
@@ -2612,6 +2755,9 @@
2612
2755
  type: graph
2613
2756
  nodes: "[[FV.COMPONENT:*]]"
2614
2757
  labeled: true
2758
+ nest:
2759
+ properties:
2760
+ - PART-OF
2615
2761
  properties:
2616
2762
  - KIND
2617
2763
  children:
@@ -2629,7 +2775,8 @@
2629
2775
  diagram:
2630
2776
  type: hub
2631
2777
  center: self
2632
- nodes: "[[FV.COMPONENT:*]], [[FR.REQUIREMENT:*]], [[INTERFACE:*]], [[DM.ENTITY:*]]"
2778
+ nodes: "[[FV.COMPONENT:*]], [[FR.REQUIREMENT:*]], [[INTERFACE:*]], [[DM.ENTITY:*]],
2779
+ [[TACTIC:*]], [[DECISION:*]]"
2633
2780
  labeled: true
2634
2781
  qualified: true
2635
2782
  properties:
@@ -2717,7 +2864,15 @@
2717
2864
  https://c4model.com/diagrams/container
2718
2865
  diagram:
2719
2866
  type: grid
2720
- nodes: "[[TS.TIER:*]]"
2867
+ nodes: "[[TS.TIER:*]], [[TS.TIER:*.COMPONENT:*]]"
2868
+ nest:
2869
+ parent: true
2870
+ layout: grid
2871
+ properties:
2872
+ - PRODUCT
2873
+ config:
2874
+ size-node-width-max: 440
2875
+ grid-columns-max: 3
2721
2876
  children:
2722
2877
  - kind: TIER
2723
2878
  desc: |
@@ -2760,7 +2915,8 @@
2760
2915
  diagram:
2761
2916
  type: hub
2762
2917
  center: self
2763
- nodes: "[[TS.TIER:*.COMPONENT:*]], [[FV.COMPONENT:*]], [[DECISION:*]]"
2918
+ nodes: "[[TS.TIER:*.COMPONENT:*]], [[FV.COMPONENT:*]], [[TACTIC:*]],
2919
+ [[DECISION:*]]"
2764
2920
  labeled: true
2765
2921
  qualified: true
2766
2922
  properties:
@@ -3083,7 +3239,22 @@
3083
3239
  states the product choice), does not restate the runtime structure (a Functionality
3084
3240
  View `Module` or `Subsystem` groups the logic), does not cover production
3085
3241
  procedures (an Operations View concern does), and the trade-off that produced a
3086
- rule is a Design Decisions decision referencing the aspect through `AFFECTS`.
3242
+ rule is a Design Decisions decision referencing the aspect through `AFFECTS`,
3243
+ while the quality the rule protects (usually a `Maintainability` requirement) is
3244
+ addressed by a Quality Perspectives tactic referencing the aspect through
3245
+ `AFFECTS`, too, so the hub diagram of an aspect shows the decision and the tactic
3246
+ behind it.
3247
+ diagram:
3248
+ type: hub
3249
+ center: self
3250
+ nodes: "[[ASPECT:*]], [[TACTIC:*]], [[DECISION:*]]"
3251
+ labeled: true
3252
+ qualified: true
3253
+ properties:
3254
+ - CATEGORY
3255
+ config:
3256
+ size-node-width-max: 440
3257
+ size-node-height-scale: 1.75
3087
3258
  props:
3088
3259
  - name: CATEGORY
3089
3260
  desc: >
@@ -3136,7 +3307,7 @@
3136
3307
  diagram:
3137
3308
  type: hub
3138
3309
  center: self
3139
- nodes: "[[UNIT:*]], [[FV.COMPONENT:*]], [[NODE:*]]"
3310
+ nodes: "[[UNIT:*]], [[FV.COMPONENT:*]], [[NODE:*]], [[TACTIC:*]], [[DECISION:*]]"
3140
3311
  labeled: true
3141
3312
  qualified: true
3142
3313
  properties:
@@ -3207,8 +3378,12 @@
3207
3378
  type: graph
3208
3379
  nodes: "[[NODE:*]]"
3209
3380
  labeled: true
3381
+ qualified: true
3382
+ nest:
3383
+ properties:
3384
+ - PART-OF
3385
+ - TIER
3210
3386
  properties:
3211
- - TIER
3212
3387
  - AREA
3213
3388
  - KIND
3214
3389
  - PLATFORM
@@ -3233,7 +3408,7 @@
3233
3408
  diagram:
3234
3409
  type: hub
3235
3410
  center: self
3236
- nodes: "[[DV.TIER:*]], [[NODE:*]]"
3411
+ nodes: "[[DV.TIER:*]], [[NODE:*]], [[TACTIC:*]], [[DECISION:*]]"
3237
3412
  labeled: true
3238
3413
  qualified: true
3239
3414
  properties:
@@ -3283,7 +3458,7 @@
3283
3458
  diagram:
3284
3459
  type: hub
3285
3460
  center: self
3286
- nodes: "[[AREA:*]], [[NODE:*]]"
3461
+ nodes: "[[AREA:*]], [[NODE:*]], [[TACTIC:*]], [[DECISION:*]]"
3287
3462
  labeled: true
3288
3463
  qualified: true
3289
3464
  properties:
@@ -3310,7 +3485,7 @@
3310
3485
  type: hub
3311
3486
  center: self
3312
3487
  nodes: "[[DV.TIER:*]], [[AREA:*]], [[NODE:*]], [[NETWORK:*]], [[FV.COMPONENT:*]],
3313
- [[UNIT:*]]"
3488
+ [[UNIT:*]], [[TACTIC:*]], [[DECISION:*]]"
3314
3489
  labeled: true
3315
3490
  qualified: true
3316
3491
  properties:
@@ -3407,7 +3582,7 @@
3407
3582
  diagram:
3408
3583
  type: hub
3409
3584
  center: self
3410
- nodes: "[[NETWORK:*]], [[NODE:*]]"
3585
+ nodes: "[[NETWORK:*]], [[NODE:*]], [[TACTIC:*]], [[DECISION:*]]"
3411
3586
  labeled: true
3412
3587
  qualified: true
3413
3588
  properties:
@@ -3789,10 +3964,11 @@
3789
3964
  Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS or
3790
3965
  SOLUTION-PREMISES objects forcing the decision (e.g. the compliance
3791
3966
  obligation, the budget constraint, the dependency taken as given), anchoring
3792
- the forces `WHEN` describes in prose; omitted when no modeled requirement or
3793
- premise drives the decision.
3967
+ the forces `WHEN` describes in prose: as a decision is the response to
3968
+ forces, at least one is always named, usually a Non-Functional Requirement
3969
+ and only exceptionally a premise alone, and a decision finding no
3970
+ requirement to name reveals a missing one rather than a needless reference.
3794
3971
  value: list([[NR.*]], [[PREMISE:*]])
3795
- optional: true
3796
3972
  - name: AFFECTS
3797
3973
  desc: >
3798
3974
  Comma-separated references to the objects of the DATA, APIS, UXUI, or ARCH
@@ -3917,6 +4093,11 @@
3917
4093
  or fail, and many test cases (e.g. of Non-Functional Requirements or of cross-session rules)
3918
4094
  have no use case counterpart at all.
3919
4095
  optional: true
4096
+ coverage:
4097
+ - "[[USE-CASE:*]]"
4098
+ - "[[SCENARIO:*]]"
4099
+ - "[[REQUIREMENT:*]]"
4100
+ - "[[RULE:*]]"
3920
4101
  refs: >
3921
4102
  - ISO/IEC/IEEE 29119-3:2021: Software and systems engineering -- Software testing -- Part 3: Test documentation (2021),
3922
4103
  https://www.iso.org/standard/79429.html