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,235 @@
1
+ """
2
+ Test telemetry array migration for uniqueness support.
3
+
4
+ SPEC: .claude/agents/coach/schemas.spec.yaml::telemetry_array_migration
5
+ ID: SPEC-COACH-SCHEMA-0019
6
+
7
+ Validates:
8
+ - Telemetry field accepts array of URNs
9
+ - Backward compatibility with single URN
10
+ - Validation of array entries
11
+ - No URN collision when multiple variants share aspect
12
+ - Complete artifact-level URNs for uniqueness
13
+
14
+ Architecture:
15
+ - Tests validate ProduceItem domain entity behavior
16
+ - Tests validate ManifestParser parsing logic
17
+ - Tests validate TelemetryReconciler validation logic
18
+ """
19
+
20
+ import pytest
21
+ from pathlib import Path
22
+ from atdd.coach.commands.traceability import (
23
+ ProduceItem,
24
+ ManifestParser,
25
+ TelemetryFile
26
+ )
27
+
28
+
29
+ # ============================================================================
30
+ # Test Fixtures
31
+ # ============================================================================
32
+
33
+
34
+ @pytest.fixture
35
+ def sample_wagon_manifest_with_array_telemetry():
36
+ """Sample wagon manifest with array telemetry references."""
37
+ return {
38
+ 'wagon': 'pace-dilemmas',
39
+ 'produce': [
40
+ {
41
+ 'name': 'match:dilemma.paired',
42
+ 'to': 'external',
43
+ 'contract': 'contract:match:dilemma.paired',
44
+ 'telemetry': [
45
+ 'telemetry:match:dilemma.paired',
46
+ 'telemetry:match:pacing.exhausted'
47
+ ]
48
+ },
49
+ {
50
+ 'name': 'match:dilemma.current',
51
+ 'to': 'external',
52
+ 'contract': 'contract:match:dilemma.current',
53
+ 'telemetry': [
54
+ 'telemetry:match:dilemma.current'
55
+ ]
56
+ }
57
+ ]
58
+ }
59
+
60
+
61
+ @pytest.fixture
62
+ def sample_wagon_manifest_with_single_telemetry():
63
+ """Sample wagon manifest with single URN (backward compatibility)."""
64
+ return {
65
+ 'wagon': 'probe-character',
66
+ 'produce': [
67
+ {
68
+ 'name': 'sensory:character.dialog',
69
+ 'to': 'external',
70
+ 'contract': 'contract:sensory:character.dialog',
71
+ 'telemetry': 'telemetry:sensory:character.dialog'
72
+ }
73
+ ]
74
+ }
75
+
76
+
77
+ @pytest.fixture
78
+ def sample_wagon_manifest_with_null_telemetry():
79
+ """Sample wagon manifest with null telemetry."""
80
+ return {
81
+ 'wagon': 'stage-characters',
82
+ 'produce': [
83
+ {
84
+ 'name': 'sensory:character.expression',
85
+ 'to': 'external',
86
+ 'contract': 'contract:sensory:character.expression',
87
+ 'telemetry': None
88
+ }
89
+ ]
90
+ }
91
+
92
+
93
+ # ============================================================================
94
+ # SPEC-COACH-SCHEMA-0019: Telemetry field accepts array of URNs
95
+ # ============================================================================
96
+
97
+
98
+ @pytest.mark.platform
99
+ def test_telemetry_accepts_array(sample_wagon_manifest_with_array_telemetry):
100
+ """
101
+ SPEC-COACH-SCHEMA-0019: Telemetry field accepts array of URNs for multiple signals.
102
+
103
+ Given: Wagon has multiple produce items sharing same aspect
104
+ Example: match:dilemma.paired and match:dilemma.current
105
+ Both need separate telemetry URNs for uniqueness
106
+ When: Produce item telemetry field is defined as array
107
+ Then: Telemetry accepts array format: [telemetry:match:dilemma.paired, telemetry:match:dilemma.current]
108
+ Each array entry uses complete artifact-level URN
109
+ No URN collision when multiple variants share aspect
110
+ """
111
+ parser = ManifestParser()
112
+ produce_items = parser.parse_produce_items(sample_wagon_manifest_with_array_telemetry)
113
+
114
+ # Verify first produce item has array telemetry
115
+ first_item = produce_items[0]
116
+ assert first_item.name == 'match:dilemma.paired'
117
+ assert isinstance(first_item.telemetry_ref, list), "Telemetry should be parsed as list"
118
+ assert len(first_item.telemetry_ref) == 2
119
+ assert 'telemetry:match:dilemma.paired' in first_item.telemetry_ref
120
+ assert 'telemetry:match:pacing.exhausted' in first_item.telemetry_ref
121
+
122
+ # Verify second produce item has array telemetry
123
+ second_item = produce_items[1]
124
+ assert second_item.name == 'match:dilemma.current'
125
+ assert isinstance(second_item.telemetry_ref, list), "Telemetry should be parsed as list"
126
+ assert len(second_item.telemetry_ref) == 1
127
+ assert 'telemetry:match:dilemma.current' in second_item.telemetry_ref
128
+
129
+ # Verify no collision - each has unique URN
130
+ all_urns = first_item.telemetry_ref + second_item.telemetry_ref
131
+ assert 'telemetry:match:dilemma.paired' in all_urns
132
+ assert 'telemetry:match:dilemma.current' in all_urns
133
+ # Both are unique despite sharing aspect 'match:dilemma'
134
+
135
+
136
+ @pytest.mark.platform
137
+ def test_telemetry_validates_array_entries(sample_wagon_manifest_with_array_telemetry):
138
+ """
139
+ SPEC-COACH-SCHEMA-0019: Traceability validation checks all array entries exist.
140
+
141
+ Given: Produce item has telemetry array
142
+ When: Validating telemetry references
143
+ Then: Each entry in array is validated
144
+ Each entry must use complete artifact-level URN
145
+ Validation checks all URNs exist in telemetry directory
146
+ """
147
+ parser = ManifestParser()
148
+ produce_items = parser.parse_produce_items(sample_wagon_manifest_with_array_telemetry)
149
+
150
+ first_item = produce_items[0]
151
+
152
+ # Verify telemetry_ref is list
153
+ assert isinstance(first_item.telemetry_ref, list)
154
+
155
+ # Verify each entry is a complete URN (not null, not empty)
156
+ for telemetry_urn in first_item.telemetry_ref:
157
+ assert telemetry_urn is not None
158
+ assert isinstance(telemetry_urn, str)
159
+ assert telemetry_urn.startswith('telemetry:')
160
+ # Complete artifact-level URN includes variant
161
+ assert ':' in telemetry_urn
162
+ assert '.' in telemetry_urn
163
+
164
+ # Verify no null telemetry when array is present
165
+ assert not first_item.has_null_telemetry_ref
166
+
167
+
168
+ @pytest.mark.platform
169
+ def test_telemetry_backward_compatible_single_urn(sample_wagon_manifest_with_single_telemetry):
170
+ """
171
+ SPEC-COACH-SCHEMA-0019: Telemetry accepts single URN for backward compatibility.
172
+
173
+ Given: Wagon manifest has single telemetry URN (not array)
174
+ When: Parsing produce items
175
+ Then: Single URN is treated as single-item array internally
176
+ has_null_telemetry_ref returns False
177
+ Telemetry ref accessible as list for uniform processing
178
+ """
179
+ parser = ManifestParser()
180
+ produce_items = parser.parse_produce_items(sample_wagon_manifest_with_single_telemetry)
181
+
182
+ item = produce_items[0]
183
+ assert item.name == 'sensory:character.dialog'
184
+
185
+ # Single URN should be converted to list internally for uniform processing
186
+ assert isinstance(item.telemetry_ref, list), "Single URN should be normalized to list"
187
+ assert len(item.telemetry_ref) == 1
188
+ assert item.telemetry_ref[0] == 'telemetry:sensory:character.dialog'
189
+
190
+ # Should not be treated as null
191
+ assert not item.has_null_telemetry_ref
192
+
193
+
194
+ @pytest.mark.platform
195
+ def test_telemetry_null_handling(sample_wagon_manifest_with_null_telemetry):
196
+ """
197
+ SPEC-COACH-SCHEMA-0019: Telemetry accepts null for items without telemetry.
198
+
199
+ Given: Produce item has telemetry: null
200
+ When: Parsing produce items
201
+ Then: has_null_telemetry_ref returns True
202
+ telemetry_ref is None or empty list
203
+ """
204
+ parser = ManifestParser()
205
+ produce_items = parser.parse_produce_items(sample_wagon_manifest_with_null_telemetry)
206
+
207
+ item = produce_items[0]
208
+ assert item.name == 'sensory:character.expression'
209
+
210
+ # Null telemetry should be detected
211
+ assert item.has_null_telemetry_ref
212
+
213
+
214
+ @pytest.mark.platform
215
+ def test_produce_item_supports_telemetry_array():
216
+ """
217
+ SPEC-COACH-SCHEMA-0019: ProduceItem entity supports telemetry as array.
218
+
219
+ Given: Need to represent produce item with multiple telemetry URNs
220
+ When: Creating ProduceItem with list telemetry_ref
221
+ Then: ProduceItem stores list correctly
222
+ All properties work with list format
223
+ """
224
+ item = ProduceItem(
225
+ name='match:dilemma.paired',
226
+ to='external',
227
+ contract_ref='contract:match:dilemma.paired',
228
+ telemetry_ref=['telemetry:match:dilemma.paired', 'telemetry:match:pacing.exhausted'],
229
+ wagon='pace-dilemmas'
230
+ )
231
+
232
+ assert isinstance(item.telemetry_ref, list)
233
+ assert len(item.telemetry_ref) == 2
234
+ assert 'telemetry:match:dilemma.paired' in item.telemetry_ref
235
+ assert not item.has_null_telemetry_ref