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,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Database Test Harness Template",
4
+ "description": "Template for Supabase database operation tests",
5
+ "language": "typescript",
6
+ "framework": "vitest",
7
+ "category": "backend",
8
+ "template": "\n// URN: {urn}\nimport { test, expect } from 'vitest';\nimport { createClient } from '@supabase/supabase-js';\n\ntest('{test_name}', async () => {{\n const supabaseUrl = process.env.SUPABASE_URL;\n const supabaseKey = process.env.SUPABASE_ANON_KEY;\n const supabase = createClient(supabaseUrl, supabaseKey);\n\n // Given\n {given_setup}\n\n // When\n const startTime = Date.now();\n const {{ data, error, count }} = await supabase\n .from('{table}')\n .{operation}({operation_params})\n {filters}\n {options};\n const queryTime = Date.now() - startTime;\n\n // Then\n {then_assertions}\n\n console.log(JSON.stringify({{\n urn: '{urn}',\n status: 'PASS',\n details: {{ table: '{table}', operation: '{operation}', query_time_ms: queryTime }}\n }}));\n}});\n",
9
+ "variables": [
10
+ "urn",
11
+ "test_name",
12
+ "given_setup",
13
+ "table",
14
+ "operation",
15
+ "operation_params",
16
+ "filters",
17
+ "options",
18
+ "then_assertions"
19
+ ]
20
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "E2E Test Harness Template",
4
+ "description": "Template for end-to-end browser tests",
5
+ "language": "typescript",
6
+ "framework": "playwright",
7
+ "category": "frontend",
8
+ "template": "\ndescribe('{test_name}', () => {{\n let page: Page;\n\n beforeEach(async () => {{\n page = await browser.newPage();\n }});\n\n afterEach(async () => {{\n await page.close();\n }});\n\n it('{acceptance_name}', async () => {{\n // Given\n await page.goto('{e2e_url}');\n {given_setup}\n\n // When\n {when_action}\n\n // Then\n {then_assertions}\n }});\n}});\n",
9
+ "variables": [
10
+ "test_name",
11
+ "acceptance_name",
12
+ "e2e_url",
13
+ "given_setup",
14
+ "when_action",
15
+ "then_assertions"
16
+ ]
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Edge Function Test Harness Template",
4
+ "description": "Template for testing Supabase Edge Functions",
5
+ "language": "typescript",
6
+ "framework": "vitest",
7
+ "category": "backend",
8
+ "template": "\n// URN: {urn}\nimport { test, expect } from 'vitest';\nimport axios from 'axios';\n\ntest('{test_name}', async () => {{\n const functionUrl = `${{process.env.SUPABASE_URL}}/functions/v1/{function_name}`;\n const headers = {{\n 'Authorization': `Bearer ${{process.env.SUPABASE_ANON_KEY}}`,\n 'Content-Type': 'application/json'\n }};\n\n // Given\n {given_setup}\n\n // When\n const response = await axios.post(\n functionUrl,\n {payload},\n {{ headers, validateStatus: () => true }}\n );\n\n // Then\n {then_assertions}\n\n console.log(JSON.stringify({{\n urn: '{urn}',\n status: 'PASS',\n details: {{ function: '{function_name}', status: response.status }}\n }}));\n}});\n",
9
+ "variables": [
10
+ "urn",
11
+ "test_name",
12
+ "function_name",
13
+ "given_setup",
14
+ "payload",
15
+ "then_assertions"
16
+ ]
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Event Test Harness Template",
4
+ "description": "Template for event-driven/message bus tests",
5
+ "language": "typescript",
6
+ "framework": "vitest",
7
+ "category": "backend",
8
+ "template": "\ndescribe('{test_name}', () => {{\n let eventBus: EventBus;\n let publishedEvents: any[] = [];\n\n beforeEach(() => {{\n eventBus = new EventBus();\n eventBus.on('*', (event) => publishedEvents.push(event));\n }});\n\n it('{acceptance_name}', async () => {{\n // Given\n {given_setup}\n\n // When\n await eventBus.publish({{\n topic: '{event_topic}',\n payload: {event_payload}\n }});\n\n // Then\n {then_assertions}\n }});\n}});\n",
9
+ "variables": [
10
+ "test_name",
11
+ "acceptance_name",
12
+ "given_setup",
13
+ "event_topic",
14
+ "event_payload",
15
+ "then_assertions"
16
+ ]
17
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "HTTP Test Harness Template",
4
+ "description": "Template for HTTP/REST API tests",
5
+ "language": "typescript",
6
+ "framework": "supertest",
7
+ "category": "backend",
8
+ "template": "\ndescribe('{test_name}', () => {{\n let request: SuperTest<any>;\n\n beforeEach(() => {{\n request = supertest(app);\n }});\n\n it('{acceptance_name}', async () => {{\n // Given\n {given_setup}\n\n // When\n const response = await request\n .{http_method}('{http_path}')\n {http_headers}\n {http_body};\n\n // Then\n {then_assertions}\n }});\n}});\n",
9
+ "variables": [
10
+ "test_name",
11
+ "acceptance_name",
12
+ "given_setup",
13
+ "http_method",
14
+ "http_path",
15
+ "http_headers",
16
+ "http_body",
17
+ "then_assertions"
18
+ ]
19
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Job Test Harness Template",
4
+ "description": "Template for background job/cron tests",
5
+ "language": "python",
6
+ "framework": "pytest",
7
+ "category": "integration",
8
+ "template": "\n# URN: {urn}\nimport pytest\nimport json\nimport time\n{imports}\n\ndef test_{test_name}():\n # Given\n {given_setup}\n \n # When\n start_time = time.time()\n result = {job_invocation}\n duration = time.time() - start_time\n \n # Then\n {then_assertions}\n \n print(json.dumps({{\n 'urn': '{urn}',\n 'status': 'PASS',\n 'details': {{\n 'job': '{job_name}',\n 'duration_seconds': duration,\n 'result': str(result)\n }}\n }}))\n",
9
+ "variables": [
10
+ "urn",
11
+ "test_name",
12
+ "imports",
13
+ "given_setup",
14
+ "job_name",
15
+ "job_invocation",
16
+ "then_assertions"
17
+ ]
18
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Load Test Harness Template",
4
+ "description": "Template for load/performance tests using k6",
5
+ "language": "javascript",
6
+ "framework": "k6",
7
+ "category": "integration",
8
+ "template": "\n// URN: {urn}\nimport http from 'k6/http';\nimport {{ check, sleep }} from 'k6';\n\nexport const options = {{\n vus: {vus},\n duration: '{duration}',\n thresholds: {{\n http_req_duration: ['p(95)<{threshold_ms}'],\n }},\n}};\n\nexport default function() {{\n // Given\n {given_setup}\n\n // When\n const response = http.{method}('{url}', {params});\n\n // Then\n check(response, {{\n 'status is {expected_status}': (r) => r.status === {expected_status},\n {additional_checks}\n }});\n\n sleep(1);\n}}\n",
9
+ "variables": [
10
+ "urn",
11
+ "vus",
12
+ "duration",
13
+ "threshold_ms",
14
+ "given_setup",
15
+ "method",
16
+ "url",
17
+ "params",
18
+ "expected_status",
19
+ "additional_checks"
20
+ ]
21
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Metric Test Harness Template",
4
+ "description": "Template for metric/monitoring tests",
5
+ "language": "python",
6
+ "framework": "pytest",
7
+ "category": "integration",
8
+ "template": "\n# URN: {urn}\nimport pytest\nimport json\nfrom datetime import datetime, timedelta\n{imports}\n\ndef test_{test_name}():\n # Given\n {given_setup}\n \n # When\n start_time = datetime.now() - timedelta(minutes={window_minutes})\n metrics = {metric_query}\n \n # Then\n {then_assertions}\n \n print(json.dumps({{\n 'urn': '{urn}',\n 'status': 'PASS',\n 'details': {{\n 'metric': '{metric_name}',\n 'value': metrics.get('value')\n }}\n }}))\n",
9
+ "variables": [
10
+ "urn",
11
+ "test_name",
12
+ "imports",
13
+ "given_setup",
14
+ "window_minutes",
15
+ "metric_query",
16
+ "metric_name",
17
+ "then_assertions"
18
+ ]
19
+ }
@@ -0,0 +1,139 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Contract Pack Manifest",
4
+ "description": "Schema for contract packs that define I/O interfaces with strict validation",
5
+ "type": "object",
6
+ "required": ["feature", "version", "map", "acceptance_refs"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "feature": {
10
+ "type": "string",
11
+ "pattern": "^[a-z][a-z0-9-]*$",
12
+ "description": "Feature identifier in kebab-case"
13
+ },
14
+ "version": {
15
+ "type": "integer",
16
+ "minimum": 1,
17
+ "description": "Pack version number (increments on breaking changes)"
18
+ },
19
+ "acceptance_refs": {
20
+ "type": "array",
21
+ "minItems": 1,
22
+ "items": {
23
+ "type": "string",
24
+ "pattern": "^\\.\\./\\.\\./plan/.+\\.yaml$"
25
+ },
26
+ "description": "References to acceptance YAML files"
27
+ },
28
+ "map": {
29
+ "type": "object",
30
+ "required": ["consume", "produce"],
31
+ "additionalProperties": false,
32
+ "properties": {
33
+ "consume": {
34
+ "type": "array",
35
+ "maxItems": 3,
36
+ "items": {"$ref": "#/definitions/io_item"},
37
+ "description": "Inputs consumed by this feature (cap: 3)"
38
+ },
39
+ "produce": {
40
+ "type": "array",
41
+ "maxItems": 2,
42
+ "items": {"$ref": "#/definitions/io_item"},
43
+ "description": "Outputs produced by this feature (cap: 2)"
44
+ }
45
+ }
46
+ },
47
+ "schemas": {
48
+ "type": "array",
49
+ "items": {"type": "string"},
50
+ "description": "List of schema files generated for this pack"
51
+ },
52
+ "ports": {
53
+ "type": "array",
54
+ "items": {"type": "string"},
55
+ "description": "List of port interface files"
56
+ },
57
+ "tests": {
58
+ "type": "array",
59
+ "items": {"type": "string"},
60
+ "description": "List of generated RED test files"
61
+ }
62
+ },
63
+ "definitions": {
64
+ "io_item": {
65
+ "type": "object",
66
+ "required": ["name", "scope", "kind", "port"],
67
+ "additionalProperties": false,
68
+ "properties": {
69
+ "name": {
70
+ "type": "string",
71
+ "pattern": "^[a-z]+:[a-z][a-z0-9-]*$",
72
+ "description": "Typed identifier (e.g., match:dilemma.current)"
73
+ },
74
+ "scope": {
75
+ "type": "string",
76
+ "enum": ["external", "internal"],
77
+ "description": "External crosses port boundary, internal stays in domain"
78
+ },
79
+ "kind": {
80
+ "type": "string",
81
+ "enum": [
82
+ "dto", "command", "query", "event", "message", "notification",
83
+ "artifact", "config", "metric", "clock", "id", "job", "stream", "saga",
84
+ "entity", "value", "mutation", "state", "domain-input"
85
+ ],
86
+ "description": "Type of I/O artifact"
87
+ },
88
+ "port": {
89
+ "type": "string",
90
+ "enum": ["Repo", "Http", "Bus", "Knowledge", "Runner", "Clock", "IdGen", "Stream", "(none)"],
91
+ "description": "Port through which the I/O flows"
92
+ },
93
+ "schema": {
94
+ "type": "string",
95
+ "pattern": "^[a-z]+\\.[a-zA-Z0-9.-]+$",
96
+ "description": "Schema name without version (e.g., event.decision.chosen)"
97
+ },
98
+ "version": {
99
+ "type": "string",
100
+ "pattern": "^v[0-9]+$",
101
+ "description": "Schema version (e.g., v1)"
102
+ },
103
+ "durability": {
104
+ "type": "string",
105
+ "enum": ["transient", "persisted"],
106
+ "description": "Whether the artifact is persisted"
107
+ },
108
+ "idempotent": {
109
+ "type": "boolean",
110
+ "description": "Whether operations are idempotent"
111
+ }
112
+ },
113
+ "allOf": [
114
+ {
115
+ "if": {"properties": {"scope": {"const": "external"}}},
116
+ "then": {
117
+ "required": ["schema", "version"],
118
+ "properties": {"port": {"not": {"const": "(none)"}}},
119
+ "errorMessage": "External I/O requires schema, version, and real port"
120
+ }
121
+ },
122
+ {
123
+ "if": {"properties": {"scope": {"const": "internal"}}},
124
+ "then": {
125
+ "properties": {"port": {"const": "(none)"}},
126
+ "not": {"required": ["version"]},
127
+ "errorMessage": "Internal I/O must have port=(none) and no version"
128
+ }
129
+ },
130
+ {
131
+ "if": {"properties": {"kind": {"enum": ["entity", "value", "mutation", "state", "domain-input"]}}},
132
+ "then": {"properties": {"scope": {"const": "internal"}},
133
+ "errorMessage": "Domain kinds (entity, value, mutation, state, domain-input) must be internal"
134
+ }
135
+ }
136
+ ]
137
+ }
138
+ }
139
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Realtime Test Harness Template",
4
+ "description": "Template for testing Supabase Realtime subscriptions",
5
+ "language": "typescript",
6
+ "framework": "vitest",
7
+ "category": "backend",
8
+ "template": "\n// URN: {urn}\nimport { test, expect } from 'vitest';\nimport { createClient } from '@supabase/supabase-js';\n\ntest('{test_name}', async () => {{\n const supabase = createClient(\n process.env.SUPABASE_URL,\n process.env.SUPABASE_ANON_KEY\n );\n\n const messages = [];\n \n // Given\n {given_setup}\n\n // When\n const channel = supabase\n .channel('{channel_name}')\n .on('{event_type}', {{ event: '{event_filter}' }}, (payload) => {{\n messages.push(payload);\n }})\n .subscribe();\n\n {trigger_action}\n\n await new Promise(resolve => setTimeout(resolve, {wait_ms}));\n\n // Then\n {then_assertions}\n\n await channel.unsubscribe();\n}});\n",
9
+ "variables": [
10
+ "urn",
11
+ "test_name",
12
+ "given_setup",
13
+ "channel_name",
14
+ "event_type",
15
+ "event_filter",
16
+ "trigger_action",
17
+ "wait_ms",
18
+ "then_assertions"
19
+ ]
20
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Row Level Security Test Harness Template",
4
+ "description": "Template for testing RLS policies in Supabase",
5
+ "language": "typescript",
6
+ "framework": "vitest",
7
+ "category": "backend",
8
+ "template": "\n// URN: {urn}\nimport { test, expect } from 'vitest';\nimport { createClient } from '@supabase/supabase-js';\n\ntest('{test_name}', async () => {{\n const supabaseUrl = process.env.SUPABASE_URL;\n \n const testCases = [\n {{\n name: 'anonymous_user',\n key: process.env.SUPABASE_ANON_KEY,\n shouldAccess: {anon_access}\n }},\n {{\n name: 'authenticated_user',\n key: process.env.SUPABASE_USER_KEY,\n shouldAccess: {user_access}\n }}\n ];\n\n const results = [];\n for (const testCase of testCases) {{\n const supabase = createClient(supabaseUrl, testCase.key);\n const {{ data, error }} = await supabase\n .from('{table}')\n .{operation}({operation_params});\n \n const hasAccess = error === null;\n results.push({{\n context: testCase.name,\n expected: testCase.shouldAccess,\n actual: hasAccess,\n passed: hasAccess === testCase.shouldAccess\n }});\n }}\n\n const allPassed = results.every(r => r.passed);\n expect(allPassed).toBe(true);\n}});\n",
9
+ "variables": [
10
+ "urn",
11
+ "test_name",
12
+ "table",
13
+ "operation",
14
+ "operation_params",
15
+ "anon_access",
16
+ "user_access"
17
+ ]
18
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Script Test Harness Template",
4
+ "description": "Template for general script execution tests",
5
+ "language": "shell",
6
+ "framework": "bash",
7
+ "category": "integration",
8
+ "template": "\n#!/bin/bash\n# URN: {urn}\n\n# Given\n{given_setup}\n\n# When\nstart_time=$(date +%s)\noutput=$({script_command} {script_args} 2>&1)\nexit_code=$?\nend_time=$(date +%s)\nduration=$((end_time - start_time))\n\n# Then\nif [ $exit_code -eq {expected_exit_code} ]; then\n status=\"PASS\"\nelse\n status=\"FAIL\"\nfi\n\necho \"{\\\"urn\\\":\\\"{urn}\\\",\\\"status\\\":\\\"$status\\\",\\\"details\\\":{\\\"exit_code\\\":$exit_code,\\\"duration_seconds\\\":$duration}}\"\n\n[ \"$status\" == \"PASS\" ]\n",
9
+ "variables": [
10
+ "urn",
11
+ "given_setup",
12
+ "script_command",
13
+ "script_args",
14
+ "expected_exit_code"
15
+ ]
16
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Security Test Harness Template",
4
+ "description": "Template for security/penetration tests",
5
+ "language": "shell",
6
+ "framework": "bash",
7
+ "category": "integration",
8
+ "template": "\n#!/bin/bash\n# URN: {urn}\n\n# Given\n{given_setup}\n\n# When\nresponse=$(curl -s -w \"\\n%{{http_code}}\" \\\n -X {method} \\\n {headers} \\\n {body} \\\n \"{url}\")\n\nstatus_code=$(echo \"$response\" | tail -n1)\nbody=$(echo \"$response\" | head -n-1)\n\n# Then\nif [ \"$status_code\" -eq {expected_status} ]; then\n status=\"PASS\"\nelse\n status=\"FAIL\"\nfi\n\necho \"{\\\"urn\\\":\\\"{urn}\\\",\\\"status\\\":\\\"$status\\\",\\\"details\\\":{\\\"status_code\\\":$status_code}}\"\n\n[ \"$status\" == \"PASS\" ]\n",
9
+ "variables": [
10
+ "urn",
11
+ "given_setup",
12
+ "method",
13
+ "headers",
14
+ "body",
15
+ "url",
16
+ "expected_status"
17
+ ]
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Storage Test Harness Template",
4
+ "description": "Template for testing Supabase Storage operations",
5
+ "language": "typescript",
6
+ "framework": "vitest",
7
+ "category": "backend",
8
+ "template": "\n// URN: {urn}\nimport { test, expect } from 'vitest';\nimport { createClient } from '@supabase/supabase-js';\n\ntest('{test_name}', async () => {{\n const supabase = createClient(\n process.env.SUPABASE_URL,\n process.env.SUPABASE_ANON_KEY\n );\n\n // Given\n {given_setup}\n\n // When\n const {{ data, error }} = await supabase\n .storage\n .from('{bucket_name}')\n .{operation}({operation_params});\n\n // Then\n {then_assertions}\n\n console.log(JSON.stringify({{\n urn: '{urn}',\n status: 'PASS',\n details: {{ bucket: '{bucket_name}', operation: '{operation}' }}\n }}));\n}});\n",
9
+ "variables": [
10
+ "urn",
11
+ "test_name",
12
+ "given_setup",
13
+ "bucket_name",
14
+ "operation",
15
+ "operation_params",
16
+ "then_assertions"
17
+ ]
18
+ }
@@ -0,0 +1,128 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://wagons.dev/schemas/tester/telemetry.schema.json",
4
+ "title": "Telemetry Signal Schema",
5
+ "description": "Meta-schema that validates telemetry signal files for naming, metadata, and traceability.",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": [
9
+ "$schema",
10
+ "$id",
11
+ "version",
12
+ "type",
13
+ "plane",
14
+ "artifact_ref",
15
+ "acceptance_criteria",
16
+ "properties",
17
+ "required"
18
+ ],
19
+ "properties": {
20
+ "$schema": {
21
+ "type": "string",
22
+ "const": "http://json-schema.org/draft-07/schema#",
23
+ "description": "Must use JSON Schema Draft-07"
24
+ },
25
+ "$id": {
26
+ "type": "string",
27
+ "pattern": "^([a-z][a-z0-9\\-]*:)+[a-z][a-z0-9\\-.]*\\.(event|metric|trace|log)\\.(ui|ux|be|nw|db|st|tm|sc|au|fn|if)(\\.[a-z0-9_-]+)?$",
28
+ "description": "Signal ID pattern: {theme}(:{path})*:{aspect}.{type}.{plane}[.{measure}] (aspect may include dots)"
29
+ },
30
+ "version": {
31
+ "type": "string",
32
+ "pattern": "^\\d+\\.\\d+\\.\\d+$",
33
+ "description": "Semantic version (REQUIRED): 0.x.x for draft, 1.x.x+ for stable"
34
+ },
35
+ "type": {
36
+ "type": "string",
37
+ "enum": [
38
+ "event",
39
+ "metric",
40
+ "trace",
41
+ "log"
42
+ ],
43
+ "description": "Signal type"
44
+ },
45
+ "plane": {
46
+ "type": "string",
47
+ "enum": [
48
+ "ui",
49
+ "ux",
50
+ "be",
51
+ "nw",
52
+ "db",
53
+ "st",
54
+ "tm",
55
+ "sc",
56
+ "au",
57
+ "fn",
58
+ "if"
59
+ ],
60
+ "description": "Logical observability layer"
61
+ },
62
+ "measure": {
63
+ "type": "string",
64
+ "description": "Metric measure (required for type=metric)"
65
+ },
66
+ "unit": {
67
+ "type": "string",
68
+ "description": "Metric unit"
69
+ },
70
+ "artifact_ref": {
71
+ "type": "string",
72
+ "pattern": "^contract:([a-z][a-z0-9\\-]*:)+[a-z][a-z0-9\\-]*$",
73
+ "description": "Reference to contract schema with URN format: contract:{theme}(:{path})*:{resource}"
74
+ },
75
+ "acceptance_criteria": {
76
+ "type": "array",
77
+ "minItems": 0,
78
+ "items": {
79
+ "type": "string",
80
+ "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-]+)?|[A-Z][0-9]{3})$"
81
+ },
82
+ "description": "Array of acceptance criteria URNs that validate this signal"
83
+ },
84
+ "description": {
85
+ "type": "string",
86
+ "description": "Human-readable signal description"
87
+ },
88
+ "note": {
89
+ "type": "string",
90
+ "description": "Optional placeholder or implementation notes"
91
+ },
92
+ "properties": {
93
+ "type": "object",
94
+ "description": "JSON Schema properties object"
95
+ },
96
+ "required": {
97
+ "type": "array",
98
+ "items": {
99
+ "type": "string"
100
+ },
101
+ "description": "Required property names"
102
+ }
103
+ },
104
+ "allOf": [
105
+ {
106
+ "if": {
107
+ "properties": {
108
+ "type": { "const": "metric" }
109
+ }
110
+ },
111
+ "then": {
112
+ "required": ["measure"]
113
+ }
114
+ },
115
+ {
116
+ "if": {
117
+ "properties": {
118
+ "type": { "const": "event" }
119
+ }
120
+ },
121
+ "then": {
122
+ "not": {
123
+ "required": ["measure"]
124
+ }
125
+ }
126
+ }
127
+ ]
128
+ }