empathy-framework 4.7.1__py3-none-any.whl → 4.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {empathy_framework-4.7.1.dist-info → empathy_framework-4.8.0.dist-info}/METADATA +65 -2
  2. {empathy_framework-4.7.1.dist-info → empathy_framework-4.8.0.dist-info}/RECORD +73 -52
  3. {empathy_framework-4.7.1.dist-info → empathy_framework-4.8.0.dist-info}/WHEEL +1 -1
  4. {empathy_framework-4.7.1.dist-info → empathy_framework-4.8.0.dist-info}/entry_points.txt +2 -1
  5. {empathy_framework-4.7.1.dist-info → empathy_framework-4.8.0.dist-info}/top_level.txt +0 -1
  6. empathy_os/__init__.py +2 -0
  7. empathy_os/cache/hash_only.py +6 -3
  8. empathy_os/cache/hybrid.py +6 -3
  9. empathy_os/cli/__init__.py +128 -238
  10. empathy_os/cli/__main__.py +5 -33
  11. empathy_os/cli/commands/__init__.py +1 -8
  12. empathy_os/cli/commands/help.py +331 -0
  13. empathy_os/cli/commands/info.py +140 -0
  14. empathy_os/cli/commands/inspect.py +437 -0
  15. empathy_os/cli/commands/metrics.py +92 -0
  16. empathy_os/cli/commands/orchestrate.py +184 -0
  17. empathy_os/cli/commands/patterns.py +207 -0
  18. empathy_os/cli/commands/provider.py +93 -81
  19. empathy_os/cli/commands/setup.py +96 -0
  20. empathy_os/cli/commands/status.py +235 -0
  21. empathy_os/cli/commands/sync.py +166 -0
  22. empathy_os/cli/commands/tier.py +121 -0
  23. empathy_os/cli/commands/workflow.py +574 -0
  24. empathy_os/cli/parsers/__init__.py +62 -0
  25. empathy_os/cli/parsers/help.py +41 -0
  26. empathy_os/cli/parsers/info.py +26 -0
  27. empathy_os/cli/parsers/inspect.py +66 -0
  28. empathy_os/cli/parsers/metrics.py +42 -0
  29. empathy_os/cli/parsers/orchestrate.py +61 -0
  30. empathy_os/cli/parsers/patterns.py +54 -0
  31. empathy_os/cli/parsers/provider.py +40 -0
  32. empathy_os/cli/parsers/setup.py +42 -0
  33. empathy_os/cli/parsers/status.py +47 -0
  34. empathy_os/cli/parsers/sync.py +31 -0
  35. empathy_os/cli/parsers/tier.py +33 -0
  36. empathy_os/cli/parsers/workflow.py +77 -0
  37. empathy_os/cli/utils/__init__.py +1 -0
  38. empathy_os/cli/utils/data.py +242 -0
  39. empathy_os/cli/utils/helpers.py +68 -0
  40. empathy_os/{cli.py → cli_legacy.py} +27 -27
  41. empathy_os/cli_minimal.py +662 -0
  42. empathy_os/cli_router.py +384 -0
  43. empathy_os/cli_unified.py +38 -2
  44. empathy_os/memory/__init__.py +19 -5
  45. empathy_os/memory/short_term.py +14 -404
  46. empathy_os/memory/types.py +437 -0
  47. empathy_os/memory/unified.py +61 -48
  48. empathy_os/models/fallback.py +1 -1
  49. empathy_os/models/provider_config.py +59 -344
  50. empathy_os/models/registry.py +31 -180
  51. empathy_os/monitoring/alerts.py +14 -20
  52. empathy_os/monitoring/alerts_cli.py +24 -7
  53. empathy_os/project_index/__init__.py +2 -0
  54. empathy_os/project_index/index.py +210 -5
  55. empathy_os/project_index/scanner.py +45 -14
  56. empathy_os/project_index/scanner_parallel.py +291 -0
  57. empathy_os/socratic/ab_testing.py +1 -1
  58. empathy_os/workflows/__init__.py +31 -2
  59. empathy_os/workflows/base.py +349 -325
  60. empathy_os/workflows/bug_predict.py +8 -0
  61. empathy_os/workflows/builder.py +273 -0
  62. empathy_os/workflows/caching.py +253 -0
  63. empathy_os/workflows/code_review_pipeline.py +1 -0
  64. empathy_os/workflows/history.py +510 -0
  65. empathy_os/workflows/output.py +410 -0
  66. empathy_os/workflows/perf_audit.py +125 -19
  67. empathy_os/workflows/progress.py +324 -22
  68. empathy_os/workflows/routing.py +168 -0
  69. empathy_os/workflows/secure_release.py +1 -0
  70. empathy_os/workflows/security_audit.py +190 -0
  71. empathy_os/workflows/security_audit_phase3.py +328 -0
  72. empathy_os/workflows/telemetry_mixin.py +269 -0
  73. empathy_os/dashboard/__init__.py +0 -15
  74. empathy_os/dashboard/server.py +0 -941
  75. patterns/README.md +0 -119
  76. patterns/__init__.py +0 -95
  77. patterns/behavior.py +0 -298
  78. patterns/code_review_memory.json +0 -441
  79. patterns/core.py +0 -97
  80. patterns/debugging.json +0 -3763
  81. patterns/empathy.py +0 -268
  82. patterns/health_check_memory.json +0 -505
  83. patterns/input.py +0 -161
  84. patterns/memory_graph.json +0 -8
  85. patterns/refactoring_memory.json +0 -1113
  86. patterns/registry.py +0 -663
  87. patterns/security_memory.json +0 -8
  88. patterns/structural.py +0 -415
  89. patterns/validation.py +0 -194
  90. {empathy_framework-4.7.1.dist-info → empathy_framework-4.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,441 +0,0 @@
1
- {
2
- "version": "1.0",
3
- "updated_at": "2026-01-21T21:33:09.498043",
4
- "node_count": 27,
5
- "edge_count": 0,
6
- "nodes": [
7
- {
8
- "id": "code_review_20251223080004_775d99bcc60f",
9
- "type": "pattern",
10
- "name": "review:Review of 1 files",
11
- "description": "Code review passed with no issues identified.",
12
- "source_wizard": "code_review_crew",
13
- "source_file": "",
14
- "source_line": null,
15
- "severity": "",
16
- "confidence": 1.0,
17
- "metadata": {},
18
- "tags": [],
19
- "created_at": "2025-12-23T08:00:04.071026",
20
- "updated_at": "2025-12-23T08:00:04.071029",
21
- "status": "open"
22
- },
23
- {
24
- "id": "code_review_20251223123355_b83ec54f38d1",
25
- "type": "pattern",
26
- "name": "review:Review of 0 files",
27
- "description": "Code review passed with no issues identified.",
28
- "source_wizard": "code_review_crew",
29
- "source_file": "",
30
- "source_line": null,
31
- "severity": "",
32
- "confidence": 1.0,
33
- "metadata": {},
34
- "tags": [],
35
- "created_at": "2025-12-23T12:33:55.701270",
36
- "updated_at": "2025-12-23T12:33:55.701509",
37
- "status": "open"
38
- },
39
- {
40
- "id": "code_review_20251223123457_b83ec54f38d1",
41
- "type": "pattern",
42
- "name": "review:Review of 0 files",
43
- "description": "Code review passed with no issues identified.",
44
- "source_wizard": "code_review_crew",
45
- "source_file": "",
46
- "source_line": null,
47
- "severity": "",
48
- "confidence": 1.0,
49
- "metadata": {},
50
- "tags": [],
51
- "created_at": "2025-12-23T12:34:57.179231",
52
- "updated_at": "2025-12-23T12:34:57.179232",
53
- "status": "open"
54
- },
55
- {
56
- "id": "code_review_20251223123725_b83ec54f38d1",
57
- "type": "pattern",
58
- "name": "review:Review of 0 files",
59
- "description": "Code review passed with no issues identified.",
60
- "source_wizard": "code_review_crew",
61
- "source_file": "",
62
- "source_line": null,
63
- "severity": "",
64
- "confidence": 1.0,
65
- "metadata": {},
66
- "tags": [],
67
- "created_at": "2025-12-23T12:37:25.438909",
68
- "updated_at": "2025-12-23T12:37:25.438911",
69
- "status": "open"
70
- },
71
- {
72
- "id": "code_review_20251223181131_b83ec54f38d1",
73
- "type": "pattern",
74
- "name": "review:Review of 0 files",
75
- "description": "Code review passed with no issues identified.",
76
- "source_wizard": "code_review_crew",
77
- "source_file": "",
78
- "source_line": null,
79
- "severity": "",
80
- "confidence": 1.0,
81
- "metadata": {},
82
- "tags": [],
83
- "created_at": "2025-12-23T18:11:31.823242",
84
- "updated_at": "2025-12-23T18:11:31.823244",
85
- "status": "open"
86
- },
87
- {
88
- "id": "code_review_20251223181248_b83ec54f38d1",
89
- "type": "pattern",
90
- "name": "review:Review of 0 files",
91
- "description": "Code review passed with no issues identified.",
92
- "source_wizard": "code_review_crew",
93
- "source_file": "",
94
- "source_line": null,
95
- "severity": "",
96
- "confidence": 1.0,
97
- "metadata": {},
98
- "tags": [],
99
- "created_at": "2025-12-23T18:12:48.761103",
100
- "updated_at": "2025-12-23T18:12:48.761104",
101
- "status": "open"
102
- },
103
- {
104
- "id": "code_review_20251225125631_b83ec54f38d1",
105
- "type": "pattern",
106
- "name": "review:Review of 0 files",
107
- "description": "Code review passed with no issues identified.",
108
- "source_wizard": "code_review_crew",
109
- "source_file": "",
110
- "source_line": null,
111
- "severity": "",
112
- "confidence": 1.0,
113
- "metadata": {},
114
- "tags": [],
115
- "created_at": "2025-12-25T12:56:31.509518",
116
- "updated_at": "2025-12-25T12:56:31.509519",
117
- "status": "open"
118
- },
119
- {
120
- "id": "code_review_20251225133512_b83ec54f38d1",
121
- "type": "pattern",
122
- "name": "review:Review of 0 files",
123
- "description": "Code review passed with no issues identified.",
124
- "source_wizard": "code_review_crew",
125
- "source_file": "",
126
- "source_line": null,
127
- "severity": "",
128
- "confidence": 1.0,
129
- "metadata": {},
130
- "tags": [],
131
- "created_at": "2025-12-25T13:35:12.459565",
132
- "updated_at": "2025-12-25T13:35:12.459566",
133
- "status": "open"
134
- },
135
- {
136
- "id": "code_review_20251225223538_b83ec54f38d1",
137
- "type": "pattern",
138
- "name": "review:Review of 0 files",
139
- "description": "Code review passed with no issues identified.",
140
- "source_wizard": "code_review_crew",
141
- "source_file": "",
142
- "source_line": null,
143
- "severity": "",
144
- "confidence": 1.0,
145
- "metadata": {},
146
- "tags": [],
147
- "created_at": "2025-12-25T22:35:38.342576",
148
- "updated_at": "2025-12-25T22:35:38.342578",
149
- "status": "open"
150
- },
151
- {
152
- "id": "code_review_20251225224302_b83ec54f38d1",
153
- "type": "pattern",
154
- "name": "review:Review of 0 files",
155
- "description": "Code review passed with no issues identified.",
156
- "source_wizard": "code_review_crew",
157
- "source_file": "",
158
- "source_line": null,
159
- "severity": "",
160
- "confidence": 1.0,
161
- "metadata": {},
162
- "tags": [],
163
- "created_at": "2025-12-25T22:43:02.040549",
164
- "updated_at": "2025-12-25T22:43:02.040550",
165
- "status": "open"
166
- },
167
- {
168
- "id": "code_review_20251225224917_b83ec54f38d1",
169
- "type": "pattern",
170
- "name": "review:Review of 0 files",
171
- "description": "Code review passed with no issues identified.",
172
- "source_wizard": "code_review_crew",
173
- "source_file": "",
174
- "source_line": null,
175
- "severity": "",
176
- "confidence": 1.0,
177
- "metadata": {},
178
- "tags": [],
179
- "created_at": "2025-12-25T22:49:17.964648",
180
- "updated_at": "2025-12-25T22:49:17.964650",
181
- "status": "open"
182
- },
183
- {
184
- "id": "code_review_20251225225441_b83ec54f38d1",
185
- "type": "pattern",
186
- "name": "review:Review of 0 files",
187
- "description": "Code review passed with no issues identified.",
188
- "source_wizard": "code_review_crew",
189
- "source_file": "",
190
- "source_line": null,
191
- "severity": "",
192
- "confidence": 1.0,
193
- "metadata": {},
194
- "tags": [],
195
- "created_at": "2025-12-25T22:54:41.746375",
196
- "updated_at": "2025-12-25T22:54:41.746376",
197
- "status": "open"
198
- },
199
- {
200
- "id": "code_review_20251225225802_b83ec54f38d1",
201
- "type": "pattern",
202
- "name": "review:Review of 0 files",
203
- "description": "Code review passed with no issues identified.",
204
- "source_wizard": "code_review_crew",
205
- "source_file": "",
206
- "source_line": null,
207
- "severity": "",
208
- "confidence": 1.0,
209
- "metadata": {},
210
- "tags": [],
211
- "created_at": "2025-12-25T22:58:02.875126",
212
- "updated_at": "2025-12-25T22:58:02.875128",
213
- "status": "open"
214
- },
215
- {
216
- "id": "code_review_20251225230106_b83ec54f38d1",
217
- "type": "pattern",
218
- "name": "review:Review of 0 files",
219
- "description": "Code review passed with no issues identified.",
220
- "source_wizard": "code_review_crew",
221
- "source_file": "",
222
- "source_line": null,
223
- "severity": "",
224
- "confidence": 1.0,
225
- "metadata": {},
226
- "tags": [],
227
- "created_at": "2025-12-25T23:01:06.006464",
228
- "updated_at": "2025-12-25T23:01:06.006466",
229
- "status": "open"
230
- },
231
- {
232
- "id": "code_review_20251226001258_b83ec54f38d1",
233
- "type": "pattern",
234
- "name": "review:Review of 0 files",
235
- "description": "Code review passed with no issues identified.",
236
- "source_wizard": "code_review_crew",
237
- "source_file": "",
238
- "source_line": null,
239
- "severity": "",
240
- "confidence": 1.0,
241
- "metadata": {},
242
- "tags": [],
243
- "created_at": "2025-12-26T00:12:58.628510",
244
- "updated_at": "2025-12-26T00:12:58.628514",
245
- "status": "open"
246
- },
247
- {
248
- "id": "code_review_20251226132743_b83ec54f38d1",
249
- "type": "pattern",
250
- "name": "review:Review of 0 files",
251
- "description": "Code review passed with no issues identified.",
252
- "source_wizard": "code_review_crew",
253
- "source_file": "",
254
- "source_line": null,
255
- "severity": "",
256
- "confidence": 1.0,
257
- "metadata": {},
258
- "tags": [],
259
- "created_at": "2025-12-26T13:27:43.005241",
260
- "updated_at": "2025-12-26T13:27:43.005243",
261
- "status": "open"
262
- },
263
- {
264
- "id": "code_review_20251227104634_b83ec54f38d1",
265
- "type": "pattern",
266
- "name": "review:Review of 0 files",
267
- "description": "Code review passed with no issues identified.",
268
- "source_wizard": "code_review_crew",
269
- "source_file": "",
270
- "source_line": null,
271
- "severity": "",
272
- "confidence": 1.0,
273
- "metadata": {},
274
- "tags": [],
275
- "created_at": "2025-12-27T10:46:34.415666",
276
- "updated_at": "2025-12-27T10:46:34.415668",
277
- "status": "open"
278
- },
279
- {
280
- "id": "code_review_20251227134956_b83ec54f38d1",
281
- "type": "pattern",
282
- "name": "review:Review of 0 files",
283
- "description": "Code review passed with no issues identified.",
284
- "source_wizard": "code_review_crew",
285
- "source_file": "",
286
- "source_line": null,
287
- "severity": "",
288
- "confidence": 1.0,
289
- "metadata": {},
290
- "tags": [],
291
- "created_at": "2025-12-27T13:49:56.473522",
292
- "updated_at": "2025-12-27T13:49:56.473523",
293
- "status": "open"
294
- },
295
- {
296
- "id": "code_review_20251229001439_b83ec54f38d1",
297
- "type": "pattern",
298
- "name": "review:Review of 0 files",
299
- "description": "Code review passed with no issues identified.",
300
- "source_wizard": "code_review_crew",
301
- "source_file": "",
302
- "source_line": null,
303
- "severity": "",
304
- "confidence": 1.0,
305
- "metadata": {},
306
- "tags": [],
307
- "created_at": "2025-12-29T00:14:39.654519",
308
- "updated_at": "2025-12-29T00:14:39.654522",
309
- "status": "open"
310
- },
311
- {
312
- "id": "code_review_20251229015608_b83ec54f38d1",
313
- "type": "pattern",
314
- "name": "review:Review of 0 files",
315
- "description": "Code review passed with no issues identified.",
316
- "source_wizard": "code_review_crew",
317
- "source_file": "",
318
- "source_line": null,
319
- "severity": "",
320
- "confidence": 1.0,
321
- "metadata": {},
322
- "tags": [],
323
- "created_at": "2025-12-29T01:56:08.710859",
324
- "updated_at": "2025-12-29T01:56:08.710860",
325
- "status": "open"
326
- },
327
- {
328
- "id": "code_review_20251231031131_b83ec54f38d1",
329
- "type": "pattern",
330
- "name": "review:Review of 0 files",
331
- "description": "Code review passed with no issues identified.",
332
- "source_wizard": "code_review_crew",
333
- "source_file": "",
334
- "source_line": null,
335
- "severity": "",
336
- "confidence": 1.0,
337
- "metadata": {},
338
- "tags": [],
339
- "created_at": "2025-12-31T03:11:31.928522",
340
- "updated_at": "2025-12-31T03:11:31.928526",
341
- "status": "open"
342
- },
343
- {
344
- "id": "code_review_20251231031259_b83ec54f38d1",
345
- "type": "pattern",
346
- "name": "review:Review of 0 files",
347
- "description": "Code review passed with no issues identified.",
348
- "source_wizard": "code_review_crew",
349
- "source_file": "",
350
- "source_line": null,
351
- "severity": "",
352
- "confidence": 1.0,
353
- "metadata": {},
354
- "tags": [],
355
- "created_at": "2025-12-31T03:12:59.248006",
356
- "updated_at": "2025-12-31T03:12:59.248008",
357
- "status": "open"
358
- },
359
- {
360
- "id": "code_review_20260106002821_b83ec54f38d1",
361
- "type": "pattern",
362
- "name": "review:Review of 0 files",
363
- "description": "Code review passed with no issues identified.",
364
- "source_wizard": "code_review_crew",
365
- "source_file": "",
366
- "source_line": null,
367
- "severity": "",
368
- "confidence": 1.0,
369
- "metadata": {},
370
- "tags": [],
371
- "created_at": "2026-01-06T00:28:21.590516",
372
- "updated_at": "2026-01-06T00:28:21.590518",
373
- "status": "open"
374
- },
375
- {
376
- "id": "code_review_20260110044523_b83ec54f38d1",
377
- "type": "pattern",
378
- "name": "review:Review of 0 files",
379
- "description": "Code review passed with no issues identified.",
380
- "source_wizard": "code_review_crew",
381
- "source_file": "",
382
- "source_line": null,
383
- "severity": "",
384
- "confidence": 1.0,
385
- "metadata": {},
386
- "tags": [],
387
- "created_at": "2026-01-10T04:45:23.803937",
388
- "updated_at": "2026-01-10T04:45:23.803938",
389
- "status": "open"
390
- },
391
- {
392
- "id": "code_review_20260121210401_b83ec54f38d1",
393
- "type": "pattern",
394
- "name": "review:Review of 0 files",
395
- "description": "Code review passed with no issues identified.",
396
- "source_wizard": "code_review_crew",
397
- "source_file": "",
398
- "source_line": null,
399
- "severity": "",
400
- "confidence": 1.0,
401
- "metadata": {},
402
- "tags": [],
403
- "created_at": "2026-01-21T21:04:01.549503",
404
- "updated_at": "2026-01-21T21:04:01.549504",
405
- "status": "open"
406
- },
407
- {
408
- "id": "code_review_20260121210716_b83ec54f38d1",
409
- "type": "pattern",
410
- "name": "review:Review of 0 files",
411
- "description": "Code review passed with no issues identified.",
412
- "source_wizard": "code_review_crew",
413
- "source_file": "",
414
- "source_line": null,
415
- "severity": "",
416
- "confidence": 1.0,
417
- "metadata": {},
418
- "tags": [],
419
- "created_at": "2026-01-21T21:07:16.256485",
420
- "updated_at": "2026-01-21T21:07:16.256486",
421
- "status": "open"
422
- },
423
- {
424
- "id": "code_review_20260121213309_b83ec54f38d1",
425
- "type": "pattern",
426
- "name": "review:Review of 0 files",
427
- "description": "Code review passed with no issues identified.",
428
- "source_wizard": "code_review_crew",
429
- "source_file": "",
430
- "source_line": null,
431
- "severity": "",
432
- "confidence": 1.0,
433
- "metadata": {},
434
- "tags": [],
435
- "created_at": "2026-01-21T21:33:09.496535",
436
- "updated_at": "2026-01-21T21:33:09.496535",
437
- "status": "open"
438
- }
439
- ],
440
- "edges": []
441
- }
patterns/core.py DELETED
@@ -1,97 +0,0 @@
1
- """Core pattern models for the Wizard Factory Pattern Library.
2
-
3
- This module provides the base classes and enums used by all wizard patterns.
4
- Patterns are extracted from 78 existing wizards and encoded as Pydantic models
5
- for type safety, validation, and code generation.
6
-
7
- Copyright 2025 Smart AI Memory, LLC
8
- Licensed under Fair Source 0.9
9
- """
10
-
11
- from enum import Enum
12
- from typing import Any
13
-
14
- from pydantic import BaseModel, Field
15
-
16
-
17
- class PatternCategory(str, Enum):
18
- """Categories of wizard patterns."""
19
-
20
- STRUCTURAL = "structural"
21
- INPUT = "input"
22
- VALIDATION = "validation"
23
- BEHAVIOR = "behavior"
24
- EMPATHY = "empathy"
25
-
26
-
27
- class BasePattern(BaseModel):
28
- """Base class for all wizard patterns.
29
-
30
- All wizard patterns inherit from this base class, providing:
31
- - Unique identification
32
- - Categorization
33
- - Reusability metrics
34
- - Examples of usage in existing wizards
35
- """
36
-
37
- id: str = Field(..., description="Unique pattern identifier (e.g., 'linear_flow')")
38
- name: str = Field(..., description="Human-readable pattern name")
39
- category: PatternCategory = Field(..., description="Pattern category")
40
- description: str = Field(..., description="Detailed pattern description")
41
- frequency: int = Field(..., description="Number of wizards using this pattern", ge=0)
42
- reusability_score: float = Field(
43
- ...,
44
- description="Reusability score (0.0-1.0)",
45
- ge=0.0,
46
- le=1.0,
47
- )
48
- examples: list[str] = Field(
49
- default_factory=list,
50
- description="List of wizard IDs using this pattern",
51
- )
52
-
53
- class Config:
54
- """Pydantic config."""
55
-
56
- use_enum_values = True
57
-
58
- def to_dict(self) -> dict[str, Any]:
59
- """Convert pattern to dictionary."""
60
- return self.model_dump()
61
-
62
- @classmethod
63
- def from_dict(cls, data: dict[str, Any]) -> "BasePattern":
64
- """Create pattern from dictionary."""
65
- return cls(**data)
66
-
67
-
68
- class CodeGeneratorMixin:
69
- """Mixin for patterns that can generate code."""
70
-
71
- def generate_code(self) -> str:
72
- """Generate code from this pattern.
73
-
74
- Returns:
75
- Generated code as a string
76
-
77
- Raises:
78
- NotImplementedError: If code generation is not implemented
79
-
80
- """
81
- raise NotImplementedError(f"{self.__class__.__name__} does not implement code generation")
82
-
83
-
84
- class ValidationMixin:
85
- """Mixin for patterns that can validate wizard configurations."""
86
-
87
- def validate_config(self, config: dict[str, Any]) -> tuple[bool, list[str]]:
88
- """Validate a wizard configuration against this pattern.
89
-
90
- Args:
91
- config: Wizard configuration to validate
92
-
93
- Returns:
94
- Tuple of (is_valid, list_of_errors)
95
-
96
- """
97
- raise NotImplementedError(f"{self.__class__.__name__} does not implement validation")