@lucern/graph-primitives 1.0.26 → 1.0.28

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 (63) hide show
  1. package/dist/beliefDecay.js.map +1 -1
  2. package/dist/beliefEvidenceLinks.js.map +1 -1
  3. package/dist/beliefEvidenceLinks.operational.js.map +1 -1
  4. package/dist/contradictions.js.map +1 -1
  5. package/dist/convex.js.map +1 -1
  6. package/dist/entityBridge.js.map +1 -1
  7. package/dist/entityLifecycle.js.map +1 -1
  8. package/dist/epistemicAnswers.js.map +1 -1
  9. package/dist/epistemicBeliefs.admin.js.map +1 -1
  10. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  11. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  12. package/dist/epistemicBeliefs.core.js.map +1 -1
  13. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  14. package/dist/epistemicBeliefs.internal.js.map +1 -1
  15. package/dist/epistemicBeliefs.js.map +1 -1
  16. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  17. package/dist/epistemicBeliefs.links.js.map +1 -1
  18. package/dist/epistemicBeliefs.queries.js.map +1 -1
  19. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  20. package/dist/epistemicContracts.evaluators.js.map +1 -1
  21. package/dist/epistemicContracts.handlers.js.map +1 -1
  22. package/dist/epistemicContracts.js.map +1 -1
  23. package/dist/epistemicEdgeCreation.js.map +1 -1
  24. package/dist/epistemicEdges.handlers.js.map +1 -1
  25. package/dist/epistemicEdges.js.map +1 -1
  26. package/dist/epistemicEdges.mutations.js.map +1 -1
  27. package/dist/epistemicEdges.queries.js.map +1 -1
  28. package/dist/epistemicEvidence.js.map +1 -1
  29. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  30. package/dist/epistemicEvidenceMutations.js.map +1 -1
  31. package/dist/epistemicEvidenceQueries.js.map +1 -1
  32. package/dist/epistemicHelpers.js.map +1 -1
  33. package/dist/epistemicLinking.js.map +1 -1
  34. package/dist/epistemicNodeCreation.js.map +1 -1
  35. package/dist/epistemicNodes.internal.js.map +1 -1
  36. package/dist/epistemicNodes.js.map +1 -1
  37. package/dist/epistemicNodes.mutations.js.map +1 -1
  38. package/dist/epistemicNodes.queries.js.map +1 -1
  39. package/dist/epistemicQuestions.conviction.js.map +1 -1
  40. package/dist/epistemicQuestions.create.js.map +1 -1
  41. package/dist/epistemicQuestions.evidence.js.map +1 -1
  42. package/dist/epistemicQuestions.helpers.js.map +1 -1
  43. package/dist/epistemicQuestions.js.map +1 -1
  44. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  45. package/dist/epistemicQuestions.queries.js.map +1 -1
  46. package/dist/epistemicQuestions.sprint.js.map +1 -1
  47. package/dist/epistemicQuestions.tail.js.map +1 -1
  48. package/dist/epistemicSources.js.map +1 -1
  49. package/dist/helpers.js.map +1 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/ontologyApproval.js.map +1 -1
  52. package/dist/ontologyDefinitions.js.map +1 -1
  53. package/dist/ontologyRegistry.js.map +1 -1
  54. package/dist/projectionReconciliation.js.map +1 -1
  55. package/dist/proof-attestation.json +1 -1
  56. package/dist/questionEvidenceLinks.js.map +1 -1
  57. package/dist/resolvers.js.map +1 -1
  58. package/dist/scopeResolverCompat.js.map +1 -1
  59. package/dist/topicProjectOverlay.js.map +1 -1
  60. package/dist/topicScope.js.map +1 -1
  61. package/dist/workflowBridge.js.map +1 -1
  62. package/dist/workspaceIsolation.js.map +1 -1
  63. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/convex.ts","../src/epistemicInsert.ts","../src/epistemicBeliefs.topicAnchor.ts"],"names":[],"mappings":"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","file":"epistemicBeliefs.topicAnchor.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","import type { WithoutSystemFields } from \"convex/server\";\nimport {\n assertUuidV7Identity,\n assertStorageEdgeVocabulary,\n assertUuidShapedEdgeEndpoint,\n} from \"@lucern/contracts/ids\";\nimport {\n assertEdgePolicyAllowed,\n edgePolicyManifest,\n type EpistemicNodeType,\n} from \"@lucern/contracts\";\nimport type { Doc, Id, MutationCtx } from \"./convex\";\n\nexport async function insertEpistemicNode(\n ctx: MutationCtx,\n doc: WithoutSystemFields<Doc<\"epistemicNodes\">>,\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: any) => q.eq(\"globalId\", endpoint))\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: WithoutSystemFields<Doc<\"epistemicEdges\">>,\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","import type { Doc, Id, MutationCtx } from \"./convex\";\nimport { internal } from \"./convex\";\nimport { generateUuidV7 } from \"./globalId\";\nimport { insertEpistemicEdge } from \"./epistemicInsert.js\";\n\ntype TopicAnchorInput = {\n topicId?: string;\n topicNodeId?: string;\n topicGlobalId?: string;\n};\n\ntype TopicNodeDoc = Doc<\"epistemicNodes\"> & {\n globalId: string;\n nodeType: \"topic\";\n};\n\nfunction cleanString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction topicNodeCandidates(topicRef: string): string[] {\n const normalized = topicRef.trim();\n if (!normalized) {\n return [];\n }\n const candidates = [normalized];\n if (normalized.startsWith(\"top_\")) {\n candidates.push(normalized.slice(4));\n }\n return [...new Set(candidates)];\n}\n\nexport function readTopicNodeRef(args: TopicAnchorInput): string | undefined {\n return (\n cleanString(args.topicGlobalId) ??\n cleanString(args.topicNodeId) ??\n cleanString(args.topicId)\n );\n}\n\nexport async function resolveRequiredTopicAnchor(\n ctx: MutationCtx,\n topicRef: string,\n): Promise<TopicNodeDoc> {\n for (const candidate of topicNodeCandidates(topicRef)) {\n try {\n const direct = await ctx.db.get(candidate as Id<\"epistemicNodes\">);\n if (direct?.nodeType === \"topic\" && cleanString(direct.globalId)) {\n return direct as TopicNodeDoc;\n }\n } catch (_) {\n // Not a component-local epistemicNodes _id; try the globalId index next.\n }\n\n const byGlobalId = await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_globalId\", (q) => q.eq(\"globalId\", candidate))\n .first();\n if (byGlobalId?.nodeType === \"topic\" && cleanString(byGlobalId.globalId)) {\n return byGlobalId as TopicNodeDoc;\n }\n }\n\n throw new Error(\n \"Belief creation requires topicGlobalId or topicNodeId for a topic node in epistemicNodes. Legacy topics-table IDs are not valid belief anchors.\",\n );\n}\n\nexport function scopeFromTopicAnchor(topicNode: TopicNodeDoc) {\n return {\n topicId: topicNode.globalId,\n projectId: cleanString(topicNode.projectId),\n tenantId: cleanString(topicNode.tenantId),\n workspaceId: cleanString(topicNode.workspaceId),\n source: \"topic\" as const,\n };\n}\n\nexport async function createRequiredBeliefTopicEdge(\n ctx: MutationCtx,\n args: {\n beliefNodeId: Id<\"epistemicNodes\">;\n beliefGlobalId: string;\n topicNode: TopicNodeDoc;\n createdBy: string;\n },\n) {\n const topicGlobalId = args.topicNode.globalId;\n const now = Date.now();\n\n // C2-RR.4 Defect E — query (and write) by canonical UUIDv7 endpoints, not\n // Convex doc ids. The endpoints are belief/topic globalIds.\n const existingEdges = await ctx.db\n .query(\"epistemicEdges\")\n .withIndex(\"by_from_to\", (q) =>\n q.eq(\"fromNodeId\", args.beliefGlobalId).eq(\"toNodeId\", topicGlobalId),\n )\n .collect();\n const existing = existingEdges.find((edge) => edge.edgeType === \"belongs_to\");\n const edgeGlobalId = cleanString(existing?.globalId) ?? generateUuidV7();\n\n if (!existing) {\n await insertEpistemicEdge(ctx, {\n globalId: edgeGlobalId,\n fromNodeId: args.beliefGlobalId,\n toNodeId: topicGlobalId,\n sourceGlobalId: args.beliefGlobalId,\n targetGlobalId: topicGlobalId,\n edgeType: \"belongs_to\",\n weight: 1,\n confidence: 1,\n context: \"Belief creation topic anchor invariant.\",\n reasoningMethod: \"implicit\",\n derivationType: \"topic_scope_invariant\",\n metadata: {\n invariant: \"belief.topic_edge_required\",\n edgeUuid: edgeGlobalId,\n fromUuid: args.beliefGlobalId,\n toUuid: topicGlobalId,\n },\n createdBy: args.createdBy,\n createdAt: now,\n updatedAt: now,\n projectId: cleanString(args.topicNode.projectId),\n topicId: topicGlobalId,\n tenantId: cleanString(args.topicNode.tenantId),\n workspaceId: cleanString(args.topicNode.workspaceId),\n fromNodeType: \"belief\",\n toNodeType: \"topic\",\n fromLayer: \"L3\",\n toLayer: args.topicNode.epistemicLayer ?? \"ontological\",\n } as any);\n }\n\n await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {\n globalId: edgeGlobalId,\n fromGlobalId: args.beliefGlobalId,\n toGlobalId: topicGlobalId,\n edgeType: \"belongs_to\",\n weight: 1,\n confidence: 1,\n context: \"Belief creation topic anchor invariant.\",\n projectId: cleanString(args.topicNode.projectId),\n topicId: topicGlobalId,\n createdBy: args.createdBy,\n fromNodeType: \"belief\",\n toNodeType: \"topic\",\n fromLayer: \"L3\",\n toLayer: args.topicNode.epistemicLayer ?? \"ontological\",\n metadata: {\n invariant: \"belief.topic_edge_required\",\n edgeUuid: edgeGlobalId,\n fromUuid: args.beliefGlobalId,\n toUuid: topicGlobalId,\n },\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/convex.ts","../src/epistemicInsert.ts","../src/epistemicBeliefs.topicAnchor.ts"],"names":[],"mappings":";;;;;AAyB0B,iBAAA;AACnB,IAAM,QAAA,GAAW,MAAA;ACKxB,eAAe,0BAAA,CACb,GAAA,EACA,YAAA,EACA,QAAA,EACe;AACf,EAAA,4BAAA,CAA6B,cAAc,QAAQ,CAAA;AACnD,EAAA,MAAM,OAAO,MAAM,GAAA,CAAI,EAAA,CACpB,KAAA,CAAM,gBAAgB,CAAA,CACtB,SAAA,CAAU,aAAA,EAAe,CAAC,MAAW,CAAA,CAAE,EAAA,CAAG,YAAY,QAAQ,CAAC,EAC/D,KAAA,EAAM;AACT,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,4DAAA,EAA+D,YAAY,CAAA,gEAAA,EAAmE,QAAQ,CAAA,6BAAA;AAAA,KACxJ;AAAA,EACF;AACF;AAEA,eAAsB,mBAAA,CACpB,KACA,GAAA,EAC+B;AAC/B,EAAA,oBAAA,CAAqB,gBAAA,EAAkB,IAAI,QAAQ,CAAA;AAGnD,EAAA,2BAAA,CAA4B,IAAI,QAAQ,CAAA;AAGxC,EAAA,IAAI,CAAC,GAAA,CAAI,UAAA,IAAc,OAAO,GAAA,CAAI,eAAe,QAAA,EAAU;AACzD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,CAAC,GAAA,CAAI,QAAA,IAAY,OAAO,GAAA,CAAI,aAAa,QAAA,EAAU;AACrD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAOA,EAAA,MAAM,0BAAA,CAA2B,GAAA,EAAK,YAAA,EAAc,GAAA,CAAI,UAAU,CAAA;AAClE,EAAA,MAAM,0BAAA,CAA2B,GAAA,EAAK,UAAA,EAAY,GAAA,CAAI,QAAQ,CAAA;AAG9D,EAAA,IAAI,IAAI,YAAA,IAAgB,GAAA,CAAI,UAAA,IAAc,GAAA,CAAI,aAAa,gBAAA,EAAkB;AAC3E,IAAA,uBAAA;AAAA,MACE,kBAAA;AAAA,MACA,GAAA,CAAI,QAAA;AAAA,MACJ;AAAA,QACE,IAAA,EAAM,gBAAA;AAAA,QACN,QAAQ,GAAA,CAAI,UAAA;AAAA,QACZ,UAAU,GAAA,CAAI;AAAA,OAChB;AAAA,MACA;AAAA,QACE,IAAA,EAAM,gBAAA;AAAA,QACN,QAAQ,GAAA,CAAI,QAAA;AAAA,QACZ,UAAU,GAAA,CAAI;AAAA;AAChB,KACF;AAAA,EACF;AAEA,EAAA,OAAO,GAAA,CAAI,EAAA,CAAG,MAAA,CAAO,gBAAA,EAAkB,GAAG,CAAA;AAC5C;;;AChFA,SAAS,YAAY,KAAA,EAAoC;AACvD,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,IAAA,GAAO,MAAA,GAAS,CAAA,GACtD,KAAA,CAAM,IAAA,EAAK,GACX,MAAA;AACN;AAEA,SAAS,oBAAoB,QAAA,EAA4B;AACvD,EAAA,MAAM,UAAA,GAAa,SAAS,IAAA,EAAK;AACjC,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,UAAU,CAAA;AAC9B,EAAA,IAAI,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA,EAAG;AACjC,IAAA,UAAA,CAAW,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,UAAU,CAAC,CAAA;AAChC;AAEO,SAAS,iBAAiB,IAAA,EAA4C;AAC3E,EAAA,OACE,WAAA,CAAY,IAAA,CAAK,aAAa,CAAA,IAC9B,WAAA,CAAY,KAAK,WAAW,CAAA,IAC5B,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAE5B;AAEA,eAAsB,0BAAA,CACpB,KACA,QAAA,EACuB;AACvB,EAAA,KAAA,MAAW,SAAA,IAAa,mBAAA,CAAoB,QAAQ,CAAA,EAAG;AACrD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,EAAA,CAAG,IAAI,SAAiC,CAAA;AACjE,MAAA,IAAI,QAAQ,QAAA,KAAa,OAAA,IAAW,WAAA,CAAY,MAAA,CAAO,QAAQ,CAAA,EAAG;AAChE,QAAA,OAAO,MAAA;AAAA,MACT;AAAA,IACF,SAAS,CAAA,EAAG;AAAA,IAEZ;AAEA,IAAA,MAAM,aAAa,MAAM,GAAA,CAAI,EAAA,CAC1B,KAAA,CAAM,gBAAgB,CAAA,CACtB,SAAA,CAAU,aAAA,EAAe,CAAC,MAAM,CAAA,CAAE,EAAA,CAAG,YAAY,SAAS,CAAC,EAC3D,KAAA,EAAM;AACT,IAAA,IAAI,YAAY,QAAA,KAAa,OAAA,IAAW,WAAA,CAAY,UAAA,CAAW,QAAQ,CAAA,EAAG;AACxE,MAAA,OAAO,UAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR;AAAA,GACF;AACF;AAEO,SAAS,qBAAqB,SAAA,EAAyB;AAC5D,EAAA,OAAO;AAAA,IACL,SAAS,SAAA,CAAU,QAAA;AAAA,IACnB,SAAA,EAAW,WAAA,CAAY,SAAA,CAAU,SAAS,CAAA;AAAA,IAC1C,QAAA,EAAU,WAAA,CAAY,SAAA,CAAU,QAAQ,CAAA;AAAA,IACxC,WAAA,EAAa,WAAA,CAAY,SAAA,CAAU,WAAW,CAAA;AAAA,IAC9C,MAAA,EAAQ;AAAA,GACV;AACF;AAEA,eAAsB,6BAAA,CACpB,KACA,IAAA,EAMA;AACA,EAAA,MAAM,aAAA,GAAgB,KAAK,SAAA,CAAU,QAAA;AACrC,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAIrB,EAAA,MAAM,gBAAgB,MAAM,GAAA,CAAI,EAAA,CAC7B,KAAA,CAAM,gBAAgB,CAAA,CACtB,SAAA;AAAA,IAAU,YAAA;AAAA,IAAc,CAAC,CAAA,KACxB,CAAA,CAAE,EAAA,CAAG,YAAA,EAAc,KAAK,cAAc,CAAA,CAAE,EAAA,CAAG,UAAA,EAAY,aAAa;AAAA,IAErE,OAAA,EAAQ;AACX,EAAA,MAAM,WAAW,aAAA,CAAc,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,aAAa,YAAY,CAAA;AAC5E,EAAA,MAAM,YAAA,GAAe,WAAA,CAAY,QAAA,EAAU,QAAQ,KAAK,cAAA,EAAe;AAEvE,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,oBAAoB,GAAA,EAAK;AAAA,MAC7B,QAAA,EAAU,YAAA;AAAA,MACV,YAAY,IAAA,CAAK,cAAA;AAAA,MACjB,QAAA,EAAU,aAAA;AAAA,MACV,gBAAgB,IAAA,CAAK,cAAA;AAAA,MACrB,cAAA,EAAgB,aAAA;AAAA,MAChB,QAAA,EAAU,YAAA;AAAA,MACV,MAAA,EAAQ,CAAA;AAAA,MACR,UAAA,EAAY,CAAA;AAAA,MACZ,OAAA,EAAS,yCAAA;AAAA,MACT,eAAA,EAAiB,UAAA;AAAA,MACjB,cAAA,EAAgB,uBAAA;AAAA,MAChB,QAAA,EAAU;AAAA,QACR,SAAA,EAAW,4BAAA;AAAA,QACX,QAAA,EAAU,YAAA;AAAA,QACV,UAAU,IAAA,CAAK,cAAA;AAAA,QACf,MAAA,EAAQ;AAAA,OACV;AAAA,MACA,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,SAAA,EAAW,GAAA;AAAA,MACX,SAAA,EAAW,GAAA;AAAA,MACX,SAAA,EAAW,WAAA,CAAY,IAAA,CAAK,SAAA,CAAU,SAAS,CAAA;AAAA,MAC/C,OAAA,EAAS,aAAA;AAAA,MACT,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,MAC7C,WAAA,EAAa,WAAA,CAAY,IAAA,CAAK,SAAA,CAAU,WAAW,CAAA;AAAA,MACnD,YAAA,EAAc,QAAA;AAAA,MACd,UAAA,EAAY,OAAA;AAAA,MACZ,SAAA,EAAW,IAAA;AAAA,MACX,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,cAAA,IAAkB;AAAA,KACpC,CAAA;AAAA,EACV;AAEA,EAAA,MAAM,IAAI,SAAA,CAAU,QAAA,CAAS,CAAA,EAAG,QAAA,CAAS,aAAa,UAAA,EAAY;AAAA,IAChE,QAAA,EAAU,YAAA;AAAA,IACV,cAAc,IAAA,CAAK,cAAA;AAAA,IACnB,UAAA,EAAY,aAAA;AAAA,IACZ,QAAA,EAAU,YAAA;AAAA,IACV,MAAA,EAAQ,CAAA;AAAA,IACR,UAAA,EAAY,CAAA;AAAA,IACZ,OAAA,EAAS,yCAAA;AAAA,IACT,SAAA,EAAW,WAAA,CAAY,IAAA,CAAK,SAAA,CAAU,SAAS,CAAA;AAAA,IAC/C,OAAA,EAAS,aAAA;AAAA,IACT,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,YAAA,EAAc,QAAA;AAAA,IACd,UAAA,EAAY,OAAA;AAAA,IACZ,SAAA,EAAW,IAAA;AAAA,IACX,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,cAAA,IAAkB,aAAA;AAAA,IAC1C,QAAA,EAAU;AAAA,MACR,SAAA,EAAW,4BAAA;AAAA,MACX,QAAA,EAAU,YAAA;AAAA,MACV,UAAU,IAAA,CAAK,cAAA;AAAA,MACf,MAAA,EAAQ;AAAA;AACV,GACD,CAAA;AACH","file":"epistemicBeliefs.topicAnchor.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","import type { WithoutSystemFields } from \"convex/server\";\nimport {\n assertUuidV7Identity,\n assertStorageEdgeVocabulary,\n assertUuidShapedEdgeEndpoint,\n} from \"@lucern/contracts/ids\";\nimport {\n assertEdgePolicyAllowed,\n edgePolicyManifest,\n type EpistemicNodeType,\n} from \"@lucern/contracts\";\nimport type { Doc, Id, MutationCtx } from \"./convex\";\n\nexport async function insertEpistemicNode(\n ctx: MutationCtx,\n doc: WithoutSystemFields<Doc<\"epistemicNodes\">>,\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: any) => q.eq(\"globalId\", endpoint))\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: WithoutSystemFields<Doc<\"epistemicEdges\">>,\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","import type { Doc, Id, MutationCtx } from \"./convex\";\nimport { internal } from \"./convex\";\nimport { generateUuidV7 } from \"./globalId\";\nimport { insertEpistemicEdge } from \"./epistemicInsert.js\";\n\ntype TopicAnchorInput = {\n topicId?: string;\n topicNodeId?: string;\n topicGlobalId?: string;\n};\n\ntype TopicNodeDoc = Doc<\"epistemicNodes\"> & {\n globalId: string;\n nodeType: \"topic\";\n};\n\nfunction cleanString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction topicNodeCandidates(topicRef: string): string[] {\n const normalized = topicRef.trim();\n if (!normalized) {\n return [];\n }\n const candidates = [normalized];\n if (normalized.startsWith(\"top_\")) {\n candidates.push(normalized.slice(4));\n }\n return [...new Set(candidates)];\n}\n\nexport function readTopicNodeRef(args: TopicAnchorInput): string | undefined {\n return (\n cleanString(args.topicGlobalId) ??\n cleanString(args.topicNodeId) ??\n cleanString(args.topicId)\n );\n}\n\nexport async function resolveRequiredTopicAnchor(\n ctx: MutationCtx,\n topicRef: string,\n): Promise<TopicNodeDoc> {\n for (const candidate of topicNodeCandidates(topicRef)) {\n try {\n const direct = await ctx.db.get(candidate as Id<\"epistemicNodes\">);\n if (direct?.nodeType === \"topic\" && cleanString(direct.globalId)) {\n return direct as TopicNodeDoc;\n }\n } catch (_) {\n // Not a component-local epistemicNodes _id; try the globalId index next.\n }\n\n const byGlobalId = await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_globalId\", (q) => q.eq(\"globalId\", candidate))\n .first();\n if (byGlobalId?.nodeType === \"topic\" && cleanString(byGlobalId.globalId)) {\n return byGlobalId as TopicNodeDoc;\n }\n }\n\n throw new Error(\n \"Belief creation requires topicGlobalId or topicNodeId for a topic node in epistemicNodes. Legacy topics-table IDs are not valid belief anchors.\",\n );\n}\n\nexport function scopeFromTopicAnchor(topicNode: TopicNodeDoc) {\n return {\n topicId: topicNode.globalId,\n projectId: cleanString(topicNode.projectId),\n tenantId: cleanString(topicNode.tenantId),\n workspaceId: cleanString(topicNode.workspaceId),\n source: \"topic\" as const,\n };\n}\n\nexport async function createRequiredBeliefTopicEdge(\n ctx: MutationCtx,\n args: {\n beliefNodeId: Id<\"epistemicNodes\">;\n beliefGlobalId: string;\n topicNode: TopicNodeDoc;\n createdBy: string;\n },\n) {\n const topicGlobalId = args.topicNode.globalId;\n const now = Date.now();\n\n // C2-RR.4 Defect E — query (and write) by canonical UUIDv7 endpoints, not\n // Convex doc ids. The endpoints are belief/topic globalIds.\n const existingEdges = await ctx.db\n .query(\"epistemicEdges\")\n .withIndex(\"by_from_to\", (q) =>\n q.eq(\"fromNodeId\", args.beliefGlobalId).eq(\"toNodeId\", topicGlobalId),\n )\n .collect();\n const existing = existingEdges.find((edge) => edge.edgeType === \"belongs_to\");\n const edgeGlobalId = cleanString(existing?.globalId) ?? generateUuidV7();\n\n if (!existing) {\n await insertEpistemicEdge(ctx, {\n globalId: edgeGlobalId,\n fromNodeId: args.beliefGlobalId,\n toNodeId: topicGlobalId,\n sourceGlobalId: args.beliefGlobalId,\n targetGlobalId: topicGlobalId,\n edgeType: \"belongs_to\",\n weight: 1,\n confidence: 1,\n context: \"Belief creation topic anchor invariant.\",\n reasoningMethod: \"implicit\",\n derivationType: \"topic_scope_invariant\",\n metadata: {\n invariant: \"belief.topic_edge_required\",\n edgeUuid: edgeGlobalId,\n fromUuid: args.beliefGlobalId,\n toUuid: topicGlobalId,\n },\n createdBy: args.createdBy,\n createdAt: now,\n updatedAt: now,\n projectId: cleanString(args.topicNode.projectId),\n topicId: topicGlobalId,\n tenantId: cleanString(args.topicNode.tenantId),\n workspaceId: cleanString(args.topicNode.workspaceId),\n fromNodeType: \"belief\",\n toNodeType: \"topic\",\n fromLayer: \"L3\",\n toLayer: args.topicNode.epistemicLayer ?? \"ontological\",\n } as any);\n }\n\n await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {\n globalId: edgeGlobalId,\n fromGlobalId: args.beliefGlobalId,\n toGlobalId: topicGlobalId,\n edgeType: \"belongs_to\",\n weight: 1,\n confidence: 1,\n context: \"Belief creation topic anchor invariant.\",\n projectId: cleanString(args.topicNode.projectId),\n topicId: topicGlobalId,\n createdBy: args.createdBy,\n fromNodeType: \"belief\",\n toNodeType: \"topic\",\n fromLayer: \"L3\",\n toLayer: args.topicNode.epistemicLayer ?? \"ontological\",\n metadata: {\n invariant: \"belief.topic_edge_required\",\n edgeUuid: edgeGlobalId,\n fromUuid: args.beliefGlobalId,\n toUuid: topicGlobalId,\n },\n });\n}\n"]}