@rse/specbook 1.4.2 → 1.5.1

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.
@@ -124,9 +124,9 @@ const d2Error = (err) => {
124
124
  return message;
125
125
  }
126
126
  };
127
- /* render a D2 diagram, with the theme colors prepended as one line of
128
- theme overrides (on the theme of the style), so the overrides of the
129
- diagram itself still win */
127
+ /* render a D2 diagram, with the TALA layout engine and the theme colors
128
+ prepended as one line of configuration (on the theme of the style),
129
+ so the configuration of the diagram itself still wins */
130
130
  const renderD2 = (source, colors, style) => {
131
131
  const overrides = Object.entries(colors).map(([key, color]) => `${key}: "${color}"`).join("; ");
132
132
  const request = d2Chain.then(async () => {
@@ -140,7 +140,7 @@ const renderD2 = (source, colors, style) => {
140
140
  worker()?.ref();
141
141
  try {
142
142
  const result = await compiler.compile({
143
- fs: { index: `vars: { d2-config: { theme-overrides: { ${overrides} } } }\n${source}` },
143
+ fs: { index: `vars: { d2-config: { layout-engine: tala; theme-overrides: { ${overrides} } } }\n${source}` },
144
144
  options: { themeID: style === "dark" ? 200 : 0, scale: 1, pad: 0, noXMLTag: true }
145
145
  });
146
146
  return await compiler.render(result.diagram, result.renderOptions);
@@ -1148,8 +1148,10 @@ its own and embedded like an image -- `![<alt/>](<file/>.mmd)`,
1148
1148
  `![<alt/>](<file/>.mermaid)`, or `![<alt/>](<file/>.d2)` -- inside a
1149
1149
  description or property value, where its source is inlined at parse time.
1150
1150
  The HTML/PDF export renders every such diagram (Mermaid through
1151
- `beautiful-mermaid`, D2 through `@d2lang/d2`) in the theme colors of
1152
- the document, once per color theme, like a theme-aware image. It folds,
1151
+ `beautiful-mermaid`, D2 through `@d2lang/d2`, laid out by its TALA
1152
+ engine unless the diagram configures another `layout-engine`) in the
1153
+ theme colors of the document, once per color theme, like a theme-aware
1154
+ image. It folds,
1153
1155
  maximizes, and is omitted (`-O diagram:code`, for diagrams as code, or
1154
1156
  by nesting level) like a derived Gradia diagram. A diagram failing to render
1155
1157
  is omitted with a notice. The normalized Markdown and the AST exports
@@ -642,7 +642,10 @@
642
642
  desc: >
643
643
  The concrete behaviors and capabilities the solution must provide, describing *what* the
644
644
  system does in terms of functions, features, and operations, while the quality bounds and
645
- constraints on them belong to the Non-Functional Requirements.
645
+ constraints on them belong to the Non-Functional Requirements. The requirements are
646
+ optionally grouped into the coherent capabilities they add up to (the epics of agile
647
+ planning, the features of product management), which the overview diagram draws as boxes
648
+ around their requirements.
646
649
  optional: true
647
650
  refs: >
648
651
  - Mavin et al.: Easy Approach to Requirements Syntax (EARS) (2009),
@@ -654,12 +657,31 @@
654
657
  diagram:
655
658
  type: grid
656
659
  nodes: "[[FR.REQUIREMENT:*]]"
660
+ nest:
661
+ properties:
662
+ - GROUP
657
663
  properties:
658
664
  - PRIORITY
659
665
  config:
660
666
  size-node-width-max: 440
661
- grid-columns-max: 4
667
+ grid-columns-max: 2
662
668
  children:
669
+ - kind: GROUP
670
+ desc: >
671
+ A named group of strongly related requirements, carrying a short (1-3 word),
672
+ per-artifact unique name distinct from the names of its requirements (e.g.
673
+ `Moderation` for the moderating, forwarding, and answering of attendee inputs,
674
+ `Event Access` for the access URLs), and described by a 1-sentence description
675
+ ("what") of the capability the requirements add up to plus a 1-sentence rationale
676
+ ("why") of the cohesion. A group is an epic in the agile sense and a feature in the
677
+ product sense, but carries no obligation of its own: it has no priority, states no
678
+ behavior, and is verified through its requirements alone, so it affects the
679
+ overview diagram only, where its requirements are drawn next to each other inside
680
+ a box. The groups are listed before the requirements, and every requirement
681
+ belongs to at most one group.
682
+ optional: true
683
+ referenced:
684
+ - "[[FR.REQUIREMENT:*]]"
663
685
  - kind: REQUIREMENT
664
686
  desc: >
665
687
  A single functional requirement, named with a short (3-8 word) summary and described
@@ -674,14 +696,15 @@
674
696
  unwanted-behavior (`If <condition>, then the system MUST ...`).
675
697
  optional: true
676
698
  format:
677
- maxTableColumns: 6
699
+ type: compact
678
700
  referenced:
679
701
  - "[[USE-CASE:*]]"
680
702
  diagram:
681
703
  type: hub
682
704
  center: self
683
- nodes: "[[FR.REQUIREMENT:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]], [[RULE:*]],
684
- [[USE-CASE:*]], [[DM.ENTITY:*]], [[FV.COMPONENT:*]], [[TEST-CASE:*]]"
705
+ nodes: "[[FR.GROUP:*]], [[FR.REQUIREMENT:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
706
+ [[RULE:*]], [[USE-CASE:*]], [[DM.ENTITY:*]], [[FV.COMPONENT:*]],
707
+ [[TEST-CASE:*]]"
685
708
  labeled: true
686
709
  qualified: true
687
710
  config:
@@ -697,6 +720,23 @@
697
720
  time"), preserving the conscious decision rather than silently dropping it,
698
721
  with the statement still phrased as it would be if in scope.
699
722
  value: enum(MUST,SHOULD,COULD,WONT)
723
+ - name: GROUP
724
+ desc: >
725
+ Reference to the FUNCTIONAL-REQUIREMENTS group the requirement belongs to,
726
+ placing it next to the other requirements of the group in the overview
727
+ diagram; omitted for a requirement standing on its own.
728
+ value: "[[FR.GROUP:*]]"
729
+ optional: true
730
+ - name: DEPENDS-ON
731
+ desc: >
732
+ Comma-separated references to the FUNCTIONAL-REQUIREMENTS objects the
733
+ requirement presupposes, i.e. whose behavior has to exist before its own
734
+ makes sense (e.g. replying to chat messages presupposes chat messages),
735
+ so that dropping or deferring a requirement reveals what falls with it;
736
+ omitted for a requirement presupposing no other one.
737
+ value: list([[FR.REQUIREMENT:*]])
738
+ optional: true
739
+ acyclic: true
700
740
  - name: PREMISES
701
741
  desc: >
702
742
  Comma-separated references to the SOLUTION-PREMISES objects the
@@ -748,6 +788,8 @@
748
788
  exception the lint warning cannot tell apart) and its hub diagram shows what
749
789
  answers it.
750
790
  optional: true
791
+ format:
792
+ type: compact
751
793
  referenced:
752
794
  - "[[TACTIC:*]]"
753
795
  - "[[DECISION:*]]"
@@ -1145,7 +1187,7 @@
1145
1187
  center: self
1146
1188
  nodes: "[[USE-CASE:*]], [[ROLE:*]], [[PERSONA:*]], [[STEP:*]], [[ACTIVITY:*]],
1147
1189
  [[FR.REQUIREMENT:*]], [[RULE:*]], [[DM.ENTITY:*]], [[TRANSITION:*]],
1148
- [[PERMISSION:*]], [[PRINCIPLE:*]], [[STORYBOARD:*]], [[CV.ENTITY:*]],
1190
+ [[PERMISSION:*]], [[IC.PRINCIPLE:*]], [[STORYBOARD:*]], [[CV.ENTITY:*]],
1149
1191
  [[TEST-CASE:*]]"
1150
1192
  labeled: true
1151
1193
  qualified: true
@@ -2230,7 +2272,7 @@
2230
2272
  optional: true
2231
2273
  diagram:
2232
2274
  type: grid
2233
- nodes: "[[PRINCIPLE:*]]"
2275
+ nodes: "[[IC.PRINCIPLE:*]]"
2234
2276
  properties:
2235
2277
  - CATEGORY
2236
2278
  config:
@@ -2246,8 +2288,10 @@
2246
2288
  solution, plus a 1-sentence rationale ("why"). A principle is solution-wide and
2247
2289
  independent of any particular screen or flow (a structure recurring within one flow
2248
2290
  is a Dialog Pattern instead), decides between design alternatives (the alternative
2249
- it rejects is its `TRADE-OFF`), and is not verifiable by a metric (a measurable
2250
- quality bound is a Non-Functional Requirement instead).
2291
+ it rejects is its `TRADE-OFF`), is not verifiable by a metric (a measurable
2292
+ quality bound is a Non-Functional Requirement instead), and governs the user's
2293
+ experience (a principle governing the architecture is an Architecture Tenets
2294
+ principle instead).
2251
2295
  optional: true
2252
2296
  referenced:
2253
2297
  - "[[DIALOG-PATTERN:*]]"
@@ -2256,7 +2300,7 @@
2256
2300
  diagram:
2257
2301
  type: hub
2258
2302
  center: self
2259
- nodes: "[[PRINCIPLE:*]], [[PERSONA:*]], [[STEP:*]], [[USE-CASE:*]], [[CONVENTION:*]],
2303
+ nodes: "[[IC.PRINCIPLE:*]], [[PERSONA:*]], [[STEP:*]], [[USE-CASE:*]], [[CONVENTION:*]],
2260
2304
  [[DIALOG-PATTERN:*]], [[ELEMENT:*]], [[DECISION:*]]"
2261
2305
  labeled: true
2262
2306
  qualified: true
@@ -2354,7 +2398,7 @@
2354
2398
  diagram:
2355
2399
  type: hub
2356
2400
  center: self
2357
- nodes: "[[CONVENTION:*]], [[PERSONA:*]], [[PRINCIPLE:*]], [[TERM:*]], [[DECISION:*]]"
2401
+ nodes: "[[CONVENTION:*]], [[PERSONA:*]], [[IC.PRINCIPLE:*]], [[TERM:*]], [[DECISION:*]]"
2358
2402
  labeled: true
2359
2403
  qualified: true
2360
2404
  config:
@@ -2383,7 +2427,7 @@
2383
2427
  Comma-separated references to the INTERACTION-CONCEPT objects the convention
2384
2428
  supports in wording, so that a convention is grounded in the interaction
2385
2429
  philosophy rather than in taste alone.
2386
- value: list([[PRINCIPLE:*]])
2430
+ value: list([[IC.PRINCIPLE:*]])
2387
2431
  optional: true
2388
2432
  - name: TERMS
2389
2433
  desc: >
@@ -2438,7 +2482,7 @@
2438
2482
  diagram:
2439
2483
  type: hub
2440
2484
  center: self
2441
- nodes: "[[DIALOG-PATTERN:*]], [[PRINCIPLE:*]], [[STORYBOARD:*]], [[DECISION:*]]"
2485
+ nodes: "[[DIALOG-PATTERN:*]], [[IC.PRINCIPLE:*]], [[STORYBOARD:*]], [[DECISION:*]]"
2442
2486
  deep: true
2443
2487
  labeled: true
2444
2488
  qualified: true
@@ -2475,7 +2519,7 @@
2475
2519
  Comma-separated references to the INTERACTION-CONCEPT objects the pattern
2476
2520
  embodies, so that every principle is shown to be honored by at least one
2477
2521
  pattern rather than merely declared.
2478
- value: list([[PRINCIPLE:*]])
2522
+ value: list([[IC.PRINCIPLE:*]])
2479
2523
  optional: true
2480
2524
  - name: USES
2481
2525
  desc: >
@@ -2644,7 +2688,7 @@
2644
2688
  diagram:
2645
2689
  type: hub
2646
2690
  center: self
2647
- nodes: "[[ELEMENT:*]], [[PERSONA:*]], [[PRINCIPLE:*]], [[MOCKUP:*]]"
2691
+ nodes: "[[ELEMENT:*]], [[PERSONA:*]], [[IC.PRINCIPLE:*]], [[MOCKUP:*]]"
2648
2692
  labeled: true
2649
2693
  qualified: true
2650
2694
  config:
@@ -2674,7 +2718,7 @@
2674
2718
  Comma-separated references to the INTERACTION-CONCEPT objects the element
2675
2719
  supports in appearance, so that an element is grounded in the interaction
2676
2720
  philosophy rather than in taste alone.
2677
- value: list([[PRINCIPLE:*]])
2721
+ value: list([[IC.PRINCIPLE:*]])
2678
2722
  optional: true
2679
2723
  - name: SOURCE
2680
2724
  desc: >
@@ -2734,10 +2778,218 @@
2734
2778
  the design tool or a screenshot of an already existing user interface, so
2735
2779
  that the look is seen rather than only read.
2736
2780
 
2781
+ - kind: ARCH
2782
+ name: Architecture Tenets
2783
+ id: AT
2784
+ file: 22-ARCH-AT-Architecture-Tenets.md
2785
+ desc: >
2786
+ The architecture philosophy of the solution, stated as the few overarching maxims and the
2787
+ standing principles derived from them, which every pattern, view, tactic, decision, and
2788
+ aspect of the architecture has to obey, while the reusable structures belong to the
2789
+ Architecture Patterns and the concrete ones to the views following them. The maxims are listed in decreasing precedence, so that whenever two maxims conflict
2790
+ in a particular design decision, the earlier one wins, and a principle conflict is settled
2791
+ by the precedence of the maxims the principles derive from.
2792
+
2793
+ The tenets are prescriptive and reusable, not verifiable and not decided once: a quality
2794
+ bound verifiable by a metric is a Non-Functional Requirement, the mechanism achieving a
2795
+ quality is a Quality Perspectives tactic, the rule about the source structure and process
2796
+ is a Development Aspects aspect, the one-off trade-off between genuine alternatives is a
2797
+ Design Decisions decision (which applies the tenets through `GUIDED-BY`), and the
2798
+ principle governing the user's experience is an Interaction Concept principle.
2799
+ optional: true
2800
+ refs: >
2801
+ - The Open Group: TOGAF Standard, 10th ed.: Architecture Principles (2022),
2802
+ https://pubs.opengroup.org/togaf-standard/adm-techniques/chap02.html
2803
+ - Greefhorst/Proper: Architecture Principles: The Cornerstones of Enterprise Architecture (2011),
2804
+ https://link.springer.com/book/10.1007/978-3-642-20279-7
2805
+ - Starke/Hruschka: arc42 Template: Solution Strategy (2005),
2806
+ https://arc42.org/overview
2807
+ diagram:
2808
+ type: grid
2809
+ nodes: "[[MAXIM:*]], [[AT.PRINCIPLE:*]]"
2810
+ config:
2811
+ size-node-width-max: 440
2812
+ grid-columns-max: 4
2813
+ children:
2814
+ - kind: MAXIM
2815
+ desc: >
2816
+ A single architecture maxim, named with a short (2-5 word) preference or imperative
2817
+ (e.g. `Simplicity over Flexibility`, `Buy before Build`, `Own the Data`) and
2818
+ described in a concise (1-3 sentence) paragraph by how it guides the architecture
2819
+ of the solution as a whole, plus a 1-sentence rationale ("why"). A solution has only
2820
+ a few (3-7) maxims: a maxim is solution-wide and independent of any particular view
2821
+ or element (a rule bound to a structure is a principle instead), decides between
2822
+ design alternatives (the subordinated side usually named by its `X over Y` form),
2823
+ and is not verifiable by a metric (a measurable quality bound is a Non-Functional
2824
+ Requirement instead).
2825
+ optional: true
2826
+ format:
2827
+ type: compact
2828
+ diagram:
2829
+ type: hub
2830
+ center: self
2831
+ nodes: "[[MAXIM:*]], [[AT.PRINCIPLE:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
2832
+ [[TACTIC:*]], [[DECISION:*]], [[ASPECT:*]]"
2833
+ labeled: true
2834
+ qualified: true
2835
+ config:
2836
+ size-node-width-max: 440
2837
+ props:
2838
+ - name: DRIVEN-BY
2839
+ desc: >
2840
+ Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS or
2841
+ SOLUTION-PREMISES objects the maxim answers (e.g. the maintainability
2842
+ requirement, the small-team premise), so that a maxim is grounded in the
2843
+ forces on the solution rather than in taste alone; omitted for a maxim
2844
+ rooted in the Solution Vision alone.
2845
+ value: list([[NR.*]], [[PREMISE:*]])
2846
+ optional: true
2847
+ - kind: PRINCIPLE
2848
+ desc: >
2849
+ A single architecture principle, named with a short (2-5 word) summary (e.g.
2850
+ `Stateless Services`, `One Owner per Entity`, `Async between Contexts`) and
2851
+ described in a concise (1-3 sentence) paragraph as the standing rule the
2852
+ architecture follows whenever its concern arises, stated with `MUST`/`MUST NOT`
2853
+ or `SHOULD`/`SHOULD NOT`, plus a 1-sentence rationale ("why"). A principle is
2854
+ bound to a particular structure of the architecture (a rule independent of any
2855
+ structure is a maxim instead), reusable across many decisions (a trade-off made
2856
+ once between genuine alternatives is a Design Decisions decision instead), names
2857
+ no mechanism and no product (the mechanism is a Quality
2858
+ Perspectives tactic, the product a Technology Stack component), and governs the
2859
+ architecture, not the source process (a Development Aspects aspect), the code (a
2860
+ Code Patterns pattern), or the user's experience (an Interaction Concept
2861
+ principle).
2862
+ optional: true
2863
+ format:
2864
+ type: compact
2865
+ diagram:
2866
+ type: hub
2867
+ center: self
2868
+ nodes: "[[MAXIM:*]], [[AT.PRINCIPLE:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
2869
+ [[TACTIC:*]], [[DECISION:*]], [[ASPECT:*]]"
2870
+ labeled: true
2871
+ qualified: true
2872
+ config:
2873
+ size-node-width-max: 440
2874
+ props:
2875
+ - name: MAXIMS
2876
+ desc: >
2877
+ Comma-separated references to the MAXIM objects the principle
2878
+ concretizes (e.g. a `Stateless Services` principle concretizing a
2879
+ `Scale Out over Scale Up` maxim), so that the principles form a hierarchy
2880
+ below the maxims rather than a flat catalogue; omitted for a principle
2881
+ standing on its own forces alone.
2882
+ value: list([[MAXIM:*]])
2883
+ optional: true
2884
+ - name: DRIVEN-BY
2885
+ desc: >
2886
+ Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS or
2887
+ SOLUTION-PREMISES objects the principle answers beyond the maxims it
2888
+ concretizes (e.g. the availability requirement, the hosting constraint);
2889
+ omitted for a principle grounded in its maxims alone.
2890
+ value: list([[NR.*]], [[PREMISE:*]])
2891
+ optional: true
2892
+ - name: IMPLICATIONS
2893
+ desc: >
2894
+ What following the principle obliges the architecture to, stated as a 1-2
2895
+ sentence description of the consequences for the elements it governs
2896
+ (e.g. `session state lives in the shared store, so every component
2897
+ instance is replaceable at any time`), as opposed to the rationale which
2898
+ states why the principle is worth these consequences; omitted when nothing
2899
+ non-obvious follows from the principle.
2900
+ optional: true
2901
+
2902
+ - kind: ARCH
2903
+ name: Architecture Patterns
2904
+ id: AP
2905
+ file: 23-ARCH-AP-Architecture-Patterns.md
2906
+ desc: >
2907
+ The reusable structural solutions the architecture of the solution follows, each a named
2908
+ pattern of the literature or of the organization (e.g. hexagonal architecture,
2909
+ transactional outbox, backend for frontend) applied to the solution as a whole, which the
2910
+ views following them realize, the tactics build upon, the decisions choose, and the code
2911
+ patterns code. The artifact completes the guidance of the architecture: the Architecture
2912
+ Tenets state what the architecture values and obeys, the patterns state the structures it
2913
+ takes to do so.
2914
+
2915
+ A pattern names a structure, nothing else: the mechanism achieving one quality attribute
2916
+ is a Quality Perspectives tactic (which may be built from patterns), the one-off trade-off
2917
+ choosing a pattern over its alternatives is a Design Decisions decision, the coded form of
2918
+ a pattern is a Code Patterns pattern shown as a listing, and a structure of the user
2919
+ interface is a Dialog Patterns pattern.
2920
+ optional: true
2921
+ refs: >
2922
+ - Buschmann et al.: Pattern-Oriented Software Architecture, Vol. 1: A System of Patterns (1996),
2923
+ https://www.wiley.com/en-us/Pattern+Oriented+Software+Architecture%2C+Volume+1%2C+A+System+of+Patterns-p-9780471958697
2924
+ - Fowler: Patterns of Enterprise Application Architecture (2002),
2925
+ https://martinfowler.com/books/eaa.html
2926
+ - Hohpe/Woolf: Enterprise Integration Patterns (2003),
2927
+ https://www.enterpriseintegrationpatterns.com/
2928
+ - Richardson: Microservices Patterns (2018),
2929
+ https://microservices.io/patterns/
2930
+ diagram:
2931
+ type: grid
2932
+ nodes: "[[PATTERN:*]]"
2933
+ config:
2934
+ size-node-width-max: 440
2935
+ grid-columns-max: 4
2936
+ children:
2937
+ - kind: PATTERN
2938
+ desc: >
2939
+ A single architecture pattern, named with its established short (2-5 word) name
2940
+ (e.g. `Hexagonal Architecture`, `Transactional Outbox`, `Backend for Frontend`)
2941
+ and described in a concise (1-3 sentence) paragraph by the structure the pattern
2942
+ prescribes and the problem it solves in the solution, plus a 1-sentence rationale
2943
+ ("why") for adopting it. A pattern is a structure reusable beyond one quality
2944
+ attribute (a mechanism for one quality is a Quality Perspectives tactic instead)
2945
+ and beyond one decision (a trade-off made once is a Design Decisions decision
2946
+ instead), applies the Architecture Tenets rather than restating them, and is
2947
+ realized by the elements of the views following it, which reference it, so its
2948
+ hub diagram shows where it took effect.
2949
+ optional: true
2950
+ format:
2951
+ type: compact
2952
+ diagram:
2953
+ type: hub
2954
+ center: self
2955
+ nodes: "[[PATTERN:*]], [[AT.PRINCIPLE:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
2956
+ [[FV.COMPONENT:*]], [[TACTIC:*]], [[DECISION:*]], [[CODE-PATTERN:*]]"
2957
+ labeled: true
2958
+ qualified: true
2959
+ config:
2960
+ size-node-width-max: 440
2961
+ props:
2962
+ - name: PRINCIPLES
2963
+ desc: >
2964
+ Comma-separated references to the ARCHITECTURE-TENETS principles the
2965
+ pattern applies (e.g. a `Transactional Outbox` applying an `Async between
2966
+ Contexts` principle), so that a pattern is adopted for a stated stance of
2967
+ the architecture rather than for its popularity; omitted for a pattern
2968
+ applying no modeled principle.
2969
+ value: list([[AT.PRINCIPLE:*]])
2970
+ optional: true
2971
+ - name: DRIVEN-BY
2972
+ desc: >
2973
+ Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS or
2974
+ SOLUTION-PREMISES objects the pattern answers beyond the principles it
2975
+ applies (e.g. the scalability requirement, the hosting constraint); omitted
2976
+ for a pattern grounded in its principles alone.
2977
+ value: list([[NR.*]], [[PREMISE:*]])
2978
+ optional: true
2979
+ - name: USES
2980
+ desc: >
2981
+ Comma-separated references to the smaller ARCHITECTURE-PATTERNS objects
2982
+ the pattern is composed of (e.g. a `Saga` using a `Transactional Outbox`
2983
+ for its steps), so that the patterns form a language of related structures
2984
+ rather than a flat catalogue.
2985
+ value: list([[PATTERN:*]])
2986
+ optional: true
2987
+ acyclic: true
2988
+
2737
2989
  - kind: ARCH
2738
2990
  name: Context View
2739
2991
  id: CV
2740
- file: 22-ARCH-CV-Context-View.md
2992
+ file: 24-ARCH-CV-Context-View.md
2741
2993
  desc: >
2742
2994
  The relationships, dependencies, and interactions between the solution and its environment,
2743
2995
  defining the system's boundary by enumerating the external entities sitting at it. The
@@ -2869,7 +3121,7 @@
2869
3121
  - kind: ARCH
2870
3122
  name: Functionality View
2871
3123
  id: FV
2872
- file: 23-ARCH-FV-Functionality-View.md
3124
+ file: 25-ARCH-FV-Functionality-View.md
2873
3125
  desc: >
2874
3126
  The functional components of the solution, their responsibilities, interfaces, and primary
2875
3127
  interactions, describing *how* the solution's runtime elements are structured and which
@@ -2908,9 +3160,9 @@
2908
3160
  diagram:
2909
3161
  type: hub
2910
3162
  center: self
2911
- nodes: "[[FV.COMPONENT:*]], [[FR.REQUIREMENT:*]], [[INTERFACE:*]], [[DM.ENTITY:*]],
2912
- [[UNIT:*]], [[NODE:*]], [[CONCERN:*]], [[TACTIC:*]], [[DECISION:*]],
2913
- [[CODE-PATTERN:*]]"
3163
+ nodes: "[[FV.COMPONENT:*]], [[FR.REQUIREMENT:*]], [[PATTERN:*]], [[INTERFACE:*]],
3164
+ [[DM.ENTITY:*]], [[UNIT:*]], [[NODE:*]], [[CONCERN:*]], [[TACTIC:*]],
3165
+ [[DECISION:*]], [[CODE-PATTERN:*]]"
2914
3166
  labeled: true
2915
3167
  qualified: true
2916
3168
  properties:
@@ -2948,6 +3200,14 @@
2948
3200
  that every Functional Requirement is owned by at least one component.
2949
3201
  value: list([[FR.*]])
2950
3202
  optional: true
3203
+ - name: PATTERNS
3204
+ desc: >
3205
+ Comma-separated references to the ARCHITECTURE-PATTERNS objects the
3206
+ structure of the component follows (e.g. the service shaped by a
3207
+ `Hexagonal Architecture`, the publisher keeping a `Transactional Outbox`);
3208
+ omitted for a component following no modeled pattern.
3209
+ value: list([[PATTERN:*]])
3210
+ optional: true
2951
3211
  - name: OWNS
2952
3212
  desc: >
2953
3213
  Comma-separated references to the DATA-MODEL entities the component owns,
@@ -2986,7 +3246,7 @@
2986
3246
  - kind: ARCH
2987
3247
  name: Technology Stack
2988
3248
  id: TS
2989
- file: 24-ARCH-TS-Technology-Stack.md
3249
+ file: 26-ARCH-TS-Technology-Stack.md
2990
3250
  desc: >
2991
3251
  The concrete technology products the solution is built upon, organized by tier and lifecycle
2992
3252
  phase, recording for each component its chosen product, its purpose, and the alternatives
@@ -3347,7 +3607,7 @@
3347
3607
  - kind: ARCH
3348
3608
  name: Development Aspects
3349
3609
  id: DA
3350
- file: 25-ARCH-DA-Development-Aspects.md
3610
+ file: 27-ARCH-DA-Development-Aspects.md
3351
3611
  desc: >
3352
3612
  The architecture supporting the software development process, defining the module
3353
3613
  organization, build approach, and codeline conventions. The artifact is absent when the
@@ -3379,18 +3639,20 @@
3379
3639
  states the product choice), does not restate the runtime structure (a Functionality
3380
3640
  View `Module` or `Subsystem` groups the logic), does not cover production
