Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
23967fc
test(harness): isolated relay stack + hard-dataset seeder for GUI rea…
Jul 3, 2026
146ccaa
docs(bridge): channel-window /query extension contract + 39005/39006 …
Jul 3, 2026
d032737
feat(relay): channel window read API — keyset pagination + relay-sign…
Jul 3, 2026
e30a301
test(db): fresh-database migration test expects three applied versions
Jul 3, 2026
87eaa42
feat(desktop): add relay-backed channel windows
Jul 3, 2026
ed7cb75
test(desktop): cover live event before channel window
Jul 3, 2026
036f2ee
test(harness): deterministic ancestor-island parity RED (GUI read-mod…
Jul 3, 2026
b4802a9
fix(desktop): trust relay channel window cursor
Jul 3, 2026
2edc527
test(harness): make ancestor-island trigger state-tolerant for the RE…
Jul 3, 2026
574c31f
test(desktop): e2e bridge handler for get_channel_window
Jul 3, 2026
6d6eed5
test(desktop): mock-mode get_channel_window emits bounds + honors cursor
Jul 3, 2026
0c749f9
Merge overhaul/client-core: server-assembled channel window read mode…
Jul 3, 2026
dfb1cd0
Merge overhaul/test-harness: ancestor-island parity gate (RED on main…
Jul 3, 2026
f29b168
docs: add NIP-CW (Channel Window) — normative spec for the /query win…
Jul 3, 2026
da456ac
test(desktop): retire stale escape-hatch assertion in dense-second smoke
Jul 3, 2026
29a8de6
test(desktop): model channel-window paging in e2e bridge
Jul 3, 2026
41901ae
fix(desktop): consume relay thread read models
Jul 3, 2026
3640e71
fix(desktop): self-heal older-history paging after reconnect
Jul 3, 2026
b18f9d6
test(e2e): default parity relay to the canonical :3000, not the :3030…
Jul 3, 2026
f2a551f
chore(desktop): keep ChannelScreen within size limit
Jul 3, 2026
9a533a9
fix(desktop): close live channel window gaps
Jul 3, 2026
1b03128
fix(relay): reject malformed before_id with 400 instead of silent hea…
Jul 3, 2026
5d2482e
test(desktop): mirror relay broadcast depth-1 row classification in t…
Jul 3, 2026
5c5f809
test(desktop): add RED regressions for live-window blockers 2 and 4
Jul 3, 2026
b822560
Merge wren/review-live-window-fixes: close live channel window gaps (…
Jul 3, 2026
89e7323
Merge dawn/harness-review-regressions: RED regressions for live-windo…
Jul 3, 2026
2285d38
Merge fix/window-cursor-malformed-before-id: 400 on malformed before_…
Jul 3, 2026
933aa7a
style(desktop): biome format for live-broadcast-reply spec
Jul 3, 2026
eecc778
fix(desktop): preserve live thread replies across refetch
Jul 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions crates/buzz-core/src/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ pub const KIND_NIP29_GROUP_MEMBERS: u32 = 39002;
/// NIP-29: Addressable group roles definition.
pub const KIND_NIP29_GROUP_ROLES: u32 = 39003;

// Channel-window overlays (relay-signed, synthesized at query time, never
// stored). Appended to bridge `/query` responses for `top_level` window
// requests — see docs/bridge-channel-window.md.
/// Thread summary overlay: `e`/`d` tag = root event id, content =
/// `{reply_count, descendant_count, last_reply_at, participants}`.
pub const KIND_THREAD_SUMMARY: u32 = 39005;
/// Window bounds overlay: `d` tag = `<channel_id>:<request-cursor-or-head>`,
/// content = `{has_more, next_cursor}`. The only authority on exhaustion —
/// clients must not infer `has_more` from row counts.
pub const KIND_WINDOW_BOUNDS: u32 = 39006;

/// Workflow definition (parameterized replaceable, d=workflow_uuid).
pub const KIND_WORKFLOW_DEF: u32 = 30620;

Expand Down Expand Up @@ -471,6 +482,8 @@ pub const ALL_KINDS: &[u32] = &[
KIND_NIP29_GROUP_ADMINS,
KIND_NIP29_GROUP_MEMBERS,
KIND_NIP29_GROUP_ROLES,
KIND_THREAD_SUMMARY,
KIND_WINDOW_BOUNDS,
KIND_PRESENCE_UPDATE,
KIND_TYPING_INDICATOR,
KIND_HUDDLE_REACTION,
Expand Down Expand Up @@ -615,6 +628,8 @@ pub const fn is_relay_only_kind(kind: u32) -> bool {
| KIND_PRESENCE_SNAPSHOT
| KIND_MESH_LLM_RELAY_STATUS
| KIND_DM_VISIBILITY
| KIND_THREAD_SUMMARY
| KIND_WINDOW_BOUNDS
)
}

Expand All @@ -639,6 +654,8 @@ const _: () = assert!(is_parameterized_replaceable(KIND_WORKFLOW_DEF)); // 30620
const _: () = assert!(is_parameterized_replaceable(KIND_EVENT_REMINDER)); // 30300 ∈ 30000–39999
const _: () = assert!(is_parameterized_replaceable(KIND_MESH_LLM_RELAY_STATUS)); // 30621 ∈ 30000–39999
const _: () = assert!(is_parameterized_replaceable(KIND_DM_VISIBILITY)); // 30622 ∈ 30000–39999
const _: () = assert!(is_parameterized_replaceable(KIND_THREAD_SUMMARY)); // 39005 ∈ 30000–39999
const _: () = assert!(is_parameterized_replaceable(KIND_WINDOW_BOUNDS)); // 39006 ∈ 30000–39999

// Compile-time: NIP-34 parameterized replaceable kinds are in the correct range.
const _: () = assert!(
Expand Down
14 changes: 6 additions & 8 deletions crates/buzz-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,23 +1243,21 @@ impl Db {
thread::get_thread_summary(&self.pool, community_id, event_id).await
}

/// Top-level messages for a channel.
pub async fn get_channel_messages_top_level(
/// One channel window: top-level rows + summaries + server `has_more`.
pub async fn get_channel_window(
&self,
community_id: CommunityId,
channel_id: Uuid,
limit: u32,
before_cursor: Option<DateTime<Utc>>,
since_cursor: Option<DateTime<Utc>>,
cursor: Option<(DateTime<Utc>, Vec<u8>)>,
kind_filter: Option<&[u32]>,
) -> Result<Vec<thread::TopLevelMessage>> {
thread::get_channel_messages_top_level(
) -> Result<thread::ChannelWindow> {
thread::get_channel_window(
&self.pool,
community_id,
channel_id,
limit,
before_cursor,
since_cursor,
cursor,
kind_filter,
)
.await
Expand Down
2 changes: 1 addition & 1 deletion crates/buzz-db/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ mod tests {

run_migrations(&pool).await.expect("run migrations");

assert_eq!(applied_versions(&pool).await, vec![1, 2]);
assert_eq!(applied_versions(&pool).await, vec![1, 2, 3]);
let sql = migration_sql();
let tables = create_tables(sql.as_str());
for table in [
Expand Down
Loading