@praxisui/charts 9.0.0-beta.73 → 9.0.0-beta.75

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-07-12T01:34:40.567Z",
3
+ "generatedAt": "2026-07-16T21:37:28.607Z",
4
4
  "packageName": "@praxisui/charts",
5
- "packageVersion": "9.0.0-beta.73",
5
+ "packageVersion": "9.0.0-beta.75",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 2,
@@ -73,7 +73,43 @@
73
73
  "name": "chartDocument",
74
74
  "type": "PraxisXUiChartContract | null",
75
75
  "required": false,
76
- "description": "Optional canonical x-ui.chart document used as the authoring source of truth for settings-panel integration."
76
+ "description": "Optional canonical x-ui.chart document used as the authoring source of truth for settings-panel integration.",
77
+ "default": {
78
+ "version": "0.1.0",
79
+ "kind": "bar",
80
+ "chartId": "palette-chart",
81
+ "title": "Analytics preview",
82
+ "subtitle": "Sample chart inserted from the Praxis component palette.",
83
+ "source": {
84
+ "kind": "derived"
85
+ },
86
+ "dimensions": [
87
+ {
88
+ "field": "category",
89
+ "role": "category"
90
+ }
91
+ ],
92
+ "metrics": [
93
+ {
94
+ "field": "value",
95
+ "aggregation": "sum",
96
+ "label": "Value"
97
+ }
98
+ ],
99
+ "legend": {
100
+ "enabled": true
101
+ },
102
+ "labels": {
103
+ "enabled": false
104
+ },
105
+ "tooltip": {
106
+ "enabled": true
107
+ },
108
+ "motion": {
109
+ "enabled": true,
110
+ "preset": "standard"
111
+ }
112
+ }
77
113
  },
78
114
  {
79
115
  "name": "queryContext",
@@ -104,21 +140,21 @@
104
140
  "name": "availableResources",
105
141
  "type": "ReadonlyArray<ChartEditorResourceOption>",
106
142
  "required": false,
107
- "description": "Catalog of remote resources exposed to the runtime chart editor when customization is enabled.",
143
+ "description": "Transient governed resource catalog. id is the stable discovery identity and path is the root-relative operational value persisted to chartDocument.source.resource; the catalog itself is not persisted.",
108
144
  "default": []
109
145
  },
110
146
  {
111
147
  "name": "availableFields",
112
148
  "type": "ReadonlyArray<ChartEditorFieldOption>",
113
149
  "required": false,
114
- "description": "Catalog of semantic fields exposed to the runtime chart editor when customization is enabled.",
150
+ "description": "Transient capability-backed field catalog with exact operation, aggregation and distribution terms/histogram eligibility; not intended for widget persistence.",
115
151
  "default": []
116
152
  },
117
153
  {
118
154
  "name": "availableTargets",
119
155
  "type": "ReadonlyArray<ChartEditorTargetOption>",
120
156
  "required": false,
121
- "description": "Catalog of widget or route targets exposed to chart runtime actions in the config editor.",
157
+ "description": "Transient event-scoped targets from existing top-level links that are compatible with public, non-deprecated widget ports or explicitly writable declared page state. events[] identifies the exact authorized structured Chart events; raw pointClick never authorizes events.pointClick, which uses pointAction. Local transform.output semantic-kind inspection is provisional and does not replace a Core-validated transform-output projection (P2). The catalog is not persisted.",
122
158
  "default": []
123
159
  }
124
160
  ],
@@ -127,13 +163,25 @@
127
163
  "name": "pointClick",
128
164
  "type": "PraxisChartPointEvent",
129
165
  "required": false,
130
- "description": "Emitted when the host wants to react to a point/series click."
166
+ "description": "Raw renderer-neutral point evidence emitted when the host wants to observe a point/series click."
167
+ },
168
+ {
169
+ "name": "pointAction",
170
+ "type": "PraxisChartPointActionEvent",
171
+ "required": false,
172
+ "description": "Emitted when a configured pointClick action resolves semantic filters and target evidence from a point/series click."
131
173
  },
132
174
  {
133
175
  "name": "selectionChange",
134
176
  "type": "PraxisChartSelectionEvent",
135
177
  "required": false,
136
- "description": "Emitted when declarative chart selection resolves a selected point and its canonical filters."
178
+ "description": "Emitted when declarative single-point chart selection resolves selected point evidence and canonical filters."
179
+ },
180
+ {
181
+ "name": "drillDown",
182
+ "type": "PraxisChartDrillDownEvent",
183
+ "required": false,
184
+ "description": "Emitted when declarative drill-down resolves action, target and canonical filters from a selected chart point."
137
185
  },
138
186
  {
139
187
  "name": "crossFilter",
@@ -263,7 +311,7 @@
263
311
  "label": "Point Click",
264
312
  "direction": "output",
265
313
  "semanticKind": "event",
266
- "description": "Interaction event emitted when a point or series is clicked.",
314
+ "description": "Raw renderer-neutral point evidence emitted when a point or series is clicked.",
267
315
  "cardinality": "stream",
268
316
  "schema": {
269
317
  "id": "PraxisChartPointEvent",
@@ -275,6 +323,23 @@
275
323
  "group": "interaction"
276
324
  }
277
325
  },
326
+ {
327
+ "id": "pointAction",
328
+ "label": "Point Action",
329
+ "direction": "output",
330
+ "semanticKind": "event",
331
+ "description": "Structured configured pointClick action derived from raw point evidence.",
332
+ "cardinality": "stream",
333
+ "schema": {
334
+ "id": "PraxisChartPointActionEvent",
335
+ "kind": "ts-type",
336
+ "ref": "PraxisChartPointActionEvent"
337
+ },
338
+ "exposure": {
339
+ "public": true,
340
+ "group": "interaction"
341
+ }
342
+ },
278
343
  {
279
344
  "id": "selectionChange",
280
345
  "label": "Selection Change",
@@ -292,6 +357,23 @@
292
357
  "group": "interaction"
293
358
  }
294
359
  },
360
+ {
361
+ "id": "drillDown",
362
+ "label": "Drill Down",
363
+ "direction": "output",
364
+ "semanticKind": "event",
365
+ "description": "Structured drill-down action payload derived from selected chart point evidence.",
366
+ "cardinality": "stream",
367
+ "schema": {
368
+ "id": "PraxisChartDrillDownEvent",
369
+ "kind": "ts-type",
370
+ "ref": "PraxisChartDrillDownEvent"
371
+ },
372
+ "exposure": {
373
+ "public": true,
374
+ "group": "interaction"
375
+ }
376
+ },
295
377
  {
296
378
  "id": "crossFilter",
297
379
  "label": "Cross Filter",
@@ -348,6 +430,71 @@
348
430
  "component": "[ref:PraxisChartWidgetConfigEditor]",
349
431
  "title": "Configure chart"
350
432
  },
433
+ "authoringManifestRef": {
434
+ "componentId": "praxis-chart",
435
+ "source": "PRAXIS_CHARTS_AUTHORING_MANIFEST"
436
+ },
437
+ "insertionPresets": [
438
+ {
439
+ "id": "canonical-chart",
440
+ "label": "Canonical chart",
441
+ "description": "Creates a chart widget from the canonical x-ui.chart authoring document.",
442
+ "icon": "bar_chart",
443
+ "inputs": {
444
+ "chartDocument": {
445
+ "version": "0.1.0",
446
+ "kind": "bar",
447
+ "chartId": "palette-chart",
448
+ "title": "Analytics preview",
449
+ "subtitle": "Sample chart inserted from the Praxis component palette.",
450
+ "source": {
451
+ "kind": "derived"
452
+ },
453
+ "dimensions": [
454
+ {
455
+ "field": "category",
456
+ "role": "category"
457
+ }
458
+ ],
459
+ "metrics": [
460
+ {
461
+ "field": "value",
462
+ "aggregation": "sum",
463
+ "label": "Value"
464
+ }
465
+ ],
466
+ "legend": {
467
+ "enabled": true
468
+ },
469
+ "labels": {
470
+ "enabled": false
471
+ },
472
+ "tooltip": {
473
+ "enabled": true
474
+ },
475
+ "motion": {
476
+ "enabled": true,
477
+ "preset": "standard"
478
+ }
479
+ },
480
+ "data": [
481
+ {
482
+ "category": "A",
483
+ "value": 18
484
+ },
485
+ {
486
+ "category": "B",
487
+ "value": 32
488
+ },
489
+ {
490
+ "category": "C",
491
+ "value": 24
492
+ }
493
+ ],
494
+ "enableCustomization": true
495
+ }
496
+ }
497
+ ],
351
498
  "source": "projects/praxis-charts/src/lib/praxis-chart.metadata.ts",
352
499
  "exportName": "PRAXIS_CHART_COMPONENT_METADATA",
