@lucern/graph-primitives 1.0.27 → 1.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/beliefDecay.js.map +1 -1
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.js.map +1 -1
- package/dist/contradictions.js +3 -3
- package/dist/contradictions.js.map +1 -1
- package/dist/convex.js.map +1 -1
- package/dist/entityBridge.js.map +1 -1
- package/dist/entityLifecycle.js +7 -39
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.js +6 -42
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.js +2 -21
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +1 -0
- package/dist/epistemicBeliefs.confidence.js +4 -40
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.js +6 -44
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +1 -0
- package/dist/epistemicBeliefs.forkEvidence.js +2 -22
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +3 -27
- package/dist/epistemicBeliefs.helpers.js +4 -40
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.js +2 -22
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +17 -55
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.js +7 -45
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.js +7 -43
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.queries.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
- package/dist/epistemicContracts.evaluators.js +4 -40
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.js +4 -40
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +4 -40
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicEdgeCreation.js.map +1 -1
- package/dist/epistemicEdges.handlers.js.map +1 -1
- package/dist/epistemicEdges.js +4 -4
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.js +4 -4
- package/dist/epistemicEdges.mutations.js.map +1 -1
- package/dist/epistemicEdges.queries.js.map +1 -1
- package/dist/epistemicEvidence.js +5 -5
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceHelpers.js.map +1 -1
- package/dist/epistemicEvidenceMutations.js +5 -5
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicEvidenceQueries.js.map +1 -1
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicLinking.js.map +1 -1
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +4 -4
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.js +4 -4
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicNodes.queries.js.map +1 -1
- package/dist/epistemicQuestions.conviction.js.map +1 -1
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.helpers.js.map +1 -1
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.lifecycle.js.map +1 -1
- package/dist/epistemicQuestions.queries.js.map +1 -1
- package/dist/epistemicQuestions.sprint.js.map +1 -1
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/epistemicSources.js +2 -2
- package/dist/epistemicSources.js.map +1 -1
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +50 -121
- package/dist/index.js.map +1 -1
- package/dist/ontologyApproval.js.map +1 -1
- package/dist/ontologyDefinitions.js.map +1 -1
- package/dist/ontologyRegistry.js.map +1 -1
- package/dist/projectionReconciliation.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.js.map +1 -1
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/convex.ts","../src/graphTypes.ts","../src/epistemicLayerRules.ts","../src/epistemicLinking.ts"],"names":[],"mappings":"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","file":"epistemicLinking.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * Graph Type Registry for Convex\n *\n * This file mirrors the canonical type registry at lib/ontology/types.ts\n * but is compatible with Convex's bundling requirements.\n *\n * IMPORTANT: Keep this file in sync with lib/ontology/types.ts\n * The frontend uses lib/ontology/types.ts, Convex uses this file.\n *\n * @see /docs/architecture/UNIFIED_GRAPH_ARCHITECTURE.md\n */\n\n// =============================================================================\n// EPISTEMIC LAYERS\n// =============================================================================\n\nexport type EpistemicLayer =\n | \"L4\"\n | \"L3\"\n | \"L2\"\n | \"L1\"\n | \"ontological\"\n | \"organizational\";\n\n// =============================================================================\n// NODE TYPE TO LABEL MAPPING\n// =============================================================================\n\nexport const NODE_TYPE_TO_LABEL: Record<string, string> = {\n // L4: Audit Targets\n decision: \"Decision\",\n\n // L3: Traversal Anchors\n belief: \"Belief\",\n question: \"Question\",\n theme: \"Theme\",\n deal: \"Deal\",\n topic: \"Topic\",\n\n // L2: Compression Boundary\n claim: \"Claim\",\n evidence: \"Evidence\",\n synthesis: \"Synthesis\",\n answer: \"Answer\",\n\n // L1: Terminal Leaves\n atomic_fact: \"AtomicFact\",\n excerpt: \"Excerpt\",\n source: \"Source\",\n\n // Ontological (Neo4j is SOT)\n company: \"Company\",\n person: \"Person\",\n investor: \"Investor\",\n function: \"Function\",\n value_chain: \"ValueChain\",\n};\n\n// =============================================================================\n// EDGE TYPE TO NEO4J RELATIONSHIP MAPPING\n// =============================================================================\n\n/**\n * Epistemic Kernel v2: 6 canonical edge types + ontological edges.\n *\n * Weight and metadata carry nuance that previously required 67 separate type strings.\n * See: docs/architecture/epistemic-kernel-v2.md\n */\nexport const EDGE_TYPE_TO_REL: Record<string, string> = {\n // === THE SIX CANONICAL EPISTEMIC EDGE TYPES ===\n supports: \"SUPPORTS\", // L3↔L3: belief bears on belief (weight -1 to +1)\n informs: \"INFORMS\", // L2→L3: evidence bears on belief\n depends_on: \"DEPENDS_ON\", // L3→L3, Q→Q: structural gate\n derived_from: \"DERIVED_FROM\", // Any→Any: provenance chain (fork, synthesis, extraction, answer)\n contains: \"CONTAINS\", // Any→Any: hierarchy, scoping, membership\n tests: \"TESTS\", // Q→L3: question interrogates belief\n\n // === L4 DECISION EDGES (derived_from with derivationType=decision) ===\n // Kept as separate Neo4j relationship types for backward compat with L4 queries.\n // New code should use derived_from + metadata.\n based_on_belief: \"BASED_ON_BELIEF\",\n based_on_question: \"BASED_ON_QUESTION\",\n blocked_by_contradiction: \"BLOCKED_BY_CONTRADICTION\",\n informed_by_theme: \"INFORMED_BY_THEME\",\n\n // === ONTOLOGICAL EDGES (tenant-extensible, managed by ontology system) ===\n works_at: \"WORKS_AT\",\n invested_in: \"INVESTED_IN\",\n competes_with: \"COMPETES_WITH\",\n participates_in: \"PARTICIPATES_IN\",\n founded_by: \"FOUNDED_BY\",\n evaluates: \"EVALUATES\",\n performs: \"PERFORMS\",\n function_in: \"FUNCTION_IN\",\n impacts: \"IMPACTS\",\n raised_from: \"RAISED_FROM\",\n mentioned_in: \"MENTIONED_IN\",\n perspective_on: \"PERSPECTIVE_ON\",\n about_entity: \"ABOUT_ENTITY\",\n entity_referenced_in: \"ENTITY_REFERENCED_IN\",\n};\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Get the epistemic layer for a node type\n */\nexport function getNodeLayer(nodeType: string): EpistemicLayer {\n const L4_TYPES = [\"decision\"];\n const L3_TYPES = [\"belief\", \"question\", \"theme\", \"deal\"];\n const L2_TYPES = [\"claim\", \"evidence\", \"synthesis\", \"answer\"];\n const L1_TYPES = [\"atomic_fact\", \"excerpt\", \"source\"];\n const ONTOLOGICAL_TYPES = [\n \"company\",\n \"person\",\n \"investor\",\n \"function\",\n \"value_chain\",\n ];\n const ORGANIZATIONAL_TYPES = [\"topic\"];\n\n if (L4_TYPES.includes(nodeType)) {\n return \"L4\";\n }\n if (L3_TYPES.includes(nodeType)) {\n return \"L3\";\n }\n if (L2_TYPES.includes(nodeType)) {\n return \"L2\";\n }\n if (L1_TYPES.includes(nodeType)) {\n return \"L1\";\n }\n if (ONTOLOGICAL_TYPES.includes(nodeType)) {\n return \"ontological\";\n }\n if (ORGANIZATIONAL_TYPES.includes(nodeType)) {\n return \"organizational\";\n }\n\n // Unknown types default to L2\n console.warn(`[GraphTypes] Unknown nodeType \"${nodeType}\", defaulting to L2`);\n return \"L2\";\n}\n\n/**\n * Get the Neo4j label for a node type\n */\nexport function getNeo4jLabel(nodeType: string): string {\n return (\n NODE_TYPE_TO_LABEL[nodeType] ||\n nodeType.charAt(0).toUpperCase() + nodeType.slice(1)\n );\n}\n\n/**\n * Get the Neo4j relationship type for an edge type\n */\nexport function getNeo4jRelType(edgeType: string): string {\n return EDGE_TYPE_TO_REL[edgeType] || edgeType.toUpperCase();\n}\n\n/**\n * The 6 canonical epistemic edge types (Kernel v2).\n * Anything not in this set or the ontological/L4 sets is deprecated.\n */\nconst CANONICAL_EPISTEMIC_TYPES = new Set([\n \"supports\",\n \"informs\",\n \"depends_on\",\n \"derived_from\",\n \"contains\",\n \"tests\",\n]);\n\n/**\n * Check if an edge type is deprecated.\n *\n * Kernel v2: only the 6 canonical epistemic types, L4 decision types,\n * and ontological types are active. All legacy types (67 old types) are deprecated.\n */\nexport function isDeprecatedEdgeType(edgeType: string): boolean {\n // Canonical epistemic types are NOT deprecated\n if (CANONICAL_EPISTEMIC_TYPES.has(edgeType)) return false;\n // Types in the EDGE_TYPE_TO_REL map (ontological + L4) are NOT deprecated\n if (edgeType in EDGE_TYPE_TO_REL) return false;\n // Everything else is a legacy type\n return true;\n}\n","/**\n * Epistemic Spine helper module split from epistemicHelpers.ts.\n */\n\nimport type { Id } from \"./convex\";\n\n// =============================================================================\n// TYPE MAPPINGS\n// =============================================================================\n\ntype EpistemicNodeType =\n // L4: Audit targets\n | \"decision\"\n // L3: Traversal anchors\n | \"belief\"\n | \"question\"\n | \"theme\"\n | \"deal\"\n // L2: Compression boundary\n | \"claim\"\n | \"evidence\"\n | \"synthesis\"\n | \"answer\"\n // L1: Terminal leaves\n | \"atomic_fact\"\n | \"excerpt\"\n | \"source\";\n\ntype OntologicalNodeType =\n | \"company\"\n | \"person\"\n | \"investor\"\n | \"function\"\n | \"value_chain\";\n\ntype NodeType = EpistemicNodeType | OntologicalNodeType;\n\n// =============================================================================\n// EPISTEMIC LAYER ARCHITECTURE (Lucern Invariant Compliance)\n// =============================================================================\n\n/**\n * Epistemic Layer - governs traversal rules\n * L4 → L3 → L2 → L1 (never skip layers)\n */\nexport type EpistemicLayer =\n | \"L4\"\n | \"L3\"\n | \"L2\"\n | \"L1\"\n | \"ontological\"\n | \"organizational\";\n\n/**\n * Map nodeType to its epistemic layer\n *\n * Layer semantics:\n * - L4: Audit targets (decisions, outcomes) - what we committed to\n * - L3: Traversal anchors (beliefs, questions, themes) - epistemic structure\n * - L2: Compression boundary (claims, evidence, synthesis) - minimum reasoning unit\n * - L1: Terminal leaves (atomic_fact, excerpt, source) - non-traversable grounding\n * - ontological: Entities in the world (companies, people) - not epistemic\n * - organizational: Structural containers (topics, lenses, worktrees) - not epistemic\n */\nexport function getNodeLayer(nodeType: string): EpistemicLayer {\n switch (nodeType) {\n // L4: Audit targets\n case \"decision\":\n return \"L4\";\n\n // L3: Traversal anchors\n case \"belief\":\n case \"question\":\n case \"theme\":\n case \"deal\":\n return \"L3\";\n\n // L2: Compression boundary\n case \"claim\":\n case \"evidence\":\n case \"synthesis\":\n case \"answer\":\n return \"L2\";\n\n // L1: Terminal leaves\n case \"atomic_fact\":\n case \"excerpt\":\n case \"source\":\n return \"L1\";\n\n // Ontological entities\n case \"company\":\n case \"person\":\n case \"investor\":\n case \"function\":\n case \"value_chain\":\n return \"ontological\";\n\n // Organizational containers\n case \"topic\":\n return \"organizational\";\n\n default:\n // Unknown types default to L2 (safest for traversal)\n console.warn(\n `[EpistemicLayer] Unknown nodeType: ${nodeType}, defaulting to L2`\n );\n return \"L2\";\n }\n}\n\n/**\n * Layer traversal rules\n * Key constraint: Cannot skip layers during traversal\n */\nexport const LAYER_TRAVERSAL_RULES = {\n L4: {\n canReach: [\"L3\", \"L4\"], // Decisions can reach beliefs/questions\n mustPassThrough: \"L3\", // Must go through L3 to reach L2\n },\n L3: {\n canReach: [\"L2\", \"L3\", \"L4\"], // Beliefs can reach evidence, other beliefs, or decisions\n mustPassThrough: \"L2\", // Must go through L2 to reach L1\n },\n L2: {\n canReach: [\"L1\", \"L2\", \"L3\"], // Evidence can reach sources, other evidence, or beliefs\n mustPassThrough: null, // L2 can reach L1 directly\n },\n L1: {\n canReach: [\"L1\"], // Sources can only reach other sources\n mustPassThrough: null, // Terminal - no traversal beyond\n },\n ontological: {\n canReach: [\"L3\", \"L2\", \"ontological\"], // Entities can link to epistemic structure\n mustPassThrough: null, // No layer constraints for entities\n },\n organizational: {\n canReach: [\"L3\", \"L2\", \"organizational\"], // Containers scope epistemic structure + nest\n mustPassThrough: null, // No layer constraints for containers\n },\n} as const;\n\n/**\n * Check if a direct edge between two layers is allowed\n */\nexport function isValidLayerConnection(\n fromLayer: EpistemicLayer,\n toLayer: EpistemicLayer\n): boolean {\n const rules = LAYER_TRAVERSAL_RULES[fromLayer];\n return (rules.canReach as readonly string[]).includes(toLayer);\n}\n\n/**\n * Get layer hierarchy number (for comparison)\n * Higher number = higher layer\n */\nexport function getLayerDepth(layer: EpistemicLayer): number {\n switch (layer) {\n case \"L4\":\n return 4;\n case \"L3\":\n return 3;\n case \"L2\":\n return 2;\n case \"L1\":\n return 1;\n case \"ontological\":\n return 0; // Ontological exists outside the epistemic hierarchy\n case \"organizational\":\n return 0; // Organizational exists outside the epistemic hierarchy\n default:\n return 2;\n }\n}\n\n/**\n * Check if we can traverse from one layer to another\n * (considering intermediate layers)\n */\nexport function canTraverseToLayer(\n fromLayer: EpistemicLayer,\n toLayer: EpistemicLayer\n): boolean {\n const fromDepth = getLayerDepth(fromLayer);\n const toDepth = getLayerDepth(toLayer);\n\n // Ontological/organizational layers are special - use explicit rules\n if (\n fromLayer === \"ontological\" ||\n toLayer === \"ontological\" ||\n fromLayer === \"organizational\" ||\n toLayer === \"organizational\"\n ) {\n return isValidLayerConnection(fromLayer, toLayer);\n }\n\n // Can always stay at same layer\n if (fromDepth === toDepth) {\n return true;\n }\n\n // Can go up (L1→L2→L3→L4) or down (L4→L3→L2→L1)\n // But must respect layer rules\n return isValidLayerConnection(fromLayer, toLayer);\n}\n\n// =============================================================================\n// PHASE 2D: LAYER-AWARE TRAVERSAL\n// =============================================================================\n\n/**\n * Traversal mode - determines how to traverse the graph\n *\n * anchor_down: Start at L3 belief, traverse to L2 evidence, stop at L1 sources\n * anchor_up: Start at L2 evidence, traverse to L3 beliefs it supports\n * same_layer: Traverse within a single layer (e.g., belief → belief)\n * decision_trace: Start at L4 decision, traverse to L3 beliefs it was based on\n */\nexport type TraversalMode =\n | \"anchor_down\"\n | \"anchor_up\"\n | \"same_layer\"\n | \"decision_trace\";\n\n/**\n * Traversal options for layer-aware queries\n */\nexport type TraversalOptions = {\n /** Starting node ID */\n startNodeId: Id<\"epistemicNodes\">;\n /** Traversal mode */\n mode: TraversalMode;\n /** Edge types to follow (empty = all valid for mode) */\n allowedEdgeTypes?: string[];\n /** Maximum depth */\n maxDepth?: number;\n /** Minimum layer to stop at (L1 = 1, L4 = 4) */\n minLayer?: number;\n /** Maximum layer to reach */\n maxLayer?: number;\n};\n\n/**\n * Check if traversal should continue based on layer constraints\n */\nexport function shouldContinueTraversal(\n currentLayer: EpistemicLayer,\n targetLayer: EpistemicLayer,\n options: {\n mode: TraversalMode;\n minLayer?: number;\n maxLayer?: number;\n }\n): boolean {\n const currentDepth = getLayerDepth(currentLayer);\n const targetDepth = getLayerDepth(targetLayer);\n\n // Check min/max layer constraints\n if (options.minLayer !== undefined && targetDepth < options.minLayer) {\n return false; // Would go below minimum layer\n }\n if (options.maxLayer !== undefined && targetDepth > options.maxLayer) {\n return false; // Would go above maximum layer\n }\n\n // Mode-specific rules\n switch (options.mode) {\n case \"anchor_down\":\n // Can only go down (L4→L3→L2→L1)\n return targetDepth < currentDepth || targetDepth === currentDepth;\n\n case \"anchor_up\":\n // Can only go up (L1→L2→L3→L4)\n return targetDepth > currentDepth || targetDepth === currentDepth;\n\n case \"same_layer\":\n // Must stay at same layer\n return targetDepth === currentDepth;\n\n case \"decision_trace\":\n // Decisions (L4) can trace to beliefs (L3), stop there\n return currentDepth === 4\n ? targetDepth === 3\n : targetDepth === currentDepth;\n\n default:\n return true;\n }\n}\n\n/**\n * Get default minLayer for a traversal mode\n */\nexport function getDefaultMinLayer(mode: TraversalMode): number {\n switch (mode) {\n case \"anchor_down\":\n return 1; // Can go all the way to L1 sources\n case \"anchor_up\":\n return 2; // Start at L2 evidence minimum\n case \"same_layer\":\n return 1; // No constraint\n case \"decision_trace\":\n return 3; // Stop at L3 beliefs (don't go to L2 evidence)\n default:\n return 1;\n }\n}\n\n/**\n * Get allowed edge types for a traversal mode\n */\nexport function getDefaultEdgeTypesForMode(mode: TraversalMode): string[] {\n switch (mode) {\n case \"anchor_down\":\n // From beliefs/questions down to evidence and sources\n return [\n \"informs\", // evidence → belief (traverse backwards)\n \"derived_from\", // evidence → source (provenance) + evidence → question\n ];\n case \"anchor_up\":\n // From evidence up to beliefs\n return [\"informs\", \"derived_from\"];\n case \"same_layer\":\n // Within-layer relationships\n return [\n // L3: Belief ↔ Belief\n \"depends_on\",\n \"supports\",\n \"contains\",\n // L3: Question ↔ Question\n \"prerequisite_for\",\n \"parallel_to\",\n // L2: Evidence ↔ Evidence\n \"corroborates\",\n \"extends\",\n \"same_source_as\",\n \"same_theme_as\",\n ];\n case \"decision_trace\":\n // From decisions to beliefs\n return [\n \"derived_from\",\n \"depends_on\",\n \"contains\",\n ];\n default:\n return [];\n }\n}\n\n// =============================================================================\n// PHASE 2C: EDGE LAYER RULES\n// =============================================================================\n\n/**\n * Edge Layer Rules - defines valid layer combinations for each edge type\n *\n * Format: { from: [allowed source layers], to: [allowed target layers] }\n *\n * Key rules:\n * - L4 edges: Decision → L3 (beliefs, questions, themes)\n * - Cross-layer edges: L2 → L3 (evidence informs beliefs)\n * - Same-layer edges: L3 → L3, L2 → L2 (beliefs depend on beliefs)\n * - Downward edges: L2 → L1 (evidence extracted from source)\n * - Lifecycle edges: same layer only (supersedes)\n */\nexport const EDGE_LAYER_RULES: Record<\n string,\n { from: EpistemicLayer[]; to: EpistemicLayer[]; description: string }\n> = {\n // === L4 Decision Edges ===\n based_on_belief: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Belief (L4 → L3)\",\n },\n based_on_question: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Question (L4 → L3)\",\n },\n blocked_by_contradiction: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Contradiction (L4 → L3)\",\n },\n informed_by_theme: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Theme (L4 → L3)\",\n },\n\n // === Evidence Flow (L2 → L3, L2 → L1) ===\n derived_from: {\n from: [\"L2\", \"L3\", \"L4\"],\n to: [\"L1\", \"L2\", \"L3\"],\n description: \"A was produced from B (provenance chain)\",\n },\n answers: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Evidence → Question (L2 → L3)\",\n },\n responds_to: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Answer → Question (L2 → L3)\",\n },\n informs: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Evidence → Belief (L2 → L3)\",\n },\n qualifies: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Evidence → Belief (L2 → L3)\",\n },\n\n // === Question → Belief (L3 → L3) ===\n tests: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Question → Belief (L3 → L3)\",\n },\n explores: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Question → Belief assumption (L3 → L3)\",\n },\n\n // === Synthesis (L2 → L2, L2 → L1) ===\n based_on: {\n from: [\"L2\"],\n to: [\"L2\", \"L1\"],\n description: \"Synthesis → Evidence/Source (L2 → L2/L1)\",\n },\n\n // === Theme Relationships (L3 → L3) ===\n relates_to_thesis: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Belief → Theme (L3 → L3)\",\n },\n belongs_to: {\n from: [\"L3\", \"L2\"], // Can belong to theme from L3 or L2\n to: [\"L3\"],\n description: \"Any → Theme (L3/L2 → L3)\",\n },\n plays_theme: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Deal → Theme (L3 → L3)\",\n },\n\n // === Topic Hierarchy (L3 → organizational) ===\n scoped_by: {\n from: [\"L3\"],\n to: [\"organizational\"],\n description: \"Belief/Question → Topic (L3 → organizational)\",\n },\n\n // === Deal/Company ===\n evaluates: {\n from: [\"L3\"],\n to: [\"ontological\"],\n description: \"Deal → Company (L3 → ontological)\",\n },\n\n // === People (ontological → ontological, ontological → L3) ===\n perspective_on: {\n from: [\"ontological\"],\n to: [\"L3\"],\n description: \"Person → Belief/Theme (ontological → L3)\",\n },\n works_at: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Person → Company (ontological → ontological)\",\n },\n\n // === Value Chain (ontological) ===\n participates_in: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → ValueChain (ontological → ontological)\",\n },\n performs: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Function (ontological → ontological)\",\n },\n function_in: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Function → ValueChain (ontological → ontological)\",\n },\n impacts: {\n from: [\"L3\"],\n to: [\"ontological\"],\n description: \"Theme → ValueChain (L3 → ontological)\",\n },\n\n // === Investment (ontological) ===\n invested_in: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Investor → Company (ontological → ontological)\",\n },\n raised_from: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Investor (ontological → ontological)\",\n },\n\n // === Entity↔Belief Bridge (OE-B) ===\n about_entity: {\n from: [\"L3\"],\n to: [\"ontological\"],\n description: \"Belief/Question/Theme → Entity (L3 → ontological)\",\n },\n entity_referenced_in: {\n from: [\"ontological\"],\n to: [\"L2\"],\n description: \"Entity → Evidence (ontological → L2)\",\n },\n mentioned_in: {\n from: [\"ontological\"],\n to: [\"L1\"],\n description: \"Entity → Source document (ontological → L1)\",\n },\n founded_by: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Person (ontological → ontological)\",\n },\n competes_with: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Company (ontological → ontological)\",\n },\n contains: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"ValueChain → Function (ontological → ontological)\",\n },\n\n // === Lifecycle (same layer only) ===\n supersedes: {\n from: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n to: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n description: \"NewNode → OldNode (same layer only - validated separately)\",\n },\n same_as: {\n from: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n to: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n description: \"Duplicate detection (same layer only - validated separately)\",\n },\n\n // === Same-Type: Belief ↔ Belief (L3 → L3) ===\n depends_on: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Belief B requires Belief A (L3 → L3)\",\n },\n reinforces: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Beliefs strengthen each other (L3 → L3)\",\n },\n parent_of: {\n from: [\"L3\", \"organizational\"],\n to: [\"L3\", \"organizational\"],\n description:\n \"A is higher-level than B (L3 → L3, organizational → organizational)\",\n },\n child_of: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Belief A is more specific (L3 → L3)\",\n },\n\n // === Same-Type: Question ↔ Question (L3 → L3) ===\n prerequisite_for: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Question A must be answered first (L3 → L3)\",\n },\n parallel_to: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Same topic, different angles (L3 → L3)\",\n },\n\n // === Same-Type: Evidence ↔ Evidence (L2 → L2) ===\n corroborates: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Independent support (L2 → L2)\",\n },\n extends: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Adds depth (L2 → L2)\",\n },\n same_source_as: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Same document/study (L2 → L2)\",\n },\n same_theme_as: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Same topic/entity (L2 → L2)\",\n },\n\n // === NEW: Deep Epistemic Analysis Edges (Phase: Schema Upgrade) ===\n assumes: {\n from: [\"L3\"],\n to: [\"L3\"],\n description:\n \"Hidden dependency - Belief B implicitly assumes Belief A (L3 → L3)\",\n },\n would_predict: {\n from: [\"L3\"],\n to: [\"L2\"],\n description:\n \"Pre-registered prediction - If Belief true, expect Evidence (L3 → L2)\",\n },\n analogous_to: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Explicit analogy - Belief A is like Belief B (L3 → L3)\",\n },\n independent_of: {\n from: [\"L2\"],\n to: [\"L2\"],\n description:\n \"True evidence independence - Evidence A independent of B (L2 → L2)\",\n },\n\n // NOTE: Deprecated edge types (supports, contradicts, derived_from, cites,\n // summarizes, related_to, partially_answers, blocks, refines, branches_from)\n // have been REMOVED from the system. Use compliant alternatives instead.\n};\n\n/**\n * Validate an edge against layer rules\n *\n * Returns { valid: true } or { valid: false, reason: string }\n */\nexport function validateEdgeLayers(\n edgeType: string,\n fromLayer: EpistemicLayer,\n toLayer: EpistemicLayer\n): { valid: boolean; reason?: string } {\n const rules = EDGE_LAYER_RULES[edgeType];\n\n // Unknown edge type - allow but warn\n if (!rules) {\n console.warn(\n `[EdgeValidation] Unknown edge type: ${edgeType}, allowing by default`\n );\n return { valid: true };\n }\n\n // Special handling for same-layer edges (supersedes)\n if (edgeType === \"supersedes\") {\n if (fromLayer !== toLayer) {\n return {\n valid: false,\n reason: `${edgeType} edges must be between nodes of the same layer. Got ${fromLayer} → ${toLayer}`,\n };\n }\n return { valid: true };\n }\n\n // Check from layer\n if (!rules.from.includes(fromLayer)) {\n return {\n valid: false,\n reason: `Edge type '${edgeType}' does not allow source layer ${fromLayer}. Allowed: ${rules.from.join(\", \")}`,\n };\n }\n\n // Check to layer\n if (!rules.to.includes(toLayer)) {\n return {\n valid: false,\n reason: `Edge type '${edgeType}' does not allow target layer ${toLayer}. Allowed: ${rules.to.join(\", \")}`,\n };\n }\n\n return { valid: true };\n}\n\n","/**\n * Epistemic Linking Mutations\n *\n * Creates proper edges in the epistemic graph when linking entities.\n * These mutations are called by the SuggestedMatches component when\n * a user links items from AI-suggested matches.\n *\n * @see /docs/architecture/EPISTEMIC_SPINE.md\n */\n\nimport { v } from \"convex/values\";\nimport { internal } from \"./convex\";\nimport { mutation } from \"./convex\";\nimport {\n getNodeLayer,\n isDeprecatedEdgeType,\n validateEdgeLayers,\n} from \"./epistemicHelpers\";\nimport { checkProjectAccess } from \"@lucern/access-control/access\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\n\n// =============================================================================\n// EDGE TYPE MAPPINGS\n// =============================================================================\n\n/**\n * Map frontend relation types to Convex edge types\n */\nconst RELATION_TO_EDGE_TYPE: Record<string, string> = {\n // Cross-type: Evidence → Belief\n supports: \"informs\", // with weight > 0\n contradicts: \"informs\", // with weight < 0\n\n // Cross-type: Question → Belief\n tests: \"tests\",\n\n // Cross-type: Evidence → Question\n answers: \"derived_from\",\n partial: \"derived_from\", // with lower weight\n context: \"derived_from\", // with even lower weight\n\n // Same-type: Belief ↔ Belief\n depends_on: \"depends_on\",\n reinforces: \"supports\",\n parent: \"contains\",\n child: \"contains\",\n\n // Same-type: Question ↔ Question\n prerequisite: \"prerequisite_for\",\n parallel: \"parallel_to\",\n\n // Same-type: Evidence ↔ Evidence\n corroborates: \"corroborates\",\n extends: \"extends\",\n same_source: \"same_source_as\",\n same_theme: \"same_theme_as\",\n\n // Generic\n adjacent: \"related_to\",\n related: \"related_to\",\n informs: \"informs\",\n};\n\n/**\n * Calculate edge weight based on relation type\n */\nfunction getEdgeWeight(relation: string): number {\n switch (relation) {\n case \"supports\":\n case \"corroborates\":\n return 0.7;\n case \"contradicts\":\n return -0.7;\n case \"qualifies\":\n case \"partial\":\n return 0.4;\n case \"context\":\n case \"adjacent\":\n return 0.2;\n case \"depends_on\":\n case \"parent\":\n case \"prerequisite\":\n return 0.8;\n case \"child\":\n return 0.6;\n case \"parallel\":\n case \"extends\":\n case \"same_theme\":\n case \"same_source\":\n return 0.5;\n default:\n return 0.5;\n }\n}\n\nfunction buildDeterministicEdgeGlobalId(\n fromGlobalId: string,\n toGlobalId: string,\n edgeType: string\n): string {\n return `edge_link_${edgeType}_${fromGlobalId}_${toGlobalId}`;\n}\n\n// =============================================================================\n// BELIEF-BELIEF LINKING\n// =============================================================================\n\n/**\n * Link two beliefs with a semantic relationship\n */\nexport const linkBeliefToBelief = mutation({\n args: {\n fromBeliefId: v.id(\"epistemicNodes\"),\n toBeliefId: v.id(\"epistemicNodes\"),\n relation: v.string(), // \"depends_on\" | \"supports\" | \"contains\" | \"contradicts\" | \"adjacent\"\n userId: v.string(),\n rationale: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx, args) => {\n const fromBelief = await ctx.db.get(args.fromBeliefId);\n const toBelief = await ctx.db.get(args.toBeliefId);\n\n if (\n !fromBelief ||\n !toBelief ||\n fromBelief.nodeType !== \"belief\" ||\n toBelief.nodeType !== \"belief\"\n ) {\n throw new Error(\"One or both beliefs not found\");\n }\n\n // Verify project access\n if (fromBelief.projectId) {\n const hasAccess = await checkProjectAccess(\n ctx,\n fromBelief.projectId,\n args.userId\n );\n if (!hasAccess) {\n throw new Error(\"No permission to link these beliefs\");\n }\n }\n\n const fromNode = fromBelief;\n const toNode = toBelief;\n\n if (fromNode && toNode) {\n // Create epistemic edge\n const edgeType = RELATION_TO_EDGE_TYPE[args.relation] || \"related_to\";\n const weight = getEdgeWeight(args.relation);\n\n // Phase 2C: Get layers and validate\n const fromLayer =\n fromNode.epistemicLayer || getNodeLayer(fromNode.nodeType);\n const toLayer = toNode.epistemicLayer || getNodeLayer(toNode.nodeType);\n\n const validation = validateEdgeLayers(edgeType, fromLayer, toLayer);\n if (!validation.valid) {\n console.warn(\n `[EpistemicLinking] Invalid edge blocked: ${validation.reason}`\n );\n // Don't throw - just skip creating invalid edge to avoid breaking UI\n } else if (isDeprecatedEdgeType(edgeType)) {\n // Block removed edge types\n console.error(\n `[EpistemicLinking] FORBIDDEN edge type '${edgeType}' blocked. Use compliant edge types.`\n );\n // Skip creating - don't break UI\n } else {\n // Deterministic IDs make Neo4j MERGE idempotent without relying on Convex mirrors.\n const edgeGlobalId = buildDeterministicEdgeGlobalId(\n fromNode.globalId,\n toNode.globalId,\n edgeType\n );\n\n // Phase 1 (Graph Architecture): Write to Neo4j directly\n await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {\n globalId: edgeGlobalId,\n fromGlobalId: fromNode.globalId,\n toGlobalId: toNode.globalId,\n edgeType: edgeType as\n | \"depends_on\"\n | \"supports\"\n | \"contains\"\n | \"informs\"\n | \"derived_from\"\n | \"tests\",\n weight,\n context: args.rationale || `Linked as ${args.relation}`,\n topicId: fromBelief.projectId\n ? String(fromBelief.projectId)\n : undefined,\n createdBy: args.userId,\n fromNodeType: \"belief\",\n toNodeType: \"belief\",\n fromLayer,\n toLayer,\n });\n }\n }\n\n return { success: true };\n },\n});\n\n// =============================================================================\n// QUESTION-QUESTION LINKING\n// =============================================================================\n\n/**\n * ⛔ DEPRECATED: Question-to-question linking is disabled.\n *\n * Raw questions are excluded from the graph visualization once key questions exist,\n * so question-to-question edges create unnecessary noise without providing value.\n *\n * This mutation now returns success without creating edges for backwards compatibility.\n */\nexport const linkQuestionToQuestion = mutation({\n args: {\n fromQuestionId: v.id(\"epistemicNodes\"),\n toQuestionId: v.id(\"epistemicNodes\"),\n relation: v.string(), // \"parent\" | \"child\" | \"prerequisite\" | \"parallel\" | \"contradicts\" | \"adjacent\"\n userId: v.string(),\n rationale: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (_ctx, _args) => {\n // ⛔ Question-to-question edges are no longer created.\n // Raw questions are excluded from the graph once key questions exist.\n console.log(\n \"[EpistemicLinking] Question-to-question linking is deprecated and disabled.\"\n );\n return { success: true, deprecated: true };\n },\n});\n\n// =============================================================================\n// EVIDENCE-EVIDENCE LINKING\n// =============================================================================\n\n/**\n * Link two pieces of evidence with a semantic relationship\n */\nexport const linkEvidenceToEvidence = mutation({\n args: {\n fromInsightId: v.id(\"epistemicNodes\"),\n toInsightId: v.id(\"epistemicNodes\"),\n relation: v.string(), // \"corroborates\" | \"contradicts\" | \"extends\" | \"same_source\" | \"same_theme\" | \"adjacent\"\n userId: v.string(),\n rationale: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx, args) => {\n const fromInsight = await ctx.db.get(args.fromInsightId);\n const toInsight = await ctx.db.get(args.toInsightId);\n\n if (!fromInsight || !toInsight) {\n throw new Error(\"One or both insights not found\");\n }\n\n // Verify project access\n if (fromInsight.projectId) {\n const hasAccess = await checkProjectAccess(\n ctx,\n fromInsight.projectId,\n args.userId\n );\n if (!hasAccess) {\n throw new Error(\"No permission to link these evidence items\");\n }\n }\n\n const fromNode =\n fromInsight.nodeType === \"evidence\" ? (fromInsight as any) : null;\n const toNode =\n toInsight.nodeType === \"evidence\" ? (toInsight as any) : null;\n\n if (fromNode && toNode) {\n const edgeType = RELATION_TO_EDGE_TYPE[args.relation] || \"related_to\";\n const weight = getEdgeWeight(args.relation);\n\n // Phase 2C: Get layers and validate\n const fromLayer =\n fromNode.epistemicLayer || getNodeLayer(fromNode.nodeType);\n const toLayer = toNode.epistemicLayer || getNodeLayer(toNode.nodeType);\n\n const validation = validateEdgeLayers(edgeType, fromLayer, toLayer);\n if (!validation.valid) {\n console.warn(\n `[EpistemicLinking] Invalid edge blocked: ${validation.reason}`\n );\n } else if (isDeprecatedEdgeType(edgeType)) {\n console.error(\n `[EpistemicLinking] FORBIDDEN edge type '${edgeType}' blocked. Use compliant edge types.`\n );\n } else {\n const edgeGlobalId = buildDeterministicEdgeGlobalId(\n fromNode.globalId,\n toNode.globalId,\n edgeType\n );\n\n // Phase 1 (Graph Architecture): Write to Neo4j directly\n await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {\n globalId: edgeGlobalId,\n fromGlobalId: fromNode.globalId,\n toGlobalId: toNode.globalId,\n edgeType: edgeType as\n | \"corroborates\"\n | \"extends\"\n | \"same_source_as\"\n | \"same_theme_as\",\n weight,\n context: args.rationale || `Linked as ${args.relation}`,\n topicId: fromInsight.projectId\n ? String(fromInsight.projectId)\n : undefined,\n createdBy: args.userId,\n fromNodeType: \"evidence\",\n toNodeType: \"evidence\",\n fromLayer,\n toLayer,\n });\n }\n }\n\n return { success: true };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/convex.ts","../src/graphTypes.ts","../src/epistemicLayerRules.ts","../src/epistemicLinking.ts"],"names":[],"mappings":"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","file":"epistemicLinking.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * Graph Type Registry for Convex\n *\n * This file mirrors the canonical type registry at lib/ontology/types.ts\n * but is compatible with Convex's bundling requirements.\n *\n * IMPORTANT: Keep this file in sync with lib/ontology/types.ts\n * The frontend uses lib/ontology/types.ts, Convex uses this file.\n *\n * @see /docs/architecture/UNIFIED_GRAPH_ARCHITECTURE.md\n */\n\n// =============================================================================\n// EPISTEMIC LAYERS\n// =============================================================================\n\nexport type EpistemicLayer =\n | \"L4\"\n | \"L3\"\n | \"L2\"\n | \"L1\"\n | \"ontological\"\n | \"organizational\";\n\n// =============================================================================\n// NODE TYPE TO LABEL MAPPING\n// =============================================================================\n\nexport const NODE_TYPE_TO_LABEL: Record<string, string> = {\n // L4: Audit Targets\n decision: \"Decision\",\n\n // L3: Traversal Anchors\n belief: \"Belief\",\n question: \"Question\",\n theme: \"Theme\",\n deal: \"Deal\",\n topic: \"Topic\",\n\n // L2: Compression Boundary\n claim: \"Claim\",\n evidence: \"Evidence\",\n synthesis: \"Synthesis\",\n answer: \"Answer\",\n\n // L1: Terminal Leaves\n atomic_fact: \"AtomicFact\",\n excerpt: \"Excerpt\",\n source: \"Source\",\n\n // Ontological (Neo4j is SOT)\n company: \"Company\",\n person: \"Person\",\n investor: \"Investor\",\n function: \"Function\",\n value_chain: \"ValueChain\",\n};\n\n// =============================================================================\n// EDGE TYPE TO NEO4J RELATIONSHIP MAPPING\n// =============================================================================\n\n/**\n * Epistemic Kernel v2: 6 canonical edge types + ontological edges.\n *\n * Weight and metadata carry nuance that previously required 67 separate type strings.\n * See: docs/architecture/epistemic-kernel-v2.md\n */\nexport const EDGE_TYPE_TO_REL: Record<string, string> = {\n // === THE SIX CANONICAL EPISTEMIC EDGE TYPES ===\n supports: \"SUPPORTS\", // L3↔L3: belief bears on belief (weight -1 to +1)\n informs: \"INFORMS\", // L2→L3: evidence bears on belief\n depends_on: \"DEPENDS_ON\", // L3→L3, Q→Q: structural gate\n derived_from: \"DERIVED_FROM\", // Any→Any: provenance chain (fork, synthesis, extraction, answer)\n contains: \"CONTAINS\", // Any→Any: hierarchy, scoping, membership\n tests: \"TESTS\", // Q→L3: question interrogates belief\n\n // === L4 DECISION EDGES (derived_from with derivationType=decision) ===\n // Kept as separate Neo4j relationship types for backward compat with L4 queries.\n // New code should use derived_from + metadata.\n based_on_belief: \"BASED_ON_BELIEF\",\n based_on_question: \"BASED_ON_QUESTION\",\n blocked_by_contradiction: \"BLOCKED_BY_CONTRADICTION\",\n informed_by_theme: \"INFORMED_BY_THEME\",\n\n // === ONTOLOGICAL EDGES (tenant-extensible, managed by ontology system) ===\n works_at: \"WORKS_AT\",\n invested_in: \"INVESTED_IN\",\n competes_with: \"COMPETES_WITH\",\n participates_in: \"PARTICIPATES_IN\",\n founded_by: \"FOUNDED_BY\",\n evaluates: \"EVALUATES\",\n performs: \"PERFORMS\",\n function_in: \"FUNCTION_IN\",\n impacts: \"IMPACTS\",\n raised_from: \"RAISED_FROM\",\n mentioned_in: \"MENTIONED_IN\",\n perspective_on: \"PERSPECTIVE_ON\",\n about_entity: \"ABOUT_ENTITY\",\n entity_referenced_in: \"ENTITY_REFERENCED_IN\",\n};\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Get the epistemic layer for a node type\n */\nexport function getNodeLayer(nodeType: string): EpistemicLayer {\n const L4_TYPES = [\"decision\"];\n const L3_TYPES = [\"belief\", \"question\", \"theme\", \"deal\"];\n const L2_TYPES = [\"claim\", \"evidence\", \"synthesis\", \"answer\"];\n const L1_TYPES = [\"atomic_fact\", \"excerpt\", \"source\"];\n const ONTOLOGICAL_TYPES = [\n \"company\",\n \"person\",\n \"investor\",\n \"function\",\n \"value_chain\",\n ];\n const ORGANIZATIONAL_TYPES = [\"topic\"];\n\n if (L4_TYPES.includes(nodeType)) {\n return \"L4\";\n }\n if (L3_TYPES.includes(nodeType)) {\n return \"L3\";\n }\n if (L2_TYPES.includes(nodeType)) {\n return \"L2\";\n }\n if (L1_TYPES.includes(nodeType)) {\n return \"L1\";\n }\n if (ONTOLOGICAL_TYPES.includes(nodeType)) {\n return \"ontological\";\n }\n if (ORGANIZATIONAL_TYPES.includes(nodeType)) {\n return \"organizational\";\n }\n\n // Unknown types default to L2\n console.warn(`[GraphTypes] Unknown nodeType \"${nodeType}\", defaulting to L2`);\n return \"L2\";\n}\n\n/**\n * Get the Neo4j label for a node type\n */\nexport function getNeo4jLabel(nodeType: string): string {\n return (\n NODE_TYPE_TO_LABEL[nodeType] ||\n nodeType.charAt(0).toUpperCase() + nodeType.slice(1)\n );\n}\n\n/**\n * Get the Neo4j relationship type for an edge type\n */\nexport function getNeo4jRelType(edgeType: string): string {\n return EDGE_TYPE_TO_REL[edgeType] || edgeType.toUpperCase();\n}\n\n/**\n * The 6 canonical epistemic edge types (Kernel v2).\n * Anything not in this set or the ontological/L4 sets is deprecated.\n */\nconst CANONICAL_EPISTEMIC_TYPES = new Set([\n \"supports\",\n \"informs\",\n \"depends_on\",\n \"derived_from\",\n \"contains\",\n \"tests\",\n]);\n\n/**\n * Check if an edge type is deprecated.\n *\n * Kernel v2: only the 6 canonical epistemic types, L4 decision types,\n * and ontological types are active. All legacy types (67 old types) are deprecated.\n */\nexport function isDeprecatedEdgeType(edgeType: string): boolean {\n // Canonical epistemic types are NOT deprecated\n if (CANONICAL_EPISTEMIC_TYPES.has(edgeType)) return false;\n // Types in the EDGE_TYPE_TO_REL map (ontological + L4) are NOT deprecated\n if (edgeType in EDGE_TYPE_TO_REL) return false;\n // Everything else is a legacy type\n return true;\n}\n","/**\n * Epistemic Spine helper module split from epistemicHelpers.ts.\n */\n\nimport type { Id } from \"./convex\";\n\n// =============================================================================\n// TYPE MAPPINGS\n// =============================================================================\n\ntype EpistemicNodeType =\n // L4: Audit targets\n | \"decision\"\n // L3: Traversal anchors\n | \"belief\"\n | \"question\"\n | \"theme\"\n | \"deal\"\n // L2: Compression boundary\n | \"claim\"\n | \"evidence\"\n | \"synthesis\"\n | \"answer\"\n // L1: Terminal leaves\n | \"atomic_fact\"\n | \"excerpt\"\n | \"source\";\n\ntype OntologicalNodeType =\n | \"company\"\n | \"person\"\n | \"investor\"\n | \"function\"\n | \"value_chain\";\n\ntype NodeType = EpistemicNodeType | OntologicalNodeType;\n\n// =============================================================================\n// EPISTEMIC LAYER ARCHITECTURE (Lucern Invariant Compliance)\n// =============================================================================\n\n/**\n * Epistemic Layer - governs traversal rules\n * L4 → L3 → L2 → L1 (never skip layers)\n */\nexport type EpistemicLayer =\n | \"L4\"\n | \"L3\"\n | \"L2\"\n | \"L1\"\n | \"ontological\"\n | \"organizational\";\n\n/**\n * Map nodeType to its epistemic layer\n *\n * Layer semantics:\n * - L4: Audit targets (decisions, outcomes) - what we committed to\n * - L3: Traversal anchors (beliefs, questions, themes) - epistemic structure\n * - L2: Compression boundary (claims, evidence, synthesis) - minimum reasoning unit\n * - L1: Terminal leaves (atomic_fact, excerpt, source) - non-traversable grounding\n * - ontological: Entities in the world (companies, people) - not epistemic\n * - organizational: Structural containers (topics, lenses, worktrees) - not epistemic\n */\nexport function getNodeLayer(nodeType: string): EpistemicLayer {\n switch (nodeType) {\n // L4: Audit targets\n case \"decision\":\n return \"L4\";\n\n // L3: Traversal anchors\n case \"belief\":\n case \"question\":\n case \"theme\":\n case \"deal\":\n return \"L3\";\n\n // L2: Compression boundary\n case \"claim\":\n case \"evidence\":\n case \"synthesis\":\n case \"answer\":\n return \"L2\";\n\n // L1: Terminal leaves\n case \"atomic_fact\":\n case \"excerpt\":\n case \"source\":\n return \"L1\";\n\n // Ontological entities\n case \"company\":\n case \"person\":\n case \"investor\":\n case \"function\":\n case \"value_chain\":\n return \"ontological\";\n\n // Organizational containers\n case \"topic\":\n return \"organizational\";\n\n default:\n // Unknown types default to L2 (safest for traversal)\n console.warn(\n `[EpistemicLayer] Unknown nodeType: ${nodeType}, defaulting to L2`\n );\n return \"L2\";\n }\n}\n\n/**\n * Layer traversal rules\n * Key constraint: Cannot skip layers during traversal\n */\nexport const LAYER_TRAVERSAL_RULES = {\n L4: {\n canReach: [\"L3\", \"L4\"], // Decisions can reach beliefs/questions\n mustPassThrough: \"L3\", // Must go through L3 to reach L2\n },\n L3: {\n canReach: [\"L2\", \"L3\", \"L4\"], // Beliefs can reach evidence, other beliefs, or decisions\n mustPassThrough: \"L2\", // Must go through L2 to reach L1\n },\n L2: {\n canReach: [\"L1\", \"L2\", \"L3\"], // Evidence can reach sources, other evidence, or beliefs\n mustPassThrough: null, // L2 can reach L1 directly\n },\n L1: {\n canReach: [\"L1\"], // Sources can only reach other sources\n mustPassThrough: null, // Terminal - no traversal beyond\n },\n ontological: {\n canReach: [\"L3\", \"L2\", \"ontological\"], // Entities can link to epistemic structure\n mustPassThrough: null, // No layer constraints for entities\n },\n organizational: {\n canReach: [\"L3\", \"L2\", \"organizational\"], // Containers scope epistemic structure + nest\n mustPassThrough: null, // No layer constraints for containers\n },\n} as const;\n\n/**\n * Check if a direct edge between two layers is allowed\n */\nexport function isValidLayerConnection(\n fromLayer: EpistemicLayer,\n toLayer: EpistemicLayer\n): boolean {\n const rules = LAYER_TRAVERSAL_RULES[fromLayer];\n return (rules.canReach as readonly string[]).includes(toLayer);\n}\n\n/**\n * Get layer hierarchy number (for comparison)\n * Higher number = higher layer\n */\nexport function getLayerDepth(layer: EpistemicLayer): number {\n switch (layer) {\n case \"L4\":\n return 4;\n case \"L3\":\n return 3;\n case \"L2\":\n return 2;\n case \"L1\":\n return 1;\n case \"ontological\":\n return 0; // Ontological exists outside the epistemic hierarchy\n case \"organizational\":\n return 0; // Organizational exists outside the epistemic hierarchy\n default:\n return 2;\n }\n}\n\n/**\n * Check if we can traverse from one layer to another\n * (considering intermediate layers)\n */\nexport function canTraverseToLayer(\n fromLayer: EpistemicLayer,\n toLayer: EpistemicLayer\n): boolean {\n const fromDepth = getLayerDepth(fromLayer);\n const toDepth = getLayerDepth(toLayer);\n\n // Ontological/organizational layers are special - use explicit rules\n if (\n fromLayer === \"ontological\" ||\n toLayer === \"ontological\" ||\n fromLayer === \"organizational\" ||\n toLayer === \"organizational\"\n ) {\n return isValidLayerConnection(fromLayer, toLayer);\n }\n\n // Can always stay at same layer\n if (fromDepth === toDepth) {\n return true;\n }\n\n // Can go up (L1→L2→L3→L4) or down (L4→L3→L2→L1)\n // But must respect layer rules\n return isValidLayerConnection(fromLayer, toLayer);\n}\n\n// =============================================================================\n// PHASE 2D: LAYER-AWARE TRAVERSAL\n// =============================================================================\n\n/**\n * Traversal mode - determines how to traverse the graph\n *\n * anchor_down: Start at L3 belief, traverse to L2 evidence, stop at L1 sources\n * anchor_up: Start at L2 evidence, traverse to L3 beliefs it supports\n * same_layer: Traverse within a single layer (e.g., belief → belief)\n * decision_trace: Start at L4 decision, traverse to L3 beliefs it was based on\n */\nexport type TraversalMode =\n | \"anchor_down\"\n | \"anchor_up\"\n | \"same_layer\"\n | \"decision_trace\";\n\n/**\n * Traversal options for layer-aware queries\n */\nexport type TraversalOptions = {\n /** Starting node ID */\n startNodeId: Id<\"epistemicNodes\">;\n /** Traversal mode */\n mode: TraversalMode;\n /** Edge types to follow (empty = all valid for mode) */\n allowedEdgeTypes?: string[];\n /** Maximum depth */\n maxDepth?: number;\n /** Minimum layer to stop at (L1 = 1, L4 = 4) */\n minLayer?: number;\n /** Maximum layer to reach */\n maxLayer?: number;\n};\n\n/**\n * Check if traversal should continue based on layer constraints\n */\nexport function shouldContinueTraversal(\n currentLayer: EpistemicLayer,\n targetLayer: EpistemicLayer,\n options: {\n mode: TraversalMode;\n minLayer?: number;\n maxLayer?: number;\n }\n): boolean {\n const currentDepth = getLayerDepth(currentLayer);\n const targetDepth = getLayerDepth(targetLayer);\n\n // Check min/max layer constraints\n if (options.minLayer !== undefined && targetDepth < options.minLayer) {\n return false; // Would go below minimum layer\n }\n if (options.maxLayer !== undefined && targetDepth > options.maxLayer) {\n return false; // Would go above maximum layer\n }\n\n // Mode-specific rules\n switch (options.mode) {\n case \"anchor_down\":\n // Can only go down (L4→L3→L2→L1)\n return targetDepth < currentDepth || targetDepth === currentDepth;\n\n case \"anchor_up\":\n // Can only go up (L1→L2→L3→L4)\n return targetDepth > currentDepth || targetDepth === currentDepth;\n\n case \"same_layer\":\n // Must stay at same layer\n return targetDepth === currentDepth;\n\n case \"decision_trace\":\n // Decisions (L4) can trace to beliefs (L3), stop there\n return currentDepth === 4\n ? targetDepth === 3\n : targetDepth === currentDepth;\n\n default:\n return true;\n }\n}\n\n/**\n * Get default minLayer for a traversal mode\n */\nexport function getDefaultMinLayer(mode: TraversalMode): number {\n switch (mode) {\n case \"anchor_down\":\n return 1; // Can go all the way to L1 sources\n case \"anchor_up\":\n return 2; // Start at L2 evidence minimum\n case \"same_layer\":\n return 1; // No constraint\n case \"decision_trace\":\n return 3; // Stop at L3 beliefs (don't go to L2 evidence)\n default:\n return 1;\n }\n}\n\n/**\n * Get allowed edge types for a traversal mode\n */\nexport function getDefaultEdgeTypesForMode(mode: TraversalMode): string[] {\n switch (mode) {\n case \"anchor_down\":\n // From beliefs/questions down to evidence and sources\n return [\n \"informs\", // evidence → belief (traverse backwards)\n \"derived_from\", // evidence → source (provenance) + evidence → question\n ];\n case \"anchor_up\":\n // From evidence up to beliefs\n return [\"informs\", \"derived_from\"];\n case \"same_layer\":\n // Within-layer relationships\n return [\n // L3: Belief ↔ Belief\n \"depends_on\",\n \"supports\",\n \"contains\",\n // L3: Question ↔ Question\n \"prerequisite_for\",\n \"parallel_to\",\n // L2: Evidence ↔ Evidence\n \"corroborates\",\n \"extends\",\n \"same_source_as\",\n \"same_theme_as\",\n ];\n case \"decision_trace\":\n // From decisions to beliefs\n return [\n \"derived_from\",\n \"depends_on\",\n \"contains\",\n ];\n default:\n return [];\n }\n}\n\n// =============================================================================\n// PHASE 2C: EDGE LAYER RULES\n// =============================================================================\n\n/**\n * Edge Layer Rules - defines valid layer combinations for each edge type\n *\n * Format: { from: [allowed source layers], to: [allowed target layers] }\n *\n * Key rules:\n * - L4 edges: Decision → L3 (beliefs, questions, themes)\n * - Cross-layer edges: L2 → L3 (evidence informs beliefs)\n * - Same-layer edges: L3 → L3, L2 → L2 (beliefs depend on beliefs)\n * - Downward edges: L2 → L1 (evidence extracted from source)\n * - Lifecycle edges: same layer only (supersedes)\n */\nexport const EDGE_LAYER_RULES: Record<\n string,\n { from: EpistemicLayer[]; to: EpistemicLayer[]; description: string }\n> = {\n // === L4 Decision Edges ===\n based_on_belief: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Belief (L4 → L3)\",\n },\n based_on_question: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Question (L4 → L3)\",\n },\n blocked_by_contradiction: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Contradiction (L4 → L3)\",\n },\n informed_by_theme: {\n from: [\"L4\"],\n to: [\"L3\"],\n description: \"Decision → Theme (L4 → L3)\",\n },\n\n // === Evidence Flow (L2 → L3, L2 → L1) ===\n derived_from: {\n from: [\"L2\", \"L3\", \"L4\"],\n to: [\"L1\", \"L2\", \"L3\"],\n description: \"A was produced from B (provenance chain)\",\n },\n answers: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Evidence → Question (L2 → L3)\",\n },\n responds_to: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Answer → Question (L2 → L3)\",\n },\n informs: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Evidence → Belief (L2 → L3)\",\n },\n qualifies: {\n from: [\"L2\"],\n to: [\"L3\"],\n description: \"Evidence → Belief (L2 → L3)\",\n },\n\n // === Question → Belief (L3 → L3) ===\n tests: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Question → Belief (L3 → L3)\",\n },\n explores: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Question → Belief assumption (L3 → L3)\",\n },\n\n // === Synthesis (L2 → L2, L2 → L1) ===\n based_on: {\n from: [\"L2\"],\n to: [\"L2\", \"L1\"],\n description: \"Synthesis → Evidence/Source (L2 → L2/L1)\",\n },\n\n // === Theme Relationships (L3 → L3) ===\n relates_to_thesis: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Belief → Theme (L3 → L3)\",\n },\n belongs_to: {\n from: [\"L3\", \"L2\"], // Can belong to theme from L3 or L2\n to: [\"L3\"],\n description: \"Any → Theme (L3/L2 → L3)\",\n },\n plays_theme: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Deal → Theme (L3 → L3)\",\n },\n\n // === Topic Hierarchy (L3 → organizational) ===\n scoped_by: {\n from: [\"L3\"],\n to: [\"organizational\"],\n description: \"Belief/Question → Topic (L3 → organizational)\",\n },\n\n // === Deal/Company ===\n evaluates: {\n from: [\"L3\"],\n to: [\"ontological\"],\n description: \"Deal → Company (L3 → ontological)\",\n },\n\n // === People (ontological → ontological, ontological → L3) ===\n perspective_on: {\n from: [\"ontological\"],\n to: [\"L3\"],\n description: \"Person → Belief/Theme (ontological → L3)\",\n },\n works_at: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Person → Company (ontological → ontological)\",\n },\n\n // === Value Chain (ontological) ===\n participates_in: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → ValueChain (ontological → ontological)\",\n },\n performs: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Function (ontological → ontological)\",\n },\n function_in: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Function → ValueChain (ontological → ontological)\",\n },\n impacts: {\n from: [\"L3\"],\n to: [\"ontological\"],\n description: \"Theme → ValueChain (L3 → ontological)\",\n },\n\n // === Investment (ontological) ===\n invested_in: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Investor → Company (ontological → ontological)\",\n },\n raised_from: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Investor (ontological → ontological)\",\n },\n\n // === Entity↔Belief Bridge (OE-B) ===\n about_entity: {\n from: [\"L3\"],\n to: [\"ontological\"],\n description: \"Belief/Question/Theme → Entity (L3 → ontological)\",\n },\n entity_referenced_in: {\n from: [\"ontological\"],\n to: [\"L2\"],\n description: \"Entity → Evidence (ontological → L2)\",\n },\n mentioned_in: {\n from: [\"ontological\"],\n to: [\"L1\"],\n description: \"Entity → Source document (ontological → L1)\",\n },\n founded_by: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Person (ontological → ontological)\",\n },\n competes_with: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"Company → Company (ontological → ontological)\",\n },\n contains: {\n from: [\"ontological\"],\n to: [\"ontological\"],\n description: \"ValueChain → Function (ontological → ontological)\",\n },\n\n // === Lifecycle (same layer only) ===\n supersedes: {\n from: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n to: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n description: \"NewNode → OldNode (same layer only - validated separately)\",\n },\n same_as: {\n from: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n to: [\"L4\", \"L3\", \"L2\", \"L1\", \"ontological\", \"organizational\"],\n description: \"Duplicate detection (same layer only - validated separately)\",\n },\n\n // === Same-Type: Belief ↔ Belief (L3 → L3) ===\n depends_on: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Belief B requires Belief A (L3 → L3)\",\n },\n reinforces: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Beliefs strengthen each other (L3 → L3)\",\n },\n parent_of: {\n from: [\"L3\", \"organizational\"],\n to: [\"L3\", \"organizational\"],\n description:\n \"A is higher-level than B (L3 → L3, organizational → organizational)\",\n },\n child_of: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Belief A is more specific (L3 → L3)\",\n },\n\n // === Same-Type: Question ↔ Question (L3 → L3) ===\n prerequisite_for: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Question A must be answered first (L3 → L3)\",\n },\n parallel_to: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Same topic, different angles (L3 → L3)\",\n },\n\n // === Same-Type: Evidence ↔ Evidence (L2 → L2) ===\n corroborates: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Independent support (L2 → L2)\",\n },\n extends: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Adds depth (L2 → L2)\",\n },\n same_source_as: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Same document/study (L2 → L2)\",\n },\n same_theme_as: {\n from: [\"L2\"],\n to: [\"L2\"],\n description: \"Same topic/entity (L2 → L2)\",\n },\n\n // === NEW: Deep Epistemic Analysis Edges (Phase: Schema Upgrade) ===\n assumes: {\n from: [\"L3\"],\n to: [\"L3\"],\n description:\n \"Hidden dependency - Belief B implicitly assumes Belief A (L3 → L3)\",\n },\n would_predict: {\n from: [\"L3\"],\n to: [\"L2\"],\n description:\n \"Pre-registered prediction - If Belief true, expect Evidence (L3 → L2)\",\n },\n analogous_to: {\n from: [\"L3\"],\n to: [\"L3\"],\n description: \"Explicit analogy - Belief A is like Belief B (L3 → L3)\",\n },\n independent_of: {\n from: [\"L2\"],\n to: [\"L2\"],\n description:\n \"True evidence independence - Evidence A independent of B (L2 → L2)\",\n },\n\n // NOTE: Deprecated edge types (supports, contradicts, derived_from, cites,\n // summarizes, related_to, partially_answers, blocks, refines, branches_from)\n // have been REMOVED from the system. Use compliant alternatives instead.\n};\n\n/**\n * Validate an edge against layer rules\n *\n * Returns { valid: true } or { valid: false, reason: string }\n */\nexport function validateEdgeLayers(\n edgeType: string,\n fromLayer: EpistemicLayer,\n toLayer: EpistemicLayer\n): { valid: boolean; reason?: string } {\n const rules = EDGE_LAYER_RULES[edgeType];\n\n // Unknown edge type - allow but warn\n if (!rules) {\n console.warn(\n `[EdgeValidation] Unknown edge type: ${edgeType}, allowing by default`\n );\n return { valid: true };\n }\n\n // Special handling for same-layer edges (supersedes)\n if (edgeType === \"supersedes\") {\n if (fromLayer !== toLayer) {\n return {\n valid: false,\n reason: `${edgeType} edges must be between nodes of the same layer. Got ${fromLayer} → ${toLayer}`,\n };\n }\n return { valid: true };\n }\n\n // Check from layer\n if (!rules.from.includes(fromLayer)) {\n return {\n valid: false,\n reason: `Edge type '${edgeType}' does not allow source layer ${fromLayer}. Allowed: ${rules.from.join(\", \")}`,\n };\n }\n\n // Check to layer\n if (!rules.to.includes(toLayer)) {\n return {\n valid: false,\n reason: `Edge type '${edgeType}' does not allow target layer ${toLayer}. Allowed: ${rules.to.join(\", \")}`,\n };\n }\n\n return { valid: true };\n}\n\n","/**\n * Epistemic Linking Mutations\n *\n * Creates proper edges in the epistemic graph when linking entities.\n * These mutations are called by the SuggestedMatches component when\n * a user links items from AI-suggested matches.\n *\n * @see /docs/architecture/EPISTEMIC_SPINE.md\n */\n\nimport { v } from \"convex/values\";\nimport { internal } from \"./convex\";\nimport { mutation } from \"./convex\";\nimport {\n getNodeLayer,\n isDeprecatedEdgeType,\n validateEdgeLayers,\n} from \"./epistemicHelpers\";\nimport { checkProjectAccess } from \"@lucern/access-control/access\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\n\n// =============================================================================\n// EDGE TYPE MAPPINGS\n// =============================================================================\n\n/**\n * Map frontend relation types to Convex edge types\n */\nconst RELATION_TO_EDGE_TYPE: Record<string, string> = {\n // Cross-type: Evidence → Belief\n supports: \"informs\", // with weight > 0\n contradicts: \"informs\", // with weight < 0\n\n // Cross-type: Question → Belief\n tests: \"tests\",\n\n // Cross-type: Evidence → Question\n answers: \"derived_from\",\n partial: \"derived_from\", // with lower weight\n context: \"derived_from\", // with even lower weight\n\n // Same-type: Belief ↔ Belief\n depends_on: \"depends_on\",\n reinforces: \"supports\",\n parent: \"contains\",\n child: \"contains\",\n\n // Same-type: Question ↔ Question\n prerequisite: \"prerequisite_for\",\n parallel: \"parallel_to\",\n\n // Same-type: Evidence ↔ Evidence\n corroborates: \"corroborates\",\n extends: \"extends\",\n same_source: \"same_source_as\",\n same_theme: \"same_theme_as\",\n\n // Generic\n adjacent: \"related_to\",\n related: \"related_to\",\n informs: \"informs\",\n};\n\n/**\n * Calculate edge weight based on relation type\n */\nfunction getEdgeWeight(relation: string): number {\n switch (relation) {\n case \"supports\":\n case \"corroborates\":\n return 0.7;\n case \"contradicts\":\n return -0.7;\n case \"qualifies\":\n case \"partial\":\n return 0.4;\n case \"context\":\n case \"adjacent\":\n return 0.2;\n case \"depends_on\":\n case \"parent\":\n case \"prerequisite\":\n return 0.8;\n case \"child\":\n return 0.6;\n case \"parallel\":\n case \"extends\":\n case \"same_theme\":\n case \"same_source\":\n return 0.5;\n default:\n return 0.5;\n }\n}\n\nfunction buildDeterministicEdgeGlobalId(\n fromGlobalId: string,\n toGlobalId: string,\n edgeType: string\n): string {\n return `edge_link_${edgeType}_${fromGlobalId}_${toGlobalId}`;\n}\n\n// =============================================================================\n// BELIEF-BELIEF LINKING\n// =============================================================================\n\n/**\n * Link two beliefs with a semantic relationship\n */\nexport const linkBeliefToBelief = mutation({\n args: {\n fromBeliefId: v.id(\"epistemicNodes\"),\n toBeliefId: v.id(\"epistemicNodes\"),\n relation: v.string(), // \"depends_on\" | \"supports\" | \"contains\" | \"contradicts\" | \"adjacent\"\n userId: v.string(),\n rationale: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx, args) => {\n const fromBelief = await ctx.db.get(args.fromBeliefId);\n const toBelief = await ctx.db.get(args.toBeliefId);\n\n if (\n !fromBelief ||\n !toBelief ||\n fromBelief.nodeType !== \"belief\" ||\n toBelief.nodeType !== \"belief\"\n ) {\n throw new Error(\"One or both beliefs not found\");\n }\n\n // Verify project access\n if (fromBelief.projectId) {\n const hasAccess = await checkProjectAccess(\n ctx,\n fromBelief.projectId,\n args.userId\n );\n if (!hasAccess) {\n throw new Error(\"No permission to link these beliefs\");\n }\n }\n\n const fromNode = fromBelief;\n const toNode = toBelief;\n\n if (fromNode && toNode) {\n // Create epistemic edge\n const edgeType = RELATION_TO_EDGE_TYPE[args.relation] || \"related_to\";\n const weight = getEdgeWeight(args.relation);\n\n // Phase 2C: Get layers and validate\n const fromLayer =\n fromNode.epistemicLayer || getNodeLayer(fromNode.nodeType);\n const toLayer = toNode.epistemicLayer || getNodeLayer(toNode.nodeType);\n\n const validation = validateEdgeLayers(edgeType, fromLayer, toLayer);\n if (!validation.valid) {\n console.warn(\n `[EpistemicLinking] Invalid edge blocked: ${validation.reason}`\n );\n // Don't throw - just skip creating invalid edge to avoid breaking UI\n } else if (isDeprecatedEdgeType(edgeType)) {\n // Block removed edge types\n console.error(\n `[EpistemicLinking] FORBIDDEN edge type '${edgeType}' blocked. Use compliant edge types.`\n );\n // Skip creating - don't break UI\n } else {\n // Deterministic IDs make Neo4j MERGE idempotent without relying on Convex mirrors.\n const edgeGlobalId = buildDeterministicEdgeGlobalId(\n fromNode.globalId,\n toNode.globalId,\n edgeType\n );\n\n // Phase 1 (Graph Architecture): Write to Neo4j directly\n await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {\n globalId: edgeGlobalId,\n fromGlobalId: fromNode.globalId,\n toGlobalId: toNode.globalId,\n edgeType: edgeType as\n | \"depends_on\"\n | \"supports\"\n | \"contains\"\n | \"informs\"\n | \"derived_from\"\n | \"tests\",\n weight,\n context: args.rationale || `Linked as ${args.relation}`,\n topicId: fromBelief.projectId\n ? String(fromBelief.projectId)\n : undefined,\n createdBy: args.userId,\n fromNodeType: \"belief\",\n toNodeType: \"belief\",\n fromLayer,\n toLayer,\n });\n }\n }\n\n return { success: true };\n },\n});\n\n// =============================================================================\n// QUESTION-QUESTION LINKING\n// =============================================================================\n\n/**\n * ⛔ DEPRECATED: Question-to-question linking is disabled.\n *\n * Raw questions are excluded from the graph visualization once key questions exist,\n * so question-to-question edges create unnecessary noise without providing value.\n *\n * This mutation now returns success without creating edges for backwards compatibility.\n */\nexport const linkQuestionToQuestion = mutation({\n args: {\n fromQuestionId: v.id(\"epistemicNodes\"),\n toQuestionId: v.id(\"epistemicNodes\"),\n relation: v.string(), // \"parent\" | \"child\" | \"prerequisite\" | \"parallel\" | \"contradicts\" | \"adjacent\"\n userId: v.string(),\n rationale: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (_ctx, _args) => {\n // ⛔ Question-to-question edges are no longer created.\n // Raw questions are excluded from the graph once key questions exist.\n console.log(\n \"[EpistemicLinking] Question-to-question linking is deprecated and disabled.\"\n );\n return { success: true, deprecated: true };\n },\n});\n\n// =============================================================================\n// EVIDENCE-EVIDENCE LINKING\n// =============================================================================\n\n/**\n * Link two pieces of evidence with a semantic relationship\n */\nexport const linkEvidenceToEvidence = mutation({\n args: {\n fromInsightId: v.id(\"epistemicNodes\"),\n toInsightId: v.id(\"epistemicNodes\"),\n relation: v.string(), // \"corroborates\" | \"contradicts\" | \"extends\" | \"same_source\" | \"same_theme\" | \"adjacent\"\n userId: v.string(),\n rationale: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx, args) => {\n const fromInsight = await ctx.db.get(args.fromInsightId);\n const toInsight = await ctx.db.get(args.toInsightId);\n\n if (!fromInsight || !toInsight) {\n throw new Error(\"One or both insights not found\");\n }\n\n // Verify project access\n if (fromInsight.projectId) {\n const hasAccess = await checkProjectAccess(\n ctx,\n fromInsight.projectId,\n args.userId\n );\n if (!hasAccess) {\n throw new Error(\"No permission to link these evidence items\");\n }\n }\n\n const fromNode =\n fromInsight.nodeType === \"evidence\" ? (fromInsight as any) : null;\n const toNode =\n toInsight.nodeType === \"evidence\" ? (toInsight as any) : null;\n\n if (fromNode && toNode) {\n const edgeType = RELATION_TO_EDGE_TYPE[args.relation] || \"related_to\";\n const weight = getEdgeWeight(args.relation);\n\n // Phase 2C: Get layers and validate\n const fromLayer =\n fromNode.epistemicLayer || getNodeLayer(fromNode.nodeType);\n const toLayer = toNode.epistemicLayer || getNodeLayer(toNode.nodeType);\n\n const validation = validateEdgeLayers(edgeType, fromLayer, toLayer);\n if (!validation.valid) {\n console.warn(\n `[EpistemicLinking] Invalid edge blocked: ${validation.reason}`\n );\n } else if (isDeprecatedEdgeType(edgeType)) {\n console.error(\n `[EpistemicLinking] FORBIDDEN edge type '${edgeType}' blocked. Use compliant edge types.`\n );\n } else {\n const edgeGlobalId = buildDeterministicEdgeGlobalId(\n fromNode.globalId,\n toNode.globalId,\n edgeType\n );\n\n // Phase 1 (Graph Architecture): Write to Neo4j directly\n await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {\n globalId: edgeGlobalId,\n fromGlobalId: fromNode.globalId,\n toGlobalId: toNode.globalId,\n edgeType: edgeType as\n | \"corroborates\"\n | \"extends\"\n | \"same_source_as\"\n | \"same_theme_as\",\n weight,\n context: args.rationale || `Linked as ${args.relation}`,\n topicId: fromInsight.projectId\n ? String(fromInsight.projectId)\n : undefined,\n createdBy: args.userId,\n fromNodeType: \"evidence\",\n toNodeType: \"evidence\",\n fromLayer,\n toLayer,\n });\n }\n }\n\n return { success: true };\n },\n});\n"]}
|