@lucern/graph-primitives 0.1.0-alpha.4 → 0.3.0-alpha.0

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 (38) hide show
  1. package/dist/beliefDecay.js +199 -18
  2. package/dist/beliefDecay.js.map +1 -1
  3. package/dist/beliefEvidenceLinks.js.map +1 -1
  4. package/dist/confidencePropagationDispatch.js.map +1 -1
  5. package/dist/contradictions.js.map +1 -1
  6. package/dist/entityBridge.js.map +1 -1
  7. package/dist/entityLifecycle.js.map +1 -1
  8. package/dist/epistemicAnswers.js +21 -36
  9. package/dist/epistemicAnswers.js.map +1 -1
  10. package/dist/epistemicBeliefs.js +92 -651
  11. package/dist/epistemicBeliefs.js.map +1 -1
  12. package/dist/epistemicContracts.js +65 -624
  13. package/dist/epistemicContracts.js.map +1 -1
  14. package/dist/epistemicEdges.js.map +1 -1
  15. package/dist/epistemicEvidence.js +71 -630
  16. package/dist/epistemicEvidence.js.map +1 -1
  17. package/dist/epistemicHelpers.js +3 -2
  18. package/dist/epistemicHelpers.js.map +1 -1
  19. package/dist/epistemicLinking.js.map +1 -1
  20. package/dist/epistemicNodes.js +49 -585
  21. package/dist/epistemicNodes.js.map +1 -1
  22. package/dist/epistemicQuestions.js +46 -590
  23. package/dist/epistemicQuestions.js.map +1 -1
  24. package/dist/epistemicSources.js +29 -565
  25. package/dist/epistemicSources.js.map +1 -1
  26. package/dist/evaluators/index.js +65 -624
  27. package/dist/evaluators/index.js.map +1 -1
  28. package/dist/index.js +304 -905
  29. package/dist/index.js.map +1 -1
  30. package/dist/ontologyApproval.js.map +1 -1
  31. package/dist/ontologyDefinitions.js.map +1 -1
  32. package/dist/ontologyRegistry.js.map +1 -1
  33. package/dist/projectionReconciliation.js.map +1 -1
  34. package/dist/questionEvidenceLinks.js +188 -2
  35. package/dist/questionEvidenceLinks.js.map +1 -1
  36. package/dist/workspaceIsolation.js +30 -581
  37. package/dist/workspaceIsolation.js.map +1 -1
  38. package/package.json +5 -6
@@ -1,5 +1,5 @@
1
1
  import { v } from 'convex/values';
2
- import { componentsGeneric, defineTable, queryGeneric, mutationGeneric, anyApi, internalMutationGeneric, internalQueryGeneric } from 'convex/server';
2
+ import { componentsGeneric, queryGeneric, mutationGeneric, anyApi, internalMutationGeneric, internalQueryGeneric } from 'convex/server';
3
3
 
4
4
  // src/epistemicNodes.ts
5
5
  var api = anyApi;
@@ -816,7 +816,7 @@ var mutation = mutationGeneric;
816
816
  var query = queryGeneric;
817
817
 
818
818
  // src/graphTypes.ts
