@phuc1403/musketeer 0.3.0 → 0.5.0

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.
Files changed (114) hide show
  1. package/README.md +49 -49
  2. package/manifest.json +301 -253
  3. package/package.json +1 -1
  4. package/template/.claude/hooks/block-unsafe-adr-title.cjs +70 -0
  5. package/template/.claude/hooks/init-adr-dir.cjs +110 -0
  6. package/template/.claude/hooks/inject-adr-env.cjs +82 -0
  7. package/template/.claude/hooks/lib/characteristics/checker.cjs +357 -0
  8. package/template/.claude/hooks/sync-adr-toc.cjs +111 -0
  9. package/template/.claude/hooks/validate-characteristics-hook.cjs +66 -0
  10. package/template/.claude/hooks/warn-missing-characteristics.cjs +32 -0
  11. package/template/.claude/skills/adr-writer/SKILL.md +24 -101
  12. package/template/.claude/skills/adr-writer/references/adr-example.md +0 -5
  13. package/template/.claude/skills/adr-writer/references/adr-template.md +0 -12
  14. package/template/.claude/skills/architecture-characteristic-writer/SKILL.md +197 -99
  15. package/template/.claude/skills/architecture-characteristic-writer/assets/worksheet-template.md +18 -29
  16. package/template/.claude/skills/architecture-characteristic-writer/references/characteristics-catalog.md +22 -88
  17. package/template/.claude/skills/architecture-characteristic-writer/scripts/ranking-table.cjs +171 -0
  18. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  19. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.AssemblyInfo.cs +22 -0
  20. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.AssemblyInfoInputs.cache +1 -0
  21. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.GeneratedMSBuildEditorConfig.editorconfig +23 -0
  22. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.GlobalUsings.g.cs +17 -0
  23. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.assets.cache +0 -0
  24. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/__SolutionName__.Api.csproj.nuget.dgspec.json +1536 -0
  25. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/__SolutionName__.Api.csproj.nuget.g.props +16 -0
  26. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/__SolutionName__.Api.csproj.nuget.g.targets +2 -0
  27. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/project.assets.json +559 -0
  28. package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/project.nuget.cache +8 -0
  29. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  30. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.AssemblyInfo.cs +22 -0
  31. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.AssemblyInfoInputs.cache +1 -0
  32. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.GeneratedMSBuildEditorConfig.editorconfig +17 -0
  33. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.GlobalUsings.g.cs +8 -0
  34. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.assets.cache +0 -0
  35. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/__SolutionName__.Application.csproj.nuget.dgspec.json +690 -0
  36. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/__SolutionName__.Application.csproj.nuget.g.props +16 -0
  37. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/__SolutionName__.Application.csproj.nuget.g.targets +2 -0
  38. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/project.assets.json +376 -0
  39. package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/project.nuget.cache +8 -0
  40. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  41. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.AssemblyInfo.cs +22 -0
  42. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.AssemblyInfoInputs.cache +1 -0
  43. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.GeneratedMSBuildEditorConfig.editorconfig +17 -0
  44. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.GlobalUsings.g.cs +8 -0
  45. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.assets.cache +0 -0
  46. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/__SolutionName__.Domain.csproj.nuget.dgspec.json +347 -0
  47. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/__SolutionName__.Domain.csproj.nuget.g.props +16 -0
  48. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/__SolutionName__.Domain.csproj.nuget.g.targets +2 -0
  49. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/project.assets.json +353 -0
  50. package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/project.nuget.cache +8 -0
  51. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  52. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.AssemblyInfo.cs +22 -0
  53. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.AssemblyInfoInputs.cache +1 -0
  54. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.GeneratedMSBuildEditorConfig.editorconfig +17 -0
  55. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.GlobalUsings.g.cs +8 -0
  56. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.assets.cache +0 -0
  57. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.csproj.AssemblyReference.cache +0 -0
  58. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/__SolutionName__.Infrastructure.csproj.nuget.dgspec.json +1047 -0
  59. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/__SolutionName__.Infrastructure.csproj.nuget.g.props +16 -0
  60. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/__SolutionName__.Infrastructure.csproj.nuget.g.targets +7 -0
  61. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/project.assets.json +858 -0
  62. package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/project.nuget.cache +17 -0
  63. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Api.Tests +0 -0
  64. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  65. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.AssemblyInfo.cs +22 -0
  66. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.AssemblyInfoInputs.cache +1 -0
  67. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
  68. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.GlobalUsings.g.cs +9 -0
  69. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.assets.cache +0 -0
  70. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.csproj.AssemblyReference.cache +0 -0
  71. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/__SolutionName__.Api.Tests.csproj.nuget.dgspec.json +1908 -0
  72. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/__SolutionName__.Api.Tests.csproj.nuget.g.props +27 -0
  73. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/__SolutionName__.Api.Tests.csproj.nuget.g.targets +16 -0
  74. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/project.assets.json +3283 -0
  75. package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/project.nuget.cache +60 -0
  76. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Application.Tests +0 -0
  77. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  78. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.AssemblyInfo.cs +22 -0
  79. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.AssemblyInfoInputs.cache +1 -0
  80. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
  81. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.GlobalUsings.g.cs +9 -0
  82. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.assets.cache +0 -0
  83. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.csproj.AssemblyReference.cache +0 -0
  84. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/__SolutionName__.Application.Tests.csproj.nuget.dgspec.json +1055 -0
  85. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/__SolutionName__.Application.Tests.csproj.nuget.g.props +26 -0
  86. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/__SolutionName__.Application.Tests.csproj.nuget.g.targets +11 -0
  87. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/project.assets.json +1662 -0
  88. package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/project.nuget.cache +30 -0
  89. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Domain.Tests +0 -0
  90. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  91. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.AssemblyInfo.cs +22 -0
  92. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.AssemblyInfoInputs.cache +1 -0
  93. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
  94. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.GlobalUsings.g.cs +9 -0
  95. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.assets.cache +0 -0
  96. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.csproj.AssemblyReference.cache +0 -0
  97. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/__SolutionName__.Domain.Tests.csproj.nuget.dgspec.json +712 -0
  98. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/__SolutionName__.Domain.Tests.csproj.nuget.g.props +26 -0
  99. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/__SolutionName__.Domain.Tests.csproj.nuget.g.targets +11 -0
  100. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/project.assets.json +1644 -0
  101. package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/project.nuget.cache +30 -0
  102. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Infrastructure.Tests +0 -0
  103. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
  104. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.AssemblyInfo.cs +22 -0
  105. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.AssemblyInfoInputs.cache +1 -0
  106. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
  107. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.GlobalUsings.g.cs +9 -0
  108. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.assets.cache +0 -0
  109. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.csproj.AssemblyReference.cache +0 -0
  110. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/__SolutionName__.Infrastructure.Tests.csproj.nuget.dgspec.json +1412 -0
  111. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/__SolutionName__.Infrastructure.Tests.csproj.nuget.g.props +26 -0
  112. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/__SolutionName__.Infrastructure.Tests.csproj.nuget.g.targets +13 -0
  113. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/project.assets.json +2130 -0
  114. package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/project.nuget.cache +38 -0
