# Copyright 2026 John Wilger

[package]
name = "emc"
version = "0.1.6"
edition = "2024"
license = "AGPL-3.0-or-later"
description = "Event Model Compiler for deterministic event-model authoring, validation, and proof artifact generation."
repository = "https://git.johnwilger.com/Slipstream/emc"
readme = "README.md"
keywords = ["event-modeling", "lean4", "quint", "mcp"]
categories = ["command-line-utilities", "development-tools"]

[dependencies]
clap = { version = "4.6.1", features = ["std", "help", "usage", "error-context", "suggestions"] }
eventcore = "1.0.0"
eventcore-fs = "1.0.0"
eventcore-types = "1.0.0"
fs4 = "1.1.0"
hex = "0.4.3"
nutype = { version = "0.6.2", features = ["serde"] }
rmcp = { version = "1.7.0", default-features = false }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
sha2 = "0.11.0"
tokio = { version = "1.48.0", features = ["rt"] }

[dev-dependencies]
assert_cmd = "2.1.1"
predicates = "3.1.3"
tempfile = "3.23.0"

# Clippy lint policy: enable the high-signal stable groups at `forbid` while
# intentionally leaving experimental (`nursery`), subjective (`pedantic`), and
# contradictory (`restriction`) groups disabled as groups. Selected restriction
# lints below are exact opt-ins for quality, test diagnostics, and LLM-friendly
# maintainability.
#
# If a third-party macro emits an `allow`, the only permitted project-wide
# exception is changing that exact lint from `forbid` to `deny`; never downgrade
# a containing group such as `clippy::all` or `clippy::restriction`.
# `clippy::cargo` is capped at `deny` so the exact `multiple_crate_versions`
# exception below can permit eventcore-sqlite's adapter dependency graph.
[lints.rust]
# Deny rustc's own warnings (dead_code, unused, etc.) at the source level so a
# plain `cargo build`/`cargo test` fails exactly as CI does (CI also sets
# `RUSTFLAGS=-Dwarnings`). `deny` (not `forbid`) so local `#[expect(...)]`
# escape hatches still work, mirroring the clippy policy below.
warnings = "deny"

