atdd 0.1.0__py3-none-any.whl

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 (183) hide show
  1. atdd/__init__.py +0 -0
  2. atdd/cli.py +404 -0
  3. atdd/coach/__init__.py +0 -0
  4. atdd/coach/commands/__init__.py +0 -0
  5. atdd/coach/commands/add_persistence_metadata.py +215 -0
  6. atdd/coach/commands/analyze_migrations.py +188 -0
  7. atdd/coach/commands/consumers.py +720 -0
  8. atdd/coach/commands/infer_governance_status.py +149 -0
  9. atdd/coach/commands/initializer.py +177 -0
  10. atdd/coach/commands/interface.py +1078 -0
  11. atdd/coach/commands/inventory.py +565 -0
  12. atdd/coach/commands/migration.py +240 -0
  13. atdd/coach/commands/registry.py +1560 -0
  14. atdd/coach/commands/session.py +430 -0
  15. atdd/coach/commands/sync.py +405 -0
  16. atdd/coach/commands/test_interface.py +399 -0
  17. atdd/coach/commands/test_runner.py +141 -0
  18. atdd/coach/commands/tests/__init__.py +1 -0
  19. atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
  20. atdd/coach/commands/traceability.py +4264 -0
  21. atdd/coach/conventions/session.convention.yaml +754 -0
  22. atdd/coach/overlays/__init__.py +2 -0
  23. atdd/coach/overlays/claude.md +2 -0
  24. atdd/coach/schemas/config.schema.json +34 -0
  25. atdd/coach/schemas/manifest.schema.json +101 -0
  26. atdd/coach/templates/ATDD.md +282 -0
  27. atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
  28. atdd/coach/utils/__init__.py +0 -0
  29. atdd/coach/utils/graph/__init__.py +0 -0
  30. atdd/coach/utils/graph/urn.py +875 -0
  31. atdd/coach/validators/__init__.py +0 -0
  32. atdd/coach/validators/shared_fixtures.py +365 -0
  33. atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
  34. atdd/coach/validators/test_registry.py +575 -0
  35. atdd/coach/validators/test_session_validation.py +1183 -0
  36. atdd/coach/validators/test_traceability.py +448 -0
  37. atdd/coach/validators/test_update_feature_paths.py +108 -0
  38. atdd/coach/validators/test_validate_contract_consumers.py +297 -0
  39. atdd/coder/__init__.py +1 -0
  40. atdd/coder/conventions/adapter.recipe.yaml +88 -0
  41. atdd/coder/conventions/backend.convention.yaml +460 -0
  42. atdd/coder/conventions/boundaries.convention.yaml +666 -0
  43. atdd/coder/conventions/commons.convention.yaml +460 -0
  44. atdd/coder/conventions/complexity.recipe.yaml +109 -0
  45. atdd/coder/conventions/component-naming.convention.yaml +178 -0
  46. atdd/coder/conventions/design.convention.yaml +327 -0
  47. atdd/coder/conventions/design.recipe.yaml +273 -0
  48. atdd/coder/conventions/dto.convention.yaml +660 -0
  49. atdd/coder/conventions/frontend.convention.yaml +542 -0
  50. atdd/coder/conventions/green.convention.yaml +1012 -0
  51. atdd/coder/conventions/presentation.convention.yaml +587 -0
  52. atdd/coder/conventions/refactor.convention.yaml +535 -0
  53. atdd/coder/conventions/technology.convention.yaml +206 -0
  54. atdd/coder/conventions/tests/__init__.py +0 -0
  55. atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
  56. atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
  57. atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
  58. atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
  59. atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
  60. atdd/coder/conventions/thinness.recipe.yaml +82 -0
  61. atdd/coder/conventions/train.convention.yaml +325 -0
  62. atdd/coder/conventions/verification.protocol.yaml +53 -0
  63. atdd/coder/schemas/design_system.schema.json +361 -0
  64. atdd/coder/validators/__init__.py +0 -0
  65. atdd/coder/validators/test_commons_structure.py +485 -0
  66. atdd/coder/validators/test_complexity.py +416 -0
  67. atdd/coder/validators/test_cross_language_consistency.py +431 -0
  68. atdd/coder/validators/test_design_system_compliance.py +413 -0
  69. atdd/coder/validators/test_dto_testing_patterns.py +268 -0
  70. atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
  71. atdd/coder/validators/test_green_layer_dependencies.py +148 -0
  72. atdd/coder/validators/test_green_python_layer_structure.py +103 -0
  73. atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
  74. atdd/coder/validators/test_import_boundaries.py +396 -0
  75. atdd/coder/validators/test_init_file_urns.py +593 -0
  76. atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
  77. atdd/coder/validators/test_presentation_convention.py +260 -0
  78. atdd/coder/validators/test_python_architecture.py +674 -0
  79. atdd/coder/validators/test_quality_metrics.py +420 -0
  80. atdd/coder/validators/test_station_master_pattern.py +244 -0
  81. atdd/coder/validators/test_train_infrastructure.py +454 -0
  82. atdd/coder/validators/test_train_urns.py +293 -0
  83. atdd/coder/validators/test_typescript_architecture.py +616 -0
  84. atdd/coder/validators/test_usecase_structure.py +421 -0
  85. atdd/coder/validators/test_wagon_boundaries.py +586 -0
  86. atdd/conftest.py +126 -0
  87. atdd/planner/__init__.py +1 -0
  88. atdd/planner/conventions/acceptance.convention.yaml +538 -0
  89. atdd/planner/conventions/appendix.convention.yaml +187 -0
  90. atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
  91. atdd/planner/conventions/component.convention.yaml +670 -0
  92. atdd/planner/conventions/criteria.convention.yaml +141 -0
  93. atdd/planner/conventions/feature.convention.yaml +371 -0
  94. atdd/planner/conventions/interface.convention.yaml +382 -0
  95. atdd/planner/conventions/steps.convention.yaml +141 -0
  96. atdd/planner/conventions/train.convention.yaml +552 -0
  97. atdd/planner/conventions/wagon.convention.yaml +275 -0
  98. atdd/planner/conventions/wmbt.convention.yaml +258 -0
  99. atdd/planner/schemas/acceptance.schema.json +336 -0
  100. atdd/planner/schemas/appendix.schema.json +78 -0
  101. atdd/planner/schemas/component.schema.json +114 -0
  102. atdd/planner/schemas/feature.schema.json +197 -0
  103. atdd/planner/schemas/train.schema.json +192 -0
  104. atdd/planner/schemas/wagon.schema.json +281 -0
  105. atdd/planner/schemas/wmbt.schema.json +59 -0
  106. atdd/planner/validators/__init__.py +0 -0
  107. atdd/planner/validators/conftest.py +5 -0
  108. atdd/planner/validators/test_draft_wagon_registry.py +374 -0
  109. atdd/planner/validators/test_plan_cross_refs.py +240 -0
  110. atdd/planner/validators/test_plan_uniqueness.py +224 -0
  111. atdd/planner/validators/test_plan_urn_resolution.py +268 -0
  112. atdd/planner/validators/test_plan_wagons.py +174 -0
  113. atdd/planner/validators/test_train_validation.py +514 -0
  114. atdd/planner/validators/test_wagon_urn_chain.py +648 -0
  115. atdd/planner/validators/test_wmbt_consistency.py +327 -0
  116. atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
  117. atdd/tester/__init__.py +1 -0
  118. atdd/tester/conventions/artifact.convention.yaml +257 -0
  119. atdd/tester/conventions/contract.convention.yaml +1009 -0
  120. atdd/tester/conventions/filename.convention.yaml +555 -0
  121. atdd/tester/conventions/migration.convention.yaml +509 -0
  122. atdd/tester/conventions/red.convention.yaml +797 -0
  123. atdd/tester/conventions/routing.convention.yaml +51 -0
  124. atdd/tester/conventions/telemetry.convention.yaml +458 -0
  125. atdd/tester/schemas/a11y.tmpl.json +17 -0
  126. atdd/tester/schemas/artifact.schema.json +189 -0
  127. atdd/tester/schemas/contract.schema.json +591 -0
  128. atdd/tester/schemas/contract.tmpl.json +95 -0
  129. atdd/tester/schemas/db.tmpl.json +20 -0
  130. atdd/tester/schemas/e2e.tmpl.json +17 -0
  131. atdd/tester/schemas/edge_function.tmpl.json +17 -0
  132. atdd/tester/schemas/event.tmpl.json +17 -0
  133. atdd/tester/schemas/http.tmpl.json +19 -0
  134. atdd/tester/schemas/job.tmpl.json +18 -0
  135. atdd/tester/schemas/load.tmpl.json +21 -0
  136. atdd/tester/schemas/metric.tmpl.json +19 -0
  137. atdd/tester/schemas/pack.schema.json +139 -0
  138. atdd/tester/schemas/realtime.tmpl.json +20 -0
  139. atdd/tester/schemas/rls.tmpl.json +18 -0
  140. atdd/tester/schemas/script.tmpl.json +16 -0
  141. atdd/tester/schemas/sec.tmpl.json +18 -0
  142. atdd/tester/schemas/storage.tmpl.json +18 -0
  143. atdd/tester/schemas/telemetry.schema.json +128 -0
  144. atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
  145. atdd/tester/schemas/test_filename.schema.json +194 -0
  146. atdd/tester/schemas/test_intent.schema.json +179 -0
  147. atdd/tester/schemas/unit.tmpl.json +18 -0
  148. atdd/tester/schemas/visual.tmpl.json +18 -0
  149. atdd/tester/schemas/ws.tmpl.json +17 -0
  150. atdd/tester/utils/__init__.py +0 -0
  151. atdd/tester/utils/filename.py +300 -0
  152. atdd/tester/validators/__init__.py +0 -0
  153. atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
  154. atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
  155. atdd/tester/validators/conftest.py +5 -0
  156. atdd/tester/validators/coverage_gap_report.py +321 -0
  157. atdd/tester/validators/fix_dual_ac_references.py +179 -0
  158. atdd/tester/validators/remove_duplicate_lines.py +93 -0
  159. atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
  160. atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
  161. atdd/tester/validators/test_artifact_naming_category.py +307 -0
  162. atdd/tester/validators/test_contract_schema_compliance.py +706 -0
  163. atdd/tester/validators/test_contracts_structure.py +200 -0
  164. atdd/tester/validators/test_coverage_adequacy.py +797 -0
  165. atdd/tester/validators/test_dual_ac_reference.py +225 -0
  166. atdd/tester/validators/test_fixture_validity.py +372 -0
  167. atdd/tester/validators/test_isolation.py +487 -0
  168. atdd/tester/validators/test_migration_coverage.py +204 -0
  169. atdd/tester/validators/test_migration_criteria.py +276 -0
  170. atdd/tester/validators/test_migration_generation.py +116 -0
  171. atdd/tester/validators/test_python_test_naming.py +410 -0
  172. atdd/tester/validators/test_red_layer_validation.py +95 -0
  173. atdd/tester/validators/test_red_python_layer_structure.py +87 -0
  174. atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
  175. atdd/tester/validators/test_telemetry_structure.py +634 -0
  176. atdd/tester/validators/test_typescript_test_naming.py +301 -0
  177. atdd/tester/validators/test_typescript_test_structure.py +84 -0
  178. atdd-0.1.0.dist-info/METADATA +191 -0
  179. atdd-0.1.0.dist-info/RECORD +183 -0
  180. atdd-0.1.0.dist-info/WHEEL +5 -0
  181. atdd-0.1.0.dist-info/entry_points.txt +2 -0
  182. atdd-0.1.0.dist-info/licenses/LICENSE +674 -0
  183. atdd-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,178 @@
