@lucern/graph-primitives 1.0.27 → 1.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) 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 +3 -3
  5. package/dist/contradictions.js.map +1 -1
  6. package/dist/convex.js.map +1 -1
  7. package/dist/entityBridge.js.map +1 -1
  8. package/dist/entityLifecycle.js +7 -39
  9. package/dist/entityLifecycle.js.map +1 -1
  10. package/dist/epistemicAnswers.js.map +1 -1
  11. package/dist/epistemicBeliefs.admin.js +6 -42
  12. package/dist/epistemicBeliefs.admin.js.map +1 -1
  13. package/dist/epistemicBeliefs.backfills.js +2 -21
  14. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  15. package/dist/epistemicBeliefs.confidence.d.ts +1 -0
  16. package/dist/epistemicBeliefs.confidence.js +4 -40
  17. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  18. package/dist/epistemicBeliefs.core.js +6 -44
  19. package/dist/epistemicBeliefs.core.js.map +1 -1
  20. package/dist/epistemicBeliefs.d.ts +1 -0
  21. package/dist/epistemicBeliefs.forkEvidence.js +2 -22
  22. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  23. package/dist/epistemicBeliefs.helpers.d.ts +3 -27
  24. package/dist/epistemicBeliefs.helpers.js +4 -40
  25. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  26. package/dist/epistemicBeliefs.internal.js +2 -22
  27. package/dist/epistemicBeliefs.internal.js.map +1 -1
  28. package/dist/epistemicBeliefs.js +17 -55
  29. package/dist/epistemicBeliefs.js.map +1 -1
  30. package/dist/epistemicBeliefs.lifecycle.js +7 -45
  31. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  32. package/dist/epistemicBeliefs.links.js +7 -43
  33. package/dist/epistemicBeliefs.links.js.map +1 -1
  34. package/dist/epistemicBeliefs.queries.js.map +1 -1
  35. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  36. package/dist/epistemicContracts.evaluators.js +4 -40
  37. package/dist/epistemicContracts.evaluators.js.map +1 -1
  38. package/dist/epistemicContracts.handlers.js +4 -40
  39. package/dist/epistemicContracts.handlers.js.map +1 -1
  40. package/dist/epistemicContracts.js +4 -40
  41. package/dist/epistemicContracts.js.map +1 -1
  42. package/dist/epistemicEdgeCreation.js.map +1 -1
  43. package/dist/epistemicEdges.handlers.js.map +1 -1
  44. package/dist/epistemicEdges.js +4 -4
  45. package/dist/epistemicEdges.js.map +1 -1
  46. package/dist/epistemicEdges.mutations.js +4 -4
  47. package/dist/epistemicEdges.mutations.js.map +1 -1
  48. package/dist/epistemicEdges.queries.js.map +1 -1
  49. package/dist/epistemicEvidence.js +5 -5
  50. package/dist/epistemicEvidence.js.map +1 -1
  51. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  52. package/dist/epistemicEvidenceMutations.js +5 -5
  53. package/dist/epistemicEvidenceMutations.js.map +1 -1
  54. package/dist/epistemicEvidenceQueries.js.map +1 -1
  55. package/dist/epistemicHelpers.js.map +1 -1
  56. package/dist/epistemicLinking.js.map +1 -1
  57. package/dist/epistemicNodeCreation.js.map +1 -1
  58. package/dist/epistemicNodes.internal.js.map +1 -1
  59. package/dist/epistemicNodes.js +4 -4
  60. package/dist/epistemicNodes.js.map +1 -1
  61. package/dist/epistemicNodes.mutations.js +4 -4
  62. package/dist/epistemicNodes.mutations.js.map +1 -1
  63. package/dist/epistemicNodes.queries.js.map +1 -1
  64. package/dist/epistemicQuestions.conviction.js.map +1 -1
  65. package/dist/epistemicQuestions.create.js.map +1 -1
  66. package/dist/epistemicQuestions.evidence.js.map +1 -1
  67. package/dist/epistemicQuestions.helpers.js.map +1 -1
  68. package/dist/epistemicQuestions.js.map +1 -1
  69. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  70. package/dist/epistemicQuestions.queries.js.map +1 -1
  71. package/dist/epistemicQuestions.sprint.js.map +1 -1
  72. package/dist/epistemicQuestions.tail.js.map +1 -1
  73. package/dist/epistemicSources.js +2 -2
  74. package/dist/epistemicSources.js.map +1 -1
  75. package/dist/helpers.js.map +1 -1
  76. package/dist/index.d.ts +1 -0
  77. package/dist/index.js +50 -121
  78. package/dist/index.js.map +1 -1
  79. package/dist/ontologyApproval.js.map +1 -1
  80. package/dist/ontologyDefinitions.js.map +1 -1
  81. package/dist/ontologyRegistry.js.map +1 -1
  82. package/dist/projectionReconciliation.js.map +1 -1
  83. package/dist/proof-attestation.json +1 -1
  84. package/dist/questionEvidenceLinks.js.map +1 -1
  85. package/dist/resolvers.js.map +1 -1
  86. package/dist/scopeResolverCompat.js.map +1 -1
  87. package/dist/topicProjectOverlay.js.map +1 -1
  88. package/dist/topicScope.js.map +1 -1
  89. package/dist/workflowBridge.js.map +1 -1
  90. package/dist/workspaceIsolation.js.map +1 -1
  91. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/convex.ts","../src/ontologyApproval.ts"],"names":[],"mappings":";;;;;AAc0B,iBAAA;AAsGnB,IAAM,gBAAA,GACX,uBAAA;AAGK,IAAM,QAAA,GACX,eAAA;AACK,IAAM,KAAA,GAAQ,YAAA;ACnHd,IAAM,uBAAuB,KAAA,CAAM;AAAA,EACxC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,SAAS,aAAa,EAAE,OAAO,CAAA,EAAG,QAAA,EAAU,EAAC,EAAE;AACjD,CAAC;AAEM,IAAM,oBAAoB,KAAA,CAAM;AAAA,EACrC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,YAAY;AACvB,CAAC;AAEM,IAAM,0BAA0B,KAAA,CAAM;AAAA,EAC3C,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,YAAY;AACvB,CAAC;AAEM,IAAM,oBAAoB,QAAA,CAAS;AAAA,EACxC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,SAAS,YAAY;AACvB,CAAC;AAEM,IAAM,UAAU,QAAA,CAAS;AAAA,EAC9B,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,OAAA,EAAS,IAAA,EAAK;AACxC,CAAC;AAEM,IAAM,SAAS,QAAA,CAAS;AAAA,EAC7B,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,OAAA,EAAS,IAAA,EAAK;AACxC,CAAC;AAEM,IAAM,cAAc,QAAA,CAAS;AAAA,EAClC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,OAAO,IAAA,EAAmB,IAAA,MAAmC;AAAA,IACpE,QAAA,EAAU,CAAA;AAAA,IACV,KAAA,EAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,GAC7B,IAAA,CAAK,QAAQ,MAAA,GACb;AAAA,GACN;AACF,CAAC;AAEM,IAAM,4BAA4B,QAAA,CAAS;AAAA,EAChD,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,QAAA,EAAU,CAAA,EAAE;AACtC,CAAC;AAEM,IAAM,kBAAkB,gBAAA,CAAiB;AAAA,EAC9C,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,OAAA,EAAS,IAAA,EAAK;AACxC,CAAC;AAEM,IAAM,0BAA0B,gBAAA,CAAiB;AAAA,EACtD,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,SAAS,aAAa,EAAE,OAAA,EAAS,CAAA,EAAG,cAAc,CAAA,EAAE;AACtD,CAAC","file":"ontologyApproval.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","// DORMANT: Ontology approval UI stubbed in EK-16.1c. Re-enable when approval workflow ships.\n\nimport { v } from \"convex/values\";\nimport { internalMutation, mutation, query } from \"./convex\";\nimport type { MutationCtx } from \"./convex\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\n\nexport const getPendingForProject = query({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ total: 0, bySource: [] }),\n});\n\nexport const getPendingForNode = query({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => [],\n});\n\nexport const getThemeOntologyMatches = query({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => [],\n});\n\nexport const createPendingLink = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => null,\n});\n\nexport const approve = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ success: true }),\n});\n\nexport const reject = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ success: true }),\n});\n\nexport const bulkApprove = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async (_ctx: MutationCtx, args: { linkIds?: unknown[] }) => ({\n approved: 0,\n total: Array.isArray(args.linkIds)\n ? args.linkIds.length\n : 0,\n }),\n});\n\nexport const bulkApproveHighConfidence = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ approved: 0 }),\n});\n\nexport const createNeo4jEdge = internalMutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ success: true }),\n});\n\nexport const batchCreatePendingLinks = internalMutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ created: 0, autoApproved: 0 }),\n});\n"]}