353
500
  "authoringManifest": {
@@ -370,7 +517,7 @@
370
517
  {
371
518
  "name": "queryContext",
372
519
  "type": "PraxisChartQueryContext | null",
373
- "description": "Declarative query context merged into remote datasource requests."
520
+ "description": "Canonical @praxisui/core query context observed by remote datasource requests; flat filters execute in praxis.stats and governed filterExpression is preserved but rejected until stats expression support is proven."
374
521
  },
375
522
  {
376
523
  "name": "remoteDataResolver",
@@ -380,17 +527,17 @@
380
527
  {
381
528
  "name": "availableResources",
382
529
  "type": "ChartEditorResourceOption[]",
383
- "description": "Governed remote resource catalog exposed to the config editor."
530
+ "description": "Transient authoring catalog: id is the stable /schemas/catalog discovery identity, while path is the governed root-relative operational value persisted to chartDocument.source.resource."
384
531
  },
385
532
  {
386
533
  "name": "availableFields",
387
534
  "type": "ChartEditorFieldOption[]",
388
- "description": "Governed semantic field catalog exposed to the config editor."
535
+ "description": "Transient capability-backed field catalog. operations, aggregations and distributionModes declare exact group-by, timeseries, distribution/terms and distribution/histogram eligibility."
389
536
  },
390
537
  {
391
538
  "name": "availableTargets",
392
539
  "type": "ChartEditorTargetOption[]",
393
- "description": "Governed widget or route targets exposed to chart event authoring."
540
+ "description": "Transient visual-authoring targets derived from existing top-level composition links to public, non-deprecated widget ports or explicitly writable declared page state; id is the unique authoring identity and events[] declares the exact structured Chart events authorized by compatible links. Raw pointClick evidence never authorizes events.pointClick, which is emitted through pointAction. Local transform.output semantic-kind inspection does not replace a Core-validated transform-output projection (P2), and the visual catalog does not yet publish the target input-schema/port projection required for end-to-end mapping validation."
394
541
  }
395
542
  ],
396
543
  "editableTargets": [
@@ -417,7 +564,12 @@
417
564
  {
418
565
  "kind": "queryContext",
419
566
  "resolver": "praxis-chart-query-context",
420
- "description": "Runtime queryContext contract for filters, sort, limit and page."
567
+ "description": "Runtime @praxisui/core queryContext contract for filters, filterExpression, sort, limit, page and governance metadata."
568
+ },
569
+ {
570
+ "kind": "pointClick",
571
+ "resolver": "x-ui-chart-events-point-click",
572
+ "description": "Raw pointClick evidence plus a separate pointAction output for configured pointClick actions."
421
573
  },
422
574
  {
423
575
  "kind": "crossFilter",
@@ -432,7 +584,7 @@
432
584
  {
433
585
  "kind": "selection",
434
586
  "resolver": "x-ui-chart-events-selection-change",
435
- "description": "Selection event enablement and mapping semantics."
587
+ "description": "Single-point selection event enablement and mapping semantics; toggle and multi-select are intentionally not advertised."
436
588
  },
437
589
  {
438
590
  "kind": "legend",
@@ -993,7 +1145,8 @@
993
1145
  ]
994
1146
  },
995
1147
  "resource": {
996
- "type": "string"
1148
+ "type": "string",
1149
+ "pattern": "^/(?!/)"
997
1150
  },
998
1151
  "operation": {
999
1152
  "enum": [
@@ -1096,7 +1249,6 @@
1096
1249
  ],
1097
1250
  "identityKeys": [
1098
1251
  "availableResources[].path",
1099
- "availableResources[].id",
1100
1252
  "availableFields[].field"
1101
1253
  ],
1102
1254
  "inputSchema": {
@@ -1112,7 +1264,8 @@
1112
1264
  ]
1113
1265
  },
1114
1266
  "resource": {
1115
- "type": "string"
1267
+ "type": "string",
1268
+ "pattern": "^/(?!/)"
1116
1269
  },
1117
1270
  "operation": {
1118
1271
  "enum": [
@@ -1135,7 +1288,7 @@
1135
1288
  "stats-operation-not-supported",
1136
1289
  "remote-binding-incomplete"
1137
1290
  ],
1138
- "description": "Binds a derived or praxis.stats source using the governed resource and field catalogs instead of free-form prompt examples."
1291
+ "description": "Binds a derived or praxis.stats source using governed catalogs. For praxis.stats, availableResources[].id is discovery-only: validation requires the matching availableResources[].path and compilation persists that path as chartDocument.source.resource."
1139
1292
  }
1140
1293
  }
1141
1294
  ],
@@ -1174,6 +1327,9 @@
1174
1327
  "filters": {
1175
1328
  "type": "object"
1176
1329
  },
1330
+ "filterExpression": {
1331
+ "type": "object"
1332
+ },
1177
1333
  "sort": {
1178
1334
  "type": "array",
1179
1335
  "items": {
@@ -1201,6 +1357,7 @@
1201
1357
  "requiresConfirmation": false,
1202
1358
  "validators": [
1203
1359
  "query-context-structured",
1360
+ "query-context-filter-expression-stats-unsupported",
1204
1361
  "query-context-fields-exist",
1205
1362
  "query-context-safe-values",
1206
1363
  "editor-runtime-round-trip"
@@ -1213,6 +1370,112 @@
1213
1370
  "config-initialized"
1214
1371
  ]
1215
1372
  },
1373
+ {
1374
+ "operationId": "pointClick.configure",
1375
+ "title": "Configure chart point click",
1376
+ "scope": "eventMapping",
1377
+ "targetKind": "pointClick",
1378
+ "target": {
1379
+ "kind": "pointClick",
1380
+ "resolver": "x-ui-chart-events-point-click",
1381
+ "ambiguityPolicy": "fail",
1382
+ "required": false
1383
+ },
1384
+ "inputSchema": {
1385
+ "type": "object",
1386
+ "required": [
1387
+ "action"
1388
+ ],
1389
+ "properties": {
1390
+ "action": {
1391
+ "enum": [
1392
+ "filter-widget",
1393
+ "open-detail",
1394
+ "navigate",
1395
+ "update-context",
1396
+ "emit"
1397
+ ]
1398
+ },
1399
+ "target": {
1400
+ "type": "string"
1401
+ },
1402
+ "mapping": {
1403
+ "type": "object",
1404
+ "additionalProperties": {
1405
+ "type": "string"
1406
+ }
1407
+ }
1408
+ }
1409
+ },
1410
+ "effects": [
1411
+ {
1412
+ "kind": "compile-domain-patch",
1413
+ "handler": "chart-event-point-click-configure",
1414
+ "handlerContract": {
1415
+ "reads": [
1416
+ "chartDocument.events.pointClick",
1417
+ "chartDocument.dimensions[]",
1418
+ "availableTargets[]"
1419
+ ],
1420
+ "writes": [
1421
+ "chartDocument.events.pointClick"
1422
+ ],
1423
+ "identityKeys": [
1424
+ "availableTargets[].id"
1425
+ ],
1426
+ "inputSchema": {
1427
+ "type": "object",
1428
+ "required": [
1429
+ "action"
1430
+ ],
1431
+ "properties": {
1432
+ "action": {
1433
+ "enum": [
1434
+ "filter-widget",
1435
+ "open-detail",
1436
+ "navigate",
1437
+ "update-context",
1438
+ "emit"
1439
+ ]
1440
+ },
1441
+ "target": {
1442
+ "type": "string"
1443
+ },
1444
+ "mapping": {
1445
+ "type": "object",
1446
+ "additionalProperties": {
1447
+ "type": "string"
1448
+ }
1449
+ }
1450
+ }
1451
+ },
1452
+ "failureModes": [
1453
+ "target-not-in-catalog",
1454
+ "mapping-source-field-missing",
1455
+ "mapping-target-invalid",
1456
+ "unsafe-event-action"
1457
+ ],
1458
+ "description": "Configures pointClick through the pointAction output while keeping pointClick as raw point evidence."
1459
+ }
1460
+ }
1461
+ ],
1462
+ "destructive": false,
1463
+ "requiresConfirmation": false,
1464
+ "validators": [
1465
+ "point-click-action-structured",
1466
+ "event-target-governed",
1467
+ "event-mapping-fields-exist",
1468
+ "event-action-supported",
1469
+ "editor-runtime-round-trip"
1470
+ ],
1471
+ "affectedPaths": [
1472
+ "chartDocument.events.pointClick"
1473
+ ],
1474
+ "submissionImpact": "affects-schema-backed-data",
1475
+ "preconditions": [
1476
+ "config-initialized"
1477
+ ]
1478
+ },
1216
1479
  {
1217
1480
  "operationId": "crossFilter.configure",
1218
1481
  "title": "Configure chart cross-filter",
@@ -1298,7 +1561,7 @@
1298
1561
  "mapping-target-invalid",
1299
1562
  "unsafe-event-action"
1300
1563
  ],
1301
- "description": "Configures crossFilter as a structured event action that emits safe query-context filters to a governed target."
1564
+ "description": "Configures crossFilter as a structured event action emitted through the crossFilter output with safe query-context filters to a governed target. For praxis.stats rows, key is governed bucket identity and label is presentation evidence; mappings may use key when the target schema accepts that identity."
1302
1565
  }