@@ -1,40 +1,29 @@
1
1
  # Architecture Characteristics Worksheet
2
2
 
3
- | Field | Value |
4
- |---|---|
5
- | **System/Project** | {system_name} |
6
- | **Domain/Quantum** | {domain_quantum} |
7
- | **Architect/Team** | {architect_team} |
8
- | **Date** | {date} |
9
- | **Next Review** | {next_review} |
10
-
11
- ---
3
+ Derived from the top 7 of `architecture-characteristics-ranking.md`.
12
4
 
13
- ## Driving Characteristics (up to 7)
5
+ ## Driving Characteristics
14
6
 
15
- <!-- Rationale = WHY the system needs this (business driver / risk), never HOW it's delivered.
16
- No libraries, patterns, components, or tactics (e.g. ports/adapters, load-balancer, caching). -->
7
+ <!-- From the top 7 of the ranking, in ranked order.
8
+ A composite replaces its components only when EVERY component is in the top 7:
9
+ agility = maintainability + testability + deployability
10
+ reliability = availability + testability + data integrity + data consistency + fault tolerance
11
+ Never list a composite and its components together.
12
+ No backfill: fewer than 7 rows is expected once a composite forms.
13
+ Rationale = WHY the system needs this, meaning the business driver or risk.
14
+ Never name the mechanism: no patterns, libraries, components, or tactics. -->
17
15
 