1
+ {"version":3,"sources":["../src/convex.ts","../src/ontologyApproval.ts"],"names":[],"mappings":";;;;;AAyB0B,iBAAA;AAsGnB,IAAM,gBAAA,GACX,uBAAA;AAGK,IAAM,QAAA,GACX,eAAA;AACK,IAAM,KAAA,GAAQ,YAAA;AC9Hd,IAAM,uBAAuB,KAAA,CAAM;AAAA,EACxC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,SAAS,aAAa,EAAE,OAAO,CAAA,EAAG,QAAA,EAAU,EAAC,EAAE;AACjD,CAAC;AAEM,IAAM,oBAAoB,KAAA,CAAM;AAAA,EACrC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,YAAY;AACvB,CAAC;AAEM,IAAM,0BAA0B,KAAA,CAAM;AAAA,EAC3C,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,YAAY;AACvB,CAAC;AAEM,IAAM,oBAAoB,QAAA,CAAS;AAAA,EACxC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,SAAS,YAAY;AACvB,CAAC;AAEM,IAAM,UAAU,QAAA,CAAS;AAAA,EAC9B,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,OAAA,EAAS,IAAA,EAAK;AACxC,CAAC;AAEM,IAAM,SAAS,QAAA,CAAS;AAAA,EAC7B,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,OAAA,EAAS,IAAA,EAAK;AACxC,CAAC;AAEM,IAAM,cAAc,QAAA,CAAS;AAAA,EAClC,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,OAAO,IAAA,EAAmB,IAAA,MAAmC;AAAA,IACpE,QAAA,EAAU,CAAA;AAAA,IACV,KAAA,EAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,GAC7B,IAAA,CAAK,QAAQ,MAAA,GACb;AAAA,GACN;AACF,CAAC;AAEM,IAAM,4BAA4B,QAAA,CAAS;AAAA,EAChD,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,QAAA,EAAU,CAAA,EAAE;AACtC,CAAC;AAEM,IAAM,kBAAkB,gBAAA,CAAiB;AAAA,EAC9C,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,aAAa,EAAE,OAAA,EAAS,IAAA,EAAK;AACxC,CAAC;AAEM,IAAM,0BAA0B,gBAAA,CAAiB;AAAA,EACtD,IAAA,EAAM,EAAE,GAAA,EAAI;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,SAAS,aAAa,EAAE,OAAA,EAAS,CAAA,EAAG,cAAc,CAAA,EAAE;AACtD,CAAC","file":"ontologyApproval.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","// DORMANT: Ontology approval UI stubbed in EK-16.1c. Re-enable when approval workflow ships.\n\nimport { v } from \"convex/values\";\nimport { internalMutation, mutation, query } from \"./convex\";\nimport type { MutationCtx } from \"./convex\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\n\nexport const getPendingForProject = query({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ total: 0, bySource: [] }),\n});\n\nexport const getPendingForNode = query({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => [],\n});\n\nexport const getThemeOntologyMatches = query({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => [],\n});\n\nexport const createPendingLink = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => null,\n});\n\nexport const approve = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ success: true }),\n});\n\nexport const reject = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ success: true }),\n});\n\nexport const bulkApprove = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async (_ctx: MutationCtx, args: { linkIds?: unknown[] }) => ({\n approved: 0,\n total: Array.isArray(args.linkIds)\n ? args.linkIds.length\n : 0,\n }),\n});\n\nexport const bulkApproveHighConfidence = mutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ approved: 0 }),\n});\n\nexport const createNeo4jEdge = internalMutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ success: true }),\n});\n\nexport const batchCreatePendingLinks = internalMutation({\n args: v.any(),\n returns: permissiveReturn,\n handler: async () => ({ created: 0, autoApproved: 0 }),\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/convex.ts","../src/ontologyHelpers.ts","../src/ontologyDefinitions.ts"],"names":[],"mappings":"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","file":"ontologyDefinitions.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * Ontology Definition Pure Helpers\n *\n * Pure functions for ontology key validation, version string validation,\n * layer merging, and soft edge constraint checking.\n *\n * Separated from ontologyDefinitions.ts to enable unit testing without\n * Convex runtime dependencies.\n *\n * @module graph-primitives/ontologyHelpers\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type EntityTypeEntry = {\n value: string;\n label: string;\n description?: string;\n schema?: unknown;\n subtypes?: Array<{ value: string; label: string; description?: string }>;\n};\n\nexport type EdgeTypeEntry = {\n value: string;\n label: string;\n description?: string;\n sourceTypes?: string[];\n targetTypes?: string[];\n constraintSeverity?: \"warn\" | \"info\";\n};\n\nexport type MergedOntology = {\n entityTypes: EntityTypeEntry[];\n edgeTypes: EdgeTypeEntry[];\n layers: string[]; // ontologyKeys in composition order\n};\n\nexport type EdgeConstraintResult = {\n valid: boolean;\n warnings: string[];\n};\n\n// =============================================================================\n// PURE HELPER FUNCTIONS\n// =============================================================================\n\nconst ONTOLOGY_KEY_REGEX = /^[a-z][a-z0-9-]*[a-z0-9]$/;\nconst VERSION_STRING_REGEX = /^\\d+\\.\\d+\\.\\d+$/;\n\n/**\n * Validate and normalize an ontology key.\n * Must be lowercase alphanumeric with hyphens, 2+ chars.\n */\nexport function validateOntologyKey(key: string): {\n valid: boolean;\n normalized: string;\n error?: string;\n} {\n const normalized = key.trim().toLowerCase();\n if (normalized.length < 2) {\n return {\n valid: false,\n normalized,\n error: \"Ontology key must be at least 2 characters.\",\n };\n }\n if (normalized.length > 64) {\n return {\n valid: false,\n normalized,\n error: \"Ontology key must be at most 64 characters.\",\n };\n }\n if (!ONTOLOGY_KEY_REGEX.test(normalized)) {\n return {\n valid: false,\n normalized,\n error:\n \"Ontology key must start with a letter, contain only lowercase letters, digits, and hyphens, and not end with a hyphen.\",\n };\n }\n return { valid: true, normalized };\n}\n\n/**\n * Validate a version string (basic semver-like format).\n * Accepts \"X.Y.Z\" where X, Y, Z are non-negative integers.\n */\nexport const validateVersionString = VERSION_STRING_REGEX.test.bind(\n VERSION_STRING_REGEX\n) as (version: string) => boolean;\n\n/**\n * Merge ontology layers additively. Child adds to parent; never removes.\n * Duplicate entity/edge values in child override parent entries.\n */\nexport function mergeOntologyLayers(\n parent: { entityTypes: EntityTypeEntry[]; edgeTypes: EdgeTypeEntry[] },\n child: { entityTypes: EntityTypeEntry[]; edgeTypes: EdgeTypeEntry[] },\n parentKey: string,\n childKey: string\n): MergedOntology {\n // Entity types: child overrides parent by value\n const entityMap = new Map<string, EntityTypeEntry>();\n for (const et of parent.entityTypes) {\n entityMap.set(et.value, et);\n }\n for (const et of child.entityTypes) {\n entityMap.set(et.value, et);\n }\n\n // Edge types: child overrides parent by value\n const edgeMap = new Map<string, EdgeTypeEntry>();\n for (const edge of parent.edgeTypes) {\n edgeMap.set(edge.value, edge);\n }\n for (const edge of child.edgeTypes) {\n edgeMap.set(edge.value, edge);\n }\n\n return {\n entityTypes: Array.from(entityMap.values()),\n edgeTypes: Array.from(edgeMap.values()),\n layers: [parentKey, childKey],\n };\n}\n\n/**\n * Validate an edge against soft constraints.\n * Returns warnings but never blocks (soft constraint model).\n */\nexport function validateEdgeConstraint(\n edge: { sourceType: string; targetType: string; edgeType: string },\n constraints: EdgeTypeEntry | undefined\n): EdgeConstraintResult {\n if (!constraints) {\n return { valid: true, warnings: [] };\n }\n\n const warnings: string[] = [];\n\n if (\n constraints.sourceTypes &&\n constraints.sourceTypes.length > 0 &&\n !constraints.sourceTypes.includes(edge.sourceType)\n ) {\n warnings.push(\n `Edge type \"${edge.edgeType}\" recommends source types [${constraints.sourceTypes.join(\", \")}] but got \"${edge.sourceType}\".`\n );\n }\n\n if (\n constraints.targetTypes &&\n constraints.targetTypes.length > 0 &&\n !constraints.targetTypes.includes(edge.targetType)\n ) {\n warnings.push(\n `Edge type \"${edge.edgeType}\" recommends target types [${constraints.targetTypes.join(\", \")}] but got \"${edge.targetType}\".`\n );\n }\n\n // Soft constraints: always valid, just warn\n return { valid: true, warnings };\n}\n\n/**\n * Resolve effective tier from definition tier and tenantId.\n */\nexport function resolveEffectiveTier(\n defTier: \"platform\" | \"pack\" | \"tenant\",\n tenantId?: string\n): \"platform\" | \"pack\" | \"tenant\" {\n if (!tenantId) {\n return \"platform\";\n }\n if (defTier === \"platform\") {\n return \"platform\";\n }\n return defTier;\n}\n","/**\n * Ontology Definition Mutations & Queries\n *\n * CRUD operations for first-class ontology definition objects.\n * Follows the packDefinitions + packVersions two-table pattern from Master Control.\n *\n * Pure helper functions live in ontologyHelpers.ts for unit testing.\n *\n * @module graph-primitives/ontologyDefinitions\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport type { Id, MutationCtx, QueryCtx } from \"./convex\";\nimport { mutation, query } from \"./convex\";\nimport type {\n EdgeTypeEntry,\n EntityTypeEntry,\n MergedOntology,\n} from \"./ontologyHelpers\";\nimport {\n mergeOntologyLayers,\n validateOntologyKey,\n validateVersionString,\n} from \"./ontologyHelpers\";\n\n// =============================================================================\n// AUTH HELPER\n// =============================================================================\n\nasync function requireAuth(ctx: MutationCtx): Promise<string> {\n const userId = await getCurrentUserId(ctx as any);\n if (!userId) {\n throw new Error(\"Authentication required.\");\n }\n return userId;\n}\n\nasync function _requireAuthQuery(ctx: QueryCtx): Promise<string> {\n const userId = await getCurrentUserId(ctx as any);\n if (!userId) {\n throw new Error(\"Authentication required.\");\n }\n return userId;\n}\n\n// =============================================================================\n// AUDIT HELPER\n// =============================================================================\n\ntype AuditEntityType = \"ontologyDefinition\" | \"ontologyVersion\";\ntype AuditChangeType =\n | \"created\"\n | \"updated\"\n | \"archived\"\n | \"published\"\n | \"deprecated\";\ntype IndexRangeBuilder = {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype OntologyDefinitionStatus =\n | \"draft\"\n | \"active\"\n | \"deprecated\"\n | \"archived\";\ntype OntologyVersionStatus = \"draft\" | \"published\" | \"deprecated\";\ntype OntologyDefinitionDoc = {\n _id: Id<\"ontologyDefinitions\">;\n ontologyKey: string;\n name?: string;\n description?: string;\n parentOntologyId?: Id<\"ontologyDefinitions\">;\n status: OntologyDefinitionStatus;\n};\ntype OntologyVersionDoc = {\n _id: Id<\"ontologyVersions\">;\n ontologyId: Id<\"ontologyDefinitions\">;\n ontologyKey: string;\n version: string;\n status: OntologyVersionStatus;\n publishedAt?: number;\n entityTypes: unknown;\n edgeTypes: unknown;\n};\ntype CreateOntologyVersionArgs = {\n ontologyId: Id<\"ontologyDefinitions\">;\n version: string;\n entityTypes: EntityTypeEntry[];\n edgeTypes: EdgeTypeEntry[];\n releaseNotes?: string;\n};\ntype UpdateDraftVersionArgs = {\n id: Id<\"ontologyVersions\">;\n entityTypes?: EntityTypeEntry[];\n edgeTypes?: EdgeTypeEntry[];\n releaseNotes?: string;\n};\ntype VersionStatusMutationArgs = {\n id: Id<\"ontologyVersions\">;\n ontologyId?: Id<\"ontologyDefinitions\">;\n};\n\nasync function logAudit(\n ctx: MutationCtx,\n args: {\n entityType: AuditEntityType;\n entityId: string;\n changeType: AuditChangeType;\n changedBy: string;\n previousState: unknown;\n newState: unknown;\n }\n) {\n await ctx.db.insert(\"epistemicAudit\", {\n entityType: args.entityType,\n entityId: args.entityId,\n changeType: args.changeType,\n changedAt: Date.now(),\n changedBy: args.changedBy,\n isAgent: false,\n previousState: args.previousState ?? null,\n newState: args.newState ?? null,\n });\n}\n\n// =============================================================================\n// QUERIES\n// =============================================================================\n\n/**\n * Get an ontology definition by ID.\n */\nexport const getOntologyDefinition = query({\n args: { id: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { id: Id<\"ontologyDefinitions\"> }\n ) => {\n return await ctx.db.get(args.id);\n },\n});\n\n/**\n * Get an ontology definition by ontologyKey (optionally scoped by tenant).\n */\nexport const getOntologyDefinitionByKey = query({\n args: {\n ontologyKey: v.string(),\n tenantId: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyKey: string; tenantId?: string }\n ) => {\n if (args.tenantId) {\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_ontologyKey\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"ontologyKey\", args.ontologyKey)\n )\n .first();\n }\n // Platform default (tenantId = undefined)\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_ontologyKey\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", undefined).eq(\"ontologyKey\", args.ontologyKey)\n )\n .first();\n },\n});\n\n/**\n * List ontology definitions with optional filters.\n */\nexport const listOntologyDefinitions = query({\n args: {\n tenantId: v.optional(v.string()),\n tier: v.optional(\n v.union(v.literal(\"platform\"), v.literal(\"pack\"), v.literal(\"tenant\"))\n ),\n status: v.optional(\n v.union(\n v.literal(\"draft\"),\n v.literal(\"active\"),\n v.literal(\"deprecated\"),\n v.literal(\"archived\")\n )\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: {\n tenantId?: string;\n tier?: \"platform\" | \"pack\" | \"tenant\";\n status?: OntologyDefinitionStatus;\n }\n ) => {\n if (args.tenantId && args.status) {\n const status = args.status;\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_status\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"status\", status)\n )\n .collect();\n }\n if (args.status) {\n const status = args.status;\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_status\", (q: IndexRangeBuilder) =>\n q.eq(\"status\", status)\n )\n .collect();\n }\n if (args.tier) {\n const tier = args.tier;\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tier\", (q: IndexRangeBuilder) => q.eq(\"tier\", tier))\n .collect();\n }\n return await ctx.db.query(\"ontologyDefinitions\").collect();\n },\n});\n\n/**\n * Get a specific version by ontologyId + version string.\n */\nexport const getOntologyVersion = query({\n args: {\n ontologyKey: v.string(),\n version: v.string(),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyKey: string; version: string }\n ) => {\n return await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyKey_version\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyKey\", args.ontologyKey).eq(\"version\", args.version)\n )\n .first();\n },\n});\n\n/**\n * List versions for an ontology, optionally filtered by status.\n */\nexport const listOntologyVersions = query({\n args: {\n ontologyId: v.id(\"ontologyDefinitions\"),\n status: v.optional(\n v.union(\n v.literal(\"draft\"),\n v.literal(\"published\"),\n v.literal(\"deprecated\")\n )\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyId: Id<\"ontologyDefinitions\">; status?: OntologyVersionStatus }\n ) => {\n const all = (await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyId\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyId\", args.ontologyId)\n )\n .collect()) as OntologyVersionDoc[];\n\n if (args.status) {\n return all.filter(\n (versionDoc: OntologyVersionDoc) => versionDoc.status === args.status\n );\n }\n return all;\n },\n});\n\n/**\n * Get the latest published version for an ontology.\n */\nexport const getPublishedVersion = query({\n args: { ontologyId: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyId: Id<\"ontologyDefinitions\"> }\n ) => {\n const published = (await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyId\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyId\", args.ontologyId)\n )\n .collect()) as OntologyVersionDoc[];\n\n const publishedOnly = published.filter(\n (versionDoc: OntologyVersionDoc) => versionDoc.status === \"published\"\n );\n if (publishedOnly.length === 0) {\n return null;\n }\n\n // Return most recently published\n publishedOnly.sort(\n (a: OntologyVersionDoc, b: OntologyVersionDoc) =>\n (b.publishedAt ?? 0) - (a.publishedAt ?? 0)\n );\n return publishedOnly[0];\n },\n});\n\n/**\n * Resolve the effective ontology by composing parent chain.\n * Walks parentOntologyId chain (max depth 3) and merges additively.\n */\nexport const resolveEffectiveOntology = query({\n args: { ontologyId: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyId: Id<\"ontologyDefinitions\"> }\n ) => {\n const MAX_DEPTH = 3;\n type OntologyDef = {\n ontologyKey: string;\n parentOntologyId?: Id<\"ontologyDefinitions\">;\n };\n type OntologyVer = {\n status: string;\n publishedAt?: number;\n entityTypes: unknown;\n edgeTypes: unknown;\n };\n const chain: Array<{ def: OntologyDef; version: OntologyVer | null }> = [];\n\n // Walk parent chain\n let currentId: Id<\"ontologyDefinitions\"> | undefined = args.ontologyId;\n for (let depth = 0; depth < MAX_DEPTH && currentId; depth++) {\n const ontologyId = currentId;\n const def = await ctx.db.get(ontologyId);\n if (!def) {\n break;\n }\n const defTyped = def as unknown as OntologyDef & {\n _id: Id<\"ontologyDefinitions\">;\n };\n\n // Get latest published version\n const versions = (await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyId\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyId\", ontologyId)\n )\n .collect()) as OntologyVer[];\n const published = versions\n .filter((ver: OntologyVer) => ver.status === \"published\")\n .sort(\n (a: OntologyVer, b: OntologyVer) =>\n ((b.publishedAt as number) ?? 0) - ((a.publishedAt as number) ?? 0)\n );\n\n chain.unshift({\n def: defTyped,\n version: (published[0] as OntologyVer) ?? null,\n });\n currentId = defTyped.parentOntologyId;\n }\n\n if (chain.length === 0) {\n return null;\n }\n\n // Merge layers from root (platform) to leaf (tenant)\n let merged: MergedOntology = {\n entityTypes: [],\n edgeTypes: [],\n layers: [],\n };\n\n for (const { def, version } of chain) {\n if (!version) {\n merged.layers.push(def.ontologyKey);\n continue;\n }\n const previousLayerKey = merged.layers.at(-1) ?? def.ontologyKey;\n merged = mergeOntologyLayers(\n merged,\n {\n entityTypes: version.entityTypes as EntityTypeEntry[],\n edgeTypes: version.edgeTypes as EdgeTypeEntry[],\n },\n previousLayerKey,\n def.ontologyKey\n );\n }\n\n return merged;\n },\n});\n\n// =============================================================================\n// MUTATIONS\n// =============================================================================\n\n/**\n * Create a new ontology definition.\n */\nexport const createOntologyDefinition = mutation({\n args: {\n ontologyKey: v.string(),\n name: v.string(),\n description: v.optional(v.string()),\n tenantId: v.optional(v.string()),\n tier: v.union(\n v.literal(\"platform\"),\n v.literal(\"pack\"),\n v.literal(\"tenant\")\n ),\n parentOntologyId: v.optional(v.id(\"ontologyDefinitions\")),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: MutationCtx,\n args: {\n ontologyKey: string;\n name: string;\n description?: string;\n tenantId?: string;\n tier: \"platform\" | \"pack\" | \"tenant\";\n parentOntologyId?: Id<\"ontologyDefinitions\">;\n }\n ) => {\n const userId = await requireAuth(ctx);\n\n // Validate ontology key\n const keyResult = validateOntologyKey(args.ontologyKey);\n if (!keyResult.valid) {\n throw new Error(keyResult.error ?? \"Invalid ontology key\");\n }\n\n // Check uniqueness within tenant scope\n const existing = await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_ontologyKey\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"ontologyKey\", keyResult.normalized)\n )\n .first();\n\n if (existing) {\n throw new Error(\n `Ontology \"${keyResult.normalized}\" already exists for tenant ${args.tenantId ?? \"(platform)\"}.`\n );\n }\n\n // Validate parent exists if specified\n if (args.parentOntologyId) {\n const parent = await ctx.db.get(args.parentOntologyId);\n if (!parent) {\n throw new Error(\"Parent ontology definition not found.\");\n }\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"ontologyDefinitions\", {\n ontologyKey: keyResult.normalized,\n name: args.name,\n description: args.description,\n tenantId: args.tenantId,\n tier: args.tier,\n parentOntologyId: args.parentOntologyId,\n status: \"draft\",\n createdBy: userId,\n createdAt: now,\n updatedAt: now,\n });\n\n await logAudit(ctx, {\n entityType: \"ontologyDefinition\",\n entityId: id,\n changeType: \"created\",\n changedBy: userId,\n previousState: null,\n newState: {\n ontologyKey: keyResult.normalized,\n name: args.name,\n tier: args.tier,\n },\n });\n\n return { id, ontologyKey: keyResult.normalized };\n },\n});\n\n/**\n * Update an ontology definition (name, description, status).\n * Only allowed while draft or active.\n */\nexport const updateOntologyDefinition = mutation({\n args: {\n id: v.id(\"ontologyDefinitions\"),\n name: v.optional(v.string()),\n description: v.optional(v.string()),\n status: v.optional(\n v.union(v.literal(\"draft\"), v.literal(\"active\"), v.literal(\"deprecated\"))\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: MutationCtx,\n args: {\n id: Id<\"ontologyDefinitions\">;\n name?: string;\n description?: string;\n status?: Exclude<OntologyDefinitionStatus, \"archived\">;\n }\n ) => {\n const userId = await requireAuth(ctx);\n\n const def = (await ctx.db.get(args.id)) as OntologyDefinitionDoc | null;\n if (!def) {\n throw new Error(\"Ontology definition not found.\");\n }\n\n if (def.status === \"archived\") {\n throw new Error(\"Cannot update an archived ontology definition.\");\n }\n\n const previousState = {\n name: def.name,\n description: def.description,\n status: def.status,\n };\n\n const patch: Record<string, unknown> = { updatedAt: Date.now() };\n if (args.name !== undefined) {\n patch.name = args.name;\n }\n if (args.description !== undefined) {\n patch.description = args.description;\n }\n if (args.status !== undefined) {\n patch.status = args.status;\n }\n\n await ctx.db.patch(args.id, patch);\n\n await logAudit(ctx, {\n entityType: \"ontologyDefinition\",\n entityId: args.id,\n changeType: \"updated\",\n changedBy: userId,\n previousState,\n newState: patch,\n });\n\n return { success: true };\n },\n});\n\n/**\n * Archive an ontology definition.\n */\nexport const archiveOntologyDefinition = mutation({\n args: { id: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: MutationCtx,\n args: { id: Id<\"ontologyDefinitions\"> }\n ) => {\n const userId = await requireAuth(ctx);\n\n const def = (await ctx.db.get(args.id)) as OntologyDefinitionDoc | null;\n if (!def) {\n throw new Error(\"Ontology definition not found.\");\n }\n\n if (def.status === \"archived\") {\n return { success: true };\n }\n\n await ctx.db.patch(args.id, { status: \"archived\", updatedAt: Date.now() });\n\n await logAudit(ctx, {\n entityType: \"ontologyDefinition\",\n entityId: args.id,\n changeType: \"archived\",\n changedBy: userId,\n previousState: { status: def.status },\n newState: { status: \"archived\" },\n });\n\n return { success: true };\n },\n});\n\n/**\n * Create a new version snapshot for an ontology.\n */\nexport const createOntologyVersion = mutation({\n args: {\n ontologyId: v.id(\"ontologyDefinitions\"),\n version: v.string(),\n entityTypes: v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.optional(v.any()),\n subtypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n })\n )\n ),\n })\n ),\n edgeTypes: v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n sourceTypes: v.optional(v.array(v.string())),\n targetTypes: v.optional(v.array(v.string())),\n constraintSeverity: v.optional(\n v.union(v.literal(\"warn\"), v.literal(\"info\"))\n ),\n })\n ),\n releaseNotes: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: CreateOntologyVersionArgs) => {\n const userId = await requireAuth(ctx);\n\n // Validate version string\n if (!validateVersionString(args.version)) {\n throw new Error(\n `Invalid version string \"${args.version}\". Must be in X.Y.Z format.`\n );\n }\n\n // Validate parent definition exists\n const def = (await ctx.db.get(\n args.ontologyId\n )) as OntologyDefinitionDoc | null;\n if (!def) {\n throw new Error(\"Ontology definition not found.\");\n }\n\n if (def.status === \"archived\") {\n throw new Error(\"Cannot add versions to an archived ontology.\");\n }\n\n // Check version uniqueness\n const existing = await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyKey_version\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyKey\", def.ontologyKey).eq(\"version\", args.version)\n )\n .first();\n\n if (existing) {\n throw new Error(\n `Version \"${args.version}\" already exists for ontology \"${def.ontologyKey}\".`\n );\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"ontologyVersions\", {\n ontologyId: args.ontologyId,\n ontologyKey: def.ontologyKey,\n version: args.version,\n status: \"draft\",\n entityTypes: args.entityTypes,\n edgeTypes: args.edgeTypes,\n releaseNotes: args.releaseNotes,\n createdAt: now,\n });\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: id,\n changeType: \"created\",\n changedBy: userId,\n previousState: null,\n newState: {\n ontologyKey: def.ontologyKey,\n version: args.version,\n entityTypeCount: args.entityTypes.length,\n edgeTypeCount: args.edgeTypes.length,\n },\n });\n\n return { id, version: args.version };\n },\n});\n\n/**\n * Update a draft version (entityTypes, edgeTypes, releaseNotes).\n * Only allowed while version is in \"draft\" status.\n */\nexport const updateDraftVersion = mutation({\n args: {\n id: v.id(\"ontologyVersions\"),\n entityTypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.optional(v.any()),\n subtypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n })\n )\n ),\n })\n )\n ),\n edgeTypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n sourceTypes: v.optional(v.array(v.string())),\n targetTypes: v.optional(v.array(v.string())),\n constraintSeverity: v.optional(\n v.union(v.literal(\"warn\"), v.literal(\"info\"))\n ),\n })\n )\n ),\n releaseNotes: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: UpdateDraftVersionArgs) => {\n const userId = await requireAuth(ctx);\n\n const ver = (await ctx.db.get(args.id)) as OntologyVersionDoc | null;\n if (!ver) {\n throw new Error(\"Ontology version not found.\");\n }\n\n if (ver.status !== \"draft\") {\n throw new Error(\n `Cannot update a ${ver.status} version. Only draft versions are editable.`\n );\n }\n\n const patch: Record<string, unknown> = {};\n if (args.entityTypes !== undefined) {\n patch.entityTypes = args.entityTypes;\n }\n if (args.edgeTypes !== undefined) {\n patch.edgeTypes = args.edgeTypes;\n }\n if (args.releaseNotes !== undefined) {\n patch.releaseNotes = args.releaseNotes;\n }\n\n await ctx.db.patch(args.id, patch);\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: args.id,\n changeType: \"updated\",\n changedBy: userId,\n previousState: { status: ver.status },\n newState: patch,\n });\n\n return { success: true };\n },\n});\n\n/**\n * Publish a version — freezes it (status → \"published\").\n * If the parent definition is \"draft\", promotes it to \"active\".\n */\nexport const publishOntologyVersion = mutation({\n args: {\n id: v.id(\"ontologyVersions\"),\n ontologyId: v.optional(v.id(\"ontologyDefinitions\")),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: VersionStatusMutationArgs) => {\n const userId = await requireAuth(ctx);\n\n const ver = (await ctx.db.get(args.id)) as OntologyVersionDoc | null;\n if (!ver) {\n throw new Error(\"Ontology version not found.\");\n }\n\n // Verify ownership if ontologyId provided\n if (args.ontologyId && ver.ontologyId !== args.ontologyId) {\n throw new Error(\n \"Version does not belong to the specified ontology definition.\"\n );\n }\n\n if (ver.status !== \"draft\") {\n throw new Error(\n `Cannot publish a ${ver.status} version. Only draft versions can be published.`\n );\n }\n\n const now = Date.now();\n await ctx.db.patch(args.id, {\n status: \"published\",\n publishedBy: userId,\n publishedAt: now,\n });\n\n // Promote parent definition to \"active\" if still in \"draft\"\n const def = (await ctx.db.get(ver.ontologyId)) as\n | OntologyDefinitionDoc\n | null;\n if (def && def.status === \"draft\") {\n await ctx.db.patch(ver.ontologyId, {\n status: \"active\",\n updatedAt: now,\n });\n }\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: args.id,\n changeType: \"published\",\n changedBy: userId,\n previousState: { status: \"draft\" },\n newState: { status: \"published\", publishedAt: now },\n });\n\n return { success: true, publishedAt: now };\n },\n});\n\n/**\n * Deprecate a published version.\n */\nexport const deprecateOntologyVersion = mutation({\n args: {\n id: v.id(\"ontologyVersions\"),\n ontologyId: v.optional(v.id(\"ontologyDefinitions\")),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: VersionStatusMutationArgs) => {\n const userId = await requireAuth(ctx);\n\n const ver = (await ctx.db.get(args.id)) as OntologyVersionDoc | null;\n if (!ver) {\n throw new Error(\"Ontology version not found.\");\n }\n\n // Verify ownership if ontologyId provided\n if (args.ontologyId && ver.ontologyId !== args.ontologyId) {\n throw new Error(\n \"Version does not belong to the specified ontology definition.\"\n );\n }\n\n if (ver.status === \"deprecated\") {\n return { success: true };\n }\n\n if (ver.status !== \"published\") {\n throw new Error(\n `Cannot deprecate a ${ver.status} version. Only published versions can be deprecated.`\n );\n }\n\n await ctx.db.patch(args.id, { status: \"deprecated\" });\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: args.id,\n changeType: \"deprecated\",\n changedBy: userId,\n previousState: { status: \"published\" },\n newState: { status: \"deprecated\" },\n });\n\n return { success: true };\n },\n});\n"]}
1
+ {"version":3,"sources":["../src/convex.ts","../src/ontologyHelpers.ts","../src/ontologyDefinitions.ts"],"names":[],"mappings":"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","file":"ontologyDefinitions.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * Ontology Definition Pure Helpers\n *\n * Pure functions for ontology key validation, version string validation,\n * layer merging, and soft edge constraint checking.\n *\n * Separated from ontologyDefinitions.ts to enable unit testing without\n * Convex runtime dependencies.\n *\n * @module graph-primitives/ontologyHelpers\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type EntityTypeEntry = {\n value: string;\n label: string;\n description?: string;\n schema?: unknown;\n subtypes?: Array<{ value: string; label: string; description?: string }>;\n};\n\nexport type EdgeTypeEntry = {\n value: string;\n label: string;\n description?: string;\n sourceTypes?: string[];\n targetTypes?: string[];\n constraintSeverity?: \"warn\" | \"info\";\n};\n\nexport type MergedOntology = {\n entityTypes: EntityTypeEntry[];\n edgeTypes: EdgeTypeEntry[];\n layers: string[]; // ontologyKeys in composition order\n};\n\nexport type EdgeConstraintResult = {\n valid: boolean;\n warnings: string[];\n};\n\n// =============================================================================\n// PURE HELPER FUNCTIONS\n// =============================================================================\n\nconst ONTOLOGY_KEY_REGEX = /^[a-z][a-z0-9-]*[a-z0-9]$/;\nconst VERSION_STRING_REGEX = /^\\d+\\.\\d+\\.\\d+$/;\n\n/**\n * Validate and normalize an ontology key.\n * Must be lowercase alphanumeric with hyphens, 2+ chars.\n */\nexport function validateOntologyKey(key: string): {\n valid: boolean;\n normalized: string;\n error?: string;\n} {\n const normalized = key.trim().toLowerCase();\n if (normalized.length < 2) {\n return {\n valid: false,\n normalized,\n error: \"Ontology key must be at least 2 characters.\",\n };\n }\n if (normalized.length > 64) {\n return {\n valid: false,\n normalized,\n error: \"Ontology key must be at most 64 characters.\",\n };\n }\n if (!ONTOLOGY_KEY_REGEX.test(normalized)) {\n return {\n valid: false,\n normalized,\n error:\n \"Ontology key must start with a letter, contain only lowercase letters, digits, and hyphens, and not end with a hyphen.\",\n };\n }\n return { valid: true, normalized };\n}\n\n/**\n * Validate a version string (basic semver-like format).\n * Accepts \"X.Y.Z\" where X, Y, Z are non-negative integers.\n */\nexport const validateVersionString = VERSION_STRING_REGEX.test.bind(\n VERSION_STRING_REGEX\n) as (version: string) => boolean;\n\n/**\n * Merge ontology layers additively. Child adds to parent; never removes.\n * Duplicate entity/edge values in child override parent entries.\n */\nexport function mergeOntologyLayers(\n parent: { entityTypes: EntityTypeEntry[]; edgeTypes: EdgeTypeEntry[] },\n child: { entityTypes: EntityTypeEntry[]; edgeTypes: EdgeTypeEntry[] },\n parentKey: string,\n childKey: string\n): MergedOntology {\n // Entity types: child overrides parent by value\n const entityMap = new Map<string, EntityTypeEntry>();\n for (const et of parent.entityTypes) {\n entityMap.set(et.value, et);\n }\n for (const et of child.entityTypes) {\n entityMap.set(et.value, et);\n }\n\n // Edge types: child overrides parent by value\n const edgeMap = new Map<string, EdgeTypeEntry>();\n for (const edge of parent.edgeTypes) {\n edgeMap.set(edge.value, edge);\n }\n for (const edge of child.edgeTypes) {\n edgeMap.set(edge.value, edge);\n }\n\n return {\n entityTypes: Array.from(entityMap.values()),\n edgeTypes: Array.from(edgeMap.values()),\n layers: [parentKey, childKey],\n };\n}\n\n/**\n * Validate an edge against soft constraints.\n * Returns warnings but never blocks (soft constraint model).\n */\nexport function validateEdgeConstraint(\n edge: { sourceType: string; targetType: string; edgeType: string },\n constraints: EdgeTypeEntry | undefined\n): EdgeConstraintResult {\n if (!constraints) {\n return { valid: true, warnings: [] };\n }\n\n const warnings: string[] = [];\n\n if (\n constraints.sourceTypes &&\n constraints.sourceTypes.length > 0 &&\n !constraints.sourceTypes.includes(edge.sourceType)\n ) {\n warnings.push(\n `Edge type \"${edge.edgeType}\" recommends source types [${constraints.sourceTypes.join(\", \")}] but got \"${edge.sourceType}\".`\n );\n }\n\n if (\n constraints.targetTypes &&\n constraints.targetTypes.length > 0 &&\n !constraints.targetTypes.includes(edge.targetType)\n ) {\n warnings.push(\n `Edge type \"${edge.edgeType}\" recommends target types [${constraints.targetTypes.join(\", \")}] but got \"${edge.targetType}\".`\n );\n }\n\n // Soft constraints: always valid, just warn\n return { valid: true, warnings };\n}\n\n/**\n * Resolve effective tier from definition tier and tenantId.\n */\nexport function resolveEffectiveTier(\n defTier: \"platform\" | \"pack\" | \"tenant\",\n tenantId?: string\n): \"platform\" | \"pack\" | \"tenant\" {\n if (!tenantId) {\n return \"platform\";\n }\n if (defTier === \"platform\") {\n return \"platform\";\n }\n return defTier;\n}\n","/**\n * Ontology Definition Mutations & Queries\n *\n * CRUD operations for first-class ontology definition objects.\n * Follows the packDefinitions + packVersions two-table pattern from Master Control.\n *\n * Pure helper functions live in ontologyHelpers.ts for unit testing.\n *\n * @module graph-primitives/ontologyDefinitions\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport type { Id, MutationCtx, QueryCtx } from \"./convex\";\nimport { mutation, query } from \"./convex\";\nimport type {\n EdgeTypeEntry,\n EntityTypeEntry,\n MergedOntology,\n} from \"./ontologyHelpers\";\nimport {\n mergeOntologyLayers,\n validateOntologyKey,\n validateVersionString,\n} from \"./ontologyHelpers\";\n\n// =============================================================================\n// AUTH HELPER\n// =============================================================================\n\nasync function requireAuth(ctx: MutationCtx): Promise<string> {\n const userId = await getCurrentUserId(ctx as any);\n if (!userId) {\n throw new Error(\"Authentication required.\");\n }\n return userId;\n}\n\nasync function _requireAuthQuery(ctx: QueryCtx): Promise<string> {\n const userId = await getCurrentUserId(ctx as any);\n if (!userId) {\n throw new Error(\"Authentication required.\");\n }\n return userId;\n}\n\n// =============================================================================\n// AUDIT HELPER\n// =============================================================================\n\ntype AuditEntityType = \"ontologyDefinition\" | \"ontologyVersion\";\ntype AuditChangeType =\n | \"created\"\n | \"updated\"\n | \"archived\"\n | \"published\"\n | \"deprecated\";\ntype IndexRangeBuilder = {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype OntologyDefinitionStatus =\n | \"draft\"\n | \"active\"\n | \"deprecated\"\n | \"archived\";\ntype OntologyVersionStatus = \"draft\" | \"published\" | \"deprecated\";\ntype OntologyDefinitionDoc = {\n _id: Id<\"ontologyDefinitions\">;\n ontologyKey: string;\n name?: string;\n description?: string;\n parentOntologyId?: Id<\"ontologyDefinitions\">;\n status: OntologyDefinitionStatus;\n};\ntype OntologyVersionDoc = {\n _id: Id<\"ontologyVersions\">;\n ontologyId: Id<\"ontologyDefinitions\">;\n ontologyKey: string;\n version: string;\n status: OntologyVersionStatus;\n publishedAt?: number;\n entityTypes: unknown;\n edgeTypes: unknown;\n};\ntype CreateOntologyVersionArgs = {\n ontologyId: Id<\"ontologyDefinitions\">;\n version: string;\n entityTypes: EntityTypeEntry[];\n edgeTypes: EdgeTypeEntry[];\n releaseNotes?: string;\n};\ntype UpdateDraftVersionArgs = {\n id: Id<\"ontologyVersions\">;\n entityTypes?: EntityTypeEntry[];\n edgeTypes?: EdgeTypeEntry[];\n releaseNotes?: string;\n};\ntype VersionStatusMutationArgs = {\n id: Id<\"ontologyVersions\">;\n ontologyId?: Id<\"ontologyDefinitions\">;\n};\n\nasync function logAudit(\n ctx: MutationCtx,\n args: {\n entityType: AuditEntityType;\n entityId: string;\n changeType: AuditChangeType;\n changedBy: string;\n previousState: unknown;\n newState: unknown;\n }\n) {\n await ctx.db.insert(\"epistemicAudit\", {\n entityType: args.entityType,\n entityId: args.entityId,\n changeType: args.changeType,\n changedAt: Date.now(),\n changedBy: args.changedBy,\n isAgent: false,\n previousState: args.previousState ?? null,\n newState: args.newState ?? null,\n });\n}\n\n// =============================================================================\n// QUERIES\n// =============================================================================\n\n/**\n * Get an ontology definition by ID.\n */\nexport const getOntologyDefinition = query({\n args: { id: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { id: Id<\"ontologyDefinitions\"> }\n ) => {\n return await ctx.db.get(args.id);\n },\n});\n\n/**\n * Get an ontology definition by ontologyKey (optionally scoped by tenant).\n */\nexport const getOntologyDefinitionByKey = query({\n args: {\n ontologyKey: v.string(),\n tenantId: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyKey: string; tenantId?: string }\n ) => {\n if (args.tenantId) {\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_ontologyKey\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"ontologyKey\", args.ontologyKey)\n )\n .first();\n }\n // Platform default (tenantId = undefined)\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_ontologyKey\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", undefined).eq(\"ontologyKey\", args.ontologyKey)\n )\n .first();\n },\n});\n\n/**\n * List ontology definitions with optional filters.\n */\nexport const listOntologyDefinitions = query({\n args: {\n tenantId: v.optional(v.string()),\n tier: v.optional(\n v.union(v.literal(\"platform\"), v.literal(\"pack\"), v.literal(\"tenant\"))\n ),\n status: v.optional(\n v.union(\n v.literal(\"draft\"),\n v.literal(\"active\"),\n v.literal(\"deprecated\"),\n v.literal(\"archived\")\n )\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: {\n tenantId?: string;\n tier?: \"platform\" | \"pack\" | \"tenant\";\n status?: OntologyDefinitionStatus;\n }\n ) => {\n if (args.tenantId && args.status) {\n const status = args.status;\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_status\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"status\", status)\n )\n .collect();\n }\n if (args.status) {\n const status = args.status;\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_status\", (q: IndexRangeBuilder) =>\n q.eq(\"status\", status)\n )\n .collect();\n }\n if (args.tier) {\n const tier = args.tier;\n return await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tier\", (q: IndexRangeBuilder) => q.eq(\"tier\", tier))\n .collect();\n }\n return await ctx.db.query(\"ontologyDefinitions\").collect();\n },\n});\n\n/**\n * Get a specific version by ontologyId + version string.\n */\nexport const getOntologyVersion = query({\n args: {\n ontologyKey: v.string(),\n version: v.string(),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyKey: string; version: string }\n ) => {\n return await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyKey_version\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyKey\", args.ontologyKey).eq(\"version\", args.version)\n )\n .first();\n },\n});\n\n/**\n * List versions for an ontology, optionally filtered by status.\n */\nexport const listOntologyVersions = query({\n args: {\n ontologyId: v.id(\"ontologyDefinitions\"),\n status: v.optional(\n v.union(\n v.literal(\"draft\"),\n v.literal(\"published\"),\n v.literal(\"deprecated\")\n )\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyId: Id<\"ontologyDefinitions\">; status?: OntologyVersionStatus }\n ) => {\n const all = (await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyId\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyId\", args.ontologyId)\n )\n .collect()) as OntologyVersionDoc[];\n\n if (args.status) {\n return all.filter(\n (versionDoc: OntologyVersionDoc) => versionDoc.status === args.status\n );\n }\n return all;\n },\n});\n\n/**\n * Get the latest published version for an ontology.\n */\nexport const getPublishedVersion = query({\n args: { ontologyId: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyId: Id<\"ontologyDefinitions\"> }\n ) => {\n const published = (await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyId\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyId\", args.ontologyId)\n )\n .collect()) as OntologyVersionDoc[];\n\n const publishedOnly = published.filter(\n (versionDoc: OntologyVersionDoc) => versionDoc.status === \"published\"\n );\n if (publishedOnly.length === 0) {\n return null;\n }\n\n // Return most recently published\n publishedOnly.sort(\n (a: OntologyVersionDoc, b: OntologyVersionDoc) =>\n (b.publishedAt ?? 0) - (a.publishedAt ?? 0)\n );\n return publishedOnly[0];\n },\n});\n\n/**\n * Resolve the effective ontology by composing parent chain.\n * Walks parentOntologyId chain (max depth 3) and merges additively.\n */\nexport const resolveEffectiveOntology = query({\n args: { ontologyId: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { ontologyId: Id<\"ontologyDefinitions\"> }\n ) => {\n const MAX_DEPTH = 3;\n type OntologyDef = {\n ontologyKey: string;\n parentOntologyId?: Id<\"ontologyDefinitions\">;\n };\n type OntologyVer = {\n status: string;\n publishedAt?: number;\n entityTypes: unknown;\n edgeTypes: unknown;\n };\n const chain: Array<{ def: OntologyDef; version: OntologyVer | null }> = [];\n\n // Walk parent chain\n let currentId: Id<\"ontologyDefinitions\"> | undefined = args.ontologyId;\n for (let depth = 0; depth < MAX_DEPTH && currentId; depth++) {\n const ontologyId = currentId;\n const def = await ctx.db.get(ontologyId);\n if (!def) {\n break;\n }\n const defTyped = def as unknown as OntologyDef & {\n _id: Id<\"ontologyDefinitions\">;\n };\n\n // Get latest published version\n const versions = (await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyId\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyId\", ontologyId)\n )\n .collect()) as OntologyVer[];\n const published = versions\n .filter((ver: OntologyVer) => ver.status === \"published\")\n .sort(\n (a: OntologyVer, b: OntologyVer) =>\n ((b.publishedAt as number) ?? 0) - ((a.publishedAt as number) ?? 0)\n );\n\n chain.unshift({\n def: defTyped,\n version: (published[0] as OntologyVer) ?? null,\n });\n currentId = defTyped.parentOntologyId;\n }\n\n if (chain.length === 0) {\n return null;\n }\n\n // Merge layers from root (platform) to leaf (tenant)\n let merged: MergedOntology = {\n entityTypes: [],\n edgeTypes: [],\n layers: [],\n };\n\n for (const { def, version } of chain) {\n if (!version) {\n merged.layers.push(def.ontologyKey);\n continue;\n }\n const previousLayerKey = merged.layers.at(-1) ?? def.ontologyKey;\n merged = mergeOntologyLayers(\n merged,\n {\n entityTypes: version.entityTypes as EntityTypeEntry[],\n edgeTypes: version.edgeTypes as EdgeTypeEntry[],\n },\n previousLayerKey,\n def.ontologyKey\n );\n }\n\n return merged;\n },\n});\n\n// =============================================================================\n// MUTATIONS\n// =============================================================================\n\n/**\n * Create a new ontology definition.\n */\nexport const createOntologyDefinition = mutation({\n args: {\n ontologyKey: v.string(),\n name: v.string(),\n description: v.optional(v.string()),\n tenantId: v.optional(v.string()),\n tier: v.union(\n v.literal(\"platform\"),\n v.literal(\"pack\"),\n v.literal(\"tenant\")\n ),\n parentOntologyId: v.optional(v.id(\"ontologyDefinitions\")),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: MutationCtx,\n args: {\n ontologyKey: string;\n name: string;\n description?: string;\n tenantId?: string;\n tier: \"platform\" | \"pack\" | \"tenant\";\n parentOntologyId?: Id<\"ontologyDefinitions\">;\n }\n ) => {\n const userId = await requireAuth(ctx);\n\n // Validate ontology key\n const keyResult = validateOntologyKey(args.ontologyKey);\n if (!keyResult.valid) {\n throw new Error(keyResult.error ?? \"Invalid ontology key\");\n }\n\n // Check uniqueness within tenant scope\n const existing = await ctx.db\n .query(\"ontologyDefinitions\")\n .withIndex(\"by_tenant_ontologyKey\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"ontologyKey\", keyResult.normalized)\n )\n .first();\n\n if (existing) {\n throw new Error(\n `Ontology \"${keyResult.normalized}\" already exists for tenant ${args.tenantId ?? \"(platform)\"}.`\n );\n }\n\n // Validate parent exists if specified\n if (args.parentOntologyId) {\n const parent = await ctx.db.get(args.parentOntologyId);\n if (!parent) {\n throw new Error(\"Parent ontology definition not found.\");\n }\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"ontologyDefinitions\", {\n ontologyKey: keyResult.normalized,\n name: args.name,\n description: args.description,\n tenantId: args.tenantId,\n tier: args.tier,\n parentOntologyId: args.parentOntologyId,\n status: \"draft\",\n createdBy: userId,\n createdAt: now,\n updatedAt: now,\n });\n\n await logAudit(ctx, {\n entityType: \"ontologyDefinition\",\n entityId: id,\n changeType: \"created\",\n changedBy: userId,\n previousState: null,\n newState: {\n ontologyKey: keyResult.normalized,\n name: args.name,\n tier: args.tier,\n },\n });\n\n return { id, ontologyKey: keyResult.normalized };\n },\n});\n\n/**\n * Update an ontology definition (name, description, status).\n * Only allowed while draft or active.\n */\nexport const updateOntologyDefinition = mutation({\n args: {\n id: v.id(\"ontologyDefinitions\"),\n name: v.optional(v.string()),\n description: v.optional(v.string()),\n status: v.optional(\n v.union(v.literal(\"draft\"), v.literal(\"active\"), v.literal(\"deprecated\"))\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: MutationCtx,\n args: {\n id: Id<\"ontologyDefinitions\">;\n name?: string;\n description?: string;\n status?: Exclude<OntologyDefinitionStatus, \"archived\">;\n }\n ) => {\n const userId = await requireAuth(ctx);\n\n const def = (await ctx.db.get(args.id)) as OntologyDefinitionDoc | null;\n if (!def) {\n throw new Error(\"Ontology definition not found.\");\n }\n\n if (def.status === \"archived\") {\n throw new Error(\"Cannot update an archived ontology definition.\");\n }\n\n const previousState = {\n name: def.name,\n description: def.description,\n status: def.status,\n };\n\n const patch: Record<string, unknown> = { updatedAt: Date.now() };\n if (args.name !== undefined) {\n patch.name = args.name;\n }\n if (args.description !== undefined) {\n patch.description = args.description;\n }\n if (args.status !== undefined) {\n patch.status = args.status;\n }\n\n await ctx.db.patch(args.id, patch);\n\n await logAudit(ctx, {\n entityType: \"ontologyDefinition\",\n entityId: args.id,\n changeType: \"updated\",\n changedBy: userId,\n previousState,\n newState: patch,\n });\n\n return { success: true };\n },\n});\n\n/**\n * Archive an ontology definition.\n */\nexport const archiveOntologyDefinition = mutation({\n args: { id: v.id(\"ontologyDefinitions\") },\n returns: permissiveReturn,\n handler: async (\n ctx: MutationCtx,\n args: { id: Id<\"ontologyDefinitions\"> }\n ) => {\n const userId = await requireAuth(ctx);\n\n const def = (await ctx.db.get(args.id)) as OntologyDefinitionDoc | null;\n if (!def) {\n throw new Error(\"Ontology definition not found.\");\n }\n\n if (def.status === \"archived\") {\n return { success: true };\n }\n\n await ctx.db.patch(args.id, { status: \"archived\", updatedAt: Date.now() });\n\n await logAudit(ctx, {\n entityType: \"ontologyDefinition\",\n entityId: args.id,\n changeType: \"archived\",\n changedBy: userId,\n previousState: { status: def.status },\n newState: { status: \"archived\" },\n });\n\n return { success: true };\n },\n});\n\n/**\n * Create a new version snapshot for an ontology.\n */\nexport const createOntologyVersion = mutation({\n args: {\n ontologyId: v.id(\"ontologyDefinitions\"),\n version: v.string(),\n entityTypes: v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.optional(v.any()),\n subtypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n })\n )\n ),\n })\n ),\n edgeTypes: v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n sourceTypes: v.optional(v.array(v.string())),\n targetTypes: v.optional(v.array(v.string())),\n constraintSeverity: v.optional(\n v.union(v.literal(\"warn\"), v.literal(\"info\"))\n ),\n })\n ),\n releaseNotes: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: CreateOntologyVersionArgs) => {\n const userId = await requireAuth(ctx);\n\n // Validate version string\n if (!validateVersionString(args.version)) {\n throw new Error(\n `Invalid version string \"${args.version}\". Must be in X.Y.Z format.`\n );\n }\n\n // Validate parent definition exists\n const def = (await ctx.db.get(\n args.ontologyId\n )) as OntologyDefinitionDoc | null;\n if (!def) {\n throw new Error(\"Ontology definition not found.\");\n }\n\n if (def.status === \"archived\") {\n throw new Error(\"Cannot add versions to an archived ontology.\");\n }\n\n // Check version uniqueness\n const existing = await ctx.db\n .query(\"ontologyVersions\")\n .withIndex(\"by_ontologyKey_version\", (q: IndexRangeBuilder) =>\n q.eq(\"ontologyKey\", def.ontologyKey).eq(\"version\", args.version)\n )\n .first();\n\n if (existing) {\n throw new Error(\n `Version \"${args.version}\" already exists for ontology \"${def.ontologyKey}\".`\n );\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"ontologyVersions\", {\n ontologyId: args.ontologyId,\n ontologyKey: def.ontologyKey,\n version: args.version,\n status: \"draft\",\n entityTypes: args.entityTypes,\n edgeTypes: args.edgeTypes,\n releaseNotes: args.releaseNotes,\n createdAt: now,\n });\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: id,\n changeType: \"created\",\n changedBy: userId,\n previousState: null,\n newState: {\n ontologyKey: def.ontologyKey,\n version: args.version,\n entityTypeCount: args.entityTypes.length,\n edgeTypeCount: args.edgeTypes.length,\n },\n });\n\n return { id, version: args.version };\n },\n});\n\n/**\n * Update a draft version (entityTypes, edgeTypes, releaseNotes).\n * Only allowed while version is in \"draft\" status.\n */\nexport const updateDraftVersion = mutation({\n args: {\n id: v.id(\"ontologyVersions\"),\n entityTypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.optional(v.any()),\n subtypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n })\n )\n ),\n })\n )\n ),\n edgeTypes: v.optional(\n v.array(\n v.object({\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n sourceTypes: v.optional(v.array(v.string())),\n targetTypes: v.optional(v.array(v.string())),\n constraintSeverity: v.optional(\n v.union(v.literal(\"warn\"), v.literal(\"info\"))\n ),\n })\n )\n ),\n releaseNotes: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: UpdateDraftVersionArgs) => {\n const userId = await requireAuth(ctx);\n\n const ver = (await ctx.db.get(args.id)) as OntologyVersionDoc | null;\n if (!ver) {\n throw new Error(\"Ontology version not found.\");\n }\n\n if (ver.status !== \"draft\") {\n throw new Error(\n `Cannot update a ${ver.status} version. Only draft versions are editable.`\n );\n }\n\n const patch: Record<string, unknown> = {};\n if (args.entityTypes !== undefined) {\n patch.entityTypes = args.entityTypes;\n }\n if (args.edgeTypes !== undefined) {\n patch.edgeTypes = args.edgeTypes;\n }\n if (args.releaseNotes !== undefined) {\n patch.releaseNotes = args.releaseNotes;\n }\n\n await ctx.db.patch(args.id, patch);\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: args.id,\n changeType: \"updated\",\n changedBy: userId,\n previousState: { status: ver.status },\n newState: patch,\n });\n\n return { success: true };\n },\n});\n\n/**\n * Publish a version — freezes it (status → \"published\").\n * If the parent definition is \"draft\", promotes it to \"active\".\n */\nexport const publishOntologyVersion = mutation({\n args: {\n id: v.id(\"ontologyVersions\"),\n ontologyId: v.optional(v.id(\"ontologyDefinitions\")),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: VersionStatusMutationArgs) => {\n const userId = await requireAuth(ctx);\n\n const ver = (await ctx.db.get(args.id)) as OntologyVersionDoc | null;\n if (!ver) {\n throw new Error(\"Ontology version not found.\");\n }\n\n // Verify ownership if ontologyId provided\n if (args.ontologyId && ver.ontologyId !== args.ontologyId) {\n throw new Error(\n \"Version does not belong to the specified ontology definition.\"\n );\n }\n\n if (ver.status !== \"draft\") {\n throw new Error(\n `Cannot publish a ${ver.status} version. Only draft versions can be published.`\n );\n }\n\n const now = Date.now();\n await ctx.db.patch(args.id, {\n status: \"published\",\n publishedBy: userId,\n publishedAt: now,\n });\n\n // Promote parent definition to \"active\" if still in \"draft\"\n const def = (await ctx.db.get(ver.ontologyId)) as\n | OntologyDefinitionDoc\n | null;\n if (def && def.status === \"draft\") {\n await ctx.db.patch(ver.ontologyId, {\n status: \"active\",\n updatedAt: now,\n });\n }\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: args.id,\n changeType: \"published\",\n changedBy: userId,\n previousState: { status: \"draft\" },\n newState: { status: \"published\", publishedAt: now },\n });\n\n return { success: true, publishedAt: now };\n },\n});\n\n/**\n * Deprecate a published version.\n */\nexport const deprecateOntologyVersion = mutation({\n args: {\n id: v.id(\"ontologyVersions\"),\n ontologyId: v.optional(v.id(\"ontologyDefinitions\")),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: VersionStatusMutationArgs) => {\n const userId = await requireAuth(ctx);\n\n const ver = (await ctx.db.get(args.id)) as OntologyVersionDoc | null;\n if (!ver) {\n throw new Error(\"Ontology version not found.\");\n }\n\n // Verify ownership if ontologyId provided\n if (args.ontologyId && ver.ontologyId !== args.ontologyId) {\n throw new Error(\n \"Version does not belong to the specified ontology definition.\"\n );\n }\n\n if (ver.status === \"deprecated\") {\n return { success: true };\n }\n\n if (ver.status !== \"published\") {\n throw new Error(\n `Cannot deprecate a ${ver.status} version. Only published versions can be deprecated.`\n );\n }\n\n await ctx.db.patch(args.id, { status: \"deprecated\" });\n\n await logAudit(ctx, {\n entityType: \"ontologyVersion\",\n entityId: args.id,\n changeType: \"deprecated\",\n changedBy: userId,\n previousState: { status: \"published\" },\n newState: { status: \"deprecated\" },\n });\n\n return { success: true };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/convex.ts","../src/ontologyRegistry.ts"],"names":[],"mappings":"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","file":"ontologyRegistry.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * Ontology Registry\n *\n * Seeds schemaEnumConfig with platform-default entity types, subtypes,\n * and entity edge types. Provides tenant extension API.\n *\n * Categories:\n * - entity_type: Company, Person, Investor, Function, ValueChain\n * - entity_subtype: company/private, investor/vc, etc.\n * - entity_edge_type: works_at, invested_in, etc.\n *\n * @module graph-primitives/ontologyRegistry\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport type { MutationCtx } from \"./convex\";\nimport { internalMutation, mutation } from \"./convex\";\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY TYPES\n// =============================================================================\n\ntype FieldSchema = {\n type: \"string\" | \"number\" | \"boolean\";\n required: boolean;\n};\n\ntype EntityTypeDefinition = {\n value: string;\n label: string;\n description: string;\n schema: Record<string, FieldSchema>;\n};\n\nconst PLATFORM_ENTITY_TYPES: EntityTypeDefinition[] = [\n {\n value: \"company\",\n label: \"Company\",\n description: \"A business entity — startup, portfolio company, or corporate\",\n schema: {\n name: { type: \"string\", required: true },\n sector: { type: \"string\", required: false },\n founded_year: { type: \"number\", required: false },\n website: { type: \"string\", required: false },\n domain: { type: \"string\", required: false },\n },\n },\n {\n value: \"person\",\n label: \"Person\",\n description: \"An individual — founder, executive, or contact\",\n schema: {\n name: { type: \"string\", required: true },\n role: { type: \"string\", required: false },\n affiliation: { type: \"string\", required: false },\n linkedin: { type: \"string\", required: false },\n },\n },\n {\n value: \"investor\",\n label: \"Investor\",\n description: \"An investment entity — fund, GP, or angel\",\n schema: {\n name: { type: \"string\", required: true },\n fund_name: { type: \"string\", required: false },\n investment_focus: { type: \"string\", required: false },\n aum: { type: \"number\", required: false },\n },\n },\n {\n value: \"function\",\n label: \"Function\",\n description: \"A business function in a value chain\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n {\n value: \"value_chain\",\n label: \"Value Chain\",\n description: \"A value chain or industry vertical\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY SUBTYPES\n// =============================================================================\n\ntype SubtypeDefinition = {\n value: string;\n label: string;\n parentType: string;\n};\n\nconst PLATFORM_ENTITY_SUBTYPES: SubtypeDefinition[] = [\n // Company subtypes\n { value: \"company/private\", label: \"Private Company\", parentType: \"company\" },\n { value: \"company/corporate\", label: \"Corporate\", parentType: \"company\" },\n {\n value: \"company/portfolio\",\n label: \"Portfolio Company\",\n parentType: \"company\",\n },\n // Investor subtypes\n { value: \"investor/vc\", label: \"Venture Capital\", parentType: \"investor\" },\n { value: \"investor/lp\", label: \"Limited Partner\", parentType: \"investor\" },\n { value: \"investor/cvc\", label: \"Corporate VC\", parentType: \"investor\" },\n { value: \"investor/pe\", label: \"Private Equity\", parentType: \"investor\" },\n {\n value: \"investor/family_office\",\n label: \"Family Office\",\n parentType: \"investor\",\n },\n { value: \"investor/angel\", label: \"Angel Investor\", parentType: \"investor\" },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY EDGE TYPES\n// =============================================================================\n\ntype EntityEdgeTypeDefinition = {\n value: string;\n label: string;\n description: string;\n};\ntype IndexRangeBuilder = {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype EnumConfigRow = {\n _id: string;\n value: string;\n};\ntype RegisterEntityTypeArgs = {\n tenantId: string;\n value: string;\n label: string;\n description?: string;\n schema: unknown;\n domainNamespace?: string;\n};\n\nconst PLATFORM_ENTITY_EDGE_TYPES: EntityEdgeTypeDefinition[] = [\n {\n value: \"works_at\",\n label: \"Works At\",\n description: \"Person → Company/Investor employment\",\n },\n {\n value: \"performs\",\n label: \"Performs\",\n description: \"Company → Function capability\",\n },\n {\n value: \"invested_in\",\n label: \"Invested In\",\n description: \"Investor → Company investment\",\n },\n {\n value: \"founded_by\",\n label: \"Founded By\",\n description: \"Company → Person founding\",\n },\n {\n value: \"participates_in\",\n label: \"Participates In\",\n description: \"Company → ValueChain participation\",\n },\n {\n value: \"function_in\",\n label: \"Function In\",\n description: \"Function → ValueChain membership\",\n },\n {\n value: \"impacts\",\n label: \"Impacts\",\n description: \"Theme → ValueChain impact\",\n },\n {\n value: \"mentioned_in\",\n label: \"Mentioned In\",\n description: \"Entity → Source reference\",\n },\n {\n value: \"competes_with\",\n label: \"Competes With\",\n description: \"Company → Company competition\",\n },\n {\n value: \"depends_on\",\n label: \"Depends On\",\n description: \"Entity → Entity dependency\",\n },\n {\n value: \"contains\",\n label: \"Contains\",\n description: \"Containment: ValueChain → Function, Belief/Question/Theme → Entity, Entity → Evidence\",\n },\n {\n value: \"raised_from\",\n label: \"Raised From\",\n description: \"Company → Investor fundraising\",\n },\n {\n value: \"derived_from\",\n label: \"Derived From\",\n description: \"Entity → Entity deduplication merge link (replaces same_as)\",\n },\n];\n\n// =============================================================================\n// SEED MUTATION (idempotent)\n// =============================================================================\n\nasync function upsertEnumEntry(\n ctx: MutationCtx,\n entry: {\n category: string;\n value: string;\n label: string;\n description?: string;\n tier: \"platform\" | \"tenant\";\n metadata?: Record<string, unknown>;\n sortOrder?: number;\n }\n): Promise<{ inserted: boolean }> {\n const existing = await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_category_value\", (q: IndexRangeBuilder) =>\n q.eq(\"category\", entry.category).eq(\"value\", entry.value)\n )\n .first();\n\n if (existing) {\n return { inserted: false };\n }\n\n const now = Date.now();\n await ctx.db.insert(\"schemaEnumConfig\", {\n category: entry.category,\n value: entry.value,\n label: entry.label,\n description: entry.description,\n tier: entry.tier,\n metadata: entry.metadata,\n sortOrder: entry.sortOrder,\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { inserted: true };\n}\n\n/**\n * Seed the ontology registry with platform-default entity types.\n * Idempotent — safe to call multiple times.\n */\nexport const seedOntologyRegistry = internalMutation({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx) => {\n let inserted = 0;\n let skipped = 0;\n\n // Seed entity types\n for (let i = 0; i < PLATFORM_ENTITY_TYPES.length; i++) {\n const entityType = PLATFORM_ENTITY_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_type\",\n value: entityType.value,\n label: entityType.label,\n description: entityType.description,\n tier: \"platform\",\n metadata: { schema: entityType.schema },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity subtypes\n for (let i = 0; i < PLATFORM_ENTITY_SUBTYPES.length; i++) {\n const subtype = PLATFORM_ENTITY_SUBTYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_subtype\",\n value: subtype.value,\n label: subtype.label,\n tier: \"platform\",\n metadata: { parentType: subtype.parentType },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity edge types\n for (let i = 0; i < PLATFORM_ENTITY_EDGE_TYPES.length; i++) {\n const edgeType = PLATFORM_ENTITY_EDGE_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_edge_type\",\n value: edgeType.value,\n label: edgeType.label,\n description: edgeType.description,\n tier: \"platform\",\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n return { inserted, skipped, total: inserted + skipped };\n },\n});\n\n// =============================================================================\n// TENANT EXTENSION API\n// =============================================================================\n\n/**\n * Register a new entity type for a tenant.\n * Creates a schemaEnumConfig entry with tier='tenant'.\n */\nexport const registerEntityType = mutation({\n args: {\n tenantId: v.string(),\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.any(), // Record<string, { type, required }>\n domainNamespace: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: RegisterEntityTypeArgs) => {\n // Auth guard — tenant mutations require authenticated user\n const userId = await getCurrentUserId(ctx);\n if (!userId) {\n throw new Error(\"Authentication required to register entity types.\");\n }\n\n // Check for existing entry with same value\n const existing = (await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_tenant_category\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"category\", \"entity_type\")\n )\n .collect()) as EnumConfigRow[];\n\n const duplicate = existing.find((e: EnumConfigRow) => e.value === args.value);\n if (duplicate) {\n throw new Error(\n `Entity type \"${args.value}\" already registered for tenant ${args.tenantId}`\n );\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"schemaEnumConfig\", {\n tenantId: args.tenantId,\n category: \"entity_type\",\n value: args.value,\n label: args.label,\n description: args.description,\n tier: \"tenant\" as const,\n domainNamespace: args.domainNamespace,\n metadata: { schema: args.schema },\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { id, value: args.value };\n },\n});\n"]}
1
+ {"version":3,"sources":["../src/convex.ts","../src/ontologyRegistry.ts"],"names":[],"mappings":"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","file":"ontologyRegistry.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * Ontology Registry\n *\n * Seeds schemaEnumConfig with platform-default entity types, subtypes,\n * and entity edge types. Provides tenant extension API.\n *\n * Categories:\n * - entity_type: Company, Person, Investor, Function, ValueChain\n * - entity_subtype: company/private, investor/vc, etc.\n * - entity_edge_type: works_at, invested_in, etc.\n *\n * @module graph-primitives/ontologyRegistry\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport type { MutationCtx } from \"./convex\";\nimport { internalMutation, mutation } from \"./convex\";\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY TYPES\n// =============================================================================\n\ntype FieldSchema = {\n type: \"string\" | \"number\" | \"boolean\";\n required: boolean;\n};\n\ntype EntityTypeDefinition = {\n value: string;\n label: string;\n description: string;\n schema: Record<string, FieldSchema>;\n};\n\nconst PLATFORM_ENTITY_TYPES: EntityTypeDefinition[] = [\n {\n value: \"company\",\n label: \"Company\",\n description: \"A business entity — startup, portfolio company, or corporate\",\n schema: {\n name: { type: \"string\", required: true },\n sector: { type: \"string\", required: false },\n founded_year: { type: \"number\", required: false },\n website: { type: \"string\", required: false },\n domain: { type: \"string\", required: false },\n },\n },\n {\n value: \"person\",\n label: \"Person\",\n description: \"An individual — founder, executive, or contact\",\n schema: {\n name: { type: \"string\", required: true },\n role: { type: \"string\", required: false },\n affiliation: { type: \"string\", required: false },\n linkedin: { type: \"string\", required: false },\n },\n },\n {\n value: \"investor\",\n label: \"Investor\",\n description: \"An investment entity — fund, GP, or angel\",\n schema: {\n name: { type: \"string\", required: true },\n fund_name: { type: \"string\", required: false },\n investment_focus: { type: \"string\", required: false },\n aum: { type: \"number\", required: false },\n },\n },\n {\n value: \"function\",\n label: \"Function\",\n description: \"A business function in a value chain\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n {\n value: \"value_chain\",\n label: \"Value Chain\",\n description: \"A value chain or industry vertical\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY SUBTYPES\n// =============================================================================\n\ntype SubtypeDefinition = {\n value: string;\n label: string;\n parentType: string;\n};\n\nconst PLATFORM_ENTITY_SUBTYPES: SubtypeDefinition[] = [\n // Company subtypes\n { value: \"company/private\", label: \"Private Company\", parentType: \"company\" },\n { value: \"company/corporate\", label: \"Corporate\", parentType: \"company\" },\n {\n value: \"company/portfolio\",\n label: \"Portfolio Company\",\n parentType: \"company\",\n },\n // Investor subtypes\n { value: \"investor/vc\", label: \"Venture Capital\", parentType: \"investor\" },\n { value: \"investor/lp\", label: \"Limited Partner\", parentType: \"investor\" },\n { value: \"investor/cvc\", label: \"Corporate VC\", parentType: \"investor\" },\n { value: \"investor/pe\", label: \"Private Equity\", parentType: \"investor\" },\n {\n value: \"investor/family_office\",\n label: \"Family Office\",\n parentType: \"investor\",\n },\n { value: \"investor/angel\", label: \"Angel Investor\", parentType: \"investor\" },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY EDGE TYPES\n// =============================================================================\n\ntype EntityEdgeTypeDefinition = {\n value: string;\n label: string;\n description: string;\n};\ntype IndexRangeBuilder = {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype EnumConfigRow = {\n _id: string;\n value: string;\n};\ntype RegisterEntityTypeArgs = {\n tenantId: string;\n value: string;\n label: string;\n description?: string;\n schema: unknown;\n domainNamespace?: string;\n};\n\nconst PLATFORM_ENTITY_EDGE_TYPES: EntityEdgeTypeDefinition[] = [\n {\n value: \"works_at\",\n label: \"Works At\",\n description: \"Person → Company/Investor employment\",\n },\n {\n value: \"performs\",\n label: \"Performs\",\n description: \"Company → Function capability\",\n },\n {\n value: \"invested_in\",\n label: \"Invested In\",\n description: \"Investor → Company investment\",\n },\n {\n value: \"founded_by\",\n label: \"Founded By\",\n description: \"Company → Person founding\",\n },\n {\n value: \"participates_in\",\n label: \"Participates In\",\n description: \"Company → ValueChain participation\",\n },\n {\n value: \"function_in\",\n label: \"Function In\",\n description: \"Function → ValueChain membership\",\n },\n {\n value: \"impacts\",\n label: \"Impacts\",\n description: \"Theme → ValueChain impact\",\n },\n {\n value: \"mentioned_in\",\n label: \"Mentioned In\",\n description: \"Entity → Source reference\",\n },\n {\n value: \"competes_with\",\n label: \"Competes With\",\n description: \"Company → Company competition\",\n },\n {\n value: \"depends_on\",\n label: \"Depends On\",\n description: \"Entity → Entity dependency\",\n },\n {\n value: \"contains\",\n label: \"Contains\",\n description: \"Containment: ValueChain → Function, Belief/Question/Theme → Entity, Entity → Evidence\",\n },\n {\n value: \"raised_from\",\n label: \"Raised From\",\n description: \"Company → Investor fundraising\",\n },\n {\n value: \"derived_from\",\n label: \"Derived From\",\n description: \"Entity → Entity deduplication merge link (replaces same_as)\",\n },\n];\n\n// =============================================================================\n// SEED MUTATION (idempotent)\n// =============================================================================\n\nasync function upsertEnumEntry(\n ctx: MutationCtx,\n entry: {\n category: string;\n value: string;\n label: string;\n description?: string;\n tier: \"platform\" | \"tenant\";\n metadata?: Record<string, unknown>;\n sortOrder?: number;\n }\n): Promise<{ inserted: boolean }> {\n const existing = await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_category_value\", (q: IndexRangeBuilder) =>\n q.eq(\"category\", entry.category).eq(\"value\", entry.value)\n )\n .first();\n\n if (existing) {\n return { inserted: false };\n }\n\n const now = Date.now();\n await ctx.db.insert(\"schemaEnumConfig\", {\n category: entry.category,\n value: entry.value,\n label: entry.label,\n description: entry.description,\n tier: entry.tier,\n metadata: entry.metadata,\n sortOrder: entry.sortOrder,\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { inserted: true };\n}\n\n/**\n * Seed the ontology registry with platform-default entity types.\n * Idempotent — safe to call multiple times.\n */\nexport const seedOntologyRegistry = internalMutation({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx) => {\n let inserted = 0;\n let skipped = 0;\n\n // Seed entity types\n for (let i = 0; i < PLATFORM_ENTITY_TYPES.length; i++) {\n const entityType = PLATFORM_ENTITY_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_type\",\n value: entityType.value,\n label: entityType.label,\n description: entityType.description,\n tier: \"platform\",\n metadata: { schema: entityType.schema },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity subtypes\n for (let i = 0; i < PLATFORM_ENTITY_SUBTYPES.length; i++) {\n const subtype = PLATFORM_ENTITY_SUBTYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_subtype\",\n value: subtype.value,\n label: subtype.label,\n tier: \"platform\",\n metadata: { parentType: subtype.parentType },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity edge types\n for (let i = 0; i < PLATFORM_ENTITY_EDGE_TYPES.length; i++) {\n const edgeType = PLATFORM_ENTITY_EDGE_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_edge_type\",\n value: edgeType.value,\n label: edgeType.label,\n description: edgeType.description,\n tier: \"platform\",\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n return { inserted, skipped, total: inserted + skipped };\n },\n});\n\n// =============================================================================\n// TENANT EXTENSION API\n// =============================================================================\n\n/**\n * Register a new entity type for a tenant.\n * Creates a schemaEnumConfig entry with tier='tenant'.\n */\nexport const registerEntityType = mutation({\n args: {\n tenantId: v.string(),\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.any(), // Record<string, { type, required }>\n domainNamespace: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: RegisterEntityTypeArgs) => {\n // Auth guard — tenant mutations require authenticated user\n const userId = await getCurrentUserId(ctx);\n if (!userId) {\n throw new Error(\"Authentication required to register entity types.\");\n }\n\n // Check for existing entry with same value\n const existing = (await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_tenant_category\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"category\", \"entity_type\")\n )\n .collect()) as EnumConfigRow[];\n\n const duplicate = existing.find((e: EnumConfigRow) => e.value === args.value);\n if (duplicate) {\n throw new Error(\n `Entity type \"${args.value}\" already registered for tenant ${args.tenantId}`\n );\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"schemaEnumConfig\", {\n tenantId: args.tenantId,\n category: \"entity_type\",\n value: args.value,\n label: args.label,\n description: args.description,\n tier: \"tenant\" as const,\n domainNamespace: args.domainNamespace,\n metadata: { schema: args.schema },\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { id, value: args.value };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/convex.ts","../src/projectionStaleness.ts","../src/projectionReconciliation.ts"],"names":[],"mappings":"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","file":"projectionReconciliation.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * projectionStaleness module implementation.\n */\n\nexport type ProjectionEndpointClass =\n | \"analytics\"\n | \"traversal\"\n | \"entity_read\"\n | \"non_graph\";\n\nexport type ProjectionFallbackMode =\n | \"fail_with_503\"\n | \"degrade_to_convex_depth_limited\"\n | \"fallback_to_convex_entity_read\"\n | \"none\";\n\nexport type ProjectionStalenessPolicy = {\n endpointClass: ProjectionEndpointClass;\n thresholdMs: number;\n fallbackMode: ProjectionFallbackMode;\n nonOverridable: true;\n};\n\nexport type ProjectionStalenessInput = {\n endpointClass: ProjectionEndpointClass;\n queueBacklogAgeMs: number;\n queuePendingCount: number;\n queueFailedCount: number;\n nowMs?: number;\n lastSuccessfulSyncAt?: number;\n};\n\nexport type ProjectionStalenessEnvelope = {\n endpointClass: ProjectionEndpointClass;\n stalenessMs: number;\n thresholdMs: number;\n isStale: boolean;\n fallbackMode: ProjectionFallbackMode;\n queuePendingCount: number;\n queueFailedCount: number;\n evaluatedAt: number;\n lastSuccessfulSyncAt?: number;\n lastSuccessfulSyncAgeMs?: number;\n reasonCode:\n | \"PROJECTION_HEALTHY\"\n | \"PROJECTION_STALE\"\n | \"PROJECTION_STALE_WITH_FAILED_RETRIES\";\n};\n\nexport const PROJECTION_STALENESS_POLICIES: Record<\n ProjectionEndpointClass,\n ProjectionStalenessPolicy\n> = {\n analytics: {\n endpointClass: \"analytics\",\n thresholdMs: 30_000,\n fallbackMode: \"fail_with_503\",\n nonOverridable: true,\n },\n traversal: {\n endpointClass: \"traversal\",\n thresholdMs: 60_000,\n fallbackMode: \"degrade_to_convex_depth_limited\",\n nonOverridable: true,\n },\n entity_read: {\n endpointClass: \"entity_read\",\n thresholdMs: 5 * 60_000,\n fallbackMode: \"fallback_to_convex_entity_read\",\n nonOverridable: true,\n },\n non_graph: {\n endpointClass: \"non_graph\",\n thresholdMs: Number.POSITIVE_INFINITY,\n fallbackMode: \"none\",\n nonOverridable: true,\n },\n};\n\nexport function getProjectionStalenessPolicy(\n endpointClass: ProjectionEndpointClass\n): ProjectionStalenessPolicy {\n return PROJECTION_STALENESS_POLICIES[endpointClass];\n}\n\nexport function evaluateProjectionStaleness(\n input: ProjectionStalenessInput\n): ProjectionStalenessEnvelope {\n const policy = getProjectionStalenessPolicy(input.endpointClass);\n const evaluatedAt = input.nowMs ?? Date.now();\n const stalenessMs = Math.max(0, input.queueBacklogAgeMs);\n const isStale = stalenessMs > policy.thresholdMs;\n const lastSuccessfulSyncAgeMs =\n input.lastSuccessfulSyncAt !== undefined\n ? Math.max(0, evaluatedAt - input.lastSuccessfulSyncAt)\n : undefined;\n\n return {\n endpointClass: input.endpointClass,\n stalenessMs,\n thresholdMs: policy.thresholdMs,\n isStale,\n fallbackMode: policy.fallbackMode,\n queuePendingCount: input.queuePendingCount,\n queueFailedCount: input.queueFailedCount,\n evaluatedAt,\n lastSuccessfulSyncAt: input.lastSuccessfulSyncAt,\n lastSuccessfulSyncAgeMs,\n reasonCode: isStale\n ? input.queueFailedCount > 0\n ? \"PROJECTION_STALE_WITH_FAILED_RETRIES\"\n : \"PROJECTION_STALE\"\n : \"PROJECTION_HEALTHY\",\n };\n}\n\nexport function shouldFailClosedForProjection(\n envelope: ProjectionStalenessEnvelope\n): boolean {\n return envelope.isStale && envelope.fallbackMode === \"fail_with_503\";\n}\n","/**\n * Projection Reconciliation Runtime\n *\n * Phase 2 (WT-C) runtime hooks for Convex-authoritative / Neo4j-projected\n * reconciliation health and endpoint-class staleness evaluation.\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport { internal, internalAction, internalQuery, query } from \"./convex\";\nimport type { ActionCtx, QueryCtx } from \"./convex\";\nimport {\n evaluateProjectionStaleness,\n type ProjectionEndpointClass,\n} from \"./projectionStaleness\";\ntype QueueStatus = \"pending\" | \"in_progress\" | \"failed\" | \"succeeded\";\n\ntype QueueRow = {\n status: QueueStatus;\n createdAt: number;\n updatedAt: number;\n};\n\ntype IndexQueryBuilder = {\n eq(field: string, value: unknown): IndexQueryBuilder;\n};\n\nfunction maxTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let maxValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (maxValue === undefined || value > maxValue) {\n maxValue = value;\n }\n }\n return maxValue;\n}\n\nfunction minTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let minValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (minValue === undefined || value < minValue) {\n minValue = value;\n }\n }\n return minValue;\n}\n\nasync function getQueueSnapshot(ctx: QueryCtx) {\n const [pendingRows, inProgressRows, failedRows, succeededRows] =\n await Promise.all([\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"pending\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"in_progress\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"failed\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"succeeded\"))\n .collect() as Promise<QueueRow[]>,\n ]);\n\n const now = Date.now();\n const backlogOldestCreatedAt = minTimestamp(\n [...pendingRows, ...inProgressRows],\n \"createdAt\"\n );\n const queueBacklogAgeMs =\n backlogOldestCreatedAt !== undefined\n ? Math.max(0, now - backlogOldestCreatedAt)\n : 0;\n const lastSuccessfulSyncAt = maxTimestamp(succeededRows, \"updatedAt\");\n\n return {\n now,\n queuePendingCount: pendingRows.length,\n queueInProgressCount: inProgressRows.length,\n queueFailedCount: failedRows.length,\n queueSucceededCount: succeededRows.length,\n queueBacklogAgeMs,\n backlogOldestCreatedAt,\n lastSuccessfulSyncAt,\n };\n}\n\nfunction buildEndpointAssessments(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n const analytics = evaluateProjectionStaleness({\n endpointClass: \"analytics\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const traversal = evaluateProjectionStaleness({\n endpointClass: \"traversal\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const entityRead = evaluateProjectionStaleness({\n endpointClass: \"entity_read\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const nonGraph = evaluateProjectionStaleness({\n endpointClass: \"non_graph\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n\n return {\n analytics,\n traversal,\n entityRead,\n nonGraph,\n };\n}\n\nfunction buildProjectionReconciliationStatus(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n return {\n ...snapshot,\n endpointAssessments: buildEndpointAssessments(snapshot),\n generatedAt: snapshot.now,\n };\n}\n\nfunction assertAuthenticated(clerkId: string | null): string {\n if (!clerkId) {\n throw new Error(\"Authentication required\");\n }\n return clerkId;\n}\n\nexport const getProjectionReconciliationStatusInternal = internalQuery({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const getProjectionReconciliationStatus = query({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const assessProjectionStaleness = query({\n args: {\n endpointClass: v.union(\n v.literal(\"analytics\"),\n v.literal(\"traversal\"),\n v.literal(\"entity_read\"),\n v.literal(\"non_graph\")\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { endpointClass: ProjectionEndpointClass }\n ) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n const endpointClass = args.endpointClass as ProjectionEndpointClass;\n\n return {\n endpointClass,\n assessment: evaluateProjectionStaleness({\n endpointClass,\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n }),\n snapshot,\n };\n },\n});\n\nexport const runProjectionRepairCycle = internalAction({\n args: {\n limit: v.optional(v.number()),\n },\n returns: permissiveReturn,\n handler: async (ctx: ActionCtx, args: { limit?: number }) => {\n const processed = await ctx.runAction(\n internal.neo4jSync.processRetryQueue,\n {\n limit: args.limit ?? 25,\n }\n );\n const status = await ctx.runQuery(\n internal.projectionReconciliation\n .getProjectionReconciliationStatusInternal,\n {}\n );\n\n return {\n processed,\n status,\n runAt: Date.now(),\n };\n },\n});\n"]}
1
+ {"version":3,"sources":["../src/convex.ts","../src/projectionStaleness.ts","../src/projectionReconciliation.ts"],"names":[],"mappings":"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","file":"projectionReconciliation.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * projectionStaleness module implementation.\n */\n\nexport type ProjectionEndpointClass =\n | \"analytics\"\n | \"traversal\"\n | \"entity_read\"\n | \"non_graph\";\n\nexport type ProjectionFallbackMode =\n | \"fail_with_503\"\n | \"degrade_to_convex_depth_limited\"\n | \"fallback_to_convex_entity_read\"\n | \"none\";\n\nexport type ProjectionStalenessPolicy = {\n endpointClass: ProjectionEndpointClass;\n thresholdMs: number;\n fallbackMode: ProjectionFallbackMode;\n nonOverridable: true;\n};\n\nexport type ProjectionStalenessInput = {\n endpointClass: ProjectionEndpointClass;\n queueBacklogAgeMs: number;\n queuePendingCount: number;\n queueFailedCount: number;\n nowMs?: number;\n lastSuccessfulSyncAt?: number;\n};\n\nexport type ProjectionStalenessEnvelope = {\n endpointClass: ProjectionEndpointClass;\n stalenessMs: number;\n thresholdMs: number;\n isStale: boolean;\n fallbackMode: ProjectionFallbackMode;\n queuePendingCount: number;\n queueFailedCount: number;\n evaluatedAt: number;\n lastSuccessfulSyncAt?: number;\n lastSuccessfulSyncAgeMs?: number;\n reasonCode:\n | \"PROJECTION_HEALTHY\"\n | \"PROJECTION_STALE\"\n | \"PROJECTION_STALE_WITH_FAILED_RETRIES\";\n};\n\nexport const PROJECTION_STALENESS_POLICIES: Record<\n ProjectionEndpointClass,\n ProjectionStalenessPolicy\n> = {\n analytics: {\n endpointClass: \"analytics\",\n thresholdMs: 30_000,\n fallbackMode: \"fail_with_503\",\n nonOverridable: true,\n },\n traversal: {\n endpointClass: \"traversal\",\n thresholdMs: 60_000,\n fallbackMode: \"degrade_to_convex_depth_limited\",\n nonOverridable: true,\n },\n entity_read: {\n endpointClass: \"entity_read\",\n thresholdMs: 5 * 60_000,\n fallbackMode: \"fallback_to_convex_entity_read\",\n nonOverridable: true,\n },\n non_graph: {\n endpointClass: \"non_graph\",\n thresholdMs: Number.POSITIVE_INFINITY,\n fallbackMode: \"none\",\n nonOverridable: true,\n },\n};\n\nexport function getProjectionStalenessPolicy(\n endpointClass: ProjectionEndpointClass\n): ProjectionStalenessPolicy {\n return PROJECTION_STALENESS_POLICIES[endpointClass];\n}\n\nexport function evaluateProjectionStaleness(\n input: ProjectionStalenessInput\n): ProjectionStalenessEnvelope {\n const policy = getProjectionStalenessPolicy(input.endpointClass);\n const evaluatedAt = input.nowMs ?? Date.now();\n const stalenessMs = Math.max(0, input.queueBacklogAgeMs);\n const isStale = stalenessMs > policy.thresholdMs;\n const lastSuccessfulSyncAgeMs =\n input.lastSuccessfulSyncAt !== undefined\n ? Math.max(0, evaluatedAt - input.lastSuccessfulSyncAt)\n : undefined;\n\n return {\n endpointClass: input.endpointClass,\n stalenessMs,\n thresholdMs: policy.thresholdMs,\n isStale,\n fallbackMode: policy.fallbackMode,\n queuePendingCount: input.queuePendingCount,\n queueFailedCount: input.queueFailedCount,\n evaluatedAt,\n lastSuccessfulSyncAt: input.lastSuccessfulSyncAt,\n lastSuccessfulSyncAgeMs,\n reasonCode: isStale\n ? input.queueFailedCount > 0\n ? \"PROJECTION_STALE_WITH_FAILED_RETRIES\"\n : \"PROJECTION_STALE\"\n : \"PROJECTION_HEALTHY\",\n };\n}\n\nexport function shouldFailClosedForProjection(\n envelope: ProjectionStalenessEnvelope\n): boolean {\n return envelope.isStale && envelope.fallbackMode === \"fail_with_503\";\n}\n","/**\n * Projection Reconciliation Runtime\n *\n * Phase 2 (WT-C) runtime hooks for Convex-authoritative / Neo4j-projected\n * reconciliation health and endpoint-class staleness evaluation.\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport { internal, internalAction, internalQuery, query } from \"./convex\";\nimport type { ActionCtx, QueryCtx } from \"./convex\";\nimport {\n evaluateProjectionStaleness,\n type ProjectionEndpointClass,\n} from \"./projectionStaleness\";\ntype QueueStatus = \"pending\" | \"in_progress\" | \"failed\" | \"succeeded\";\n\ntype QueueRow = {\n status: QueueStatus;\n createdAt: number;\n updatedAt: number;\n};\n\ntype IndexQueryBuilder = {\n eq(field: string, value: unknown): IndexQueryBuilder;\n};\n\nfunction maxTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let maxValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (maxValue === undefined || value > maxValue) {\n maxValue = value;\n }\n }\n return maxValue;\n}\n\nfunction minTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let minValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (minValue === undefined || value < minValue) {\n minValue = value;\n }\n }\n return minValue;\n}\n\nasync function getQueueSnapshot(ctx: QueryCtx) {\n const [pendingRows, inProgressRows, failedRows, succeededRows] =\n await Promise.all([\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"pending\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"in_progress\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"failed\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"succeeded\"))\n .collect() as Promise<QueueRow[]>,\n ]);\n\n const now = Date.now();\n const backlogOldestCreatedAt = minTimestamp(\n [...pendingRows, ...inProgressRows],\n \"createdAt\"\n );\n const queueBacklogAgeMs =\n backlogOldestCreatedAt !== undefined\n ? Math.max(0, now - backlogOldestCreatedAt)\n : 0;\n const lastSuccessfulSyncAt = maxTimestamp(succeededRows, \"updatedAt\");\n\n return {\n now,\n queuePendingCount: pendingRows.length,\n queueInProgressCount: inProgressRows.length,\n queueFailedCount: failedRows.length,\n queueSucceededCount: succeededRows.length,\n queueBacklogAgeMs,\n backlogOldestCreatedAt,\n lastSuccessfulSyncAt,\n };\n}\n\nfunction buildEndpointAssessments(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n const analytics = evaluateProjectionStaleness({\n endpointClass: \"analytics\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const traversal = evaluateProjectionStaleness({\n endpointClass: \"traversal\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const entityRead = evaluateProjectionStaleness({\n endpointClass: \"entity_read\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const nonGraph = evaluateProjectionStaleness({\n endpointClass: \"non_graph\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n\n return {\n analytics,\n traversal,\n entityRead,\n nonGraph,\n };\n}\n\nfunction buildProjectionReconciliationStatus(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n return {\n ...snapshot,\n endpointAssessments: buildEndpointAssessments(snapshot),\n generatedAt: snapshot.now,\n };\n}\n\nfunction assertAuthenticated(clerkId: string | null): string {\n if (!clerkId) {\n throw new Error(\"Authentication required\");\n }\n return clerkId;\n}\n\nexport const getProjectionReconciliationStatusInternal = internalQuery({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const getProjectionReconciliationStatus = query({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const assessProjectionStaleness = query({\n args: {\n endpointClass: v.union(\n v.literal(\"analytics\"),\n v.literal(\"traversal\"),\n v.literal(\"entity_read\"),\n v.literal(\"non_graph\")\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { endpointClass: ProjectionEndpointClass }\n ) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n const endpointClass = args.endpointClass as ProjectionEndpointClass;\n\n return {\n endpointClass,\n assessment: evaluateProjectionStaleness({\n endpointClass,\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n }),\n snapshot,\n };\n },\n});\n\nexport const runProjectionRepairCycle = internalAction({\n args: {\n limit: v.optional(v.number()),\n },\n returns: permissiveReturn,\n handler: async (ctx: ActionCtx, args: { limit?: number }) => {\n const processed = await ctx.runAction(\n internal.neo4jSync.processRetryQueue,\n {\n limit: args.limit ?? 25,\n }\n );\n const status = await ctx.runQuery(\n internal.projectionReconciliation\n .getProjectionReconciliationStatusInternal,\n {}\n );\n\n return {\n processed,\n status,\n runAt: Date.now(),\n };\n },\n});\n"]}
@@ -41,5 +41,5 @@
41
41
  "convex-validators",
42
42
  "proof-attestation"
43
43
  ],
44
- "signedAt": 1781409837253
44
+ "signedAt": 1781580822164
45
45
  }