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.
- atdd/__init__.py +0 -0
- atdd/cli.py +404 -0
- atdd/coach/__init__.py +0 -0
- atdd/coach/commands/__init__.py +0 -0
- atdd/coach/commands/add_persistence_metadata.py +215 -0
- atdd/coach/commands/analyze_migrations.py +188 -0
- atdd/coach/commands/consumers.py +720 -0
- atdd/coach/commands/infer_governance_status.py +149 -0
- atdd/coach/commands/initializer.py +177 -0
- atdd/coach/commands/interface.py +1078 -0
- atdd/coach/commands/inventory.py +565 -0
- atdd/coach/commands/migration.py +240 -0
- atdd/coach/commands/registry.py +1560 -0
- atdd/coach/commands/session.py +430 -0
- atdd/coach/commands/sync.py +405 -0
- atdd/coach/commands/test_interface.py +399 -0
- atdd/coach/commands/test_runner.py +141 -0
- atdd/coach/commands/tests/__init__.py +1 -0
- atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
- atdd/coach/commands/traceability.py +4264 -0
- atdd/coach/conventions/session.convention.yaml +754 -0
- atdd/coach/overlays/__init__.py +2 -0
- atdd/coach/overlays/claude.md +2 -0
- atdd/coach/schemas/config.schema.json +34 -0
- atdd/coach/schemas/manifest.schema.json +101 -0
- atdd/coach/templates/ATDD.md +282 -0
- atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
- atdd/coach/utils/__init__.py +0 -0
- atdd/coach/utils/graph/__init__.py +0 -0
- atdd/coach/utils/graph/urn.py +875 -0
- atdd/coach/validators/__init__.py +0 -0
- atdd/coach/validators/shared_fixtures.py +365 -0
- atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
- atdd/coach/validators/test_registry.py +575 -0
- atdd/coach/validators/test_session_validation.py +1183 -0
- atdd/coach/validators/test_traceability.py +448 -0
- atdd/coach/validators/test_update_feature_paths.py +108 -0
- atdd/coach/validators/test_validate_contract_consumers.py +297 -0
- atdd/coder/__init__.py +1 -0
- atdd/coder/conventions/adapter.recipe.yaml +88 -0
- atdd/coder/conventions/backend.convention.yaml +460 -0
- atdd/coder/conventions/boundaries.convention.yaml +666 -0
- atdd/coder/conventions/commons.convention.yaml +460 -0
- atdd/coder/conventions/complexity.recipe.yaml +109 -0
- atdd/coder/conventions/component-naming.convention.yaml +178 -0
- atdd/coder/conventions/design.convention.yaml +327 -0
- atdd/coder/conventions/design.recipe.yaml +273 -0
- atdd/coder/conventions/dto.convention.yaml +660 -0
- atdd/coder/conventions/frontend.convention.yaml +542 -0
- atdd/coder/conventions/green.convention.yaml +1012 -0
- atdd/coder/conventions/presentation.convention.yaml +587 -0
- atdd/coder/conventions/refactor.convention.yaml +535 -0
- atdd/coder/conventions/technology.convention.yaml +206 -0
- atdd/coder/conventions/tests/__init__.py +0 -0
- atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
- atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
- atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
- atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
- atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
- atdd/coder/conventions/thinness.recipe.yaml +82 -0
- atdd/coder/conventions/train.convention.yaml +325 -0
- atdd/coder/conventions/verification.protocol.yaml +53 -0
- atdd/coder/schemas/design_system.schema.json +361 -0
- atdd/coder/validators/__init__.py +0 -0
- atdd/coder/validators/test_commons_structure.py +485 -0
- atdd/coder/validators/test_complexity.py +416 -0
- atdd/coder/validators/test_cross_language_consistency.py +431 -0
- atdd/coder/validators/test_design_system_compliance.py +413 -0
- atdd/coder/validators/test_dto_testing_patterns.py +268 -0
- atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
- atdd/coder/validators/test_green_layer_dependencies.py +148 -0
- atdd/coder/validators/test_green_python_layer_structure.py +103 -0
- atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
- atdd/coder/validators/test_import_boundaries.py +396 -0
- atdd/coder/validators/test_init_file_urns.py +593 -0
- atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
- atdd/coder/validators/test_presentation_convention.py +260 -0
- atdd/coder/validators/test_python_architecture.py +674 -0
- atdd/coder/validators/test_quality_metrics.py +420 -0
- atdd/coder/validators/test_station_master_pattern.py +244 -0
- atdd/coder/validators/test_train_infrastructure.py +454 -0
- atdd/coder/validators/test_train_urns.py +293 -0
- atdd/coder/validators/test_typescript_architecture.py +616 -0
- atdd/coder/validators/test_usecase_structure.py +421 -0
- atdd/coder/validators/test_wagon_boundaries.py +586 -0
- atdd/conftest.py +126 -0
- atdd/planner/__init__.py +1 -0
- atdd/planner/conventions/acceptance.convention.yaml +538 -0
- atdd/planner/conventions/appendix.convention.yaml +187 -0
- atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
- atdd/planner/conventions/component.convention.yaml +670 -0
- atdd/planner/conventions/criteria.convention.yaml +141 -0
- atdd/planner/conventions/feature.convention.yaml +371 -0
- atdd/planner/conventions/interface.convention.yaml +382 -0
- atdd/planner/conventions/steps.convention.yaml +141 -0
- atdd/planner/conventions/train.convention.yaml +552 -0
- atdd/planner/conventions/wagon.convention.yaml +275 -0
- atdd/planner/conventions/wmbt.convention.yaml +258 -0
- atdd/planner/schemas/acceptance.schema.json +336 -0
- atdd/planner/schemas/appendix.schema.json +78 -0
- atdd/planner/schemas/component.schema.json +114 -0
- atdd/planner/schemas/feature.schema.json +197 -0
- atdd/planner/schemas/train.schema.json +192 -0
- atdd/planner/schemas/wagon.schema.json +281 -0
- atdd/planner/schemas/wmbt.schema.json +59 -0
- atdd/planner/validators/__init__.py +0 -0
- atdd/planner/validators/conftest.py +5 -0
- atdd/planner/validators/test_draft_wagon_registry.py +374 -0
- atdd/planner/validators/test_plan_cross_refs.py +240 -0
- atdd/planner/validators/test_plan_uniqueness.py +224 -0
- atdd/planner/validators/test_plan_urn_resolution.py +268 -0
- atdd/planner/validators/test_plan_wagons.py +174 -0
- atdd/planner/validators/test_train_validation.py +514 -0
- atdd/planner/validators/test_wagon_urn_chain.py +648 -0
- atdd/planner/validators/test_wmbt_consistency.py +327 -0
- atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
- atdd/tester/__init__.py +1 -0
- atdd/tester/conventions/artifact.convention.yaml +257 -0
- atdd/tester/conventions/contract.convention.yaml +1009 -0
- atdd/tester/conventions/filename.convention.yaml +555 -0
- atdd/tester/conventions/migration.convention.yaml +509 -0
- atdd/tester/conventions/red.convention.yaml +797 -0
- atdd/tester/conventions/routing.convention.yaml +51 -0
- atdd/tester/conventions/telemetry.convention.yaml +458 -0
- atdd/tester/schemas/a11y.tmpl.json +17 -0
- atdd/tester/schemas/artifact.schema.json +189 -0
- atdd/tester/schemas/contract.schema.json +591 -0
- atdd/tester/schemas/contract.tmpl.json +95 -0
- atdd/tester/schemas/db.tmpl.json +20 -0
- atdd/tester/schemas/e2e.tmpl.json +17 -0
- atdd/tester/schemas/edge_function.tmpl.json +17 -0
- atdd/tester/schemas/event.tmpl.json +17 -0
- atdd/tester/schemas/http.tmpl.json +19 -0
- atdd/tester/schemas/job.tmpl.json +18 -0
- atdd/tester/schemas/load.tmpl.json +21 -0
- atdd/tester/schemas/metric.tmpl.json +19 -0
- atdd/tester/schemas/pack.schema.json +139 -0
- atdd/tester/schemas/realtime.tmpl.json +20 -0
- atdd/tester/schemas/rls.tmpl.json +18 -0
- atdd/tester/schemas/script.tmpl.json +16 -0
- atdd/tester/schemas/sec.tmpl.json +18 -0
- atdd/tester/schemas/storage.tmpl.json +18 -0
- atdd/tester/schemas/telemetry.schema.json +128 -0
- atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
- atdd/tester/schemas/test_filename.schema.json +194 -0
- atdd/tester/schemas/test_intent.schema.json +179 -0
- atdd/tester/schemas/unit.tmpl.json +18 -0
- atdd/tester/schemas/visual.tmpl.json +18 -0
- atdd/tester/schemas/ws.tmpl.json +17 -0
- atdd/tester/utils/__init__.py +0 -0
- atdd/tester/utils/filename.py +300 -0
- atdd/tester/validators/__init__.py +0 -0
- atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
- atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
- atdd/tester/validators/conftest.py +5 -0
- atdd/tester/validators/coverage_gap_report.py +321 -0
- atdd/tester/validators/fix_dual_ac_references.py +179 -0
- atdd/tester/validators/remove_duplicate_lines.py +93 -0
- atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
- atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
- atdd/tester/validators/test_artifact_naming_category.py +307 -0
- atdd/tester/validators/test_contract_schema_compliance.py +706 -0
- atdd/tester/validators/test_contracts_structure.py +200 -0
- atdd/tester/validators/test_coverage_adequacy.py +797 -0
- atdd/tester/validators/test_dual_ac_reference.py +225 -0
- atdd/tester/validators/test_fixture_validity.py +372 -0
- atdd/tester/validators/test_isolation.py +487 -0
- atdd/tester/validators/test_migration_coverage.py +204 -0
- atdd/tester/validators/test_migration_criteria.py +276 -0
- atdd/tester/validators/test_migration_generation.py +116 -0
- atdd/tester/validators/test_python_test_naming.py +410 -0
- atdd/tester/validators/test_red_layer_validation.py +95 -0
- atdd/tester/validators/test_red_python_layer_structure.py +87 -0
- atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
- atdd/tester/validators/test_telemetry_structure.py +634 -0
- atdd/tester/validators/test_typescript_test_naming.py +301 -0
- atdd/tester/validators/test_typescript_test_structure.py +84 -0
- atdd-0.1.0.dist-info/METADATA +191 -0
- atdd-0.1.0.dist-info/RECORD +183 -0
- atdd-0.1.0.dist-info/WHEEL +5 -0
- atdd-0.1.0.dist-info/entry_points.txt +2 -0
- atdd-0.1.0.dist-info/licenses/LICENSE +674 -0
- atdd-0.1.0.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
|
+
])
|
atdd/planner/__init__.py
ADDED
|
@@ -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?"
|