3381
3641
  procedures (an Operations View concern does), does not prescribe how a concern is
3382
- coded (a Code Patterns pattern shows that as a listing), and the trade-off that
3642
+ coded (a Code Patterns pattern shows that as a listing), the tenet the rule
3643
+ concretizes is an Architecture Tenets maxim or principle referenced through
3644
+ `GUIDED-BY`, and the trade-off that
3383
3645
  produced a rule is a Design Decisions decision referencing the aspect through
3384
3646
  `AFFECTS`, while the quality the rule protects (usually a `Maintainability`
3385
3647
  requirement) is
3386
3648
  addressed by a Quality Perspectives tactic referencing the aspect through
3387
- `AFFECTS`, too, so the hub diagram of an aspect shows the decision and the tactic
3388
- behind it.
3649
+ `AFFECTS`, too, so the hub diagram of an aspect shows the tenet, the decision, and
3650
+ the tactic behind it.
3389
3651
  optional: true
3390
3652
  diagram:
3391
3653
  type: hub
3392
3654
  center: self
3393
- nodes: "[[ASPECT:*]], [[TACTIC:*]], [[DECISION:*]]"
3655
+ nodes: "[[ASPECT:*]], [[MAXIM:*]], [[AT.PRINCIPLE:*]], [[TACTIC:*]], [[DECISION:*]]"
3394
3656
  labeled: true
