Skip to content

docs: the Linux package ships iced, not GTK - #318

Merged
charliek merged 3 commits into
mainfrom
feature/plan-023-docs
Aug 9, 2026
Merged

docs: the Linux package ships iced, not GTK#318
charliek merged 3 commits into
mainfrom
feature/plan-023-docs

Conversation

@charliek

@charliek charliek commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Plan 023, workstream B (+ the third W-D bug). Part 3 of 3 — #316 merged,
#317 in flight.

The problem

main has shipped the iced UI as the Linux package's /usr/bin/roost
since the deb swap, but the docs still described gtk4-rs as the Linux UI.

The worst case: README.md is installed into the package itself
(packaging/nfpm.yaml/usr/share/doc/roost/README.md). So the package
shipped documentation contradicting its own binary — and its only
build-from-source instruction for Linux built roost-linux, not the UI a
user actually gets. CLAUDE.md, which every future session reads first, said
the same in five places.

The rule this follows

Where a doc describes current state: the Linux package ships the iced UI;
GTK remains in-repo as the development/parity implementation.
Deliberately
never "GTK is gone" — crates/roost-linux still builds, and gtk-build
plus all three e2e-gtk* lanes still gate every PR. Only the package
changed.

For the governing docs, the sharper framing: two shipped platform products
(Swift + AppKit on macOS, iced on Linux) vs three in-repo UI
implementations
.

What changed

README.md (both the claim and the build-from-source block), docs/index.md,
CLAUDE.md (×5), docs/reference/architecture.md (×4),
docs/development/vision.md (×2), config.md, claude-testing.md,
setup.md, crates/README.md, the Makefile header, and the CHANGELOG.md
header's stale /release:release command name.

architecture.md's Stack table needed restructuring, not a one-row edit.
Every Linux cell named GTK, so correcting only "Window + chrome" would have
left the table more self-contradicting than before. It is now three columns
(macOS / Linux-GTK-dev / Linux-iced-shipped), and the rows that are genuinely
shared point at their real roost-engine/roost-ipc paths.

That surfaced a stale path the old table had carried for a while:
crates/roost-linux/src/daemon/pty.rs no longer exists — the PTY moved to
crates/roost-engine/src/pty.rs, shared by both Linux UIs. CLAUDE.md cited
the same dead path. Neither was in the swept inventory; both are fixed.

vision.md gets exactly two edits — the current-state intro and the
## Architecture mermaid diagram. Its DL-* decision-log entries are
untouched: they are historical rationale, and rewriting them would falsify the
record.

Also retires "Iced POC" as a label for a UI that now ships, in the places that
describe current state (the dev profile is now "iced dev build"). Historical
plan documents keep their original wording.

Plus the third W-D bug

tools/screenshot/lib.sh's ut_socket_for gtk produced
/tmp/roost-<uid>/roost/roost.sock when XDG_RUNTIME_DIR was unset — a
doubled segment the real resolver never emits (paths.rs gives
/tmp/roost-<uid>/roost.sock). It also accepted an empty or relative
XDG_RUNTIME_DIR where the resolver requires absolute. The sibling iced arm
was already correct; gtk now mirrors it.

This matters more than it did: the packaged iced UI runs on the gtk
profile
, so this is the path tooling would use against a real user install.

Covered by a real test rather than a one-off transcript.
tools/roosttest_unit/test_socket_paths.py sources lib.sh in a subprocess
and asserts exact output for all four XDG_RUNTIME_DIR states (absolute,
unset, empty, relative) across both Linux targets — the semantics being that
an invalid value is ignored with a fallback, not an error. It stubs uname
so the non-Darwin branch is exercised deterministically on a Mac too, and it
lives where ci.yml's harness-unit job already runs it. Confirmed it fails
against the unfixed script
: three of the four gtk cases show the doubled
segment.

