@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.
- package/README.md +49 -49
- package/manifest.json +301 -253
- package/package.json +1 -1
- package/template/.claude/hooks/block-unsafe-adr-title.cjs +70 -0
- package/template/.claude/hooks/init-adr-dir.cjs +110 -0
- package/template/.claude/hooks/inject-adr-env.cjs +82 -0
- package/template/.claude/hooks/lib/characteristics/checker.cjs +357 -0
- package/template/.claude/hooks/sync-adr-toc.cjs +111 -0
- package/template/.claude/hooks/validate-characteristics-hook.cjs +66 -0
- package/template/.claude/hooks/warn-missing-characteristics.cjs +32 -0
- package/template/.claude/skills/adr-writer/SKILL.md +24 -101
- package/template/.claude/skills/adr-writer/references/adr-example.md +0 -5
- package/template/.claude/skills/adr-writer/references/adr-template.md +0 -12
- package/template/.claude/skills/architecture-characteristic-writer/SKILL.md +197 -99
- package/template/.claude/skills/architecture-characteristic-writer/assets/worksheet-template.md +18 -29
- package/template/.claude/skills/architecture-characteristic-writer/references/characteristics-catalog.md +22 -88
- package/template/.claude/skills/architecture-characteristic-writer/scripts/ranking-table.cjs +171 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.GeneratedMSBuildEditorConfig.editorconfig +23 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.GlobalUsings.g.cs +17 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/Debug/net10.0/__SolutionName__.Api.assets.cache +0 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/__SolutionName__.Api.csproj.nuget.dgspec.json +1536 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/__SolutionName__.Api.csproj.nuget.g.props +16 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/__SolutionName__.Api.csproj.nuget.g.targets +2 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/project.assets.json +559 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Api/obj/project.nuget.cache +8 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.GeneratedMSBuildEditorConfig.editorconfig +17 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.GlobalUsings.g.cs +8 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/Debug/net10.0/__SolutionName__.Application.assets.cache +0 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/__SolutionName__.Application.csproj.nuget.dgspec.json +690 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/__SolutionName__.Application.csproj.nuget.g.props +16 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/__SolutionName__.Application.csproj.nuget.g.targets +2 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/project.assets.json +376 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Application/obj/project.nuget.cache +8 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.GeneratedMSBuildEditorConfig.editorconfig +17 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.GlobalUsings.g.cs +8 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/Debug/net10.0/__SolutionName__.Domain.assets.cache +0 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/__SolutionName__.Domain.csproj.nuget.dgspec.json +347 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/__SolutionName__.Domain.csproj.nuget.g.props +16 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/__SolutionName__.Domain.csproj.nuget.g.targets +2 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/project.assets.json +353 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Domain/obj/project.nuget.cache +8 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.GeneratedMSBuildEditorConfig.editorconfig +17 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.GlobalUsings.g.cs +8 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.assets.cache +0 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/Debug/net10.0/__SolutionName__.Infrastructure.csproj.AssemblyReference.cache +0 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/__SolutionName__.Infrastructure.csproj.nuget.dgspec.json +1047 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/__SolutionName__.Infrastructure.csproj.nuget.g.props +16 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/__SolutionName__.Infrastructure.csproj.nuget.g.targets +7 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/project.assets.json +858 -0
- package/template/dotnet-scaffold/src/__SolutionName__.Infrastructure/obj/project.nuget.cache +17 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Api.Tests +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.GlobalUsings.g.cs +9 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.assets.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/Debug/net10.0/__SolutionName__.Api.Tests.csproj.AssemblyReference.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/__SolutionName__.Api.Tests.csproj.nuget.dgspec.json +1908 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/__SolutionName__.Api.Tests.csproj.nuget.g.props +27 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/__SolutionName__.Api.Tests.csproj.nuget.g.targets +16 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/project.assets.json +3283 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Api.Tests/obj/project.nuget.cache +60 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Application.Tests +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.GlobalUsings.g.cs +9 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.assets.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/Debug/net10.0/__SolutionName__.Application.Tests.csproj.AssemblyReference.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/__SolutionName__.Application.Tests.csproj.nuget.dgspec.json +1055 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/__SolutionName__.Application.Tests.csproj.nuget.g.props +26 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/__SolutionName__.Application.Tests.csproj.nuget.g.targets +11 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/project.assets.json +1662 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Application.Tests/obj/project.nuget.cache +30 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Domain.Tests +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.GlobalUsings.g.cs +9 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.assets.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/Debug/net10.0/__SolutionName__.Domain.Tests.csproj.AssemblyReference.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/__SolutionName__.Domain.Tests.csproj.nuget.dgspec.json +712 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/__SolutionName__.Domain.Tests.csproj.nuget.g.props +26 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/__SolutionName__.Domain.Tests.csproj.nuget.g.targets +11 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/project.assets.json +1644 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Domain.Tests/obj/project.nuget.cache +30 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/bin/Debug/net10.0/.msCoverageSourceRootsMapping___SolutionName__.Infrastructure.Tests +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +4 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.AssemblyInfo.cs +22 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.AssemblyInfoInputs.cache +1 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.GeneratedMSBuildEditorConfig.editorconfig +17 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.GlobalUsings.g.cs +9 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.assets.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/Debug/net10.0/__SolutionName__.Infrastructure.Tests.csproj.AssemblyReference.cache +0 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/__SolutionName__.Infrastructure.Tests.csproj.nuget.dgspec.json +1412 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/__SolutionName__.Infrastructure.Tests.csproj.nuget.g.props +26 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/__SolutionName__.Infrastructure.Tests.csproj.nuget.g.targets +13 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/project.assets.json +2130 -0
- package/template/dotnet-scaffold/tests/__SolutionName__.Infrastructure.Tests/obj/project.nuget.cache +38 -0
package/template/.claude/skills/architecture-characteristic-writer/assets/worksheet-template.md
CHANGED
|
@@ -1,40 +1,29 @@
|
|
|
1
1
|
# Architecture Characteristics Worksheet
|
|
2
2
|
|
|
3
|
-
|
|
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
|
|
5
|
+
## Driving Characteristics
|
|
14
6
|
|
|
15
|
-
<!--
|
|
16
|
-
|
|
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 |
|
|
19
|
-
|
|
20
|
-
| 1 | {char1} | {
|
|
21
|
-
| 2 | {char2} | {
|
|
16
|
+
| # | Characteristic | Rationale |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| 1 | {char1} | {rationale1} |
|
|
19
|
+
| 2 | {char2} | {rationale2} |
|
|
22
20
|
|
|
23
21
|
## Implicit Characteristics
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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} | {
|
|
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 |
|
|
8
|
-
|
|
9
|
-
| **performance** | Time it takes for system to process a business request |
|
|
10
|
-
| **responsiveness** | Time it takes to get a response to the user |
|
|
11
|
-
| **availability** | Uptime of a system; usually measured in 9's (e.g., 99.9%) |
|
|
12
|
-
| **fault tolerance** | When fatal errors occur, other parts of system continue to function |
|
|
13
|
-
| **scalability** | System capacity and growth over time; as users/requests increase, responsiveness, performance, and error rates remain constant |
|
|
14
|
-
| **elasticity** | System can expand and respond quickly to unexpected or anticipated extreme loads (e.g., 20 to 250,000 users instantly) |
|
|
15
|
-
| **data integrity** | Data across the system is correct and there is no data loss |
|
|
16
|
-
| **data consistency** | Data across the system is in sync and consistent across databases and tables |
|
|
17
|
-
| **adaptability** | Ease in which system can adapt to changes in environment and functionality |
|
|
18
|
-
| **extensibility** | Ease in which system can be extended with additional features and functionality |
|
|
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
|
-
|
|
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,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;
|