wasm4pm-compat 26.6.5

Minimal paper-complete, feature-capped Rust process-evidence crate. Start with compatibility. Graduate to execution.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
//! Witness markers — type-level proof carriers naming the canon a value answers to.
//!
//! A *witness* is a zero-sized marker type that names **which standard, paper,
//! API grammar, Rust law, or internal bridge** a piece of evidence is being
//! admitted, projected, or graduated *against*. Witnesses do not carry data and
//! do not run anything: they exist purely to make the boundary law legible at
//! the type level, so an `Admission<T, Ocel20>` cannot be silently mistaken for
//! an `Admission<T, Xes1849>`.
//!
//! ## What witnesses ARE
//!
//! - Compile-time tags that thread a *named authority* through
//!   [`crate::evidence::Evidence`], [`crate::admission::Admission`], and
//!   [`crate::admission::Refusal`].
//! - Carriers of human-facing metadata ([`crate::witness::Witness::KEY`], [`crate::witness::Witness::TITLE`],
//!   [`crate::witness::Witness::YEAR`], [`crate::witness::Witness::FAMILY`]) so a diagnostic can explain *what*
//!   was being checked.
//!
//! ## What witnesses are **NOT**
//!
//! - **Not** validators. A witness names the authority; it never checks
//!   conformance to it. Checking is an engine concern that belongs in `wasm4pm`,
//!   never in this structure-only crate.
//! - **Not** runtime values. They are empty `enum`s — uninhabited and zero-cost.
//!
//! ## Graduation
//!
//! When a surface stops being a *compatibility* surface and needs to actually
//! verify a standard (e.g. truly check OCEL 2.0 object-event link integrity),
//! the witness travels with the value into `wasm4pm`, where a real engine
//! consumes it. Here, it is only a label.

/// The family a [`crate::witness::Witness`] belongs to — what *kind* of authority it names.
///
/// Families let diagnostics and indexes group witnesses by provenance without
/// hard-coding each marker. This is structure only: a family is a label, not a
/// capability.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WitnessFamily {
    /// A published interchange/data standard (e.g. OCEL 2.0, XES 1849-2016).
    Standard,
    /// An academic paper defining a model or model family (e.g. POWL, WF-net
    /// soundness, OC-Petri-nets, OCPQ).
    Paper,
    /// An API grammar a consumer must speak to interoperate (e.g. the `pm4py`
    /// call shape, or a `pmax` consumer grammar).
    ApiGrammar,
    /// A Rust-language law this crate enforces structurally (e.g. typestate
    /// admission, `forbid(unsafe_code)`).
    RustLaw,
    /// An internal bridge toward graduation (e.g. the `wasm4pm` engine bridge).
    InternalBridge,
}

/// A type-level proof carrier naming a single standard, paper, grammar, or law.
///
/// Implementors are empty enums (uninhabited, zero-cost). The associated
/// constants are the *only* observable content — they let a [`crate::diagnostic`]
/// surface explain which authority a value was admitted or refused against.
///
/// This trait represents an **authority label**. It does **not** represent the
/// authority's checking logic; this crate is structure-only. A value tagged with
/// a witness should graduate to `wasm4pm` when it needs to be *verified* against
/// that authority rather than merely *named* by it.
///
/// # Examples
///
/// ```
/// use wasm4pm_compat::witness::{Witness, WitnessFamily, Ocel20};
///
/// assert_eq!(Ocel20::KEY, "ocel-2.0");
/// assert_eq!(Ocel20::TITLE, "OCEL 2.0");
/// assert_eq!(Ocel20::YEAR, Some(2023));
/// assert_eq!(Ocel20::FAMILY, WitnessFamily::Standard);
/// ```
pub trait Witness {
    /// A stable, lowercase, machine-facing key (e.g. `"ocel-2.0"`).
    const KEY: &'static str;
    /// The family this witness belongs to.
    const FAMILY: WitnessFamily;
    /// A human-facing title (e.g. `"OCEL 2.0"`).
    const TITLE: &'static str;
    /// The publication year, if the authority has a dated edition.
    const YEAR: Option<u16>;
}

