/** * One node's relational web — the shared walk behind `get_relational_web`. * * Both stores had their own copy of this BFS and both copies had the same two * defects, which is the argument for there being one. * * **It returned edges it had no nodes for.** The loop pushed every edge touching * a visited node, including edges whose far end sat past the depth limit and was * never returned. A consumer drawing that gets a dangling reference; a consumer * counting it is told the web is denser than the nodes it was handed. * * **It had no notion of a container.** `chronicle:miadi-chronicle` carries a * `belongs_to` from all 82 episodes. So depth 2 from any one episode went * episode → root → all 81 others, and "what does this episode touch" answered * with the corpus. Measured 2026-09-03: episode 011 has exactly **one** relation * and its 2-hop web came back with 31 nodes and 100 edges — 81KB, over the tool * result limit, from a node with one neighbour. * * A container is reached and not expanded through: it stays in the answer, * because "this episode belongs to the chronicle" is true and worth knowing, and * the walk does not leave again through its other 81 edges. * * @see app/api/nodes/[id]/web/route.ts — the HTTP surface with the same semantics */ /** * Structural, not nominal. * * `StoredNode` and `StoredEdge` are declared privately and identically inside * both `jsonl-store.ts` and `http-store.ts` — a duplication this file is not the * place to unwind. Taking the shape instead of the name lets one walk serve both * stores without either importing the other's copy, and callers keep their own * richer types through the generic parameters. */ export interface WebNode { id: string; name?: string; metadata?: Record | null; } export interface WebEdge { from_id: string; to_id: string; } /** * Node kinds that are containers by definition, whatever their degree. * * Named rather than inferred. Degree is a proxy and it drifts: on the wheel * measured 2026-09-03 the median degree is 2, p99 is 14, the chronicle root is * 82 — and `node:land:host:gaia` at 17 is already closing that gap, so a * threshold correct today is wrong in weeks. The corpus already spells the * thing directly. */ export declare const CONTAINER_KINDS: readonly ["chronicle_root"]; /** * A node above this degree is treated as a container even unnamed — the backstop * for containers nobody has classified yet. Placed in the gap between the * busiest ordinary node (17) and the root (82). */ export declare const DEFAULT_MAX_EXPAND_DEGREE = 20; export interface RelationalWebOptions { depth?: number; /** `null` disables suppression entirely. */ maxExpandDegree?: number | null; containerKinds?: readonly string[]; /** * Hard cap on returned nodes, applied when the CENTRE is itself a container. * * Suppression protects a walk that *encounters* a hub, and does nothing for a * walk that starts on one — asking about the chronicle root is a legitimate * question, and the centre is never suppressed. But its answer is the whole * corpus: measured 2026-09-05, `get_relational_web` centred on * `chronicle:miadi-chronicle` at depth 1 returned **157,233 characters**, over * twice the listing that had just been cut for overrunning the tool-result * limit, reachable by an obvious call. * * So the centre still answers, and answers a page, and says it is one. */ maxNodes?: number; } /** Nodes returned when the centre is a container and the answer would be the corpus. */ export declare const DEFAULT_MAX_NODES = 60; /** A container the walk reached and declined to expand through. */ export interface WebHubHold { id: string; name: string; degree: number; reason: 'kind' | 'degree'; /** Neighbours behind it that no other path reached. */ unexpanded: number; } export interface RelationalWebResult { nodes: N[]; edges: E[]; hubs: WebHubHold[]; /** True when some node adjacent to the returned set was not returned. */ truncated: boolean; /** Set when the node cap trimmed the answer, with what the whole would have been. */ capped?: { returned: number; available: number; }; } export declare function buildRelationalWeb(nodeId: string, allNodes: N[], allEdges: E[], options?: RelationalWebOptions): RelationalWebResult; //# sourceMappingURL=relational-web.d.ts.map