scroll # Cross-Mesh Sift — Specification ##Overview `/api/things` endpoint enhancement toautomatically aggregate Things from allaccessible Boxes across mesh nodes. Replacessingle-node querying with unified multi-nodeaggregation, returning deduplicated resultswith precedence control. ## Architecture ###Design Principle Portal is the mesh center. Itknows all nodes and their Boxes. By default,aggregate all accessible Boxes unless aparameter narrows the scope. This makescross-node discovery the baseline behavior.### Query Flow 1. **Client Request** →`/api/things?being=hex&box_order=hexlet,hexperiment,hexstone`2. **Portal Sift** → Load mesh topology +accessible Boxes 3. **Fan-Out** → Issueparallel `/api/things` requests to each node4. **Merge** → Combine results by box_orderprecedence, deduplicate by document_id 5.**Pagination** → Merge cursors, sort allresults, return next_cursor 6. **Response**→ unified Things array with origin_boxmetadata per item ### Parameters **Existing(pass-through to all nodes):** - `being` —Being name/handle (required for being-specificqueries) - `ring` — Ring UUIDs(comma-separated) - `sapphire` — Thing typefilter - `limit` — Results per page (1-100,default 20) - `cursor` — Pagination token(RFC3339 timestamp) - `start_day` / `end_day`— Sacred-day range - `exclude` — Excludedtypes (comma-separated) - `visibility` —public|private **New (control aggregation):**- `box_order` — Comma-separated node namesdefining precedence for deduplication -Example: `?box_order=hexlet,hexperiment` meansif doc_id appears in both, use hexlet'sversion - Default: all nodes in meshconstellation order (typically: hexlet first)- Single node: `?box_order=hexperiment`queries only that node's Boxes - `boxes` —Specific Box names to include(comma-separated) - Example:`?boxes=hexperiment,migration-moons-2026-05`narrows to those Boxes only - Default: allaccessible Boxes across all nodes - Overridesbox_order (box_order still controlsprecedence) ## Implementation Strategy ### Gapcms-001: Mesh Topology & Box Discovery**What:** Load Portal's mesh constellation andquery Box metadata from each node. **Output:**Mapping of node_name → [Box{uuid, name,visibility, thing_count}] **Implementation:**- In `api_things_sift`: Check `?box_order` and`?boxes` parameters - Query local Boxes +remote node Boxes via HTTP - Cache Boxmetadata (TTL: 5 min) - Handle node offlinegracefully (skip, return available results,warn in response) ### Gap cms-002: ParallelNode Fetching **What:** Issue concurrent`/api/things` requests to each node, passingfilters through. **Input:** Deduplicatedparams (being, ring, sapphire, etc.) +box_order precedence **Output:**Vec<(node_name, Results)> — tagged resultsfrom each source **Implementation:** - Usetokio::join_all for parallel HTTP requests -Construct query string on each node (preservebeing, ring, sapphire, etc.) - Each nodereturns its local Things matching filters -Collect all results with origin node metadata### Gap cms-003: Merge & Deduplicate byPrecedence **What:** Combine Things frommultiple nodes, keeping first version bybox_order. **Algorithm:** 1. Parse box_order:`["hexlet", "hexperiment", "hexstone"]` 2.Flatten all Things from all nodes into asingle vec 3. Group by `document_id` 4. Foreach group: keep Thing from first node inbox_order 5. Tag each Thing: `{ ...,origin_box: "hexlet", origin_node: "hexlet" }`6. De-duplicate: if doc_id exists in 2 nodes,discard non-primary copy **Example:** ``` Nodehexlet: doc_A (v1), doc_B (v1) Nodehexperiment: doc_A (v2), doc_C (v1) box_order:hexlet, hexperiment Result: doc_A (v1 fromhexlet), doc_B (v1 from hexlet), doc_C (v1from hexperiment) ``` ### Gap cms-004:Pagination Across Sources **What:** Mergepaginated results from multiple nodes into asingle cursor-based stream. **Algorithm:** 1.Collect all Things from all nodes (all pages,respect limit) 2. Sort by `created_at DESC,document_id DESC` (consistent ordering) 3.Slice [:limit] to return page 4. Return`next_cursor = things[limit-1].created_at` ifmore exist 5. Client next request:`?cursor=<next_cursor>` refetches all nodes,continues **Note:** This is O(N) across allsources per page. For high-volume feeds,consider: - Limit box_order to reduce fan-out- Cache recent aggregations - Implementserver-side cursor tracking per nodecombination ## Response Format ```json {"sacred": true, "being": { "name": "hex","id": "...", "handle": "hex" }, "count": 42,"things": [ { "document_id": "...", "type":"app.bsky.feed.post", "title": "...", "body":"...", "gem_values": { ... }, "created_at":"2026-05-30T...", "origin_box": "hexperiment","origin_node": "hexperiment" }, ... ],"next_cursor": "2026-05-30T12:34:56Z","aggregation_info": { "nodes_queried":["hexlet", "hexperiment"], "boxes_merged": 3,"deduped_count": 5 } } ``` ## Error Handling -**Node offline:** Return available results +warning: `"warning": "hexperiment offline,results from hexlet + hexstone only"` - **Boxnot found:** Skip silently (Box may have beendeleted) - **Auth failure on remote node:**Return public-only results from that node -**Malformed box_order:** Treat as default (allnodes) ## Rollout **Phase 1:** Implementcms-001 + cms-002 (mesh topology + fetching)**Phase 2:** Implement cms-003 (deduplicationby precedence) **Phase 3:** Implement cms-004(pagination) **Phase 4:** Test withbeing-profile.js on hexperiment queryinghexlet + hexperiment Boxes **Phase 5:** Deployto all nodes ## Testing - Unit: Deduplicationlogic (same doc_id in 2 nodes) - Integration:Query hexperiment Box from hexlet via`/api/things?boxes=hexperiment` - E2E:being-profile.js on hexperiment loads ATThings from hexperiment Box on hexlet