git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commitd09bb6600a8b771a9ac2707229418838d9938b82
parent28917ef12d
authorLucas Galante <[email protected]>
date2026-08-25 11:44
docs: move the cce-ui rebuild note into the workspace guide

It landed in the crate's CLAUDE.md in 28917ef, but it is a workspace-wide
fact about the toolkit and its ~20 dependents, not a compositor one — and
WORKSPACE.md is what the root CLAUDE.md sends people to first.

Placed directly after the `ccebuild status` paragraph, because it is the
caveat to that paragraph's claim: status answers "is what's running the
code I built?" by comparing mtimes in target/release against
~/.local/bin, which cannot see a client that is stale against a
*dependency* rather than its own sources.

Reworded on the way: the CLAUDE.md version leaned on "the reason above"
for the one-cargo-shape advice, which points backwards there but forwards
here — the feature-unification note is further down this file. Made that
sentence self-contained instead.

Co-Authored-By: Claude Opus 5 <[email protected]>

 CLAUDE.md    | 26 --------------------------
 WORKSPACE.md | 26 ++++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index af25bb6..8ff76e3 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -91,32 +91,6 @@ script and the `.desktop` entries above both started out.
 `ccebuild restart` deliberately cannot reach the compositor: `cce-fx` is not a user
 unit (startcce launches it), and restarting it would tear down the session.
 
-**A change to `cce-ui` reaches a client only when that client is rebuilt.** The
-toolkit is a static Rust library, so committing and installing `cce-ui` itself
-changes nothing about the ~20 crates that link it — each has to be rebuilt and
-reinstalled before it carries the change. `ccebuild status` will not flag this:
-those binaries are not stale against *their own* sources, only against a
-dependency, which is exactly the case it cannot see.
-
-Then there is a second step: a **running** process keeps its old inode until it
-is relaunched (that is the `(deleted)` exe `status` and `restart` key on), and
-`cce-fx` itself keeps its own until the next login. So a toolkit fix lands in
-three stages — commit, rebuild dependents, relaunch — and it is the middle one
-that gets skipped.
-
-Learned from cce-ui@2416904, which raised each client's `RLIMIT_NOFILE`: the
-fix was committed and cce-ui installed, yet every client still ran at the old
-limit until its own crate was rebuilt. Sweep with one cargo invocation over the
-dependents (`cargo build --release -p ... -p ...`, one shape — alternating with
-a bare `--workspace` build re-resolves features and invalidates crates), then
-`ccebuild install --no-build <crate>` for each. Verify by looking *inside* the
-installed binary for something the change introduced, e.g.
-`strings ~/.local/bin/<crate> | grep -q '<new log string>'`, rather than
-trusting that the build ran. **Leave `cce-browser` out of such a sweep unless
-asked** — it builds Servo, which costs far more than the rest of the workspace
-combined; it keeps whatever toolkit version it was last built against until
-someone decides that trade is worth making.
-
 Building emits a harmless warning that per-package `[profile.*]` in this `Cargo.toml`
 is ignored because profiles are only honored at the workspace root.
 
diff --git a/WORKSPACE.md b/WORKSPACE.md
index b13d52d..28294d5 100644
--- a/WORKSPACE.md
+++ b/WORKSPACE.md
@@ -138,6 +138,32 @@ Because `install` unlinks before writing, a process still on the old inode repor
 exe as `(deleted)`, which is how both `status` and `restart` detect drift. It also
 catches apps launched straight out of `target/` rather than `~/.local/bin`.
 
+**But it cannot see a client that is stale against `cce-ui`.** The toolkit is a
+static Rust library, so committing and installing `cce-ui` itself changes nothing
+about the ~20 crates that link it — each has to be rebuilt and reinstalled before
+it carries the change. `status` compares each binary's mtime in `target/release`
+against the one in `~/.local/bin`, so a client nobody rebuilt has both old and
+equal and reads as up to date. It is stale against a *dependency*, the one kind of
+staleness that check has no notion of.
+
+Then a **running** process keeps its old inode until it is relaunched, and
+`cce-fx` keeps its own until the next login. So a toolkit fix lands in three
+stages — commit, rebuild dependents, relaunch — and it is the middle one that
+gets skipped. Learned from cce-ui@2416904, which raised each client's
+`RLIMIT_NOFILE`: the fix was committed and cce-ui installed, and every client
+still ran at the old limit until its own crate was rebuilt, thirteen of them.
+
+Sweep with one cargo invocation over the dependents (`cargo build --release -p …
+-p …` — one shape, since alternating with a bare `--workspace` build re-resolves
+features and invalidates crates, as below), then `ccebuild install
+--no-build <crate>` for each. Verify by looking *inside* the installed binary for
+something the change introduced — `strings ~/.local/bin/<crate> | grep -q
+'<new log string>'` — rather than trusting that the build ran. **Leave
+`cce-browser` out of such a sweep unless asked**: it builds Servo, which costs
+more than the rest of the workspace combined, so it keeps whatever toolkit
+version it was last built against until someone decides that trade is worth
+making.
+
 For plain cargo work:
 
 ```sh