@lucern/graph-primitives 1.0.30 → 1.0.32

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.
Files changed (89) hide show
  1. package/dist/beliefEvidenceLinks.js.map +1 -1
  2. package/dist/beliefEvidenceLinks.operational.js.map +1 -1
  3. package/dist/contradictions.js +5 -5
  4. package/dist/contradictions.js.map +1 -1
  5. package/dist/entityLifecycle.js.map +1 -1
  6. package/dist/epistemicAnswers.js +1 -1
  7. package/dist/epistemicAnswers.js.map +1 -1
  8. package/dist/epistemicBeliefs.admin.js +2 -2
  9. package/dist/epistemicBeliefs.admin.js.map +1 -1
  10. package/dist/epistemicBeliefs.backfills.js +3 -3
  11. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  12. package/dist/epistemicBeliefs.confidence.js +1 -4
  13. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  14. package/dist/epistemicBeliefs.core.js +20 -30
  15. package/dist/epistemicBeliefs.core.js.map +1 -1
  16. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  17. package/dist/epistemicBeliefs.helpers.js +1 -1
  18. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  19. package/dist/epistemicBeliefs.internal.js +15 -25
  20. package/dist/epistemicBeliefs.internal.js.map +1 -1
  21. package/dist/epistemicBeliefs.js +27 -40
  22. package/dist/epistemicBeliefs.js.map +1 -1
  23. package/dist/epistemicBeliefs.lifecycle.js +1 -4
  24. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  25. package/dist/epistemicBeliefs.links.js +1 -1
  26. package/dist/epistemicBeliefs.links.js.map +1 -1
  27. package/dist/epistemicBeliefs.queries.js.map +1 -1
  28. package/dist/epistemicBeliefs.topicAnchor.js +12 -22
  29. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  30. package/dist/epistemicContracts.evaluators.js +1 -4
  31. package/dist/epistemicContracts.evaluators.js.map +1 -1
  32. package/dist/epistemicContracts.handlers.js +1 -4
  33. package/dist/epistemicContracts.handlers.js.map +1 -1
  34. package/dist/epistemicContracts.js +1 -4
  35. package/dist/epistemicContracts.js.map +1 -1
  36. package/dist/epistemicEdgeCreation.js.map +1 -1
  37. package/dist/epistemicEdges.handlers.js.map +1 -1
  38. package/dist/epistemicEdges.js +6 -7
  39. package/dist/epistemicEdges.js.map +1 -1
  40. package/dist/epistemicEdges.mutations.js +3 -4
  41. package/dist/epistemicEdges.mutations.js.map +1 -1
  42. package/dist/epistemicEdges.queries.js +3 -3
  43. package/dist/epistemicEdges.queries.js.map +1 -1
  44. package/dist/epistemicEvidence.js +10 -10
  45. package/dist/epistemicEvidence.js.map +1 -1
  46. package/dist/epistemicEvidenceHelpers.js +1 -1
  47. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  48. package/dist/epistemicEvidenceMutations.js +5 -5
  49. package/dist/epistemicEvidenceMutations.js.map +1 -1
  50. package/dist/epistemicEvidenceQueries.js +6 -6
  51. package/dist/epistemicEvidenceQueries.js.map +1 -1
  52. package/dist/epistemicHelpers.js +4 -4
  53. package/dist/epistemicHelpers.js.map +1 -1
  54. package/dist/epistemicInsert.js.map +1 -1
  55. package/dist/epistemicLayerRules.js +2 -2
  56. package/dist/epistemicLayerRules.js.map +1 -1
  57. package/dist/epistemicLinking.js.map +1 -1
  58. package/dist/epistemicNodeCreation.js +2 -2
  59. package/dist/epistemicNodeCreation.js.map +1 -1
  60. package/dist/epistemicNodes.internal.js +2 -3
  61. package/dist/epistemicNodes.internal.js.map +1 -1
  62. package/dist/epistemicNodes.js +10 -12
  63. package/dist/epistemicNodes.js.map +1 -1
  64. package/dist/epistemicNodes.mutations.js +3 -4
  65. package/dist/epistemicNodes.mutations.js.map +1 -1
  66. package/dist/epistemicNodes.queries.js +5 -5
  67. package/dist/epistemicNodes.queries.js.map +1 -1
  68. package/dist/epistemicQuestions.conviction.js +5 -5
  69. package/dist/epistemicQuestions.conviction.js.map +1 -1
  70. package/dist/epistemicQuestions.create.js +7 -7
  71. package/dist/epistemicQuestions.create.js.map +1 -1
  72. package/dist/epistemicQuestions.evidence.js +2 -2
  73. package/dist/epistemicQuestions.evidence.js.map +1 -1
  74. package/dist/epistemicQuestions.helpers.js +7 -4
  75. package/dist/epistemicQuestions.helpers.js.map +1 -1
  76. package/dist/epistemicQuestions.js +16 -13
  77. package/dist/epistemicQuestions.js.map +1 -1
  78. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  79. package/dist/epistemicQuestions.queries.js +2 -2
  80. package/dist/epistemicQuestions.queries.js.map +1 -1
  81. package/dist/epistemicQuestions.sprint.js +6 -3
  82. package/dist/epistemicQuestions.sprint.js.map +1 -1
  83. package/dist/epistemicQuestions.tail.js +2 -2
  84. package/dist/epistemicQuestions.tail.js.map +1 -1
  85. package/dist/epistemicSources.js.map +1 -1
  86. package/dist/index.js +79 -92
  87. package/dist/index.js.map +1 -1
  88. package/dist/proof-attestation.json +1 -1
  89. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/convex.ts","../src/debug.ts","../src/embeddingTrigger.ts","../src/epistemicInsert.ts","../src/topicScope.ts","../src/workspaceIsolation.ts","../src/epistemicSources.ts"],"names":["query","normalizeScopeValue","v"],"mappings":"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","file":"epistemicSources.js","sourcesContent":["import type { Doc as AccessControlDoc } from \"@lucern/access-control/convex\";\nimport {\n type UnsafeConvexAnyApi,\n unsafeConvexAnyApi,\n} from \"@lucern/contracts/convex/unsafeAnyApi\";\nimport {\n actionGeneric,\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.\nconst unsafeApi = unsafeConvexAnyApi(\n \"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface\"\n);\nexport const api = unsafeApi;\nexport const components =\n componentsGeneric() as unknown as UntypedFunctionReferenceSurface;\nexport const internal = unsafeApi;\n\ntype UntypedFunctionReferenceSurface = UnsafeConvexAnyApi;\ntype BoundaryValue = UntypedFunctionReferenceSurface[string];\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> =\n AccessControlDoc<TableName>;\nexport type DataModel = Record<TableNames, unknown>;\ninterface IndexRangeBuilder {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n field(fieldName: string): string;\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}\ninterface FilterBuilder {\n and(...clauses: unknown[]): FilterBuilder;\n eq(left: unknown, right: unknown): FilterBuilder;\n field(fieldName: string): string;\n gt(left: unknown, right: unknown): FilterBuilder;\n gte(left: unknown, right: unknown): FilterBuilder;\n lt(left: unknown, right: unknown): FilterBuilder;\n lte(left: unknown, right: unknown): FilterBuilder;\n neq(left: unknown, right: unknown): FilterBuilder;\n or(...clauses: unknown[]): FilterBuilder;\n [operator: string]: unknown;\n}\ninterface QueryInitializer<TableName extends TableNames> {\n collect(): Promise<Doc<TableName>[]>;\n filter(predicate: (q: FilterBuilder) => unknown): QueryInitializer<TableName>;\n first(): Promise<Doc<TableName> | null>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n take(limit: number): Promise<Doc<TableName>[]>;\n unique(): Promise<Doc<TableName> | null>;\n withIndex(\n indexName: string,\n range?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n withSearchIndex(\n indexName: string,\n search?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n}\nexport interface DatabaseReader {\n get<TableName extends TableNames>(\n id: unknown\n ): Promise<Doc<TableName> | null>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\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};\ninterface Scheduler {\n runAfter(\n delayMs: number,\n functionReference: unknown,\n args?: unknown\n ): Promise<void>;\n}\ninterface AuthReader {\n getUserIdentity(): Promise<{\n readonly subject: string;\n readonly [claimName: string]: unknown;\n } | null>;\n}\ninterface RuntimeInvoker {\n runAction<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runMutation<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runQuery<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\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 Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\ntype OptionalHandlerConvexFunctionBuilder<Ctx> = <\n Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler?: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\nexport const action =\n 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 OptionalHandlerConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as OptionalHandlerConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","interface GraphPrimitiveDebugEnvironment {\n process?: {\n env?: Record<string, string | undefined>;\n };\n}\n\nfunction isGraphPrimitiveDebugEnabled(): boolean {\n const env = (globalThis as GraphPrimitiveDebugEnvironment).process?.env;\n return (\n env?.LUCERN_COMPAT_FALLBACK_DEBUG === \"1\" || env?.LUCERN_GRAPH_DEBUG === \"1\"\n );\n}\n\nexport function formatGraphPrimitiveError(error: unknown): string {\n if (error instanceof Error) {\n return `${error.name}: ${error.message}`;\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error === null) {\n return \"null\";\n }\n if (error === undefined) {\n return \"undefined\";\n }\n try {\n return JSON.stringify(error);\n } catch {\n return Object.prototype.toString.call(error);\n }\n}\n\nexport function debugGraphPrimitiveFallback(\n message: string,\n context?: Record<string, unknown>\n): void {\n if (!isGraphPrimitiveDebugEnabled()) {\n return;\n }\n console.debug(message, context ?? {});\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public ABI surface; rename requires a cross-package migration update.\n/**\n * Shared helper to schedule embedding generation after epistemic node creation.\n *\n * Best-effort — failures are silently caught. The embedding generation action\n * is a public action in convex/embeddingActions.ts that calls Pinecone.\n */\n\nimport type { Id } from \"./convex\";\nimport { debugGraphPrimitiveFallback } from \"./debug\";\n\ninterface EmbeddingScheduler {\n runAfter(\n delayMs: number,\n functionReference: unknown,\n args?: unknown\n ): Promise<void>;\n}\n\ninterface EmbeddingTriggerContext {\n scheduler: EmbeddingScheduler;\n}\n\ninterface EmbeddingTriggerArgs {\n confidence?: number;\n createdBy: string;\n ctx: EmbeddingTriggerContext;\n hasAnswer?: boolean;\n nodeId: Id<\"epistemicNodes\">;\n nodeType:\n | \"belief\"\n | \"question\"\n | \"evidence\"\n | \"answer\"\n | \"synthesis\"\n | \"theme\"\n | \"source\";\n projectId?: string | null;\n text: string;\n topicId?: string | null;\n}\n\nconst embeddingActionRef = \"embeddingActions:generateEpistemicNodeEmbedding\";\n\nexport async function scheduleEmbeddingGeneration(\n args: EmbeddingTriggerArgs\n): Promise<void> {\n try {\n await args.ctx.scheduler.runAfter(0, embeddingActionRef, {\n nodeId: args.nodeId,\n projectId: args.projectId ? String(args.projectId) : undefined,\n topicId: args.topicId ? String(args.topicId) : undefined,\n createdBy: args.createdBy,\n nodeType: args.nodeType,\n text: args.text.slice(0, 20_000),\n hasAnswer: args.hasAnswer,\n confidence: args.confidence,\n });\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[embeddingTrigger] Failed to schedule embedding generation\",\n {\n error,\n nodeId: String(args.nodeId),\n nodeType: args.nodeType,\n }\n );\n // Embedding generation is best-effort — never block node creation\n }\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\nimport {\n assertEdgePolicyAllowed,\n type EpistemicNodeType,\n edgePolicyManifest,\n} from \"@lucern/contracts\";\nimport {\n assertStorageEdgeVocabulary,\n assertUuidShapedEdgeEndpoint,\n assertUuidV7Identity,\n} from \"@lucern/contracts/ids\";\nimport type { Id, MutationCtx } from \"./convex\";\n\ninterface GlobalIdIndexQuery {\n eq(field: \"globalId\", value: string): GlobalIdIndexQuery;\n}\n\ninterface EpistemicNodeInsertDoc extends Record<string, unknown> {\n globalId: string;\n}\n\ninterface EpistemicEdgeInsertDoc extends Record<string, unknown> {\n edgeType: string;\n fromNodeId: string;\n fromNodeType?: string;\n globalId: string;\n toNodeId: string;\n toNodeType?: string;\n}\n\nexport function insertEpistemicNode(\n ctx: MutationCtx,\n doc: EpistemicNodeInsertDoc\n): Promise<Id<\"epistemicNodes\">> {\n assertUuidV7Identity(\"epistemicNodes\", doc.globalId);\n return ctx.db.insert(\"epistemicNodes\", doc);\n}\n\n/**\n * C2-RR.4b — REFERENTIAL edge-endpoint canonicality (amends RR.4's FORMAT guard).\n *\n * Proves an endpoint is the `globalId` of an EXISTING `epistemicNodes` row, not\n * that it has a v7 shape. Refuses doc-ids and fabricated/unknown endpoints while\n * keeping legacy v4-`globalId` nodes (the established prod corpus) linkable.\n * SHAPE pre-filter accepts both v4 and v7; the indexed `by_globalId` lookup is\n * the referential authority (no full scan). v7-format stays enforced only at new\n * identity minting (`assertUuidV7Identity`). See c2-rr4b-endpoint-referential.\n */\nasync function assertExistingNodeEndpoint(\n ctx: MutationCtx,\n endpointRole: \"fromNodeId\" | \"toNodeId\",\n endpoint: string\n): Promise<void> {\n assertUuidShapedEdgeEndpoint(endpointRole, endpoint);\n const node = await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_globalId\", (q: GlobalIdIndexQuery) =>\n q.eq(\"globalId\", endpoint)\n )\n .first();\n if (!node) {\n throw new Error(\n `edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`\n );\n }\n}\n\nexport async function insertEpistemicEdge(\n ctx: MutationCtx,\n doc: EpistemicEdgeInsertDoc\n): Promise<Id<\"epistemicEdges\">> {\n assertUuidV7Identity(\"epistemicEdges\", doc.globalId);\n\n // R1.1a — STORAGE-VOCABULARY MEMBERSHIP\n assertStorageEdgeVocabulary(doc.edgeType);\n\n // R1.1b — ENDPOINT PRESENCE\n if (!doc.fromNodeId || typeof doc.fromNodeId !== \"string\") {\n throw new Error(\n \"edge_endpoint_missing: epistemicEdges insert requires a non-empty fromNodeId\"\n );\n }\n if (!doc.toNodeId || typeof doc.toNodeId !== \"string\") {\n throw new Error(\n \"edge_endpoint_missing: epistemicEdges insert requires a non-empty toNodeId\"\n );\n }\n\n // C2-RR.4b Defect E (REFERENTIAL) — ENDPOINT CANONICAL IDENTITY. Edge\n // endpoints must each be the globalId of an EXISTING epistemicNodes row,\n // never a Convex doc id, a legacy topic id, or a fabricated/unknown uuid.\n // This refuses the mixed _id/globalId endpoint writes at the floor while\n // keeping legacy v4-globalId nodes linkable (RR.4b prod-incident cure).\n await assertExistingNodeEndpoint(ctx, \"fromNodeId\", doc.fromNodeId);\n await assertExistingNodeEndpoint(ctx, \"toNodeId\", doc.toNodeId);\n\n // R1.1c — FULL POLICY ASSERT (when nodeTypes are present and edgeType is in public manifest)\n if (doc.fromNodeType && doc.toNodeType && doc.edgeType !== \"extracted_from\") {\n assertEdgePolicyAllowed(\n edgePolicyManifest,\n doc.edgeType,\n {\n kind: \"epistemic_node\",\n nodeId: doc.fromNodeId,\n nodeType: doc.fromNodeType as EpistemicNodeType,\n },\n {\n kind: \"epistemic_node\",\n nodeId: doc.toNodeId,\n nodeType: doc.toNodeType as EpistemicNodeType,\n }\n );\n }\n\n return ctx.db.insert(\"epistemicEdges\", doc);\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/** Topic-scope resolution helpers for graph-primitive operations. */\nimport { v } from \"convex/values\";\nimport type { Id } from \"./convex\";\nimport { api as appApi } from \"./convex\";\nimport { debugGraphPrimitiveFallback } from \"./debug\";\n\nconst LEGACY_SCOPE_FIELD = \"graphScopeProjectId\";\n\ntype UnknownRecord = Record<string, unknown>;\n\ninterface TopicScopeContext {\n db: {\n get(id: string): Promise<unknown>;\n query(tableName: string): TopicScopeQuery;\n };\n runQuery?: <TResult>(fnRef: unknown, args: unknown) => Promise<TResult>;\n}\n\ninterface TopicScopeQuery {\n collect(): Promise<unknown[]>;\n first(): Promise<unknown | null>;\n withIndex(\n indexName: string,\n range?: (q: TopicScopeIndexRangeBuilder) => unknown\n ): TopicScopeQuery;\n}\n\ninterface TopicScopeIndexRangeBuilder {\n eq(field: string, value: unknown): TopicScopeIndexRangeBuilder;\n}\n\ntype TopicDoc = Record<string, unknown> & {\n _id: Id<\"topics\">;\n globalId?: string;\n name?: string;\n depth?: number;\n createdAt?: number;\n parentTopicId?: Id<\"topics\">;\n tenantId?: string;\n workspaceId?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport interface TopicProjectScope {\n projectId?: string;\n source: \"topic\" | \"project_mapped_topic\" | \"topic_inferred\" | \"topic_node\";\n tenantId?: string;\n topicId: Id<\"topics\">;\n workspaceId?: string;\n}\n\n/**\n * RR.5 (legacy topics-table retirement) — graph-primitives mirror of the\n * kernel's epistemicNodes-first topic-scope fallback. Kept in lockstep with\n * `packages/reasoning-kernel/src/adapters/lib/topicScope.ts`\n * (`tests/unit/convex/topic-scope-fallbacks.test.ts` asserts parity).\n *\n * Resolves a topic that exists only as `epistemicNodes(nodeType=\"topic\")` —\n * the write-of-record — when no legacy `topics` row backs the ref, returning the\n * node's `topicId` self-key so scoped beliefs/evidence/questions stay reachable.\n * See the kernel module for the full silent-empty-result rationale.\n */\ninterface TopicNodeScopeDoc {\n _id: string | Id<\"epistemicNodes\">;\n globalId?: string;\n metadata?: UnknownRecord;\n nodeType?: string;\n topicId?: string;\n}\n\nasync function resolveTopicNodeScopeOrNull(\n ctx: TopicScopeContext,\n ref: string\n): Promise<TopicProjectScope | null> {\n if (!ctx?.db || typeof ctx.db.query !== \"function\") {\n return null;\n }\n\n let node: TopicNodeScopeDoc | null = null;\n\n // 1. The ref IS the topic node's UUIDv7 globalId.\n try {\n const byGlobalId = (await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_globalId\", (q) => q.eq(\"globalId\", ref))\n .first()) as TopicNodeScopeDoc | null;\n if (byGlobalId && byGlobalId.nodeType === \"topic\") {\n node = byGlobalId;\n }\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] topic-node scope lookup by globalId failed\",\n { error, ref }\n );\n }\n\n if (!node) {\n return null;\n }\n\n const scopeKey =\n normalizeScopeValue(node.topicId) ?? normalizeScopeValue(node.globalId);\n if (!scopeKey) {\n return null;\n }\n\n return {\n topicId: scopeKey as Id<\"topics\">,\n projectId: asMappedProjectId(node),\n source: \"topic_node\",\n };\n}\n\ninterface MaterializedTopicNodeDoc {\n _id: string | Id<\"epistemicNodes\">;\n metadata?: Record<string, unknown>;\n}\n\nfunction asMappedProjectId(\n topic: Pick<TopicDoc, \"metadata\"> | TopicNodeScopeDoc | null | undefined\n): string | undefined {\n if (!topic) {\n return;\n }\n const directLegacyProjectId = normalizeScopeValue(\n (topic as UnknownRecord)[LEGACY_SCOPE_FIELD]\n );\n if (directLegacyProjectId) {\n return directLegacyProjectId;\n }\n const metadata = topic.metadata || {};\n const candidate =\n (metadata as UnknownRecord)[LEGACY_SCOPE_FIELD] ||\n (metadata as UnknownRecord).legacyProjectId ||\n (metadata as UnknownRecord).projectId ||\n (metadata as UnknownRecord).scopeProjectId;\n return typeof candidate === \"string\"\n ? normalizeScopeValue(candidate)\n : undefined;\n}\n\nfunction normalizeScopeValue(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return;\n }\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction pickPrimaryTopic(candidates: TopicDoc[]): TopicDoc | undefined {\n return [...candidates].sort((a, b) => {\n const depthA = a.depth ?? 9999;\n const depthB = b.depth ?? 9999;\n if (depthA !== depthB) {\n return depthA - depthB;\n }\n const createdA = a.createdAt ?? Number.MAX_SAFE_INTEGER;\n const createdB = b.createdAt ?? Number.MAX_SAFE_INTEGER;\n if (createdA !== createdB) {\n return createdA - createdB;\n }\n return String(a.name || \"\").localeCompare(String(b.name || \"\"));\n })[0];\n}\n\nasync function findTopicsByScopeAlias(\n ctx: TopicScopeContext,\n scopeId: string\n): Promise<TopicDoc[]> {\n const query = ctx.db.query(\"topics\") as TopicScopeQuery;\n try {\n return (await query\n .withIndex(\"by_graph_scope_project\", (q) =>\n q.eq(LEGACY_SCOPE_FIELD, scopeId)\n )\n .collect()) as TopicDoc[];\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] Failed to resolve scope alias via index\",\n {\n error,\n scopeId,\n }\n );\n // Older Lucern dev deployments can lag index backfills while still carrying\n // the underlying topics table. Scan and filter so scope resolution keeps\n // working during the rollout.\n const topics = (await query.collect()) as TopicDoc[];\n return topics.filter((topic) => {\n const normalizedGlobalId = normalizeScopeValue(topic.globalId);\n const mappedProjectId = asMappedProjectId(topic);\n return (\n String(topic._id) === scopeId ||\n normalizedGlobalId === scopeId ||\n mappedProjectId === scopeId\n );\n });\n }\n}\n\nasync function tryResolveHostTopicById(\n ctx: TopicScopeContext,\n topicId: string\n): Promise<TopicDoc | null> {\n if (typeof ctx.runQuery !== \"function\") {\n return null;\n }\n try {\n return ((await ctx.runQuery(appApi.topics.get, {\n id: topicId,\n })) ?? null) as TopicDoc | null;\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] Failed to resolve topic by host query\",\n {\n error,\n topicId,\n }\n );\n return null;\n }\n}\n\nasync function tryResolveHostTopicByLegacyScope(\n ctx: TopicScopeContext,\n legacyScopeId: string\n): Promise<TopicDoc | null> {\n if (typeof ctx.runQuery !== \"function\") {\n return null;\n }\n try {\n return ((await ctx.runQuery(appApi.topics.getByLegacyScopeId, {\n projectId: legacyScopeId,\n })) ?? null) as TopicDoc | null;\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] Failed to resolve topic by legacy scope\",\n {\n error,\n legacyScopeId,\n }\n );\n return null;\n }\n}\n\nexport function readMaterializedTopicTableId(\n topicNode: MaterializedTopicNodeDoc | null | undefined\n): string | undefined {\n if (!topicNode) {\n return;\n }\n\n const metadata = (topicNode.metadata || {}) as Record<string, unknown>;\n const topicTableId =\n (metadata.topicTableId as string | undefined) ||\n (metadata.topicId as string | undefined);\n\n return typeof topicTableId === \"string\" && topicTableId.trim().length > 0\n ? topicTableId.trim()\n : undefined;\n}\n\n/**\n * Walk the topic parent chain to find inherited workspaceId and tenantId.\n * Mirrors the pattern used by resolveTopicOntology for ontologyId inheritance.\n * Max depth: 10 (defensive limit against pathological nesting).\n */\nasync function resolveInheritedWorkspaceScope(\n ctx: TopicScopeContext,\n topic: TopicDoc\n): Promise<{ tenantId?: string; workspaceId?: string }> {\n const MAX_DEPTH = 10;\n let tenantId = normalizeScopeValue(topic.tenantId);\n let workspaceId = normalizeScopeValue(topic.workspaceId);\n\n if (tenantId && workspaceId) {\n return { tenantId, workspaceId };\n }\n\n let current: TopicDoc | null = topic;\n for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {\n current = (await ctx.db.get(current.parentTopicId)) as TopicDoc | null;\n if (!current) {\n break;\n }\n\n if (!tenantId) {\n tenantId = normalizeScopeValue(current.tenantId);\n }\n if (!workspaceId) {\n workspaceId = normalizeScopeValue(current.workspaceId);\n }\n if (tenantId && workspaceId) {\n break;\n }\n }\n\n return { tenantId, workspaceId };\n}\n\nexport async function resolveTopicProjectScope(\n ctx: TopicScopeContext,\n args: { topicId?: Id<\"topics\"> | string; projectId?: string }\n): Promise<TopicProjectScope> {\n if (args.topicId) {\n return await resolveScopeFromTopicId(ctx, args.topicId);\n }\n\n if (args.projectId) {\n return await resolveScopeFromLegacyProjectId(ctx, args.projectId);\n }\n\n throw new Error(\n \"Missing scope: provide topicId (preferred) or legacy projectId alias.\"\n );\n}\n\nasync function resolveScopeFromTopicId(\n ctx: TopicScopeContext,\n topicId: Id<\"topics\"> | string\n): Promise<TopicProjectScope> {\n const topic = await resolveTopicDocFromTopicId(ctx, topicId);\n if (topic) {\n return await buildTopicScope(ctx, topic, \"topic\");\n }\n\n const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));\n if (nodeScope) {\n return nodeScope;\n }\n throw new Error(`Topic not found: ${String(topicId)}`);\n}\n\nasync function resolveTopicDocFromTopicId(\n ctx: TopicScopeContext,\n topicId: Id<\"topics\"> | string\n): Promise<TopicDoc | null> {\n const direct = await tryReadTopicDoc(ctx, topicId, {\n failureLog: \"[topicScope] Failed to load topic by direct id\",\n idLogKey: \"topicId\",\n });\n if (direct) {\n return direct;\n }\n\n const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));\n if (hostTopic) {\n return hostTopic;\n }\n\n return (\n pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null\n );\n}\n\nasync function resolveScopeFromLegacyProjectId(\n ctx: TopicScopeContext,\n legacyProjectId: string\n): Promise<TopicProjectScope> {\n const directTopic = await resolveDirectLegacyProjectTopic(\n ctx,\n legacyProjectId\n );\n if (directTopic) {\n return await buildTopicScope(ctx, directTopic, \"topic_inferred\", {\n fallbackProjectId: legacyProjectId,\n });\n }\n\n const primary = pickPrimaryTopic(\n await findTopicsByScopeAlias(ctx, legacyProjectId)\n );\n if (primary) {\n return await buildTopicScope(ctx, primary, \"project_mapped_topic\", {\n fallbackProjectId: legacyProjectId,\n });\n }\n\n const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);\n if (nodeScope) {\n return {\n ...nodeScope,\n projectId: nodeScope.projectId ?? legacyProjectId,\n };\n }\n\n throw new Error(\n `Legacy project scope ${legacyProjectId} has no mapped topic.`\n );\n}\n\nasync function resolveDirectLegacyProjectTopic(\n ctx: TopicScopeContext,\n legacyProjectId: string\n): Promise<TopicDoc | null> {\n const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {\n failureLog: \"[topicScope] Failed to load direct project topic\",\n idLogKey: \"projectId\",\n });\n return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);\n}\n\nasync function tryReadTopicDoc(\n ctx: TopicScopeContext,\n id: Id<\"topics\"> | string,\n log: { failureLog: string; idLogKey: \"projectId\" | \"topicId\" }\n): Promise<TopicDoc | null> {\n try {\n return (await ctx.db.get(id)) as TopicDoc | null;\n } catch (error) {\n debugGraphPrimitiveFallback(log.failureLog, {\n error,\n [log.idLogKey]: id,\n });\n return null;\n }\n}\n\nasync function buildTopicScope(\n ctx: TopicScopeContext,\n topic: TopicDoc,\n source: TopicProjectScope[\"source\"],\n options: { fallbackProjectId?: string } = {}\n): Promise<TopicProjectScope> {\n const inherited = await resolveInheritedWorkspaceScope(ctx, topic);\n const mapped = asMappedProjectId(topic);\n return {\n topicId: topic._id,\n ...(mapped || options.fallbackProjectId\n ? { projectId: mapped ?? options.fallbackProjectId }\n : {}),\n tenantId: inherited.tenantId,\n workspaceId: inherited.workspaceId,\n source,\n };\n}\n\n/** Shared scope args for graph-primitive functions. topicId is canonical; projectId is a legacy alias. */\nexport const optionalScopeArgs = {\n projectId: v.optional(v.string()),\n topicId: v.optional(v.string()),\n} as const;\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\nimport {\n getLayerForNodeType,\n isNodeType,\n} from \"@lucern/contracts/schema-helpers/spine/tables/epistemicNodes\";\nimport type { MutationCtx, QueryCtx } from \"./convex\";\nimport { resolveTopicProjectScope, type TopicProjectScope } from \"./topicScope\";\n\ntype StructuredInvariantError = Error & {\n status: number;\n code: string;\n invariantCode?: string;\n suggestion?: string;\n details?: unknown;\n};\n\ninterface ScopeLike {\n epistemicLayer?: unknown;\n nodeType?: unknown;\n projectId?: unknown;\n publicationStatus?: unknown;\n tenantId?: unknown;\n topicId?: unknown;\n workspaceId?: unknown;\n}\n\nexport interface RuntimePackMutationContext {\n packInstallScope?: \"tenant\" | \"workspace\";\n packKey?: string;\n toolName?: string;\n}\n\nexport function normalizeScopeValue(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return;\n }\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction throwWorkspaceIsolationError(args: {\n message: string;\n invariantCode: string;\n suggestion: string;\n details?: unknown;\n}): never {\n const error = new Error(args.message) as StructuredInvariantError;\n error.status = 409;\n error.code = \"INVARIANT_VIOLATION\";\n error.invariantCode = args.invariantCode;\n error.suggestion = args.suggestion;\n error.details = args.details;\n throw error;\n}\n\nexport function assertWorkspaceScopedEpistemicNodeScope(args: {\n scope: TopicProjectScope;\n nodeType: string;\n mutationName: string;\n}): void {\n const layer = isNodeType(args.nodeType)\n ? getLayerForNodeType(args.nodeType)\n : undefined;\n if (layer === \"ontological\") {\n return;\n }\n\n const workspaceId = normalizeScopeValue(args.scope.workspaceId);\n if (workspaceId) {\n return;\n }\n\n throwWorkspaceIsolationError({\n message:\n \"Workspace-scoped reasoning isolation requires workspaceId on non-ontological node creation.\",\n invariantCode: \"workspace.scope_required_for_epistemic_nodes\",\n suggestion:\n \"Resolve the topic/project scope through a workspace-bound topic before creating epistemic nodes.\",\n details: {\n mutationName: args.mutationName,\n nodeType: args.nodeType,\n topicId: args.scope.topicId,\n projectId: args.scope.projectId,\n },\n });\n}\n\nexport function nodeMatchesWorkspaceReasoningScope(\n node: ScopeLike | null | undefined,\n scope: Pick<TopicProjectScope, \"tenantId\" | \"workspaceId\">\n): boolean {\n if (!node) {\n return false;\n }\n\n const scopeTenantId = normalizeScopeValue(scope.tenantId);\n const scopeWorkspaceId = normalizeScopeValue(scope.workspaceId);\n const nodeTenantId = normalizeScopeValue(node.tenantId);\n const nodeWorkspaceId = normalizeScopeValue(node.workspaceId);\n const epistemicLayer =\n typeof node.epistemicLayer === \"string\" ? node.epistemicLayer : undefined;\n\n if (scopeTenantId && nodeTenantId && scopeTenantId !== nodeTenantId) {\n return false;\n }\n\n // Ontological entities are tenant-global (no workspace required)\n if (epistemicLayer === \"ontological\" && nodeWorkspaceId === undefined) {\n return true;\n }\n\n // Published nodes are visible at tenant scope — the microservice API surface.\n // The node stays in its workspace, but tenant-scope queries can see it.\n if (!scopeWorkspaceId && node.publicationStatus === \"published\") {\n return true;\n }\n\n if (!scopeWorkspaceId) {\n return nodeWorkspaceId === undefined;\n }\n\n return scopeWorkspaceId === nodeWorkspaceId;\n}\n\nexport function edgeMatchesWorkspaceReasoningScope(\n edge: ScopeLike | null | undefined,\n scope: Pick<TopicProjectScope, \"tenantId\" | \"workspaceId\">\n): boolean {\n if (!edge) {\n return false;\n }\n\n const scopeTenantId = normalizeScopeValue(scope.tenantId);\n const scopeWorkspaceId = normalizeScopeValue(scope.workspaceId);\n const edgeTenantId = normalizeScopeValue(edge.tenantId);\n const edgeWorkspaceId = normalizeScopeValue(edge.workspaceId);\n\n if (scopeTenantId && edgeTenantId && scopeTenantId !== edgeTenantId) {\n return false;\n }\n\n if (!scopeWorkspaceId) {\n return edgeWorkspaceId === undefined;\n }\n\n return scopeWorkspaceId === edgeWorkspaceId;\n}\n\nexport async function resolveNodeScopeForWorkspaceIsolation(\n ctx: QueryCtx | MutationCtx,\n node: ScopeLike | null | undefined\n): Promise<{\n tenantId?: string;\n workspaceId?: string;\n epistemicLayer?: string;\n nodeType?: string;\n}> {\n const epistemicLayer =\n typeof node?.epistemicLayer === \"string\" ? node.epistemicLayer : undefined;\n const resolved = {\n tenantId: normalizeScopeValue(node?.tenantId),\n workspaceId: normalizeScopeValue(node?.workspaceId),\n epistemicLayer,\n nodeType: typeof node?.nodeType === \"string\" ? node.nodeType : undefined,\n };\n\n if (!node) {\n return resolved;\n }\n\n if (resolved.epistemicLayer === \"ontological\") {\n return resolved;\n }\n\n if (resolved.tenantId || resolved.workspaceId) {\n return resolved;\n }\n\n const topicId = normalizeScopeValue(node.topicId);\n if (topicId) {\n const topicScope = await resolveTopicProjectScope(ctx, {\n topicId,\n });\n return {\n ...resolved,\n tenantId: topicScope.tenantId,\n workspaceId: topicScope.workspaceId,\n };\n }\n\n if (node.projectId) {\n const topicScope = await resolveTopicProjectScope(ctx, {\n projectId: String(node.projectId),\n });\n return {\n ...resolved,\n tenantId: topicScope.tenantId,\n workspaceId: topicScope.workspaceId,\n };\n }\n\n return resolved;\n}\n\nexport function resolveRuntimePackMutationContext(args: {\n runtimeToolName?: string;\n runtimePackKey?: string;\n runtimePackInstallScope?: \"tenant\" | \"workspace\";\n}): RuntimePackMutationContext | undefined {\n if (\n !(\n args.runtimeToolName ||\n args.runtimePackKey ||\n args.runtimePackInstallScope\n )\n ) {\n return;\n }\n\n return {\n toolName: args.runtimeToolName,\n packKey: args.runtimePackKey,\n packInstallScope: args.runtimePackInstallScope,\n };\n}\n\nexport function assertTenantPackWorkspaceMutationAllowed(args: {\n runtime?: RuntimePackMutationContext;\n target: ScopeLike;\n mutationName: string;\n}): void {\n if (!args.runtime?.packKey || args.runtime.packInstallScope !== \"tenant\") {\n return;\n }\n\n const targetWorkspaceId = normalizeScopeValue(args.target.workspaceId);\n const targetLayer =\n typeof args.target.epistemicLayer === \"string\"\n ? args.target.epistemicLayer\n : undefined;\n\n if (!targetWorkspaceId || targetLayer === \"ontological\") {\n return;\n }\n\n throwWorkspaceIsolationError({\n message: `Tenant-scoped pack \"${args.runtime.packKey}\" cannot mutate workspace-scoped reasoning state.`,\n invariantCode: \"workspace.tenant_pack_reasoning_write_forbidden\",\n suggestion:\n \"Use a workspace-scoped pack for workspace-local graph mutations, or route the change through tenant-global canonical entity flows.\",\n details: {\n mutationName: args.mutationName,\n toolName: args.runtime.toolName,\n packKey: args.runtime.packKey,\n targetWorkspaceId,\n targetNodeType: args.target.nodeType,\n targetLayer,\n },\n });\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/**\n * Epistemic Sources API\n *\n * Invariants:\n * - Invariant 7: evidence is context-bound. Sources carry topic, author, and capture time.\n * - Invariant 8: no retroactive reinterpretation. Source identity fields stay immutable.\n * - Invariant 14: no silent state transitions. Every create/update is audited.\n * - Invariant 15: retrieval respects boundaries. Sources live at L1 terminal leaves.\n */\n\nimport {\n checkScopeAccess,\n requireScopeWriteAccess,\n} from \"@lucern/access-control/access\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport { v } from \"convex/values\";\nimport type { Doc, Id, MutationCtx, QueryCtx } from \"./convex\";\nimport { internal, mutation, query } from \"./convex\";\nimport { scheduleEmbeddingGeneration } from \"./embeddingTrigger\";\nimport { insertEpistemicNode } from \"./epistemicInsert.js\";\nimport type { EpistemicDbReader } from \"./epistemicQuestions.helpers\";\nimport { generateGlobalId } from \"./globalId\";\nimport { resolveTopicProjectScope } from \"./topicScope\";\nimport { assertWorkspaceScopedEpistemicNodeScope } from \"./workspaceIsolation\";\n\nconst TRAILING_SLASHES_PATTERN = /\\/+$/;\nconst HASH_MODULUS = 2 ** 32;\nconst HASH_SIGN_BOUNDARY = 2 ** 31;\n\ntype SourceMutationCtx = MutationCtx;\ntype SourceNodeDoc = Doc<\"epistemicNodes\"> & {\n _id: Id<\"epistemicNodes\">;\n metadata?: Record<string, unknown>;\n nodeType?: string;\n title?: string;\n topicId?: string;\n};\ntype SourceAuditChangeType = \"source_created\" | \"source_metadata_updated\";\n\ninterface SourceAuditRecord {\n changedAt: number;\n changedBy: string;\n changeType: SourceAuditChangeType;\n entityId: string;\n entityType: \"source\";\n isAgent: false;\n newState?: Record<string, unknown> | null;\n previousState?: Record<string, unknown> | null;\n topicId?: string;\n}\n\ninterface UpsertSourceArgs {\n capturedAt?: number;\n kind: string;\n metadata?: unknown;\n sha?: string;\n title?: string;\n topicId?: string;\n url?: string;\n userId: string;\n}\n\ninterface GetSourceByIdArgs {\n nodeId?: Id<\"epistemicNodes\">;\n sourceId?: string;\n}\n\ninterface SourceUrlQueryArgs {\n url: string;\n}\n\ninterface SourceShaQueryArgs {\n sha: string;\n}\n\ntype StructuredSourceError = Error & {\n status: number;\n code: string;\n invariantCode?: string;\n suggestion?: string;\n details?: unknown;\n};\n\nfunction throwStructuredSourceError(args: {\n message: string;\n status: number;\n code: string;\n invariantCode?: string;\n suggestion?: string;\n details?: unknown;\n}): never {\n const error = new Error(args.message) as StructuredSourceError;\n error.status = args.status;\n error.code = args.code;\n error.invariantCode = args.invariantCode;\n error.suggestion = args.suggestion;\n error.details = args.details;\n throw error;\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return;\n }\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction readConvexId<TableName extends string>(\n value: unknown\n): Id<TableName> | null {\n const normalized = normalizeString(value);\n return normalized ? (normalized as Id<TableName>) : null;\n}\n\nfunction normalizeNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n\nfunction isSourceNodeDoc(value: unknown): value is SourceNodeDoc {\n const record = asRecord(value);\n return (\n readConvexId<\"epistemicNodes\">(record._id) !== null &&\n normalizeString(record.nodeType) === \"source\"\n );\n}\n\nfunction normalizeMetadata(metadata: unknown): Record<string, unknown> {\n const record = asRecord(metadata);\n const { url: _ignoredUrl, contentSha: _ignoredSha, ...rest } = record;\n return rest;\n}\n\nfunction toSignedInt32(value: number): number {\n const normalized = ((value % HASH_MODULUS) + HASH_MODULUS) % HASH_MODULUS;\n return normalized >= HASH_SIGN_BOUNDARY\n ? normalized - HASH_MODULUS\n : normalized;\n}\n\nfunction generateSourceContentHash(identity: string): string {\n const content = `source:${identity.trim().toLowerCase()}`;\n let hash = 5381;\n for (let index = 0; index < content.length; index += 1) {\n hash = toSignedInt32(hash * 33 + content.charCodeAt(index));\n }\n return Math.abs(hash).toString(16).padStart(8, \"0\");\n}\n\nexport function normalizeSourceUrl(url: string): string {\n const trimmed = normalizeString(url);\n if (!trimmed) {\n throwStructuredSourceError({\n message: \"Source URL is required.\",\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.url.valid\",\n suggestion: \"Provide an absolute URL with a valid protocol and host.\",\n });\n }\n\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n throwStructuredSourceError({\n message: `Invalid URL: ${trimmed}`,\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.url.valid\",\n suggestion: \"Provide an absolute URL with a valid protocol and host.\",\n details: { url: trimmed },\n });\n }\n\n const protocol = parsed.protocol.toLowerCase();\n const hostname = parsed.hostname.toLowerCase();\n const port = parsed.port ? `:${parsed.port}` : \"\";\n const pathname =\n parsed.pathname === \"/\"\n ? \"\"\n : parsed.pathname.replace(TRAILING_SLASHES_PATTERN, \"\");\n\n const sortedEntries = [...parsed.searchParams.entries()].sort(\n ([aKey, aValue], [bKey, bValue]) =>\n aKey === bKey ? aValue.localeCompare(bValue) : aKey.localeCompare(bKey)\n );\n const params = new URLSearchParams();\n for (const [key, value] of sortedEntries) {\n params.append(key, value);\n }\n const search = params.toString();\n\n return `${protocol}//${hostname}${port}${pathname}${\n search.length > 0 ? `?${search}` : \"\"\n }`;\n}\n\nasync function findSourceByIdentity(\n ctx: { db: EpistemicDbReader },\n args: { normalizedUrl?: string; sha?: string }\n): Promise<SourceNodeDoc | null> {\n const sourceNodes = await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_nodeType\", (q) => q.eq(\"nodeType\", \"source\"))\n .collect();\n\n let urlMatch: SourceNodeDoc | null = null;\n let shaMatch: SourceNodeDoc | null = null;\n\n for (const node of sourceNodes) {\n if (!isSourceNodeDoc(node)) {\n continue;\n }\n const metadata = asRecord(node.metadata);\n if (\n args.normalizedUrl &&\n normalizeString(metadata.url) === args.normalizedUrl &&\n !urlMatch\n ) {\n urlMatch = node;\n }\n if (\n args.sha &&\n normalizeString(metadata.contentSha) === args.sha &&\n !shaMatch\n ) {\n shaMatch = node;\n }\n if (urlMatch && (!args.sha || shaMatch)) {\n break;\n }\n }\n\n if (urlMatch && shaMatch && String(urlMatch._id) !== String(shaMatch._id)) {\n throwStructuredSourceError({\n message:\n \"Source identity conflict: URL and SHA resolve to different source nodes.\",\n status: 409,\n code: \"CONTENT_SHA_MISMATCH\",\n invariantCode: \"source.content_hash_immutable\",\n suggestion:\n \"Same source identity resolves to different records. Create a new source with a distinct URL or use fork semantics.\",\n details: {\n urlSourceId: String(urlMatch._id),\n shaSourceId: String(shaMatch._id),\n },\n });\n }\n\n return urlMatch ?? shaMatch;\n}\n\nfunction buildSourceMetadata(args: {\n existingMetadata?: Record<string, unknown>;\n normalizedUrl?: string;\n sha?: string;\n kind: string;\n capturedAt?: number;\n metadata?: Record<string, unknown>;\n}) {\n const existingMetadata = args.existingMetadata ?? {};\n const nextMetadata: Record<string, unknown> = {\n ...existingMetadata,\n kind: args.kind,\n ...args.metadata,\n };\n\n if (args.capturedAt !== undefined) {\n nextMetadata.capturedAt = args.capturedAt;\n }\n if (!Object.hasOwn(existingMetadata, \"url\") && args.normalizedUrl) {\n nextMetadata.url = args.normalizedUrl;\n } else if (Object.hasOwn(existingMetadata, \"url\")) {\n nextMetadata.url = existingMetadata.url;\n }\n if (!Object.hasOwn(existingMetadata, \"contentSha\") && args.sha) {\n nextMetadata.contentSha = args.sha;\n } else if (Object.hasOwn(existingMetadata, \"contentSha\")) {\n nextMetadata.contentSha = existingMetadata.contentSha;\n }\n\n return nextMetadata;\n}\n\nfunction readSourceIdentity(args: UpsertSourceArgs): {\n normalizedUrl?: string;\n sha?: string;\n} {\n const sourceUrl = normalizeString(args.url);\n const normalizedUrl = sourceUrl ? normalizeSourceUrl(sourceUrl) : undefined;\n const sha = normalizeString(args.sha);\n\n if (!(normalizedUrl || sha)) {\n throwStructuredSourceError({\n message: \"Source identity requires a URL or content SHA.\",\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.identity.required\",\n suggestion: \"Provide url or sha.\",\n });\n }\n\n return { normalizedUrl, sha };\n}\n\nasync function syncSourceNodeToNeo4j(args: {\n ctx: SourceMutationCtx;\n nodeId: Id<\"epistemicNodes\">;\n}): Promise<void> {\n await args.ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {\n nodeId: args.nodeId,\n operation: \"upsert\",\n });\n}\n\nasync function insertSourceAudit(\n ctx: SourceMutationCtx,\n audit: SourceAuditRecord\n): Promise<void> {\n await ctx.db.insert(\"epistemicAudit\", { ...audit });\n}\n\nasync function updateExistingSource(args: {\n capturedAt?: number;\n ctx: SourceMutationCtx;\n existing: SourceNodeDoc;\n kind: string;\n metadataPatch: Record<string, unknown>;\n now: number;\n sha?: string;\n title?: string;\n userId: string;\n}): Promise<SourceNodeDoc> {\n if (\n args.existing.topicId &&\n !(await checkScopeAccess(\n args.ctx,\n String(args.existing.topicId),\n args.userId\n ))\n ) {\n throwStructuredSourceError({\n message: \"Access denied to existing source scope.\",\n status: 403,\n code: \"FORBIDDEN\",\n invariantCode: \"policy.scope_required\",\n suggestion: \"Request access to the source topic scope and retry.\",\n details: { topicId: args.existing.topicId },\n });\n }\n\n const existingMetadata = asRecord(args.existing.metadata);\n const existingSha = normalizeString(existingMetadata.contentSha);\n if (args.sha && existingSha && existingSha !== args.sha) {\n throwStructuredSourceError({\n message: \"Same URL cannot be reused with a different content hash.\",\n status: 409,\n code: \"CONTENT_SHA_MISMATCH\",\n invariantCode: \"source.content_hash_immutable\",\n suggestion:\n \"Same URL, different content. Create a new source with a distinct URL or use fork semantics.\",\n details: {\n sourceId: String(args.existing._id),\n url: existingMetadata.url,\n existingSha,\n receivedSha: args.sha,\n },\n });\n }\n\n const nextMetadata = buildSourceMetadata({\n existingMetadata,\n kind: args.kind,\n capturedAt: normalizeNumber(args.capturedAt),\n metadata: args.metadataPatch,\n });\n\n const patch: Record<string, unknown> = {\n metadata: nextMetadata,\n updatedAt: args.now,\n };\n const title = normalizeString(args.title);\n if (title) {\n patch.title = title;\n patch.canonicalText = title;\n }\n\n await args.ctx.db.patch(args.existing._id, patch);\n await syncSourceNodeToNeo4j({\n ctx: args.ctx,\n nodeId: args.existing._id,\n });\n\n await insertSourceAudit(args.ctx, {\n entityType: \"source\",\n entityId: String(args.existing._id),\n changeType: \"source_metadata_updated\",\n changedAt: args.now,\n changedBy: args.userId,\n isAgent: false,\n topicId: args.existing.topicId ? String(args.existing.topicId) : undefined,\n previousState: {\n title: args.existing.title,\n metadata: existingMetadata,\n },\n newState: {\n title: title ?? args.existing.title,\n metadata: nextMetadata,\n },\n });\n\n const updated = await args.ctx.db.get(args.existing._id);\n return isSourceNodeDoc(updated) ? updated : args.existing;\n}\n\nasync function createSource(args: {\n capturedAt?: number;\n ctx: SourceMutationCtx;\n kind: string;\n metadataPatch: Record<string, unknown>;\n normalizedUrl?: string;\n now: number;\n sha?: string;\n title?: string;\n topicId?: string;\n userId: string;\n}): Promise<SourceNodeDoc | null> {\n if (!normalizeString(args.topicId)) {\n throwStructuredSourceError({\n message: \"topicId is required when creating a new source.\",\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.context_required\",\n suggestion: \"Provide topicId when creating a new source node.\",\n });\n }\n\n const scope = await resolveTopicProjectScope(args.ctx, {\n topicId: args.topicId,\n });\n assertWorkspaceScopedEpistemicNodeScope({\n scope,\n nodeType: \"source\",\n mutationName: \"epistemicSources.upsertSource\",\n });\n if (scope.projectId) {\n await requireScopeWriteAccess(args.ctx, scope.projectId, args.userId);\n }\n\n const globalId = generateGlobalId();\n const title = normalizeString(args.title);\n const nextMetadata = buildSourceMetadata({\n normalizedUrl: args.normalizedUrl,\n sha: args.sha,\n kind: args.kind,\n capturedAt: normalizeNumber(args.capturedAt),\n metadata: args.metadataPatch,\n });\n const nodeId = await insertEpistemicNode(args.ctx, {\n globalId,\n topicId: scope.topicId,\n projectId: scope.projectId,\n tenantId: scope.tenantId,\n workspaceId: scope.workspaceId,\n nodeType: \"source\",\n epistemicLayer: \"L1\",\n canonicalText: title ?? args.normalizedUrl ?? \"source\",\n contentHash:\n args.sha ??\n generateSourceContentHash(args.normalizedUrl ?? title ?? \"source\"),\n ...(title ? { title } : {}),\n status: \"active\",\n createdAt: args.now,\n updatedAt: args.now,\n createdBy: args.userId,\n metadata: nextMetadata,\n });\n\n await syncSourceNodeToNeo4j({\n ctx: args.ctx,\n nodeId,\n });\n\n await scheduleEmbeddingGeneration({\n ctx: args.ctx,\n nodeId,\n projectId: scope.projectId,\n topicId: scope.topicId,\n createdBy: args.userId,\n nodeType: \"source\",\n text: sourceEmbeddingText({\n title,\n url: args.normalizedUrl,\n kind: args.kind,\n metadata: nextMetadata,\n }),\n });\n\n await insertSourceAudit(args.ctx, {\n entityType: \"source\",\n entityId: String(nodeId),\n changeType: \"source_created\",\n changedAt: args.now,\n changedBy: args.userId,\n isAgent: false,\n topicId: scope.topicId ? String(scope.topicId) : undefined,\n previousState: null,\n newState: {\n title,\n url: args.normalizedUrl,\n contentSha: args.sha,\n kind: args.kind,\n },\n });\n\n const created = await args.ctx.db.get(nodeId);\n return isSourceNodeDoc(created) ? created : null;\n}\n\nfunction sourceEmbeddingText(args: {\n title?: string;\n url?: string;\n kind: string;\n metadata: Record<string, unknown>;\n}) {\n const lines = [\n normalizeString(args.title),\n normalizeString(args.url),\n args.kind,\n normalizeString(args.metadata.sourceDescription),\n ].filter((value): value is string => Boolean(value));\n return lines.join(\"\\n\");\n}\n\nexport const upsertSource = mutation({\n args: {\n url: v.optional(v.string()),\n sha: v.optional(v.string()),\n kind: v.string(),\n title: v.optional(v.string()),\n capturedAt: v.optional(v.number()),\n metadata: v.optional(v.any()),\n topicId: v.optional(v.string()),\n userId: v.string(),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: UpsertSourceArgs) => {\n const { normalizedUrl, sha } = readSourceIdentity(args);\n const now = Date.now();\n const metadataPatch = normalizeMetadata(args.metadata);\n const existing = await findSourceByIdentity(ctx, { normalizedUrl, sha });\n\n if (existing) {\n return await updateExistingSource({\n ctx,\n existing,\n kind: args.kind,\n capturedAt: args.capturedAt,\n metadataPatch,\n now,\n sha,\n title: args.title,\n userId: args.userId,\n });\n }\n\n return await createSource({\n ctx,\n normalizedUrl,\n sha,\n kind: args.kind,\n capturedAt: args.capturedAt,\n metadataPatch,\n now,\n title: args.title,\n topicId: args.topicId,\n userId: args.userId,\n });\n },\n});\n\nexport const getById = query({\n args: {\n nodeId: v.optional(v.id(\"epistemicNodes\")),\n sourceId: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx, args: GetSourceByIdArgs) => {\n const id = args.nodeId ?? readConvexId<\"epistemicNodes\">(args.sourceId);\n if (!id) {\n return null;\n }\n const node = await ctx.db.get(id);\n if (!isSourceNodeDoc(node)) {\n return null;\n }\n return node;\n },\n});\n\nexport const findByUrl = query({\n args: {\n url: v.string(),\n },\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx, args: SourceUrlQueryArgs) => {\n const normalizedUrl = normalizeSourceUrl(args.url);\n const node = await findSourceByIdentity(ctx, { normalizedUrl });\n return node?.nodeType === \"source\" ? node : null;\n },\n});\n\nexport const findBySha = query({\n args: {\n sha: v.string(),\n },\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx, args: SourceShaQueryArgs) => {\n const sha = normalizeString(args.sha);\n if (!sha) {\n return null;\n }\n const node = await findSourceByIdentity(ctx, { sha });\n return node?.nodeType === \"source\" ? node : null;\n },\n});\n"]}
