[workspace]
resolver = "2"
members = ["facett-core", "facett-source-link", "facett-flow", "facett-graph", "facett-arrow", "facett-pop", "facett-pipeline", "facett-table", "facett-grid", "facett-map", "facett-map3d", "facett-map3d-flight", "facett-geomap", "facett-osm", "facett-graph3d", "facett-plot", "facett-plotters", "facett-form", "facett-card", "facett-menu", "facett-syschart", "facett-icebergview", "facett-filedialog", "facett-console", "facett-video", "facett-docview", "facett-jobview", "facett-about", "facett-graphview", "facett-log", "facett-stat", "facett-tabbar", "facett-matrix", "facett-fleet-view", "facett-graphpan", "facett-warehousedeck", "facett-model3d", "facett-git", "facett-timeline", "facett-plandag", "facett-flowsim", "facett-helix", "facett-security", "facett-app", "facett-confirm", "facett-toast", "facett-kanban", "facett-calendar", "facett-gantt", "facett-cfd", "facett-search", "facett-markdown", "facett-manual", "facett-file", "facett-graphnav", "facett-lineage", "facett-dbexplorer", "facett-sdp", "facett-brokkr", "facett-brokkrview", "facett-cicd", "facett-holger", "facett-korp", "facett-claude", "facett-zoneui", "facett-releaseview", "facett-buildthing", "facett-deploykey", "facett-auth-ui", "facett-binview", "facett-coderoom-view", "facett", "facett-wasm-demo", "facett-simview", "facett-demo", "facett-graphgen", "facet-wrapped", "facet-wrapped-group", "facett-build-thing", "facett-ops", "xtask"]
# `facett-py` (the pyo3/maturin native wheel) is deliberately NOT a member: it links
# libpython and must never enter the normal `cargo build`. It is its own detached
# workspace, built only by maturin. Excluded here so cargo never walks into it.
exclude = ["facett-py"]
[workspace.package]
# 0.1.17 (2026-08-23). 21 of the 71 crates DRIFTED from their published copies at
# 0.1.16 — crates.io bytes are immutable, so those edits can only reach a consumer
# as a new version. Every crate here shares this one version, so the bump is
# repo-wide by construction; that is what a workspace version means.
#
# Forced by two Gate B refusals that a workspace build cannot produce:
# facett-map3d E0277 `V3: From<Vec3>` — the impl is in local facett-core, not in
# the published 0.1.16 bytes
# facett-osm E0599 `Way::from_lonlat_owned_with` — same, in facett-map
version = "0.2.0"
edition = "2024"
license = "MIT"
repository = "https://git.gunnar.rs/nordisk/facett"
[workspace.dependencies]
egui = "0.36"
serde_json = "1"
# ── THE ONE wgpu feature list (LAW 4: WebGPU/modern backends only) ────────────
# Every member's direct `wgpu` dep inherits this via `workspace = true`, so the
# backend set has ONE writer. It is wgpu 30's `default` minus `gles`: dropping
# `gles` drops `wgpu-hal`'s GL backend, `glow` and `khronos-egl` from every
# SHIPPED binary's graph (`webgl` stays off the same way — egui-wgpu is always
# declared `default-features = false` in this tree, and eframe hosts use
# `wgpu_no_default_features`, because `egui-wgpu/default` would re-enable both).
# `webgpu` costs nothing natively (its deps are wasm32-target-gated) and is what
# the wasm bundles run on; `metal`/`dx12` compile to nothing off their OSes.
# Guarded by `facett-core/tests/webgl_free_law.rs` (and korp's mirror), which
# red-fires if `glow`/`khronos-egl` re-enter any normal dependency graph.
wgpu = { version = "30", default-features = false, features = [
"std",
"parking_lot",
"vulkan",
"dx12",
"metal",
"wgsl",
"webgpu",
] }
# ── vello's wgpu, ALONE on 29 (lane H, 2026-10-02) ───────────────────────────
# egui-wgpu 0.36 is on wgpu 30; vello's newest release (0.10.0, 2026-08-14) still
# requires `wgpu ^29.0.3` (vello main moved to 30 in linebender/vello#1909 on
# 2026-09-15, unreleased). The two vello seams — facett-core `l1-vello` and
# facett-graphview `gpu`'s rasterizer — each open their OWN headless device, never
# egui's, so they keep running on this second wgpu under the name `wgpu29` and share
# no type with the wgpu-30 stack. Native backends as above (no `gles`, LAW 4).
# DELETE this entry (and the `wgpu29` aliases) the day vello ships on wgpu 30.
# `fragile-send-sync-non-atomic-wasm`: on egui 0.35 this wgpu got it from egui-wgpu's
# feature list (one wgpu, unified); alone it must say it, or graphview's process-wide
# `static` renderer cache is not `Send` on wasm32 (E0277 at `src/gpu.rs:320`). No-op
# on native.
# NO `webgpu` here, on purpose: wgpu 29 and wgpu 30 each vendor their own WebGPU JS
# bindings, and one wasm bundle carrying both is refused by wasm-bindgen ("duplicate
# string enums: GpuLoadOp", MEASURED 2026-10-02 in the container road for facett-demo
# and facet-wrapped). The vello lane never ran in a browser (it opens its device with
# `pollster::block_on`, which cannot wait on a JS promise), so on wasm32 this wgpu has
# no backend, `GpuRenderer::new` answers None and the CPU raster draws — as before.
# `webgpu` only ever applies off-native, so native backends are unchanged.
wgpu29 = { package = "wgpu", version = "29", default-features = false, features = [
"std",
"parking_lot",
"vulkan",
"dx12",
"metal",
"wgsl",
"fragile-send-sync-non-atomic-wasm",
] }
# `nornir-testmatrix` (the functional-status emitter) resolves from crates.io —
# 0.2.2 carries `functional_status` + the `testmatrix` feature. NO local
# `[patch.crates-io]` path: the nornir-server builds facett from its OWN clone as
# the `nornir` user and MUST NEVER reach the dev checkout's files.
# EXCEPTION while egui 0.36 is unpublished in nornir-robotui (lane H, 2026-10-02): the
# patch below takes it from the SIBLING edda (relative path — a clone patches to its own
# sibling, as `dwarves-runa` already does). Remove both lines when robotui is published.
# ── the ONE sanctioned patch: SELF-referential, so it cannot escape the clone ──
# This does NOT weaken the rule above. That rule forbids a patch whose path leaves
# this repo (`../edda/...`) and reaches a *different* checkout's files. The path
# below is relative to this workspace root, so every clone — including the
# nornir-server's own — patches to ITS OWN `facett-pipeline`, never to the dev tree.
#
# WHY IT IS NEEDED. `knut/crates/knut-pipelines/Cargo.toml:101` declares
# facett-pipeline = { version = "0.1", default-features = false, optional = true }
# with NO `path` key, so it resolves from crates.io. `facett-pipeline` dev-deps
# `knut-pipelines` BY PATH with `features = ["facett-adapter"]`, and that feature
# enables `dep:facett-pipeline` — the REGISTRY one. Two incompatible `PipelineModel`
# types therefore link into one build. It surfaces at
# `facett-pipeline/tests/knut_facett_matrix.rs:262` as
# `expected PipelineModel, found facett_pipeline::PipelineModel`, and it degrades the
# ordinary developer command line: `cargo test -p facett-pipeline` became ambiguous
# between the two copies and needed a full `path+file:///…#0.1.13` spec to run at all.
#
# Fixing it HERE rather than in knut is deliberate: it repairs facett's own builds
# while leaving knut's manifest registry-clean, and it matches the precedent modgunn
# and skade already use for `nornir-build-thing`. The deeper fix — breaking the
# dev-dependency cycle out into a separate integration crate — is still open.
# Same bug class as `nornir-config`, which linked two `BuildVariantSet` types.
[patch.crates-io]
# 2026-10-05 (merge to main): crates.io serves nornir-robotui
# (published 2026-10-04; the siblings carry the same code, at most test/doc edits
# since): their rows are gone.
facett-pipeline = { path = "facett-pipeline" }
# The two siblings facett-core / facett-pipeline used to reach by `../../` PATH.
# They are registry deps in the member manifests now, so a consumer that fetches a
# facett crate by git (knut → facett-pipeline, 2026-09-10) resolves them from
# crates.io; this root patch keeps LOCAL builds of facett on the sibling checkouts,
# and a root patch is never seen by a downstream consumer (patches apply at the
# consumer's own workspace root only).
znippy-zoomies = { path = "../znippy-zoomies" }
dwarves-runa = { path = "../edda/crates/dwarves-runa" }
# egui 0.36 (lane H, 2026-10-02): the robot-UI driver's newest crates.io release (0.3.4)
# is built on egui/egui_kittest 0.35, so its `Harness`/`Context` would be a SECOND egui
# beside this workspace's. The sibling edda checkout carries it on egui 0.36 (branch
# `egui-0.36`); this patch goes away when that nornir-robotui is published.
# …and its row type: the path robotui takes edda's LOCAL nornir-testmatrix (0.2.13) by
# path, so the registry copy (0.2.8) would be a second `TestResultRow` beside it
# (`facett-app/tests/robot_chrome.rs` mixes the two). One source for both until the
# robotui release lands. korp carries the same patch.
nornir-testmatrix = { path = "../edda/crates/nornir-testmatrix" }
# Rickard, 2026-09-05: test artifacts carry line tables only — full DWARF in every test
# binary and its deps was the bulk of a target dir (gunnar/target 271 GB, korp/target 852 GB
# on the day the disks filled); backtraces still show file:line.
[profile.test]
debug = "line-tables-only"