3395
3657
  qualified: true
3396
3658
  properties:
@@ -3408,11 +3670,19 @@
3408
3670
  standards and conventions), `Testing` (test conventions, layout, and
3409
3671
  coverage rules), or `Tooling` (development tools and automation).
3410
3672
  value: enum(Structure,Build,Dependency,Codeline,Standardization,Testing,Tooling)
3673
+ - name: GUIDED-BY
3674
+ desc: >
3675
+ Comma-separated references to the ARCHITECTURE-TENETS objects the aspect
3676
+ concretizes for the source structure and process (e.g. the module
3677
+ layering following a `Dependencies Point Inward` principle); omitted for
3678
+ an aspect concretizing no modeled tenet.
3679
+ value: list([[MAXIM:*]], [[AT.PRINCIPLE:*]])
3680
+ optional: true
3411
3681
 
3412
3682
  - kind: ARCH
3413
3683
  name: Concurrency View
3414
3684
  id: CO
3415
- file: 26-ARCH-CO-Concurrency-View.md
3685
+ file: 28-ARCH-CO-Concurrency-View.md
3416
3686
  desc: >
3417
3687
  The concurrency structure of the solution, mapping functional components to processes and
3418
3688
  threads, and defining how they coordinate and communicate. The artifact is absent when the
