T-X8CF-promote-shared-crates-to-packages-rust
Status: planning/draft · Impact: medium · Complexity: medium
Begin Phase 2 convergence: promote genuinely shared Rust crates out of
apps/pumice/crates into packages/rust/, and introduce a workspace-level
Cargo.toml once two Rust projects share code — filling the packages/rust/
tree that D-0012-monorepo-tooling created empty.
After Phase 1, pumice’s crates build as an isolated cargo unit under
apps/pumice. packages/rust/ exists but is empty; there is no
workspace-level Cargo.toml.
| Location | Role today |
|---|---|
apps/pumice/crates/* | pumice, pumice-config, pumice-desktop (app-local) |
packages/rust/ | Empty; the shared-crate home from D-0012-monorepo-tooling |
| (none) | No workspace Cargo.toml |
Proposed
Section titled “Proposed”Promote the genuinely shareable crates to packages/rust/<crate> and introduce
a cargo workspace so apps/pumice and the shared crates resolve through it —
per S-0008-apps-consume-substrate-through-published-surfaces’s dependency direction.
Primary candidate — pumice-desktop → packages/rust/tauri-desktop-kit.
Its modules are generic Tauri desktop utilities with zero pumice-domain
coupling: audio (play_sound via rodio), autostart/positioner plugin
wrappers, clipboard (arboard, with a documented macOS WKWebView workaround),
and tray (menu/click-routing behind a clean host seam). Concrete second
consumer: the planned thin Tauri wrapper T-CKC1 (apps/desktop) would use
exactly these — which is what justifies promotion under
S-0001-co-locate-first-promote-when-shared rather than speculative
extraction.
Secondary candidate — pumice-config: mixed; the generic format/export
helpers may promote, but journal/notifications/ui/defaults are
domain-coupled. Promote case-by-case only with a real second consumer.
The frontend counterparts are separate tasks: the @ontogen admin-layer
packages (T-W3KP) and generic Vue composables (T-N7RT).
Approach
Section titled “Approach”- Identify shared crates.
pumice-desktopis the primary (generic Tauri kit, second consumer =T-CKC1); evaluatepumice-configpiecemeal. Thepumicecore (timer/ux_labels/schema) stays app-local — it is the domain. - Move to
packages/rust/. Relocatepumice-desktoptopackages/rust/tauri-desktop-kit; update path deps insrc-tauri. - Introduce a cargo workspace. Add a workspace
Cargo.tomllistingapps/pumice/src-tauri,apps/pumice/crates/*, andpackages/rust/*as members; align onresolver = "2". - Respect dependency direction. Ensure the app depends on shared crates, not the reverse (S-0008-apps-consume-substrate-through-published-surfaces).
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
packages/rust/<crate>/** | new | Promoted shared crate(s) |
Cargo.toml (workspace root) | new | Workspace members + resolver |
apps/pumice/**/Cargo.toml | edit | Repoint path deps to the promoted crates |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: At least one genuinely shared crate lives under
packages/rust/and pumice consumes it via the workspace. - AC-2: A workspace
Cargo.tomlresolvesapps/pumiceandpackages/rust/*as members; the full build passes. - AC-3: Dependency direction follows S-0008-apps-consume-substrate-through-published-surfaces (app → shared, never the reverse).
Out of scope
Section titled “Out of scope”- Adapter seam to the TS substrate —
T-Z5MK. - Speculative promotion — move only crates with a real second consumer.
Dependencies
Section titled “Dependencies”T-P4LZ(hard): the crates must build isolated under moon before promotion.
Depends on
Section titled “Depends on”T-P4LZ