1
+ {"version":3,"sources":["../src/convex.ts","../src/debug.ts","../src/embeddingTrigger.ts","../src/epistemicInsert.ts","../src/topicScope.ts","../src/workspaceIsolation.ts","../src/epistemicSources.ts"],"names":["query","normalizeScopeValue","v"],"mappings":"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","file":"epistemicSources.js","sourcesContent":["import type { Doc as AccessControlDoc } from \"@lucern/access-control/convex\";\nimport {\n type UnsafeConvexAnyApi,\n unsafeConvexAnyApi,\n} from \"@lucern/contracts/convex/unsafeAnyApi\";\nimport {\n actionGeneric,\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.\nconst unsafeApi = unsafeConvexAnyApi(\n \"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface\"\n);\nexport const api = unsafeApi;\nexport const components =\n componentsGeneric() as unknown as UntypedFunctionReferenceSurface;\nexport const internal = unsafeApi;\n\ntype UntypedFunctionReferenceSurface = UnsafeConvexAnyApi;\ntype BoundaryValue = UntypedFunctionReferenceSurface[string];\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> =\n AccessControlDoc<TableName>;\nexport type DataModel = Record<TableNames, unknown>;\ninterface IndexRangeBuilder {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n field(fieldName: string): string;\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}\ninterface FilterBuilder {\n and(...clauses: unknown[]): FilterBuilder;\n eq(left: unknown, right: unknown): FilterBuilder;\n field(fieldName: string): string;\n gt(left: unknown, right: unknown): FilterBuilder;\n gte(left: unknown, right: unknown): FilterBuilder;\n lt(left: unknown, right: unknown): FilterBuilder;\n lte(left: unknown, right: unknown): FilterBuilder;\n neq(left: unknown, right: unknown): FilterBuilder;\n or(...clauses: unknown[]): FilterBuilder;\n [operator: string]: unknown;\n}\ninterface QueryInitializer<TableName extends TableNames> {\n collect(): Promise<Doc<TableName>[]>;\n filter(predicate: (q: FilterBuilder) => unknown): QueryInitializer<TableName>;\n first(): Promise<Doc<TableName> | null>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n take(limit: number): Promise<Doc<TableName>[]>;\n unique(): Promise<Doc<TableName> | null>;\n withIndex(\n indexName: string,\n range?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n withSearchIndex(\n indexName: string,\n search?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n}\nexport interface DatabaseReader {\n get<TableName extends TableNames>(\n id: unknown\n ): Promise<Doc<TableName> | null>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\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};\ninterface Scheduler {\n runAfter(\n delayMs: number,\n functionReference: unknown,\n args?: unknown\n ): Promise<void>;\n}\ninterface AuthReader {\n getUserIdentity(): Promise<{\n readonly subject: string;\n readonly [claimName: string]: unknown;\n } | null>;\n}\ninterface RuntimeInvoker {\n runAction<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runMutation<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runQuery<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\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 Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\ntype OptionalHandlerConvexFunctionBuilder<Ctx> = <\n Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler?: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\nexport const action =\n 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 OptionalHandlerConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as OptionalHandlerConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","interface GraphPrimitiveDebugEnvironment {\n process?: {\n env?: Record<string, string | undefined>;\n };\n}\n\nfunction isGraphPrimitiveDebugEnabled(): boolean {\n const env = (globalThis as GraphPrimitiveDebugEnvironment).process?.env;\n return (\n env?.LUCERN_COMPAT_FALLBACK_DEBUG === \"1\" || env?.LUCERN_GRAPH_DEBUG === \"1\"\n );\n}\n\nexport function formatGraphPrimitiveError(error: unknown): string {\n if (error instanceof Error) {\n return `${error.name}: ${error.message}`;\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error === null) {\n return \"null\";\n }\n if (error === undefined) {\n return \"undefined\";\n }\n try {\n return JSON.stringify(error);\n } catch {\n return Object.prototype.toString.call(error);\n }\n}\n\nexport function debugGraphPrimitiveFallback(\n message: string,\n context?: Record<string, unknown>\n): void {\n if (!isGraphPrimitiveDebugEnabled()) {\n return;\n }\n console.debug(message, context ?? {});\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public ABI surface; rename requires a cross-package migration update.\n/**\n * Shared helper to schedule embedding generation after epistemic node creation.\n *\n * Best-effort — failures are silently caught. The embedding generation action\n * is a public action in convex/embeddingActions.ts that calls Pinecone.\n */\n\nimport type { Id } from \"./convex\";\nimport { debugGraphPrimitiveFallback } from \"./debug\";\n\ninterface EmbeddingScheduler {\n runAfter(\n delayMs: number,\n functionReference: unknown,\n args?: unknown\n ): Promise<void>;\n}\n\ninterface EmbeddingTriggerContext {\n scheduler: EmbeddingScheduler;\n}\n\ninterface EmbeddingTriggerArgs {\n confidence?: number;\n createdBy: string;\n ctx: EmbeddingTriggerContext;\n hasAnswer?: boolean;\n nodeId: Id<\"epistemicNodes\">;\n nodeType:\n | \"belief\"\n | \"question\"\n | \"evidence\"\n | \"answer\"\n | \"synthesis\"\n | \"theme\"\n | \"source\";\n projectId?: string | null;\n text: string;\n topicId?: string | null;\n}\n\nconst embeddingActionRef = \"embeddingActions:generateEpistemicNodeEmbedding\";\n\nexport async function scheduleEmbeddingGeneration(\n args: EmbeddingTriggerArgs\n): Promise<void> {\n try {\n await args.ctx.scheduler.runAfter(0, embeddingActionRef, {\n nodeId: args.nodeId,\n projectId: args.projectId ? String(args.projectId) : undefined,\n topicId: args.topicId ? String(args.topicId) : undefined,\n createdBy: args.createdBy,\n nodeType: args.nodeType,\n text: args.text.slice(0, 20_000),\n hasAnswer: args.hasAnswer,\n confidence: args.confidence,\n });\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[embeddingTrigger] Failed to schedule embedding generation\",\n {\n error,\n nodeId: String(args.nodeId),\n nodeType: args.nodeType,\n }\n );\n // Embedding generation is best-effort — never block node creation\n }\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\nimport {\n assertEdgePolicyAllowed,\n type EpistemicNodeType,\n edgePolicyManifest,\n} from \"@lucern/contracts\";\nimport {\n assertStorageEdgeVocabulary,\n assertUuidShapedEdgeEndpoint,\n assertUuidV7Identity,\n} from \"@lucern/contracts/ids\";\nimport type { Id, MutationCtx } from \"./convex\";\n\ninterface GlobalIdIndexQuery {\n eq(field: \"globalId\", value: string): GlobalIdIndexQuery;\n}\n\ninterface EpistemicNodeInsertDoc extends Record<string, unknown> {\n globalId: string;\n}\n\ninterface EpistemicEdgeInsertDoc extends Record<string, unknown> {\n edgeType: string;\n fromNodeId: string;\n fromNodeType?: string;\n globalId: string;\n toNodeId: string;\n toNodeType?: string;\n}\n\nexport function insertEpistemicNode(\n ctx: MutationCtx,\n doc: EpistemicNodeInsertDoc\n): Promise<Id<\"epistemicNodes\">> {\n assertUuidV7Identity(\"epistemicNodes\", doc.globalId);\n return ctx.db.insert(\"epistemicNodes\", doc);\n}\n\n/**\n * C2-RR.4b — REFERENTIAL edge-endpoint canonicality (amends RR.4's FORMAT guard).\n *\n * Proves an endpoint is the UUIDv7 `globalId` of an EXISTING\n * `epistemicNodes` row. Refuses doc ids, fabricated/unknown endpoints, and\n * legacy UUIDv4 `globalId`s; those must be reminted through the identity\n * backfill ledger before participating in new edge writes.\n */\nasync function assertExistingNodeEndpoint(\n ctx: MutationCtx,\n endpointRole: \"fromNodeId\" | \"toNodeId\",\n endpoint: string\n): Promise<void> {\n assertUuidShapedEdgeEndpoint(endpointRole, endpoint);\n const node = await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_globalId\", (q: GlobalIdIndexQuery) =>\n q.eq(\"globalId\", endpoint)\n )\n .first();\n if (!node) {\n throw new Error(\n `edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`\n );\n }\n}\n\nexport async function insertEpistemicEdge(\n ctx: MutationCtx,\n doc: EpistemicEdgeInsertDoc\n): Promise<Id<\"epistemicEdges\">> {\n assertUuidV7Identity(\"epistemicEdges\", doc.globalId);\n\n // R1.1a — STORAGE-VOCABULARY MEMBERSHIP\n assertStorageEdgeVocabulary(doc.edgeType);\n\n // R1.1b — ENDPOINT PRESENCE\n if (!doc.fromNodeId || typeof doc.fromNodeId !== \"string\") {\n throw new Error(\n \"edge_endpoint_missing: epistemicEdges insert requires a non-empty fromNodeId\"\n );\n }\n if (!doc.toNodeId || typeof doc.toNodeId !== \"string\") {\n throw new Error(\n \"edge_endpoint_missing: epistemicEdges insert requires a non-empty toNodeId\"\n );\n }\n\n // C2-RR.4b Defect E (REFERENTIAL) — ENDPOINT CANONICAL IDENTITY. Edge\n // endpoints must each be the globalId of an EXISTING epistemicNodes row,\n // never a Convex doc id, a legacy topic id, or a fabricated/unknown uuid.\n // This refuses mixed _id/globalId endpoint writes at the floor and keeps\n // legacy UUIDv4 graph rows inside the explicit remint/backfill lane.\n await assertExistingNodeEndpoint(ctx, \"fromNodeId\", doc.fromNodeId);\n await assertExistingNodeEndpoint(ctx, \"toNodeId\", doc.toNodeId);\n\n // R1.1c — FULL POLICY ASSERT (when nodeTypes are present and edgeType is in public manifest)\n if (doc.fromNodeType && doc.toNodeType && doc.edgeType !== \"extracted_from\") {\n assertEdgePolicyAllowed(\n edgePolicyManifest,\n doc.edgeType,\n {\n kind: \"epistemic_node\",\n nodeId: doc.fromNodeId,\n nodeType: doc.fromNodeType as EpistemicNodeType,\n },\n {\n kind: \"epistemic_node\",\n nodeId: doc.toNodeId,\n nodeType: doc.toNodeType as EpistemicNodeType,\n }\n );\n }\n\n return ctx.db.insert(\"epistemicEdges\", doc);\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/** Topic-scope resolution helpers for graph-primitive operations. */\nimport { v } from \"convex/values\";\nimport type { Id } from \"./convex\";\nimport { api as appApi } from \"./convex\";\nimport { debugGraphPrimitiveFallback } from \"./debug\";\n\nconst LEGACY_SCOPE_FIELD = \"graphScopeProjectId\";\n\ntype UnknownRecord = Record<string, unknown>;\n\ninterface TopicScopeContext {\n db: {\n get(id: string): Promise<unknown>;\n query(tableName: string): TopicScopeQuery;\n };\n runQuery?: <TResult>(fnRef: unknown, args: unknown) => Promise<TResult>;\n}\n\ninterface TopicScopeQuery {\n collect(): Promise<unknown[]>;\n first(): Promise<unknown | null>;\n withIndex(\n indexName: string,\n range?: (q: TopicScopeIndexRangeBuilder) => unknown\n ): TopicScopeQuery;\n}\n\ninterface TopicScopeIndexRangeBuilder {\n eq(field: string, value: unknown): TopicScopeIndexRangeBuilder;\n}\n\ntype TopicDoc = Record<string, unknown> & {\n _id: Id<\"topics\">;\n globalId?: string;\n name?: string;\n depth?: number;\n createdAt?: number;\n parentTopicId?: Id<\"topics\">;\n tenantId?: string;\n workspaceId?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport interface TopicProjectScope {\n projectId?: string;\n source: \"topic\" | \"project_mapped_topic\" | \"topic_inferred\" | \"topic_node\";\n tenantId?: string;\n topicId: Id<\"topics\">;\n workspaceId?: string;\n}\n\n/**\n * RR.5 (legacy topics-table retirement) — graph-primitives mirror of the\n * kernel's epistemicNodes-first topic-scope fallback. Kept in lockstep with\n * `packages/reasoning-kernel/src/adapters/lib/topicScope.ts`\n * (`tests/unit/convex/topic-scope-fallbacks.test.ts` asserts parity).\n *\n * Resolves a topic that exists only as `epistemicNodes(nodeType=\"topic\")` —\n * the write-of-record — when no legacy `topics` row backs the ref, returning the\n * node's `topicId` self-key so scoped beliefs/evidence/questions stay reachable.\n * See the kernel module for the full silent-empty-result rationale.\n */\ninterface TopicNodeScopeDoc {\n _id: string | Id<\"epistemicNodes\">;\n globalId?: string;\n metadata?: UnknownRecord;\n nodeType?: string;\n topicId?: string;\n}\n\nasync function resolveTopicNodeScopeOrNull(\n ctx: TopicScopeContext,\n ref: string\n): Promise<TopicProjectScope | null> {\n if (!ctx?.db || typeof ctx.db.query !== \"function\") {\n return null;\n }\n\n let node: TopicNodeScopeDoc | null = null;\n\n // 1. The ref IS the topic node's UUIDv7 globalId.\n try {\n const byGlobalId = (await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_globalId\", (q) => q.eq(\"globalId\", ref))\n .first()) as TopicNodeScopeDoc | null;\n if (byGlobalId && byGlobalId.nodeType === \"topic\") {\n node = byGlobalId;\n }\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] topic-node scope lookup by globalId failed\",\n { error, ref }\n );\n }\n\n if (!node) {\n return null;\n }\n\n const scopeKey =\n normalizeScopeValue(node.topicId) ?? normalizeScopeValue(node.globalId);\n if (!scopeKey) {\n return null;\n }\n\n return {\n topicId: scopeKey as Id<\"topics\">,\n projectId: asMappedProjectId(node),\n source: \"topic_node\",\n };\n}\n\ninterface MaterializedTopicNodeDoc {\n _id: string | Id<\"epistemicNodes\">;\n metadata?: Record<string, unknown>;\n}\n\nfunction asMappedProjectId(\n topic: Pick<TopicDoc, \"metadata\"> | TopicNodeScopeDoc | null | undefined\n): string | undefined {\n if (!topic) {\n return;\n }\n const directLegacyProjectId = normalizeScopeValue(\n (topic as UnknownRecord)[LEGACY_SCOPE_FIELD]\n );\n if (directLegacyProjectId) {\n return directLegacyProjectId;\n }\n const metadata = topic.metadata || {};\n const candidate =\n (metadata as UnknownRecord)[LEGACY_SCOPE_FIELD] ||\n (metadata as UnknownRecord).legacyProjectId ||\n (metadata as UnknownRecord).projectId ||\n (metadata as UnknownRecord).scopeProjectId;\n return typeof candidate === \"string\"\n ? normalizeScopeValue(candidate)\n : undefined;\n}\n\nfunction normalizeScopeValue(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return;\n }\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction pickPrimaryTopic(candidates: TopicDoc[]): TopicDoc | undefined {\n return [...candidates].sort((a, b) => {\n const depthA = a.depth ?? 9999;\n const depthB = b.depth ?? 9999;\n if (depthA !== depthB) {\n return depthA - depthB;\n }\n const createdA = a.createdAt ?? Number.MAX_SAFE_INTEGER;\n const createdB = b.createdAt ?? Number.MAX_SAFE_INTEGER;\n if (createdA !== createdB) {\n return createdA - createdB;\n }\n return String(a.name || \"\").localeCompare(String(b.name || \"\"));\n })[0];\n}\n\nasync function findTopicsByScopeAlias(\n ctx: TopicScopeContext,\n scopeId: string\n): Promise<TopicDoc[]> {\n const query = ctx.db.query(\"topics\") as TopicScopeQuery;\n try {\n return (await query\n .withIndex(\"by_graph_scope_project\", (q) =>\n q.eq(LEGACY_SCOPE_FIELD, scopeId)\n )\n .collect()) as TopicDoc[];\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] Failed to resolve scope alias via index\",\n {\n error,\n scopeId,\n }\n );\n // Older Lucern dev deployments can lag index backfills while still carrying\n // the underlying topics table. Scan and filter so scope resolution keeps\n // working during the rollout.\n const topics = (await query.collect()) as TopicDoc[];\n return topics.filter((topic) => {\n const normalizedGlobalId = normalizeScopeValue(topic.globalId);\n const mappedProjectId = asMappedProjectId(topic);\n return (\n String(topic._id) === scopeId ||\n normalizedGlobalId === scopeId ||\n mappedProjectId === scopeId\n );\n });\n }\n}\n\nasync function tryResolveHostTopicById(\n ctx: TopicScopeContext,\n topicId: string\n): Promise<TopicDoc | null> {\n if (typeof ctx.runQuery !== \"function\") {\n return null;\n }\n try {\n return ((await ctx.runQuery(appApi.topics.get, {\n id: topicId,\n })) ?? null) as TopicDoc | null;\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] Failed to resolve topic by host query\",\n {\n error,\n topicId,\n }\n );\n return null;\n }\n}\n\nasync function tryResolveHostTopicByLegacyScope(\n ctx: TopicScopeContext,\n legacyScopeId: string\n): Promise<TopicDoc | null> {\n if (typeof ctx.runQuery !== \"function\") {\n return null;\n }\n try {\n return ((await ctx.runQuery(appApi.topics.getByLegacyScopeId, {\n projectId: legacyScopeId,\n })) ?? null) as TopicDoc | null;\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[topicScope] Failed to resolve topic by legacy scope\",\n {\n error,\n legacyScopeId,\n }\n );\n return null;\n }\n}\n\nexport function readMaterializedTopicTableId(\n topicNode: MaterializedTopicNodeDoc | null | undefined\n): string | undefined {\n if (!topicNode) {\n return;\n }\n\n const metadata = (topicNode.metadata || {}) as Record<string, unknown>;\n const topicTableId =\n (metadata.topicTableId as string | undefined) ||\n (metadata.topicId as string | undefined);\n\n return typeof topicTableId === \"string\" && topicTableId.trim().length > 0\n ? topicTableId.trim()\n : undefined;\n}\n\n/**\n * Walk the topic parent chain to find inherited workspaceId and tenantId.\n * Mirrors the pattern used by resolveTopicOntology for ontologyId inheritance.\n * Max depth: 10 (defensive limit against pathological nesting).\n */\nasync function resolveInheritedWorkspaceScope(\n ctx: TopicScopeContext,\n topic: TopicDoc\n): Promise<{ tenantId?: string; workspaceId?: string }> {\n const MAX_DEPTH = 10;\n let tenantId = normalizeScopeValue(topic.tenantId);\n let workspaceId = normalizeScopeValue(topic.workspaceId);\n\n if (tenantId && workspaceId) {\n return { tenantId, workspaceId };\n }\n\n let current: TopicDoc | null = topic;\n for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {\n current = (await ctx.db.get(current.parentTopicId)) as TopicDoc | null;\n if (!current) {\n break;\n }\n\n if (!tenantId) {\n tenantId = normalizeScopeValue(current.tenantId);\n }\n if (!workspaceId) {\n workspaceId = normalizeScopeValue(current.workspaceId);\n }\n if (tenantId && workspaceId) {\n break;\n }\n }\n\n return { tenantId, workspaceId };\n}\n\nexport async function resolveTopicProjectScope(\n ctx: TopicScopeContext,\n args: { topicId?: Id<\"topics\"> | string; projectId?: string }\n): Promise<TopicProjectScope> {\n if (args.topicId) {\n return await resolveScopeFromTopicId(ctx, args.topicId);\n }\n\n if (args.projectId) {\n return await resolveScopeFromLegacyProjectId(ctx, args.projectId);\n }\n\n throw new Error(\n \"Missing scope: provide topicId (preferred) or legacy projectId alias.\"\n );\n}\n\nasync function resolveScopeFromTopicId(\n ctx: TopicScopeContext,\n topicId: Id<\"topics\"> | string\n): Promise<TopicProjectScope> {\n const topic = await resolveTopicDocFromTopicId(ctx, topicId);\n if (topic) {\n return await buildTopicScope(ctx, topic, \"topic\");\n }\n\n const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));\n if (nodeScope) {\n return nodeScope;\n }\n throw new Error(`Topic not found: ${String(topicId)}`);\n}\n\nasync function resolveTopicDocFromTopicId(\n ctx: TopicScopeContext,\n topicId: Id<\"topics\"> | string\n): Promise<TopicDoc | null> {\n const direct = await tryReadTopicDoc(ctx, topicId, {\n failureLog: \"[topicScope] Failed to load topic by direct id\",\n idLogKey: \"topicId\",\n });\n if (direct) {\n return direct;\n }\n\n const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));\n if (hostTopic) {\n return hostTopic;\n }\n\n return (\n pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null\n );\n}\n\nasync function resolveScopeFromLegacyProjectId(\n ctx: TopicScopeContext,\n legacyProjectId: string\n): Promise<TopicProjectScope> {\n const directTopic = await resolveDirectLegacyProjectTopic(\n ctx,\n legacyProjectId\n );\n if (directTopic) {\n return await buildTopicScope(ctx, directTopic, \"topic_inferred\", {\n fallbackProjectId: legacyProjectId,\n });\n }\n\n const primary = pickPrimaryTopic(\n await findTopicsByScopeAlias(ctx, legacyProjectId)\n );\n if (primary) {\n return await buildTopicScope(ctx, primary, \"project_mapped_topic\", {\n fallbackProjectId: legacyProjectId,\n });\n }\n\n const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);\n if (nodeScope) {\n return {\n ...nodeScope,\n projectId: nodeScope.projectId ?? legacyProjectId,\n };\n }\n\n throw new Error(\n `Legacy project scope ${legacyProjectId} has no mapped topic.`\n );\n}\n\nasync function resolveDirectLegacyProjectTopic(\n ctx: TopicScopeContext,\n legacyProjectId: string\n): Promise<TopicDoc | null> {\n const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {\n failureLog: \"[topicScope] Failed to load direct project topic\",\n idLogKey: \"projectId\",\n });\n return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);\n}\n\nasync function tryReadTopicDoc(\n ctx: TopicScopeContext,\n id: Id<\"topics\"> | string,\n log: { failureLog: string; idLogKey: \"projectId\" | \"topicId\" }\n): Promise<TopicDoc | null> {\n try {\n return (await ctx.db.get(id)) as TopicDoc | null;\n } catch (error) {\n debugGraphPrimitiveFallback(log.failureLog, {\n error,\n [log.idLogKey]: id,\n });\n return null;\n }\n}\n\nasync function buildTopicScope(\n ctx: TopicScopeContext,\n topic: TopicDoc,\n source: TopicProjectScope[\"source\"],\n options: { fallbackProjectId?: string } = {}\n): Promise<TopicProjectScope> {\n const inherited = await resolveInheritedWorkspaceScope(ctx, topic);\n const mapped = asMappedProjectId(topic);\n return {\n topicId: topic._id,\n ...(mapped || options.fallbackProjectId\n ? { projectId: mapped ?? options.fallbackProjectId }\n : {}),\n tenantId: inherited.tenantId,\n workspaceId: inherited.workspaceId,\n source,\n };\n}\n\n/** Shared scope args for graph-primitive functions. topicId is canonical; projectId is a legacy alias. */\nexport const optionalScopeArgs = {\n projectId: v.optional(v.string()),\n topicId: v.optional(v.string()),\n} as const;\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\nimport {\n getLayerForNodeType,\n isNodeType,\n} from \"@lucern/contracts/schema-helpers/spine/tables/epistemicNodes\";\nimport type { MutationCtx, QueryCtx } from \"./convex\";\nimport { resolveTopicProjectScope, type TopicProjectScope } from \"./topicScope\";\n\ntype StructuredInvariantError = Error & {\n status: number;\n code: string;\n invariantCode?: string;\n suggestion?: string;\n details?: unknown;\n};\n\ninterface ScopeLike {\n epistemicLayer?: unknown;\n nodeType?: unknown;\n projectId?: unknown;\n publicationStatus?: unknown;\n tenantId?: unknown;\n topicId?: unknown;\n workspaceId?: unknown;\n}\n\nexport interface RuntimePackMutationContext {\n packInstallScope?: \"tenant\" | \"workspace\";\n packKey?: string;\n toolName?: string;\n}\n\nexport function normalizeScopeValue(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return;\n }\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction throwWorkspaceIsolationError(args: {\n message: string;\n invariantCode: string;\n suggestion: string;\n details?: unknown;\n}): never {\n const error = new Error(args.message) as StructuredInvariantError;\n error.status = 409;\n error.code = \"INVARIANT_VIOLATION\";\n error.invariantCode = args.invariantCode;\n error.suggestion = args.suggestion;\n error.details = args.details;\n throw error;\n}\n\nexport function assertWorkspaceScopedEpistemicNodeScope(args: {\n scope: TopicProjectScope;\n nodeType: string;\n mutationName: string;\n}): void {\n const layer = isNodeType(args.nodeType)\n ? getLayerForNodeType(args.nodeType)\n : undefined;\n if (layer === \"ontological\") {\n return;\n }\n\n const workspaceId = normalizeScopeValue(args.scope.workspaceId);\n if (workspaceId) {\n return;\n }\n\n throwWorkspaceIsolationError({\n message:\n \"Workspace-scoped reasoning isolation requires workspaceId on non-ontological node creation.\",\n invariantCode: \"workspace.scope_required_for_epistemic_nodes\",\n suggestion:\n \"Resolve the topic/project scope through a workspace-bound topic before creating epistemic nodes.\",\n details: {\n mutationName: args.mutationName,\n nodeType: args.nodeType,\n topicId: args.scope.topicId,\n projectId: args.scope.projectId,\n },\n });\n}\n\nexport function nodeMatchesWorkspaceReasoningScope(\n node: ScopeLike | null | undefined,\n scope: Pick<TopicProjectScope, \"tenantId\" | \"workspaceId\">\n): boolean {\n if (!node) {\n return false;\n }\n\n const scopeTenantId = normalizeScopeValue(scope.tenantId);\n const scopeWorkspaceId = normalizeScopeValue(scope.workspaceId);\n const nodeTenantId = normalizeScopeValue(node.tenantId);\n const nodeWorkspaceId = normalizeScopeValue(node.workspaceId);\n const epistemicLayer =\n typeof node.epistemicLayer === \"string\" ? node.epistemicLayer : undefined;\n\n if (scopeTenantId && nodeTenantId && scopeTenantId !== nodeTenantId) {\n return false;\n }\n\n // Ontological entities are tenant-global (no workspace required)\n if (epistemicLayer === \"ontological\" && nodeWorkspaceId === undefined) {\n return true;\n }\n\n // Published nodes are visible at tenant scope — the microservice API surface.\n // The node stays in its workspace, but tenant-scope queries can see it.\n if (!scopeWorkspaceId && node.publicationStatus === \"published\") {\n return true;\n }\n\n if (!scopeWorkspaceId) {\n return nodeWorkspaceId === undefined;\n }\n\n return scopeWorkspaceId === nodeWorkspaceId;\n}\n\nexport function edgeMatchesWorkspaceReasoningScope(\n edge: ScopeLike | null | undefined,\n scope: Pick<TopicProjectScope, \"tenantId\" | \"workspaceId\">\n): boolean {\n if (!edge) {\n return false;\n }\n\n const scopeTenantId = normalizeScopeValue(scope.tenantId);\n const scopeWorkspaceId = normalizeScopeValue(scope.workspaceId);\n const edgeTenantId = normalizeScopeValue(edge.tenantId);\n const edgeWorkspaceId = normalizeScopeValue(edge.workspaceId);\n\n if (scopeTenantId && edgeTenantId && scopeTenantId !== edgeTenantId) {\n return false;\n }\n\n if (!scopeWorkspaceId) {\n return edgeWorkspaceId === undefined;\n }\n\n return scopeWorkspaceId === edgeWorkspaceId;\n}\n\nexport async function resolveNodeScopeForWorkspaceIsolation(\n ctx: QueryCtx | MutationCtx,\n node: ScopeLike | null | undefined\n): Promise<{\n tenantId?: string;\n workspaceId?: string;\n epistemicLayer?: string;\n nodeType?: string;\n}> {\n const epistemicLayer =\n typeof node?.epistemicLayer === \"string\" ? node.epistemicLayer : undefined;\n const resolved = {\n tenantId: normalizeScopeValue(node?.tenantId),\n workspaceId: normalizeScopeValue(node?.workspaceId),\n epistemicLayer,\n nodeType: typeof node?.nodeType === \"string\" ? node.nodeType : undefined,\n };\n\n if (!node) {\n return resolved;\n }\n\n if (resolved.epistemicLayer === \"ontological\") {\n return resolved;\n }\n\n if (resolved.tenantId || resolved.workspaceId) {\n return resolved;\n }\n\n const topicId = normalizeScopeValue(node.topicId);\n if (topicId) {\n const topicScope = await resolveTopicProjectScope(ctx, {\n topicId,\n });\n return {\n ...resolved,\n tenantId: topicScope.tenantId,\n workspaceId: topicScope.workspaceId,\n };\n }\n\n if (node.projectId) {\n const topicScope = await resolveTopicProjectScope(ctx, {\n projectId: String(node.projectId),\n });\n return {\n ...resolved,\n tenantId: topicScope.tenantId,\n workspaceId: topicScope.workspaceId,\n };\n }\n\n return resolved;\n}\n\nexport function resolveRuntimePackMutationContext(args: {\n runtimeToolName?: string;\n runtimePackKey?: string;\n runtimePackInstallScope?: \"tenant\" | \"workspace\";\n}): RuntimePackMutationContext | undefined {\n if (\n !(\n args.runtimeToolName ||\n args.runtimePackKey ||\n args.runtimePackInstallScope\n )\n ) {\n return;\n }\n\n return {\n toolName: args.runtimeToolName,\n packKey: args.runtimePackKey,\n packInstallScope: args.runtimePackInstallScope,\n };\n}\n\nexport function assertTenantPackWorkspaceMutationAllowed(args: {\n runtime?: RuntimePackMutationContext;\n target: ScopeLike;\n mutationName: string;\n}): void {\n if (!args.runtime?.packKey || args.runtime.packInstallScope !== \"tenant\") {\n return;\n }\n\n const targetWorkspaceId = normalizeScopeValue(args.target.workspaceId);\n const targetLayer =\n typeof args.target.epistemicLayer === \"string\"\n ? args.target.epistemicLayer\n : undefined;\n\n if (!targetWorkspaceId || targetLayer === \"ontological\") {\n return;\n }\n\n throwWorkspaceIsolationError({\n message: `Tenant-scoped pack \"${args.runtime.packKey}\" cannot mutate workspace-scoped reasoning state.`,\n invariantCode: \"workspace.tenant_pack_reasoning_write_forbidden\",\n suggestion:\n \"Use a workspace-scoped pack for workspace-local graph mutations, or route the change through tenant-global canonical entity flows.\",\n details: {\n mutationName: args.mutationName,\n toolName: args.runtime.toolName,\n packKey: args.runtime.packKey,\n targetWorkspaceId,\n targetNodeType: args.target.nodeType,\n targetLayer,\n },\n });\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/**\n * Epistemic Sources API\n *\n * Invariants:\n * - Invariant 7: evidence is context-bound. Sources carry topic, author, and capture time.\n * - Invariant 8: no retroactive reinterpretation. Source identity fields stay immutable.\n * - Invariant 14: no silent state transitions. Every create/update is audited.\n * - Invariant 15: retrieval respects boundaries. Sources live at L1 terminal leaves.\n */\n\nimport {\n checkScopeAccess,\n requireScopeWriteAccess,\n} from \"@lucern/access-control/access\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport { v } from \"convex/values\";\nimport type { Doc, Id, MutationCtx, QueryCtx } from \"./convex\";\nimport { internal, mutation, query } from \"./convex\";\nimport { scheduleEmbeddingGeneration } from \"./embeddingTrigger\";\nimport { insertEpistemicNode } from \"./epistemicInsert.js\";\nimport type { EpistemicDbReader } from \"./epistemicQuestions.helpers\";\nimport { generateGlobalId } from \"./globalId\";\nimport { resolveTopicProjectScope } from \"./topicScope\";\nimport { assertWorkspaceScopedEpistemicNodeScope } from \"./workspaceIsolation\";\n\nconst TRAILING_SLASHES_PATTERN = /\\/+$/;\nconst HASH_MODULUS = 2 ** 32;\nconst HASH_SIGN_BOUNDARY = 2 ** 31;\n\ntype SourceMutationCtx = MutationCtx;\ntype SourceNodeDoc = Doc<\"epistemicNodes\"> & {\n _id: Id<\"epistemicNodes\">;\n metadata?: Record<string, unknown>;\n nodeType?: string;\n title?: string;\n topicId?: string;\n};\ntype SourceAuditChangeType = \"source_created\" | \"source_metadata_updated\";\n\ninterface SourceAuditRecord {\n changedAt: number;\n changedBy: string;\n changeType: SourceAuditChangeType;\n entityId: string;\n entityType: \"source\";\n isAgent: false;\n newState?: Record<string, unknown> | null;\n previousState?: Record<string, unknown> | null;\n topicId?: string;\n}\n\ninterface UpsertSourceArgs {\n capturedAt?: number;\n kind: string;\n metadata?: unknown;\n sha?: string;\n title?: string;\n topicId?: string;\n url?: string;\n userId: string;\n}\n\ninterface GetSourceByIdArgs {\n nodeId?: Id<\"epistemicNodes\">;\n sourceId?: string;\n}\n\ninterface SourceUrlQueryArgs {\n url: string;\n}\n\ninterface SourceShaQueryArgs {\n sha: string;\n}\n\ntype StructuredSourceError = Error & {\n status: number;\n code: string;\n invariantCode?: string;\n suggestion?: string;\n details?: unknown;\n};\n\nfunction throwStructuredSourceError(args: {\n message: string;\n status: number;\n code: string;\n invariantCode?: string;\n suggestion?: string;\n details?: unknown;\n}): never {\n const error = new Error(args.message) as StructuredSourceError;\n error.status = args.status;\n error.code = args.code;\n error.invariantCode = args.invariantCode;\n error.suggestion = args.suggestion;\n error.details = args.details;\n throw error;\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return;\n }\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction readConvexId<TableName extends string>(\n value: unknown\n): Id<TableName> | null {\n const normalized = normalizeString(value);\n return normalized ? (normalized as Id<TableName>) : null;\n}\n\nfunction normalizeNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n\nfunction isSourceNodeDoc(value: unknown): value is SourceNodeDoc {\n const record = asRecord(value);\n return (\n readConvexId<\"epistemicNodes\">(record._id) !== null &&\n normalizeString(record.nodeType) === \"source\"\n );\n}\n\nfunction normalizeMetadata(metadata: unknown): Record<string, unknown> {\n const record = asRecord(metadata);\n const { url: _ignoredUrl, contentSha: _ignoredSha, ...rest } = record;\n return rest;\n}\n\nfunction toSignedInt32(value: number): number {\n const normalized = ((value % HASH_MODULUS) + HASH_MODULUS) % HASH_MODULUS;\n return normalized >= HASH_SIGN_BOUNDARY\n ? normalized - HASH_MODULUS\n : normalized;\n}\n\nfunction generateSourceContentHash(identity: string): string {\n const content = `source:${identity.trim().toLowerCase()}`;\n let hash = 5381;\n for (let index = 0; index < content.length; index += 1) {\n hash = toSignedInt32(hash * 33 + content.charCodeAt(index));\n }\n return Math.abs(hash).toString(16).padStart(8, \"0\");\n}\n\nexport function normalizeSourceUrl(url: string): string {\n const trimmed = normalizeString(url);\n if (!trimmed) {\n throwStructuredSourceError({\n message: \"Source URL is required.\",\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.url.valid\",\n suggestion: \"Provide an absolute URL with a valid protocol and host.\",\n });\n }\n\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n throwStructuredSourceError({\n message: `Invalid URL: ${trimmed}`,\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.url.valid\",\n suggestion: \"Provide an absolute URL with a valid protocol and host.\",\n details: { url: trimmed },\n });\n }\n\n const protocol = parsed.protocol.toLowerCase();\n const hostname = parsed.hostname.toLowerCase();\n const port = parsed.port ? `:${parsed.port}` : \"\";\n const pathname =\n parsed.pathname === \"/\"\n ? \"\"\n : parsed.pathname.replace(TRAILING_SLASHES_PATTERN, \"\");\n\n const sortedEntries = [...parsed.searchParams.entries()].sort(\n ([aKey, aValue], [bKey, bValue]) =>\n aKey === bKey ? aValue.localeCompare(bValue) : aKey.localeCompare(bKey)\n );\n const params = new URLSearchParams();\n for (const [key, value] of sortedEntries) {\n params.append(key, value);\n }\n const search = params.toString();\n\n return `${protocol}//${hostname}${port}${pathname}${\n search.length > 0 ? `?${search}` : \"\"\n }`;\n}\n\nasync function findSourceByIdentity(\n ctx: { db: EpistemicDbReader },\n args: { normalizedUrl?: string; sha?: string }\n): Promise<SourceNodeDoc | null> {\n const sourceNodes = await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_nodeType\", (q) => q.eq(\"nodeType\", \"source\"))\n .collect();\n\n let urlMatch: SourceNodeDoc | null = null;\n let shaMatch: SourceNodeDoc | null = null;\n\n for (const node of sourceNodes) {\n if (!isSourceNodeDoc(node)) {\n continue;\n }\n const metadata = asRecord(node.metadata);\n if (\n args.normalizedUrl &&\n normalizeString(metadata.url) === args.normalizedUrl &&\n !urlMatch\n ) {\n urlMatch = node;\n }\n if (\n args.sha &&\n normalizeString(metadata.contentSha) === args.sha &&\n !shaMatch\n ) {\n shaMatch = node;\n }\n if (urlMatch && (!args.sha || shaMatch)) {\n break;\n }\n }\n\n if (urlMatch && shaMatch && String(urlMatch._id) !== String(shaMatch._id)) {\n throwStructuredSourceError({\n message:\n \"Source identity conflict: URL and SHA resolve to different source nodes.\",\n status: 409,\n code: \"CONTENT_SHA_MISMATCH\",\n invariantCode: \"source.content_hash_immutable\",\n suggestion:\n \"Same source identity resolves to different records. Create a new source with a distinct URL or use fork semantics.\",\n details: {\n urlSourceId: String(urlMatch._id),\n shaSourceId: String(shaMatch._id),\n },\n });\n }\n\n return urlMatch ?? shaMatch;\n}\n\nfunction buildSourceMetadata(args: {\n existingMetadata?: Record<string, unknown>;\n normalizedUrl?: string;\n sha?: string;\n kind: string;\n capturedAt?: number;\n metadata?: Record<string, unknown>;\n}) {\n const existingMetadata = args.existingMetadata ?? {};\n const nextMetadata: Record<string, unknown> = {\n ...existingMetadata,\n kind: args.kind,\n ...args.metadata,\n };\n\n if (args.capturedAt !== undefined) {\n nextMetadata.capturedAt = args.capturedAt;\n }\n if (!Object.hasOwn(existingMetadata, \"url\") && args.normalizedUrl) {\n nextMetadata.url = args.normalizedUrl;\n } else if (Object.hasOwn(existingMetadata, \"url\")) {\n nextMetadata.url = existingMetadata.url;\n }\n if (!Object.hasOwn(existingMetadata, \"contentSha\") && args.sha) {\n nextMetadata.contentSha = args.sha;\n } else if (Object.hasOwn(existingMetadata, \"contentSha\")) {\n nextMetadata.contentSha = existingMetadata.contentSha;\n }\n\n return nextMetadata;\n}\n\nfunction readSourceIdentity(args: UpsertSourceArgs): {\n normalizedUrl?: string;\n sha?: string;\n} {\n const sourceUrl = normalizeString(args.url);\n const normalizedUrl = sourceUrl ? normalizeSourceUrl(sourceUrl) : undefined;\n const sha = normalizeString(args.sha);\n\n if (!(normalizedUrl || sha)) {\n throwStructuredSourceError({\n message: \"Source identity requires a URL or content SHA.\",\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.identity.required\",\n suggestion: \"Provide url or sha.\",\n });\n }\n\n return { normalizedUrl, sha };\n}\n\nasync function syncSourceNodeToNeo4j(args: {\n ctx: SourceMutationCtx;\n nodeId: Id<\"epistemicNodes\">;\n}): Promise<void> {\n await args.ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {\n nodeId: args.nodeId,\n operation: \"upsert\",\n });\n}\n\nasync function insertSourceAudit(\n ctx: SourceMutationCtx,\n audit: SourceAuditRecord\n): Promise<void> {\n await ctx.db.insert(\"epistemicAudit\", { ...audit });\n}\n\nasync function updateExistingSource(args: {\n capturedAt?: number;\n ctx: SourceMutationCtx;\n existing: SourceNodeDoc;\n kind: string;\n metadataPatch: Record<string, unknown>;\n now: number;\n sha?: string;\n title?: string;\n userId: string;\n}): Promise<SourceNodeDoc> {\n if (\n args.existing.topicId &&\n !(await checkScopeAccess(\n args.ctx,\n String(args.existing.topicId),\n args.userId\n ))\n ) {\n throwStructuredSourceError({\n message: \"Access denied to existing source scope.\",\n status: 403,\n code: \"FORBIDDEN\",\n invariantCode: \"policy.scope_required\",\n suggestion: \"Request access to the source topic scope and retry.\",\n details: { topicId: args.existing.topicId },\n });\n }\n\n const existingMetadata = asRecord(args.existing.metadata);\n const existingSha = normalizeString(existingMetadata.contentSha);\n if (args.sha && existingSha && existingSha !== args.sha) {\n throwStructuredSourceError({\n message: \"Same URL cannot be reused with a different content hash.\",\n status: 409,\n code: \"CONTENT_SHA_MISMATCH\",\n invariantCode: \"source.content_hash_immutable\",\n suggestion:\n \"Same URL, different content. Create a new source with a distinct URL or use fork semantics.\",\n details: {\n sourceId: String(args.existing._id),\n url: existingMetadata.url,\n existingSha,\n receivedSha: args.sha,\n },\n });\n }\n\n const nextMetadata = buildSourceMetadata({\n existingMetadata,\n kind: args.kind,\n capturedAt: normalizeNumber(args.capturedAt),\n metadata: args.metadataPatch,\n });\n\n const patch: Record<string, unknown> = {\n metadata: nextMetadata,\n updatedAt: args.now,\n };\n const title = normalizeString(args.title);\n if (title) {\n patch.title = title;\n patch.canonicalText = title;\n }\n\n await args.ctx.db.patch(args.existing._id, patch);\n await syncSourceNodeToNeo4j({\n ctx: args.ctx,\n nodeId: args.existing._id,\n });\n\n await insertSourceAudit(args.ctx, {\n entityType: \"source\",\n entityId: String(args.existing._id),\n changeType: \"source_metadata_updated\",\n changedAt: args.now,\n changedBy: args.userId,\n isAgent: false,\n topicId: args.existing.topicId ? String(args.existing.topicId) : undefined,\n previousState: {\n title: args.existing.title,\n metadata: existingMetadata,\n },\n newState: {\n title: title ?? args.existing.title,\n metadata: nextMetadata,\n },\n });\n\n const updated = await args.ctx.db.get(args.existing._id);\n return isSourceNodeDoc(updated) ? updated : args.existing;\n}\n\nasync function createSource(args: {\n capturedAt?: number;\n ctx: SourceMutationCtx;\n kind: string;\n metadataPatch: Record<string, unknown>;\n normalizedUrl?: string;\n now: number;\n sha?: string;\n title?: string;\n topicId?: string;\n userId: string;\n}): Promise<SourceNodeDoc | null> {\n if (!normalizeString(args.topicId)) {\n throwStructuredSourceError({\n message: \"topicId is required when creating a new source.\",\n status: 400,\n code: \"INVALID_REQUEST\",\n invariantCode: \"source.context_required\",\n suggestion: \"Provide topicId when creating a new source node.\",\n });\n }\n\n const scope = await resolveTopicProjectScope(args.ctx, {\n topicId: args.topicId,\n });\n assertWorkspaceScopedEpistemicNodeScope({\n scope,\n nodeType: \"source\",\n mutationName: \"epistemicSources.upsertSource\",\n });\n if (scope.projectId) {\n await requireScopeWriteAccess(args.ctx, scope.projectId, args.userId);\n }\n\n const globalId = generateGlobalId();\n const title = normalizeString(args.title);\n const nextMetadata = buildSourceMetadata({\n normalizedUrl: args.normalizedUrl,\n sha: args.sha,\n kind: args.kind,\n capturedAt: normalizeNumber(args.capturedAt),\n metadata: args.metadataPatch,\n });\n const nodeId = await insertEpistemicNode(args.ctx, {\n globalId,\n topicId: scope.topicId,\n projectId: scope.projectId,\n tenantId: scope.tenantId,\n workspaceId: scope.workspaceId,\n nodeType: \"source\",\n epistemicLayer: \"L1\",\n canonicalText: title ?? args.normalizedUrl ?? \"source\",\n contentHash:\n args.sha ??\n generateSourceContentHash(args.normalizedUrl ?? title ?? \"source\"),\n ...(title ? { title } : {}),\n status: \"active\",\n createdAt: args.now,\n updatedAt: args.now,\n createdBy: args.userId,\n metadata: nextMetadata,\n });\n\n await syncSourceNodeToNeo4j({\n ctx: args.ctx,\n nodeId,\n });\n\n await scheduleEmbeddingGeneration({\n ctx: args.ctx,\n nodeId,\n projectId: scope.projectId,\n topicId: scope.topicId,\n createdBy: args.userId,\n nodeType: \"source\",\n text: sourceEmbeddingText({\n title,\n url: args.normalizedUrl,\n kind: args.kind,\n metadata: nextMetadata,\n }),\n });\n\n await insertSourceAudit(args.ctx, {\n entityType: \"source\",\n entityId: String(nodeId),\n changeType: \"source_created\",\n changedAt: args.now,\n changedBy: args.userId,\n isAgent: false,\n topicId: scope.topicId ? String(scope.topicId) : undefined,\n previousState: null,\n newState: {\n title,\n url: args.normalizedUrl,\n contentSha: args.sha,\n kind: args.kind,\n },\n });\n\n const created = await args.ctx.db.get(nodeId);\n return isSourceNodeDoc(created) ? created : null;\n}\n\nfunction sourceEmbeddingText(args: {\n title?: string;\n url?: string;\n kind: string;\n metadata: Record<string, unknown>;\n}) {\n const lines = [\n normalizeString(args.title),\n normalizeString(args.url),\n args.kind,\n normalizeString(args.metadata.sourceDescription),\n ].filter((value): value is string => Boolean(value));\n return lines.join(\"\\n\");\n}\n\nexport const upsertSource = mutation({\n args: {\n url: v.optional(v.string()),\n sha: v.optional(v.string()),\n kind: v.string(),\n title: v.optional(v.string()),\n capturedAt: v.optional(v.number()),\n metadata: v.optional(v.any()),\n topicId: v.optional(v.string()),\n userId: v.string(),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: UpsertSourceArgs) => {\n const { normalizedUrl, sha } = readSourceIdentity(args);\n const now = Date.now();\n const metadataPatch = normalizeMetadata(args.metadata);\n const existing = await findSourceByIdentity(ctx, { normalizedUrl, sha });\n\n if (existing) {\n return await updateExistingSource({\n ctx,\n existing,\n kind: args.kind,\n capturedAt: args.capturedAt,\n metadataPatch,\n now,\n sha,\n title: args.title,\n userId: args.userId,\n });\n }\n\n return await createSource({\n ctx,\n normalizedUrl,\n sha,\n kind: args.kind,\n capturedAt: args.capturedAt,\n metadataPatch,\n now,\n title: args.title,\n topicId: args.topicId,\n userId: args.userId,\n });\n },\n});\n\nexport const getById = query({\n args: {\n nodeId: v.optional(v.id(\"epistemicNodes\")),\n sourceId: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx, args: GetSourceByIdArgs) => {\n const id = args.nodeId ?? readConvexId<\"epistemicNodes\">(args.sourceId);\n if (!id) {\n return null;\n }\n const node = await ctx.db.get(id);\n if (!isSourceNodeDoc(node)) {\n return null;\n }\n return node;\n },\n});\n\nexport const findByUrl = query({\n args: {\n url: v.string(),\n },\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx, args: SourceUrlQueryArgs) => {\n const normalizedUrl = normalizeSourceUrl(args.url);\n const node = await findSourceByIdentity(ctx, { normalizedUrl });\n return node?.nodeType === \"source\" ? node : null;\n },\n});\n\nexport const findBySha = query({\n args: {\n sha: v.string(),\n },\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx, args: SourceShaQueryArgs) => {\n const sha = normalizeString(args.sha);\n if (!sha) {\n return null;\n }\n const node = await findSourceByIdentity(ctx, { sha });\n return node?.nodeType === \"source\" ? node : null;\n },\n});\n"]}