@@ -3507,7 +3777,7 @@
3507
3777
  - kind: ARCH
3508
3778
  name: Deployment View
3509
3779
  id: DV
3510
- file: 27-ARCH-DV-Deployment-View.md
3780
+ file: 29-ARCH-DV-Deployment-View.md
3511
3781
  desc: >
3512
3782
  The environment into which the solution is deployed, partitioning it into tiers and mapping
3513
3783
  software elements to the runtime platform, hardware, and network topology.
@@ -3762,7 +4032,7 @@
3762
4032
  - kind: ARCH
3763
4033
  name: Operations View
3764
4034
  id: OV
3765
- file: 28-ARCH-OV-Operations-View.md
4035
+ file: 30-ARCH-OV-Operations-View.md
3766
4036
  desc: >
3767
4037
  The way the solution is operated, administered, and supported in production, defining the
3768
4038
  standing procedures by which the operating organization installs, configures, migrates,
@@ -3877,7 +4147,7 @@
3877
4147
  - kind: ARCH
3878
4148
  name: Quality Perspectives
3879
4149
  id: QP
3880
- file: 29-ARCH-QP-Quality-Perspectives.md
4150
+ file: 31-ARCH-QP-Quality-Perspectives.md
3881
4151
  desc: >
3882
4152
  How the Non-Functional Requirements (NR) are addressed by the architecture, through the
