Files
buzz/docs/solo-mobile-contract.md
klopez4212 c9e35f8ac7 fix(mobile): restore Solo chats from channel labels (#8466)
Restore Solo chats and project placement on mobile using `buzz.solo`
labels and creator metadata. Invalidate stale channel details when
identity changes so opening and sending preserve refreshed Solo
identity; shared chats retain ordinary sending. New mobile Solo chats
publish the discovery label, and the personal send guard enforces
ownership even when route hints or legacy placement suggest Solo.

The current desktop producer lives in `block/buzz-app`. [Contract
documentation](0201ca0572/docs/solo-mobile-contract.md)
links its production creation call to relay identity generation and
mobile regression coverage. Public metadata fields are documented.

Validation: clean analysis; 3,542 mobile tests (5 skipped), 4 push
checks, and 280 core unit/doc tests passed. Removing the cache fix
reproduces the send failure. Local push hooks were skipped with owner
approval after an unrelated terminal timeout and disk exhaustion; full
local CI is not green. GitHub CI must validate the pushed commit. The
initial build was installed/launched on iPhone; follow-up native and
live cross-client confirmation remain pending.

The ownership regression supplies a valid owned member recipient and
checks the exact rejection. A New chat UI test captures the real signed
kind-9007 command. Both regressions were mutation-verified: removing the
ownership guard or the production creation label causes the
corresponding test to fail.

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
2026-10-20 11:10:24 -04:00

2.8 KiB

Solo desktop/mobile contract

The current Solo producer is block/buzz-app, not the older desktop/ client retained in this repository.

The captured producer revision is 64726576ed3b082daa5786e5e7ca6b5a018663a1:

  • SoloDraft.tsx calls session.channelWrites.create.
  • channel-writes.ts emits kind 9007 with channel_type=stream, visibility=private, and t=buzz.solo. Its existing production-service test is “creates a Solo chat in its single durable outbox command” in channel-writes.test.ts.
  • model.ts retains project assignments but drops the legacy groups.channels discovery list.

The desktop does not author P. The relay derives the creator from the signed creation event. In this repository, channel_labels_from_tags in crates/buzz-relay/src/handlers/side_effects.rs parses creation labels; group_state_identity_tags in crates/buzz-core/src/channel.rs emits the leading type t, subsequent label t tags, and uppercase creator P. emit_group_discovery_events uses that builder for relay metadata. Mobile reads those facts through ChannelData.fromEvent and its channel providers.

Reproducible contract coverage

test-fixtures/solo-creation.json contains an actual captured production create command, plus expected relay identity tags using a synthetic creator. To recapture it from a checkout of the pinned desktop revision:

node --experimental-transform-types scripts/contracts/capture-solo-creation.mjs /path/to/buzz-app > test-fixtures/solo-creation.json

The script invokes createChannelWrites(...).create(...) and captures its outbox command without publishing anything. The core test desktop_solo_creation_preserves_mobile_identity_contract feeds those command labels through the production parser and relay identity builder. The mobile regression “refresh replaces stale Solo details before opening and sending” consumes the same identity tags through the real list/detail providers, primes old details, refreshes, opens Solo, and sends through the personal sender with an empty legacy chat list. Existing widget coverage checks project and unfiled placement and shared-chat ordinary sending.

These are compositional contract tests, not a live desktop/relay/device E2E run. Physical-device installation and launch alone do not prove that journey.