Verification

  • A full grep -rn "gtk4-rs\|roost-linux\|Iced POC\|poc/iced" sweep over every
    tracked markdown file, with a written disposition for every surviving
    hit
    (fixed / correct-as-historical / correct-as-dev-UI /
    out-of-scope-archive) — 111 hits. A grep for wording already fixed would
    not be a gate; this is.
  • Every newly cited file path checked to exist.
  • mkdocs build succeeds. --strict surfaces only pre-existing warnings,
    confirmed unchanged by this diff via git stash. Worth stating because
    docs.yml has no pull_request trigger — it only runs on push to main,
    so nothing else builds the site before merge, and a broken link would first
    appear as a failed Pages deploy afterwards.
  • python3 -m unittest discover -s tools/roosttest_unit — 50 tests pass
    (8 new).
  • shellcheck tools/screenshot/lib.sh clean.

Scope notes

Two things beyond the brief's swept inventory, both flagged deliberately:
architecture.md's poc/iced paragraph (false in both halves after the
merge, and it sat two lines below a line being corrected), and the six
additional current-state contradictions the plan's panel review surfaced —
including README.md's build block, which is the highest-value one and lives
in the file the package ships.

Left alone on purpose: installation.md, paths.md's profile table,
CLAUDE.md's GTK4 library-preference row, vision.md's decision log, and the
archived/historical plan documents.

No dependency, privacy, or secret impact. Prose plus one shell fix and one new
unit test; no production code touched.

Plan 023 §D2 — the pinned wording rule and gate

D2.0 — The brief supplied a swept list and asked that it be executed
rather than re-derived. The panel found six more current-state
contradictions; they are adopted because the brief's own definition of done is
"no documentation shipped in the package, and none of the governing docs,
still claims GTK is the Linux UI"
, and README.md:45 — the only Linux build
instruction in the file installed into the .deb — fails that test squarely.

D2.3 — architecture.md: :3 (drop "production", name three
implementations), :13-24 (the whole Stack table, not just the header row
— fixing one row makes the rest more contradictory), :39 (add roost-iced/
to the repo-layout tree).

D2.7 — the gate is a sweep, not a phrase-grep. The first draft's gate
searched for wording already fixed. Replaced with a full sweep plus a written
disposition for every surviving hit, and mkdocs build --strict.

D4.2ut_socket_for gtk gets precise expected outputs for all four
XDG_RUNTIME_DIR states, and a durable regression in
tools/roosttest_unit/ — reversing the first draft's "no test home exists".

🤖 Generated with Claude Code

https://claude.ai/code/session_01SgxiEBQTqgNjPswKqcs12d

charliek and others added 2 commits August 9, 2026 17:22
`main` has shipped the iced UI as the Linux package's `/usr/bin/roost`
since the deb swap, but the docs still described gtk4-rs as the Linux UI.
The worst case was `README.md`, which `packaging/nfpm.yaml` installs to
`/usr/share/doc/roost/README.md`: the package shipped documentation
contradicting its own binary, and its only build-from-source instruction
for Linux built `roost-linux` — not the UI a user actually gets.

Corrected throughout, to one consistent shape: two shipped platform
products (Swift + AppKit on macOS, iced on Linux) and three in-repo UI
implementations. Deliberately NOT "GTK is gone" — `crates/roost-linux`
still builds and `gtk-build` plus all three `e2e-gtk*` lanes still gate
every PR. Only the package changed.

`architecture.md`'s Stack table needed restructuring rather than a one-row
edit: every Linux cell named GTK, so correcting only "Window + chrome"
would have left the table more self-contradicting than before. It is now
three columns, and the rows that are genuinely shared point at their real
`roost-engine`/`roost-ipc` paths. That surfaced a stale path the old table
had carried for a while — `crates/roost-linux/src/daemon/pty.rs` no longer
exists; the PTY has moved to `crates/roost-engine/src/pty.rs`, shared by
both Linux UIs. `CLAUDE.md` cited the same dead path.

vision.md gets exactly two edits — the current-state intro and the
`## Architecture` mermaid diagram. Its DL-* decision-log entries are
untouched: they are historical rationale, and rewriting them would falsify
the record.

Also retires "Iced POC" as a label for a UI that now ships, in the places
that describe current state (the dev profile is now "iced dev build").
Historical plan documents keep their original wording.

