[workspace]
resolver = "2"
members = [
    "crates/epiphany-determinism",
    "crates/epiphany-core",
    "crates/epiphany-bundle",
    "crates/epiphany-ops",
    "crates/epiphany-layout-ir",
    "crates/epiphany-engrave",
    "crates/epiphany-render-svg",
    "crates/epiphany-editor-core",
    "crates/epiphany-editor-gui",
    "crates/epiphany-testkit",
]

# Agent A shipped epiphany-determinism first; Agent B's epiphany-core and Agent
# D's epiphany-bundle build on it (in parallel — the bundle depends on A only,
# not on B or C). Agent C's epiphany-ops builds on A and B. Agent E's
# epiphany-layout-ir (Chapter 7 + the Chapter 9 solver interface) lands last
# among the implementation crates, on A and B (plus C's `OperationKindTag` for
# the edit-barrier types). Agent F's epiphany-testkit is cross-cutting: it
# drives the real shipped A/B/C/D/E — its layout-round-trip harness, formerly a
# faithful in-tree stub, now re-points at the real epiphany-layout-ir. See
# spec/QUICKSTART.md for the dependency order.

[workspace.package]
edition = "2021"
rust-version = "1.77"
authors = ["Epiphany contributors"]
repository = "https://github.com/epiphany-notation/epiphany"

[workspace.dependencies]
blake3 = "1"
epiphany-determinism = { path = "crates/epiphany-determinism" }
# Agent C's epiphany-ops builds the concurrent-reduction semantics (Chapter 6)
# on top of the score graph; the layout-ir and testkit crates will depend on it
# too, so its path is declared once here.
epiphany-core = { path = "crates/epiphany-core" }
# Agent D's epiphany-bundle is the on-disk container (Chapter 8). Agent F's
# testkit drives its crash-recovery and manifest-selection gates, so its path is
# declared here alongside the other intra-workspace crates.
epiphany-bundle = { path = "crates/epiphany-bundle" }
# Agent C's epiphany-ops is the concurrent-semantics layer (Chapter 6). Agent F's
# testkit drives its convergence, reduction-determinism, and equivocation gates,
# so its path is declared here alongside the other intra-workspace crates.
epiphany-ops = { path = "crates/epiphany-ops" }
# Agent E's epiphany-layout-ir is the layout IR + constraint-solver interface
# (Chapters 7 & 9). Agent F's testkit drives its layout round-trip gate
# (v0 acceptance criterion 6), so its path is declared here alongside the other
# intra-workspace crates.
epiphany-layout-ir = { path = "crates/epiphany-layout-ir" }
# Agent I's Phase-2 visible-slice crates: epiphany-engrave is the real
# constraint solver (Chapter 9 Minimal tier — in progress) consuming the
# ConstrainedLayoutIR; epiphany-render-svg is the SVG renderer behind the
# Chapter 7 RenderIR interface. The renderer is developed against the stub
# solver first (QUICKSTART, Agent I), so it depends on the engrave crate only
# for the demo binary's `--solver=real` path.
epiphany-engrave = { path = "crates/epiphany-engrave" }
epiphany-render-svg = { path = "crates/epiphany-render-svg" }
# A headless editor core over the score graph (selection, hit-test query, operation
# minting, apply/re-render, selection preservation) — the API a GUI calls.
epiphany-editor-core = { path = "crates/epiphany-editor-core" }
# Agent F's testkit. Declared here so Agent I's render crate can use its score
# fixtures (`ten_measure_single_staff`) as a dev-dependency for the demo binary
# and acceptance tests.
epiphany-testkit = { path = "crates/epiphany-testkit" }
# Event-arena storage backend (QUICKSTART decision 2): slotmap gives
# generation-checked stale-handle detection, matching the spec's
# identifier-stability requirement (Chapter 5).
slotmap = "1"
# Replica-identifier entropy source (QUICKSTART decision 1): CSPRNG seed for
# the >=64-bit random ReplicaId (Chapter 5 §"Identifier Generation"). This is
# the only sanctioned use of platform randomness (Appendix D §"Randomness").
getrandom = "0.2"
# Exact arbitrary-precision rationals for the promoted arm of RationalTime
# (Chapter 3 §"Recommended Implementation: Inline-or-Promoted").
num-rational = { version = "0.4", default-features = false, features = ["num-bigint"] }
num-bigint = { version = "0.4", default-features = false }
num-traits = { version = "0.2", default-features = false }
# Unicode NFC normalization for canonical text identity (Appendix D §"Text and
# Unicode": canonical text fields MUST be NFC). Used to normalize registry /
# catalog names so canonically-equivalent spellings compare equal.
unicode-normalization = "0.1"
# Zstandard, for the bundle's chunk *read* path (Chapter 8 §"Compression":
# conforming implementations MUST support reading zstd-compressed chunks; the
# write path deliberately stays uncompressed in v0). epiphany-bundle only ever
# calls the decoder in production code; the encoder is used by its tests to
# produce compressed fixtures. Default features (legacy formats, dictionary
# building) are off — none are needed to decode standard frames.
zstd = { version = "0.13", default-features = false }
# Criterion drives the Chapter 10 performance benches (Phase 2 worklist F1) in
# epiphany-testkit/benches (see that crate's DECISIONS.md, F0/F1). Pinned to
# the 0.5 line: its MSRV (1.70) fits the workspace's pinned 1.77, while
# criterion 0.6+ requires 1.80. Default features are off — the plotting stack
# (plotters) and rayon are dead weight for budget gates — keeping only
# `cargo_bench_support` so plain `cargo bench` remains the entry point.
criterion = { version = "0.5", default-features = false, features = ["cargo_bench_support"] }

# Determinism-sensitive: never enable fast-math-style codegen on canonical
# numerical paths (Appendix D, "Rounding and CPU Behavior"). The default
# release profile is already IEEE-conformant; we keep overflow checks on in
# every profile so identifier/coordinate arithmetic faults loudly instead of
# silently wrapping.
[profile.release]
overflow-checks = true
