mirror of
https://github.com/block/buzz.git
synced 2026-10-31 06:21:34 +00:00
b9fa51ecaf030d9f71ca35d98599aaabd5e0ffbd
18 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b9fa51ecaf |
test: cover pubsub presence typing isolation
Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz> |
||
|
|
da6051fdbc |
test(conformance): fill api_tokens_nip98_replay row — doc-only api_token half + wire-driven NIP-98 replay half
Fills both `pending_lane` stubs in `mod api_tokens_nip98_replay`: # `token_minted_in_a_does_not_authorize_in_b` — doc-only The api_token mint surface does not exist on the wire in `buzz-relay`: no `/tokens` route in `router.rs:52-79` (verified by hand on PR head), no `tokens` module in `crates/buzz-relay/src/api/`. The 792-line self-service minting endpoint that existed pre-rewrite (sprout-relay PR #37, commit `f84da74d3`) was deliberately not ported. Api_tokens are *consumed* (not minted) by the Blossom upload path at `media.rs:638`. This means "mint in A, present to B" has no wire precondition — a wire-driven row would test a contract with no entry point. The honest shape is doc-only, mirroring `audit_log`: where audit proves the *output* surface does not exist on the wire, api_tokens proves the *input* surface does not. Both are strictly stronger isolation claims than a wire-denied assertion. The `(community_id, token_hash)` fence itself is directly proven at the storage layer (where direct Postgres access is in-convention): * `crates/buzz-db/src/api_token.rs:425 lookup_by_hash_is_scoped_to_community` — same hash in A and B, A-scoped lookup returns A only. * `crates/buzz-db/src/api_token.rs:488 active_lookup_by_hash_is_scoped_to_community` — mirror for the revoked-filter variant. Plus the consumer fence: `media.rs:638` calls the scoped DB lookup with `tenant.community()` derived from request host *before* token resolution (`media.rs:97` comment names the row-44 fence explicitly). # `nip98_replay_seenset_is_shared_and_community_scoped` — wire-driven Load-bearing wire claim: within-community replay rejection. Sign a NIP-98 event E for A's `u=`, POST to A → 200. POST again → 401 with a body that names replay detection. The proof that the shared (cross-pod) seen-set is in the request path at all — without it, any pod would re-honor a spent NIP-98 event. Mutate-bite: `check_nip98_replay → noop` in `bridge.rs:79` (return `Ok(())` without consulting the guard). Under mutation, second POST goes 200 instead of 401. Test asserts the failure with named assertion message pointing at the mutate-bite handle, so a future reader sees what would have been caught. Cross-community independence is a *tripwire*, not a bite: sign an independent NIP-98 event E' for B's `u=` (different event_id by u-tag canonicalization divergence), POST to B → 200 even though E was spent in A. Catches future namespace-globalization regressions (key truncation, u-normalization collapse) that would break the spend-spread, on top of the unit-layer proof at `crates/buzz-auth/src/nip98_replay.rs:163 key_isolates_communities_for_same_event_id` (which the substrate's own doc-comment names as "belt-and-suspenders"). The prefix-drop mutation considered earlier turned out to be vacuous against natural wire traffic: u-tag divergence across communities makes event_ids already community-distinct, so dropping the community prefix from `nip98_replay_key` does not collapse natural traffic into a shared slot. A same-event_id-different-community wire collision can't be constructed because u-host (`verify_bridge_auth`) rejects with 401 before the replay check runs. That artificial property is proven at the unit layer; the wire layer asserts the load-bearing per-call replay rejection. # Bar * `cargo check -p buzz-test-client --tests`: clean. * `cargo clippy -p buzz-test-client --tests -- -D warnings`: clean. * `cargo fmt -p buzz-test-client -- --check`: clean. * Default test run (no `--ignored`): 1 passed (doc-only `#[test]`), 16 ignored (live rows). * `--ignored api_tokens` against fresh `:3300` harness (`BUZZ_GIT_CONFORMANCE_PROBE=false`): GREEN. * Mutate-bite `check_nip98_replay → noop` on `bridge.rs:79`, rebuild, restart: RED on the within-A second-POST assertion ("second POST to A with the same NIP-98 event MUST be rejected as replay (got 200 OK)"), `left: 200, right: 401`. Restored byte-identical, GREEN again. Base: PR #1321 head `ae703c5c8`. Test-only diff: zero lines in `buzz-db`, `buzz-relay`, or `buzz-auth` production code. Matrix 8/14. Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz> |
||
|
|
ae703c5c89 |
test(conformance): fill channels_membership row — same channel UUID coexists in two communities
Conformance matrix row `channels_membership` (re-routed from Mari to Quinn at Eva's call — Mari's #1328 scroll-fix is still landing on main, and the row's substrate is the same same-UUID-in-two-communities shape I already used as the setup for `search_fts`). Fills the `pending_lane("buzz-db", ...)` stub at `crates/buzz-test-client/tests/conformance_multitenant.rs::mod channels_membership`. The row's scope is the **positive arm** of the same `is_member_cached` scope branch that `row_zero_host_binding`'s `#h` override-attempt row exercises as the **negative arm**. Sibling-not-replacement, per the frame Dawn established when cold-reading row_zero (b): row_zero proves the override-attempt fails closed against `get_channel(A, U) == None`; this row proves the coexistence positive — when U exists in *both* A and B (legal under the `(community_id, id)` PK), `get_channel` finds the right per-community row and each community's posts land in its own instance. A bug that resolves `get_channel`/`is_member_cached` against the claimed community instead of the host-derived one would pass row_zero (b)'s negative-arm test (rejection still happens for some reason) but fail this row's positive-arm test (A's post might land in B's channel or be returned to B's query). So this row catches a class of bugs row_zero (b) structurally cannot, even though both share the `is_member_cached` scope branch. Shape: 1. One keypair shared across both communities — proves the fence is `community_id`, not `pubkey`. 2. Same channel UUID `U` created in both A and B via REST kind:9007. 3. Same key posts kind:9 with community-distinct content to U on each WS-AUTH'd connection ("A message in shared-UUID channel" / "B message in shared-UUID channel"). Distinct content per the named setup-equivalence-vacuity lesson in `landed-on-head-discipline` — without it, distinct rows would collide on Nostr event id (hash includes content; community is server-side provenance, not in the hash) and a leak would be indistinguishable from the honest path on the wire. 4. REST `POST /query` with `{kinds:[9], #h:[U]}` against each host. 5. Each side: count == 1, content == own community's. A leak surfaces as count == 2 (both rows returned through shared `#h: U` filter) OR content mismatch on count == 1. Bar (by my own hands against the live `:3100` harness, PR head `6aa0cec4a`): Clean → GREEN. Mutate (single fence — single-fence-per-path topology here, unlike search_fts's defense-in-depth): - crates/buzz-db/src/event.rs:266-270 — `query_events` non-p-tag branch `WHERE community_id = ` → `WHERE TRUE` (using the `let _ = q.community_id;` pattern Eva established on row_zero, one of the three honest sidesteps for the param-count trap I flagged in my prior message; the other two are renumbering and `( IS NOT NULL)`). → RED on `hits_a.len() == 1` with the failure message listing both contents: ["B message in shared-UUID channel", "A message in shared-UUID channel"] Distinct content makes the leak observable as B's message surfacing inside A's wire response. Restore → diff empty → GREEN. Bar checklist: - `cargo fmt -p buzz-test-client -- --check`: exit 0. - `cargo clippy -p buzz-test-client --tests -- -D warnings`: clean. - `cargo test -p buzz-test-client --tests`: full package non-ignored green (4 nip42_host_binding_live tests are #[ignore]'d by design). - Strict-FF onto PR head: this is +1 on `6aa0cec4a`, verified by `git merge-base --is-ancestor` + `git rev-list --count`. - Trailers preserved as single pair via initial `--trailer` flag (not `--amend --trailer`, which doubled them earlier in the session). - Live two-host harness on `:3100`: my clean (post-restore) binary, recipe per RESEARCH/CONFORMANCE_MATRIX_STATUS_2026-06-27.md v3. Conformance lane: this row is one of fourteen in the file; per Eva's row-ownership contract, this commit touches only the `channels_membership` module. No other rows modified. Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz> |
||
|
|
6aa0cec4a9 |
test(conformance): fill users_profiles_nip05 row — kind:0 + NIP-05 lookup per-community
Conformance matrix row `users_profiles_nip05` (Quinn — buzz-search/auth
joint, both halves driven by Quinn per one-author-per-mod-block
discipline; Sami's active queue is `api_tokens_nip98_replay` per Eva's
batching). Fills both `pending_lane` stubs in the row.
Half 1: `same_pubkey_distinct_profiles_in_two_communities`
Same keypair publishes kind:0 (Metadata) on each host's WS-AUTH'd
connection with community-distinct content
(`{"display_name":"A profile"}` vs `{"display_name":"B profile"}`).
NIP-01 replaceable semantics: latest kind:0 per
`(community_id, pubkey)` is what subsequent queries return. REST
`POST /query` (using dev-mode `X-Pubkey` auth, which the
`BUZZ_REQUIRE_AUTH_TOKEN=false` harness allows) returns each host's
own kind:0 — never the other's. Distinct content per community is
load-bearing for the bite: identical content would collapse the leak
into setup-equivalence vacuity (Dawn's catch on `audit_log` —
identical Nostr event ids when (pubkey, created_at, kind, tags,
content) match — making the assertion blind to the wrong-row
substitution).
Half 2: `same_nip05_local_part_on_two_hosts_is_independent`
Same local-part registered in BOTH communities with **distinct**
pubkeys (one per community). `GET /.well-known/nostr.json?name=alice`
against host A returns A's pubkey; against host B returns B's pubkey.
Distinct pubkeys per community make the leak observable as
wrong-pubkey-returned on the wire — the same setup-equivalence-vacuity
defense Dawn established (different keys = different rows = the wrong
answer is observable in the response, not just absent from it). Handle
canonicalization uses `extract_relay_domain` (mirrors
`crates/buzz-relay/src/api/nip05.rs::extract_domain`) against
`RELAY_URL` env so the test still works if the harness's relay URL
changes; defaults to `localhost` for the standard recipe.
Bar (by my own hands against the live `:3100` harness, PR head
`b02d767f2`):
Clean → BOTH GREEN.
Mutate (community fences dropped, both paths simultaneously, mirroring
the search_fts dual-fence approach):
- crates/buzz-db/src/event.rs:267-270 — `query_events` non-p-tag
branch `WHERE community_id = $1` → `WHERE TRUE`
- crates/buzz-db/src/user.rs:185 — `get_user_by_nip05`
`WHERE community_id = $1 AND LOWER(handle) = LOWER($2)` →
`WHERE LOWER(handle) = LOWER($1)` (rebind to keep param count
aligned)
→ BOTH halves RED on their own assertions:
- kind:0 half: "B's kind:0 content is not B's profile — A's
profile leaked through. got: '{"display_name":"A profile"}'"
- NIP-05 half: "NIP-05 lookup on B for local-part 'alice_…' must
resolve to B's pubkey ($B_PK); got $A_PK. If this is A's
pubkey, the community fence on `get_user_by_nip05` has been
dropped and A's user leaked through B's lookup."
Restore both fences (worktree diff empty after restore) → BOTH GREEN.
Each half bit on a SINGLE-fence mutation this time, unlike search_fts's
defense-in-depth shape. That's because the kind:0 read path
(`query_events`) and the NIP-05 lookup path (`get_user_by_nip05`)
each have one community fence at their layer, not redundant fences
across two layers like the FTS+batch-fetch shape. Different rows have
different defense topologies; this row's mutate-bite is the simpler
single-fence form, exactly as the named failure-mode analysis in
`landed-on-head-discipline` rule #2 sub-bullet predicts (the union of
fences IS what makes the property load-bearing; here the union has
exactly one element per path).
Bar checklist:
- `cargo fmt -p buzz-test-client -- --check`: exit 0.
- `cargo clippy -p buzz-test-client --tests -- -D warnings`: clean.
- `cargo test -p buzz-test-client --tests`: non-ignored 0/0 (the 4
nip42_host_binding_live tests are #[ignore]'d by design — they need
the live harness).
- Strict-FF onto PR head: this is +1 on `b02d767f2`, verified by
`git merge-base --is-ancestor` + `git rev-list --count`.
- Trailers preserved as single pair via the explicit `--trailer`
flags on the initial commit (not `--amend --trailer`, which doubled
them earlier in the session).
- Live two-host harness on `:3100`: my clean (post-restore) binary,
recipe per RESEARCH/CONFORMANCE_MATRIX_STATUS_2026-06-27.md, two
community rows seeded `a.localhost:3100`/`b.localhost:3100`.
Conformance lane: this row is one of fourteen in the file; per Eva's
row-ownership contract, this commit touches only the
`users_profiles_nip05` module. No other rows modified.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
|
||
|
|
b02d767f24 |
test(conformance): fill search_fts row — two-host NIP-50 isolation + delete
Conformance matrix row `search_fts` (Quinn, buzz-search). Fills the
`pending_lane("buzz-search", ...)` stub at
`crates/buzz-test-client/tests/conformance_multitenant.rs::mod search_fts`
with a two-host A/B-isolation shape: one keypair shared across A and B,
same channel UUID reused in both communities (legal under the
`(community_id, id)` PK), the *same* unique FTS token posted to each
community as kind:9 events but with **community-distinct content**.
NIP-50 search on each host must return exactly one hit carrying that
host's community's content; NIP-09 kind:5 delete in A leaves B's row
intact.
Bar (by my own hands against a live two-host relay on the conformance
recipe — Eva's `:3100` `relay-mt` harness, a/b.localhost, shared
PG/Redis, base PR head `bf8a1a4fa`):
Clean → GREEN.
Mutate (both community fences on the search read path, simultaneously):
crates/buzz-search/src/query.rs:160-161 (FTS WHERE community_id = $ctx)
crates/buzz-db/src/event.rs:870-872 (get_events_by_ids WHERE community_id = $1)
→ RED on `hits_a.len() == 1` with the failure message listing both
contents:
["A community probe ftsconf_…", "B community probe ftsconf_…"]
Restore both → GREEN.
Two contract surprises discovered by running the row against the live
relay (the lesson Eva established with nip11_relay_info — obligation
text under-determines the layer):
1. The community fence is doubly defended on the search read path: FTS
filters at the query layer, then `get_events_by_ids` re-filters at
the read layer. Mutating either fence alone keeps the
wire-observable property intact (the other defends). The honest
mutate-bite is to drop both simultaneously; that's what makes the
union load-bearing for the wire return. The test's doc comment
names both layers and explains why the single-layer mutation would
give a false-green.
2. With identical content in both communities, the Nostr event id is
the SAME byte string in both rows (id = hash(pubkey, created_at,
kind, tags, content); community is server-side provenance, not
serialized into id). Under a leak, the wire returns "the row
matching id" — which can be either community's row — and a count==1
assertion can't tell A's row from B's. Earlier iterations of this
test used identical content and discovered the hard way that
single-hit-with-other-community's-row is indistinguishable from
correct behavior at that assertion. Per-community-distinct content
(`"A community probe {token}"` vs `"B community probe {token}"`)
makes the leak observable: distinct content hashes to distinct ids
(different rows), and the assertion `hits[0].content == content_a`
pins which community's row came back.
Other discipline notes:
- Test is `#[ignore]` by default; selected with `-- --ignored`. Reads
two env vars: `RELAY_URL_A` / `RELAY_URL_B`, both addressing the same
relay process on different `Host` headers.
- Requires the two-host harness recipe (`BUZZ_HEALTH_PORT=8180
BUZZ_METRICS_PORT=9202 BUZZ_RECONCILE_CHANNELS=false
BUZZ_GIT_CONFORMANCE_PROBE=false`, two `communities` rows mapping
`a.localhost:3100` and `b.localhost:3100` to distinct community
UUIDs, one binary). Full recipe in the v2 dependency report at
`RESEARCH/CONFORMANCE_MATRIX_STATUS_2026-06-27.md`.
- Requires Sami's NIP-42 per-tenant relay-tag fix on PR head
(`bf8a1a4fa`) — without it, `BuzzTestClient::connect(&ws_a, &keys)`
fails AUTH on the non-configured host. The row was pre-positioned on
`809ff9faf` and rebased forward to PR head `bf8a1a4fa` exactly +1
commit; clean rebase (different file regions from
auth.rs/bridge.rs/nip42_host_binding_live.rs).
- Conformance lane: this row (`search_fts`) is one of fourteen in the
file; per Eva's row-ownership contract, this commit touches only the
`search_fts` module. No other rows modified.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
|
||
|
|
f7ec53b06d |
test(conformance): fill row_zero_host_binding (unmapped fail-closed + #h override-reject)
Replace both pending_lane stubs in row_zero_host_binding with live wire tests:
(a) unmapped_host_fails_closed_generically — drives an unmapped host over the
HTTP door (404) vs a mapped host (non-404): the status *difference* proves
no default-tenant fallthrough. Asserts the rejection body echoes neither the
host authority nor the bare label (generic, no enumeration oracle), and that
a raw WS upgrade to the unknown host is rejected at the handshake. Doc-
comment notes the mapped-200/unmapped-404 status difference is an
intentional, door-scoped distinguisher (non-nostr+json SPA/WS door only) so
a future reader does not "fix" it into a 404-everywhere that breaks the SPA
fallback; the nostr+json door deliberately does not expose it.
(b) client_supplied_community_cannot_override_host — creates an OPEN channel in
community B only, confirms it is postable in B (positive control), then posts
a kind:9 #h-tagging that B-only channel UUID over an A connection. A must
reject: the host-derived community wins over the client #h claim. Open
visibility isolates the override property from the ordinary membership gate
(the A-side post can fail for exactly one reason: the channel doesn't exist
in A's community). Asserts the rejection does not echo the B channel UUID
(no cross-community existence oracle).
Bite-specificity: the override assertion also pins the reason string
"restricted: not a channel member" (the exact IngestError::Rejected the
override path emits at ingest.rs:446), so the red means "A rejected because
the host-derived community refused the #h claim", not merely "A rejected
for some earlier-gate reason" (bind_community 404 / bridge-auth 403 /
NIP-98 replay / relay-membership 403 / JSON parse 400 all precede the
channel-scope branch). Two cold reviewers (Dawn, Mari) converged on this
independently from the sanitization and channels-membership sides.
Sibling-not-replacement: #h override-attempt is row_zero; the relay-tag /
token-u-host override signals are Sami's NIP-42 rows; same-UUID coexistence is
Mari's channels_membership row. Cross-refs documented in the doc-comments.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
|
||
|
|
1d7db983ab |
test(conformance): audit_log isolation — doc-only row + integrated relay test + error sanitization
The audit log has no client-reachable wire surface: there is no /audit
route in the relay, and AuditError is never relayed to a client. A pure
black-box A≡B conformance row (the shape every other row in
conformance_multitenant.rs uses) is therefore impossible, and reaching
behind the wire into Postgres from that file would break its black-box
contract. So the obligation is proven across three honest homes:
1. Doc-only conformance row (conformance_multitenant.rs): cites the
no-wire-surface fact — a strictly stronger isolation claim than "the
oracle is denied" — plus the per-community-chain substrate and the two
executable proofs below.
2. Integrated relay test (buzz-relay handlers::event): drives
dispatch_persistent_event under two tenants against a shared Postgres
and asserts each community's audit chain contains only its own
object_id and verifies independently. Proves the
host→TenantContext→chain wiring keeps tenants isolated end-to-end.
No WS-AUTH in the loop, so it is not blocked on NIP-42.
3. Error-sanitization unit test (buzz-audit error): asserts no AuditError
variant's rendered text embeds a community_id, constraint name, or
cross-community object id, with a non-vacuous check that per-community
seq still appears.
Both runnable pieces mutate-bitten: a stale-tenant scoping bug reds the
isolation assertion ("B's event id appeared in A's chain"); leaking a
constraint name into an #[error] string reds the sanitization assertion.
Co-authored-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
|
||
|
|
bf8a1a4fa7 |
buzz-relay: bind NIP-42 AUTH relay tag to per-tenant host (row 44 sibling)
NIP-42 sibling of the NIP-98 host-binding fix in |
||
|
|
809ff9faf7 |
test(conformance): nip11_relay_info — NIP-11 is host-agnostic, not a community-enumeration oracle
First real (non-pending_lane) conformance row in conformance_multitenant.rs; the reference pattern remaining rows copy. Asserts the wire-observable complement to the compile-time static-input fence (_RELAY_INFO_BUILD_STATIC_INPUT_FENCE): the NIP-11 relay-info document served for host A, host B, and an *unmapped* host are all byte-identical. Identical docs are the proof that the unauthenticated relay-info endpoint carries no host-derived field and therefore cannot be used to probe which communities are configured on a deployment. Corrects an initial design error caught by running the row against a live two-host relay: the unmapped-host case must return 200 with the same static doc, NOT 404 — a 200-vs-404 status difference between mapped and unmapped hosts would itself be the enumeration oracle. Fail-closed host binding lives on the WS-upgrade / non-nostr+json path (router.rs::nip11_or_ws_handler) and is the obligation of row_zero_host_binding, not this row. Adds url_unknown() helper (RELAY_URL_UNKNOWN) alongside url_a/url_b. Verified by hand against a live two-host relay (a/b.localhost:3100, shared PG/Redis): green -> mutate (leak request Host into the served description) -> red on the A==B assertion with a real wire diff, not a compile break -> restore -> green. Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz> |
||
|
|
3fd16cc1f7 |
fix(search): restore privacy kind exclusions at the FTS storage layer
The Typesense→Postgres FTS rewrite replaced out-of-band indexing with
`search_tsv TSVECTOR GENERATED ALWAYS AS (to_tsvector('simple', content))
STORED` over every row. The old relay (handlers/event.rs:287 on main)
deliberately skipped search-indexing for three kind classes, and the new
search query layer has no kind exclusion — so gift wraps, DM-visibility
snapshots, and event reminders were all in the FTS index.
Fix at the storage layer (option A — single source of truth, zero
app-layer drift across multiple search call sites): make the generated
column yield `NULL::tsvector` for excluded kinds via a CASE expression.
A NULL tsvector never matches `@@`, so excluded rows are structurally
unsearchable.
Excluded set, parity with main's `handlers/event.rs:287-290`:
- 1059 KIND_GIFT_WRAP (NIP-17 ciphertext)
- 30300 KIND_EVENT_REMINDER (AUTHOR_ONLY_KINDS — defense in depth)
- 30622 KIND_DM_VISIBILITY (per-viewer private hide state)
Constants are inlined in the migration with a comment naming the
`buzz_core::kind` names: sqlx migrations are frozen SQL and can't
`use buzz_core::kind`; importing core into a migration would be worse
drift than the inline-with-comment shape.
Three coupled layers:
1. Schema CASE in migrations/0001_initial_schema.sql. The 0001 schema
was consolidated by Max in
|
||
|
|
787774f3b4 |
test(conformance): multi-tenant A/B isolation harness skeleton
Executable form of docs/multi-tenant-conformance.md: one module per obligation-table surface row (14 surfaces, 18 isolation tests) plus the N=1 parity gate documented against the existing e2e suites. Each A/B isolation test addresses two hosts (RELAY_URL_A/RELAY_URL_B) on the SAME relay process — one binary, one Postgres, one Redis, two communities — proving no tenant-observable state crosses a boundary derived from host, never caller input. All #[ignore] (need a running two-host relay) so a normal cargo test run reports 0 passed / 18 ignored; they cannot fake-pass. Rows the lane hasn't landed yet panic via pending_lane(lane, obligation), which names the exact obligation for the owner to fill in and makes the remaining work one grep. Lane ownership tagged per module. (cherry picked from commit 9d6d35f07a17fcf5ccd8a6f20fdede3349e67024) Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co> Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com> |
||
|
|
73cc31cc52 |
chore: remove LLM-slop comments across the codebase (#1277)
Signed-off-by: Tyler Longwell <tlongwell@block.xyz> Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Max <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Mari <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Quinn <96f056ad5f2305c8ddf637dc65d048aa4c12d7daeb8867690e34fca46b0ef64c@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Sami <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Perci <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Tyler Longwell <tlongwell@block.xyz> |
||
|
|
d256935c36 |
feat: publish personas, teams, and managed agents as relay events (#939)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Will Pfleger <pfleger.will@gmail.com> |
||
|
|
38a9533439 | [codex] Make relay frame limit configurable (#1225) | ||
|
|
6780ea21e4 |
fix(relay): resubscribe agents when an archived channel is restored (#1187)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co> |
||
|
|
26563968cb |
feat(relay): add NIP-ER push scheduler with cross-pod delivery (#957)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co> |
||
|
|
79fcfd82bc |
feat(relay): implement NIP-ER event reminder support (kind:30300) (#934)
Signed-off-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Will Pfleger <wpfleger@squareup.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co> |
||
|
|
d99ad131f1 |
refactor: rename sprout backend to buzz (#958)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <wpfleger@block.xyz> Signed-off-by: Will Pfleger <wpfleger@squareup.com> Signed-off-by: Will Pfleger <wpfleger96@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub1fgdl5qqnh3k3f2xkqrvt7cujalhm623x4s7fdjdj5yrtp5fzjl9qrjpucw <4a1bfa0013bc6d14a8d600d8bf6392efefbd2a26ac3c96c9b2a106b0d12297ca@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub16v54tttfqacx9ycvc3k0ut0npj564ahcuajzy6qjvh57ntmsf4uq4806j2 <d32955ad69077062930cc46cfe2df30ca9aaf6f8e76422681265e9e9af704d78@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Will Pfleger <wpfleger96@gmail.com> |