18
- | # | Characteristic | Top 3 | Rationale |
19
- |---|---|---|---|
20
- | 1 | {char1} | {yes/no} | {rationale1} |
21
- | 2 | {char2} | {yes/no} | {rationale2} |
16
+ | # | Characteristic | Rationale |
17
+ |---|---|---|
18
+ | 1 | {char1} | {rationale1} |
19
+ | 2 | {char2} | {rationale2} |
22
20
 
23
21
  ## Implicit Characteristics
24
22
 
25
- Only list implicit characteristics (feasibility, security, maintainability, observability) NOT already in Driving Characteristics. Composites (agility, reliability) can appear in either section.
26
-
27
- <!-- Notes = WHY this is only implicit (e.g. "low stakes — no sensitive data") + residual risk, never what to build. -->
23
+ <!-- The four implicit characteristics are feasibility, security, maintainability, observability.
24
+ List only those NOT in the top 7. A characteristic absorbed into a composite counts as present.
25
+ Notes = why it is only implicit, plus the risk that leaves. Never what to build. -->
28
26
 
29
27
  | Characteristic | Notes |
30
28
  |---|---|
31
- | {implicit1} | {notes} |
32
-
33
- ## Others Considered
34
-
35
- | Characteristic | Reason Not Selected |
36
- |---|---|
37
- | {other1} | {reason1} |
38
- | {other2} | {reason2} |
39
-
40
- ---
29
+ | {implicit1} | {notes1} |
@@ -1,33 +1,29 @@
1
1
  # Architecture Characteristics Catalog
2
2
 
3
- Based on Mark Richards' Architecture Characteristics Worksheet (DeveloperToArchitect.com, March 2024) and "Software Architecture" reference material.
4
-
5
3
  ## Common Architecture Characteristics
6
4
 
7
- | Characteristic | Definition | Related |
8
- |---|---|---|
9
- | **performance** | Time it takes for system to process a business request | a |
10
- | **responsiveness** | Time it takes to get a response to the user | a |
11
- | **availability** | Uptime of a system; usually measured in 9's (e.g., 99.9%) | b |
12
- | **fault tolerance** | When fatal errors occur, other parts of system continue to function | b |
13
- | **scalability** | System capacity and growth over time; as users/requests increase, responsiveness, performance, and error rates remain constant | c |
14
- | **elasticity** | System can expand and respond quickly to unexpected or anticipated extreme loads (e.g., 20 to 250,000 users instantly) | c |
15
- | **data integrity** | Data across the system is correct and there is no data loss | d |
16
- | **data consistency** | Data across the system is in sync and consistent across databases and tables | d |
17
- | **adaptability** | Ease in which system can adapt to changes in environment and functionality | e |
18
- | **extensibility** | Ease in which system can be extended with additional features and functionality | e |
19
- | **concurrency** | Ability to process simultaneous requests, usually in the same order received; implied when scalability and elasticity are supported | |
20
- | **interoperability** | Ability to interface and interact with other systems to complete a business request | |
21
- | **deployability** | Amount of ceremony involved with releasing software, frequency of releases, and overall risk of deployment | |
22
- | **testability** | Ease of and completeness of testing | |
23
- | **abstraction** | Level at which parts of system are isolated from other parts (internal and external interactions) | |
24
- | **workflow** | Ability to manage complex workflows requiring multiple parts (services) to complete a business request | |
25
- | **configurability** | Ability to support multiple configurations, custom on-demand configurations and configuration updates | |
26
- | **recoverability** | Ability to start where it left off in the event of a system crash | |
27
-
28
- **Related pairs (a/b):** Some systems only need one, others may need both.
29
-
30
- ## Implicit Characteristics (Always Considered)
5
+ | Characteristic | Definition |
6
+ |---|---|
7
+ | **performance** | Time it takes for system to process a business request |
8
+ | **responsiveness** | Time it takes to get a response to the user |
9
+ | **availability** | Uptime of a system; usually measured in 9's (e.g., 99.9%) |
10
+ | **fault tolerance** | When fatal errors occur, other parts of system continue to function |
11
+ | **scalability** | System capacity and growth over time; as users/requests increase, responsiveness, performance, and error rates remain constant |
12
+ | **elasticity** | System can expand and respond quickly to unexpected or anticipated extreme loads (e.g., 20 to 250,000 users instantly) |
13
+ | **data integrity** | Data across the system is correct and there is no data loss |
14
+ | **data consistency** | Data across the system is in sync and consistent across databases and tables |
15
+ | **adaptability** | Ease in which system can adapt to changes in environment and functionality |
16
+ | **extensibility** | Ease in which system can be extended with additional features and functionality |
17
+ | **concurrency** | Ability to process simultaneous requests, usually in the same order received; implied when scalability and elasticity are supported |
18
+ | **interoperability** | Ability to interface and interact with other systems to complete a business request |
19
+ | **deployability** | Amount of ceremony involved with releasing software, frequency of releases, and overall risk of deployment |
20
+ | **testability** | Ease of and completeness of testing |
21
+ | **abstraction** | Level at which parts of system are isolated from other parts (internal and external interactions) |
22
+ | **workflow** | Ability to manage complex workflows requiring multiple parts (services) to complete a business request |
23
+ | **configurability** | Ability to support multiple configurations, custom on-demand configurations and configuration updates |
24
+ | **recoverability** | Ability to start where it left off in the event of a system crash |
25
+
26
+ ## Implicit Characteristics
31
27
 
