Docs contradict each other on whether local image pixels travel over shm #194
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#194
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Two felis docs (and issue #120) contradict each other about whether daemon→client image
pixels travel over shared memory. A downstream client author reading them cannot tell
which is normative.
docs/explanation/architecture/overview.md— "Implications / No shared memory":docs/explanation/architecture/ipc.md— "Open extensibility considerations", therationale for deferring the heavy-payload suppression bit:
Issue #120 carries the same sentence ("locally, image bytes travel over shm and the
waste is marginal"), so the claim is in three places.
Reproduction
At
105b089979369fd310757375af3df7900ae7e523:The only shm felis actually has is the Kitty
t=sproducer→daemon transfer mode(
docs/explanation/protocols/kitty-graphics.md,docs/explanation/data-model/image-store.md).The daemon copies those bytes into its own image store; what reaches a client is
ImageMsgframes over the socket, exactly as "No shared memory" says.Why it matters beyond wording
The deferral of #120 is justified by the false half. If local image pixels really rode
shm, the local waste would be zero and only the cross-host case could ever motivate the
bit. They do not: locally the pixels are copied into every subscriber's socket, so a
same-host TUI client that drops them already pays for bytes it discards. That may still
be small enough to not be worth a flag — but the deferral should rest on a fact rather
than on this one.
How it surfaced
felis-tui (
natsukium/felis-tui) had copied the sentence into its own roadmap whilefollowing felis to this rev, and a reader was sent looking for a local shm path in the
client that does not exist. Corrected downstream in
natsukium/felis-tui#follow-felis-105b0899, but the felis-side contradiction is whatproduced it.
Out of scope for the downstream PR
Only felis can decide which of the two statements is the normative one, and the fix
cascades across two explanation docs plus the #120 body — a felis doc-cascade change,
not a change an ecosystem repo can make.
Triage plan (2026-09-07)
Verdict: accepted,
priority/P1(docs-only, ~15 lines; the tag must not freeze an architecture doc that contradicts itself on the IPC boundary — a downstream client author has already been misled).Verified: the "No shared memory" statement in
docs/explanation/architecture/overview.mdmatches the code. Daemon→client pixels areImageMsg::Chunkframes (crates/felis-daemon/src/graphics.rs, 256 KiB chunks) cloned into every window subscriber's outbound queue (serve/session_task.rs,materialize_image_events→broadcast), consumed from the socket infelis-client-core/src/image_shadow.rs. NoSCM_RIGHTS/memfd/fd-passing path exists anywhere incrates/. The only shm in felis is the Kittyt=sproducer→daemon transfer (graphics/image_decode.rs), which stops at the daemon's image store. Theipc.mdsentence ("locally, image bytes already travel over shm") was false from birth (f2696d23) and #120's body repeats it.Approach:
docs/explanation/architecture/ipc.md"Open extensibility considerations": replace the shm sentence with the true statement — locally every window subscriber receives its own pixel copy over the socket (ImageMsg::Chunk), a cost that is unmeasured and bounded by image size; keep the deferral and the cross-host-first trigger. Link tooverview.md#no-shared-memory. Say "unmeasured", never "marginal" (principle 2: no unmeasured optimization claims).overview.md"No shared memory": one sentence that the Kittyt=sproducer→daemon transfer is the only shm in the system and ends at the image store; cross-linkdata-model/image-store.md.git grep -in shm docs/must hit only the Kittyt=spages. No reference twin change, no CHANGELOG, noskills/felis, no schema. Fact correction, not a decision record — the why goes in the commit body.Non-goal: this does not motivate a same-host suppression path before v0.1.0 (principle 1: nobody has shown the cost); #120 stays open unchanged in scope.