819
- function getNodeLayer(nodeType2) {
819
+ function getNodeLayer(nodeType) {
820
820
  const L4_TYPES = ["decision"];
821
821
  const L3_TYPES = ["belief", "question", "theme", "deal"];
822
822
  const L2_TYPES = ["claim", "evidence", "synthesis", "answer"];
@@ -829,25 +829,25 @@ function getNodeLayer(nodeType2) {
829
829
  "value_chain"
830
830
  ];
831
831
  const ORGANIZATIONAL_TYPES = ["topic"];
832
- if (L4_TYPES.includes(nodeType2)) {
832
+ if (L4_TYPES.includes(nodeType)) {
833
833
  return "L4";
834
834
  }
835
- if (L3_TYPES.includes(nodeType2)) {
835
+ if (L3_TYPES.includes(nodeType)) {
836
836
  return "L3";
837
837
  }
838
- if (L2_TYPES.includes(nodeType2)) {
838
+ if (L2_TYPES.includes(nodeType)) {
839
839
  return "L2";
840
840
  }
841
- if (L1_TYPES.includes(nodeType2)) {
841
+ if (L1_TYPES.includes(nodeType)) {
842
842
  return "L1";
843
843
  }
844
- if (ONTOLOGICAL_TYPES.includes(nodeType2)) {
844
+ if (ONTOLOGICAL_TYPES.includes(nodeType)) {
845
845
  return "ontological";
846
846
  }
847
- if (ORGANIZATIONAL_TYPES.includes(nodeType2)) {
847
+ if (ORGANIZATIONAL_TYPES.includes(nodeType)) {
848
848
  return "organizational";
849
849
  }
850
- console.warn(`[GraphTypes] Unknown nodeType "${nodeType2}", defaulting to L2`);
850
+ console.warn(`[GraphTypes] Unknown nodeType "${nodeType}", defaulting to L2`);
851
851
  return "L2";
852
852
  }
853
853
 
@@ -858,11 +858,11 @@ var RESOLVED_PREDICTION_OUTCOMES = [
858
858
  "partial",
859
859
  "expired"
860
860
  ];
861
- function hasResolvedPredictionOutcome(predictionMeta2) {
862
- if (!predictionMeta2 || typeof predictionMeta2 !== "object") {
861
+ function hasResolvedPredictionOutcome(predictionMeta) {
862
+ if (!predictionMeta || typeof predictionMeta !== "object") {
863
863
  return false;
864
864
  }
865
- const outcome = predictionMeta2.outcome;
865
+ const outcome = predictionMeta.outcome;
866
866
  return typeof outcome === "string" && RESOLVED_PREDICTION_OUTCOMES.includes(outcome);
867
867
  }
868
868
 
@@ -1264,567 +1264,31 @@ var optionalScopeArgs = {
1264
1264
  projectId: v.optional(v.string()),
1265
1265
  topicId: v.optional(v.string())
1266
1266
  };
1267
- v.number();
1268
- v.union(
1269
- v.literal("very_high"),
1270
- // 0.9+
1271
- v.literal("high"),
1272
- // 0.7-0.9
1273
- v.literal("medium"),
1274
- // 0.4-0.7
1275
- v.literal("low"),
1276
- // 0.2-0.4
1277
- v.literal("very_low")
1278
- // 0-0.2
1279
- );
1280
- v.union(
1281
- v.literal(1),
1282
- // Critical
1283
- v.literal(2),
1284
- // High
1285
- v.literal(3),
1286
- // Medium
1287
- v.literal(4),
1288
- // Low
1289
- v.literal(5)
1290
- // Backlog
1291
- );
1292
- v.union(
1293
- v.literal("critical"),
1294
- v.literal("high"),
1295
- v.literal("medium"),
1296
- v.literal("low"),
1297
- v.literal("backlog")
1298
- );
1299
- v.union(
1300
- v.literal("active"),
1301
- v.literal("paused"),
1302
- v.literal("completed"),
1303
- v.literal("archived")
1304
- );
1305
- v.union(
1306
- v.literal("pending"),
1307
- v.literal("processing"),
1308
- v.literal("completed"),
1309
- v.literal("failed")
1310
- );
1311
- v.object({
1312
- crunchbaseId: v.optional(v.string()),
1313
- linkedinUrl: v.optional(v.string()),
1314
- pitchbookId: v.optional(v.string()),
1315
- twitterUrl: v.optional(v.string()),
1316
- domain: v.optional(v.string())
1317
- });
1318
- var sourceType = v.union(
1319
- v.literal("proprietary"),
1320
- // Internal Stack research
1321
- v.literal("primary"),
1322
- // Direct interviews, calls
1323
- v.literal("secondary"),
1324
- // Published sources
1325
- v.literal("ai_generated"),
1326
- // AI-synthesized
1327
- v.literal("user_input"),
1328
- // Manual user entry
1329
- v.literal("inferred")
1330
- // System inference
1331
- );
1332
- v.object({
1333
- sourceType: v.optional(sourceType),
1334
- sourceId: v.optional(v.string()),
1335
- // Reference to source entity
1336
- sourceUrl: v.optional(v.string()),
1337
- sourceDate: v.optional(v.number()),
1338
- sourceName: v.optional(v.string())
1339
- });
1340
- v.object({
1341
- cursor: v.optional(v.string()),
1342
- limit: v.optional(v.number())
1343
- });
1344
- v.object({
1345
- hasMore: v.boolean(),
1346
- nextCursor: v.optional(v.string()),
1347
- totalCount: v.optional(v.number())
1348
- });
1349
- var richTextContent = v.object({
1350
- type: v.literal("doc"),
1351
- content: looseJsonArray
1352
- });
1353
- v.union(v.string(), richTextContent);
1354
- v.object({
1355
- promptTokens: v.optional(v.number()),
1356
- completionTokens: v.optional(v.number()),
1357
- totalTokens: v.optional(v.number())
1358
- });
1359
- v.object({
1360
- fileName: v.optional(v.string()),
1361
- fileSize: v.optional(v.number()),
1362
- mimeType: v.optional(v.string()),
1363
- storageId: v.optional(v.id("_storage")),
1364
- externalUrl: v.optional(v.string())
1365
- });
1366
1267
 
1367
- // ../schema-management/src/spine/tables/epistemicNodes.ts
1368
- var nodeType = v.union(
1369
- // --- L4: Audit Targets (decisions, outcomes) ---
1370
- v.literal("decision"),
1371
- // Investment decision with knowledge horizon snapshot
1372
- // --- L3: Traversal Anchors (epistemic structure) ---
1373
- v.literal("belief"),
1374
- // Structured conviction (immutable formulation)
1375
- v.literal("question"),
1376
- // Unit of uncertainty
1377
- v.literal("theme"),
1378
- // Investment thesis / conviction cluster
1379
- v.literal("deal"),
1380
- // Investment evaluation process
1381
- v.literal("topic"),
1382
- // Hierarchical knowledge container
1383
- // --- L2: Compression Boundary (minimum reasoning unit) ---
1384
- v.literal("claim"),
1385
- // Atomic assertion that can be true/false
1386
- v.literal("evidence"),
1387
- // Interpreted signal linked to beliefs
1388
- v.literal("synthesis"),
1389
- // Primers, deep research
1390
- v.literal("answer"),
1391
- // Immutable answer snapshot for a question
1392
- // --- L1: Terminal Leaves (non-traversable, grounding) ---
1393
- v.literal("atomic_fact"),
1394
- // Raw fact from source (not interpreted)
1395
- v.literal("excerpt"),
1396
- // Direct quote from source document
1397
- v.literal("source"),
1398
- // News, documents, transcripts
1399
- // --- Ontological Entities (things in the world) ---
1400
- v.literal("company"),
1401
- // Organization (subtype: private, corporate, portfolio)
1402
- v.literal("person"),
1403
- // Individual (founder, expert, LP, contact)
1404
- v.literal("investor"),
1405
- // Investment entity (subtype: vc, lp, cvc, pe, family_office, angel)
1406
- v.literal("function"),
1407
- // What a company does (from classifier)
1408
- v.literal("value_chain")
1409
- // Market structure / value flow
1410
- );
1411
- var epistemicLayer = v.union(
1412
- v.literal("L4"),
1413
- // Decisions, outcomes - audit targets
1414
- v.literal("L3"),
1415
- // Beliefs, questions, themes - traversal anchors
1416
- v.literal("L2"),
1417
- // Claims, evidence, synthesis - compression boundary
1418
- v.literal("L1"),
1419
- // Atomic facts, excerpts, sources - terminal leaves
1420
- v.literal("ontological"),
1421
- // Companies, people, etc - not epistemic
1422
- v.literal("organizational")
1423
- // Topics, lenses, worktrees — structural containers
1424
- );
1425
- var nodeStatus = v.union(
1426
- v.literal("active"),
1427
- v.literal("superseded"),
1428
- // Replaced by newer version
1429
- v.literal("archived"),
1430
- v.literal("deleted")
1431
- );
1432
- var sourceType2 = v.union(
1433
- v.literal("human"),
1434
- // User created directly
1435
- v.literal("ai_extracted"),
1436
- // LLM extracted from a source
1437
- v.literal("ai_generated"),
1438
- // LLM synthesized/created
1439
- v.literal("imported"),
1440
- // External system import
1441
- v.literal("system"),
1442
- // System-generated (migrations, classifiers)
1443
- v.literal("verified"),
1444
- // Human-verified source
1445
- v.literal("proprietary")
1446
- // Proprietary/internal data
1447
- );
1448
- var verificationStatus = v.union(
1449
- v.literal("unverified"),
1450
- v.literal("human_verified"),
1451
- v.literal("ai_verified"),
1452
- v.literal("contradicted"),
1453
- v.literal("outdated")
1454
- );
1455
- var syncStatus = v.union(
1456
- v.literal("synced"),
1457
- // Node and edges fully synced to Neo4j
1458
- v.literal("pending_edges"),
1459
- // Node created, edges being created
1460
- v.literal("edge_creation_failed")
1461
- // Edge creation failed, needs retry
1462
- );
1463
- var audienceLabel = v.string();
1464
- var sensitivityTier = v.union(
1465
- v.literal("low"),
1466
- v.literal("medium"),
1467
- v.literal("high"),
1468
- v.literal("restricted")
1469
- );
1470
- var exportClass = v.union(
1471
- v.literal("internal_only"),
1472
- v.literal("client_safe"),
1473
- v.literal("public_safe"),
1474
- v.literal("restricted")
1475
- );
1476
- var anonymizationClass = v.union(
1477
- v.literal("none"),
1478
- v.literal("standard"),
1479
- v.literal("strict")
1480
- );
1481
- var epistemicStatus = v.union(
1482
- v.literal("hypothesis"),
1483
- // Initial conjecture, low evidence
1484
- v.literal("emerging"),
1485
- // Building evidence, gaining traction
1486
- v.literal("established"),
1487
- // Well-evidenced, core to thesis
1488
- v.literal("challenged"),
1489
- // Contradicting evidence appeared
1490
- v.literal("assumption"),
1491
- // Taken as given, not actively tested
1492
- v.literal("deprecated")
1493
- // Superseded or abandoned
1494
- );
1495
- var beliefStatus = v.union(
1496
- v.literal("assumption"),
1497
- v.literal("hypothesis"),
1498
- v.literal("belief"),
1499
- v.literal("fact")
1500
- );
1501
- var reversibility = v.union(
1502
- v.literal("irreversible"),
1503
- // One-way door decision
1504
- v.literal("hard_to_reverse"),
1505
- // Significant cost to undo
1506
- v.literal("reversible"),
1507
- // Can change course with moderate effort
1508
- v.literal("trivial")
1509
- // Easy to adjust
1510
- );
1511
- var predictionOutcome = v.union(
1512
- v.literal("pending"),
1513
- v.literal("confirmed"),
1514
- v.literal("disconfirmed"),
1515
- v.literal("partial"),
1516
- v.literal("expired")
1517
- );
1518
- var predictionMeta = v.object({
1519
- isPrediction: v.boolean(),
1520
- registeredAt: v.number(),
1521
- // When prediction was made
1522
- expectedBy: v.optional(v.number()),
1523
- // When we expect resolution
1524
- outcome: v.optional(predictionOutcome),
1525
- outcomeRecordedAt: v.optional(v.number()),
1526
- outcomeEvidenceId: v.optional(v.string()),
1527
- // globalId of confirming evidence
1528
- confidenceAtPrediction: v.optional(v.number()),
1529
- // 0-1
1530
- actualVsPredicted: v.optional(v.string())
1531
- // Notes on how outcome compared
1532
- });
1533
- var methodology = v.union(
1534
- // Primary Research (high value)
1535
- v.literal("primary_research"),
1536
- // Direct investigation
1537
- v.literal("expert_interview"),
1538
- // Expert call/interview
1539
- v.literal("customer_interview"),
1540
- // Customer research
1541
- v.literal("field_observation"),
1542
- // On-site observation
1543
- v.literal("proprietary_data"),
1544
- // Internal data analysis
1545
- // Secondary Research
1546
- v.literal("desk_research"),
1547
- // Public sources
1548
- v.literal("regulatory_filing"),
1549
- // SEC, regulatory docs
1550
- v.literal("news_article"),
1551
- // News/press
1552
- v.literal("academic_paper"),
1553
- // Academic research
1554
- // AI-Assisted
1555
- v.literal("ai_synthesis"),
1556
- // AI-generated synthesis
1557
- v.literal("ai_extraction")
1558
- // AI-extracted from source
1559
- );
1560
- var informationAsymmetry = v.union(
1561
- v.literal("proprietary"),
1562
- // Only we have this
1563
- v.literal("early"),
1564
- // We're early but others will get it
1565
- v.literal("common")
1566
- // Everyone has access
1567
- );
1568
- var temporalNature = v.union(
1569
- v.literal("factual"),
1570
- // Resolved outcome. Grounded in reality.
1571
- v.literal("forecast"),
1572
- // Prediction. Will resolve. Discounted weight.
1573
- v.literal("unknown")
1574
- // Not yet classified.
1575
- );
1576
- var questionType = v.union(
1577
- v.literal("validation"),
1578
- // Does evidence support this belief?
1579
- v.literal("falsification"),
1580
- // What would prove this belief wrong?
1581
- v.literal("assumption_probe"),
1582
- // Is this unstated assumption true?
1583
- v.literal("prediction_test"),
1584
- // Will this predicted outcome occur?
1585
- v.literal("counterfactual"),
1586
- // What would we expect if X were false?
1587
- v.literal("discovery"),
1588
- // What don't we know yet?
1589
- v.literal("clarification"),
1590
- // What does X actually mean?
1591
- v.literal("comparison"),
1592
- // How does X compare to Y?
1593
- v.literal("causal"),
1594
- // What caused X?
1595
- v.literal("mechanism"),
1596
- // How does X work?
1597
- v.literal("general")
1598
- // Unclassified
1599
- );
1600
- var questionPriority = v.union(
1601
- v.literal("critical"),
1602
- // Blocks decision-making
1603
- v.literal("high"),
1604
- // Important for thesis
1605
- v.literal("medium"),
1606
- // Would be nice to know
1607
- v.literal("low")
1608
- // Background/curiosity
1609
- );
1610
- var answerQuality = v.union(
1611
- v.literal("definitive"),
1612
- // Clear, well-supported
1613
- v.literal("strong"),
1614
- // Good evidence, high confidence
1615
- v.literal("moderate"),
1616
- // Some evidence
1617
- v.literal("weak"),
1618
- // Limited evidence
1619
- v.literal("speculative"),
1620
- // Mostly conjecture
1621
- v.literal("unanswered")
1622
- // No answer yet
1623
- );
1624
- var consensusView = v.union(
1625
- v.literal("aligned"),
1626
- // We agree with market consensus
1627
- v.literal("ahead_of"),
1628
- // We see this before consensus does
1629
- v.literal("contrarian"),
1630
- // We actively disagree with consensus
1631
- v.literal("orthogonal"),
1632
- // We're looking at something consensus isn't discussing
1633
- v.literal("unknown")
1634
- // We don't know what consensus thinks
1635
- );
1636
- var themeConviction = v.union(
1637
- v.literal("high"),
1638
- // Strong conviction, actively deploying
1639
- v.literal("medium"),
1640
- // Building conviction
1641
- v.literal("low"),
1642
- // Exploring, not convicted
1643
- v.literal("negative")
1644
- // Actively avoiding
1645
- );
1646
- var decisionType = v.union(
1647
- v.literal("invest"),
1648
- v.literal("pass"),
1649
- v.literal("follow_on"),
1650
- v.literal("exit"),
1651
- v.literal("deep_dive"),
1652
- v.literal("monitor"),
1653
- v.literal("deprioritize"),
1654
- v.literal("thesis_adopt"),
1655
- v.literal("thesis_revise"),
1656
- v.literal("thesis_abandon")
1657
- );
1658
- var decisionOutcome = v.union(
1659
- v.literal("pending"),
1660
- v.literal("successful"),
1661
- v.literal("unsuccessful"),
1662
- v.literal("mixed"),
1663
- v.literal("unknown")
1664
- );
1665
- var externalIds2 = v.object({
1666
- crunchbase: v.optional(v.string()),
1667
- linkedin: v.optional(v.string()),
1668
- pitchbook: v.optional(v.string()),
1669
- twitter: v.optional(v.string()),
1670
- website: v.optional(v.string())
1671
- });
1672
- defineTable({
1673
- // === IDENTITY ===
1674
- globalId: v.string(),
1675
- // UUID - survives migration to Neo4j
1676
- // === TYPE ===
1677
- nodeType,
1678
- // === EPISTEMIC LAYER ===
1679
- epistemicLayer: v.optional(epistemicLayer),
1680
- // === SUBTYPE (for typed entities) ===
1681
- subtype: v.optional(v.string()),
1682
- // company: private|corporate|portfolio, investor: vc|lp|cvc|pe|family_office|angel
1683
- // === CONTENT ===
1684
- canonicalText: v.string(),
1685
- // The core content (belief statement, company name, etc.)
1686
- contentHash: v.string(),
1687
- // SHA256(nodeType + canonicalText) for deduplication
1688
- // Extended content (for sources/syntheses)
1689
- content: v.optional(v.string()),
1690
- // Full text for documents/articles
1691
- contentType: v.optional(v.string()),
1692
- // "markdown", "html", "pdf", "text"
1693
- // === METADATA ===
1694
- title: v.optional(v.string()),
1695
- // Display title
1696
- tags: v.optional(v.array(v.string())),
1697
- domain: v.optional(v.string()),
1698
- // For companies: website domain
1699
- // Type-specific metadata (flexible object - LEGACY)
1700
- // New code should use the typed fields below when available
1701
- metadata: v.optional(looseJsonObject),
1702
- // === POLICY / ENTITLEMENT ===
1703
- tenantId: v.optional(v.string()),
1704
- workspaceId: v.optional(v.string()),
1705
- ownerPrincipalId: v.optional(v.string()),
1706
- audienceLabel: v.optional(audienceLabel),
1707
- policyTags: v.optional(v.array(v.string())),
1708
- sensitivityTier: v.optional(sensitivityTier),
1709
- exportClass: v.optional(exportClass),
1710
- anonymizationClass: v.optional(anonymizationClass),
1711
- // === PUBLICATION (visibility-based, not copy-based) ===
1712
- // Publication expands who can see a workspace-local node — the node stays
1713
- // in its workspace, like a microservice exposing part of its API surface.
1714
- // Rules-based: pack/tenant-level publicationRules auto-evaluate on
1715
- // confidence changes and node creation. No manual click-by-click.
1716
- publicationStatus: v.optional(
1717
- v.union(
1718
- v.literal("unpublished"),
1719
- // Default: workspace-local only
1720
- v.literal("published"),
1721
- // Visible at tenant scope (rules matched)
1722
- v.literal("suppressed")
1723
- // Manually blocked even if rules match
1724
- )
1725
- ),
1726
- publishedAt: v.optional(v.number()),
1727
- // When publication status last changed to published
1728
- publishedBy: v.optional(v.string()),
1729
- // userId or "system:publication_rules" for auto-publish
1730
- // === TYPED METADATA FIELDS ===
1731
- // --- Belief ---
1732
- // Belief type — validated against schemaEnumConfig category "belief_type"
1733
- // Platform core: hypothesis, belief, principle, invariant, assumption,
1734
- // tenet, prior, preference, goal, forecast
1735
- beliefType: v.optional(v.string()),
1736
- beliefStatus: v.optional(beliefStatus),
1737
- epistemicStatus: v.optional(epistemicStatus),
1738
- reversibility: v.optional(reversibility),
1739
- predictionMeta: v.optional(predictionMeta),
1740
- // Consensus tracking (for non-consensus detection)
1741
- consensusView: v.optional(consensusView),
1742
- consensusConfidence: v.optional(v.number()),
1743
- // 0-1: What we think consensus confidence is
1744
- consensusSource: v.optional(v.string()),
1745
- // Where we got the consensus view (twitter, reports, etc.)
1746
- // --- Evidence ---
1747
- methodology: v.optional(methodology),
1748
- informationAsymmetry: v.optional(informationAsymmetry),
1749
- temporalNature: v.optional(temporalNature),
1750
- // --- Question ---
1751
- questionType: v.optional(questionType),
1752
- questionPriority: v.optional(questionPriority),
1753
- answerQuality: v.optional(answerQuality),
1754
- // --- Theme ---
1755
- themeConviction: v.optional(themeConviction),
1756
- // Market timing (for "early on theme" detection)
1757
- marketAwarenessDate: v.optional(v.number()),
1758
- // When this theme became broadly discussed
1759
- marketAwarenessSource: v.optional(v.string()),
1760
- // How we know (first major report, twitter volume spike, etc.)
1761
- earlySignalIds: v.optional(v.array(v.string())),
1762
- // globalIds of evidence we had before market awareness
1763
- // --- Decision ---
1764
- decisionType: v.optional(decisionType),
1765
- decisionOutcome: v.optional(decisionOutcome),
1766
- // === EXTERNAL IDS (for ontological entities) ===
1767
- externalIds: v.optional(externalIds2),
1768
- // === PROVENANCE ===
1769
- sourceType: sourceType2,
1770
- aiProvider: v.optional(v.string()),
1771
- // "claude", "gemini", "gpt-4", etc.
1772
- extractedFromNodeId: v.optional(v.id("epistemicNodes")),
1773
- // Quick reference to source
1774
- // === EXTRACTION CONTEXT ===
1775
- extractionModel: v.optional(v.string()),
1776
- // "claude-sonnet-4-20250514"
1777
- extractionPromptName: v.optional(v.string()),
1778
- // "lucern/extract-evidence"
1779
- extractionPromptVersion: v.optional(v.number()),
1780
- extractionTemperature: v.optional(v.number()),
1781
- extractionLangfuseTraceId: v.optional(v.string()),
1782
- // === GROUNDING VERIFICATION ===
1783
- groundingVerified: v.optional(v.boolean()),
1784
- groundingConfidence: v.optional(v.number()),
1785
- // 0-1 match quality
1786
- groundingMatchedText: v.optional(v.string()),
1787
- // Actual text from source
1788
- groundingStartOffset: v.optional(v.number()),
1789
- groundingEndOffset: v.optional(v.number()),
1790
- groundingRejectionReason: v.optional(v.string()),
1791
- // === CONFIDENCE & VERIFICATION ===
1792
- confidence: v.optional(v.number()),
1793
- // 0-1 projected probability P(x) = b + a*u
1794
- verificationStatus: v.optional(verificationStatus),
1795
- // === SL OPINION (Subjective Logic — Kernel v2) ===
1796
- // Replaces scalar confidence with rich epistemic state.
1797
- // b + d + u = 1. P(x) = b + a*u is stored in `confidence` for backward compat.
1798
- opinion_b: v.optional(v.number()),
1799
- // Belief: evidence FOR (0-1)
1800
- opinion_d: v.optional(v.number()),
1801
- // Disbelief: evidence AGAINST (0-1)
1802
- opinion_u: v.optional(v.number()),
1803
- // Uncertainty: absence of evidence (0-1)
1804
- opinion_a: v.optional(v.number()),
1805
- // Base rate / prior probability (0-1)
1806
- tupleContradicted: v.optional(v.boolean()),
1807
- // Single-belief tuple-space contradiction flag
1808
- // === LIFECYCLE ===
1809
- status: nodeStatus,
1810
- supersededBy: v.optional(v.id("epistemicNodes")),
1811
- // === OWNERSHIP ===
1812
- topicId: v.optional(v.string()),
1813
- // Canonical scope container (topic-first model)
1814
- projectId: v.optional(v.string()),
1815
- // DEPRECATED: Use belongs_to edges
1816
- createdBy: v.string(),
1817
- // Clerk user ID
1818
- createdAt: v.number(),
1819
- updatedAt: v.number(),
1820
- // === NEO4J SYNC STATUS ===
1821
- syncStatus: v.optional(syncStatus),
1822
- syncError: v.optional(v.string())
1823
- // Error message if sync failed
1824
- }).index("by_globalId", ["globalId"]).index("by_contentHash", ["contentHash"]).index("by_nodeType", ["nodeType"]).index("by_subtype", ["nodeType", "subtype"]).index("by_domain", ["domain"]).index("by_project", ["projectId"]).index("by_project_type", ["projectId", "nodeType"]).index("by_topic", ["topicId"]).index("by_topic_type", ["topicId", "nodeType"]).index("by_tenantId", ["tenantId"]).index("by_workspaceId", ["workspaceId"]).index("by_tenant_workspace", ["tenantId", "workspaceId"]).index("by_audienceLabel", ["audienceLabel"]).index("by_sensitivityTier", ["sensitivityTier"]).index("by_exportClass", ["exportClass"]).index("by_status", ["status"]).index("by_sourceType", ["sourceType"]).index("by_verification", ["verificationStatus"]).index("by_layer", ["epistemicLayer"]).index("by_layer_type", ["epistemicLayer", "nodeType"]).index("by_syncStatus", ["syncStatus"]).index("by_publicationStatus", ["publicationStatus"]).index("by_tenant_publicationStatus", ["tenantId", "publicationStatus"]).index("by_belief_status", ["nodeType", "beliefStatus"]).index("by_epistemic_status", ["nodeType", "epistemicStatus"]).index("by_temporal_nature", ["nodeType", "temporalNature"]).index("by_methodology", ["nodeType", "methodology"]).index("by_reversibility", ["nodeType", "reversibility"]).index("by_questionType", ["nodeType", "questionType"]).index("by_questionPriority", ["nodeType", "questionPriority"]).searchIndex("search_canonicalText", {
1825
- searchField: "canonicalText",
1826
- filterFields: ["nodeType", "projectId", "topicId", "status"]
1827
- });
1268
+ // ../../packages/contracts/src/schema-helpers/spine/tables/epistemicNodes.ts
1269
+ var NODE_TYPES = [
1270
+ "decision",
1271
+ "belief",
1272
+ "question",
1273
+ "theme",
1274
+ "deal",
1275
+ "topic",
1276
+ "claim",
1277
+ "evidence",
1278
+ "synthesis",
1279
+ "answer",
1280
+ "atomic_fact",
1281
+ "excerpt",
1282
+ "source",
1283
+ "company",
1284
+ "person",
1285
+ "investor",
1286
+ "function",
1287
+ "value_chain"
1288
+ ];
1289
+ function isNodeType(value) {
1290
+ return NODE_TYPES.includes(value);
1291
+ }
1828
1292
  function getLayerForNodeType(type) {
1829
1293
  switch (type) {
1830
1294
  case "decision":
@@ -1872,7 +1336,7 @@ function throwWorkspaceIsolationError(args) {
1872
1336
  throw error;
1873
1337
  }
1874
1338
  function assertWorkspaceScopedEpistemicNodeScope(args) {
1875
- const layer = getLayerForNodeType(args.nodeType);
1339
+ const layer = isNodeType(args.nodeType) ? getLayerForNodeType(args.nodeType) : void 0;
1876
1340
  if (layer === "ontological") {
1877
1341
  return;
1878
1342
  }
@@ -2108,8 +1572,8 @@ var getByProjectAndTypeLite = query({
2108
1572
  const pageSize = clampNodeLimit(args.limit);
2109
1573
  const scanLimit = Math.min(pageSize * 3, MAX_NODE_PAGE_SIZE);
2110
1574
  const query2 = ctx.db.query("epistemicNodes").withIndex(
2111
- scope.topicId ? "by_topic_type" : "by_project_type",
2112
- (q) => scope.topicId ? q.eq("topicId", scope.topicId).eq("nodeType", args.nodeType) : q.eq("projectId", scope.projectId).eq("nodeType", args.nodeType)
1575
+ "by_topic_type",
1576
+ (q) => q.eq("topicId", scope.topicId).eq("nodeType", args.nodeType)
2113
1577
  );
2114
1578
  const nodes = await query2.order("desc").take(scanLimit);
2115
1579
  const statusFiltered = args.status ? nodes.filter((n) => n.status === args.status) : nodes.filter((n) => n.status === "active");
@@ -2315,7 +1779,7 @@ var create = mutation({
2315
1779
  if (existing && existing.status === "active") {
2316
1780
  return { nodeId: existing._id, isDuplicate: true };
2317
1781
  }
2318
- const epistemicLayer2 = getNodeLayer(args.nodeType);
1782
+ const epistemicLayer = getNodeLayer(args.nodeType);
2319
1783
  const resolvedScope = args.topicId || args.projectId ? await resolveTopicProjectScope(ctx, {
2320
1784
  topicId: args.topicId,
2321
1785
  projectId: args.projectId
@@ -2332,11 +1796,11 @@ var create = mutation({
2332
1796
  tenantId: resolvedScope.tenantId,
2333
1797
  workspaceId: resolvedScope.workspaceId,
2334
1798
  nodeType: args.nodeType,
2335
- epistemicLayer: epistemicLayer2
1799
+ epistemicLayer
2336
1800
  },
2337
1801
  mutationName: "epistemicNodes.create"
2338
1802
  });
2339
- } else if (epistemicLayer2 !== "ontological") {
1803
+ } else if (epistemicLayer !== "ontological") {
2340
1804
  throw new Error(
2341
1805
  "Workspace-scoped reasoning isolation requires topicId or projectId for non-ontological node creation."
2342
1806
  );
@@ -2344,7 +1808,7 @@ var create = mutation({
2344
1808
  const nodeId = await ctx.db.insert("epistemicNodes", {
2345
1809
  globalId: args.globalId,
2346
1810
  nodeType: args.nodeType,
2347
- epistemicLayer: epistemicLayer2,
1811
+ epistemicLayer,
2348
1812
  // Phase 2B: Auto-derived from nodeType
2349
1813
  subtype: args.subtype,
2350
1814
  canonicalText: args.canonicalText,
@@ -2505,11 +1969,11 @@ var supersede = mutation({
2505
1969
  mutationName: "epistemicNodes.supersede"
2506
1970
  });
2507
1971
  const now = Date.now();
2508
- const epistemicLayer2 = oldNode.epistemicLayer || getNodeLayer(oldNode.nodeType);
1972
+ const epistemicLayer = oldNode.epistemicLayer || getNodeLayer(oldNode.nodeType);
2509
1973
  const newNodeId = await ctx.db.insert("epistemicNodes", {
2510
1974
  globalId: args.newGlobalId,
2511
1975
  nodeType: oldNode.nodeType,
2512
- epistemicLayer: epistemicLayer2,
1976
+ epistemicLayer,
2513
1977
  // Phase 2B: Inherit layer (supersession is same-layer only)
2514
1978
  canonicalText: args.newCanonicalText,
2515
1979
  contentHash: args.newContentHash,
@@ -2742,14 +2206,14 @@ var batchCreate = mutation({
2742
2206
  nodeType: node.nodeType,
2743
2207
  mutationName: "epistemicNodes.batchCreate"
2744
2208
  });
2745
- const epistemicLayer2 = getNodeLayer(node.nodeType);
2209
+ const epistemicLayer = getNodeLayer(node.nodeType);
2746
2210
  const resolvedScope = node.topicId || node.projectId ? await resolveTopicProjectScope(ctx, {
2747
2211
  topicId: node.topicId,
2748
2212
  projectId: node.projectId
2749
2213
  }).catch(() => void 0) : void 0;
2750
2214
  const nodeId = await ctx.db.insert("epistemicNodes", {
2751
2215
  ...node,
2752
- epistemicLayer: epistemicLayer2,
2216
+ epistemicLayer,
2753
2217
  // Phase 2B: Auto-derived from nodeType
2754
2218
  verificationStatus: node.verificationStatus ?? "unverified",
2755
2219
  status: "active",
@@ -2833,11 +2297,11 @@ var createInternal = internalMutation({
2833
2297
  projectId: args.projectId
2834
2298
  }).catch(() => void 0) : void 0;
2835
2299
  const contentHash = args.contentHash || `${args.nodeType}:${args.canonicalText}`.slice(0, 64);
2836
- const epistemicLayer2 = args.epistemicLayer || getNodeLayer(args.nodeType);
2300
+ const epistemicLayer = args.epistemicLayer || getNodeLayer(args.nodeType);
2837
2301
  const nodeId = await ctx.db.insert("epistemicNodes", {
2838
2302
  globalId: args.globalId,
2839
2303
  nodeType: args.nodeType,
2840
- epistemicLayer: epistemicLayer2,
2304
+ epistemicLayer,
2841
2305
  subtype: args.subtype,
2842
2306
  canonicalText: args.canonicalText,
2843
2307
  contentHash,