3883
4153
  tactics built into the solution across the views.
@@ -3911,7 +4181,11 @@
3911
4181
  mechanism has to meet is the `METRIC` of the addressed Non-Functional Requirement
3912
4182
  and is not restated, the production procedure performed against the mechanism
3913
4183
  (e.g. scaling out, restoring) is an Operations View concern referenced through
3914
- `OPERATED-BY`, the trade-off that chose the mechanism over alternatives is a
4184
+ `OPERATED-BY`, the tenet the mechanism follows is an Architecture Tenets maxim or
4185
+ principle referenced through `GUIDED-BY`, the structure it is built from is an
4186
+ Architecture Patterns pattern referenced through `PATTERNS`, the trade-off that
4187
+ chose the mechanism
4188
+ over alternatives is a
3915
4189
  Design Decisions decision referencing the tactic through `DECIDES`, the product
3916
4190
  realizing the mechanism is a Technology Stack component referenced through
3917
4191
  `TOOLS`, the developer-facing rule about the source structure is an aspect of the
@@ -3927,9 +4201,10 @@
3927
4201
  diagram:
3928
4202
  type: hub
3929
4203
  center: self
3930
- nodes: "[[TACTIC:*]], [[NR.REQUIREMENT:*]], [[FV.COMPONENT:*]], [[UNIT:*]],
3931
- [[ASPECT:*]], [[NODE:*]], [[DM.ENTITY:*]], [[CONCERN:*]], [[DECISION:*]],
3932
- [[TS.TIER:*.COMPONENT:*]], [[CODE-PATTERN:*]], [[TEST-CASE:*]]"
4204
+ nodes: "[[TACTIC:*]], [[NR.REQUIREMENT:*]], [[MAXIM:*]], [[AT.PRINCIPLE:*]],
4205
+ [[PATTERN:*]], [[FV.COMPONENT:*]], [[UNIT:*]], [[ASPECT:*]], [[NODE:*]],
4206
+ [[DM.ENTITY:*]], [[CONCERN:*]], [[DECISION:*]], [[TS.TIER:*.COMPONENT:*]],
4207
+ [[CODE-PATTERN:*]], [[TEST-CASE:*]]"
3933
4208
  labeled: true
