atdd 0.2.1__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 (184) hide show
  1. atdd/__init__.py +6 -0
  2. atdd/__main__.py +4 -0
  3. atdd/cli.py +404 -0
  4. atdd/coach/__init__.py +0 -0
  5. atdd/coach/commands/__init__.py +0 -0
  6. atdd/coach/commands/add_persistence_metadata.py +215 -0
  7. atdd/coach/commands/analyze_migrations.py +188 -0
  8. atdd/coach/commands/consumers.py +720 -0
  9. atdd/coach/commands/infer_governance_status.py +149 -0
  10. atdd/coach/commands/initializer.py +177 -0
  11. atdd/coach/commands/interface.py +1078 -0
  12. atdd/coach/commands/inventory.py +565 -0
  13. atdd/coach/commands/migration.py +240 -0
  14. atdd/coach/commands/registry.py +1560 -0
  15. atdd/coach/commands/session.py +430 -0
  16. atdd/coach/commands/sync.py +405 -0
  17. atdd/coach/commands/test_interface.py +399 -0
  18. atdd/coach/commands/test_runner.py +141 -0
  19. atdd/coach/commands/tests/__init__.py +1 -0
  20. atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
  21. atdd/coach/commands/traceability.py +4264 -0
  22. atdd/coach/conventions/session.convention.yaml +754 -0
  23. atdd/coach/overlays/__init__.py +2 -0
  24. atdd/coach/overlays/claude.md +2 -0
  25. atdd/coach/schemas/config.schema.json +34 -0
  26. atdd/coach/schemas/manifest.schema.json +101 -0
  27. atdd/coach/templates/ATDD.md +282 -0
  28. atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
  29. atdd/coach/utils/__init__.py +0 -0
  30. atdd/coach/utils/graph/__init__.py +0 -0
  31. atdd/coach/utils/graph/urn.py +875 -0
  32. atdd/coach/validators/__init__.py +0 -0
  33. atdd/coach/validators/shared_fixtures.py +365 -0
  34. atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
  35. atdd/coach/validators/test_registry.py +575 -0
  36. atdd/coach/validators/test_session_validation.py +1183 -0
  37. atdd/coach/validators/test_traceability.py +448 -0
  38. atdd/coach/validators/test_update_feature_paths.py +108 -0
  39. atdd/coach/validators/test_validate_contract_consumers.py +297 -0
  40. atdd/coder/__init__.py +1 -0
  41. atdd/coder/conventions/adapter.recipe.yaml +88 -0
  42. atdd/coder/conventions/backend.convention.yaml +460 -0
  43. atdd/coder/conventions/boundaries.convention.yaml +666 -0
  44. atdd/coder/conventions/commons.convention.yaml +460 -0
  45. atdd/coder/conventions/complexity.recipe.yaml +109 -0
  46. atdd/coder/conventions/component-naming.convention.yaml +178 -0
  47. atdd/coder/conventions/design.convention.yaml +327 -0
  48. atdd/coder/conventions/design.recipe.yaml +273 -0
  49. atdd/coder/conventions/dto.convention.yaml +660 -0
  50. atdd/coder/conventions/frontend.convention.yaml +542 -0
  51. atdd/coder/conventions/green.convention.yaml +1012 -0
  52. atdd/coder/conventions/presentation.convention.yaml +587 -0
  53. atdd/coder/conventions/refactor.convention.yaml +535 -0
  54. atdd/coder/conventions/technology.convention.yaml +206 -0
  55. atdd/coder/conventions/tests/__init__.py +0 -0
  56. atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
  57. atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
  58. atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
  59. atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
  60. atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
  61. atdd/coder/conventions/thinness.recipe.yaml +82 -0
  62. atdd/coder/conventions/train.convention.yaml +325 -0
  63. atdd/coder/conventions/verification.protocol.yaml +53 -0
  64. atdd/coder/schemas/design_system.schema.json +361 -0
  65. atdd/coder/validators/__init__.py +0 -0
  66. atdd/coder/validators/test_commons_structure.py +485 -0
  67. atdd/coder/validators/test_complexity.py +416 -0
  68. atdd/coder/validators/test_cross_language_consistency.py +431 -0
  69. atdd/coder/validators/test_design_system_compliance.py +413 -0
  70. atdd/coder/validators/test_dto_testing_patterns.py +268 -0
  71. atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
  72. atdd/coder/validators/test_green_layer_dependencies.py +148 -0
  73. atdd/coder/validators/test_green_python_layer_structure.py +103 -0
  74. atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
  75. atdd/coder/validators/test_import_boundaries.py +396 -0
  76. atdd/coder/validators/test_init_file_urns.py +593 -0
  77. atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
  78. atdd/coder/validators/test_presentation_convention.py +260 -0
  79. atdd/coder/validators/test_python_architecture.py +674 -0
  80. atdd/coder/validators/test_quality_metrics.py +420 -0
  81. atdd/coder/validators/test_station_master_pattern.py +244 -0
  82. atdd/coder/validators/test_train_infrastructure.py +454 -0
  83. atdd/coder/validators/test_train_urns.py +293 -0
  84. atdd/coder/validators/test_typescript_architecture.py +616 -0
  85. atdd/coder/validators/test_usecase_structure.py +421 -0
  86. atdd/coder/validators/test_wagon_boundaries.py +586 -0
  87. atdd/conftest.py +126 -0
  88. atdd/planner/__init__.py +1 -0
  89. atdd/planner/conventions/acceptance.convention.yaml +538 -0
  90. atdd/planner/conventions/appendix.convention.yaml +187 -0
  91. atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
  92. atdd/planner/conventions/component.convention.yaml +670 -0
  93. atdd/planner/conventions/criteria.convention.yaml +141 -0
  94. atdd/planner/conventions/feature.convention.yaml +371 -0
  95. atdd/planner/conventions/interface.convention.yaml +382 -0
  96. atdd/planner/conventions/steps.convention.yaml +141 -0
  97. atdd/planner/conventions/train.convention.yaml +552 -0
  98. atdd/planner/conventions/wagon.convention.yaml +275 -0
  99. atdd/planner/conventions/wmbt.convention.yaml +258 -0
  100. atdd/planner/schemas/acceptance.schema.json +336 -0
  101. atdd/planner/schemas/appendix.schema.json +78 -0
  102. atdd/planner/schemas/component.schema.json +114 -0
  103. atdd/planner/schemas/feature.schema.json +197 -0
  104. atdd/planner/schemas/train.schema.json +192 -0
  105. atdd/planner/schemas/wagon.schema.json +281 -0
  106. atdd/planner/schemas/wmbt.schema.json +59 -0
  107. atdd/planner/validators/__init__.py +0 -0
  108. atdd/planner/validators/conftest.py +5 -0
  109. atdd/planner/validators/test_draft_wagon_registry.py +374 -0
  110. atdd/planner/validators/test_plan_cross_refs.py +240 -0
  111. atdd/planner/validators/test_plan_uniqueness.py +224 -0
  112. atdd/planner/validators/test_plan_urn_resolution.py +268 -0
  113. atdd/planner/validators/test_plan_wagons.py +174 -0
  114. atdd/planner/validators/test_train_validation.py +514 -0
  115. atdd/planner/validators/test_wagon_urn_chain.py +648 -0
  116. atdd/planner/validators/test_wmbt_consistency.py +327 -0
  117. atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
  118. atdd/tester/__init__.py +1 -0
  119. atdd/tester/conventions/artifact.convention.yaml +257 -0
  120. atdd/tester/conventions/contract.convention.yaml +1009 -0
  121. atdd/tester/conventions/filename.convention.yaml +555 -0
  122. atdd/tester/conventions/migration.convention.yaml +509 -0
  123. atdd/tester/conventions/red.convention.yaml +797 -0
  124. atdd/tester/conventions/routing.convention.yaml +51 -0
  125. atdd/tester/conventions/telemetry.convention.yaml +458 -0
  126. atdd/tester/schemas/a11y.tmpl.json +17 -0
  127. atdd/tester/schemas/artifact.schema.json +189 -0
  128. atdd/tester/schemas/contract.schema.json +591 -0
  129. atdd/tester/schemas/contract.tmpl.json +95 -0
  130. atdd/tester/schemas/db.tmpl.json +20 -0
  131. atdd/tester/schemas/e2e.tmpl.json +17 -0
  132. atdd/tester/schemas/edge_function.tmpl.json +17 -0
  133. atdd/tester/schemas/event.tmpl.json +17 -0
  134. atdd/tester/schemas/http.tmpl.json +19 -0
  135. atdd/tester/schemas/job.tmpl.json +18 -0
  136. atdd/tester/schemas/load.tmpl.json +21 -0
  137. atdd/tester/schemas/metric.tmpl.json +19 -0
  138. atdd/tester/schemas/pack.schema.json +139 -0
  139. atdd/tester/schemas/realtime.tmpl.json +20 -0
  140. atdd/tester/schemas/rls.tmpl.json +18 -0
  141. atdd/tester/schemas/script.tmpl.json +16 -0
  142. atdd/tester/schemas/sec.tmpl.json +18 -0
  143. atdd/tester/schemas/storage.tmpl.json +18 -0
  144. atdd/tester/schemas/telemetry.schema.json +128 -0
  145. atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
  146. atdd/tester/schemas/test_filename.schema.json +194 -0
  147. atdd/tester/schemas/test_intent.schema.json +179 -0
  148. atdd/tester/schemas/unit.tmpl.json +18 -0
  149. atdd/tester/schemas/visual.tmpl.json +18 -0
  150. atdd/tester/schemas/ws.tmpl.json +17 -0
  151. atdd/tester/utils/__init__.py +0 -0
  152. atdd/tester/utils/filename.py +300 -0
  153. atdd/tester/validators/__init__.py +0 -0
  154. atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
  155. atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
  156. atdd/tester/validators/conftest.py +5 -0
  157. atdd/tester/validators/coverage_gap_report.py +321 -0
  158. atdd/tester/validators/fix_dual_ac_references.py +179 -0
  159. atdd/tester/validators/remove_duplicate_lines.py +93 -0
  160. atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
  161. atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
  162. atdd/tester/validators/test_artifact_naming_category.py +307 -0
  163. atdd/tester/validators/test_contract_schema_compliance.py +706 -0
  164. atdd/tester/validators/test_contracts_structure.py +200 -0
  165. atdd/tester/validators/test_coverage_adequacy.py +797 -0
  166. atdd/tester/validators/test_dual_ac_reference.py +225 -0
  167. atdd/tester/validators/test_fixture_validity.py +372 -0
  168. atdd/tester/validators/test_isolation.py +487 -0
  169. atdd/tester/validators/test_migration_coverage.py +204 -0
  170. atdd/tester/validators/test_migration_criteria.py +276 -0
  171. atdd/tester/validators/test_migration_generation.py +116 -0
  172. atdd/tester/validators/test_python_test_naming.py +410 -0
  173. atdd/tester/validators/test_red_layer_validation.py +95 -0
  174. atdd/tester/validators/test_red_python_layer_structure.py +87 -0
  175. atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
  176. atdd/tester/validators/test_telemetry_structure.py +634 -0
  177. atdd/tester/validators/test_typescript_test_naming.py +301 -0
  178. atdd/tester/validators/test_typescript_test_structure.py +84 -0
  179. atdd-0.2.1.dist-info/METADATA +221 -0
  180. atdd-0.2.1.dist-info/RECORD +184 -0
  181. atdd-0.2.1.dist-info/WHEEL +5 -0
  182. atdd-0.2.1.dist-info/entry_points.txt +2 -0
  183. atdd-0.2.1.dist-info/licenses/LICENSE +674 -0
  184. atdd-0.2.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,555 @@
