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
atdd/conftest.py ADDED
@@ -0,0 +1,126 @@
1
+ """
2
+ Root conftest for unified test reporting across all test categories.
3
+ """
4
+ import pytest
5
+
6
+
7
+ def pytest_configure(config):
8
+ """Add custom metadata and markers."""
9
+ # ATDD lifecycle markers
10
+ config.addinivalue_line("markers", "planner: Planning phase validation tests")
11
+ config.addinivalue_line("markers", "tester: Testing phase validation tests (contracts-as-code)")
12
+ config.addinivalue_line("markers", "coder: Coding phase validation tests")
13
+
14
+ # Legacy/component markers
15
+ config.addinivalue_line("markers", "platform: Platform validation tests")
16
+ config.addinivalue_line("markers", "backend: Backend Python tests")
17
+ config.addinivalue_line("markers", "frontend: Frontend Preact/TypeScript tests")
18
+ config.addinivalue_line("markers", "agents: Agent behavior tests")
19
+ config.addinivalue_line("markers", "schemas: Schema validation tests")
20
+ config.addinivalue_line("markers", "utils: Utility and runtime tests")
21
+ config.addinivalue_line("markers", "contracts: Contract tests")
22
+ config.addinivalue_line("markers", "telemetry: Telemetry tests")
23
+
24
+ # Custom metadata for HTML report
25
+ if hasattr(config, '_metadata'):
26
+ config._metadata.update({
27
+ "Project": "Wagons Platform",
28
+ "Test Categories": "Platform, Backend, Agents, Schemas, Utils",
29
+ "Environment": "Development",
30
+ })
31
+
32
+
33
+ def pytest_collection_modifyitems(items):
34
+ """Auto-assign category markers based on file path."""
35
+ for item in items:
36
+ # Get test file path
37
+ test_path = str(item.fspath)
38
+
39
+ # Assign ATDD lifecycle markers
40
+ if "atdd/planner/" in test_path:
41
+ item.add_marker(pytest.mark.planner)
42
+ elif "atdd/tester/" in test_path:
43
+ item.add_marker(pytest.mark.tester)
44
+ elif "atdd/coder/" in test_path:
45
+ item.add_marker(pytest.mark.coder)
46
+
47
+ # Assign legacy/component markers
48
+ elif "platform_validation" in test_path:
49
+ item.add_marker(pytest.mark.platform)
50
+ elif "python/" in test_path:
51
+ item.add_marker(pytest.mark.backend)
52
+ elif ".claude/agents/" in test_path:
53
+ item.add_marker(pytest.mark.agents)
54
+ elif ".claude/schemas/" in test_path:
55
+ item.add_marker(pytest.mark.schemas)
56
+ elif ".claude/utils/" in test_path:
57
+ item.add_marker(pytest.mark.utils)
58
+ elif "contracts/" in test_path:
59
+ item.add_marker(pytest.mark.contracts)
60
+ elif "telemetry/" in test_path:
61
+ item.add_marker(pytest.mark.telemetry)
62
+ elif "web/" in test_path:
63
+ item.add_marker(pytest.mark.frontend)
64
+
65
+
66
+ def pytest_html_report_title(report):
67
+ """Customize HTML report title."""
68
+ report.title = "Wagons Platform - Comprehensive Test Report"
69
+
70
+
71
+ def pytest_html_results_table_header(cells):
72
+ """Add category column to results table."""
73
+ cells.insert(1, '<th>Category</th>')
74
+
75
+
76
+ def pytest_html_results_table_row(report, cells):
77
+ """Add category to each test row."""
78
+ category = "Unknown"
79
+
80
+ if hasattr(report, 'nodeid'):
81
+ path = report.nodeid
82
+
83
+ # ATDD lifecycle categories
84
+ if 'atdd/planner/' in path:
85
+ category = '📋 Planner'
86
+ elif 'atdd/tester/' in path:
87
+ category = '🧪 Tester'
88
+ elif 'atdd/coder/' in path:
89
+ category = '⚙️ Coder'
90
+ # Legacy categories
91
+ elif 'platform_validation' in path:
92
+ category = '🗺️ Platform'
93
+ elif 'python/' in path:
94
+ category = '🐍 Backend'
95
+ elif '.claude/agents/' in path:
96
+ category = '🤖 Agents'
97
+ elif '.claude/schemas/' in path:
98
+ category = '📋 Schemas'
99
+ elif '.claude/utils/' in path:
100
+ category = '🔧 Utils'
101
+ elif 'contracts/' in path:
102
+ category = '📄 Contracts'
103
+ elif 'telemetry/' in path:
104
+ category = '📊 Telemetry'
105
+ elif 'web/' in path:
106
+ category = '💙 Frontend'
107
+
108
+ cells.insert(1, f'<td>{category}</td>')
109
+
110
+
111
+ def pytest_html_results_summary(prefix, summary, postfix):
112
+ """Add custom summary header."""
113
+ prefix.extend([
114
+ '<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); '
115
+ 'padding: 30px; border-radius: 10px; color: white; margin: 20px 0; text-align: center;">'
116
+ '<h1 style="margin: 0 0 15px 0; font-size: 32px;">🚀 Wagons Platform Test Suite</h1>'
117
+ '<p style="margin: 0; opacity: 0.9; font-size: 18px;">Comprehensive validation across all components</p>'
118
+ '<div style="margin-top: 20px; display: flex; gap: 15px; justify-content: center; flex-wrap: wrap;">'
119
+ '<span style="background: rgba(255,255,255,0.2); padding: 8px 16px; border-radius: 20px;">🗺️ Platform</span>'
120
+ '<span style="background: rgba(255,255,255,0.2); padding: 8px 16px; border-radius: 20px;">🐍 Backend</span>'
121
+ '<span style="background: rgba(255,255,255,0.2); padding: 8px 16px; border-radius: 20px;">🤖 Agents</span>'
122
+ '<span style="background: rgba(255,255,255,0.2); padding: 8px 16px; border-radius: 20px;">📋 Schemas</span>'
123
+ '<span style="background: rgba(255,255,255,0.2); padding: 8px 16px; border-radius: 20px;">🔧 Utils</span>'
124
+ '</div>'
125
+ '</div>'
126
+ ])
@@ -0,0 +1 @@
1
+ """Planner audits, conventions and schemas."""
@@ -0,0 +1,538 @@
1
+ version: "1.0"
2
+ name: "Acceptance Convention"
3
+ description: "Convention for acceptance criteria generation with Gherkin and harness types"
4
+
5
+ # Acceptance structure defined in schema
6
+ structure:
7
+ $ref: "schemas:planner:acceptance"
8
+
9
+ # Abstract Fields for Stakeholder Readability (within each section)
10
+ abstract_fields:
11
+ description: "Gherkin-style abstract narrative within given/when/then sections for human readability"
12
+ purpose: "Enable stakeholder review and WMBT verbosity with business-focused Gherkin narratives"
13
+ usage: "Optional - enhances acceptance criteria with natural language alongside structured data"
14
+ location: "Within each section: given.abstract, when.abstract, then.abstract"
15
+
16
+ fields:
17
+ given_abstract:
18
+ location: "given.abstract"
19
+ type: "array of strings"
20
+ constraint: "minItems: 1"
21
+ required: true
22
+ description: "Gherkin Given statements describing preconditions (REQUIRED)"
23
+ pattern: "Each item describes a single precondition or setup state"
24
+ example:
25
+ - "appendix.convention.yaml defines manifest structure"
26
+ - "User account exists in the database"
27
+ - "Valid credentials are provided"
28
+
29
+ when_abstract:
30
+ location: "when.abstract"
31
+ type: "string"
32
+ constraint: "minLength: 5"
33
+ required: true
34
+ description: "Gherkin When statement describing the trigger action (REQUIRED)"
35
+ pattern: "Present tense, clear actor and action"
36
+ example: "User submits login form with credentials"
37
+
38
+ then_abstract:
39
+ location: "then.abstract"
40
+ type: "array of strings"
41
+ constraint: "minItems: 1"
42
+ required: true
43
+ description: "Gherkin Then statements describing expected outcomes (REQUIRED)"
44
+ pattern: "Each item describes a single observable outcome"
45
+ example:
46
+ - "Wagon manifest includes appendices: [] array at root level"
47
+ - "WMBT files include appendices: [] array"
48
+ - "Feature manifests include appendices: [] array"
49
+ - "Resolver can resolve appendix paths using URN pattern"
50
+
51
+ relationship_to_structured_fields:
52
+ complementary: "Abstract fields coexist with structured fields within same section"
53
+ purpose_distinction: "Abstract for stakeholders (Gherkin), structured for machines (test generation)"
54
+ required: "All abstract fields (given.abstract, when.abstract, then.abstract) are REQUIRED"
55
+ identity_purpose: "identity.purpose already serves as scenario name - no separate top-level name needed"
56
+ example: |
57
+ given:
58
+ abstract: ["User is logged in", "Account has credits"]
59
+ auth: {required: true, type: "bearer"}
60
+ data: [{user_id: "123", credits: 100}]
61
+
62
+ when:
63
+ abstract: "User purchases a product"
64
+ action: "request"
65
+ target: "/api/purchase"
66
+ parameters: {product_id: "abc"}
67
+
68
+ then:
69
+ abstract: ["Purchase succeeds", "Credits are deducted", "Receipt is generated"]
70
+ assertions: [{type: "equals", target: "status", value: 200}]
71
+
72
+ # URN Generation
73
+ urn_generation:
74
+ utility: "utils.graph.URNBuilder"
75
+ method: "URNBuilder.acceptance(wagon_id, wmbt_id, harness_code, seq, slug=None)"
76
+ pattern: "acc:{wagon}:{wmbt_id}-{harness}-{NNN}[-{slug}]"
77
+
78
+ example: |
79
+ from utils.graph import URNBuilder
80
+ urn = URNBuilder.acceptance("authenticate-user", "C004", "E2E", "019")
81
+ # Returns: "acc:authenticate-user:C004-E2E-019"
82
+
83
+ urn_with_slug = URNBuilder.acceptance("maintain-ux", "C004", "E2E", "019", "user-connection")
84
+ # Returns: "acc:maintain-ux:C004-E2E-019-user-connection"
85
+
86
+ rationale: |
87
+ - Makes WMBT tie explicit (wmbt_id = step code + seq, e.g., C004)
88
+ - Bakes in harness visibility for quick routing
89
+ - Keeps per-harness sequence (NNN) and allows optional slug for readability
90
+ - Enforces colon = hierarchy, dash = facet cluster
91
+
92
+ validation:
93
+ pattern: "^acc:[a-z][a-z0-9-]*:[DLPCEMYRK][0-9]{3}-(UNIT|HTTP|EVENT|WS|E2E|A11Y|VIS|METRIC|JOB|DB|SEC|LOAD|SCRIPT|WIDGET|GOLDEN|BLOC|INTEGRATION|RLS|EDGE|REALTIME|STORAGE)-[0-9]{3}(?:-[a-z0-9-]+)?$"
94
+ description: "Enforces colon for hierarchy (acc:wagon:wmbt_id) and dash-joined facet cluster (-harness-NNN[-slug])"
95
+
96
+ legacy_format:
97
+ pattern: "acc:{wagon}:{nnn}:{acceptance_id}"
98
+ example: "acc:authenticate-user:001:AC-EXEC-201"
99
+ note: "Old format - being migrated to new pattern"
100
+
101
+ # Harness code mapping (authoritative)
102
+ harness_codes:
103
+ unit: UNIT
104
+ http: HTTP
105
+ event: EVENT
106
+ ws: WS
107
+ e2e: E2E
108
+ a11y: A11Y
109
+ visual: VIS
110
+ metric: METRIC
111
+ job: JOB
112
+ db: DB
113
+ sec: SEC
114
+ load: LOAD
115
+ script: SCRIPT
116
+ widget: WIDGET
117
+ golden: GOLDEN
118
+ bloc: BLOC
119
+ integration: INTEGRATION
120
+ rls: RLS
121
+ edge_function: EDGE
122
+ realtime: REALTIME
123
+ storage: STORAGE
124
+
125
+ generators:
126
+ id:
127
+ prompt: "Compose the acceptance id with the step code and a zero-padded index (AC-{STEP}-{NNN})."
128
+ pattern: "AC-{STEP}-{NNN}"
129
+ source: "conventions:planner:acceptance:id_mapping"
130
+ note: "Legacy format - kept for backward compatibility in identity.id field"
131
+
132
+ urn:
133
+ prompt: "Derive the URN from the wagon slug, WMBT ID, harness code, and sequence using URNBuilder.acceptance."
134
+ pattern: "acc:{wagon}:{wmbt_id}-{harness}-{NNN}[-{slug}]"
135
+ example: "acc:maintain-ux:C004-E2E-019-user-connection"
136
+ parts:
137
+ wagon: "Parent wagon identifier (kebab-case)"
138
+ wmbt_id: "WMBT step code + seq (e.g., C004, E001)"
139
+ harness: "Harness code (UPPERCASE from harness_codes mapping)"
140
+ NNN: "Zero-padded per-harness acceptance sequence (001-999)"
141
+ slug: "Optional kebab-case descriptor for readability"
142
+
143
+ harness:
144
+ prompt: "Select the harness that best exercises the outcome (unit/http/event/ws/e2e/a11y/visual/metric/job/db/sec/load/script)."
145
+ source: "conventions:planner:acceptance:harness_types"
146
+ route:
147
+ prompt: "Populate route.layers and route.sequence so actions flow from presentation → application → domain → integration as needed."
148
+ pattern: "{layer}.{action}"
149
+ source: "conventions:planner:acceptance:route_construction"
150
+ given:
151
+ prompt: "Declare only the preconditions needed (auth, builders, time, stubbing, knobs) before the action runs."
152
+ source: "conventions:planner:acceptance:gherkin_structure.given"
153
+ when:
154
+ prompt: "Describe the trigger using the harness-specific shape (http request details, unit target, event topic, etc.)."
155
+ source: "conventions:planner:acceptance:gherkin_structure.when"
156
+ then:
157
+ prompt: "List assertions that prove the outcome (status, body, headers, error, metrics, etc.)."
158
+ source: "conventions:planner:acceptance:gherkin_structure.then"
159
+
160
+ guidelines:
161
+ acceptance_cap: "Keep acceptances ≤5 per WMBT; if you need more, split the WMBT into clearer outcomes."
162
+ metric_binding: "Each acceptance maps to exactly one metric_id from plan/_lego/acceptance-metrics.yaml (no mixed measures)."
163
+ lens_dimension_dependency: "Respect WMBT rules: one dimension and one lens_ref per WMBT; acceptances inherit context from the parent WMBT."
164
+ collocation: "Store WMBT, acceptances, tests, and generated artifacts together to keep history and review cohesive."
165
+
166
+ related_resources:
167
+ metrics_catalog: "conventions:criteria:metrics"
168
+ template_registry: ".claude/templates/tester/templates.manifest.yaml"
169
+ blocks: "conventions:criteria"
170
+
171
+ planes:
172
+ description: "Keyword cues for selecting test layer planes when routing"
173
+ table:
174
+ ui: ["display", "visible", "screen", "render", "animation"]
175
+ ux: ["understand", "clarity", "steps", "easy", "confusing"]
176
+ be: ["validate", "apply", "compute", "reconcile", "rule"]
177
+ nw: ["request", "response", "timeout", "websocket", "stream"]
178
+ db: ["query", "index", "transaction", "lock", "row"]
179
+ st: ["asset", "download", "upload", "cache", "blob", "cdn"]
180
+ tm: ["event", "metrics", "trace", "ingest", "drop"]
181
+ sc: ["schema", "contract", "version", "field", "json"]
182
+ au: ["login", "token", "permission", "rate-limit", "403"]
183
+ fn: ["price", "balance", "payout", "token"]
184
+ if: ["cpu", "memory", "pod", "node", "gpu"]
185
+
186
+ # Harness types and their typical usage
187
+ harness_types:
188
+ unit:
189
+ description: "Unit tests for isolated logic"
190
+ prompt: "Use when verifying pure functions or domain policies without IO."
191
+ typical_layers: ["domain", "application"]
192
+
193
+ http:
194
+ description: "HTTP API endpoint tests"
195
+ prompt: "Exercise REST/GraphQL handlers via network boundaries."
196
+ typical_layers: ["integration", "application"]
197
+
198
+ event:
199
+ description: "Event-driven behavior tests"
200
+ prompt: "Assert publish/consume flows through message topics."
201
+ typical_layers: ["application", "integration"]
202
+
203
+ ws:
204
+ description: "WebSocket real-time tests"
205
+ prompt: "Validate realtime subscriptions and streaming semantics."
206
+ typical_layers: ["integration"]
207
+
208
+ e2e:
209
+ description: "End-to-end user journey tests"
210
+ prompt: "Drive the UI like a user across presentation + backend layers."
211
+ typical_layers: ["presentation"]
212
+
213
+ a11y:
214
+ description: "Accessibility compliance tests"
215
+ prompt: "Check accessibility tree, focus order, contrast ratios."
216
+ typical_layers: ["presentation"]
217
+
218
+ visual:
219
+ description: "Visual regression tests"
220
+ prompt: "Compare rendered snapshots or layout diffs."
221
+ typical_layers: ["presentation"]
222
+
223
+ metric:
224
+ description: "Performance metric tests"
225
+ prompt: "Assert telemetry counters, spans, or service-level thresholds."
226
+ typical_layers: ["application", "integration"]
227
+
228
+ job:
229
+ description: "Background job/task tests"
230
+ prompt: "Trigger schedulers or workers and verify side effects."
231
+ typical_layers: ["application"]
232
+
233
+ db:
234
+ description: "Database operation tests"
235
+ prompt: "Validate persistence semantics using real repositories/queries."
236
+ typical_layers: ["integration"]
237
+
238
+ sec:
239
+ description: "Security tests"
240
+ prompt: "Probe authz, permissions, or threat scenarios."
241
+ typical_layers: ["application", "integration"]
242
+
243
+ load:
244
+ description: "Load and stress tests"
245
+ prompt: "Measure system resilience under concurrent demand."
246
+ typical_layers: ["integration"]
247
+
248
+ script:
249
+ description: "Script execution tests"
250
+ prompt: "Invoke maintenance or CLI scripts end-to-end."
251
+ typical_layers: ["application"]
252
+
253
+ widget:
254
+ description: "Widget/component tests"
255
+ prompt: "Test isolated UI widgets or components."
256
+ typical_layers: ["presentation"]
257
+
258
+ golden:
259
+ description: "Golden file tests"
260
+ prompt: "Compare output against golden reference files."
261
+ typical_layers: ["presentation", "application"]
262
+
263
+ bloc:
264
+ description: "BLoC pattern tests"
265
+ prompt: "Test Business Logic Component state management."
266
+ typical_layers: ["application"]
267
+
268
+ integration:
269
+ description: "Integration tests"
270
+ prompt: "Test integration between multiple components or services."
271
+ typical_layers: ["integration"]
272
+
273
+ rls:
274
+ description: "Row-level security tests"
275
+ prompt: "Validate database row-level security policies."
276
+ typical_layers: ["integration"]
277
+
278
+ edge_function:
279
+ description: "Edge function tests"
280
+ prompt: "Test serverless edge functions and their behavior."
281
+ typical_layers: ["integration"]
282
+
283
+ realtime:
284
+ description: "Realtime subscription tests"
285
+ prompt: "Validate realtime data subscriptions and updates."
286
+ typical_layers: ["integration"]
287
+
288
+ storage:
289
+ description: "Storage operation tests"
290
+ prompt: "Test file storage, uploads, and retrieval operations."
291
+ typical_layers: ["integration"]
292
+
293
+ # ID generation pattern
294
+ id_pattern: "AC-{STEP}-{NNN}"
295
+ id_mapping:
296
+ define: "DEF"
297
+ locate: "LOC"
298
+ prepare: "PREP"
299
+ confirm: "CONF"
300
+ execute: "EXEC"
301
+ monitor: "MON"
302
+ modify: "MOD"
303
+ resolve: "RES"
304
+ conclude: "CONC"
305
+
306
+ # Route sequence construction
307
+ route_construction:
308
+ description: "How to build route.sequence based on test flow"
309
+ prompt: "Describe the layer transitions the test exercises in execution order."
310
+ pattern: "{layer}.{action}"
311
+ examples:
312
+ presentation_flow:
313
+ - "presentation.command" # User initiates action
314
+ - "application.use_case" # Business logic processes
315
+ - "domain.validate" # Domain rules applied
316
+ - "integration.persist" # Data saved
317
+
318
+ query_flow:
319
+ - "presentation.query" # User requests data
320
+ - "application.query" # Query handled
321
+ - "integration.read" # Data fetched
322
+
323
+ event_flow:
324
+ - "integration.call_external" # External event received
325
+ - "application.aggregate" # Event aggregated
326
+ - "domain.mutate" # State changed
327
+ - "integration.persist" # Change persisted
328
+
329
+
330
+ # Maximum acceptances
331
+ max_per_wmbt: 5
332
+ expected_ratios:
333
+ acceptance_to_test: "1:1" # One acceptance → one test
334
+ test_to_component: "N:1" # Many tests → one component
335
+
336
+ # Layer routing based on harness type
337
+ layer_routing:
338
+ presentation: ["presentation.command", "presentation.query", "presentation.display"]
339
+ application: ["application.use_case", "application.query", "application.aggregate"]
340
+ domain: ["domain.create", "domain.validate", "domain.mutate", "domain.policy"]
341
+ integration: ["integration.read", "integration.persist", "integration.call_external"]
342
+
343
+ # Given/When/Then Structure Guide
344
+ gherkin_structure:
345
+ given:
346
+ description: "Setup and preconditions"
347
+ prompt: "Capture only the state required for the acceptance to run deterministically."
348
+ fields:
349
+ auth:
350
+ description: "Authentication context"
351
+ prompt: "List credentials/scopes required prior to executing the WHEN."
352
+ example:
353
+ scopes: ["read:users", "write:users"]
354
+ builders:
355
+ description: "Test data builders to set up state"
356
+ prompt: "Reference builders to create domain objects with minimal parameters."
357
+ example:
358
+ - ref: "UserBuilder"
359
+ as: "testUser"
360
+ params: {email: "test@example.com"}
361
+ time:
362
+ description: "Time-related setup"
363
+ prompt: "Freeze time or advance clocks when timing impacts the assertions."
364
+ example:
365
+ freeze_at: "2024-01-01T00:00:00Z"
366
+ stubbing:
367
+ description: "External dependency stubs"
368
+ prompt: "Declare mock policies or capability overrides needed for deterministic runs."
369
+ example:
370
+ policy: "strict"
371
+ overrides:
372
+ - capability: "payment-api"
373
+ mode: "mock"
374
+ knobs:
375
+ description: "Feature flags and configuration"
376
+ prompt: "Toggle only the flags relevant to this acceptance."
377
+ example:
378
+ featureX: true
379
+ maxRetries: 3
380
+
381
+ when:
382
+ description: "Action or trigger - varies by harness type (REQUIRED)"
383
+ prompt: "Express the single trigger that moves the system under test. The when.abstract field is REQUIRED."
384
+ required: true
385
+ harness_specific:
386
+ http:
387
+ required: ["method", "path"]
388
+ prompt: "Define the HTTP method/path and payload sent to the endpoint."
389
+ example:
390
+ method: "POST"
391
+ path: "/api/users"
392
+ headers: {"Content-Type": "application/json"}
393
+ body: {name: "John", email: "john@example.com"}
394
+
395
+ unit:
396
+ required: ["target"]
397
+ prompt: "Call the unit under test with explicit arguments/state."
398
+ example:
399
+ target: "UserService.createUser"
400
+ args: {userData: {name: "John"}}
401
+
402
+ event:
403
+ required: ["topic"]
404
+ prompt: "Publish or consume the event topic and payload being validated."
405
+ example:
406
+ topic: "user.created"
407
+ payload: {userId: "123", timestamp: "2024-01-01T00:00:00Z"}
408
+
409
+ ws:
410
+ prompt: "Open/subscribe to websocket channels relevant to the assertion."
411
+ example:
412
+ url: "ws://localhost:8080/events"
413
+ subscribe_msg: {action: "subscribe", channel: "updates"}
414
+
415
+ e2e:
416
+ prompt: "List the user interactions or navigation steps to perform end-to-end."
417
+ example:
418
+ url: "http://localhost:3000/login"
419
+ actions: ["fill #email", "fill #password", "click #submit"]
420
+
421
+ then:
422
+ description: "Expected outcomes - array of assertions (REQUIRED)"
423
+ prompt: "Assert observable effects that prove the acceptance criteria satisfied. The then.abstract field is REQUIRED."
424
+ required: true
425
+ assertion_kinds:
426
+ - kind: "status"
427
+ prompt: "Use when verifying response status codes or job exit codes."
428
+ example: {kind: "status", expect: 200}
429
+
430
+ - kind: "body"
431
+ prompt: "Compare structured payloads (JSON/object fields)."
432
+ example: {kind: "body", expect: {id: "123", name: "John"}}
433
+
434
+ - kind: "headers"
435
+ prompt: "Validate response headers or metadata returned."
436
+ example: {kind: "headers", expect: {"Content-Type": "application/json"}}
437
+
438
+ - kind: "error"
439
+ prompt: "Assert errors, codes, or validation messages."
440
+ example: {kind: "error", expect: {code: "USER_EXISTS", message: "User already exists"}}
441
+
442
+ - kind: "event_published"
443
+ example: {kind: "event_published", expect: {topic: "user.created", payload: {userId: "123"}}}
444
+
445
+ - kind: "state_changed"
446
+ example: {kind: "state_changed", expect: {entity: "User", id: "123", field: "status", value: "active"}}
447
+
448
+ - kind: "metric"
449
+ example: {kind: "metric", expect: {name: "response_time", operator: "<", value: 1000}}
450
+
451
+ signal:
452
+ description: "Telemetry signals emitted when acceptance executes (OpenTelemetry + analytics) - REQUIRED"
453
+ prompt: "Define what metrics, traces, logs, and events prove this acceptance works in production. Extract operational expectations (latency, errors) → metrics. Extract user actions (conversions, feature usage) → events."
454
+ required: true
455
+
456
+ fields:
457
+ metrics:
458
+ description: "OpenTelemetry metrics for observability using artifact-based URN naming"
459
+ prompt: "Derive from 'then' quantifiable expectations. Use format: telemetry:metric:{plane}:{domain}:{resource}[.{category}]:{measure}. Artifact must exist in contracts/_artifacts.yaml. No operations/wagons in URN."
460
+ naming_rules:
461
+ - "Format: telemetry:metric:{plane}:{artifact}[.{category}]:{measure}"
462
+ - "plane: ui | ux | be | db | nw | st | tm | sc | au | fn | if"
463
+ - "artifact: domain:resource (e.g., decision:chosen, match:result, ux:foundations.colors)"
464
+ - "category: optional third facet for nested resources (e.g., colors, typography, spacing)"
465
+ - "measure: latency | duration | throughput | error_rate | success_rate | count | size | age | staleness | freshness"
466
+ - "Entity artifacts (nouns) use: count, size, age, staleness, freshness"
467
+ - "Event artifacts (past-tense verbs) use: latency, duration, throughput, error_rate, success_rate"
468
+ - "Operations/wagons go in attributes, NOT in URN"
469
+ example:
470
+ - name: "telemetry:metric:be:order:created:duration"
471
+ type: "histogram"
472
+ threshold: "200ms"
473
+ aggregation: "p95"
474
+ attributes: ["operation:persist", "phase:commit"]
475
+
476
+ traces:
477
+ description: "OpenTelemetry distributed trace spans using artifact-based URN naming"
478
+ prompt: "Define expected spans during execution. Use format: telemetry:trace:{plane}:{domain}:{resource}[.{category}]. No measure segment for traces."
479
+ naming_rules:
480
+ - "Format: telemetry:trace:{plane}:{artifact}[.{category}]"
481
+ - "No measure segment (traces are execution flows, not metrics)"
482
+ - "category: optional facet for nested resources (follows same pattern as metrics)"
483
+ example:
484
+ - name: "telemetry:trace:be:order:created"
485
+ kind: "server"
486
+ attributes: ["order_id", "user_id"]
487
+
488
+ logs:
489
+ description: "OpenTelemetry structured logs (optional URN naming)"
490
+ prompt: "Expected log patterns with severity levels. Optional name field for structured telemetry."
491
+ naming_rules:
492
+ - "Format (optional): telemetry:log:{plane}:{artifact}[.{category}]"
493
+ - "name field is optional; body is required"
494
+ - "category: optional facet for nested resources"
495
+ example:
496
+ - body: "Order created successfully"
497
+ severity: "info"
498
+ name: "telemetry:log:be:order:created"
499
+
500
+ events:
501
+ description: "Analytics events for product tracking (Segment/Mixpanel/Amplitude) or OTel events"
502
+ prompt: "Derive from 'when' user actions. Use telemetry URN for OTel events, or analytics naming for product events. Resource must be past-tense verb from lexicon."
503
+ naming_rules:
504
+ - "Telemetry URN: telemetry:event:{plane}:{artifact}[.{category}]"
505
+ - "Analytics: Title Case with Spaces (e.g., 'Order Created')"
506
+ - "Resource must be past-tense verb from lexicon: started, finished, chosen, validated, created, etc."
507
+ - "category: optional facet for nested resources"
508
+ example:
509
+ - name: "telemetry:event:be:order:created"
510
+ properties: ["order_id", "user_id", "total"]
511
+ - name: "Order Created"
512
+ properties: ["order_id", "total"]
513
+ tracking_plan_ref: "order_events_v1"
514
+
515
+ examples:
516
+ full_signal_with_telemetry_urns:
517
+ metrics:
518
+ - name: "telemetry:metric:be:order:created:duration"
519
+ type: "histogram"
520
+ threshold: "200ms"
521
+ attributes: ["operation:persist"]
522
+ traces:
523
+ - name: "telemetry:trace:be:order:created"
524
+ kind: "server"
525
+ logs:
526
+ - body: "Order created"
527
+ severity: "info"
528
+ name: "telemetry:log:be:order:created"
529
+ events:
530
+ - name: "telemetry:event:be:order:created"
531
+ properties: ["order_id", "total"]
532
+
533
+ # Extraction: Pure conversational approach
534
+ extraction:
535
+ description: "Ask user directly for missing context (no inference, no suggestions)"
536
+
537
+ wagon_inference:
538
+ prompt: "Which wagon should this acceptance belong to?"