32
28
  | Characteristic | Definition |
33
29
  |---|---|
@@ -36,71 +32,9 @@ Based on Mark Richards' Architecture Characteristics Worksheet (DeveloperToArchi
36
32
  | **maintainability** | Level of effort required to locate and apply changes to the system |
37
33
  | **observability** | Ability to make available and stream metrics such as overall health, uptime, response times, performance, etc. |
38
34
 
39
- Implicit characteristics become **driving** characteristics if they are critical concerns.
40
-
41
35
  ## Composite Architecture Characteristics
42
36
 
43
37
  | Composite | Components |
44
38
  |---|---|
45
39
  | **agility** | maintainability + testability + deployability |
46
40
  | **reliability** | availability + testability + data integrity + data consistency + fault tolerance |
47
-
48
- ## Category Groupings (from reference material)
49
-
50
- ### Process Characteristics
51
- modularity, testability, agility, deployability, decouple-ability, extensibility
52
-
53
- ### Structural Characteristics
54
- security, maintainability, extensibility, portability, localization
55
-
56
- ### Operational Characteristics
57
- scalability, recoverability, robustness, performance, reliability/safety, availability
58
-
59
- ### Cross-cutting Characteristics
60
- security, legal, authentication/authorization, privacy, accessibility, usability
61
-
62
- ## Guiding Questions by Category
63
-
64
- ### Operational
65
- - How many concurrent users are expected? Peak vs average?
66
- - What uptime SLA is required? (99.9%? 99.99%?)
67
- - Is traffic steady or bursty? (e.g., seasonal spikes, flash sales)
68
- - How fast must the system respond? (ms? seconds?)
69
- - What happens if the system goes down? Business impact?
70
-
71
- ### Structural
72
- - How frequently will new features be added?
73
- - How many external systems need integration?
74
- - How large is the development team? Multiple teams?
75
- - How often will the system be deployed?
76
- - Is the codebase expected to grow significantly?
77
-
78
- ### Cross-cutting
79
- - Does the system handle sensitive/personal data?
80
- - Are there compliance requirements? (GDPR, HIPAA, PCI-DSS, SOC2)
81
- - Does it need to work across regions/languages?
82
- - Who are the end users? Technical sophistication?
83
- - Are there legal/regulatory constraints?
84
-
85
- ### Environment & Feasibility
86
- - Startup (agility-first) or enterprise (stability-first)?
87
- - Budget and timeline constraints?
88
- - Team expertise — what technologies are they comfortable with?
89
- - Existing infrastructure that must be leveraged?
90
-
91
- ## Custom Characteristics
92
-
93
- If no existing characteristic fits, create a custom one:
94
- - Name MUST end in `-ility` (e.g., `auditability`, `portability`, `learnability`)
95
- - Provide a clear, one-sentence definition following the pattern: "The ability/ease/level of [what the system can do]"
96
- - Assign to the most appropriate category
97
- - Document why existing characteristics don't cover this concern
98
-
99
- ### Examples of Custom Characteristics
100
- | Characteristic | Definition | Category |
101
- |---|---|---|
102
- | **auditability** | The ability to trace and record all system actions for compliance review | Cross-cutting |
103
- | **portability** | The ease in which the system can be moved to a different environment or platform | Structural |
104
- | **learnability** | The ease in which new developers can understand and contribute to the system | Process |
105
- | **debuggability** | The ease in which issues can be identified and diagnosed in production | Operational |
106
- | **reproducibility** | The ability to consistently reproduce system behavior across environments | Process |
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env node
2
+ // Scaffolds and repairs the architecture-characteristics ranking table.
3
+ //
4
+ // scaffold write a blank ranking holding every catalog characteristic
5
+ // fix renumber the Order column and rebuild every "Above X:" prefix
6
+ // from the row order as it now stands, keeping the justifications
7
+ //
8
+ // Ranking ORDER and justification prose are the architect's work. Everything
9
+ // this script touches — which characteristics appear, the numbering, which row
10
+ // each reason compares against — is mechanical, so no one has to transcribe it.
11
+ //
12
+ // Run `fix` after moving rows. A prefix left naming the wrong row is the usual
13
+ // defect after a reorder, and regenerating them makes it impossible.
14
+
15
+ const fs = require('fs');
16
+ const path = require('path');
17
+
18
+ const {
19
+ loadCatalog,
20
+ normalise,
21
+ locateTable,
22
+ splitCells,
23
+ isSeparator,
24
+ RANKING_HEADER,
25
+ } = require('../../../hooks/lib/characteristics/checker.cjs');
26
+
27
+ const DEFAULT_FILE = 'docs/architecture-characteristics-ranking.md';
28
+
29
+ // The validation hook resolves the ranking against CLAUDE_PROJECT_DIR. Resolve
30
+ // against the same root, or running this from a subdirectory would quietly
31
+ // write a second ranking somewhere the hook never looks at.
32
+ const projectRoot = () => process.env.CLAUDE_PROJECT_DIR || process.cwd();
33
+ const PLACEHOLDER = '{why}';
34
+ const HEADING = '# Architecture Characteristics Ranking';
35
+
36
+ const PREAMBLE = [
37
+ HEADING,
38
+ '',
39
+ 'All characteristics in priority order. The top 7 feed the worksheet in',
40
+ '`architecture-characteristics.md`.',
41
+ '',
42
+ '<!-- Reason = why this row outranks the row directly BELOW it. Comparative, never a description.',
43
+ ' Keep the "Above {next characteristic}:" prefix and replace {why} with the justification.',
44
+ ' Both sides must appear: what this row protects, and what the row below gives up.',
45
+ ' State WHY the system needs it, meaning the business driver or risk.',
46
+ ' Never name the mechanism: no patterns, libraries, components, or tactics.',
47
+ '',
48
+ ' Move rows freely, then run scripts/ranking-table.cjs fix to renumber and',
49
+ ' rebuild every prefix. Do not hand-maintain the numbering or the prefixes. -->',
50
+ '',
51
+ ];
52
+
53
+ const die = (msg) => {
54
+ process.stderr.write(`${msg}\n`);
55
+ process.exit(1);
56
+ };
57
+
58
+ // Builds the three table lines plus data rows for the given ordered names,
59
+ // pairing each row with the justification supplied for it.
60
+ function render(order, justifications) {
61
+ const rows = order.map((name, i) => {
62
+ const last = i === order.length - 1;
63
+ const reason = last ? '—' : `Above ${order[i + 1]}: ${justifications[i] || PLACEHOLDER}`;
64
+ return `| ${i + 1} | ${name} | ${reason} |`;
65
+ });
66
+ return ['| Order | Characteristic | Reason |', '|---|---|---|', ...rows];
67
+ }
68
+
69
+ // Drops an "Above X:" prefix and a lone em dash, leaving the justification the
70
+ // author actually wrote.
71
+ function justificationOf(reason) {
72
+ const text = String(reason).trim();
73
+ if (/^[—-]$/.test(text)) return '';
74
+ const m = text.match(/^above\s+[^:]+:\s*(.*)$/i);
75
+ return (m ? m[1] : text).trim();
76
+ }
77
+
78
+ function scaffold(argv) {
79
+ const out = argv.out || DEFAULT_FILE;
80
+ const target = path.resolve(projectRoot(), out);
81
+
82
+ if (fs.existsSync(target) && !argv.force) {
83
+ die(`${out} already exists. Run fix to repair it, or pass --force to start over.`);
84
+ }
85
+
86
+ const { catalog } = loadCatalog(argv.catalog);
87
+ fs.mkdirSync(path.dirname(target), { recursive: true });
88
+ fs.writeFileSync(target, [...PREAMBLE, ...render(catalog, []), ''].join('\n'), 'utf8');
89
+
90
+ process.stdout.write(
91
+ `Wrote ${out} with ${catalog.length} characteristics in catalog order.\n` +
92
+ 'Reorder the rows, replace every {why}, then run fix.\n'
93
+ );
94
+ }
95
+
96
+ function fix(argv) {
97
+ const file = argv.file || DEFAULT_FILE;
98
+ const target = path.resolve(projectRoot(), file);
99
+
100
+ if (!fs.existsSync(target)) die(`${file} does not exist. Run scaffold first.`);
101
+
102
+ const original = fs.readFileSync(target, 'utf8');
103
+ const eol = original.includes('\r\n') ? '\r\n' : '\n';
104
+ const lines = original.split(/\r?\n/);
105
+
106
+ const bounds = locateTable(lines, RANKING_HEADER);
107
+ if (!bounds) die(`${file} holds no table with a "| Order | Characteristic | Reason |" header row.`);
108
+
109
+ const table = lines.slice(bounds.start, bounds.end);
110
+ const data = table.filter((l) => {
111
+ const c = splitCells(l);
112
+ return c.length >= 3 && !isSeparator(c) && !/^order$/i.test(c[0]);
113
+ });
114
+
115
+ if (!data.length) die(`${file} holds no ranking rows to fix.`);
116
+
117
+ const order = data.map((l) => normalise(splitCells(l)[1]));
118
+ const justifications = data.map((l) => justificationOf(splitCells(l)[2]));
119
+
120
+ const { catalog } = loadCatalog(argv.catalog);
121
+ const unknown = order.filter((n) => !catalog.includes(n));
122
+ if (unknown.length) die(`${file} names characteristics absent from the catalog: ${unknown.join(', ')}`);
123
+
124
+ const rebuilt = render(order, justifications);
125
+ const next = [...lines.slice(0, bounds.start), ...rebuilt, ...lines.slice(bounds.end)];
126
+ const updated = next.join(eol);
127
+
128
+ // Reported whether or not anything moved: a scaffold is already correct and
129
+ // still has every justification left to write.
130
+ const blank = justifications.filter((j, i) => i < justifications.length - 1 && (!j || j === PLACEHOLDER)).length;
131
+ const outstanding = blank ? `${blank} row(s) still need a justification in place of ${PLACEHOLDER}.\n` : '';
132
+
133
+ if (updated === original) {
134
+ process.stdout.write(`${file} is already correct.\n${outstanding}`);
135
+ return;
136
+ }
137
+
138
+ fs.writeFileSync(target, updated, 'utf8');
139
+
140
+ const repaired = data.filter((l, i) => splitCells(l)[2] !== splitCells(rebuilt[i + 2])[2]).length;
141
+ const renumbered = data.filter((l, i) => splitCells(l)[0] !== String(i + 1)).length;
142
+
143
+ process.stdout.write(
144
+ `Fixed ${file}: renumbered ${renumbered} row(s), rebuilt ${repaired} reason(s).\n${outstanding}`
145
+ );
146
+ }
147
+
148
+ function main() {
149
+ const [command, ...rest] = process.argv.slice(2);
150
+ const argv = { force: false };
151
+
152
+ for (let i = 0; i < rest.length; i += 1) {
153
+ const flag = rest[i];
154
+ if (flag === '--force') argv.force = true;
155
+ else if (flag === '--out') argv.out = rest[(i += 1)];
156
+ else if (flag === '--file') argv.file = rest[(i += 1)];
157
+ else if (flag === '--catalog') argv.catalog = rest[(i += 1)];
158
+ else die(`unknown argument: ${flag}`);
159
+ }
160
+
161
+ try {
162
+ if (command === 'scaffold') return scaffold(argv);
163
+ if (command === 'fix') return fix(argv);
164
+ } catch (err) {
165
+ die(err.message);
166
+ }
167
+
168
+ die('usage: ranking-table.cjs scaffold [--out <path>] [--force] | fix [--file <path>]');
169
+ }
170
+
171
+ main();
@@ -0,0 +1,4 @@
1
+ // <autogenerated />
2
+ using System;
3
+ using System.Reflection;
4
+ [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
@@ -0,0 +1,22 @@
1
+ //------------------------------------------------------------------------------
2
+ // <auto-generated>
3
+ // This code was generated by a tool.
4
+ //
5
+ // Changes to this file may cause incorrect behavior and will be lost if
6
+ // the code is regenerated.
7
+ // </auto-generated>
8
+ //------------------------------------------------------------------------------
9
+
10
+ using System;
11
+ using System.Reflection;
12
+
13
+ [assembly: System.Reflection.AssemblyCompanyAttribute("__SolutionName__.Api")]
14
+ [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
15
+ [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
16
+ [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b8b9e4e3c73f140ae7b06d954c63afb26d78c687")]
17
+ [assembly: System.Reflection.AssemblyProductAttribute("__SolutionName__.Api")]
18
+ [assembly: System.Reflection.AssemblyTitleAttribute("__SolutionName__.Api")]
19
+ [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
20
+
21
+ // Generated by the MSBuild WriteCodeFragment class.
22
+
@@ -0,0 +1 @@
1
+ 922649250c3cbe1ea76366976311f3d76bad60fe3f765d7bf9d3d9b685476c9f
@@ -0,0 +1,23 @@
1
+ is_global = true
2
+ build_property.TargetFramework = net10.0
3
+ build_property.TargetFrameworkIdentifier = .NETCoreApp
4
+ build_property.TargetFrameworkVersion = v10.0
5
+ build_property.TargetPlatformMinVersion =
6
+ build_property.UsingMicrosoftNETSdkWeb = true
7
+ build_property.ProjectTypeGuids =
8
+ build_property.InvariantGlobalization =
9
+ build_property.PlatformNeutralAssembly =
10
+ build_property.EnforceExtendedAnalyzerRules =
11
+ build_property._SupportedPlatformList = Linux,macOS,Windows
12
+ build_property.RootNamespace = __SolutionName__.Api
13
+ build_property.RootNamespace = __SolutionName__.Api
14
+ build_property.ProjectDir = C:\Projects2\Personal\musketeer\template\dotnet-scaffold\src\__SolutionName__.Api\
15
+ build_property.EnableComHosting =
16
+ build_property.EnableGeneratedComInterfaceComImportInterop =
17
+ build_property.RazorLangVersion = 9.0
18
+ build_property.SupportLocalizedComponentNames =
19
+ build_property.GenerateRazorMetadataSourceChecksumAttributes =
20
+ build_property.MSBuildProjectDirectory = C:\Projects2\Personal\musketeer\template\dotnet-scaffold\src\__SolutionName__.Api
21
+ build_property._RazorSourceGeneratorDebug =
22
+ build_property.EffectiveAnalysisLevelStyle = 10.0
23
+ build_property.EnableCodeStyleSeverity =
@@ -0,0 +1,17 @@
1
+ // <auto-generated/>
2
+ global using Microsoft.AspNetCore.Builder;
3
+ global using Microsoft.AspNetCore.Hosting;
4
+ global using Microsoft.AspNetCore.Http;
5
+ global using Microsoft.AspNetCore.Routing;
6
+ global using Microsoft.Extensions.Configuration;
7
+ global using Microsoft.Extensions.DependencyInjection;
8
+ global using Microsoft.Extensions.Hosting;
9
+ global using Microsoft.Extensions.Logging;
10
+ global using System;
11
+ global using System.Collections.Generic;
12
+ global using System.IO;
13
+ global using System.Linq;
14
+ global using System.Net.Http;
15
+ global using System.Net.Http.Json;
16
+ global using System.Threading;
17
+ global using System.Threading.Tasks;