[lints.clippy]
# Generated from `clippy-driver -W help` by `scripts/sync-clippy-lints.mjs`.
# Keep every current `clippy::all` member enumerated exactly rather than
# setting `clippy::all = "forbid"`; group-level `forbid` conflicts with
# third-party macro `allow` attributes and emits `forbidden_lint_groups`,
# a future-incompat warning that `-D warnings` intentionally does not catch.
cargo = { level = "deny", priority = -1 }
# Stricter posture (https://billylevin.dev/posts/clippy-config/): turn the
# `pedantic` and `restriction` categories ON as groups, then decline individual
# lints below with an explicit `allow` + reason. `nursery` is intentionally left
# off (unstable lints). Group level is `deny` (not `forbid`) so local
# `#[expect(...)]` escape hatches keep working, matching the policy above.
pedantic = { level = "deny", priority = -1 }
restriction = { level = "deny", priority = -1 }
#
# --- declined pedantic/restriction lints (explicit opt-outs, with reasons) ---
# Contradictory or not our house style:
implicit_return = "allow"
question_mark_used = "allow"
single_call_fn = "allow"
shadow_reuse = "allow"
shadow_same = "allow"
shadow_unrelated = "allow"
pattern_type_mismatch = "allow"
renamed_function_params = "allow"
impl_trait_in_params = "allow"
inline_trait_bounds = "allow"
single_char_lifetime_names = "allow"
unused_trait_names = "allow"
unneeded_field_pattern = "allow"
let_underscore_untyped = "allow"
string_add = "allow"
else_if_without_else = "allow"
semicolon_outside_block = "allow"
# Module/file layout (we use inline modules deliberately):
mod_module_files = "allow"
inline_modules = "allow"
# Literal-suffix style (the two lints contradict; we adopt neither):
separated_literal_suffix = "allow"
# Documentation/ordering — too heavy for this crate:
missing_docs_in_private_items = "allow"
arbitrary_source_item_ordering = "allow"
multiple_inherent_impl = "allow"
# Complexity lints are ENFORCED (kept denied): an over-long or over-complex
# function is a signal to refactor, not to suppress. `cognitive_complexity` is
# a nursery lint, enabled explicitly here because the nursery group is off.
cognitive_complexity = "deny"
# Visibility style:
pub_with_shorthand = "allow"
pub_use = "allow"
field_scoped_visibility_modifiers = "allow"
missing_trait_methods = "allow"
# `emc` is a std binary, not no_std:
std_instead_of_core = "allow"
std_instead_of_alloc = "allow"
# Exhaustiveness:
wildcard_enum_match_arm = "allow"
# Permitted ONLY as provably-impossible-state markers / test assertions; all
# other panicking APIs (unwrap/expect/index/slice/unchecked-arith) stay DENIED
# because emc code must never panic:
unreachable = "allow"
panic_in_result_fn = "allow"
# Numeric literal-type inference (not a panic concern):
default_numeric_fallback = "allow"
# Legitimate CLI I/O:
print_stdout = "allow"
print_stderr = "allow"
create_dir = "allow"
# --- end declined lints ---
#
# Exact restriction-lint opt-ins remain listed here with the same policy.
absolute_paths = "deny"
absurd_extreme_comparisons = "forbid"
allow_attributes = "forbid"
almost_complete_range = "forbid"
almost_swapped = "forbid"
approx_constant = "forbid"
arc_with_non_send_sync = "forbid"
assertions_on_constants = "forbid"
assign_op_pattern = "forbid"
async_yields_async = "forbid"
await_holding_invalid_type = "forbid"
await_holding_lock = "forbid"
await_holding_refcell_ref = "forbid"
bad_bit_mask = "forbid"
bind_instead_of_map = "forbid"
blanket_clippy_restriction_lints = "allow"
blocks_in_conditions = "forbid"
bool_assert_comparison = "forbid"
bool_comparison = "forbid"
borrow_deref_ref = "forbid"
borrow_interior_mutable_const = "forbid"
borrowed_box = "forbid"
box_collection = "forbid"
box_default = "forbid"
boxed_local = "forbid"
builtin_type_shadow = "forbid"
byte_char_slices = "forbid"
bytes_count_to_len = "forbid"
bytes_nth = "forbid"
cast_abs_to_unsigned = "forbid"
cast_enum_constructor = "forbid"
cast_enum_truncation = "forbid"
cast_nan_to_int = "forbid"
cast_slice_different_sizes = "forbid"
cast_slice_from_raw_parts = "forbid"
char_indices_as_byte_indices = "forbid"
char_lit_as_u8 = "forbid"
chars_last_cmp = "forbid"
chars_next_cmp = "forbid"
clone_on_copy = "forbid"
cloned_ref_to_slice_refs = "forbid"
cmp_null = "forbid"
cmp_owned = "forbid"
collapsible_if = "forbid"
collapsible_match = "forbid"
collapsible_str_replace = "forbid"
comparison_to_empty = "forbid"
confusing_method_to_numeric_cast = "forbid"
const_is_empty = "forbid"
crate_in_macro_def = "forbid"
crosspointer_transmute = "forbid"
dbg_macro = "forbid"
declare_interior_mutable_const = "forbid"
default_constructed_unit_structs = "forbid"
default_instead_of_iter_empty = "forbid"
deprecated_cfg_attr = "forbid"
deprecated_clippy_cfg_attr = "forbid"
deprecated_semver = "forbid"
deref_addrof = "forbid"
derivable_impls = "forbid"
derive_ord_xor_partial_ord = "forbid"
derived_hash_with_manual_eq = "forbid"
disallowed_fields = "forbid"
disallowed_macros = "forbid"
disallowed_methods = "forbid"
disallowed_names = "forbid"
disallowed_types = "forbid"
# cucumber-rs macros emit `allow(clippy::diverging_sub_expression)`; keep
# this exact lint at `deny` so the macro remains clippy-checkable without
# weakening the rest of the enumerated clippy::all policy.
diverging_sub_expression = "deny"
doc_lazy_continuation = "forbid"
doc_nested_refdefs = "forbid"
doc_overindented_list_items = "forbid"
doc_suspicious_footnotes = "forbid"
double_comparisons = "forbid"
double_ended_iterator_last = "forbid"
double_must_use = "forbid"
double_parens = "forbid"
drain_collect = "forbid"
drop_non_drop = "forbid"
duplicate_mod = "forbid"
duplicate_underscore_argument = "forbid"
duplicated_attributes = "forbid"
duration_subsec = "forbid"
eager_transmute = "forbid"
empty_docs = "forbid"
empty_line_after_doc_comments = "forbid"
empty_line_after_outer_attr = "forbid"
empty_loop = "forbid"
enum_clike_unportable_variant = "forbid"
# nutype macros emit `allow(clippy::enum_variant_names)`; keep this exact
# lint at `deny` so the macro remains clippy-checkable without weakening
# the rest of the enumerated clippy::all policy.
enum_variant_names = "deny"
eq_op = "forbid"
erasing_op = "forbid"
err_expect = "forbid"
excessive_nesting = "forbid"
excessive_precision = "forbid"
expect_fun_call = "forbid"
# cucumber-rs macros emit `allow(clippy::expect_used)`; keep this exact
# lint at `deny` so the macro remains clippy-checkable without weakening
# the rest of the enumerated clippy::all policy.
expect_used = "deny"
explicit_auto_deref = "forbid"
explicit_counter_loop = "forbid"
explicit_write = "forbid"
extend_with_drain = "forbid"
extra_unused_lifetimes = "forbid"
extra_unused_type_parameters = "forbid"
field_reassign_with_default = "forbid"
filter_map_bool_then = "forbid"
filter_map_identity = "forbid"
filter_next = "forbid"
flat_map_identity = "forbid"
float_equality_without_abs = "forbid"
fn_to_numeric_cast = "forbid"
fn_to_numeric_cast_with_truncation = "forbid"
for_kv_map = "forbid"
forget_non_drop = "forbid"
format_in_format_args = "forbid"
four_forward_slashes = "forbid"
from_over_into = "forbid"
from_raw_with_void_ptr = "forbid"
from_str_radix_10 = "forbid"
get_first = "forbid"
get_last_with_len = "forbid"
identity_op = "forbid"
if_let_mutex = "forbid"
if_same_then_else = "forbid"
ifs_same_cond = "forbid"
impl_hash_borrow_with_str_and_bytes = "forbid"
implicit_saturating_add = "forbid"
implicit_saturating_sub = "forbid"
implied_bounds_in_impls = "forbid"
impossible_comparisons = "forbid"
incompatible_msrv = "forbid"
inconsistent_digit_grouping = "forbid"
ineffective_bit_mask = "forbid"
ineffective_open_options = "forbid"
infallible_destructuring_match = "forbid"
infallible_try_from = "forbid"
infinite_iter = "forbid"
inherent_to_string = "forbid"
inherent_to_string_shadow_display = "forbid"
init_numbered_fields = "forbid"
inline_fn_without_body = "forbid"
inspect_for_each = "forbid"
int_plus_one = "forbid"
into_iter_on_ref = "forbid"
invalid_regex = "forbid"
inverted_saturating_sub = "forbid"
invisible_characters = "forbid"
io_other_error = "forbid"
is_digit_ascii_radix = "forbid"
items_after_test_module = "forbid"
iter_cloned_collect = "forbid"
iter_count = "forbid"
iter_kv_map = "forbid"
iter_next_loop = "forbid"
iter_next_slice = "forbid"
iter_nth = "forbid"
iter_nth_zero = "forbid"
iter_out_of_bounds = "forbid"
iter_overeager_cloned = "forbid"
iter_skip_next = "forbid"
iter_skip_zero = "forbid"
iterator_step_by_zero = "forbid"
join_absolute_paths = "forbid"
just_underscores_and_digits = "forbid"
large_const_arrays = "forbid"
large_enum_variant = "forbid"
large_include_file = "forbid"
legacy_numeric_constants = "forbid"
len_without_is_empty = "forbid"
len_zero = "forbid"
let_and_return = "forbid"
let_underscore_future = "forbid"
let_underscore_lock = "forbid"
let_unit_value = "forbid"
let_with_type_underscore = "forbid"
lines_filter_map_ok = "forbid"
lint_groups_priority = "forbid"
macro_metavars_in_unsafe = "forbid"
main_recursion = "forbid"
manual_abs_diff = "forbid"
manual_async_fn = "forbid"
manual_bits = "forbid"
manual_c_str_literals = "forbid"
manual_checked_ops = "forbid"
manual_clamp = "forbid"
manual_clear = "forbid"
manual_contains = "forbid"
manual_dangling_ptr = "forbid"
manual_div_ceil = "forbid"
manual_filter = "forbid"
manual_filter_map = "forbid"
manual_find = "forbid"
manual_find_map = "forbid"
manual_flatten = "forbid"
manual_hash_one = "forbid"
manual_ignore_case_cmp = "forbid"
manual_inspect = "forbid"
manual_is_ascii_check = "forbid"
manual_is_finite = "forbid"
manual_is_infinite = "forbid"
manual_is_multiple_of = "forbid"
manual_main_separator_str = "forbid"
manual_map = "forbid"
manual_memcpy = "forbid"
manual_next_back = "forbid"
manual_non_exhaustive = "forbid"
manual_noop_waker = "forbid"
manual_ok_err = "forbid"
manual_ok_or = "forbid"
manual_option_as_slice = "forbid"
manual_option_zip = "forbid"
manual_pattern_char_comparison = "forbid"
manual_pop_if = "forbid"
manual_range_contains = "forbid"
manual_range_patterns = "forbid"
manual_rem_euclid = "forbid"
manual_repeat_n = "forbid"
manual_retain = "forbid"
manual_rotate = "forbid"
manual_saturating_arithmetic = "forbid"
manual_slice_fill = "forbid"
manual_slice_size_calculation = "forbid"
manual_split_once = "forbid"
manual_str_repeat = "forbid"
manual_strip = "forbid"
manual_swap = "forbid"
manual_take = "forbid"
manual_try_fold = "forbid"
manual_unwrap_or = "forbid"
manual_unwrap_or_default = "forbid"
manual_while_let_some = "forbid"
map_all_any_identity = "forbid"
map_clone = "forbid"
map_collect_result_unit = "forbid"
map_entry = "forbid"
map_flatten = "forbid"
map_identity = "forbid"
match_as_ref = "forbid"
match_like_matches_macro = "forbid"
match_overlapping_arm = "forbid"
match_ref_pats = "forbid"
match_result_ok = "forbid"
match_single_binding = "forbid"
match_str_case_mismatch = "forbid"
mem_replace_option_with_none = "forbid"
mem_replace_option_with_some = "forbid"
mem_replace_with_default = "forbid"
mem_replace_with_uninit = "forbid"
min_max = "forbid"
misnamed_getters = "forbid"
misrefactored_assign_op = "forbid"
missing_assert_message = "forbid"
missing_const_for_thread_local = "forbid"
missing_enforced_import_renames = "forbid"
missing_safety_doc = "forbid"
missing_spin_loop = "forbid"
missing_transmute_annotations = "forbid"
mistyped_literal_suffixes = "forbid"
mixed_attributes_style = "forbid"
mixed_case_hex_literals = "forbid"
module_inception = "forbid"
modulo_one = "forbid"
multi_assignments = "forbid"
multiple_bound_locations = "forbid"
multiple_crate_versions = "allow"
must_use_unit = "forbid"
mut_from_ref = "forbid"
mut_mutex_lock = "forbid"
mut_range_bound = "forbid"
mutable_key_type = "forbid"
needless_arbitrary_self_type = "forbid"
needless_as_bytes = "forbid"
needless_bool = "forbid"
needless_bool_assign = "forbid"
needless_borrow = "forbid"
needless_borrowed_reference = "forbid"
needless_borrows_for_generic_args = "forbid"
needless_character_iteration = "forbid"
needless_doctest_main = "forbid"
needless_else = "forbid"
needless_ifs = "forbid"
needless_late_init = "forbid"
needless_lifetimes = "forbid"
needless_match = "forbid"
needless_maybe_sized = "forbid"
needless_option_as_deref = "forbid"
needless_option_take = "forbid"
needless_parens_on_range_literals = "forbid"
needless_pub_self = "forbid"
needless_question_mark = "forbid"
needless_range_loop = "forbid"
# cucumber-rs macros emit `allow(clippy::needless_return)`; keep this exact
# lint at `deny` so the macro remains clippy-checkable without weakening
# the rest of the enumerated clippy::all policy.
needless_return = "deny"
needless_return_with_question_mark = "forbid"
needless_splitn = "forbid"
needless_update = "forbid"
neg_cmp_op_on_partial_ord = "forbid"
neg_multiply = "forbid"
never_loop = "forbid"
new_ret_no_self = "forbid"
new_without_default = "forbid"
no_effect = "forbid"
no_effect_replace = "forbid"
non_canonical_clone_impl = "forbid"
non_canonical_partial_ord_impl = "forbid"
non_minimal_cfg = "forbid"
non_octal_unix_permissions = "forbid"
nonsensical_open_options = "forbid"
not_unsafe_ptr_arg_deref = "forbid"
obfuscated_if_else = "forbid"
octal_escapes = "forbid"
ok_expect = "forbid"
only_used_in_recursion = "forbid"
op_ref = "forbid"
option_as_ref_deref = "forbid"
option_env_unwrap = "forbid"
option_filter_map = "forbid"
option_map_or_none = "forbid"
option_map_unit_fn = "forbid"
or_then_unwrap = "forbid"
out_of_bounds_indexing = "forbid"
owned_cow = "forbid"
panic = "forbid"
panicking_overflow_checks = "forbid"
panicking_unwrap = "forbid"
partialeq_ne_impl = "forbid"
partialeq_to_none = "forbid"
path_ends_with_ext = "forbid"
permissions_set_readonly_false = "forbid"
pointers_in_nomem_asm_block = "forbid"
possible_missing_comma = "forbid"
possible_missing_else = "forbid"
precedence = "forbid"
print_in_format_impl = "forbid"
print_literal = "forbid"
print_with_newline = "forbid"
println_empty_string = "forbid"
ptr_arg = "forbid"
ptr_eq = "forbid"
ptr_offset_with_cast = "forbid"
# nutype macros emit `allow(clippy::question_mark)`; keep this exact lint
# at `deny` so the macro remains clippy-checkable without weakening the
# rest of the enumerated clippy::all policy.
question_mark = "deny"
range_zip_with_len = "forbid"
rc_clone_in_vec_init = "forbid"
read_line_without_trim = "forbid"
readonly_write_lock = "forbid"
recursive_format_impl = "forbid"
redundant_allocation = "forbid"
redundant_as_str = "forbid"
redundant_async_block = "forbid"
redundant_at_rest_pattern = "forbid"
redundant_closure = "forbid"
redundant_closure_call = "forbid"
redundant_comparisons = "forbid"
redundant_field_names = "forbid"
redundant_guards = "forbid"
redundant_iter_cloned = "forbid"
redundant_locals = "forbid"
redundant_pattern = "forbid"
redundant_pattern_matching = "forbid"
redundant_slicing = "forbid"
redundant_static_lifetimes = "forbid"
regex_creation_in_loops = "forbid"
repeat_once = "forbid"
repeat_vec_with_capacity = "forbid"
replace_box = "forbid"
repr_packed_without_abi = "forbid"
reserve_after_initialization = "forbid"
result_filter_map = "forbid"
result_large_err = "forbid"
result_map_or_into_option = "forbid"
result_map_unit_fn = "forbid"
result_unit_err = "forbid"
reversed_empty_ranges = "forbid"
same_item_push = "forbid"
seek_from_current = "forbid"
seek_to_start_instead_of_rewind = "forbid"
self_assignment = "forbid"
self_named_constructors = "forbid"
serde_api_misuse = "forbid"
short_circuit_statement = "forbid"
should_implement_trait = "forbid"
single_char_add_str = "forbid"
single_component_path_imports = "forbid"
single_element_loop = "forbid"
single_match = "forbid"
single_range_in_vec_init = "forbid"
size_of_in_element_count = "forbid"
size_of_ref = "forbid"
skip_while_next = "forbid"
sliced_string_as_bytes = "forbid"
slow_vector_initialization = "forbid"
some_filter = "forbid"
string_extend_chars = "forbid"
string_from_utf8_as_bytes = "forbid"
string_lit_chars_any = "forbid"
strlen_on_c_strings = "forbid"
suspicious_arithmetic_impl = "forbid"
suspicious_assignment_formatting = "forbid"
suspicious_command_arg_space = "forbid"
suspicious_doc_comments = "forbid"
suspicious_else_formatting = "forbid"
suspicious_map = "forbid"
suspicious_op_assign_impl = "forbid"
suspicious_open_options = "forbid"
suspicious_splitn = "forbid"
suspicious_to_owned = "forbid"
suspicious_unary_op_formatting = "forbid"
swap_ptr_to_ref = "forbid"
swap_with_temporary = "forbid"
tabs_in_doc_comments = "forbid"
temporary_assignment = "forbid"
test_attr_in_doctest = "forbid"
tests_outside_test_module = "forbid"
to_digit_is_some = "forbid"
to_string_in_format_args = "forbid"
to_string_trait_impl = "forbid"
todo = "forbid"
too_many_arguments = "forbid"
toplevel_ref_arg = "forbid"
transmute_bytes_to_str = "forbid"
transmute_int_to_bool = "forbid"
transmute_int_to_non_zero = "forbid"
transmute_null_to_fn = "forbid"
transmute_ptr_to_ref = "forbid"
transmutes_expressible_as_ptr_casts = "forbid"
transmuting_null = "forbid"
trim_split_whitespace = "forbid"
type_complexity = "forbid"
type_id_on_box = "forbid"
unbuffered_bytes = "forbid"
unconditional_recursion = "forbid"
undocumented_unsafe_blocks = "forbid"
unimplemented = "forbid"
uninit_assumed_init = "forbid"
uninit_vec = "forbid"
unit_arg = "forbid"
unit_cmp = "forbid"
unit_hash = "forbid"
unit_return_expecting_ord = "forbid"
unnecessary_cast = "forbid"
unnecessary_clippy_cfg = "forbid"
unnecessary_fallible_conversions = "forbid"
unnecessary_filter_map = "forbid"
unnecessary_find_map = "forbid"
unnecessary_first_then_check = "forbid"
unnecessary_fold = "forbid"
unnecessary_get_then_check = "forbid"
unnecessary_lazy_evaluations = "forbid"
unnecessary_literal_unwrap = "forbid"
unnecessary_map_on_constructor = "forbid"
unnecessary_map_or = "forbid"
unnecessary_min_or_max = "forbid"
unnecessary_mut_passed = "forbid"
unnecessary_operation = "forbid"
unnecessary_option_map_or_else = "forbid"
unnecessary_owned_empty_strings = "forbid"
unnecessary_result_map_or_else = "forbid"
unnecessary_sort_by = "forbid"
unnecessary_to_owned = "forbid"
unnecessary_unwrap = "forbid"
unneeded_struct_pattern = "forbid"
unneeded_wildcard_pattern = "forbid"
unsafe_removed_from_name = "forbid"
unsound_collection_transmute = "forbid"
unused_enumerate_index = "forbid"
unused_format_specs = "forbid"
unused_io_amount = "forbid"
unused_unit = "forbid"
unusual_byte_groupings = "forbid"
unwrap_or_default = "forbid"
unwrap_used = "forbid"
upper_case_acronyms = "forbid"
useless_asref = "forbid"
useless_attribute = "deny"
useless_borrows_in_formatting = "forbid"
useless_concat = "forbid"
useless_conversion = "forbid"
useless_format = "forbid"
useless_nonzero_new_unchecked = "forbid"
useless_transmute = "forbid"
useless_vec = "forbid"
vec_box = "forbid"
vec_init_then_push = "forbid"
vec_resize_to_zero = "forbid"
verbose_file_reads = "forbid"
waker_clone_wake = "forbid"
while_immutable_condition = "forbid"
while_let_loop = "forbid"
while_let_on_iterator = "forbid"
wildcard_in_or_patterns = "forbid"
write_literal = "forbid"
write_with_newline = "forbid"
writeln_empty_string = "forbid"
wrong_self_convention = "forbid"
wrong_transmute = "forbid"
zero_divided_by_zero = "forbid"
zero_prefixed_literal = "forbid"
zero_ptr = "forbid"
zero_repeat_side_effects = "forbid"
zombie_processes = "forbid"
zst_offset = "forbid"