3934
4209
  qualified: true
3935
4210
  properties:
@@ -3959,6 +4234,22 @@
3959
4234
  Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS objects the
3960
4235
  tactic addresses.
3961
4236
  value: list([[NR.*]])
4237
+ - name: GUIDED-BY
4238
+ desc: >
4239
+ Comma-separated references to the ARCHITECTURE-TENETS objects the
4240
+ mechanism of the tactic follows (e.g. the stateless replication following
4241
+ a `Stateless Services` principle); omitted for a tactic following no
4242
+ modeled tenet.
4243
+ value: list([[MAXIM:*]], [[AT.PRINCIPLE:*]])
4244
+ optional: true
4245
+ - name: PATTERNS
4246
+ desc: >
4247
+ Comma-separated references to the ARCHITECTURE-PATTERNS objects the
4248
+ mechanism of the tactic is built from (e.g. the failover built on a
4249
+ `Circuit Breaker`), while `MECHANISM` states the mechanism itself; omitted
4250
+ for a tactic built from no modeled pattern.
4251
+ value: list([[PATTERN:*]])
4252
+ optional: true
3962
4253
  - name: MECHANISM
3963
4254
  desc: >
3964
4255
  The design mechanism through which the tactic is applied to achieve the
@@ -4001,7 +4292,7 @@
4001
4292
  - kind: ARCH