/// Declares an empty-enum witness marker with metadata and a short rustdoc line.
macro_rules! witness_marker {
    ($(#[$meta:meta])* $name:ident, $key:literal, $family:expr, $title:literal, $year:expr) => {
        $(#[$meta])*
        ///
        /// Structure-only authority label; see [`Witness`]. Graduate to
        /// `wasm4pm` when this authority must be *verified*, not merely *named*.
        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
        pub enum $name {}

        impl Witness for $name {
            const KEY: &'static str = $key;
            const FAMILY: WitnessFamily = $family;
            const TITLE: &'static str = $title;
            const YEAR: Option<u16> = $year;
        }
    };
}

witness_marker!(
    /// OCEL 2.0 — the object-centric event log standard.
    Ocel20, "ocel-2.0", WitnessFamily::Standard, "OCEL 2.0", Some(2023)
);
witness_marker!(
    /// IEEE 1849-2016 (XES) — the eXtensible Event Stream interchange standard.
    Xes1849, "xes-1849-2016", WitnessFamily::Standard, "XES (IEEE 1849-2016)", Some(2016)
);
witness_marker!(
    /// The `pm4py` API call grammar a consumer must speak to interoperate.
    Pm4pyApiGrammar, "pm4py-api-grammar", WitnessFamily::ApiGrammar, "pm4py API grammar", None
);
witness_marker!(
    /// A `pmax`-style consumer grammar a downstream caller must satisfy.
    PmaxConsumerGrammar, "pmax-consumer-grammar", WitnessFamily::ApiGrammar, "pmax consumer grammar", None
);
witness_marker!(
    /// POWL — Partially Ordered Workflow Language (Kourani & van Zelst).
    PowlPaper, "powl-paper", WitnessFamily::Paper, "POWL: Partially Ordered Workflow Language", Some(2023)
);
witness_marker!(
    /// Object-centric Petri nets (van der Aalst & Berti).
    ObjectCentricPetriNetPaper,
    "oc-petri-net-paper",
    WitnessFamily::Paper,
    "Discovering Object-Centric Petri Nets",
    Some(2020)
);
witness_marker!(
    /// WF-net soundness (van der Aalst) — the soundness criterion for workflow nets.
    WfNetSoundnessPaper,
    "wfnet-soundness-paper",
    WitnessFamily::Paper,
    "The Application of Petri Nets to Workflow Management (soundness)",
    Some(1998)
);
witness_marker!(
    /// OCPQ — Object-Centric Process Querying.
    OcpqPaper, "ocpq-paper", WitnessFamily::Paper, "Object-Centric Process Querying", Some(2024)
);
witness_marker!(
    /// The Declare constraint-template family (declarative process modeling).
    DeclareFamily, "declare-family", WitnessFamily::Paper, "Declare constraint family", Some(2007)
);
witness_marker!(
    /// The predictive (business) process monitoring problem family.
    PredictiveMonitoringFamily,
    "predictive-monitoring-family",
    WitnessFamily::Paper,
    "Predictive Process Monitoring family",
    Some(2018)
);
witness_marker!(
    /// Receipt-shaped, provenance-bearing evidence (the receipt family).
    ReceiptFamily, "receipt-family", WitnessFamily::Paper, "Receipt-shaped evidence family", None
);
witness_marker!(
    /// The Rust typestate law: states are tracked at the type level and illegal
    /// transitions are unrepresentable.
    RustTypestateLaw, "rust-typestate-law", WitnessFamily::RustLaw, "Rust typestate law", None
);
witness_marker!(
    /// The internal bridge toward the `wasm4pm` execution engine (graduation).
    Wasm4pmBridge, "wasm4pm-bridge", WitnessFamily::InternalBridge, "wasm4pm graduation bridge", None
);
witness_marker!(
    /// YAWL — Yet Another Workflow Language (van der Aalst & ter Hofstede, 2004).
    ///
    /// Covers typed routing constructs (AND/XOR/OR split/join), cancellation
    /// regions, and multiple-instance tasks. An `Admission<T, YawlPaper>` is
    /// distinguishable at the type level from `Admission<T, WfNetSoundnessPaper>`.
    YawlPaper,
    "yawl-paper",
    WitnessFamily::Paper,
    "YAWL: Yet Another Workflow Language",
    Some(2004)
);
witness_marker!(
    /// Hierarchical Decomposition of Separable WF-nets (Kourani et al., 2026).
    ///
    /// Covers the separable WF-net subclass and the WF-net → POWL 2.0
    /// transformation theorem. Needed to tag admissions against this authority.
    SeparableWfNetPaper,
    "separable-wfnet-paper",
    WitnessFamily::Paper,
    "Hierarchical Decomposition of Separable Workflow-Nets",
    Some(2026)
);
witness_marker!(
    /// Workflow Patterns: The Definitive Guide (Russell, van der Aalst & ter Hofstede, 2016).
    ///
    /// Covers the canonical set of named workflow patterns (WP-1 through WP-43+).
    /// Needed to tag pattern-coverage claims against this authority.
    WorkflowPatternsPaper,
    "workflow-patterns-paper",
    WitnessFamily::Paper,
    "Workflow Patterns: The Definitive Guide",
    Some(2016)
);
witness_marker!(
    /// Inductive Miner (Leemans, Fahland & van der Aalst, 2013).
    ///
    /// Names the Inductive Miner family of process discovery algorithms. An
    /// `Admission<T, InductiveMiner>` is distinguishable from
    /// `Admission<T, AlphaMiner>` — both are discovery algorithms but name
    /// orthogonal authorities. Graduate to `wasm4pm` when the miner must
    /// actually execute.
    InductiveMiner,
    "inductive-miner",
    WitnessFamily::Paper,
    "Inductive Miner (Leemans, Fahland & van der Aalst)",
    Some(2013)
);
witness_marker!(
    /// Declare constraint-template language (Pesic & van der Aalst, 2006).
    ///
    /// Names the individual *constraint* surface of Declare — the set of
    /// constraint templates (Response, Precedence, Chain-Succession, …) and
    /// their LTL semantics. Distinct from [`DeclareFamily`], which names the
    /// broader *model family*. Use `DeclareConstraints` when admitting a
    /// single constraint or a constraint-binding; use `DeclareFamily` when
    /// admitting a whole model.
    DeclareConstraints,
    "declare-constraints",
    WitnessFamily::Paper,
    "Declare constraint-template language",
    Some(2006)
);
witness_marker!(
    /// Alignment-based conformance checking (van Dongen, de Medeiros & Wen, 2008).
    ///
    /// Names the alignment approach to conformance — the authority behind
    /// optimal and heuristic alignments between an event log and a process
    /// model. Distinct from [`WfNetSoundnessPaper`] (structural soundness)
    /// and [`OcpqPaper`] (querying). Graduate to `wasm4pm` when an actual
    /// alignment computation is needed.
    AlignmentPaper,
    "alignment-paper",
    WitnessFamily::Paper,
    "Alignment-Based Conformance Checking",
    Some(2008)
);
witness_marker!(
    /// Object-centric Petri nets — the notation authority.
    ///
    /// Names the OC-Petri-net model class itself (object types, variable arcs,
    /// binding elements), independently of the discovery algorithm described in
    /// the van der Aalst & Berti (2020) paper. Use `OcPetriNets` when tagging
    /// a *model structure*; use [`ObjectCentricPetriNetPaper`] when tagging a
    /// *discovery output* traceable to that paper's algorithm.
    OcPetriNets,
    "oc-petri-nets",
    WitnessFamily::Paper,
    "Object-Centric Petri Nets (notation)",
    Some(2020)
);
witness_marker!(
    /// Log Skeleton (Verbeek & Leemans, 2018).
    ///
    /// Names the Log Skeleton declarative model: a set of six relations
    /// (always-before, always-after, never-together, …) mined directly from
    /// an event log. An `Admission<T, LogSkeleton>` is distinguishable from
    /// `Admission<T, DeclareConstraints>` — both are declarative but name
    /// orthogonal authorities and different relation vocabularies.
    LogSkeleton,
    "log-skeleton",
    WitnessFamily::Paper,
    "Log Skeleton (Verbeek & Leemans)",
    Some(2018)
);
witness_marker!(
    /// Alpha Algorithm (van der Aalst, Weijters & Maruster, 2004).
    ///
    /// Names the Alpha Miner process discovery algorithm — the causal-matrix
    /// based approach producing a WF-net from an event log. Distinct from
    /// [`InductiveMiner`] (different algorithm, different guarantees). An
    /// `Admission<T, AlphaMiner>` is distinguishable at the type level from
    /// any other discovery-algorithm witness.
    AlphaMiner,
    "alpha-miner",
    WitnessFamily::Paper,
    "Alpha Algorithm (van der Aalst, Weijters & Maruster)",
    Some(2004)
);
witness_marker!(
    /// XES lifecycle extension authority (IEEE 1849-2016, §lifecycle).
    ///
    /// Names the authority under which a `lifecycle:transition` value is
    /// admitted or refused against the standard alphabet. Distinct from
    /// [`Xes1849`], which names the overall XES standard: `XesLifecycleExt`
    /// names the sub-authority that governs the `lifecycle:transition` alphabet
    /// specifically. Use this when tagging an admission that checks *only*
    /// lifecycle transition values, not the full XES shape.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when lifecycle-ordering enforcement (start before complete) is required.
    XesLifecycleExt,
    "xes-lifecycle-extension",
    WitnessFamily::Standard,
    "XES lifecycle extension (IEEE 1849-2016)",
    Some(2016)
);
witness_marker!(
    /// XES concept extension authority (IEEE 1849-2016, §concept).
    ///
    /// Names the authority under which a `concept:name` value is admitted or
    /// refused. Distinct from [`Xes1849`] (the overall standard) and
    /// [`XesLifecycleExt`] (lifecycle values). Use when tagging an admission
    /// that checks the `concept:name` key specifically.
    XesConceptExt,
    "xes-concept-extension",
    WitnessFamily::Standard,
    "XES concept extension (IEEE 1849-2016)",
    Some(2016)
);
witness_marker!(
    /// OCEL 2.0 object-type namespace witness.
    ///
    /// Names the authority under which a specific *object type* (e.g. `"order"`,
    /// `"item"`) within an OCEL 2.0 log is admitted or refused. Distinct from
    /// [`Ocel20`], which names the overall standard: `OcelObjectType` names the
    /// sub-authority that governs individual object-type declarations.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when type-level object classification must be *enforced*, not merely named.
    OcelObjectType,
    "ocel-object-type",
    WitnessFamily::Standard,
    "OCEL 2.0 object-type namespace",
    Some(2023)
);
witness_marker!(
    /// OCEL 2.0 event-type (activity) namespace witness.
    ///
    /// Names the authority under which a specific *event type* (activity name,
    /// e.g. `"place_order"`, `"ship"`) within an OCEL 2.0 log is admitted or
    /// refused. Distinct from [`Ocel20`], which names the overall standard:
    /// `OcelEventType` names the sub-authority that governs individual activity
    /// declarations.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when activity-type enforcement is needed.
    OcelEventType,
    "ocel-event-type",
    WitnessFamily::Standard,
    "OCEL 2.0 event-type (activity) namespace",
    Some(2023)
);
witness_marker!(
    /// OCEL 2.0 attribute-type namespace witness.
    ///
    /// Names the authority under which a specific *attribute domain* (e.g.
    /// `"price"`, `"status"`, `"quantity"`) within an OCEL 2.0 object or event
    /// is admitted or refused. Distinct from [`Ocel20`] (the overall standard)
    /// and [`OcelObjectType`] (the object-type namespace): `OcelAttributeType`
    /// governs individual attribute-domain declarations.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when attribute-domain validation is needed.
    OcelAttributeType,
    "ocel-attribute-type",
    WitnessFamily::Standard,
    "OCEL 2.0 attribute-type namespace",
    Some(2023)
);
witness_marker!(
    /// WF-net → POWL 2.0 conversion authority (Kourani, Park & van der Aalst, 2026).
    ///
    /// Names the authority that governs lossless conversion of a *separable*
    /// WF-net into a POWL 2.0 model via the decomposition theorem (Definition 4.1
    /// and Theorem 4.3 of the 2026 paper). An `Admission<T, WfNet2Powl>` asserts
    /// that the admitted value was produced by — or is compatible with — the
    /// Kourani 2026 WF-net→POWL conversion path.
    ///
    /// Distinct from [`SeparableWfNetPaper`], which names the *separability
    /// subclass* authority, and from [`PowlPaper`], which names the POWL language
    /// authority. `WfNet2Powl` names the *conversion* authority: the boundary
    /// where a WF-net *becomes* a POWL model.
    ///
    /// Structure-only authority label; see [`Witness`]. The actual conversion
    /// (decomposition, language-equivalence check) graduates to `wasm4pm`.
    WfNet2Powl,
    "wfnet-to-powl",
    WitnessFamily::Paper,
    "WF-net to POWL 2.0 conversion (Kourani, Park & van der Aalst)",
    Some(2026)
);
witness_marker!(
    /// OC-PM divergence detection authority (paper #49).
    ///
    /// Names the authority under which a *divergence* pattern in an
    /// object-centric process model is admitted or refused. Divergence occurs
    /// when an object type participates in mutually exclusive execution paths
    /// that cannot be merged without information loss.
    ///
    /// Distinct from [`ConvergenceWitness`], which names the *convergence*
    /// authority (paths that reconverge). Use `DivergenceWitness` when tagging
    /// an admission, refusal, or evidence value that specifically concerns the
    /// divergence-detection boundary in OC-PM analysis.
    ///
    /// Paper: OC-PM divergence/convergence detection (#49).
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when divergence must be *detected* rather than merely *named*.
    DivergenceWitness,
    "oc-pm-divergence",
    WitnessFamily::Paper,
    "OC-PM divergence detection (paper #49)",
    None
);
witness_marker!(
    /// OC-PM convergence detection authority (paper #49).
    ///
    /// Names the authority under which a *convergence* pattern in an
    /// object-centric process model is admitted or refused. Convergence occurs
    /// when previously divergent execution paths (see [`DivergenceWitness`])
    /// reconverge at a synchronisation point, potentially requiring a join
    /// semantics decision.
    ///
    /// Distinct from [`DivergenceWitness`], which names the *divergence*
    /// authority. Use `ConvergenceWitness` when tagging an admission, refusal,
    /// or evidence value that specifically concerns the convergence-detection
    /// boundary in OC-PM analysis.
    ///
    /// Paper: OC-PM divergence/convergence detection (#49).
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when convergence must be *detected* rather than merely *named*.
    ConvergenceWitness,
    "oc-pm-convergence",
    WitnessFamily::Paper,
    "OC-PM convergence detection (paper #49)",
    None
);
witness_marker!(
    /// Process Cube framework (van der Aalst, 2013).
    ///
    /// Names the authority under which a process cube shape — `ProcessCube`,
    /// `CubeDimension`, `CubeSlice`, `CubeCell`, `CubeProjectionWitness`, or
    /// `CellComparison` — is admitted or refused. An
    /// `Admission<T, ProcessCubePaper>` is distinguishable from any OCEL or
    /// XES witness.
    ///
    /// Paper: Process Cubes — Slicing, Dicing, Rolling Up and Drilling Down
    /// Event Data for Process Mining (van der Aalst, APBC 2013, LNBIP 159).
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when cube computation (sub-log extraction, cross-cell comparison) is
    /// required.
    ProcessCubePaper,
    "process-cube-paper",
    WitnessFamily::Paper,
    "Process Cubes (van der Aalst, 2013)",
    Some(2013)
);
witness_marker!(
    /// Operational view witness — a process cube projection to the operational
    /// (execution-level) perspective.
    ///
    /// The operational view names the projection where the cube is sliced to
    /// show the actual execution traces for a sub-population. Distinct from
    /// [`AnalyticalView`] (which names the analytical/model perspective) and
    /// [`AggregationView`] (which names the aggregated/statistical perspective).
    ///
    /// Use this witness when tagging evidence that has been projected to the
    /// operational level of the process cube — i.e., the evidence is a
    /// sub-log of concrete traces, not a discovered model or a summary metric.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when the sub-log extraction itself must be executed.
    OperationalView,
    "process-cube-operational-view",
    WitnessFamily::Paper,
    "Process Cube operational view",
    Some(2013)
);
witness_marker!(
    /// Analytical view witness — a process cube projection to the analytical
    /// (model-level) perspective.
    ///
    /// The analytical view names the projection where the cube is sliced to
    /// show the process model (e.g., Petri net, process tree) discovered from
    /// a sub-population. Distinct from [`OperationalView`] (execution traces)
    /// and [`AggregationView`] (summary metrics).
    ///
    /// Use this witness when tagging evidence that has been projected to the
    /// analytical level — i.e., the evidence is a discovered process model for
    /// a cell, not the raw traces or a statistical summary.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when model discovery per cell must be executed.
    AnalyticalView,
    "process-cube-analytical-view",
    WitnessFamily::Paper,
    "Process Cube analytical view",
    Some(2013)
);
witness_marker!(
    /// Streaming evidence authority — evidence collected from a live event stream.
    ///
    /// Names the authority under which a piece of evidence is tagged as originating
    /// from a streaming (online) source. An `Admission<T, StreamingEvidenceWitness>`
    /// is distinguishable from `Admission<T, Ocel20>` or any batch-log witness —
    /// streaming evidence may be partial, windowed, or out-of-order relative to a
    /// complete offline log.
    ///
    /// Distinct from [`CausalConsistencyWitness`] (which names the causal-ordering
    /// authority) and from any individual format witness. Use
    /// `StreamingEvidenceWitness` when tagging evidence whose *collection mode* is
    /// the relevant authority — not its format or its causal properties.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when streaming ingestion, online monitoring, or windowed conformance
    /// checking must execute.
    StreamingEvidenceWitness,
    "streaming-evidence",
    WitnessFamily::Paper,
    "Streaming evidence (online collection context)",
    None
);
witness_marker!(
    /// Causal consistency authority — cross-object causal ordering has been
    /// established and verified for this evidence.
    ///
    /// Names the authority under which cross-object causal links are asserted to
    /// be mutually consistent. An `Admission<T, CausalConsistencyWitness>` claims
    /// that the admitted value's causal order has been verified — no cycles, no
    /// contradictions — per the process-mining Chicago TDD doctrine (if the event
    /// log cannot prove a lawful causal process happened, then it did not happen).
    ///
    /// Distinct from [`StreamingEvidenceWitness`] (collection mode) and from
    /// [`CrossLogCorrelationWitness`] (cross-log merging). Use
    /// `CausalConsistencyWitness` when tagging evidence whose *causal ordering* is
    /// the relevant authority claim.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when causal ordering derivation, cycle detection, or consistency checking
    /// must execute.
    CausalConsistencyWitness,
    "causal-consistency",
    WitnessFamily::Paper,
    "Causal consistency (cross-object causal ordering verified)",
    None
);
witness_marker!(
    /// Cross-log correlation authority — events from two or more logs have been
    /// correlated under a named schema.
    ///
    /// Names the authority under which a merged log shape was produced by
    /// correlating two source logs. An `Admission<T, CrossLogCorrelationWitness>`
    /// is distinguishable from any single-log witness — it asserts that the
    /// admitted value is a *merged* result whose provenance spans multiple logs.
    ///
    /// Distinct from [`StreamingEvidenceWitness`] (collection mode) and from
    /// [`CausalConsistencyWitness`] (causal ordering). Use
    /// `CrossLogCorrelationWitness` when tagging evidence whose *multi-log
    /// provenance* is the relevant authority claim.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when cross-log event matching, join execution, or merged log analysis
    /// must execute.
    CrossLogCorrelationWitness,
    "cross-log-correlation",
    WitnessFamily::Paper,
    "Cross-log correlation (multi-log provenance)",
    None
);
witness_marker!(
    /// Aggregation view witness — a process cube projection to the aggregated
    /// (statistical/summary) perspective.
    ///
    /// The aggregation view names the projection where the cube is rolled up to
    /// show summary statistics (e.g., average fitness, variant counts) for a
    /// sub-population. Distinct from [`OperationalView`] (execution traces) and
    /// [`AnalyticalView`] (discovered models).
    ///
    /// Use this witness when tagging evidence that has been projected to the
    /// aggregation level — i.e., the evidence is a summary metric or aggregate
    /// result over a cell, not the raw traces or a process model.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when aggregation computation must be executed.
    AggregationView,
    "process-cube-aggregation-view",
    WitnessFamily::Paper,
    "Process Cube aggregation view",
    Some(2013)
);
witness_marker!(
    /// Time-aware evidence authority — temporal ordering has been established.
    ///
    /// Names the authority under which evidence has been enriched with temporal
    /// ordering context. An `Admission<T, TimeAwareWitness>` is distinguishable
    /// from an `Admission<T, TemporalProfileWitness>` — both carry temporal
    /// context but at different levels: `TimeAwareWitness` marks that ordering
    /// relations between events have been derived, while [`TemporalProfileWitness`]
    /// marks that a full temporal profile (AVG/STD per activity-pair) has been
    /// computed.
    ///
    /// Use this witness when tagging evidence that has had its event-pair temporal
    /// ordering established but not yet profiled.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when temporal ordering derivation must be executed.
    TimeAwareWitness,
    "time-aware-witness",
    WitnessFamily::Paper,
    "Time-aware evidence (temporal ordering established)",
    Some(2020)
);
witness_marker!(
    /// Temporal profile authority — full temporal profile has been computed.
    ///
    /// Names the authority under which a temporal profile (the statistical
    /// distribution of observed time distances between pairs of activities) has
    /// been computed and attached to the evidence. Distinct from
    /// [`TimeAwareWitness`] (which marks that ordering relations have been
    /// derived but not profiled).
    ///
    /// An `Admission<T, TemporalProfileWitness>` is distinguishable from
    /// `Admission<T, TimeAwareWitness>` — a temporal profile is a richer object
    /// than a bare ordering relation.
    ///
    /// Grounded in: Stertz, Rinderle-Ma & Rinderle (2020) *Temporal Profile
    /// Conformance Checking*; see also van der Aalst (2013) Process Cubes for
    /// the time dimension as a cube axis.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when temporal profile derivation or zeta-value conformance checking must
    /// be executed.
    TemporalProfileWitness,
    "temporal-profile-witness",
    WitnessFamily::Paper,
    "Temporal profile (AVG/STD per activity-pair — Stertz et al. 2020)",
    Some(2020)
);
witness_marker!(
    /// Control-flow perspective authority (Mannhardt et al., 2016).
    ///
    /// Names the authority under which evidence is typed against the
    /// control-flow perspective in the balanced multi-perspective conformance
    /// framework. The control-flow perspective covers activity ordering and
    /// routing. Distinct from [`DataPerspectiveWitness`], [`ResourcePerspectiveWitness`],
    /// and [`TimePerspectiveWitness`].
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when control-flow alignment cost computation is required.
    ControlFlowPerspectiveWitness,
    "cf-perspective",
    WitnessFamily::Paper,
    "Control-Flow Perspective (Mannhardt et al. 2016)",
    Some(2016)
);
witness_marker!(
    /// Data perspective authority (Mannhardt et al., 2016).
    ///
    /// Names the authority under which evidence is typed against the data
    /// perspective in the balanced multi-perspective conformance framework.
    /// The data perspective covers event and object attribute values. Distinct
    /// from [`ControlFlowPerspectiveWitness`], [`ResourcePerspectiveWitness`],
    /// and [`TimePerspectiveWitness`].
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when data-condition guard evaluation is required.
    DataPerspectiveWitness,
    "data-perspective",
    WitnessFamily::Paper,
    "Data Perspective (Mannhardt et al. 2016)",
    Some(2016)
);
witness_marker!(
    /// Resource perspective authority (Mannhardt et al., 2016).
    ///
    /// Names the authority under which evidence is typed against the resource
    /// perspective in the balanced multi-perspective conformance framework.
    /// The resource perspective covers who performs each activity (`org:resource`
    /// or equivalent). Distinct from the other three perspective witnesses.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when resource-based conformance cost computation is required.
    ResourcePerspectiveWitness,
    "resource-perspective",
    WitnessFamily::Paper,
    "Resource Perspective (Mannhardt et al. 2016)",
    Some(2016)
);
witness_marker!(
    /// Time perspective authority (Mannhardt et al., 2016).
    ///
    /// Names the authority under which evidence is typed against the temporal
    /// perspective in the balanced multi-perspective conformance framework.
    /// The time perspective covers timestamps, durations, and sojourn times.
    /// Distinct from the other three perspective witnesses.
    ///
    /// Structure-only authority label; see [`Witness`]. Graduate to `wasm4pm`
    /// when temporal conformance checking is required.
    TimePerspectiveWitness,
    "time-perspective",
    WitnessFamily::Paper,
    "Time Perspective (Mannhardt et al. 2016)",
    Some(2016)
);
/*
 * IMPLEMENTATION: Witness Lattice (Join-Semilattice)
 * Enforces Axiom 2: Monotonic Witness progression.
 */
/// Represents a value in a Join-Semilattice.
pub trait Join {
    fn join(self, other: Self) -> Self;
}

/// A state that can reach a "Contradiction" (Top) value.
pub trait WithTop {
    fn is_top(&self) -> bool;
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub enum WitnessState<W: Witness> {
    Unknown(core::marker::PhantomData<W>),
    Satisfied(core::marker::PhantomData<W>),
    Violated(core::marker::PhantomData<W>),
    Contradiction(core::marker::PhantomData<W>),
}

impl<W: Witness> Clone for WitnessState<W> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<W: Witness> Copy for WitnessState<W> {}

impl<W: Witness> Join for WitnessState<W> {
    fn join(self, other: Self) -> Self {
        match (self, other) {
            (WitnessState::Unknown(_), s) => s,
            (s, WitnessState::Unknown(_)) => s,
            (WitnessState::Satisfied(_), WitnessState::Satisfied(_)) => self,
            (WitnessState::Violated(_), WitnessState::Violated(_)) => self,
            _ => WitnessState::Contradiction(core::marker::PhantomData),
        }
    }
}

impl<W: Witness> WithTop for WitnessState<W> {
    fn is_top(&self) -> bool {
        matches!(self, WitnessState::Contradiction(_))
    }
}