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
|
@@ -0,0 +1,852 @@
|
|
|
1
|
+
version: "2.1"
|
|
2
|
+
name: "Artifact Naming Convention"
|
|
3
|
+
description: "Convention for naming artifacts using theme-based hierarchical taxonomy with variant facets"
|
|
4
|
+
|
|
5
|
+
changelog:
|
|
6
|
+
v2.1:
|
|
7
|
+
date: "2025-10-28"
|
|
8
|
+
changes:
|
|
9
|
+
- "Clarified separator semantics: colon for hierarchy, dot for variants"
|
|
10
|
+
- "Hierarchy (colon) can be unlimited depth, variants (dot) typically shallow (0-1)"
|
|
11
|
+
- "Updated all examples to reflect hierarchy vs variant distinction"
|
|
12
|
+
v2.0:
|
|
13
|
+
date: "2025-10-28"
|
|
14
|
+
changes:
|
|
15
|
+
- "Introduced theme:hierarchy:aspect.variant pattern"
|
|
16
|
+
- "Added theme-based taxonomy (commons, match, mechanic, sensory, etc.)"
|
|
17
|
+
- "Aligned artifact names with contract file paths"
|
|
18
|
+
|
|
19
|
+
purpose: |
|
|
20
|
+
Establish consistent naming patterns for artifacts that:
|
|
21
|
+
- Provide semantic clarity through theme-based organization
|
|
22
|
+
- Enable namespace safety to prevent naming collisions
|
|
23
|
+
- Support unlimited hierarchical depth using colons
|
|
24
|
+
- Support lateral variants using dots (typically single level)
|
|
25
|
+
- Scale gracefully as the system grows
|
|
26
|
+
- Align artifact names with contract file paths
|
|
27
|
+
|
|
28
|
+
separator_semantics:
|
|
29
|
+
colon:
|
|
30
|
+
symbol: ":"
|
|
31
|
+
purpose: "Hierarchical descent - navigate deeper into resource tree"
|
|
32
|
+
multiplicity: "Unlimited - as many levels as needed"
|
|
33
|
+
visual_weight: "Strong boundary - indicates different conceptual levels"
|
|
34
|
+
use_for:
|
|
35
|
+
- "Moving from general to specific (ux → foundations → color)"
|
|
36
|
+
- "Navigating down organizational structure"
|
|
37
|
+
- "Different conceptual levels"
|
|
38
|
+
examples:
|
|
39
|
+
- "commons:ux:foundations:color (theme → subsystem → category → item)"
|
|
40
|
+
- "commons:telemetry:observability:traces:span"
|
|
41
|
+
- "scenario:catalog:primitives:actor"
|
|
42
|
+
|
|
43
|
+
dot:
|
|
44
|
+
symbol: "."
|
|
45
|
+
purpose: "Lateral variation - different flavors/states of same thing"
|
|
46
|
+
multiplicity: "Typically 1, rarely 2 - keep shallow"
|
|
47
|
+
visual_weight: "Soft boundary - indicates same level, different facet"
|
|
48
|
+
use_for:
|
|
49
|
+
- "State variations (session.active vs session.closed)"
|
|
50
|
+
- "Type variations (config.duel vs config.team)"
|
|
51
|
+
- "Facet variations (gesture.raw vs gesture.tapped)"
|
|
52
|
+
examples:
|
|
53
|
+
- "sensory:gesture.raw (aspect + variant)"
|
|
54
|
+
- "player:session.active (aspect + state variant)"
|
|
55
|
+
- "match:config.duel (aspect + type variant)"
|
|
56
|
+
|
|
57
|
+
warning: "Multiple dots (e.g., .uuid.v7.encoded) usually indicates over-specification"
|
|
58
|
+
|
|
59
|
+
visual_hierarchy:
|
|
60
|
+
structure: |
|
|
61
|
+
theme : category : subcategory : aspect . variant
|
|
62
|
+
└─┬─┘ └──────────┬──────────────────┘ └──┬──┘
|
|
63
|
+
│ HIERARCHY VARIANT
|
|
64
|
+
│ (vertical depth) (lateral facet)
|
|
65
|
+
NAMESPACE
|
|
66
|
+
|
|
67
|
+
naming_pattern:
|
|
68
|
+
full_pattern: "{theme}(:{category})*:{aspect}(.{variant})?"
|
|
69
|
+
|
|
70
|
+
components:
|
|
71
|
+
theme:
|
|
72
|
+
definition: "Top-level architectural theme grouping related artifacts"
|
|
73
|
+
format: "lowercase, no separators"
|
|
74
|
+
multiplicity: "Required, exactly 1"
|
|
75
|
+
examples: ["commons", "match", "mechanic", "sensory", "player", "partnership", "scenario"]
|
|
76
|
+
|
|
77
|
+
category:
|
|
78
|
+
definition: "Hierarchical path segments navigating down the resource tree"
|
|
79
|
+
format: "kebab-case"
|
|
80
|
+
multiplicity: "Optional, 0+ segments"
|
|
81
|
+
examples: ["ux", "foundations", "telemetry", "observability", "catalog"]
|
|
82
|
+
|
|
83
|
+
aspect:
|
|
84
|
+
definition: "The final leaf resource noun"
|
|
85
|
+
format: "kebab-case"
|
|
86
|
+
multiplicity: "Required, exactly 1"
|
|
87
|
+
examples: ["color", "gesture", "session", "config", "identifiers"]
|
|
88
|
+
|
|
89
|
+
variant:
|
|
90
|
+
definition: "Lateral variation, facet, or state of the aspect"
|
|
91
|
+
format: "kebab-case"
|
|
92
|
+
multiplicity: "Optional, typically 0-1 segments"
|
|
93
|
+
examples: ["raw", "uuid", "active", "duel", "primary"]
|
|
94
|
+
|
|
95
|
+
examples:
|
|
96
|
+
hierarchy_only:
|
|
97
|
+
pattern: "theme:category:subcategory:aspect"
|
|
98
|
+
description: "Deep hierarchy, no variants"
|
|
99
|
+
cases:
|
|
100
|
+
- name: "commons:ux:foundations:color"
|
|
101
|
+
breakdown:
|
|
102
|
+
theme: "commons"
|
|
103
|
+
hierarchy: ["ux", "foundations"]
|
|
104
|
+
aspect: "color"
|
|
105
|
+
contract: "contracts/commons/ux/foundations/color.schema.json"
|
|
106
|
+
rationale: "Navigate from commons → ux subsystem → foundations category → color resource"
|
|
107
|
+
|
|
108
|
+
- name: "commons:telemetry:observability:span"
|
|
109
|
+
breakdown:
|
|
110
|
+
theme: "commons"
|
|
111
|
+
hierarchy: ["telemetry", "observability"]
|
|
112
|
+
aspect: "span"
|
|
113
|
+
contract: "contracts/commons/telemetry/observability/span.schema.json"
|
|
114
|
+
rationale: "Navigate from commons → telemetry → observability → span"
|
|
115
|
+
|
|
116
|
+
- name: "scenario:catalog:primitives:actor"
|
|
117
|
+
breakdown:
|
|
118
|
+
theme: "scenario"
|
|
119
|
+
hierarchy: ["catalog", "primitives"]
|
|
120
|
+
aspect: "actor"
|
|
121
|
+
contract: "contracts/scenario/catalog/primitives/actor.schema.json"
|
|
122
|
+
rationale: "Navigate from scenario → catalog → primitives → actor"
|
|
123
|
+
|
|
124
|
+
variant_only:
|
|
125
|
+
pattern: "theme:aspect.variant"
|
|
126
|
+
description: "Shallow hierarchy with variant"
|
|
127
|
+
cases:
|
|
128
|
+
- name: "commons:identifiers.uuid"
|
|
129
|
+
breakdown:
|
|
130
|
+
theme: "commons"
|
|
131
|
+
aspect: "identifiers"
|
|
132
|
+
variant: "uuid"
|
|
133
|
+
contract: "contracts/commons/identifiers/uuid.schema.json"
|
|
134
|
+
rationale: "UUID is one variant of identifiers (username is another)"
|
|
135
|
+
|
|
136
|
+
- name: "sensory:gesture.raw"
|
|
137
|
+
breakdown:
|
|
138
|
+
theme: "sensory"
|
|
139
|
+
aspect: "gesture"
|
|
140
|
+
variant: "raw"
|
|
141
|
+
contract: "contracts/sensory/gesture/raw.schema.json"
|
|
142
|
+
rationale: "Raw kinematics variant of gesture"
|
|
143
|
+
|
|
144
|
+
- name: "match:config.duel"
|
|
145
|
+
breakdown:
|
|
146
|
+
theme: "match"
|
|
147
|
+
aspect: "config"
|
|
148
|
+
variant: "duel"
|
|
149
|
+
contract: "contracts/match/config/duel.schema.json"
|
|
150
|
+
rationale: "Duel variant of match configuration"
|
|
151
|
+
|
|
152
|
+
hierarchy_and_variant:
|
|
153
|
+
pattern: "theme:category:subcategory:aspect.variant"
|
|
154
|
+
description: "Deep hierarchy with variant"
|
|
155
|
+
cases:
|
|
156
|
+
- name: "commons:ux:foundations:color.primary"
|
|
157
|
+
breakdown:
|
|
158
|
+
theme: "commons"
|
|
159
|
+
hierarchy: ["ux", "foundations"]
|
|
160
|
+
aspect: "color"
|
|
161
|
+
variant: "primary"
|
|
162
|
+
contract: "contracts/commons/ux/foundations/color/primary.schema.json"
|
|
163
|
+
rationale: "Navigate to color, then get primary variant"
|
|
164
|
+
|
|
165
|
+
- name: "commons:ux:components:button.primary"
|
|
166
|
+
breakdown:
|
|
167
|
+
theme: "commons"
|
|
168
|
+
hierarchy: ["ux", "components"]
|
|
169
|
+
aspect: "button"
|
|
170
|
+
variant: "primary"
|
|
171
|
+
contract: "contracts/commons/ux/components/button/primary.schema.json"
|
|
172
|
+
rationale: "Navigate to button component, get primary variant"
|
|
173
|
+
|
|
174
|
+
- name: "sensory:feedback:haptic:pulse.short"
|
|
175
|
+
breakdown:
|
|
176
|
+
theme: "sensory"
|
|
177
|
+
hierarchy: ["feedback", "haptic"]
|
|
178
|
+
aspect: "pulse"
|
|
179
|
+
variant: "short"
|
|
180
|
+
contract: "contracts/sensory/feedback/haptic/pulse/short.schema.json"
|
|
181
|
+
rationale: "Navigate to haptic pulse, get short duration variant"
|
|
182
|
+
|
|
183
|
+
simple_form:
|
|
184
|
+
pattern: "theme:aspect"
|
|
185
|
+
description: "No hierarchy, no variant - simplest form"
|
|
186
|
+
cases:
|
|
187
|
+
- name: "match:config"
|
|
188
|
+
breakdown:
|
|
189
|
+
theme: "match"
|
|
190
|
+
aspect: "config"
|
|
191
|
+
contract: "contracts/match/config/config.schema.json"
|
|
192
|
+
rationale: "Base match configuration (variants like .duel, .team exist separately)"
|
|
193
|
+
|
|
194
|
+
- name: "scenario:fragments"
|
|
195
|
+
breakdown:
|
|
196
|
+
theme: "scenario"
|
|
197
|
+
aspect: "fragments"
|
|
198
|
+
contract: "contracts/scenario/fragments/fragments.schema.json"
|
|
199
|
+
rationale: "Collection of fragments, no variants needed"
|
|
200
|
+
|
|
201
|
+
cardinality_semantics:
|
|
202
|
+
collection_indicator:
|
|
203
|
+
rule: "The ASPECT (final noun before variant) determines cardinality"
|
|
204
|
+
key_principle: "Pluralization of the aspect indicates collection/array schema"
|
|
205
|
+
|
|
206
|
+
detection:
|
|
207
|
+
- "Look at the final noun (aspect) in the artifact name"
|
|
208
|
+
- "If aspect ends in 's' (or is plural) → collection schema"
|
|
209
|
+
- "If aspect is singular → single item schema"
|
|
210
|
+
- "Categories in hierarchy don't affect cardinality"
|
|
211
|
+
- "Variants don't affect cardinality"
|
|
212
|
+
|
|
213
|
+
position_matters:
|
|
214
|
+
aspect_position:
|
|
215
|
+
location: "Final noun before variant (or final word if no variant)"
|
|
216
|
+
affects_cardinality: true
|
|
217
|
+
examples:
|
|
218
|
+
- artifact: "scenario:fragments"
|
|
219
|
+
aspect: "fragments"
|
|
220
|
+
cardinality: "plural → collection"
|
|
221
|
+
|
|
222
|
+
- artifact: "scenario:fragment"
|
|
223
|
+
aspect: "fragment"
|
|
224
|
+
cardinality: "singular → one item"
|
|
225
|
+
|
|
226
|
+
- artifact: "commons:ux:foundations"
|
|
227
|
+
aspect: "foundations"
|
|
228
|
+
cardinality: "plural → collection"
|
|
229
|
+
|
|
230
|
+
category_position:
|
|
231
|
+
location: "Any segment in hierarchy except final aspect"
|
|
232
|
+
affects_cardinality: false
|
|
233
|
+
note: "Category can be plural without making it a collection"
|
|
234
|
+
examples:
|
|
235
|
+
- artifact: "commons:ux:foundations:color"
|
|
236
|
+
category: "foundations (plural, but just a category name)"
|
|
237
|
+
aspect: "color (singular)"
|
|
238
|
+
cardinality: "singular → one color item"
|
|
239
|
+
|
|
240
|
+
- artifact: "commons:ux:foundations:colors"
|
|
241
|
+
category: "foundations (plural category name)"
|
|
242
|
+
aspect: "colors (plural)"
|
|
243
|
+
cardinality: "plural → collection of colors"
|
|
244
|
+
|
|
245
|
+
variant_position:
|
|
246
|
+
location: "After dot separator"
|
|
247
|
+
affects_cardinality: false
|
|
248
|
+
note: "Variant can be plural but doesn't change aspect cardinality"
|
|
249
|
+
examples:
|
|
250
|
+
- artifact: "scenario:fragment.colors"
|
|
251
|
+
aspect: "fragment (singular)"
|
|
252
|
+
variant: "colors (just a variant name)"
|
|
253
|
+
cardinality: "singular → one fragment (with colors variant)"
|
|
254
|
+
|
|
255
|
+
plural_vs_singular:
|
|
256
|
+
rule: "Use singular aspect for item schema, plural aspect for collection"
|
|
257
|
+
|
|
258
|
+
singular_aspect:
|
|
259
|
+
meaning: "Schema defines a single item"
|
|
260
|
+
pattern: "theme:path:to:item(.variant)?"
|
|
261
|
+
examples:
|
|
262
|
+
- name: "scenario:fragment"
|
|
263
|
+
aspect: "fragment (singular)"
|
|
264
|
+
file: "contracts/scenario/fragment/fragment.schema.json"
|
|
265
|
+
defines: "Schema for ONE fragment object"
|
|
266
|
+
|
|
267
|
+
- name: "commons:ux:foundation"
|
|
268
|
+
aspect: "foundation (singular)"
|
|
269
|
+
file: "contracts/commons/ux/foundation/foundation.schema.json"
|
|
270
|
+
defines: "Schema for ONE foundation item"
|
|
271
|
+
|
|
272
|
+
- name: "commons:ux:foundations:color"
|
|
273
|
+
aspect: "color (singular)"
|
|
274
|
+
file: "contracts/commons/ux/foundations/color.schema.json"
|
|
275
|
+
defines: "Schema for ONE color (foundations is just the category)"
|
|
276
|
+
|
|
277
|
+
- name: "scenario:fragment.active"
|
|
278
|
+
aspect: "fragment (singular)"
|
|
279
|
+
variant: "active"
|
|
280
|
+
defines: "Schema for ONE active fragment"
|
|
281
|
+
|
|
282
|
+
plural_aspect:
|
|
283
|
+
meaning: "Schema defines collection (array) OR references directory of items"
|
|
284
|
+
pattern: "theme:path:to:items(.variant)?"
|
|
285
|
+
examples:
|
|
286
|
+
- name: "scenario:fragments"
|
|
287
|
+
aspect: "fragments (plural)"
|
|
288
|
+
file: "contracts/scenario/fragments/fragments.schema.json"
|
|
289
|
+
defines: "Schema for ARRAY of fragments"
|
|
290
|
+
|
|
291
|
+
- name: "commons:ux:foundations"
|
|
292
|
+
aspect: "foundations (plural)"
|
|
293
|
+
represents: "All schemas in contracts/commons/ux/foundations/"
|
|
294
|
+
defines: "Collection reference or array schema for foundations"
|
|
295
|
+
|
|
296
|
+
- name: "commons:ux:foundations:colors"
|
|
297
|
+
aspect: "colors (plural)"
|
|
298
|
+
file: "contracts/commons/ux/foundations/colors.schema.json"
|
|
299
|
+
defines: "Schema for ARRAY of colors"
|
|
300
|
+
|
|
301
|
+
- name: "scenario:fragments.active"
|
|
302
|
+
aspect: "fragments (plural)"
|
|
303
|
+
variant: "active"
|
|
304
|
+
defines: "Schema for ARRAY of active fragments"
|
|
305
|
+
|
|
306
|
+
both_can_exist: true
|
|
307
|
+
coexistence_examples:
|
|
308
|
+
- singular: "scenario:fragment"
|
|
309
|
+
plural: "scenario:fragments"
|
|
310
|
+
difference: "One vs many - both valid"
|
|
311
|
+
|
|
312
|
+
- singular: "commons:ux:foundation"
|
|
313
|
+
plural: "commons:ux:foundations"
|
|
314
|
+
difference: "Item vs collection - both schemas exist"
|
|
315
|
+
|
|
316
|
+
- singular: "commons:ux:foundations:color"
|
|
317
|
+
plural: "commons:ux:foundations:colors"
|
|
318
|
+
difference: "One color vs array of colors in foundations category"
|
|
319
|
+
|
|
320
|
+
pluralization_guide:
|
|
321
|
+
regular_plurals:
|
|
322
|
+
rule: "Add 's' to singular form"
|
|
323
|
+
examples:
|
|
324
|
+
- "fragment → fragments"
|
|
325
|
+
- "color → colors"
|
|
326
|
+
- "button → buttons"
|
|
327
|
+
- "gesture → gestures"
|
|
328
|
+
|
|
329
|
+
irregular_plurals:
|
|
330
|
+
rule: "Follow English irregular plural forms"
|
|
331
|
+
examples:
|
|
332
|
+
- "analysis → analyses"
|
|
333
|
+
- "policy → policies"
|
|
334
|
+
- "datum → data"
|
|
335
|
+
- "index → indices"
|
|
336
|
+
- "child → children"
|
|
337
|
+
|
|
338
|
+
uncountable_nouns:
|
|
339
|
+
rule: "Use explicit suffix when noun doesn't pluralize naturally"
|
|
340
|
+
examples:
|
|
341
|
+
- bad: "config → configs (awkward)"
|
|
342
|
+
better: "config vs config.collection"
|
|
343
|
+
|
|
344
|
+
- bad: "data → datas (incorrect)"
|
|
345
|
+
better: "data.item vs data.items"
|
|
346
|
+
|
|
347
|
+
- ok: "metrics → metrics (already plural form acceptable)"
|
|
348
|
+
|
|
349
|
+
compound_nouns:
|
|
350
|
+
rule: "Pluralize the primary noun"
|
|
351
|
+
examples:
|
|
352
|
+
- "button-group → button-groups"
|
|
353
|
+
- "session-state → session-states"
|
|
354
|
+
- "color-palette → color-palettes"
|
|
355
|
+
|
|
356
|
+
logical_vs_physical_mapping:
|
|
357
|
+
overview: "Artifact names (logical) map to file paths (physical) with specific rules"
|
|
358
|
+
|
|
359
|
+
mapping_algorithm:
|
|
360
|
+
steps:
|
|
361
|
+
1. "Split artifact name by colons (:) and dots (.)"
|
|
362
|
+
2. "Each segment creates a directory level"
|
|
363
|
+
3. "Determine final target based on artifact type"
|
|
364
|
+
|
|
365
|
+
pseudocode: |
|
|
366
|
+
segments = split(artifact, /[:.]/g)
|
|
367
|
+
path = "contracts/" + segments[0..-1].join("/") + "/"
|
|
368
|
+
|
|
369
|
+
if has_variant:
|
|
370
|
+
file = segments[-1] + ".schema.json"
|
|
371
|
+
elif is_directory_reference:
|
|
372
|
+
file = null // directory only
|
|
373
|
+
else:
|
|
374
|
+
file = segments[-1] + ".schema.json"
|
|
375
|
+
|
|
376
|
+
three_physical_forms:
|
|
377
|
+
directory_reference:
|
|
378
|
+
when: "Logical grouping without concrete schema file"
|
|
379
|
+
artifact: "commons:ux:foundations"
|
|
380
|
+
physical_path: "contracts/commons/ux/foundations/"
|
|
381
|
+
contains: ["color.schema.json", "typography.schema.json", "spacing.schema.json"]
|
|
382
|
+
schema_file: "none - directory only"
|
|
383
|
+
usage: "Organizational grouping, not a runtime artifact"
|
|
384
|
+
note: "Plural aspect referencing a collection of related schemas"
|
|
385
|
+
|
|
386
|
+
array_schema:
|
|
387
|
+
when: "Runtime array containing multiple items of singular type"
|
|
388
|
+
artifact: "scenario:fragments"
|
|
389
|
+
physical_path: "contracts/scenario/fragments/fragments.schema.json"
|
|
390
|
+
schema_structure: |
|
|
391
|
+
{
|
|
392
|
+
"type": "array",
|
|
393
|
+
"items": {
|
|
394
|
+
"$ref": "../fragment/fragment.schema.json"
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
runtime_value: "[{fragment}, {fragment}, ...]"
|
|
398
|
+
usage: "Contract for array/collection payload"
|
|
399
|
+
note: "Plural aspect with concrete array schema file"
|
|
400
|
+
|
|
401
|
+
singular_schema:
|
|
402
|
+
when: "Single item definition"
|
|
403
|
+
artifact: "scenario:fragment"
|
|
404
|
+
physical_path: "contracts/scenario/fragment/fragment.schema.json"
|
|
405
|
+
schema_structure: |
|
|
406
|
+
{
|
|
407
|
+
"type": "object",
|
|
408
|
+
"properties": {
|
|
409
|
+
"id": {"type": "string"},
|
|
410
|
+
"label": {"type": "string"}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
runtime_value: "{id: '...', label: '...'}"
|
|
414
|
+
usage: "Contract for single item payload"
|
|
415
|
+
note: "Singular aspect = single object schema"
|
|
416
|
+
|
|
417
|
+
detailed_examples:
|
|
418
|
+
no_variant_singular:
|
|
419
|
+
artifact: "scenario:fragment"
|
|
420
|
+
breakdown: ["scenario", "fragment"]
|
|
421
|
+
physical: "contracts/scenario/fragment/fragment.schema.json"
|
|
422
|
+
explanation: "Final segment 'fragment' repeated as filename"
|
|
423
|
+
|
|
424
|
+
no_variant_plural_array:
|
|
425
|
+
artifact: "scenario:fragments"
|
|
426
|
+
breakdown: ["scenario", "fragments"]
|
|
427
|
+
physical: "contracts/scenario/fragments/fragments.schema.json"
|
|
428
|
+
schema_type: "array"
|
|
429
|
+
explanation: "Final segment 'fragments' repeated, schema defines array type"
|
|
430
|
+
|
|
431
|
+
no_variant_plural_directory:
|
|
432
|
+
artifact: "commons:ux:foundations"
|
|
433
|
+
breakdown: ["commons", "ux", "foundations"]
|
|
434
|
+
physical: "contracts/commons/ux/foundations/"
|
|
435
|
+
contains: ["color.schema.json", "typography.schema.json", "spacing.schema.json"]
|
|
436
|
+
explanation: "Directory reference - no single schema file"
|
|
437
|
+
|
|
438
|
+
with_variant_singular:
|
|
439
|
+
artifact: "sensory:gesture.raw"
|
|
440
|
+
breakdown: ["sensory", "gesture", "raw"]
|
|
441
|
+
physical: "contracts/sensory/gesture/raw.schema.json"
|
|
442
|
+
explanation: "Variant 'raw' becomes filename (no repetition of aspect)"
|
|
443
|
+
|
|
444
|
+
with_variant_plural:
|
|
445
|
+
artifact: "scenario:fragments.active"
|
|
446
|
+
breakdown: ["scenario", "fragments", "active"]
|
|
447
|
+
physical: "contracts/scenario/fragments/active.schema.json"
|
|
448
|
+
schema_type: "array (filtered subset)"
|
|
449
|
+
explanation: "Variant 'active' becomes filename, schema defines filtered array"
|
|
450
|
+
|
|
451
|
+
deep_hierarchy_singular:
|
|
452
|
+
artifact: "commons:ux:foundations:color"
|
|
453
|
+
breakdown: ["commons", "ux", "foundations", "color"]
|
|
454
|
+
physical: "contracts/commons/ux/foundations/color.schema.json"
|
|
455
|
+
explanation: "'foundations' is directory, 'color' is filename"
|
|
456
|
+
|
|
457
|
+
deep_hierarchy_plural:
|
|
458
|
+
artifact: "commons:ux:foundations:colors"
|
|
459
|
+
breakdown: ["commons", "ux", "foundations", "colors"]
|
|
460
|
+
physical: "contracts/commons/ux/foundations/colors.schema.json"
|
|
461
|
+
schema_type: "array"
|
|
462
|
+
explanation: "'foundations' is directory, 'colors' is array schema file"
|
|
463
|
+
|
|
464
|
+
deep_with_variant:
|
|
465
|
+
artifact: "commons:ux:foundations:color.primary"
|
|
466
|
+
breakdown: ["commons", "ux", "foundations", "color", "primary"]
|
|
467
|
+
physical: "contracts/commons/ux/foundations/color/primary.schema.json"
|
|
468
|
+
explanation: "'color' becomes directory, 'primary' variant becomes filename"
|
|
469
|
+
|
|
470
|
+
array_schema_structure:
|
|
471
|
+
description: "Array schemas use JSON Schema 'array' type referencing item schemas"
|
|
472
|
+
|
|
473
|
+
pattern: |
|
|
474
|
+
{
|
|
475
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
476
|
+
"$id": "urn:contract:{artifact_name}",
|
|
477
|
+
"type": "array",
|
|
478
|
+
"items": {
|
|
479
|
+
"$ref": "../{singular_item}/{singular_item}.schema.json"
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
concrete_example:
|
|
484
|
+
singular_schema:
|
|
485
|
+
file: "contracts/scenario/fragment/fragment.schema.json"
|
|
486
|
+
content: |
|
|
487
|
+
{
|
|
488
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
489
|
+
"$id": "urn:contract:scenario:fragment",
|
|
490
|
+
"type": "object",
|
|
491
|
+
"properties": {
|
|
492
|
+
"id": {"type": "string", "format": "uuid"},
|
|
493
|
+
"label": {"type": "string"},
|
|
494
|
+
"kg_subject": {"type": "string", "format": "uri"}
|
|
495
|
+
},
|
|
496
|
+
"required": ["id", "label", "kg_subject"]
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
array_schema:
|
|
500
|
+
file: "contracts/scenario/fragments/fragments.schema.json"
|
|
501
|
+
content: |
|
|
502
|
+
{
|
|
503
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
504
|
+
"$id": "urn:contract:scenario:fragments",
|
|
505
|
+
"type": "array",
|
|
506
|
+
"items": {
|
|
507
|
+
"$ref": "../fragment/fragment.schema.json"
|
|
508
|
+
},
|
|
509
|
+
"minItems": 1
|
|
510
|
+
}
|
|
511
|
+
runtime_example: |
|
|
512
|
+
[
|
|
513
|
+
{"id": "uuid-1", "label": "Fragment A", "kg_subject": "http://..."},
|
|
514
|
+
{"id": "uuid-2", "label": "Fragment B", "kg_subject": "http://..."}
|
|
515
|
+
]
|
|
516
|
+
|
|
517
|
+
disambiguation_guide:
|
|
518
|
+
question: "How to know if plural artifact is directory reference or array schema?"
|
|
519
|
+
|
|
520
|
+
heuristics:
|
|
521
|
+
organizational_grouping:
|
|
522
|
+
indicator: "Contains multiple distinct types/schemas"
|
|
523
|
+
example: "commons:ux:foundations (contains color, typography, spacing - different types)"
|
|
524
|
+
physical: "Directory with multiple .schema.json files"
|
|
525
|
+
|
|
526
|
+
runtime_collection:
|
|
527
|
+
indicator: "Contains multiple instances of same type"
|
|
528
|
+
example: "scenario:fragments (contains many fragments - same type)"
|
|
529
|
+
physical: "Single fragments.schema.json with type: array"
|
|
530
|
+
|
|
531
|
+
clarification_rules:
|
|
532
|
+
- "If plural aspect represents diverse sub-resources → directory reference"
|
|
533
|
+
- "If plural aspect represents homogeneous collection → array schema"
|
|
534
|
+
- "When in doubt, create array schema (more explicit contract)"
|
|
535
|
+
|
|
536
|
+
theme_taxonomy:
|
|
537
|
+
description: "Standard themes for artifact organization"
|
|
538
|
+
|
|
539
|
+
themes:
|
|
540
|
+
commons:
|
|
541
|
+
definition: "Shared infrastructure and cross-cutting concerns"
|
|
542
|
+
scope: "Identity, authentication, identifiers, telemetry, UX system"
|
|
543
|
+
examples: ["commons:auth.claims", "commons:identifiers.uuid", "commons:ux:foundations:color"]
|
|
544
|
+
|
|
545
|
+
match:
|
|
546
|
+
definition: "Match orchestration and game state"
|
|
547
|
+
scope: "Game sessions, dilemmas, events, scoring, configuration"
|
|
548
|
+
examples: ["match:dilemma.current", "match:state.committed", "match:config.duel"]
|
|
549
|
+
|
|
550
|
+
mechanic:
|
|
551
|
+
definition: "Core game mechanics and rules"
|
|
552
|
+
scope: "Decisions, timebank, cascades, domain impacts, predictions"
|
|
553
|
+
examples: ["mechanic:decision.choice", "mechanic:domain.impact", "mechanic:timebank.remaining"]
|
|
554
|
+
|
|
555
|
+
sensory:
|
|
556
|
+
definition: "User interaction and presentation layer"
|
|
557
|
+
scope: "Gestures, feedback, character interactions, UI state"
|
|
558
|
+
examples: ["sensory:gesture.raw", "sensory:feedback.visual", "sensory:character.dialog"]
|
|
559
|
+
|
|
560
|
+
player:
|
|
561
|
+
definition: "Player lifecycle and progression"
|
|
562
|
+
scope: "Sessions, profiles, agreements, achievements"
|
|
563
|
+
examples: ["player:session.active", "player:profile", "player:achievement.earned"]
|
|
564
|
+
|
|
565
|
+
partnership:
|
|
566
|
+
definition: "Sponsor and partner relationships"
|
|
567
|
+
scope: "Agreements, reporting, persona mapping"
|
|
568
|
+
examples: ["partnership:sponsor.agreement", "partnership:report.attribution"]
|
|
569
|
+
|
|
570
|
+
scenario:
|
|
571
|
+
definition: "Content and scenario management"
|
|
572
|
+
scope: "Fragments, graphs, materials, catalogs"
|
|
573
|
+
examples: ["scenario:fragments", "scenario:catalog:primitives:actor"]
|
|
574
|
+
|
|
575
|
+
league:
|
|
576
|
+
definition: "Competitive structures"
|
|
577
|
+
scope: "Leaderboards, brackets, rewards"
|
|
578
|
+
examples: ["league:leaderboard.current", "league:bracket.current"]
|
|
579
|
+
|
|
580
|
+
audience:
|
|
581
|
+
definition: "Viewer and streaming features"
|
|
582
|
+
scope: "Donations, streams"
|
|
583
|
+
examples: ["audience:donation.completed", "audience:stream.data"]
|
|
584
|
+
|
|
585
|
+
monetization:
|
|
586
|
+
definition: "Economic system"
|
|
587
|
+
scope: "Wallets, tokens, transactions"
|
|
588
|
+
examples: ["monetization:wallet.player", "monetization:cameo.minted"]
|
|
589
|
+
|
|
590
|
+
decision_rules:
|
|
591
|
+
when_to_use_colon:
|
|
592
|
+
description: "Use colon for hierarchical descent"
|
|
593
|
+
indicators:
|
|
594
|
+
- "Different conceptual levels"
|
|
595
|
+
- "Navigating deeper into a structure"
|
|
596
|
+
- "Moving from general to specific"
|
|
597
|
+
- "Organizational subsystems"
|
|
598
|
+
examples:
|
|
599
|
+
- "commons:ux:foundations:color (theme → subsystem → category → item)"
|
|
600
|
+
- "scenario:catalog:primitives:actor (domain → collection → type → entity)"
|
|
601
|
+
|
|
602
|
+
when_to_use_dot:
|
|
603
|
+
description: "Use dot for lateral variation"
|
|
604
|
+
indicators:
|
|
605
|
+
- "Same conceptual level, different flavor"
|
|
606
|
+
- "State variations"
|
|
607
|
+
- "Type variations"
|
|
608
|
+
- "Facet variations"
|
|
609
|
+
examples:
|
|
610
|
+
- "sensory:gesture.raw vs sensory:gesture.tapped (different gestures)"
|
|
611
|
+
- "player:session.active vs player:session.closed (different states)"
|
|
612
|
+
- "match:config.duel vs match:config.team (different modes)"
|
|
613
|
+
|
|
614
|
+
depth_guidelines:
|
|
615
|
+
hierarchy_depth:
|
|
616
|
+
typical: "2-3 levels (theme:cat1:cat2:aspect)"
|
|
617
|
+
maximum: "4-5 levels (use sparingly)"
|
|
618
|
+
guideline: "Each colon should add clear semantic value"
|
|
619
|
+
|
|
620
|
+
variant_depth:
|
|
621
|
+
typical: "0-1 levels (.variant)"
|
|
622
|
+
maximum: "2 levels (.variant.subvariant)"
|
|
623
|
+
warning: "Multiple dots often indicate over-specification"
|
|
624
|
+
guideline: "Keep variants shallow - internal details should stay internal"
|
|
625
|
+
|
|
626
|
+
urn_structure:
|
|
627
|
+
rule: "URN exactly matches artifact name - preserves colons and dots"
|
|
628
|
+
pattern: "contract:{artifact_name}"
|
|
629
|
+
|
|
630
|
+
examples:
|
|
631
|
+
- artifact: "commons:identifiers.uuid"
|
|
632
|
+
urn: "contract:commons:identifiers.uuid"
|
|
633
|
+
note: "Colon and dot preserved in URN"
|
|
634
|
+
|
|
635
|
+
- artifact: "commons:ux:foundations:color"
|
|
636
|
+
urn: "contract:commons:ux:foundations:color"
|
|
637
|
+
note: "All colons preserved"
|
|
638
|
+
|
|
639
|
+
- artifact: "commons:ux:foundations:color.primary"
|
|
640
|
+
urn: "contract:commons:ux:foundations:color.primary"
|
|
641
|
+
note: "Colons and dot preserved"
|
|
642
|
+
|
|
643
|
+
- artifact: "sensory:gesture.raw"
|
|
644
|
+
urn: "contract:sensory:gesture.raw"
|
|
645
|
+
note: "Matches exactly"
|
|
646
|
+
|
|
647
|
+
schema_identifier:
|
|
648
|
+
description: "How artifact names map to JSON Schema $id field and URN references"
|
|
649
|
+
|
|
650
|
+
id_field:
|
|
651
|
+
description: "The $id field in JSON Schema files"
|
|
652
|
+
pattern: "{theme}:{resource}[.{category}]"
|
|
653
|
+
examples:
|
|
654
|
+
- "mechanic:timebank.exhausted"
|
|
655
|
+
- "commons:ux:foundations:color"
|
|
656
|
+
- "commons:identifiers.uuid"
|
|
657
|
+
- "sensory:gesture.raw"
|
|
658
|
+
note: "NO 'urn:contract:' prefix, NO version suffix - clean artifact identifier"
|
|
659
|
+
|
|
660
|
+
urn_reference:
|
|
661
|
+
description: "URN format used in wagon produce[]/consume[] to reference contracts"
|
|
662
|
+
pattern: "contract:{artifact_name}"
|
|
663
|
+
examples:
|
|
664
|
+
- "contract:mechanic:timebank.exhausted"
|
|
665
|
+
- "contract:commons:ux:foundations:color"
|
|
666
|
+
- "contract:commons:identifiers.uuid"
|
|
667
|
+
usage: "Used in wagon manifests (plan/*/_*.yaml) to reference contract schemas"
|
|
668
|
+
note: "URN adds 'contract:' prefix for wagon produce/consume declarations"
|
|
669
|
+
|
|
670
|
+
version_separation:
|
|
671
|
+
rule: "Version is SEPARATE top-level field in schema, NOT part of $id"
|
|
672
|
+
rationale: "Allows artifact identity to remain stable across versions"
|
|
673
|
+
example:
|
|
674
|
+
$id: "mechanic:timebank.exhausted"
|
|
675
|
+
version: "1.0.0"
|
|
676
|
+
counter_example:
|
|
677
|
+
wrong: "mechanic:timebank.exhausted:v1"
|
|
678
|
+
reason: "Version in $id breaks artifact identity stability"
|
|
679
|
+
|
|
680
|
+
contract_file_mapping:
|
|
681
|
+
rule: "Artifact path maps directly to contract file path"
|
|
682
|
+
algorithm: |
|
|
683
|
+
1. Split artifact name by colons and dots
|
|
684
|
+
2. Theme becomes first directory
|
|
685
|
+
3. All segments become subdirectories
|
|
686
|
+
4. Final segment becomes filename
|
|
687
|
+
5. Add .schema.json extension
|
|
688
|
+
|
|
689
|
+
formula: |
|
|
690
|
+
artifact: theme:seg1:seg2:aspect.variant
|
|
691
|
+
contract: contracts/theme/seg1/seg2/aspect/variant.schema.json
|
|
692
|
+
|
|
693
|
+
examples:
|
|
694
|
+
- artifact: "commons:identifiers.uuid"
|
|
695
|
+
contract: "contracts/commons/identifiers/uuid.schema.json"
|
|
696
|
+
breakdown: ["commons", "identifiers", "uuid"]
|
|
697
|
+
|
|
698
|
+
- artifact: "commons:ux:foundations:color"
|
|
699
|
+
contract: "contracts/commons/ux/foundations/color.schema.json"
|
|
700
|
+
breakdown: ["commons", "ux", "foundations", "color"]
|
|
701
|
+
|
|
702
|
+
- artifact: "commons:ux:foundations:color.primary"
|
|
703
|
+
contract: "contracts/commons/ux/foundations/color/primary.schema.json"
|
|
704
|
+
breakdown: ["commons", "ux", "foundations", "color", "primary"]
|
|
705
|
+
|
|
706
|
+
- artifact: "sensory:feedback:haptic:pulse.short"
|
|
707
|
+
contract: "contracts/sensory/feedback/haptic/pulse/short.schema.json"
|
|
708
|
+
breakdown: ["sensory", "feedback", "haptic", "pulse", "short"]
|
|
709
|
+
|
|
710
|
+
anti_patterns:
|
|
711
|
+
wrong_separator_for_hierarchy:
|
|
712
|
+
bad: "commons:ux.foundations.color"
|
|
713
|
+
why: "Uses dots for hierarchy - visually suggests variants when it's actually depth"
|
|
714
|
+
fix: "commons:ux:foundations:color (colons for hierarchical descent)"
|
|
715
|
+
|
|
716
|
+
wrong_separator_for_variant:
|
|
717
|
+
bad: "sensory:gesture:raw"
|
|
718
|
+
why: "Uses colon for variant - suggests hierarchy when it's lateral variation"
|
|
719
|
+
fix: "sensory:gesture.raw (dot for variant facet)"
|
|
720
|
+
|
|
721
|
+
missing_theme:
|
|
722
|
+
bad: "gesture.raw"
|
|
723
|
+
why: "No theme - unclear which system owns this"
|
|
724
|
+
fix: "sensory:gesture.raw (adds architectural context)"
|
|
725
|
+
|
|
726
|
+
too_many_dots:
|
|
727
|
+
bad: "commons:identifiers.uuid.v7.timestamp.encoded"
|
|
728
|
+
why: "Over-specified - internal details leak into public name"
|
|
729
|
+
fix: "commons:identifiers.uuid (v7, timestamp are internal)"
|
|
730
|
+
|
|
731
|
+
unnecessary_hierarchy:
|
|
732
|
+
bad: "match:config:base:standard"
|
|
733
|
+
why: "Adds hierarchy levels without semantic value"
|
|
734
|
+
fix: "match:config (keep it simple when hierarchy doesn't add clarity)"
|
|
735
|
+
|
|
736
|
+
generic_aspect:
|
|
737
|
+
bad: "match:data"
|
|
738
|
+
why: "Too vague - what kind of data?"
|
|
739
|
+
fix: "match:state.committed (specific and meaningful)"
|
|
740
|
+
|
|
741
|
+
theme_in_aspect:
|
|
742
|
+
bad: "sensory:sensory-feedback.visual"
|
|
743
|
+
why: "Theme repeated in aspect - redundant"
|
|
744
|
+
fix: "sensory:feedback.visual (theme already provides context)"
|
|
745
|
+
|
|
746
|
+
validation_rules:
|
|
747
|
+
format:
|
|
748
|
+
- "Theme must be lowercase, no separators"
|
|
749
|
+
- "Category segments must be kebab-case"
|
|
750
|
+
- "Aspect must be kebab-case"
|
|
751
|
+
- "Variant must be kebab-case"
|
|
752
|
+
- "Use colon (:) for hierarchical descent"
|
|
753
|
+
- "Use dot (.) for lateral variants"
|
|
754
|
+
|
|
755
|
+
semantic:
|
|
756
|
+
- "Theme must be from approved taxonomy"
|
|
757
|
+
- "Each hierarchy level should add clear semantic value"
|
|
758
|
+
- "Aspect should be a concrete noun"
|
|
759
|
+
- "Variant should describe a state, type, or facet"
|
|
760
|
+
- "URN must exactly match artifact name"
|
|
761
|
+
- "Avoid deep variant nesting (typically 0-1 dots)"
|
|
762
|
+
|
|
763
|
+
technical:
|
|
764
|
+
- "Contract file must exist at contracts/{path_segments}.schema.json"
|
|
765
|
+
- "$id in contract must be urn:contract:{artifact_name}"
|
|
766
|
+
- "All consumers must reference the same artifact name"
|
|
767
|
+
- "File path must be derivable from artifact name by splitting on : and ."
|
|
768
|
+
|
|
769
|
+
migration_guide:
|
|
770
|
+
from_v1_to_v2:
|
|
771
|
+
overview: "Migrate from old pattern to theme:hierarchy:aspect.variant"
|
|
772
|
+
|
|
773
|
+
steps:
|
|
774
|
+
- step: "Identify current artifact names"
|
|
775
|
+
action: "List all produce/consume artifact names in wagons"
|
|
776
|
+
|
|
777
|
+
- step: "Determine appropriate theme"
|
|
778
|
+
action: "Map artifacts to theme taxonomy"
|
|
779
|
+
|
|
780
|
+
- step: "Identify hierarchy levels"
|
|
781
|
+
action: "Determine if artifact needs category/subcategory levels"
|
|
782
|
+
|
|
783
|
+
- step: "Separate hierarchy from variants"
|
|
784
|
+
action: "Use colons for levels, dots for variants"
|
|
785
|
+
|
|
786
|
+
- step: "Update wagon manifests"
|
|
787
|
+
action: "Update produce/consume sections"
|
|
788
|
+
|
|
789
|
+
- step: "Update feature files"
|
|
790
|
+
action: "Update ioSeeds/produces sections"
|
|
791
|
+
|
|
792
|
+
- step: "Update URNs"
|
|
793
|
+
action: "Ensure URNs match artifact names exactly"
|
|
794
|
+
|
|
795
|
+
- step: "Reorganize contracts"
|
|
796
|
+
action: "Move files to match new hierarchy"
|
|
797
|
+
|
|
798
|
+
- step: "Update contract $id fields"
|
|
799
|
+
action: "Set $id to match new URN"
|
|
800
|
+
|
|
801
|
+
example_migrations:
|
|
802
|
+
simple_rename:
|
|
803
|
+
old: "identifiers:uuid"
|
|
804
|
+
new: "commons:identifiers.uuid"
|
|
805
|
+
reason: "Added theme, converted colon to dot for variant"
|
|
806
|
+
|
|
807
|
+
hierarchy_correction:
|
|
808
|
+
old: "ux.foundations.color"
|
|
809
|
+
new: "commons:ux:foundations:color"
|
|
810
|
+
reason: "Added theme, converted dots to colons for hierarchy"
|
|
811
|
+
|
|
812
|
+
mixed:
|
|
813
|
+
old: "ux.foundations.color.primary"
|
|
814
|
+
new: "commons:ux:foundations:color.primary"
|
|
815
|
+
reason: "Added theme, colons for hierarchy, dot for variant"
|
|
816
|
+
|
|
817
|
+
benefits:
|
|
818
|
+
clear_separation:
|
|
819
|
+
description: "Visual distinction between hierarchy and variants"
|
|
820
|
+
example: "commons:ux:foundations:color.primary clearly shows 4 hierarchical levels + 1 variant"
|
|
821
|
+
|
|
822
|
+
unlimited_hierarchy:
|
|
823
|
+
description: "Can go as deep as needed without confusion"
|
|
824
|
+
example: "commons:telemetry:observability:traces:span:context (6 levels)"
|
|
825
|
+
|
|
826
|
+
controlled_variants:
|
|
827
|
+
description: "Dots signal lateral variation, discourage deep nesting"
|
|
828
|
+
example: "gesture.raw not gesture.raw.filtered.normalized (too deep)"
|
|
829
|
+
|
|
830
|
+
file_path_clarity:
|
|
831
|
+
description: "Direct mapping to filesystem structure"
|
|
832
|
+
example: "Every colon or dot becomes a directory boundary"
|
|
833
|
+
|
|
834
|
+
semantic_consistency:
|
|
835
|
+
description: "Same separator always means same thing"
|
|
836
|
+
example: "Colon always = deeper, dot always = lateral"
|
|
837
|
+
|
|
838
|
+
references:
|
|
839
|
+
conventions:
|
|
840
|
+
- "conventions:planner:wagon - Wagon structure"
|
|
841
|
+
- "conventions:planner:component - Component naming"
|
|
842
|
+
- "conventions:coder:component-naming - Implementation naming"
|
|
843
|
+
|
|
844
|
+
schemas:
|
|
845
|
+
- "schemas:planner:wagon - Wagon schema with produce/consume"
|
|
846
|
+
- "schemas:planner:feature - Feature schema"
|
|
847
|
+
|
|
848
|
+
related:
|
|
849
|
+
- "Theme taxonomy derives from bounded contexts"
|
|
850
|
+
- "Contract file structure mirrors artifact naming"
|
|
851
|
+
- "Hierarchy reflects domain organization"
|
|
852
|
+
- "Variants reflect runtime/configuration differences"
|