4002
4293
  name: Design Decisions
4003
4294
  id: DD
4004
- file: 30-ARCH-DD-Design-Decisions.md
4295
+ file: 32-ARCH-DD-Design-Decisions.md
4005
4296
  desc: >
4006
4297
  The major decisions related to the solution design, each recording the forces at play, the
4007
4298
  chosen response, and the reasoning that justifies it. The artifact is the last
@@ -4068,7 +4359,10 @@
4068
4359
  A constraint itself is not a decision: a compliance obligation, a hosting mandate,
4069
4360
  or a partner-imposed threshold is a Non-Functional Requirement (of category
4070
4361
  `Compliance`, `Constraint`, or the affected quality), and the decision is the
4071
- response to it, referencing it through `DRIVEN-BY`.
4362
+ response to it, referencing it through `DRIVEN-BY`. A standing rule is not a
4363
+ decision either: a maxim or principle reusable across many decisions is an
4364
+ Architecture Tenets object, and the decision applies it, referencing it through
4365
+ `GUIDED-BY`.
4072
4366
 
4073
4367
  `WHEN`, `WHAT`, and `WHY` are each just a single paragraph of concise and brief
4074
4368
  prose text, usually comprised of just 1 to 3 sentences. The value of a decision is
@@ -4089,11 +4383,12 @@
4089
4383
  diagram:
4090
4384
  type: hub
4091
4385
  center: self
4092
- nodes: "[[DECISION:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]], [[DM.ENTITY:*]],
4093
- [[LIFECYCLE:*]], [[ROLE:*]], [[INTERFACE:*]], [[TYPE:*]], [[ENDPOINT:*]],
4094
- [[PRINCIPLE:*]], [[CONVENTION:*]], [[DIALOG-PATTERN:*]], [[STORYBOARD:*]],
4095
- [[ELEMENT:*]], [[CV.ENTITY:*]], [[FV.COMPONENT:*]], [[UNIT:*]], [[ASPECT:*]],
4096
- [[DV.TIER:*]], [[AREA:*]], [[NODE:*]], [[NETWORK:*]], [[TACTIC:*]],
4386
+ nodes: "[[DECISION:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]], [[MAXIM:*]],
4387
+ [[AT.PRINCIPLE:*]], [[PATTERN:*]], [[DM.ENTITY:*]], [[LIFECYCLE:*]], [[ROLE:*]],
4388
+ [[INTERFACE:*]], [[TYPE:*]], [[ENDPOINT:*]], [[IC.PRINCIPLE:*]],
4389
+ [[CONVENTION:*]], [[DIALOG-PATTERN:*]], [[STORYBOARD:*]], [[ELEMENT:*]],
4390
+ [[CV.ENTITY:*]], [[FV.COMPONENT:*]], [[UNIT:*]], [[ASPECT:*]], [[DV.TIER:*]],
4391
+ [[AREA:*]], [[NODE:*]], [[NETWORK:*]], [[TACTIC:*]],
4097
4392
  [[TS.TIER:*.COMPONENT:*]], [[CODE-PATTERN:*]]"
4098
4393
  labeled: true
4099
4394
  qualified: true
@@ -4130,6 +4425,15 @@
4130
4425
  and only exceptionally a premise alone, and a decision finding no
4131
4426
  requirement to name reveals a missing one rather than a needless reference.
4132
4427
  value: list([[NR.*]], [[PREMISE:*]])
4428
+ - name: GUIDED-BY
4429
+ desc: >
4430
+ Comma-separated references to the ARCHITECTURE-TENETS objects the decision
4431
+ applies (e.g. the `Buy before Build` maxim settling the choice of a managed
4432
+ service, the `Async between Contexts` principle settling the integration
4433
+ style), anchoring the principles the rationale `WHY` rests on; omitted for
4434
+ a decision applying no modeled tenet.
4435
+ value: list([[MAXIM:*]], [[AT.PRINCIPLE:*]])
4436
+ optional: true
4133
4437
  - name: AFFECTS
4134
4438
  desc: >
4135
4439
  Comma-separated references to the objects of the DATA, APIS, UXUI, or ARCH
@@ -4141,18 +4445,19 @@
4141
4445
  chosen over a native one, the components split, the external system
4142
4446
  integrated); omitted for a decision shaping no modeled element.
4143
4447
  value: list([[DM.ENTITY:*]], [[LIFECYCLE:*]], [[ROLE:*]], [[INTERFACE:*]],
4144
- [[TYPE:*]], [[ENDPOINT:*]], [[PRINCIPLE:*]], [[CONVENTION:*]],
4448
+ [[TYPE:*]], [[ENDPOINT:*]], [[IC.PRINCIPLE:*]], [[CONVENTION:*]],
4145
4449
  [[DIALOG-PATTERN:*]], [[STORYBOARD:*]], [[ELEMENT:*]], [[CV.ENTITY:*]],
4146
4450
  [[FV.COMPONENT:*]], [[UNIT:*]], [[ASPECT:*]], [[DV.TIER:*]], [[AREA:*]],
4147
4451
  [[NODE:*]], [[NETWORK:*]])
4148
4452
  optional: true
4149
4453
  - name: DECIDES
4150
4454
  desc: >
4151
- Comma-separated references to the QUALITY-PERSPECTIVES tactics or
4152
- TECHNOLOGY-STACK components the decision chose over their alternatives,
4153
- i.e. the mechanism or product which exists because of this decision; omitted
4154
- when the decision chose no modeled tactic or product.
4155
- value: list([[TACTIC:*]], [[TS.TIER:*.COMPONENT:*]])
4455
+ Comma-separated references to the ARCHITECTURE-PATTERNS objects,
4456
+ QUALITY-PERSPECTIVES tactics, or TECHNOLOGY-STACK components the decision
4457
+ chose over their alternatives, i.e. the pattern, mechanism, or product
4458
+ which exists because of this decision; omitted when the decision chose no
4459
+ modeled pattern, tactic, or product.
4460
+ value: list([[PATTERN:*]], [[TACTIC:*]], [[TS.TIER:*.COMPONENT:*]])
4156
4461
  optional: true