1
+ # Test Filename Convention
2
+ # Defines deterministic filename generation from acceptance URNs
3
+
4
+ version: "1.0.0"
5
+
6
+ description: |
7
+ Test filename generation follows language-specific conventions derived from
8
+ acceptance URN format. This ensures consistent, traceable naming across all
9
+ test files, enabling bidirectional mapping between acceptance criteria and
10
+ their test implementations.
11
+
12
+ rationale: |
13
+ Standardized test filenames derived from acceptance URNs provide:
14
+ 1. Traceability: Direct mapping from acceptance criteria to test files
15
+ 2. Consistency: Language-specific conventions followed systematically
16
+ 3. Discoverability: Predictable filenames enable tooling and automation
17
+ 4. Maintainability: Clear relationship between requirements and tests
18
+
19
+ The URN-based approach ensures that test files can be generated deterministically
20
+ from acceptance criteria, and conversely, acceptance URNs can be extracted from
21
+ test filenames, supporting bidirectional navigation in the ATDD workflow.
22
+
23
+ urn_format:
24
+ pattern: "acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]"
25
+ description: "Acceptance URN format with optional slug"
26
+
27
+ components:
28
+ wagon:
29
+ description: "Wagon identifier in kebab-case"
30
+ pattern: "[a-z][a-z0-9-]*"
31
+ example: "maintain-ux"
32
+
33
+ WMBT:
34
+ description: "Step code + zero-padded 3-digit WMBT sequence"
35
+ pattern: "[DLPCEMYRK][0-9]{3}"
36
+ examples:
37
+ - "C004" # Code step 4
38
+ - "E019" # Evaluate step 19
39
+ - "P003" # Pace step 3
40
+
41
+ HARNESS:
42
+ description: "Test harness code (uppercase)"
43
+ pattern: "[A-Z0-9]+"
44
+ examples:
45
+ - "UNIT"
46
+ - "HTTP"
47
+ - "E2E"
48
+ - "EVENT"
49
+ - "WIDGET"
50
+
51
+ NNN:
52
+ description: "Zero-padded 3-digit per-harness acceptance sequence"
53
+ pattern: "[0-9]{3}"
54
+ examples:
55
+ - "001"
56
+ - "019"
57
+ - "042"
58
+
59
+ slug:
60
+ description: "Optional kebab-case descriptor"
61
+ pattern: "[a-z0-9-]+"
62
+ optional: true
63
+ examples:
64
+ - "user-connection"
65
+ - "primitive-endpoint"
66
+ - "avatar-display"
67
+
68
+ regex: "^acc:([a-z][a-z0-9-]*):([DLPCEMYRK][0-9]{3})-([A-Z0-9]+)-([0-9]{3})(?:-([a-z0-9-]+))?$"
69
+
70
+ examples:
71
+ - urn: "acc:maintain-ux:C004-E2E-019-user-connection"
72
+ wagon: "maintain-ux"
73
+ WMBT: "C004"
74
+ HARNESS: "E2E"
75
+ NNN: "019"
76
+ slug: "user-connection"
77
+
78
+ - urn: "acc:pace-dilemmas:P003-UNIT-042"
79
+ wagon: "pace-dilemmas"
80
+ WMBT: "P003"
81
+ HARNESS: "UNIT"
82
+ NNN: "042"
83
+ slug: null
84
+
85
+ slug_transformations:
86
+ kebab_to_snake:
87
+ description: "Convert kebab-case to snake_case (for Dart, Python, Go)"
88
+ example_input: "user-connection"
89
+ example_output: "user_connection"
90
+ algorithm: "Replace hyphens with underscores"
91
+
92
+ kebab_to_pascal:
93
+ description: "Convert kebab-case to PascalCase (for Java, Kotlin)"
94
+ example_input: "user-connection"
95
+ example_output: "UserConnection"
96
+ algorithm: "Split on hyphens, capitalize each part, join without separator"
97
+
98
+ kebab_to_kebab:
99
+ description: "Preserve kebab-case (legacy TypeScript or no-op cases)"
100
+ example_input: "user-connection"
101
+ example_output: "user-connection"
102
+ algorithm: "No transformation"
103
+
104
+ languages:
105
+ dart:
106
+ pattern: "{WMBT}_{HARNESS}_{NNN}[_{slug_snake}]_test.dart"
107
+ separator: "underscore"
108
+ casing: "WMBT and HARNESS uppercase, slug snake_case"
109
+ suffix: "_test.dart"
110
+ slug_transform: "kebab_to_snake"
111
+
112
+ example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
113
+ example_filename: "C004_E2E_019_user_connection_test.dart"
114
+
115
+ rationale: |
116
+ Dart/Flutter conventions use snake_case with underscores. Test files
117
+ are suffixed with _test.dart. Uppercase WMBT and HARNESS codes maintain
118
+ visual distinction from the slug portion.
119
+
120
+ file_locations:
121
+ - "test/{wagon}/{feature}/"
122
+ - "integration_test/{wagon}/"
123
+
124
+ typescript:
125
+ pattern: "{wmbt_lower}-{harness_lower}-{nnn}[-{slug-kebab}].test.ts"
126
+ separator: "hyphen"
127
+ casing: "all lowercase, slug kebab-case"
128
+ suffix: ".test.ts"
129
+ slug_transform: "kebab_to_kebab"
130
+
131
+ example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
132
+ example_filename: "c004-e2e-019-user-connection.test.ts"
133
+
134
+ rationale: |
135
+ TypeScript conventions favor kebab-case for filenames. Use .test.ts
136
+ suffixes for consistency across TypeScript runtimes. All lowercase ensures
137
+ modern JavaScript/TypeScript module naming.
138
+
139
+ file_locations:
140
+ - "supabase/functions/{wagon}/{feature}/test/"
141
+ - "e2e/{train}/"
142
+ - "supabase/functions/{feature}/test/" # DEPRECATED: Legacy flat structure
143
+
144
+ typescript_preact:
145
+ pattern: "{WMBT}_{HARNESS}_{NNN}[_{slug_snake}].test.ts[x]"
146
+ separator: "underscore"
147
+ casing: "WMBT and HARNESS uppercase, slug snake_case"
148
+ suffix: ".test.ts"
149
+ alternative_suffix: ".test.tsx"
150
+ slug_transform: "kebab_to_snake"
151
+
152
+ example_urn: "acc:maintain-ux:C001-WIDGET-001-button"
153
+ example_filename: "C001_WIDGET_001_button.test.tsx"
154
+
155
+ extension_rules:
156
+ ".test.ts": "Logic tests (domain, application, integration)"
157
+ ".test.tsx": "Component tests (presentation, widget harness)"
158
+
159
+ rationale: |
160
+ Preact/TypeScript tests align with URN-based filenames and use
161
+ underscore separators for readability. Use .test.tsx for component
162
+ tests that include JSX, and .test.ts for pure logic tests.
163
+
164
+ file_locations:
165
+ - "web/tests/{wagon}/{feature}/{layer}/"
166
+
167
+ python:
168
+ pattern: "test_{wmbt_lower}_{harness_lower}_{nnn}_{slug_snake}.py"
169
+ separator: "underscore"
170
+ casing: "all lowercase, slug snake_case"
171
+ prefix: "test_"
172
+ slug_transform: "kebab_to_snake"
173
+ slug_required: true
174
+ slug_source: "acceptance.identity.purpose"
175
+
176
+ example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
177
+ example_filename: "test_c004_e2e_019_user_connection.py"
178
+
179
+ rationale: |
180
+ pytest requires test files to start with test_ prefix. Python conventions
181
+ use snake_case throughout. Lowercase codes maintain consistency with
182
+ Python's typical module naming.
183
+
184
+ Slugs are MANDATORY and derived from acceptance criteria purposes to:
185
+ 1. Enable human-readable test filenames
186
+ 2. Support ATDD test discovery and traceability
187
+ 3. Provide clear intent without opening files
188
+ 4. Facilitate code review and navigation
189
+
190
+ Slug extraction: Take the acceptance purpose field, remove "Verify" prefix,
191
+ convert to lowercase, replace spaces with hyphens, and limit to first 5 words.
192
+
193
+ file_locations:
194
+ - "python/{wagon_snake}/{feature_snake}/test/" # Feature-based structure (preferred)
195
+ - "tests/{wagon}/" # Legacy wagon-level tests
196
+ - ".claude/utils/{agent}/tests/" # Platform utility tests
197
+
198
+ go:
199
+ pattern: "{wmbt_lower}_{harness_lower}_{nnn}[_{slug_snake}]_test.go"
200
+ separator: "underscore"
201
+ casing: "all lowercase, slug snake_case"
202
+ suffix: "_test.go"
203
+ slug_transform: "kebab_to_snake"
204
+
205
+ example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
206
+ example_filename: "c004_e2e_019_user_connection_test.go"
207
+
208
+ rationale: |
209
+ Go testing convention requires _test.go suffix. Go uses snake_case for
210
+ test files. Lowercase maintains consistency with Go's filename conventions.
211
+
212
+ file_locations:
213
+ - "{wagon}/"
214
+ - "cmd/{wagon}/"
215
+ - "pkg/{wagon}/"
216
+
217
+ java:
218
+ pattern: "{WMBT}{HARNESS}{NNN}{SlugPascal}Test"
219
+ separator: "none"
220
+ casing: "WMBT and HARNESS uppercase, slug PascalCase"
221
+ suffix: "Test"
222
+ slug_transform: "kebab_to_pascal"
223
+
224
+ example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
225
+ example_filename: "C004E2E019UserConnectionTest.java"
226
+ example_classname: "C004E2E019UserConnectionTest"
227
+
228
+ rationale: |
229
+ Java requires filename to match class name. JUnit convention uses Test
230
+ suffix. PascalCase without separators follows Java class naming standards.
231
+
232
+ file_locations:
233
+ - "src/test/java/{package}/{wagon}/"
234
+
235
+ kotlin:
236
+ pattern: "{WMBT}{HARNESS}{NNN}{SlugPascal}Test.kt"
237
+ separator: "none"
238
+ casing: "WMBT and HARNESS uppercase, slug PascalCase"
239
+ suffix: "Test"
240
+ slug_transform: "kebab_to_pascal"
241
+
242
+ example_urn: "acc:maintain-ux:C004-E2E-019-user-connection"
243
+ example_filename: "C004E2E019UserConnectionTest.kt"
244
+ example_classname: "C004E2E019UserConnectionTest"
245
+
246
+ rationale: |
247
+ Kotlin follows same conventions as Java for test naming. JUnit/KotlinTest
248
+ frameworks expect Test suffix and PascalCase class names.
249
+
250
+ file_locations:
251
+ - "src/test/kotlin/{package}/{wagon}/"
252
+
253
+ harness_codes:
254
+ - code: "UNIT"
255
+ description: "Unit tests for isolated component logic"
256
+ - code: "HTTP"
257
+ description: "HTTP API endpoint tests"
258
+ - code: "EVENT"
259
+ description: "Event handler and pub/sub tests"
260
+ - code: "WS"
261
+ description: "WebSocket connection tests"
262
+ - code: "E2E"
263
+ description: "End-to-end integration tests"
264
+ - code: "A11Y"
265
+ description: "Accessibility compliance tests"
266
+ - code: "VIS"
267
+ description: "Visual regression tests"
268
+ - code: "METRIC"
269
+ description: "Performance metric tests"
270
+ - code: "JOB"
271
+ description: "Background job tests"
272
+ - code: "DB"
273
+ description: "Database operation tests"
274
+ - code: "SEC"
275
+ description: "Security validation tests"
276
+ - code: "LOAD"
277
+ description: "Load and stress tests"
278
+ - code: "SCRIPT"
279
+ description: "Script execution tests"
280
+ - code: "WIDGET"
281
+ description: "Widget component tests"
282
+ - code: "GOLDEN"
283
+ description: "Golden file comparison tests"
284
+ - code: "BLOC"
285
+ description: "BLoC pattern tests"
286
+ - code: "INTEGRATION"
287
+ description: "Integration tests"
288
+ - code: "RLS"
289
+ description: "Row-level security tests"
290
+ - code: "EDGE"
291
+ description: "Edge function tests"
292
+ - code: "REALTIME"
293
+ description: "Realtime subscription tests"
294
+ - code: "STORAGE"
295
+ description: "Storage operation tests"
296
+
297
+ utility_functions:
298
+ module: ".claude/utils/tester/filename.py"
299
+
300
+ functions:
301
+ - name: "parse_acceptance_urn"
302
+ description: "Parse URN into components (wagon, WMBT, HARNESS, NNN, slug)"
303
+ signature: "parse_acceptance_urn(urn: str) -> Dict[str, Optional[str]]"
304
+
305
+ - name: "dart_filename"
306
+ description: "Generate Dart test filename from URN"
307
+ signature: "dart_filename(urn: str) -> str"
308
+
309
+ - name: "typescript_filename"
310
+ description: "Generate TypeScript test filename from URN"
311
+ signature: "typescript_filename(urn: str) -> str"
312
+
313
+ - name: "typescript_preact_filename"
314
+ description: "Generate Preact TypeScript test filename from URN"
315
+ signature: "typescript_preact_filename(urn: str, tsx: Optional[bool] = None) -> str"
316
+
317
+ - name: "python_filename"
318
+ description: "Generate Python test filename from URN"
319
+ signature: "python_filename(urn: str) -> str"
320
+
321
+ - name: "go_filename"
322
+ description: "Generate Go test filename from URN"
323
+ signature: "go_filename(urn: str) -> str"
324
+
325
+ - name: "java_classname"
326
+ description: "Generate Java/Kotlin test classname from URN"
327
+ signature: "java_classname(urn: str) -> str"
328
+
329
+ - name: "generate_test_filename"
330
+ description: "Unified interface accepting language parameter"
331
+ signature: "generate_test_filename(urn: str, language: str) -> str"
332
+
333
+ - name: "kebab_to_snake"
334
+ description: "Convert kebab-case to snake_case"
335
+ signature: "kebab_to_snake(slug: Optional[str]) -> str"
336
+
337
+ - name: "kebab_to_pascal"
338
+ description: "Convert kebab-case to PascalCase"
339
+ signature: "kebab_to_pascal(slug: Optional[str]) -> str"
340
+
341
+ validation:
342
+ urn_format:
343
+ - "URN must match regex pattern"
344
+ - "Wagon must be lowercase with hyphens"
345
+ - "WMBT must be uppercase letter + 3 digits"
346
+ - "HARNESS must be uppercase code from approved list"
347
+ - "NNN must be 3-digit zero-padded sequence"
348
+ - "Slug (if present) must be lowercase with hyphens"
349
+
350
+ filename_format:
351
+ - "Generated filename must follow language-specific pattern"
352
+ - "Casing transformations must be applied correctly"
353
+ - "Separators must match language conventions"
354
+ - "File extension must match language requirements"
355
+
356
+ test_file_header:
357
+ description: "All test files should include URN comment for traceability"
358
+
359
+ formats:
360
+ dart: |
361
+ // urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
362
+
363
+ typescript: |
364
+ // urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
365
+
366
+ python: |
367
+ # urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
368
+
369
+ go: |
370
+ // urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
371
+
372
+ java: |
373
+ // urn: acc:{wagon}:{WMBT}-{HARNESS}-{NNN}[-{slug}]
374
+
375
+ directory_structure:
376
+ description: |
377
+ Tests are organized by feature within wagon directories. Each feature contains
378
+ separate src/ and test/ folders following clean architecture principles.
379
+
380
+ pattern: "{language}/{wagon_snake}/{feature_snake}/{src|test}/"
381
+
382
+ rationale: |
383
+ Feature-based organization provides:
384
+ 1. Feature Isolation: Each feature's code and tests are colocated
385
+ 2. Traceability: Direct mapping from wagon manifest features to code structure
386
+ 3. Scalability: Wagons can contain multiple features without test conflicts
387
+ 4. Clarity: Clear separation between implementation (src/) and verification (test/)
388
+
389
+ examples:
390
+ python:
391
+ structure: |
392
+ python/
393
+ {wagon_snake}/ # Wagon directory (kebab→snake)
394
+ {feature_snake}/ # Feature directory (kebab→snake)
395
+ src/ # Implementation code
396
+ __init__.py
397
+ domain/ # Domain layer
398
+ application/ # Application layer
399
+ integration/ # Integration layer
400
+ test/ # Test code
401
+ __init__.py
402
+ test_{wmbt}_{harness}_{nnn}.py # Acceptance tests
403
+ conftest.py # Pytest fixtures
404
+
405
+ example_wagon: "generate-identifiers"
406
+ example_features:
407
+ - "generate-uuid"
408
+ - "generate-username"
409
+
410
+ concrete_structure: |
411
+ python/
412
+ generate_identifiers/
413
+ generate_uuid/
414
+ src/
415
+ __init__.py
416
+ uuid_generator.py
417
+ test/
418
+ __init__.py
419
+ test_l001_unit_001.py # Performance test
420
+ test_l001_load_001.py # Throughput test
421
+ test_c005.py # RFC compliance
422
+ test_c006.py # Deterministic generation
423
+ generate_username/
424
+ src/
425
+ __init__.py
426
+ username_sanitizer.py
427
+ username_validator.py
428
+ test/
429
+ __init__.py
430
+ test_p001_unit_001.py # Sanitization
431
+ test_p001_unit_002.py # Unicode handling
432
+ test_c001_unit_001.py # Uniqueness (taken)
433
+ test_c001_unit_002.py # Uniqueness (available)
434
+ test_c004.py # Reserved words
435
+ test_c007.py # Format enforcement
436
+
437
+ dart:
438
+ structure: |
439
+ lib/
440
+ {wagon_snake}/ # Wagon directory
441
+ {feature_snake}/ # Feature directory
442
+ src/ # Implementation
443
+ domain/
444
+ application/
445
+ presentation/
446
+ test/
447
+ {wagon_snake}/ # Test mirror structure
448
+ {feature_snake}/
449
+ {WMBT}_{HARNESS}_{NNN}_test.dart
450
+
451
+ example: |
452
+ lib/maintain_ux/provide_foundations/src/
453
+ test/maintain_ux/provide_foundations/L001_UNIT_001_test.dart
454
+
455
+ naming_transformations:
456
+ wagon_name:
457
+ input: "Wagon name from manifest (kebab-case)"
458
+ python_output: "snake_case"
459
+ dart_output: "snake_case"
460
+ typescript_output: "kebab-case"
461
+ example_input: "generate-identifiers"
462
+ example_python: "generate_identifiers"
463
+ example_dart: "generate_identifiers"
464
+
465
+ feature_name:
466
+ input: "Feature name from wagon manifest (kebab-case)"
467
+ python_output: "snake_case"
468
+ dart_output: "snake_case"
469
+ typescript_output: "kebab-case"
470
+ example_input: "generate-uuid"
471
+ example_python: "generate_uuid"
472
+ example_dart: "generate_uuid"
473
+
474
+ feature_discovery:
475
+ description: "Features are defined in wagon manifest YAML"
476
+ manifest_location: "plan/{wagon}/_{wagon}.yaml"
477
+ manifest_field: "features[]"
478
+
479
+ example_manifest: |
480
+ wagon: generate-identifiers
481
+ features:
482
+ - urn: feature:generate-identifiers:generate-uuid
483
+ - urn: feature:generate-identifiers:generate-username
484
+
485
+ feature_extraction:
486
+ pattern: "feature:{wagon}:{feature_name}"
487
+ regex: "^feature:([a-z][a-z0-9-]*):([a-z][a-z0-9-]*)$"
488
+ wagon_group: 1
489
+ feature_group: 2
490
+
491
+ acceptance_to_feature_mapping:
492
+ description: |
493
+ Each acceptance criteria belongs to a feature. The feature name determines
494
+ which test directory the test file should be placed in.
495
+
496
+ lookup_process:
497
+ 1: "Parse acceptance URN to extract wagon and WMBT code"
498
+ 2: "Load wagon manifest from plan/{wagon}/_{wagon}.yaml"
499
+ 3: "Load WMBT file from plan/{wagon}/{WMBT}.yaml"
500
+ 4: "Extract feature URNs from wagon manifest features[]"
501
+ 5: "Match acceptance to feature via acceptance.identity.purpose or metadata.feature"
502
+ 6: "Extract feature name from feature URN"
503
+ 7: "Generate test path: {lang}/{wagon_snake}/{feature_snake}/test/"
504
+
505
+ example:
506
+ acceptance_urn: "acc:generate-identifiers:L001-UNIT-001"
507
+ wagon: "generate-identifiers"
508
+ wmbt_file: "plan/generate_identifiers/L001.yaml"
509
+ feature_urn: "feature:generate-identifiers:generate-uuid"
510
+ feature_name: "generate-uuid"
511
+ test_path: "python/generate_identifiers/generate_uuid/test/"
512
+ test_filename: "test_l001_unit_001.py"
513
+ full_path: "python/generate_identifiers/generate_uuid/test/test_l001_unit_001.py"
514
+
515
+ references:
516
+ spec_ids:
517
+ - "SPEC-TESTER-CONV-0068" # Parse acceptance URN components
518
+ - "SPEC-TESTER-CONV-0069" # Generate Dart filename
519
+ - "SPEC-TESTER-CONV-0070" # Generate TypeScript filename
520
+ - "SPEC-TESTER-CONV-0071" # Generate Python filename
521
+ - "SPEC-TESTER-CONV-0072" # Generate Go filename
522
+ - "SPEC-TESTER-CONV-0073" # Generate Java/Kotlin classname
523
+ - "SPEC-TESTER-CONV-0074" # Handle URN without slug
524
+ - "SPEC-TESTER-CONV-0075" # Slug transformations
525
+ - "SPEC-TESTER-CONV-0076" # URN regex validation
526
+ - "SPEC-TESTER-CONV-0077" # Convention documentation
527
+ - "SPEC-TESTER-CONV-0078" # Platform validation enforcement
528
+ - "SPEC-TESTER-CONV-0079" # Feature-based directory structure
529
+ - "SPEC-TESTER-CONV-0080" # Acceptance-to-feature mapping
530
+
531
+ related_conventions:
532
+ - "red.convention.yaml" # References test generation
533
+ - "artifact.convention.yaml" # Pattern for URN-to-path mapping
534
+ - "backend.convention.yaml" # Layer structure within src/
535
+
536
+ related_schemas:
537
+ - ".claude/schemas/tester/test_intent.schema.json"
538
+ - ".claude/schemas/planner/acceptance.schema.json"
539
+ - ".claude/schemas/planner/wagon.schema.json"
540
+ - ".claude/schemas/planner/feature.schema.json"
541
+
542
+ migration:
543
+ from_legacy:
544
+ description: "Legacy test files may not follow URN-based naming"
545
+ strategy: |
546
+ 1. Extract URN from test file header comment
547
+ 2. Generate expected filename using utility
548
+ 3. Rename file if filename doesn't match convention
549
+ 4. Update imports and references
550
+
551
+ example_transformation:
552
+ legacy_dart: "ac_http_006_primitive_endpoint_test.dart"
553
+ legacy_urn_comment: "// urn: acc:maintain-ux.001.AC-HTTP-006"
554
+ new_urn: "acc:maintain-ux:C004-HTTP-006-primitive-endpoint"
555
+ new_filename: "C004_HTTP_006_primitive_endpoint_test.dart"