1303
1566
  }
1304
1567
  ],
@@ -1403,7 +1666,7 @@
1403
1666
  "drilldown-target-invalid",
1404
1667
  "unsafe-event-action"
1405
1668
  ],
1406
- "description": "Configures drillDown through governed route/widget targets and structured field mappings."
1669
+ "description": "Configures drillDown through the dedicated drillDown output with governed route/widget targets and structured field mappings."
1407
1670
  }
1408
1671
  }
1409
1672
  ],
@@ -1508,7 +1771,7 @@
1508
1771
  "mapping-target-invalid",
1509
1772
  "unsafe-event-action"
1510
1773
  ],
1511
- "description": "Configures selectionChange as a structured event action whose event key is governed by the operation."
1774
+ "description": "Configures selectionChange as single-point selection evidence whose event key is governed by the operation."
1512
1775
  }
1513
1776
  }
1514
1777
  ],
@@ -1516,6 +1779,7 @@
1516
1779
  "requiresConfirmation": false,
1517
1780
  "validators": [
1518
1781
  "selection-output-structured",
1782
+ "event-target-governed",
1519
1783
  "event-mapping-fields-exist",
1520
1784
  "event-action-supported",
1521
1785
  "editor-runtime-round-trip"
@@ -1623,8 +1887,7 @@
1623
1887
  {
1624
1888
  "validatorId": "chart-version-supported",
1625
1889
  "level": "error",
1626
- "code": "CHART_VERSION_SUPPORTED",
1627
- "description": "Only x-ui.chart version 0.1.0 is authorable."
1890
+ "code": "CHART_VERSION_SUPPORTED"
1628
1891
  },
1629
1892
  {
1630
1893
  "validatorId": "chart-type-supported",
@@ -1708,13 +1971,13 @@
1708
1971
  "validatorId": "remote-resource-in-api-metadata",
1709
1972
  "level": "error",
1710
1973
  "code": "REMOTE_RESOURCE_IN_API_METADATA",
1711
- "description": "Remote praxis.stats resource must come from the governed API metadata/resource catalog."
1974
+ "description": "Remote praxis.stats resource must equal a governed root-relative availableResources[].path beginning with exactly one slash; a discovery id is not an executable resource path."
1712
1975
  },
1713
1976
  {
1714
1977
  "validatorId": "bound-fields-exist",
1715
1978
  "level": "error",
1716
1979
  "code": "BOUND_FIELDS_EXIST",
1717
- "description": "Bound dimensions and metrics must exist in the schema/data context."
1980
+ "description": "Bound dimensions and metrics must exist in the capability-backed field context and satisfy its operation, aggregation and distribution-mode eligibility."
1718
1981
  },
1719
1982
  {
1720
1983
  "validatorId": "stats-operation-supported",
@@ -1726,7 +1989,13 @@
1726
1989
  "validatorId": "query-context-structured",
1727
1990
  "level": "error",
1728
1991
  "code": "QUERY_CONTEXT_STRUCTURED",
1729
- "description": "queryContext must use structured filters, sort, limit and page fields."
1992
+ "description": "queryContext must use the canonical @praxisui/core structure for filters, filterExpression, sort, limit, page and meta."
1993
+ },
1994
+ {
1995
+ "validatorId": "query-context-filter-expression-stats-unsupported",
1996
+ "level": "error",
1997
+ "code": "QUERY_CONTEXT_FILTER_EXPRESSION_STATS_UNSUPPORTED",
1998
+ "description": "praxis.stats currently executes only flat queryContext.filters; governed filterExpression must be preserved for diagnostics and rejected until backend expression support is declared."
1730
1999
  },
1731
2000
  {
1732
2001
  "validatorId": "query-context-fields-exist",
@@ -1740,6 +2009,12 @@
1740
2009
  "code": "QUERY_CONTEXT_SAFE_VALUES",
1741
2010
  "description": "queryContext values must be serializable safe data."
1742
2011
  },
2012
+ {
2013
+ "validatorId": "point-click-action-structured",
2014
+ "level": "error",
2015
+ "code": "POINT_CLICK_ACTION_STRUCTURED",
2016
+ "description": "Configured pointClick actions must be emitted through pointAction while pointClick remains raw point evidence."
2017
+ },
1743
2018
  {
1744
2019
  "validatorId": "cross-filter-output-structured",
1745
2020
  "level": "error",
@@ -1750,13 +2025,13 @@
1750
2025
  "validatorId": "event-target-governed",
1751
2026
  "level": "error",
1752
2027
  "code": "EVENT_TARGET_GOVERNED",
1753
- "description": "Event targets must be selected from availableTargets or an approved host catalog."
2028
+ "description": "Event targets must resolve to exactly one availableTargets[].id and declare the authored event plus action; missing, duplicate or cross-event identities fail closed."
1754
2029
  },
1755
2030
  {
1756
2031
  "validatorId": "event-mapping-fields-exist",
1757
2032
  "level": "error",
1758
2033
  "code": "EVENT_MAPPING_FIELDS_EXIST",
1759
- "description": "Event mapping source fields must exist in chart data context."
2034
+ "description": "Event mapping source fields must exist in chart data context; praxis.stats reserves key for bucket identity and label for presentation."
1760
2035
  },
1761
2036
  {
1762
2037
  "validatorId": "event-action-supported",
@@ -1792,8 +2067,11 @@
1792
2067
  "roundTripRequirements": [
1793
2068
  "The canonical saved shape is PraxisXUiChartContract, not raw ECharts options.",
1794
2069
  "PraxisChartConfigEditor must preserve chart kind, source, dimensions, metrics, events, legend and tooltip across apply/save/reset/reopen.",
1795
- "Remote bindings must be resolved from availableResources/API metadata and availableFields/schema context.",
1796
- "Cross-filter, drilldown and selection authoring must persist structured event actions, not prompt examples or command strings."
2070
+ "Remote bindings persist availableResources[].path; availableResources[].id remains discovery identity, and transient resource/field/target catalogs and diagnostics are never persisted in widget inputs.",
2071
+ "Cross-filter, drilldown and selection authoring must persist structured event actions, not prompt examples or command strings.",
2072
+ "[P1] Backend handler, resolver and validators now execute directly; end-to-end Page Builder parity remains open until assistant requests project the transient availableTargets[].events catalog through validationContext and expose its fail-closed diagnostics.",
2073
+ "[P2] Transform-output semantics and target input-schema/port fields must be materialized and validated by Core; local transform.output inspection and backend-enriched inputFields are not substitutes for those canonical projections.",
2074
+ "Enrichment of capability-backed availableFields with /schemas/filtered property metadata remains a later schema-flow gate."
1797
2075
  ],
1798
2076
  "examples": [
1799
2077
  {
@@ -1875,6 +2153,19 @@
1875
2153
  },
1876
2154
  "isPositive": true
1877
2155
  },
2156
+ {
2157
+ "id": "configure-stats-key-cross-filter",
2158
+ "request": "Use the governed department bucket identity to filter the employee table.",
2159
+ "operationId": "crossFilter.configure",
2160
+ "params": {
2161
+ "action": "filter-widget",
2162
+ "target": "employeesTable",
2163
+ "mapping": {
2164
+ "key": "departmentIdsIn"
2165
+ }
2166
+ },
2167
+ "isPositive": true
2168
+ },
1878
2169
  {
1879
2170
  "id": "configure-drilldown",
1880
2171
  "request": "Open the department detail when a point is clicked.",
@@ -1923,7 +2214,6 @@
1923
2214
  "request": "Save this chart in the editor and reopen it without changing the runtime chart document.",
1924
2215
  "operationId": "chart.document.set",
1925
2216
  "params": {
1926
- "version": "0.1.0",
1927
2217
  "kind": "bar",
1928
2218
  "source": {
1929
2219
  "kind": "derived"
@@ -1979,9 +2269,9 @@
1979
2269
  {
1980
2270
  "chunkIndex": 0,
1981
2271
  "chunkKind": "summary",
1982
- "content": "Component ID: praxis-chart\nSelector: praxis-chart\nFriendly Name: Praxis Chart\nDescription: Chart component for analytics and metadata-driven visualizations in Praxis UI.\nLib/Package: @praxisui/charts\nTags: chart, analytics, widget, visualization\nInputs:\n - config (PraxisChartConfig)\n - data (PraxisChartDataRow[])\n - chartDocument (PraxisXUiChartContract | null)\n - queryContext (PraxisDataQueryContext | null)\n - remoteDataResolver (PraxisChartRemoteDataResolver | null)\n - filterCriteria (Record<string, unknown> | null)\n - enableCustomization (boolean)\n - availableResources (ReadonlyArray<ChartEditorResourceOption>)\n - availableFields (ReadonlyArray<ChartEditorFieldOption>)\n - availableTargets (ReadonlyArray<ChartEditorTargetOption>)\nOutputs:\n - pointClick (PraxisChartPointEvent)\n - selectionChange (PraxisChartSelectionEvent)\n - crossFilter (PraxisChartCrossFilterEvent)\n - queryRequest (PraxisChartQueryRequestEvent)\n - loadStateChange (PraxisChartLoadState)\n - chartDocumentApplied (PraxisXUiChartContract)\n - chartDocumentSaved (PraxisXUiChartContract)\n",
2272
+ "content": "Component ID: praxis-chart\nSelector: praxis-chart\nFriendly Name: Praxis Chart\nDescription: Chart component for analytics and metadata-driven visualizations in Praxis UI.\nLib/Package: @praxisui/charts\nTags: chart, analytics, widget, visualization\nInputs:\n - config (PraxisChartConfig)\n - data (PraxisChartDataRow[])\n - chartDocument (PraxisXUiChartContract | null)\n - queryContext (PraxisDataQueryContext | null)\n - remoteDataResolver (PraxisChartRemoteDataResolver | null)\n - filterCriteria (Record<string, unknown> | null)\n - enableCustomization (boolean)\n - availableResources (ReadonlyArray<ChartEditorResourceOption>)\n - availableFields (ReadonlyArray<ChartEditorFieldOption>)\n - availableTargets (ReadonlyArray<ChartEditorTargetOption>)\nOutputs:\n - pointClick (PraxisChartPointEvent)\n - pointAction (PraxisChartPointActionEvent)\n - selectionChange (PraxisChartSelectionEvent)\n - drillDown (PraxisChartDrillDownEvent)\n - crossFilter (PraxisChartCrossFilterEvent)\n - queryRequest (PraxisChartQueryRequestEvent)\n - loadStateChange (PraxisChartLoadState)\n - chartDocumentApplied (PraxisXUiChartContract)\n - chartDocumentSaved (PraxisXUiChartContract)\nInsertion Presets:\n - canonical-chart: Canonical chart - Creates a chart widget from the canonical x-ui.chart authoring document.\n",
1983
2273
  "sourcePointer": "projects/praxis-charts/src/lib/praxis-chart.metadata.ts",
1984
- "contentHash": "fbebeb8395c3f4d58562c5553eb692fc21126d5ae9150bd9b110173dca7a6721",
2274
+ "contentHash": "5d9a01947277da58d7d6fe751dd45eb420c4607728eb61e1df417322506f917d",
1985
2275
  "sourceKind": "component_definition",
1986
2276
  "sourceId": "praxis-chart",
1987
2277
  "corpusVersion": "1.0.0"
@@ -1989,9 +2279,9 @@
1989
2279
  {
1990
2280
  "chunkIndex": 1,
1991
2281
  "chunkKind": "authoring_manifest",
1992
- "content": "{\n \"schemaVersion\": \"1.0.0\",\n \"componentId\": \"praxis-chart\",\n \"ownerPackage\": \"@praxisui/charts\",\n \"configSchemaId\": \"PraxisXUiChartContract\",\n \"manifestVersion\": \"1.0.0\",\n \"runtimeInputs\": [\n {\n \"name\": \"chartDocument\",\n \"type\": \"PraxisXUiChartContract | null\",\n \"description\": \"Canonical x-ui.chart document used as the authoring source of truth.\"\n },\n {\n \"name\": \"config\",\n \"type\": \"PraxisChartConfig\",\n \"description\": \"Runtime chart configuration mapped from or supplied beside the canonical chart document.\"\n },\n {\n \"name\": \"queryContext\",\n \"type\": \"PraxisChartQueryContext | null\",\n \"description\": \"Declarative query context merged into remote datasource requests.\"\n },\n {\n \"name\": \"remoteDataResolver\",\n \"type\": \"PraxisChartRemoteDataResolver | null\",\n \"description\": \"Host-governed remote row resolver for integrations outside the default praxis.stats client.\"\n },\n {\n \"name\": \"availableResources\",\n \"type\": \"ChartEditorResourceOption[]\",\n \"description\": \"Governed remote resource catalog exposed to the config editor.\"\n },\n {\n \"name\": \"availableFields\",\n \"type\": \"ChartEditorFieldOption[]\",\n \"description\": \"Governed semantic field catalog exposed to the config editor.\"\n },\n {\n \"name\": \"availableTargets\",\n \"type\": \"ChartEditorTargetOption[]\",\n \"description\": \"Governed widget or route targets exposed to chart event authoring.\"\n }\n ],\n \"editableTargets\": [\n {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"description\": \"Canonical `kind` field in PraxisXUiChartContract.\"\n },\n {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"description\": \"Metric-backed series definition in `metrics[]`, keyed by field.\"\n },\n {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"description\": \"Dimension role, metric axis and chart orientation semantics.\"\n },\n {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"description\": \"Source, dimensions, metrics and resource/field bindings.\"\n },\n {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"description\": \"Runtime queryContext contract for filters, sort, limit and page.\"\n },\n {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"description\": \"Cross-filter event mapping emitted as structured query-context filters.\"\n },\n {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"description\": \"Drilldown event mapping and governed target.\"\n },\n {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"description\": \"Selection event enablement and mapping semantics.\"\n },\n {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"description\": \"Legend visibility through boolean or toggleable feature object.\"\n },\n {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"description\": \"Tooltip visibility through boolean or toggleable feature object.\"\n }\n ],\n \"operations\": [\n {\n \"operationId\": \"chart.document.set\",\n \"title\": \"Set chart document\",\n \"scope\": \"global\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-document-root\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"kind\",\n \"source\"\n ],\n \"properties\": {\n \"version\": {\n \"const\": \"0.1.0\"\n },\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"chartId\": {\n \"type\": \"string\"\n },\n \"title\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"subtitle\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"source\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"options\": {\n \"type\": \"object\"\n }\n }\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"events\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-document-shape\",\n \"chart-version-supported\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"chart.type.set\",\n \"title\": \"Set chart type\",\n \"scope\": \"global\",\n \"targetKind\": \"chartType\",\n \"target\": {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-object\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-type-supported\",\n \"chart-type-series-axis-compatible\",\n \"pie-single-metric\",\n \"combo-minimum-series\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.kind\",\n \"chartDocument.orientation\",\n \"chartDocument.metrics[]\",\n \"chartDocument.dimensions[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.add\",\n \"title\": \"Add chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-series-add\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"duplicate-series-field\",\n \"aggregation-not-supported\",\n \"chart-type-series-incompatible\"\n ],\n \"description\": \"Adds a metric-backed series by semantic field, validating it against availableFields and chart kind compatibility before patching metrics[].\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"series-field-exists\",\n \"series-field-aggregable\",\n \"series-id-unique\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.remove\",\n \"title\": \"Remove chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"replacementField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"remove-by-key\",\n \"path\": \"chartDocument.metrics[]\",\n \"key\": \"field\"\n }\n ],\n \"destructive\": true,\n \"requiresConfirmation\": true,\n \"validators\": [\n \"series-exists\",\n \"destructive-series-removal-confirmed\",\n \"chart-keeps-required-metric\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-series-exists\",\n \"confirmation-collected\"\n ]\n },\n {\n \"operationId\": \"axis.configure\",\n \"title\": \"Configure chart axis\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"axis\",\n \"target\": {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-axis-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"chartDocument.orientation\"\n ],\n \"identityKeys\": [\n \"chartDocument.dimensions[].field\",\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"secondary-axis-non-combo\",\n \"missing-required-dimension\",\n \"axis-role-incompatible\"\n ],\n \"description\": \"Configures dimensions and metric axes using semantic fields, preserving combo-only secondary axis constraints.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"axis-field-exists\",\n \"secondary-axis-combo-only\",\n \"cartesian-dimension-required\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[].axis\",\n \"chartDocument.orientation\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"data.resource.bind\",\n \"title\": \"Bind chart data resource\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"role\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-data-resource-bind\",\n \"handlerContract\": {\n \"reads\": [\n \"availableResources[]\",\n \"availableFields[]\",\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"writes\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"availableResources[].path\",\n \"availableResources[].id\",\n \"availableFields[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\"\n },\n \"metrics\": {\n \"type\": \"array\"\n }\n }\n },\n \"failureModes\": [\n \"resource-not-in-api-metadata\",\n \"field-not-in-schema\",\n \"stats-operation-not-supported\",\n \"remote-binding-incomplete\"\n ],\n \"description\": \"Binds a derived or praxis.stats source using the governed resource and field catalogs instead of free-form prompt examples.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"remote-resource-in-api-metadata\",\n \"bound-fields-exist\",\n \"stats-operation-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"affects-remote-binding\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"queryContext.set\",\n \"title\": \"Set chart query context\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"queryContext\",\n \"target\": {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"filters\": {\n \"type\": \"object\"\n },\n \"sort\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"limit\": {\n \"type\": \"number\"\n },\n \"page\": {\n \"type\": \"object\"\n },\n \"meta\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"queryContext\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"query-context-structured\",\n \"query-context-fields-exist\",\n \"query-context-safe-values\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"queryContext\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"crossFilter.configure\",\n \"title\": \"Configure chart cross-filter\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"crossFilter\",\n \"target\": {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-cross-filter-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.crossFilter\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"mapping-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures crossFilter as a structured event action that emits safe query-context filters to a governed target.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"cross-filter-output-structured\",\n \"event-target-governed\",\n \"event-mapping-fields-exist\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"drilldown.configure\",\n \"title\": \"Configure chart drilldown\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"drilldown\",\n \"target\": {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-drilldown-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.drillDown\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.drillDown\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"drilldown-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures drillDown through governed route/widget targets and structured field mappings.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"drilldown-target-governed\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.drillDown\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"selection.configure\",\n \"title\": \"Configure chart selection\",\n \"scope\": \"selection\",\n \"targetKind\": \"selection\",\n \"target\": {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-selection-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.selectionChange\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.selectionChange\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"mapping-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures selectionChange as a structured event action whose event key is governed by the operation.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"selection-output-structured\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.selectionChange\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"legend.configure\",\n \"title\": \"Configure chart legend\",\n \"scope\": \"skin\",\n \"targetKind\": \"legend\",\n \"target\": {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.legend\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.legend\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"tooltip.configure\",\n \"title\": \"Configure chart tooltip\",\n \"scope\": \"skin\",\n \"targetKind\": \"tooltip\",\n \"target\": {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.tooltip\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.tooltip\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n }\n ],\n \"validators\": [\n {\n \"validatorId\": \"chart-document-shape\",\n \"level\": \"error\",\n \"code\": \"CHART_DOCUMENT_SHAPE\",\n \"description\": \"Document must conform to PraxisXUiChartContract.\"\n },\n {\n \"validatorId\": \"chart-version-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_VERSION_SUPPORTED\",\n \"description\": \"Only x-ui.chart version 0.1.0 is authorable.\"\n },\n {\n \"validatorId\": \"chart-type-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SUPPORTED\",\n \"description\": \"Chart kind must be supported by @praxisui/charts.\"\n },\n {\n \"validatorId\": \"chart-type-series-axis-compatible\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SERIES_AXIS_COMPATIBLE\",\n \"description\": \"Chart kind, dimensions, metrics and axes must be compatible.\"\n },\n {\n \"validatorId\": \"pie-single-metric\",\n \"level\": \"error\",\n \"code\": \"PIE_SINGLE_METRIC\",\n \"description\": \"Pie and donut charts support a single metric.\"\n },\n {\n \"validatorId\": \"combo-minimum-series\",\n \"level\": \"error\",\n \"code\": \"COMBO_MINIMUM_SERIES\",\n \"description\": \"Combo charts require at least two metrics.\"\n },\n {\n \"validatorId\": \"series-field-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_EXISTS\",\n \"description\": \"Series field must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"series-field-aggregable\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_AGGREGABLE\",\n \"description\": \"Metric fields must support the requested aggregation.\"\n },\n {\n \"validatorId\": \"series-id-unique\",\n \"level\": \"error\",\n \"code\": \"SERIES_ID_UNIQUE\",\n \"description\": \"Metric/series identity must be stable and unique by field.\"\n },\n {\n \"validatorId\": \"series-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_EXISTS\",\n \"description\": \"Series removal target must exist.\"\n },\n {\n \"validatorId\": \"destructive-series-removal-confirmed\",\n \"level\": \"error\",\n \"code\": \"DESTRUCTIVE_SERIES_REMOVAL_CONFIRMED\",\n \"description\": \"Removing a series requires explicit confirmation.\"\n },\n {\n \"validatorId\": \"chart-keeps-required-metric\",\n \"level\": \"error\",\n \"code\": \"CHART_KEEPS_REQUIRED_METRIC\",\n \"description\": \"A chart cannot be left without required metrics.\"\n },\n {\n \"validatorId\": \"axis-field-exists\",\n \"level\": \"error\",\n \"code\": \"AXIS_FIELD_EXISTS\",\n \"description\": \"Axis/dimension fields must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"secondary-axis-combo-only\",\n \"level\": \"error\",\n \"code\": \"SECONDARY_AXIS_COMBO_ONLY\",\n \"description\": \"Secondary axis is supported only for combo charts.\"\n },\n {\n \"validatorId\": \"cartesian-dimension-required\",\n \"level\": \"error\",\n \"code\": \"CARTESIAN_DIMENSION_REQUIRED\",\n \"description\": \"Cartesian charts require at least one dimension.\"\n },\n {\n \"validatorId\": \"remote-resource-in-api-metadata\",\n \"level\": \"error\",\n \"code\": \"REMOTE_RESOURCE_IN_API_METADATA\",\n \"description\": \"Remote praxis.stats resource must come from the governed API metadata/resource catalog.\"\n },\n {\n \"validatorId\": \"bound-fields-exist\",\n \"level\": \"error\",\n \"code\": \"BOUND_FIELDS_EXIST\",\n \"description\": \"Bound dimensions and metrics must exist in the schema/data context.\"\n },\n {\n \"validatorId\": \"stats-operation-supported\",\n \"level\": \"error\",\n \"code\": \"STATS_OPERATION_SUPPORTED\",\n \"description\": \"Remote datasource operation must be supported by the stats backend.\"\n },\n {\n \"validatorId\": \"query-context-structured\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_STRUCTURED\",\n \"description\": \"queryContext must use structured filters, sort, limit and page fields.\"\n },\n {\n \"validatorId\": \"query-context-fields-exist\",\n \"level\": \"warning\",\n \"code\": \"QUERY_CONTEXT_FIELDS_EXIST\",\n \"description\": \"queryContext filter fields should exist in the schema/data context.\"\n },\n {\n \"validatorId\": \"query-context-safe-values\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_SAFE_VALUES\",\n \"description\": \"queryContext values must be serializable safe data.\"\n },\n {\n \"validatorId\": \"cross-filter-output-structured\",\n \"level\": \"error\",\n \"code\": \"CROSS_FILTER_OUTPUT_STRUCTURED\",\n \"description\": \"Cross-filter output must be structured as query-context filters.\"\n },\n {\n \"validatorId\": \"event-target-governed\",\n \"level\": \"error\",\n \"code\": \"EVENT_TARGET_GOVERNED\",\n \"description\": \"Event targets must be selected from availableTargets or an approved host catalog.\"\n },\n {\n \"validatorId\": \"event-mapping-fields-exist\",\n \"level\": \"error\",\n \"code\": \"EVENT_MAPPING_FIELDS_EXIST\",\n \"description\": \"Event mapping source fields must exist in chart data context.\"\n },\n {\n \"validatorId\": \"event-action-supported\",\n \"level\": \"error\",\n \"code\": \"EVENT_ACTION_SUPPORTED\",\n \"description\": \"Event action must be one of the supported structured action kinds.\"\n },\n {\n \"validatorId\": \"drilldown-target-governed\",\n \"level\": \"error\",\n \"code\": \"DRILLDOWN_TARGET_GOVERNED\",\n \"description\": \"Drilldown target must be a governed route or widget target.\"\n },\n {\n \"validatorId\": \"selection-output-structured\",\n \"level\": \"error\",\n \"code\": \"SELECTION_OUTPUT_STRUCTURED\",\n \"description\": \"Selection output must resolve selected point filters deterministically.\"\n },\n {\n \"validatorId\": \"feature-toggle-valid\",\n \"level\": \"error\",\n \"code\": \"FEATURE_TOGGLE_VALID\",\n \"description\": \"Legend and tooltip feature values must be boolean or toggleable feature objects.\"\n },\n {\n \"validatorId\": \"editor-runtime-round-trip\",\n \"level\": \"error\",\n \"code\": \"EDITOR_RUNTIME_ROUND_TRIP\",\n \"description\": \"PraxisChartConfigEditor must save/reopen the same canonical document that runtime consumes.\"\n }\n ],\n \"roundTripRequirements\": [\n \"The canonical saved shape is PraxisXUiChartContract, not raw ECharts options.\",\n \"PraxisChartConfigEditor must preserve chart kind, source, dimensions, metrics, events, legend and tooltip across apply/save/reset/reopen.\",\n \"Remote bindings must be resolved from availableResources/API metadata and availableFields/schema context.\",\n \"Cross-filter, drilldown and selection authoring must persist structured event actions, not prompt examples or command strings.\"\n ],\n \"examples\": [\n {\n \"id\": \"set-bar-chart\",\n \"request\": \"Use a bar chart for employees by department.\",\n \"operationId\": \"chart.type.set\",\n \"params\": {\n \"kind\": \"bar\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"add-salary-series\",\n \"request\": \"Add salary as a summed metric.\",\n \"operationId\": \"series.add\",\n \"params\": {\n \"field\": \"salary\",\n \"aggregation\": \"sum\",\n \"label\": \"Salary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"remove-old-series\",\n \"request\": \"Remove the old cost series.\",\n \"operationId\": \"series.remove\",\n \"target\": \"cost\",\n \"params\": {\n \"field\": \"cost\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-secondary-axis\",\n \"request\": \"Put margin on a secondary axis for the combo chart.\",\n \"operationId\": \"axis.configure\",\n \"params\": {\n \"metricField\": \"margin\",\n \"metricAxis\": \"secondary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"bind-stats-resource\",\n \"request\": \"Bind this chart to payroll stats grouped by department.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"/api/stats/payroll\",\n \"operation\": \"group-by\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"set-query-context\",\n \"request\": \"Limit the chart to active employees and sort by total descending.\",\n \"operationId\": \"queryContext.set\",\n \"params\": {\n \"filters\": {\n \"status\": \"ACTIVE\"\n },\n \"sort\": [\n \"total,desc\"\n ],\n \"limit\": 10\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-cross-filter\",\n \"request\": \"Use selected department to filter the employee table.\",\n \"operationId\": \"crossFilter.configure\",\n \"params\": {\n \"action\": \"filter-widget\",\n \"target\": \"employeesTable\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-drilldown\",\n \"request\": \"Open the department detail when a point is clicked.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"action\": \"navigate\",\n \"target\": \"/departments/detail\",\n \"mapping\": {\n \"department\": \"departmentId\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-selection\",\n \"request\": \"Emit selected department as a structured selection event.\",\n \"operationId\": \"selection.configure\",\n \"params\": {\n \"action\": \"emit\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-legend\",\n \"request\": \"Show the legend.\",\n \"operationId\": \"legend.configure\",\n \"params\": {\n \"enabled\": true\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-tooltip\",\n \"request\": \"Disable tooltips.\",\n \"operationId\": \"tooltip.configure\",\n \"params\": {\n \"enabled\": false\n },\n \"isPositive\": true\n },\n {\n \"id\": \"round-trip-editor-runtime\",\n \"request\": \"Save this chart in the editor and reopen it without changing the runtime chart document.\",\n \"operationId\": \"chart.document.set\",\n \"params\": {\n \"version\": \"0.1.0\",\n \"kind\": \"bar\",\n \"source\": {\n \"kind\": \"derived\"\n },\n \"dimensions\": [\n {\n \"field\": \"department\"\n }\n ],\n \"metrics\": [\n {\n \"field\": \"total\",\n \"aggregation\": \"count\"\n }\n ]\n },\n \"isPositive\": true\n },\n {\n \"id\": \"reject-ambiguous-series-target\",\n \"request\": \"Remove total when more than one chart series resolves to total.\",\n \"operationId\": \"series.remove\",\n \"target\": \"total\",\n \"params\": {\n \"field\": \"total\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-prompt-routing\",\n \"request\": \"Use the prompt example text to decide which backend endpoint to call.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"from prompt example\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-unsafe-target\",\n \"request\": \"Navigate to javascript:alert(1) on drilldown.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"event\": \"drillDown\",\n \"action\": \"navigate\",\n \"target\": \"javascript:alert(1)\"\n },\n \"isPositive\": false\n }\n ]\n}",
2282
+ "content": "{\n \"schemaVersion\": \"1.0.0\",\n \"componentId\": \"praxis-chart\",\n \"ownerPackage\": \"@praxisui/charts\",\n \"configSchemaId\": \"PraxisXUiChartContract\",\n \"manifestVersion\": \"1.0.0\",\n \"runtimeInputs\": [\n {\n \"name\": \"chartDocument\",\n \"type\": \"PraxisXUiChartContract | null\",\n \"description\": \"Canonical x-ui.chart document used as the authoring source of truth.\"\n },\n {\n \"name\": \"config\",\n \"type\": \"PraxisChartConfig\",\n \"description\": \"Runtime chart configuration mapped from or supplied beside the canonical chart document.\"\n },\n {\n \"name\": \"queryContext\",\n \"type\": \"PraxisChartQueryContext | null\",\n \"description\": \"Canonical @praxisui/core query context observed by remote datasource requests; flat filters execute in praxis.stats and governed filterExpression is preserved but rejected until stats expression support is proven.\"\n },\n {\n \"name\": \"remoteDataResolver\",\n \"type\": \"PraxisChartRemoteDataResolver | null\",\n \"description\": \"Host-governed remote row resolver for integrations outside the default praxis.stats client.\"\n },\n {\n \"name\": \"availableResources\",\n \"type\": \"ChartEditorResourceOption[]\",\n \"description\": \"Transient authoring catalog: id is the stable /schemas/catalog discovery identity, while path is the governed root-relative operational value persisted to chartDocument.source.resource.\"\n },\n {\n \"name\": \"availableFields\",\n \"type\": \"ChartEditorFieldOption[]\",\n \"description\": \"Transient capability-backed field catalog. operations, aggregations and distributionModes declare exact group-by, timeseries, distribution/terms and distribution/histogram eligibility.\"\n },\n {\n \"name\": \"availableTargets\",\n \"type\": \"ChartEditorTargetOption[]\",\n \"description\": \"Transient visual-authoring targets derived from existing top-level composition links to public, non-deprecated widget ports or explicitly writable declared page state; id is the unique authoring identity and events[] declares the exact structured Chart events authorized by compatible links. Raw pointClick evidence never authorizes events.pointClick, which is emitted through pointAction. Local transform.output semantic-kind inspection does not replace a Core-validated transform-output projection (P2), and the visual catalog does not yet publish the target input-schema/port projection required for end-to-end mapping validation.\"\n }\n ],\n \"editableTargets\": [\n {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"description\": \"Canonical `kind` field in PraxisXUiChartContract.\"\n },\n {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"description\": \"Metric-backed series definition in `metrics[]`, keyed by field.\"\n },\n {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"description\": \"Dimension role, metric axis and chart orientation semantics.\"\n },\n {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"description\": \"Source, dimensions, metrics and resource/field bindings.\"\n },\n {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"description\": \"Runtime @praxisui/core queryContext contract for filters, filterExpression, sort, limit, page and governance metadata.\"\n },\n {\n \"kind\": \"pointClick\",\n \"resolver\": \"x-ui-chart-events-point-click\",\n \"description\": \"Raw pointClick evidence plus a separate pointAction output for configured pointClick actions.\"\n },\n {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"description\": \"Cross-filter event mapping emitted as structured query-context filters.\"\n },\n {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"description\": \"Drilldown event mapping and governed target.\"\n },\n {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"description\": \"Single-point selection event enablement and mapping semantics; toggle and multi-select are intentionally not advertised.\"\n },\n {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"description\": \"Legend visibility through boolean or toggleable feature object.\"\n },\n {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"description\": \"Tooltip visibility through boolean or toggleable feature object.\"\n }\n ],\n \"operations\": [\n {\n \"operationId\": \"chart.document.set\",\n \"title\": \"Set chart document\",\n \"scope\": \"global\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-document-root\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"kind\",\n \"source\"\n ],\n \"properties\": {\n \"version\": {\n \"const\": \"0.1.0\"\n },\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"chartId\": {\n \"type\": \"string\"\n },\n \"title\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"subtitle\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"source\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"options\": {\n \"type\": \"object\"\n }\n }\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"events\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-document-shape\",\n \"chart-version-supported\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"chart.type.set\",\n \"title\": \"Set chart type\",\n \"scope\": \"global\",\n \"targetKind\": \"chartType\",\n \"target\": {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-object\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-type-supported\",\n \"chart-type-series-axis-compatible\",\n \"pie-single-metric\",\n \"combo-minimum-series\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.kind\",\n \"chartDocument.orientation\",\n \"chartDocument.metrics[]\",\n \"chartDocument.dimensions[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.add\",\n \"title\": \"Add chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-series-add\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"duplicate-series-field\",\n \"aggregation-not-supported\",\n \"chart-type-series-incompatible\"\n ],\n \"description\": \"Adds a metric-backed series by semantic field, validating it against availableFields and chart kind compatibility before patching metrics[].\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"series-field-exists\",\n \"series-field-aggregable\",\n \"series-id-unique\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.remove\",\n \"title\": \"Remove chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"replacementField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"remove-by-key\",\n \"path\": \"chartDocument.metrics[]\",\n \"key\": \"field\"\n }\n ],\n \"destructive\": true,\n \"requiresConfirmation\": true,\n \"validators\": [\n \"series-exists\",\n \"destructive-series-removal-confirmed\",\n \"chart-keeps-required-metric\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-series-exists\",\n \"confirmation-collected\"\n ]\n },\n {\n \"operationId\": \"axis.configure\",\n \"title\": \"Configure chart axis\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"axis\",\n \"target\": {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-axis-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"chartDocument.orientation\"\n ],\n \"identityKeys\": [\n \"chartDocument.dimensions[].field\",\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"secondary-axis-non-combo\",\n \"missing-required-dimension\",\n \"axis-role-incompatible\"\n ],\n \"description\": \"Configures dimensions and metric axes using semantic fields, preserving combo-only secondary axis constraints.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"axis-field-exists\",\n \"secondary-axis-combo-only\",\n \"cartesian-dimension-required\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[].axis\",\n \"chartDocument.orientation\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"data.resource.bind\",\n \"title\": \"Bind chart data resource\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\",\n \"pattern\": \"^/(?!/)\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"role\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-data-resource-bind\",\n \"handlerContract\": {\n \"reads\": [\n \"availableResources[]\",\n \"availableFields[]\",\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"writes\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"availableResources[].path\",\n \"availableFields[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\",\n \"pattern\": \"^/(?!/)\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\"\n },\n \"metrics\": {\n \"type\": \"array\"\n }\n }\n },\n \"failureModes\": [\n \"resource-not-in-api-metadata\",\n \"field-not-in-schema\",\n \"stats-operation-not-supported\",\n \"remote-binding-incomplete\"\n ],\n \"description\": \"Binds a derived or praxis.stats source using governed catalogs. For praxis.stats, availableResources[].id is discovery-only: validation requires the matching availableResources[].path and compilation persists that path as chartDocument.source.resource.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"remote-resource-in-api-metadata\",\n \"bound-fields-exist\",\n \"stats-operation-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"affects-remote-binding\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"queryContext.set\",\n \"title\": \"Set chart query context\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"queryContext\",\n \"target\": {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"filters\": {\n \"type\": \"object\"\n },\n \"filterExpression\": {\n \"type\": \"object\"\n },\n \"sort\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"limit\": {\n \"type\": \"number\"\n },\n \"page\": {\n \"type\": \"object\"\n },\n \"meta\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"queryContext\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"query-context-structured\",\n \"query-context-filter-expression-stats-unsupported\",\n \"query-context-fields-exist\",\n \"query-context-safe-values\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"queryContext\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"pointClick.configure\",\n \"title\": \"Configure chart point click\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"pointClick\",\n \"target\": {\n \"kind\": \"pointClick\",\n \"resolver\": \"x-ui-chart-events-point-click\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-point-click-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.pointClick\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.pointClick\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"mapping-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures pointClick through the pointAction output while keeping pointClick as raw point evidence.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"point-click-action-structured\",\n \"event-target-governed\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.pointClick\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"crossFilter.configure\",\n \"title\": \"Configure chart cross-filter\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"crossFilter\",\n \"target\": {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-cross-filter-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.crossFilter\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"mapping-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures crossFilter as a structured event action emitted through the crossFilter output with safe query-context filters to a governed target. For praxis.stats rows, key is governed bucket identity and label is presentation evidence; mappings may use key when the target schema accepts that identity.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"cross-filter-output-structured\",\n \"event-target-governed\",\n \"event-mapping-fields-exist\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"drilldown.configure\",\n \"title\": \"Configure chart drilldown\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"drilldown\",\n \"target\": {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-drilldown-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.drillDown\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.drillDown\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"drilldown-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures drillDown through the dedicated drillDown output with governed route/widget targets and structured field mappings.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"drilldown-target-governed\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.drillDown\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"selection.configure\",\n \"title\": \"Configure chart selection\",\n \"scope\": \"selection\",\n \"targetKind\": \"selection\",\n \"target\": {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-selection-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.selectionChange\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.selectionChange\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"action\"\n ],\n \"properties\": {\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"mapping-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures selectionChange as single-point selection evidence whose event key is governed by the operation.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"selection-output-structured\",\n \"event-target-governed\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.selectionChange\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"legend.configure\",\n \"title\": \"Configure chart legend\",\n \"scope\": \"skin\",\n \"targetKind\": \"legend\",\n \"target\": {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.legend\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.legend\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"tooltip.configure\",\n \"title\": \"Configure chart tooltip\",\n \"scope\": \"skin\",\n \"targetKind\": \"tooltip\",\n \"target\": {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.tooltip\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.tooltip\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n }\n ],\n \"validators\": [\n {\n \"validatorId\": \"chart-document-shape\",\n \"level\": \"error\",\n \"code\": \"CHART_DOCUMENT_SHAPE\",\n \"description\": \"Document must conform to PraxisXUiChartContract.\"\n },\n {\n \"validatorId\": \"chart-version-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_VERSION_SUPPORTED\"\n },\n {\n \"validatorId\": \"chart-type-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SUPPORTED\",\n \"description\": \"Chart kind must be supported by @praxisui/charts.\"\n },\n {\n \"validatorId\": \"chart-type-series-axis-compatible\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SERIES_AXIS_COMPATIBLE\",\n \"description\": \"Chart kind, dimensions, metrics and axes must be compatible.\"\n },\n {\n \"validatorId\": \"pie-single-metric\",\n \"level\": \"error\",\n \"code\": \"PIE_SINGLE_METRIC\",\n \"description\": \"Pie and donut charts support a single metric.\"\n },\n {\n \"validatorId\": \"combo-minimum-series\",\n \"level\": \"error\",\n \"code\": \"COMBO_MINIMUM_SERIES\",\n \"description\": \"Combo charts require at least two metrics.\"\n },\n {\n \"validatorId\": \"series-field-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_EXISTS\",\n \"description\": \"Series field must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"series-field-aggregable\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_AGGREGABLE\",\n \"description\": \"Metric fields must support the requested aggregation.\"\n },\n {\n \"validatorId\": \"series-id-unique\",\n \"level\": \"error\",\n \"code\": \"SERIES_ID_UNIQUE\",\n \"description\": \"Metric/series identity must be stable and unique by field.\"\n },\n {\n \"validatorId\": \"series-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_EXISTS\",\n \"description\": \"Series removal target must exist.\"\n },\n {\n \"validatorId\": \"destructive-series-removal-confirmed\",\n \"level\": \"error\",\n \"code\": \"DESTRUCTIVE_SERIES_REMOVAL_CONFIRMED\",\n \"description\": \"Removing a series requires explicit confirmation.\"\n },\n {\n \"validatorId\": \"chart-keeps-required-metric\",\n \"level\": \"error\",\n \"code\": \"CHART_KEEPS_REQUIRED_METRIC\",\n \"description\": \"A chart cannot be left without required metrics.\"\n },\n {\n \"validatorId\": \"axis-field-exists\",\n \"level\": \"error\",\n \"code\": \"AXIS_FIELD_EXISTS\",\n \"description\": \"Axis/dimension fields must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"secondary-axis-combo-only\",\n \"level\": \"error\",\n \"code\": \"SECONDARY_AXIS_COMBO_ONLY\",\n \"description\": \"Secondary axis is supported only for combo charts.\"\n },\n {\n \"validatorId\": \"cartesian-dimension-required\",\n \"level\": \"error\",\n \"code\": \"CARTESIAN_DIMENSION_REQUIRED\",\n \"description\": \"Cartesian charts require at least one dimension.\"\n },\n {\n \"validatorId\": \"remote-resource-in-api-metadata\",\n \"level\": \"error\",\n \"code\": \"REMOTE_RESOURCE_IN_API_METADATA\",\n \"description\": \"Remote praxis.stats resource must equal a governed root-relative availableResources[].path beginning with exactly one slash; a discovery id is not an executable resource path.\"\n },\n {\n \"validatorId\": \"bound-fields-exist\",\n \"level\": \"error\",\n \"code\": \"BOUND_FIELDS_EXIST\",\n \"description\": \"Bound dimensions and metrics must exist in the capability-backed field context and satisfy its operation, aggregation and distribution-mode eligibility.\"\n },\n {\n \"validatorId\": \"stats-operation-supported\",\n \"level\": \"error\",\n \"code\": \"STATS_OPERATION_SUPPORTED\",\n \"description\": \"Remote datasource operation must be supported by the stats backend.\"\n },\n {\n \"validatorId\": \"query-context-structured\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_STRUCTURED\",\n \"description\": \"queryContext must use the canonical @praxisui/core structure for filters, filterExpression, sort, limit, page and meta.\"\n },\n {\n \"validatorId\": \"query-context-filter-expression-stats-unsupported\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_FILTER_EXPRESSION_STATS_UNSUPPORTED\",\n \"description\": \"praxis.stats currently executes only flat queryContext.filters; governed filterExpression must be preserved for diagnostics and rejected until backend expression support is declared.\"\n },\n {\n \"validatorId\": \"query-context-fields-exist\",\n \"level\": \"warning\",\n \"code\": \"QUERY_CONTEXT_FIELDS_EXIST\",\n \"description\": \"queryContext filter fields should exist in the schema/data context.\"\n },\n {\n \"validatorId\": \"query-context-safe-values\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_SAFE_VALUES\",\n \"description\": \"queryContext values must be serializable safe data.\"\n },\n {\n \"validatorId\": \"point-click-action-structured\",\n \"level\": \"error\",\n \"code\": \"POINT_CLICK_ACTION_STRUCTURED\",\n \"description\": \"Configured pointClick actions must be emitted through pointAction while pointClick remains raw point evidence.\"\n },\n {\n \"validatorId\": \"cross-filter-output-structured\",\n \"level\": \"error\",\n \"code\": \"CROSS_FILTER_OUTPUT_STRUCTURED\",\n \"description\": \"Cross-filter output must be structured as query-context filters.\"\n },\n {\n \"validatorId\": \"event-target-governed\",\n \"level\": \"error\",\n \"code\": \"EVENT_TARGET_GOVERNED\",\n \"description\": \"Event targets must resolve to exactly one availableTargets[].id and declare the authored event plus action; missing, duplicate or cross-event identities fail closed.\"\n },\n {\n \"validatorId\": \"event-mapping-fields-exist\",\n \"level\": \"error\",\n \"code\": \"EVENT_MAPPING_FIELDS_EXIST\",\n \"description\": \"Event mapping source fields must exist in chart data context; praxis.stats reserves key for bucket identity and label for presentation.\"\n },\n {\n \"validatorId\": \"event-action-supported\",\n \"level\": \"error\",\n \"code\": \"EVENT_ACTION_SUPPORTED\",\n \"description\": \"Event action must be one of the supported structured action kinds.\"\n },\n {\n \"validatorId\": \"drilldown-target-governed\",\n \"level\": \"error\",\n \"code\": \"DRILLDOWN_TARGET_GOVERNED\",\n \"description\": \"Drilldown target must be a governed route or widget target.\"\n },\n {\n \"validatorId\": \"selection-output-structured\",\n \"level\": \"error\",\n \"code\": \"SELECTION_OUTPUT_STRUCTURED\",\n \"description\": \"Selection output must resolve selected point filters deterministically.\"\n },\n {\n \"validatorId\": \"feature-toggle-valid\",\n \"level\": \"error\",\n \"code\": \"FEATURE_TOGGLE_VALID\",\n \"description\": \"Legend and tooltip feature values must be boolean or toggleable feature objects.\"\n },\n {\n \"validatorId\": \"editor-runtime-round-trip\",\n \"level\": \"error\",\n \"code\": \"EDITOR_RUNTIME_ROUND_TRIP\",\n \"description\": \"PraxisChartConfigEditor must save/reopen the same canonical document that runtime consumes.\"\n }\n ],\n \"roundTripRequirements\": [\n \"The canonical saved shape is PraxisXUiChartContract, not raw ECharts options.\",\n \"PraxisChartConfigEditor must preserve chart kind, source, dimensions, metrics, events, legend and tooltip across apply/save/reset/reopen.\",\n \"Remote bindings persist availableResources[].path; availableResources[].id remains discovery identity, and transient resource/field/target catalogs and diagnostics are never persisted in widget inputs.\",\n \"Cross-filter, drilldown and selection authoring must persist structured event actions, not prompt examples or command strings.\",\n \"[P1] Backend handler, resolver and validators now execute directly; end-to-end Page Builder parity remains open until assistant requests project the transient availableTargets[].events catalog through validationContext and expose its fail-closed diagnostics.\",\n \"[P2] Transform-output semantics and target input-schema/port fields must be materialized and validated by Core; local transform.output inspection and backend-enriched inputFields are not substitutes for those canonical projections.\",\n \"Enrichment of capability-backed availableFields with /schemas/filtered property metadata remains a later schema-flow gate.\"\n ],\n \"examples\": [\n {\n \"id\": \"set-bar-chart\",\n \"request\": \"Use a bar chart for employees by department.\",\n \"operationId\": \"chart.type.set\",\n \"params\": {\n \"kind\": \"bar\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"add-salary-series\",\n \"request\": \"Add salary as a summed metric.\",\n \"operationId\": \"series.add\",\n \"params\": {\n \"field\": \"salary\",\n \"aggregation\": \"sum\",\n \"label\": \"Salary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"remove-old-series\",\n \"request\": \"Remove the old cost series.\",\n \"operationId\": \"series.remove\",\n \"target\": \"cost\",\n \"params\": {\n \"field\": \"cost\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-secondary-axis\",\n \"request\": \"Put margin on a secondary axis for the combo chart.\",\n \"operationId\": \"axis.configure\",\n \"params\": {\n \"metricField\": \"margin\",\n \"metricAxis\": \"secondary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"bind-stats-resource\",\n \"request\": \"Bind this chart to payroll stats grouped by department.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"/api/stats/payroll\",\n \"operation\": \"group-by\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"set-query-context\",\n \"request\": \"Limit the chart to active employees and sort by total descending.\",\n \"operationId\": \"queryContext.set\",\n \"params\": {\n \"filters\": {\n \"status\": \"ACTIVE\"\n },\n \"sort\": [\n \"total,desc\"\n ],\n \"limit\": 10\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-cross-filter\",\n \"request\": \"Use selected department to filter the employee table.\",\n \"operationId\": \"crossFilter.configure\",\n \"params\": {\n \"action\": \"filter-widget\",\n \"target\": \"employeesTable\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-stats-key-cross-filter\",\n \"request\": \"Use the governed department bucket identity to filter the employee table.\",\n \"operationId\": \"crossFilter.configure\",\n \"params\": {\n \"action\": \"filter-widget\",\n \"target\": \"employeesTable\",\n \"mapping\": {\n \"key\": \"departmentIdsIn\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-drilldown\",\n \"request\": \"Open the department detail when a point is clicked.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"action\": \"navigate\",\n \"target\": \"/departments/detail\",\n \"mapping\": {\n \"department\": \"departmentId\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-selection\",\n \"request\": \"Emit selected department as a structured selection event.\",\n \"operationId\": \"selection.configure\",\n \"params\": {\n \"action\": \"emit\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-legend\",\n \"request\": \"Show the legend.\",\n \"operationId\": \"legend.configure\",\n \"params\": {\n \"enabled\": true\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-tooltip\",\n \"request\": \"Disable tooltips.\",\n \"operationId\": \"tooltip.configure\",\n \"params\": {\n \"enabled\": false\n },\n \"isPositive\": true\n },\n {\n \"id\": \"round-trip-editor-runtime\",\n \"request\": \"Save this chart in the editor and reopen it without changing the runtime chart document.\",\n \"operationId\": \"chart.document.set\",\n \"params\": {\n \"kind\": \"bar\",\n \"source\": {\n \"kind\": \"derived\"\n },\n \"dimensions\": [\n {\n \"field\": \"department\"\n }\n ],\n \"metrics\": [\n {\n \"field\": \"total\",\n \"aggregation\": \"count\"\n }\n ]\n },\n \"isPositive\": true\n },\n {\n \"id\": \"reject-ambiguous-series-target\",\n \"request\": \"Remove total when more than one chart series resolves to total.\",\n \"operationId\": \"series.remove\",\n \"target\": \"total\",\n \"params\": {\n \"field\": \"total\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-prompt-routing\",\n \"request\": \"Use the prompt example text to decide which backend endpoint to call.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"from prompt example\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-unsafe-target\",\n \"request\": \"Navigate to javascript:alert(1) on drilldown.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"event\": \"drillDown\",\n \"action\": \"navigate\",\n \"target\": \"javascript:alert(1)\"\n },\n \"isPositive\": false\n }\n ]\n}",
1993
2283
  "sourcePointer": "projects/praxis-charts/src/lib/ai/praxis-charts-authoring-manifest.ts",
1994
- "contentHash": "2cb145f1e9e59690a7b67580016445f388564511c257a04ef4bcd96c1762671a",
2284
+ "contentHash": "28a2c73ac3c736d1bdf589cea5c363c049d9e87e6f58a542376ed60112e0bf22",
1995
2285
  "sourceKind": "component_definition",
1996
2286
  "sourceId": "praxis-chart",
1997
2287
  "corpusVersion": "1.0.0"