Verified by a full `grep -rn "gtk4-rs\|roost-linux\|Iced POC\|poc/iced"`
sweep over every tracked markdown file with a written disposition for each
surviving hit, rather than a grep for the wording already fixed. Every new
file path cited was checked to exist. `mkdocs build` succeeds; `--strict`
surfaces only pre-existing warnings, confirmed unchanged by this diff —
worth stating because `docs.yml` has no pull_request trigger, so nothing
else builds the site before merge.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgxiEBQTqgNjPswKqcs12d
`ut_socket_for gtk` produced `/tmp/roost-<uid>/roost/roost.sock` when
`XDG_RUNTIME_DIR` was unset — a doubled segment the real resolver never
emits. `crates/roost-ipc/src/paths.rs` yields `/tmp/roost-<uid>/roost.sock`.
The arm also accepted an empty or relative `XDG_RUNTIME_DIR`, where the
resolver requires absolute and otherwise falls back. The sibling `iced` arm
was already correct; the gtk arm now mirrors it.

This matters more than it did: the packaged iced UI runs on the gtk
profile, so this is the path tooling would use against a real user install.

Covered by a real test rather than a one-off transcript. The new
`tools/roosttest_unit/test_socket_paths.py` sources `lib.sh` in a
subprocess and asserts exact output for all four `XDG_RUNTIME_DIR` states
(absolute, unset, empty, relative) across both Linux targets — the
semantics being that an invalid value is ignored with a fallback, not an
error. It stubs `uname` so the non-Darwin branch is exercised
deterministically on a Mac too, and it lives where `ci.yml`'s
`harness-unit` job already runs it. Confirmed it fails against the unfixed
script: three of the four gtk cases show the doubled segment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgxiEBQTqgNjPswKqcs12d
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0ae92be9-f06d-4448-9206-a1731532bc55

📥 Commits

Reviewing files that changed from the base of the PR and between 98f0987 and 6943667.

📒 Files selected for processing (16)
  • CHANGELOG.md
  • CLAUDE.md
  • Makefile
  • README.md
  • crates/README.md
  • docs/development/claude-testing.md
  • docs/development/setup.md
  • docs/development/shared-rust-engine.md
  • docs/development/vision.md
  • docs/index.md
  • docs/reference/architecture.md
  • docs/reference/config.md
  • docs/reference/ipc.md
  • docs/reference/paths.md
  • tools/roosttest_unit/test_socket_paths.py
  • tools/screenshot/lib.sh

Comment @coderabbitai help to get the list of available commands.

The cloud review reported `pass` while its body said "Review limit
reached" and it had reviewed nothing — the false-pass the plan's brief
warns about. The local CLI reviewed all 16 files and found three real
issues, two of them misses in this branch's own diff.

vision.md's command-core section still read "One contract, two
implementations", named only Swift and GTK, and ended at "Core Graphics
vs Cairo" — the same class of stale claim already fixed in CLAUDE.md's
north star, and the reason scoping vision.md to "two places" was too
narrow. Its parity question further down said "both implementations" too.
Both now name all three, and record that the two Rust UIs additionally
share `roost-engine`. The DL-* decision log remains untouched.

config.md contradicted itself: the settings table listed `link-modifier`
for "the GTK and Iced apps" while the setting's own scope note said "the
GTK app only". Verified against the source — `link_modifier_held` is
implemented in `crates/roost-iced/src/app.rs` — so the scope note was the
stale half. Fixed, and the file's portability claim now says plainly that
a few settings are honored by only some UIs, with the per-setting section
as the authority.

Not adopted: the suggestion to document iced's threading contract
alongside Mac and GTK. Real gap, but it asks for new material about
single-owner `vt_write` access and the `EngineReady` hand-off that this
docs-correction pass has not verified, and asserting an unverified
threading rule in the governing docs is worse than the omission. Noted as
follow-up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgxiEBQTqgNjPswKqcs12d
@charliek
charliek merged commit 916db38 into main Aug 9, 2026
19 checks passed
@charliek
charliek deleted the feature/plan-023-docs branch August 9, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant