Files
buzz/PHASE1C_BREAKAGE_CATALOGUE.md
npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je 7db512e48f feat(relay): complete Phase 1 single-node slice
Signed-off-by: npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz>
2026-08-10 12:11:34 -04:00

8.3 KiB

Phase 1c single-node breakage catalogue

Branch: local-mode/phase-1, based on committed SQLite core slice 88b9644 and the Phase 0 seam stack through a680665. This catalogue describes the production-router single-node slice, not the retired Phase 0 alternate router.

Result

BUZZ_PROFILE=single-node enters the normal production router through crates/buzz-relay/src/main.rs:164,1208-1305, rejects non-loopback binding (main.rs:1209-1214), and constructs SQLite, in-process pub/sub and replay fencing, filesystem media, unsupported search, and permissive admission without opening PostgreSQL, Redis, or S3 connections (main.rs:1231-1278). The readiness log enumerates intentionally disabled background/service families (main.rs:1295-1296).

The fresh WP-B matrix passed profiles, public relay-member admission (kind 9030), channel creation/membership, owner↔agent chat, thread/reply/mention, reaction add/get/remove/get, DM open and sends in both directions, feeds, explicit search denial, canonical filesystem media byte round-trip, NIP-42/history/live fan-out, and restart durability. Evidence is recorded below.

Worked as-is

Surface File:line evidence Result
Production protocol/router and NIP-42 crates/buzz-relay/src/main.rs:164,1284-1294; crates/buzz-test-client/src/bin/local_mode_smoke.rs:7-54 Normal router and client protocol; no local-only wire protocol.
PostgreSQL production profile crates/buzz-db/src/lib.rs:172-221; backend matches such as lib.rs:1730-1734 Existing PostgreSQL construction and paths remain the default backend arms.
Search failure shape crates/buzz-relay/src/api/bridge.rs:1732-1741 Local unsupported search returns explicit HTTP 501 unsupported_feature, not 500 or false success.
Loopback safety fence crates/buzz-relay/src/main.rs:1209-1214 Single-node startup fails closed on a non-loopback bind address.

Worked with local backend/shim

Surface File:line evidence Fidelity / limitation
Startup/service aggregate crates/buzz-relay/src/main.rs:1208-1305 Production router with a local backend bundle; production-only workers are not started.
Durable SQLite core crates/buzz-db/src/sqlite.rs:137-458; dispatch at crates/buzz-db/src/lib.rs:1710-1812,1891-1961,2187-2256,4848-4850,5176-5178 Real normalized community/channel/member/event/reaction/DM tables and SQL filtering. Thread ancestry remains canonical NIP-10 tags; denormalized thread metadata/counters are deferred.
Conformance row projection crates/buzz-db/src/lib.rs:1670-1699; crates/buzz-db/src/sqlite.rs:824-844 SQLite now resolves each returned row's channel community, removing the PG-only warning while retaining the non-interference trace seam.
Pub/sub + presence crates/buzz-pubsub/src/lib.rs:133-160,994-1057; startup main.rs:1252,1286-1292 Process-local, community-scoped fan-out and expiring presence leases; no cross-process Redis semantics.
NIP-98 replay crates/buzz-pubsub/src/nip98_replay.rs:1-213; startup main.rs:1270,1277 Bounded in-process replay fence; restart does not retain replay history.
Media crates/buzz-media/src/storage.rs:89-98,104-313; startup main.rs:1275 Filesystem CAS path supports canonical upload/download, sidecars, ranges and pages; no S3 replication.
Profiles/users/channels/membership SQLite methods crates/buzz-db/src/sqlite.rs:715-844,903-1079; dispatch crates/buzz-db/src/lib.rs:2299-2467,2672-2779,4334-4467 Startup owner bootstrap plus public relay-admin and channel membership flows work locally.
Feed crates/buzz-db/src/sqlite.rs:461-530; routed dispatch crates/buzz-db/src/lib.rs:3444-3470,3532-3558,3618-3642 WP-B mentions/needs-action/activity query shapes work; advanced non-routed feed methods remain PostgreSQL-only.
Reactions crates/buzz-db/src/sqlite.rs:533-599; routed writes/removal crates/buzz-db/src/lib.rs:2213-2256,3302-3344 Atomic reaction/event insertion, dedupe, and removal used by CLI matrix. Aggregate/direct helper family is not fully ported.
DM open crates/buzz-db/src/sqlite.rs:601-713; command seam crates/buzz-db/src/lib.rs:2845-2858; crates/buzz-relay/src/handlers/command_executor.rs:373-413 DM open and its command idempotency execute transactionally in SQLite. Other command kinds are rejected before persistence; broader DM list/find/create public methods remain PostgreSQL-only.
Workflow dispatch gate crates/buzz-relay/src/handlers/event.rs:520-559 Local profile does not invoke the PostgreSQL workflow engine, matching startup's disabled declaration.

Stubbed / deliberately permissive

Surface File:line evidence Local behavior
Search crates/buzz-relay/src/main.rs:1274; api/bridge.rs:1732-1741 Service is unavailable and explicitly returns 501; FTS5 is deferred.
Git, push, workflows, reapers, usage, replica tasks crates/buzz-relay/src/main.rs:1295-1296; Git route gate crates/buzz-relay/src/router.rs:49-52 Not started/exposed in the single-node profile.
Admission rate limiting crates/buzz-pubsub/src/rate_limiter.rs:97-103; startup main.rs:1278 Explicit permissive in-process policy, not Redis quotas.
Audit crates/buzz-relay/src/main.rs:1280-1282 No audit service/worker in single-node startup.
Relay signing identity crates/buzz-relay/src/main.rs:1245-1251 If no key is configured, local mode uses a public deterministic development key; safe only with the enforced loopback bind and unsuitable for shared/production use.
Unsupported command families crates/buzz-relay/src/handlers/command_executor.rs:120-128 Commands other than the dedicated atomic DM-open path are explicitly rejected before an idempotency event can be persisted.
Thread summaries and NIP-43 publications crates/buzz-relay/src/handlers/side_effects.rs (emit_live_thread_summary, publish_nip43_membership_list, publish_nip43_delta) PostgreSQL-backed thread/list snapshots are omitted locally; globally scoped NIP-43 deltas are also suppressed to avoid leaking the loopback roster. Durable NIP-10 tags and the SQLite relay-members table remain authoritative.

Blocked PostgreSQL-only public DB methods

These calls fail with typed DbError::UnsupportedBackend if reached on SQLite; they are not silently emulated. The list is representative of the remaining families rather than a claim that every Db method is ported.

Family File:line evidence Consequence
Direct deletion helpers crates/buzz-db/src/lib.rs:1919-1937 Standard event deletion uses the routed atomic helper, but callers of these direct methods remain blocked.
Channel policy crates/buzz-db/src/lib.rs:2785-2793 Channel add-policy mutation is unavailable locally.
Direct DM helpers/list crates/buzz-db/src/lib.rs:2795-2823 WP-B DM open uses the SQLite command seam; separate find/create/list APIs remain blocked.
Thread counters crates/buzz-db/src/lib.rs:3263-3277 No denormalized decrement; tag-based ancestry only.
Direct/aggregate reaction helpers crates/buzz-db/src/lib.rs:3280-3299,3347-3416 Ingest/removal tracer path works; direct add, active-record lookup, and aggregate reads are not routed.
Non-routed feed helpers crates/buzz-db/src/lib.rs:3418-3436,3510-3528,3598-3614 HTTP/CLI routed feed works; callers choosing writer-only helpers remain blocked.

Verification artifacts

Fresh runtime evidence is under .scratch/wp-b-matrix/ (ephemeral, not committed):

PASS wp_b_cli_matrix
PASS media_byte_comparison
PASS kind_9030_admission
PASS nip42,event_insert,req_history,live_fanout
PASS sqlite_restart_history
PASS no_postgres_workflow_conformance_leakage
PASS no_global_nip43_publications

The matrix covers profiles, channel creation/membership, owner↔agent chat, reply/thread/mention, reactions through removal, DM open plus both-direction sends, owner/agent feeds, explicit search 501, and canonical media upload/download byte comparison. A scan of fresh first-boot and restart logs found no Workflow trigger failed, conformance row-community lookup failed, or PostgreSQL operation on SQLite lines; the fresh SQLite file contains zero kind 8000/8001/13534 global NIP-43 publication rows. Package test counts and the exact verified commit are reported with the final commit because line numbers above describe the formatted final working tree.