4157
4462
  - name: ALTERNATIVES
4158
4463
  desc: >
@@ -4242,7 +4547,7 @@
4242
4547
  - kind: ARCH
4243
4548
  name: Code Patterns
4244
4549
  id: CP
4245
- file: 31-ARCH-CP-Code-Patterns.md
4550
+ file: 33-ARCH-CP-Code-Patterns.md
4246
4551
  desc: >
4247
4552
  The implementation patterns the source code of the solution follows, each prescribing how
4248
4553
  one recurring concern (e.g. authorization enforcement, entity persistence, error
@@ -4283,8 +4588,9 @@
4283
4588
  short (typically 10-30 lines) and the prose names what the listing cannot: the
4284
4589
  places the pattern applies and the deviation it rules out (`AVOID`).
4285
4590
 
4286
- A pattern states how a concern is coded, and nothing else: the quality mechanism
4287
- it implements is a Quality Perspectives tactic referenced through `REALIZES`, the
4591
+ A pattern states how a concern is coded, and nothing else: the structure or the
4592
+ quality mechanism it implements is an Architecture Patterns pattern or a Quality
4593
+ Perspectives tactic referenced through `REALIZES`, the
4288
4594
  trade-off that chose its approach over alternatives is a Design Decisions decision
4289
4595
  referenced through `DECIDED-BY` (a pattern weighs no alternatives itself), the
4290
4596
  product it codes against is a Technology Stack component referenced through
@@ -4299,7 +4605,7 @@
4299
4605
  center: self
4300
4606
  nodes: "[[CODE-PATTERN:*]], [[FV.COMPONENT:*]], [[UNIT:*]], [[DM.ENTITY:*]],
4301
4607
  [[ROLE:*]], [[INTERFACE:*]], [[ENDPOINT:*]], [[TS.TIER:*.COMPONENT:*]],
4302
- [[TACTIC:*]], [[DECISION:*]]"
4608
+ [[PATTERN:*]], [[TACTIC:*]], [[DECISION:*]]"
4303
4609
  labeled: true
4304
4610
  qualified: true
4305
4611
  config:
@@ -4317,10 +4623,12 @@
4317
4623
  optional: true
4318
4624
  - name: REALIZES
4319
4625
  desc: >
4320
- Comma-separated references to the QUALITY-PERSPECTIVES tactics the pattern
4321
- is the coded form of (e.g. the token check implementing the access
4322
- security tactic); omitted for a pattern serving no modeled tactic.
4323
- value: list([[TACTIC:*]])
4626
+ Comma-separated references to the ARCHITECTURE-PATTERNS objects or
4627
+ QUALITY-PERSPECTIVES tactics the pattern is the coded form of (e.g. the
4628
+ port interface coding the hexagonal architecture, the token check
4629
+ implementing the access security tactic); omitted for a pattern serving
4630
+ no modeled architecture pattern or tactic.
4631
+ value: list([[PATTERN:*]], [[TACTIC:*]])
4324
4632
  optional: true
4325
4633
  - name: DECIDED-BY
4326
4634
  desc: >
@@ -4355,7 +4663,7 @@
4355
4663
  - kind: TEST
4356
4664
  name: Test Cases
4357
4665
  id: TC
4358
- file: 32-TEST-TC-Test-Cases.md
4666
+ file: 34-TEST-TC-Test-Cases.md
4359
4667
  desc: >
4360
4668
  The verifiable conditions and steps used to confirm that requirements, domain rules, use
4361
4669
  case scenarios, state transitions, and the mechanisms, procedures, and decisions of the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rse/specbook",
3
- "version": "1.4.2",
3
+ "version": "1.5.1",
4
4
  "publishConfig": { "access": "public" },
5
5
  "description": "Markdown-based Specification Format (API, CLI and MCP service)",
6
6
  "license": "Apache-2.0",
@@ -26,7 +26,7 @@
26
26
  "sharp": "0.35.5",
27
27
  "svgo": "4.1.0",
28
28
  "@rse/mrcs": "0.9.2",
29
- "@rse/gradia": "1.4.2",
29
+ "@rse/gradia": "1.4.3",
30
30
  "beautiful-mermaid": "1.1.3",
31
31
  "@d2lang/d2": "0.1.34",
32
32
  "shiki": "4.5.0",
@@ -48,7 +48,7 @@
48
48
  "picomatch": "4.0.7",
49
49
  "es-toolkit": "1.52.0",
50
50
  "fastify": "5.12.5",
51
- "@fastify/websocket": "11.3.3",
51
+ "@fastify/websocket": "11.3.4",
52
52
  "@modelcontextprotocol/sdk": "1.32.1",
53
53
  "zod": "4.6.5"
54
54
  },
@@ -58,12 +58,12 @@
58
58
  "@eslint/js": "10.0.1",
59
59
  "typescript-eslint": "8.71.1",
60
60
  "eslint-plugin-promise": "7.3.0",
61
- "neostandard": "0.14.0-next.1",
61
+ "neostandard": "0.14.0",
62
62
  "globals": "17.13.0",
63
- "eslint-plugin-yml": "3.8.1",
63
+ "eslint-plugin-yml": "3.9.0",
64
64
  "markdownlint": "0.41.1",
65
65
  "markdownlint-cli2": "0.23.3",
66
- "@types/node": "26.6.4",
66
+ "@types/node": "26.6.5",
67
67
  "@types/picomatch": "4.0.3",
68
68
  "@types/subset-font": "2.3.0",
69
69
  "@types/nunjucks": "3.2.6",