1
+ # URN naming pattern
2
+ urn_naming:
3
+ pattern: "component:{wagon}:{feature}[.{objectCamelCase}][.{side}][.{layer}][@vN]"
4
+ description: "Stable component URN: hierarchy via colons (kind:wagon:feature), optional facets via dots."
5
+ utility: "utils.graph.URNBuilder.component(wagon_id, feature_id, component_name?, side?, layer?, version?)"
6
+
7
+ parts:
8
+ wagon: "Parent wagon identifier (kebab-case)"
9
+ feature: "Parent feature identifier (kebab-case)"
10
+ objectCamelCase: "Component name in PascalCase or camelCase"
11
+ side: "Component deployment side (frontend|backend)"
12
+ layer: "Architectural layer (presentation|application|domain|integration)"
13
+ version: "@vN suffix for explicit versioning (optional), e.g., @v2"
14
+
15
+ rules:
16
+ hierarchy_separator: ":"
17
+ facet_separator: "."
18
+ casing:
19
+ wagon_feature: "^[a-z][a-z0-9-]*$"
20
+ facets:
21
+ - "^[a-z][a-z0-9-]*$" # kebab/lower facet allowed
22
+ - "^[A-Z][a-zA-Z0-9]*$" # CamelCase facet allowed
23
+ no_file_extensions: "Do not include .py/.dart/etc. Use a 'lang-*' facet if needed."
24
+ case_policy: "IDs are case-sensitive; store exactly as written."
25
+
26
+ examples:
27
+ - urn: "component:resolve-dilemmas:choose-option.OptionValidator.backend.domain"
28
+ wagon: "resolve-dilemmas"
29
+ feature: "choose-option"
30
+ component: "OptionValidator"
31
+ side: "backend"
32
+ layer: "domain"
33
+
34
+ - urn: "component:manage-users:authenticate-user.LoginForm.frontend.presentation"
35
+ wagon: "manage-users"
36
+ feature: "authenticate-user"
37
+ component: "LoginForm"
38
+ side: "frontend"
39
+ layer: "presentation"
40
+
41
+ note: "Side and layer values are defined by component_type_catalog structure below"
42
+
43
+ # Artifact derivation for component naming
44
+ artifact_derivation:
45
+ description: "How to derive component names from artifact resources"
46
+ overview: |
47
+ Component names come from artifact resources (the part after colon).
48
+ Transform resource to PascalCase and add capability suffix based on artifact type.
49
+ Components describe CAPABILITY to handle artifacts.
50
+
51
+ rules:
52
+ pascalcase_conversion:
53
+ rule: "Convert artifact resource to PascalCase"
54
+ examples:
55
+ - from: "choice"
56
+ to: "Choice"
57
+ - from: "player-wallet"
58
+ to: "PlayerWallet"
59
+ - from: "domain-impacts"
60
+ to: "DomainImpacts"
61
+ - from: "remaining"
62
+ to: "Remaining"
63
+
64
+ capability_suffix:
65
+ rule: "Add capability suffix based on artifact type and component responsibility"
66
+ by_artifact_type:
67
+ events:
68
+ description: "Past tense resources (started, closed, credited)"
69
+ suffixes: ["Publisher", "Emitter", "Broadcaster"]
70
+ examples:
71
+ - artifact: "match:started"
72
+ resource: "started"
73
+ component: "MatchStartedPublisher"
74
+ urn: "component:resolve-dilemmas:make-choice.MatchStartedPublisher.backend.integration"
75
+
76
+ - artifact: "wallet:credited"
77
+ resource: "credited"
78
+ component: "WalletCreditedEmitter"
79
+ urn: "component:manage-wallets:credit-wallet.WalletCreditedEmitter.backend.integration"
80
+
81
+ states:
82
+ description: "Adjective resources (remaining, active, current)"
83
+ suffixes: ["Tracker", "Monitor", "Manager"]
84
+ examples:
85
+ - artifact: "mechanic:timebank.remaining"
86
+ resource: "remaining"
87
+ component: "TimebankTracker"
88
+ urn: "component:burn-timebank:track-timebank.TimebankTracker.backend.domain"
89
+
90
+ - artifact: "session:active"
91
+ resource: "active"
92
+ component: "SessionManager"
93
+ urn: "component:init-session:maintain-session.SessionManager.backend.application"
94
+
95
+ data:
96
+ description: "Noun resources (choice, identity, profile)"
97
+ suffixes: ["Provider", "Handler", "Processor", "Maker"]
98
+ examples:
99
+ - artifact: "mechanic:decision.choice"
100
+ resource: "choice"
101
+ component: "ChoiceMaker"
102
+ urn: "component:resolve-dilemmas:make-choice.ChoiceMaker.backend.domain"
103
+
104
+ - artifact: "player:identity"
105
+ resource: "identity"
106
+ component: "IdentityProvider"
107
+ urn: "component:contextualize-identity:identify-player.IdentityProvider.backend.application"
108
+
109
+ configs:
110
+ description: "Configuration resources (config, settings, agreement)"
111
+ suffixes: ["Configurator", "Builder", "Initializer"]
112
+ examples:
113
+ - artifact: "match:config"
114
+ resource: "config"
115
+ component: "MatchConfigurator"
116
+ urn: "component:setup-match:configure-match.MatchConfigurator.backend.application"
117
+
118
+ - artifact: "league:config"
119
+ resource: "config"
120
+ component: "LeagueBuilder"
121
+ urn: "component:define-league:configure-league.LeagueBuilder.backend.application"
122
+
123
+ layer_assignment:
124
+ description: "Assign components to layers based on artifact type and responsibility"
125
+
126
+ events:
127
+ typical_layers: ["integration", "application"]
128
+ rationale: "Event publishers at boundaries (external integration or internal application)"
129
+ examples:
130
+ - "MatchStartedPublisher → backend.integration (publishes to external systems)"
131
+ - "StateCommittedEmitter → backend.application (emits internal events)"
132
+
133
+ states:
134
+ typical_layers: ["domain", "application"]
135
+ rationale: "State trackers manage business state (domain) or coordinate (application)"
136
+ examples:
137
+ - "TimebankTracker → backend.domain (tracks core business state)"
138
+ - "SessionManager → backend.application (coordinates session lifecycle)"
139
+
140
+ data:
141
+ typical_layers: ["domain", "application", "integration"]
142
+ rationale: "Data handlers span layers based on responsibility"
143
+ examples:
144
+ - "ChoiceMaker → backend.domain (business logic for making choice)"
145
+ - "ChoiceHandler → backend.application (coordinates choice workflow)"
146
+ - "ChoicePersister → backend.integration (persists to database)"
147
+
148
+ configs:
149
+ typical_layers: ["application", "integration"]
150
+ rationale: "Configuration components coordinate setup or load settings"
151
+ examples:
152
+ - "MatchConfigurator → backend.application (coordinates match setup)"
153
+ - "ConfigLoader → backend.integration (loads from external config store)"
154
+
155
+ complete_example:
156
+ artifact: "mechanic:decision.choice"
157
+ wagon: "resolve-dilemmas"
158
+ feature: "make-choice"
159
+ components:
160
+ - name: "ChoiceDisplay"
161
+ urn: "component:resolve-dilemmas:make-choice.ChoiceDisplay.frontend.presentation"
162
+ purpose: "Renders choice options to user"
163
+ derivation: "Resource 'choice' → ChoiceDisplay (presentation UI)"
164
+
165
+ - name: "ChoiceValidator"
166
+ urn: "component:resolve-dilemmas:make-choice.ChoiceValidator.frontend.application"
167
+ purpose: "Validates user selection before submission"
168
+ derivation: "Resource 'choice' → ChoiceValidator (validation logic)"
169
+
170
+ - name: "ChoiceMaker"
171
+ urn: "component:resolve-dilemmas:make-choice.ChoiceMaker.backend.domain"
172
+ purpose: "Applies business rules to make the choice"
173
+ derivation: "Resource 'choice' → ChoiceMaker (core business logic)"
174
+
175
+ - name: "ChoicePersister"
176
+ urn: "component:resolve-dilemmas:make-choice.ChoicePersister.backend.integration"
177
+ purpose: "Persists choice to database"
178
+ derivation: "Resource 'choice' → ChoicePersister (persistence)"
@@ -0,0 +1,327 @@
1
+ schema_version: "1.0.1"
2
+ convention_id: "coder.design_system"
3
+ name: "Design System Convention"
4
+ description: "Hierarchy rules and validation standards for design system architecture within presentation layer."
5
+
6
+ design_system:
7
+ goal: "Enforce reusable UI patterns via tokens → primitives → components → templates hierarchy"
8
+
9
+ location:
10
+ path: "lib/design_system/"
11
+ note: "Design system is a shared wagon at same level as feature wagons"
12
+ structure:
13
+ - "tokens/" # Pure values
14
+ - "primitives/" # Basic components
15
+ - "components/" # Composed from primitives
16
+ - "templates/" # Composed from components
17
+
18
+ principles:
19
+ - id: DS-01
20
+ text: "Tokens are pure values (no logic, no widgets)"
21
+ - id: DS-02
22
+ text: "Primitives are simplest components consuming tokens"
23
+ - id: DS-03
24
+ text: "Components compose primitives and tokens only"
25
+ - id: DS-04
26
+ text: "Templates compose components, primitives, and tokens"
27
+ - id: DS-05
28
+ text: "Dependency flow: tokens ← primitives ← components ← templates"
29
+ - id: DS-06
30
+ text: "Wagons import from design_system, never reverse"
31
+ - id: DS-07
32
+ text: "Extract to design_system on 3rd occurrence (DRY threshold)"
33
+
34
+ layers:
35
+ tokens:
36
+ description: "Pure design values (spacing, radii, motion)"
37
+ path: "design_system/tokens/"
38
+ file_suffix:
39
+ dart: "*_tokens.dart"
40
+ can_import:
41
+ - "dart:core"
42
+ - "package:flutter/material.dart (for Duration, EdgeInsets)"
43
+ cannot_import:
44
+ - "primitives/"
45
+ - "components/"
46
+ - "templates/"
47
+ - "wagons/*"
48
+ examples:
49
+ - "spacing_tokens.dart: AppSpacing.m = 16.0"
50
+ - "radii_tokens.dart: AppRadii.m = 8.0"
51
+ - "motion_tokens.dart: AppMotion.base = Duration(milliseconds: 250)"
52
+ validation:
53
+ - type: no_widgets
54
+ message: "Tokens must not contain widget definitions"
55
+ - type: no_logic
56
+ message: "Tokens are pure values, no business logic"
57
+
58
+ primitives:
59
+ description: "Simplest reusable components (AppBox, AppText, AppIcon)"
60
+ path: "design_system/primitives/"
61
+ file_suffix:
62
+ dart: "*_primitive.dart"
63
+ naming_convention: "App{Primitive} (e.g., AppBox, AppText)"
64
+ can_import:
65
+ - "../tokens/"
66
+ - "dart:core"
67
+ - "package:flutter/widgets.dart"
68
+ - "package:flutter/material.dart"
69
+ cannot_import:
70
+ - "../components/"
71
+ - "../templates/"
72
+ - "wagons/*"
73
+ examples:
74
+ - "app_box_primitive.dart: Container abstraction with token-based styling"
75
+ - "app_text_primitive.dart: Text abstraction with theme typography"
76
+ - "app_icon_primitive.dart: Icon abstraction with token-based sizing"
77
+ validation:
78
+ - type: import_scan
79
+ forbid:
80
+ - "primitives → components"
81
+ - "primitives → templates"
82
+ - type: must_use_tokens
83
+ message: "Primitives should reference tokens for spacing/sizing/radii"
84
+
85
+ components:
86
+ description: "Composed UI elements (AppButton, AppTextField, AppCard)"
87
+ path: "design_system/components/"
88
+ file_suffix:
89
+ dart: "*_component.dart"
90
+ naming_convention: "App{Component} (e.g., AppButton, AppTextField)"
91
+ can_import:
92
+ - "../tokens/"
93
+ - "../primitives/"
94
+ - "dart:core"
95
+ - "package:flutter/widgets.dart"
96
+ - "package:flutter/material.dart"
97
+ cannot_import:
98
+ - "../templates/"
99
+ - "wagons/*"
100
+ examples:
101
+ - "app_button_component.dart: Button using AppBox + AppText"
102
+ - "app_text_field_component.dart: Input using AppBox + theme"
103
+ - "app_card_component.dart: Card using AppBox + elevation"
104
+ validation:
105
+ - type: import_scan
106
+ forbid:
107
+ - "components → templates"
108
+ - type: composition_check
109
+ recommend: "Use primitives over raw Container/Text widgets"
110
+
111
+ templates:
112
+ description: "Multi-component UI patterns (EmptyState, ListWithFilter)"
113
+ path: "design_system/templates/"
114
+ file_suffix:
115
+ dart: "*_template.dart"
116
+ naming_convention: "Descriptive name (e.g., EmptyState, ListWithFilter)"
117
+ can_import:
118
+ - "../tokens/"
119
+ - "../primitives/"
120
+ - "../components/"
121
+ - "dart:core"
122
+ - "package:flutter/widgets.dart"
123
+ - "package:flutter/material.dart"
124
+ cannot_import:
125
+ - "wagons/*"
126
+ examples:
127
+ - "empty_state_template.dart: Icon + Title + Description + Button"
128
+ - "list_with_filter_template.dart: Search + List + EmptyState"
129
+ validation:
130
+ - type: composition_check
131
+ recommend: "Templates should primarily use components, not raw primitives"
132
+
133
+ dependency_rules:
134
+ allowed_edges:
135
+ - from: primitives
136
+ to: [tokens]
137
+ - from: components
138
+ to: [tokens, primitives]
139
+ - from: templates
140
+ to: [tokens, primitives, components]
141
+ - from: wagons
142
+ to: [design_system/tokens, design_system/primitives, design_system/components, design_system/templates]
143
+
144
+ forbidden_edges:
145
+ - from: tokens
146
+ to: [primitives, components, templates]
147
+ message: "Tokens cannot import other design system layers"
148
+ - from: primitives
149
+ to: [components, templates]
150
+ message: "Primitives can only import tokens"
151
+ - from: components
152
+ to: [templates]
153
+ message: "Components cannot import templates"
154
+ - from: design_system
155
+ to: [wagons]
156
+ message: "Design system cannot import from feature wagons"
157
+
158
+ cross_wagon:
159
+ forbidden: true
160
+ message: "Wagons cannot import from other wagons (except via design_system or shared packages)"
161
+
162
+ extraction_rules:
163
+ dry_threshold:
164
+ occurrences: 3
165
+ rule: "Extract pattern to design_system on 3rd occurrence"
166
+ rationale: "Avoid premature abstraction; wait for proven reuse need"
167
+
168
+ token_extraction:
169
+ triggers:
170
+ - "Hardcoded spacing: EdgeInsets.all(16.0)"
171
+ - "Hardcoded radius: BorderRadius.circular(8.0)"
172
+ - "Hardcoded duration: Duration(milliseconds: 250)"
173
+ - "Hardcoded color: Color(0xFF...)"
174
+ actions:
175
+ - "Extract to appropriate token file"
176
+ - "Reuse if token value already exists"
177
+ - "Colors: prefer theme over tokens"
178
+
179
+ primitive_extraction:
180
+ triggers:
181
+ - "Repeated Container patterns (3+ similar usages)"
182
+ - "Repeated Text patterns with consistent styling"
183
+ - "Repeated Icon patterns"
184
+ actions:
185
+ - "Create primitive if not exists"
186
+ - "Primitive must only import tokens"
187
+ - "Name: App{Widget} (AppBox, AppText, AppIcon)"
188
+
189
+ component_extraction:
190
+ triggers:
191
+ - "Repeated composed widgets (button-like patterns)"
192
+ - "Similar input field patterns"
193
+ - "Card/container patterns with interaction"
194
+ actions:
195
+ - "Create component if not exists"
196
+ - "Component must use primitives (not raw widgets)"
197
+ - "Name: App{Component} (AppButton, AppTextField)"
198
+
199
+ template_extraction:
200
+ triggers:
201
+ - "Repeated multi-component patterns"
202
+ - "Common layouts (empty state, list+filter)"
203
+ - "Used across 2+ features"
204
+ actions:
205
+ - "Create template if not exists"
206
+ - "Template must primarily use components"
207
+ - "Descriptive name reflecting UI pattern"
208
+
209
+ validation_checks:
210
+ - id: VC-DS-01
211
+ name: "No hardcoded spacing in wagons"
212
+ check: "grep -r 'EdgeInsets\\.[a-z]*([0-9]' lib/*/features/"
213
+ must_not_match: true
214
+ fix: "Use AppSpacing tokens"
215
+
216
+ - id: VC-DS-02
217
+ name: "No hardcoded colors in wagons"
218
+ check: "grep -r 'Color(0x' lib/*/features/"
219
+ must_not_match: true
220
+ fix: "Use Theme.of(context).colorScheme"
221
+
222
+ - id: VC-DS-03
223
+ name: "Primitives don't import components"
224
+ check_imports:
225
+ path: "lib/design_system/primitives/"
226
+ forbid: "../components/"
227
+ violation: "DS-05: Primitives can only import tokens"
228
+
229
+ - id: VC-DS-04
230
+ name: "Components don't import templates"
231
+ check_imports:
232
+ path: "lib/design_system/components/"
233
+ forbid: "../templates/"
234
+ violation: "DS-05: Components cannot import templates"
235
+
236
+ - id: VC-DS-05
237
+ name: "Design system doesn't import wagons"
238
+ check_imports:
239
+ path: "lib/design_system/"
240
+ forbid_pattern: "package:app/((?!design_system)[^/]+)/"
241
+ violation: "DS-06: design_system cannot import from wagons"
242
+
243
+ - id: VC-DS-06
244
+ name: "No cross-wagon imports"
245
+ check_imports:
246
+ path: "lib/*/features/"
247
+ forbid_pattern: "package:app/((?!design_system)[^/]+)/features/"
248
+ violation: "Wagons cannot import from other wagons"
249
+
250
+ metrics:
251
+ - id: METRIC-DS-01
252
+ name: "Design system coverage"
253
+ formula: "wagons_using_ds / total_wagons"
254
+ target: ">= 80%"
255
+ description: "Percentage of wagons using design system components"
256
+
257
+ - id: METRIC-DS-02
258
+ name: "Component reuse rate"
259
+ formula: "avg(component_usage_count)"
260
+ target: ">= 3"
261
+ description: "Average number of wagons using each component"
262
+
263
+ - id: METRIC-DS-03
264
+ name: "Hardcoded value density"
265
+ formula: "hardcoded_tokens / total_ui_files"
266
+ target: "< 5%"
267
+ description: "Percentage of UI files with hardcoded values"
268
+
269
+ - id: METRIC-DS-04
270
+ name: "Hierarchy compliance"
271
+ formula: "valid_imports / total_imports"
272
+ target: "100%"
273
+ description: "All imports follow hierarchy rules"
274
+
275
+ ci_enforcement:
276
+ on: "pull_request"
277
+ checks:
278
+ - name: "validate_design_system_hierarchy"
279
+ command: "python .claude/utils/coder/design.py --validate-hierarchy"
280
+ on_failure: "block"
281
+
282
+ - name: "scan_hardcoded_tokens"
283
+ command: "python .claude/utils/coder/design.py --scan-tokens lib/*/features/"
284
+ on_failure: "warn"
285
+
286
+ - name: "check_import_rules"
287
+ command: "python .claude/utils/coder/design.py --check-imports"
288
+ on_failure: "block"
289
+
290
+ - name: "design_system_metrics"
291
+ command: "python .claude/utils/coder/design.py --metrics"
292
+ on_failure: "report_only"
293
+
294
+ anti_patterns:
295
+ - id: AP-DS-01
296
+ text: "Premature abstraction"
297
+ avoid: "Creating design system components before 3rd usage"
298
+ fix: "Wait for proven reuse need (DRY threshold: 3)"
299
+
300
+ - id: AP-DS-02
301
+ text: "Leaky abstraction"
302
+ avoid: "Design system components importing from wagons"
303
+ fix: "Design system must be wagon-agnostic"
304
+
305
+ - id: AP-DS-03
306
+ text: "Hierarchy bypass"
307
+ avoid: "Components using raw Container instead of AppBox"
308
+ fix: "Always use lower-level abstractions"
309
+
310
+ - id: AP-DS-04
311
+ text: "Token duplication"
312
+ avoid: "Creating new token when similar value exists"
313
+ fix: "Reuse existing tokens (e.g., AppSpacing.m = 16, don't create new 16px token)"
314
+
315
+ - id: AP-DS-05
316
+ text: "God component"
317
+ avoid: "Single component with too many variants/options"
318
+ fix: "Split into multiple focused components"
319
+
320
+ handoff_criteria:
321
+ description: "Ready for wagon refactoring when design system meets criteria"
322
+ checklist:
323
+ - "Token files created (spacing, radii, motion)"
324
+ - "Core primitives exist (AppBox, AppText, AppIcon)"
325
+ - "No hardcoded values in existing design system components"
326
+ - "Hierarchy validation passing"
327
+ - "Zero design_system → wagon imports"