@lucern/graph-primitives 0.1.0-alpha.3 → 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, internalMutationGeneric, mutationGeneric, anyApi, queryGeneric, internalQueryGeneric } from 'convex/server';
2
+ import { componentsGeneric, internalMutationGeneric, mutationGeneric, anyApi, queryGeneric, internalQueryGeneric } from 'convex/server';
3
3
 
4
4
  // src/epistemicContracts.ts
5
5
  var api = anyApi;
@@ -1577,10 +1577,8 @@ async function queryRegistryRows(ctx, args) {
1577
1577
  async function listAudienceRegistryRows(ctx, args) {
1578
1578
  return queryRegistryRows(ctx, args);
1579
1579
  }
1580
- componentsGeneric();
1581
- var internal2 = anyApi;
1582
1580
 
1583
- // ../schema-management/src/enumValidation.ts
1581
+ // ../../packages/contracts/src/schema-helpers/enumValidation.ts
1584
1582
  var BUILTIN_ENUM_FALLBACK = {
1585
1583
  topic_type: /* @__PURE__ */ new Set([
1586
1584
  "domain",
@@ -1623,7 +1621,6 @@ var BUILTIN_ENUM_FALLBACK = {
1623
1621
  "tradeoff",
1624
1622
  "policy",
1625
1623
  "implementation_choice",
1626
- // Coding intelligence domain
1627
1624
  "implementation_decision",
1628
1625
  "interface_contract",
1629
1626
  "migration_state",
@@ -1631,25 +1628,16 @@ var BUILTIN_ENUM_FALLBACK = {
1631
1628
  "deprecation_notice"
1632
1629
  ]),
1633
1630
  edge_type: /* @__PURE__ */ new Set([
1634
- // === 6 CANONICAL EPISTEMIC TYPES ===
1635
1631
  "supports",
1636
- // L3↔L3: belief bears on belief (weight -1 to +1)
1637
1632
  "informs",
1638
- // L2→L3: evidence bears on belief
1639
1633
  "depends_on",
1640
- // L3→L3, Q→Q: structural gate
1641
1634
  "derived_from",
1642
- // Any→Any: provenance chain
1643
1635
  "contains",
1644
- // Any→Any: hierarchy, scoping, membership
1645
1636
  "tests",
1646
- // Q→L3: question interrogates belief
1647
- // === STRUCTURAL / LIFECYCLE ===
1648
1637
  "supersedes",
1649
1638
  "responds_to",
1650
1639
  "belongs_to",
1651
1640
  "relates_to_thesis",
1652
- // === ONTOLOGICAL (tenant-extensible) ===
1653
1641
  "works_at",
1654
1642
  "invested_in",
1655
1643
  "competes_with",
@@ -1698,27 +1686,12 @@ var BUILTIN_ENUM_FALLBACK = {
1698
1686
  function normalizeEnumValue(value) {
1699
1687
  return value.trim().toLowerCase();
1700
1688
  }
1701
- async function validateSchemaEnumValue(ctx, args) {
1689
+ async function validateSchemaEnumValue(_ctx, args) {
1702
1690
  const normalized = normalizeEnumValue(args.value);
1703
1691
  if (!normalized) {
1704
1692
  return { valid: false, source: "none" };
1705
1693
  }
1706
- try {
1707
- const validFromSchema = await ctx.runQuery(
1708
- internal2.schemaConfig.internalValidate,
1709
- {
1710
- category: args.category,
1711
- value: normalized,
1712
- tenantId: args.tenantId
1713
- }
1714
- );
1715
- if (validFromSchema) {
1716
- return { valid: true, source: "schema" };
1717
- }
1718
- } catch {
1719
- }
1720
- const fallback = BUILTIN_ENUM_FALLBACK[args.category];
1721
- if (fallback.has(normalized)) {
1694
+ if (BUILTIN_ENUM_FALLBACK[args.category].has(normalized)) {
1722
1695
  return { valid: true, source: "builtin" };
1723
1696
  }
1724
1697
  return { valid: false, source: "none" };
@@ -1739,7 +1712,7 @@ async function assertSchemaEnumValue(ctx, args) {
1739
1712
  if (!validation.valid) {
1740
1713
  const tenantHint = args.tenantId ? ` for tenant ${args.tenantId}` : "";
1741
1714
  throw new Error(
1742
- `[${args.context}] Invalid value "${normalized}" for category "${args.category}"${tenantHint}. Add it to schemaEnumConfig before use.`
1715
+ `[${args.context}] Invalid value "${normalized}" for category "${args.category}"${tenantHint}. Add it to the contracts schema enum manifest before use.`
1743
1716
  );
1744
1717
  }
1745
1718
  return normalized;
@@ -1761,30 +1734,30 @@ var RESOLVED_PREDICTION_OUTCOMES = [
1761
1734
  function isBeliefLifecycleStatus(value) {
1762
1735
  return typeof value === "string" && BELIEF_STATUS_VALUES.includes(value);
1763
1736
  }
1764
- function normalizeBeliefConfidence(confidence2) {
1765
- if (typeof confidence2 !== "number" || !Number.isFinite(confidence2)) {
1737
+ function normalizeBeliefConfidence(confidence) {
1738
+ if (typeof confidence !== "number" || !Number.isFinite(confidence)) {
1766
1739
  return null;
1767
1740
  }
1768
- if (confidence2 >= 0 && confidence2 <= 1) {
1769
- return confidence2;
1741
+ if (confidence >= 0 && confidence <= 1) {
1742
+ return confidence;
1770
1743
  }
1771
- if (confidence2 > 1 && confidence2 <= 100) {
1772
- return confidence2 / 100;
1744
+ if (confidence > 1 && confidence <= 100) {
1745
+ return confidence / 100;
1773
1746
  }
1774
1747
  return null;
1775
1748
  }
1776
- function isResolvedByConfidence(confidence2) {
1777
- const normalized = normalizeBeliefConfidence(confidence2);
1749
+ function isResolvedByConfidence(confidence) {
1750
+ const normalized = normalizeBeliefConfidence(confidence);
1778
1751
  if (normalized === null) {
1779
1752
  return false;
1780
1753
  }
1781
1754
  return normalized <= 0 || normalized >= 1;
1782
1755
  }
1783
- function hasResolvedPredictionOutcome(predictionMeta2) {
1784
- if (!predictionMeta2 || typeof predictionMeta2 !== "object") {
1756
+ function hasResolvedPredictionOutcome(predictionMeta) {
1757
+ if (!predictionMeta || typeof predictionMeta !== "object") {
1785
1758
  return false;
1786
1759
  }
1787
- const outcome = predictionMeta2.outcome;
1760
+ const outcome = predictionMeta.outcome;
1788
1761
  return typeof outcome === "string" && RESOLVED_PREDICTION_OUTCOMES.includes(outcome);
1789
1762
  }
1790
1763
  function getPredictionMetaFromMetadata(metadata) {
@@ -2115,567 +2088,31 @@ function getTraversalDirections(direction) {
2115
2088
  }
2116
2089
  return ["outgoing", "incoming"];
2117
2090
  }
2118
- v.number();
2119
- v.union(
2120
- v.literal("very_high"),
2121
- // 0.9+
2122
- v.literal("high"),
2123
- // 0.7-0.9
2124
- v.literal("medium"),
2125
- // 0.4-0.7
2126
- v.literal("low"),
2127
- // 0.2-0.4
2128
- v.literal("very_low")
2129
- // 0-0.2
2130
- );
2131
- v.union(
2132
- v.literal(1),
2133
- // Critical
2134
- v.literal(2),
2135
- // High
2136
- v.literal(3),
2137
- // Medium
2138
- v.literal(4),
2139
- // Low
2140
- v.literal(5)
2141
- // Backlog
2142
- );
2143
- v.union(
2144
- v.literal("critical"),
2145
- v.literal("high"),
2146
- v.literal("medium"),
2147
- v.literal("low"),
2148
- v.literal("backlog")
2149
- );
2150
- v.union(
2151
- v.literal("active"),
2152
- v.literal("paused"),
2153
- v.literal("completed"),
2154
- v.literal("archived")
2155
- );
2156
- v.union(
2157
- v.literal("pending"),
2158
- v.literal("processing"),
2159
- v.literal("completed"),
2160
- v.literal("failed")
2161
- );
2162
- v.object({
2163
- crunchbaseId: v.optional(v.string()),
2164
- linkedinUrl: v.optional(v.string()),
2165
- pitchbookId: v.optional(v.string()),
2166
- twitterUrl: v.optional(v.string()),
2167
- domain: v.optional(v.string())
2168
- });
2169
- var sourceType = v.union(
2170
- v.literal("proprietary"),
2171
- // Internal Stack research
2172
- v.literal("primary"),
2173
- // Direct interviews, calls
2174
- v.literal("secondary"),
2175
- // Published sources
2176
- v.literal("ai_generated"),
2177
- // AI-synthesized
2178
- v.literal("user_input"),
2179
- // Manual user entry
2180
- v.literal("inferred")
2181
- // System inference
2182
- );
2183
- v.object({
2184
- sourceType: v.optional(sourceType),
2185
- sourceId: v.optional(v.string()),
2186
- // Reference to source entity
2187
- sourceUrl: v.optional(v.string()),
2188
- sourceDate: v.optional(v.number()),
2189
- sourceName: v.optional(v.string())
2190
- });
2191
- v.object({
2192
- cursor: v.optional(v.string()),
2193
- limit: v.optional(v.number())
2194
- });
2195
- v.object({
2196
- hasMore: v.boolean(),
2197
- nextCursor: v.optional(v.string()),
2198
- totalCount: v.optional(v.number())
2199
- });
2200
- var richTextContent = v.object({
2201
- type: v.literal("doc"),
2202
- content: looseJsonArray
2203
- });
2204
- v.union(v.string(), richTextContent);
2205
- v.object({
2206
- promptTokens: v.optional(v.number()),
2207
- completionTokens: v.optional(v.number()),
2208
- totalTokens: v.optional(v.number())
2209
- });
2210
- v.object({
2211
- fileName: v.optional(v.string()),
2212
- fileSize: v.optional(v.number()),
2213
- mimeType: v.optional(v.string()),
2214
- storageId: v.optional(v.id("_storage")),
2215
- externalUrl: v.optional(v.string())
2216
- });
2217
2091
 
2218
- // ../schema-management/src/spine/tables/epistemicNodes.ts
2219
- var nodeType = v.union(
2220
- // --- L4: Audit Targets (decisions, outcomes) ---
2221
- v.literal("decision"),
2222
- // Investment decision with knowledge horizon snapshot
2223
- // --- L3: Traversal Anchors (epistemic structure) ---
2224
- v.literal("belief"),
2225
- // Structured conviction (immutable formulation)
2226
- v.literal("question"),
2227
- // Unit of uncertainty
2228
- v.literal("theme"),
2229
- // Investment thesis / conviction cluster
2230
- v.literal("deal"),
2231
- // Investment evaluation process
2232
- v.literal("topic"),
2233
- // Hierarchical knowledge container
2234
- // --- L2: Compression Boundary (minimum reasoning unit) ---
2235
- v.literal("claim"),
2236
- // Atomic assertion that can be true/false
2237
- v.literal("evidence"),
2238
- // Interpreted signal linked to beliefs
2239
- v.literal("synthesis"),
2240
- // Primers, deep research
2241
- v.literal("answer"),
2242
- // Immutable answer snapshot for a question
2243
- // --- L1: Terminal Leaves (non-traversable, grounding) ---
2244
- v.literal("atomic_fact"),
2245
- // Raw fact from source (not interpreted)
2246
- v.literal("excerpt"),
2247
- // Direct quote from source document
2248
- v.literal("source"),
2249
- // News, documents, transcripts
2250
- // --- Ontological Entities (things in the world) ---
2251
- v.literal("company"),
2252
- // Organization (subtype: private, corporate, portfolio)
2253
- v.literal("person"),
2254
- // Individual (founder, expert, LP, contact)
2255
- v.literal("investor"),
2256
- // Investment entity (subtype: vc, lp, cvc, pe, family_office, angel)
2257
- v.literal("function"),
2258
- // What a company does (from classifier)
2259
- v.literal("value_chain")
2260
- // Market structure / value flow
2261
- );
2262
- var epistemicLayer = v.union(
2263
- v.literal("L4"),
2264
- // Decisions, outcomes - audit targets
2265
- v.literal("L3"),
2266
- // Beliefs, questions, themes - traversal anchors
2267
- v.literal("L2"),
2268
- // Claims, evidence, synthesis - compression boundary
2269
- v.literal("L1"),
2270
- // Atomic facts, excerpts, sources - terminal leaves
2271
- v.literal("ontological"),
2272
- // Companies, people, etc - not epistemic
2273
- v.literal("organizational")
2274
- // Topics, lenses, worktrees — structural containers
2275
- );
2276
- var nodeStatus = v.union(
2277
- v.literal("active"),
2278
- v.literal("superseded"),
2279
- // Replaced by newer version
2280
- v.literal("archived"),
2281
- v.literal("deleted")
2282
- );
2283
- var sourceType2 = v.union(
2284
- v.literal("human"),
2285
- // User created directly
2286
- v.literal("ai_extracted"),
2287
- // LLM extracted from a source
2288
- v.literal("ai_generated"),
2289
- // LLM synthesized/created
2290
- v.literal("imported"),
2291
- // External system import
2292
- v.literal("system"),
2293
- // System-generated (migrations, classifiers)
2294
- v.literal("verified"),
2295
- // Human-verified source
2296
- v.literal("proprietary")
2297
- // Proprietary/internal data
2298
- );
2299
- var verificationStatus = v.union(
2300
- v.literal("unverified"),
2301
- v.literal("human_verified"),
2302
- v.literal("ai_verified"),
2303
- v.literal("contradicted"),
2304
- v.literal("outdated")
2305
- );
2306
- var syncStatus = v.union(
2307
- v.literal("synced"),
2308
- // Node and edges fully synced to Neo4j
2309
- v.literal("pending_edges"),
2310
- // Node created, edges being created
2311
- v.literal("edge_creation_failed")
2312
- // Edge creation failed, needs retry
2313
- );
2314
- var audienceLabel = v.string();
2315
- var sensitivityTier = v.union(
2316
- v.literal("low"),
2317
- v.literal("medium"),
2318
- v.literal("high"),
2319
- v.literal("restricted")
2320
- );
2321
- var exportClass = v.union(
2322
- v.literal("internal_only"),
2323
- v.literal("client_safe"),
2324
- v.literal("public_safe"),
2325
- v.literal("restricted")
2326
- );
2327
- var anonymizationClass = v.union(
2328
- v.literal("none"),
2329
- v.literal("standard"),
2330
- v.literal("strict")
2331
- );
2332
- var epistemicStatus = v.union(
2333
- v.literal("hypothesis"),
2334
- // Initial conjecture, low evidence
2335
- v.literal("emerging"),
2336
- // Building evidence, gaining traction
2337
- v.literal("established"),
2338
- // Well-evidenced, core to thesis
2339
- v.literal("challenged"),
2340
- // Contradicting evidence appeared
2341
- v.literal("assumption"),
2342
- // Taken as given, not actively tested
2343
- v.literal("deprecated")
2344
- // Superseded or abandoned
2345
- );
2346
- var beliefStatus = v.union(
2347
- v.literal("assumption"),
2348
- v.literal("hypothesis"),
2349
- v.literal("belief"),
2350
- v.literal("fact")
2351
- );
2352
- var reversibility = v.union(
2353
- v.literal("irreversible"),
2354
- // One-way door decision
2355
- v.literal("hard_to_reverse"),
2356
- // Significant cost to undo
2357
- v.literal("reversible"),
2358
- // Can change course with moderate effort
2359
- v.literal("trivial")
2360
- // Easy to adjust
2361
- );
2362
- var predictionOutcome = v.union(
2363
- v.literal("pending"),
2364
- v.literal("confirmed"),
2365
- v.literal("disconfirmed"),
2366
- v.literal("partial"),
2367
- v.literal("expired")
2368
- );
2369
- var predictionMeta = v.object({
2370
- isPrediction: v.boolean(),
2371
- registeredAt: v.number(),
2372
- // When prediction was made
2373
- expectedBy: v.optional(v.number()),
2374
- // When we expect resolution
2375
- outcome: v.optional(predictionOutcome),
2376
- outcomeRecordedAt: v.optional(v.number()),
2377
- outcomeEvidenceId: v.optional(v.string()),
2378
- // globalId of confirming evidence
2379
- confidenceAtPrediction: v.optional(v.number()),
2380
- // 0-1
2381
- actualVsPredicted: v.optional(v.string())
2382
- // Notes on how outcome compared
2383
- });
2384
- var methodology = v.union(
2385
- // Primary Research (high value)
2386
- v.literal("primary_research"),
2387
- // Direct investigation
2388
- v.literal("expert_interview"),
2389
- // Expert call/interview
2390
- v.literal("customer_interview"),
2391
- // Customer research
2392
- v.literal("field_observation"),
2393
- // On-site observation
2394
- v.literal("proprietary_data"),
2395
- // Internal data analysis
2396
- // Secondary Research
2397
- v.literal("desk_research"),
2398
- // Public sources
2399
- v.literal("regulatory_filing"),
2400
- // SEC, regulatory docs
2401
- v.literal("news_article"),
2402
- // News/press
2403
- v.literal("academic_paper"),
2404
- // Academic research
2405
- // AI-Assisted
2406
- v.literal("ai_synthesis"),
2407
- // AI-generated synthesis
2408
- v.literal("ai_extraction")
2409
- // AI-extracted from source
2410
- );
2411
- var informationAsymmetry = v.union(
2412
- v.literal("proprietary"),
2413
- // Only we have this
2414
- v.literal("early"),
2415
- // We're early but others will get it
2416
- v.literal("common")
2417
- // Everyone has access
2418
- );
2419
- var temporalNature = v.union(
2420
- v.literal("factual"),
2421
- // Resolved outcome. Grounded in reality.
2422
- v.literal("forecast"),
2423
- // Prediction. Will resolve. Discounted weight.
2424
- v.literal("unknown")
2425
- // Not yet classified.
2426
- );
2427
- var questionType = v.union(
2428
- v.literal("validation"),
2429
- // Does evidence support this belief?
2430
- v.literal("falsification"),
2431
- // What would prove this belief wrong?
2432
- v.literal("assumption_probe"),
2433
- // Is this unstated assumption true?
2434
- v.literal("prediction_test"),
2435
- // Will this predicted outcome occur?
2436
- v.literal("counterfactual"),
2437
- // What would we expect if X were false?
2438
- v.literal("discovery"),
2439
- // What don't we know yet?
2440
- v.literal("clarification"),
2441
- // What does X actually mean?
2442
- v.literal("comparison"),
2443
- // How does X compare to Y?
2444
- v.literal("causal"),
2445
- // What caused X?
2446
- v.literal("mechanism"),
2447
- // How does X work?
2448
- v.literal("general")
2449
- // Unclassified
2450
- );
2451
- var questionPriority = v.union(
2452
- v.literal("critical"),
2453
- // Blocks decision-making
2454
- v.literal("high"),
2455
- // Important for thesis
2456
- v.literal("medium"),
2457
- // Would be nice to know
2458
- v.literal("low")
2459
- // Background/curiosity
2460
- );
2461
- var answerQuality = v.union(
2462
- v.literal("definitive"),
2463
- // Clear, well-supported
2464
- v.literal("strong"),
2465
- // Good evidence, high confidence
2466
- v.literal("moderate"),
2467
- // Some evidence
2468
- v.literal("weak"),
2469
- // Limited evidence
2470
- v.literal("speculative"),
2471
- // Mostly conjecture
2472
- v.literal("unanswered")
2473
- // No answer yet
2474
- );
2475
- var consensusView = v.union(
2476
- v.literal("aligned"),
2477
- // We agree with market consensus
2478
- v.literal("ahead_of"),
2479
- // We see this before consensus does
2480
- v.literal("contrarian"),
2481
- // We actively disagree with consensus
2482
- v.literal("orthogonal"),
2483
- // We're looking at something consensus isn't discussing
2484
- v.literal("unknown")
2485
- // We don't know what consensus thinks
2486
- );
2487
- var themeConviction = v.union(
2488
- v.literal("high"),
2489
- // Strong conviction, actively deploying
2490
- v.literal("medium"),
2491
- // Building conviction
2492
- v.literal("low"),
2493
- // Exploring, not convicted
2494
- v.literal("negative")
2495
- // Actively avoiding
2496
- );
2497
- var decisionType = v.union(
2498
- v.literal("invest"),
2499
- v.literal("pass"),
2500
- v.literal("follow_on"),
2501
- v.literal("exit"),
2502
- v.literal("deep_dive"),
2503
- v.literal("monitor"),
2504
- v.literal("deprioritize"),
2505
- v.literal("thesis_adopt"),
2506
- v.literal("thesis_revise"),
2507
- v.literal("thesis_abandon")
2508
- );
2509
- var decisionOutcome = v.union(
2510
- v.literal("pending"),
2511
- v.literal("successful"),
2512
- v.literal("unsuccessful"),
2513
- v.literal("mixed"),
2514
- v.literal("unknown")
2515
- );
2516
- var externalIds2 = v.object({
2517
- crunchbase: v.optional(v.string()),
2518
- linkedin: v.optional(v.string()),
2519
- pitchbook: v.optional(v.string()),
2520
- twitter: v.optional(v.string()),
2521
- website: v.optional(v.string())
2522
- });
2523
- defineTable({
2524
- // === IDENTITY ===
2525
- globalId: v.string(),
2526
- // UUID - survives migration to Neo4j
2527
- // === TYPE ===
2528
- nodeType,
2529
- // === EPISTEMIC LAYER ===
2530
- epistemicLayer: v.optional(epistemicLayer),
2531
- // === SUBTYPE (for typed entities) ===
2532
- subtype: v.optional(v.string()),
2533
- // company: private|corporate|portfolio, investor: vc|lp|cvc|pe|family_office|angel
2534
- // === CONTENT ===
2535
- canonicalText: v.string(),
2536
- // The core content (belief statement, company name, etc.)
2537
- contentHash: v.string(),
2538
- // SHA256(nodeType + canonicalText) for deduplication
2539
- // Extended content (for sources/syntheses)
2540
- content: v.optional(v.string()),
2541
- // Full text for documents/articles
2542
- contentType: v.optional(v.string()),
2543
- // "markdown", "html", "pdf", "text"
2544
- // === METADATA ===
2545
- title: v.optional(v.string()),
2546
- // Display title
2547
- tags: v.optional(v.array(v.string())),
2548
- domain: v.optional(v.string()),
2549
- // For companies: website domain
2550
- // Type-specific metadata (flexible object - LEGACY)
2551
- // New code should use the typed fields below when available
2552
- metadata: v.optional(looseJsonObject),
2553
- // === POLICY / ENTITLEMENT ===
2554
- tenantId: v.optional(v.string()),
2555
- workspaceId: v.optional(v.string()),
2556
- ownerPrincipalId: v.optional(v.string()),
2557
- audienceLabel: v.optional(audienceLabel),
2558
- policyTags: v.optional(v.array(v.string())),
2559
- sensitivityTier: v.optional(sensitivityTier),
2560
- exportClass: v.optional(exportClass),
2561
- anonymizationClass: v.optional(anonymizationClass),
2562
- // === PUBLICATION (visibility-based, not copy-based) ===
2563
- // Publication expands who can see a workspace-local node — the node stays
2564
- // in its workspace, like a microservice exposing part of its API surface.
2565
- // Rules-based: pack/tenant-level publicationRules auto-evaluate on
2566
- // confidence changes and node creation. No manual click-by-click.
2567
- publicationStatus: v.optional(
2568
- v.union(
2569
- v.literal("unpublished"),
2570
- // Default: workspace-local only
2571
- v.literal("published"),
2572
- // Visible at tenant scope (rules matched)
2573
- v.literal("suppressed")
2574
- // Manually blocked even if rules match
2575
- )
2576
- ),
2577
- publishedAt: v.optional(v.number()),
2578
- // When publication status last changed to published
2579
- publishedBy: v.optional(v.string()),
2580
- // userId or "system:publication_rules" for auto-publish
2581
- // === TYPED METADATA FIELDS ===
2582
- // --- Belief ---
2583
- // Belief type — validated against schemaEnumConfig category "belief_type"
2584
- // Platform core: hypothesis, belief, principle, invariant, assumption,
2585
- // tenet, prior, preference, goal, forecast
2586
- beliefType: v.optional(v.string()),
2587
- beliefStatus: v.optional(beliefStatus),
2588
- epistemicStatus: v.optional(epistemicStatus),
2589
- reversibility: v.optional(reversibility),
2590
- predictionMeta: v.optional(predictionMeta),
2591
- // Consensus tracking (for non-consensus detection)
2592
- consensusView: v.optional(consensusView),
2593
- consensusConfidence: v.optional(v.number()),
2594
- // 0-1: What we think consensus confidence is
2595
- consensusSource: v.optional(v.string()),
2596
- // Where we got the consensus view (twitter, reports, etc.)
2597
- // --- Evidence ---
2598
- methodology: v.optional(methodology),
2599
- informationAsymmetry: v.optional(informationAsymmetry),
2600
- temporalNature: v.optional(temporalNature),
2601
- // --- Question ---
2602
- questionType: v.optional(questionType),
2603
- questionPriority: v.optional(questionPriority),
2604
- answerQuality: v.optional(answerQuality),
2605
- // --- Theme ---
2606
- themeConviction: v.optional(themeConviction),
2607
- // Market timing (for "early on theme" detection)
2608
- marketAwarenessDate: v.optional(v.number()),
2609
- // When this theme became broadly discussed
2610
- marketAwarenessSource: v.optional(v.string()),
2611
- // How we know (first major report, twitter volume spike, etc.)
2612
- earlySignalIds: v.optional(v.array(v.string())),
2613
- // globalIds of evidence we had before market awareness
2614
- // --- Decision ---
2615
- decisionType: v.optional(decisionType),
2616
- decisionOutcome: v.optional(decisionOutcome),
2617
- // === EXTERNAL IDS (for ontological entities) ===
2618
- externalIds: v.optional(externalIds2),
2619
- // === PROVENANCE ===
2620
- sourceType: sourceType2,
2621
- aiProvider: v.optional(v.string()),
2622
- // "claude", "gemini", "gpt-4", etc.
2623
- extractedFromNodeId: v.optional(v.id("epistemicNodes")),
2624
- // Quick reference to source
2625
- // === EXTRACTION CONTEXT ===
2626
- extractionModel: v.optional(v.string()),
2627
- // "claude-sonnet-4-20250514"
2628
- extractionPromptName: v.optional(v.string()),
2629
- // "lucern/extract-evidence"
2630
- extractionPromptVersion: v.optional(v.number()),
2631
- extractionTemperature: v.optional(v.number()),
2632
- extractionLangfuseTraceId: v.optional(v.string()),
2633
- // === GROUNDING VERIFICATION ===
2634
- groundingVerified: v.optional(v.boolean()),
2635
- groundingConfidence: v.optional(v.number()),
2636
- // 0-1 match quality
2637
- groundingMatchedText: v.optional(v.string()),
2638
- // Actual text from source
2639
- groundingStartOffset: v.optional(v.number()),
2640
- groundingEndOffset: v.optional(v.number()),
2641
- groundingRejectionReason: v.optional(v.string()),
2642
- // === CONFIDENCE & VERIFICATION ===
2643
- confidence: v.optional(v.number()),
2644
- // 0-1 projected probability P(x) = b + a*u
2645
- verificationStatus: v.optional(verificationStatus),
2646
- // === SL OPINION (Subjective Logic — Kernel v2) ===
2647
- // Replaces scalar confidence with rich epistemic state.
2648
- // b + d + u = 1. P(x) = b + a*u is stored in `confidence` for backward compat.
2649
- opinion_b: v.optional(v.number()),
2650
- // Belief: evidence FOR (0-1)
2651
- opinion_d: v.optional(v.number()),
2652
- // Disbelief: evidence AGAINST (0-1)
2653
- opinion_u: v.optional(v.number()),
2654
- // Uncertainty: absence of evidence (0-1)
2655
- opinion_a: v.optional(v.number()),
2656
- // Base rate / prior probability (0-1)
2657
- tupleContradicted: v.optional(v.boolean()),
2658
- // Single-belief tuple-space contradiction flag
2659
- // === LIFECYCLE ===
2660
- status: nodeStatus,
2661
- supersededBy: v.optional(v.id("epistemicNodes")),
2662
- // === OWNERSHIP ===
2663
- topicId: v.optional(v.string()),
2664
- // Canonical scope container (topic-first model)
2665
- projectId: v.optional(v.string()),
2666
- // DEPRECATED: Use belongs_to edges
2667
- createdBy: v.string(),
2668
- // Clerk user ID
2669
- createdAt: v.number(),
2670
- updatedAt: v.number(),
2671
- // === NEO4J SYNC STATUS ===
2672
- syncStatus: v.optional(syncStatus),
2673
- syncError: v.optional(v.string())
2674
- // Error message if sync failed
2675
- }).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", {
2676
- searchField: "canonicalText",
2677
- filterFields: ["nodeType", "projectId", "topicId", "status"]
2678
- });
2092
+ // ../../packages/contracts/src/schema-helpers/spine/tables/epistemicNodes.ts
2093
+ var NODE_TYPES = [
2094
+ "decision",
2095
+ "belief",
2096
+ "question",
2097
+ "theme",
2098
+ "deal",
2099
+ "topic",
2100
+ "claim",
2101
+ "evidence",
2102
+ "synthesis",
2103
+ "answer",
2104
+ "atomic_fact",
2105
+ "excerpt",
2106
+ "source",
2107
+ "company",
2108
+ "person",
2109
+ "investor",
2110
+ "function",
2111
+ "value_chain"
2112
+ ];
2113
+ function isNodeType(value) {
2114
+ return NODE_TYPES.includes(value);
2115
+ }
2679
2116
  function getLayerForNodeType(type) {
2680
2117
  switch (type) {
2681
2118
  case "decision":
@@ -2909,7 +2346,7 @@ function throwWorkspaceIsolationError(args) {
2909
2346
  throw error;
2910
2347
  }
2911
2348
  function assertWorkspaceScopedEpistemicNodeScope(args) {
2912
- const layer = getLayerForNodeType(args.nodeType);
2349
+ const layer = isNodeType(args.nodeType) ? getLayerForNodeType(args.nodeType) : void 0;
2913
2350
  if (layer === "ontological") {
2914
2351
  return;
2915
2352
  }
@@ -2937,11 +2374,11 @@ function nodeMatchesWorkspaceReasoningScope(node, scope) {
2937
2374
  const scopeWorkspaceId = normalizeScopeValue2(scope.workspaceId);
2938
2375
  const nodeTenantId = normalizeScopeValue2(node.tenantId);
2939
2376
  const nodeWorkspaceId = normalizeScopeValue2(node.workspaceId);
2940
- const epistemicLayer2 = typeof node.epistemicLayer === "string" ? node.epistemicLayer : void 0;
2377
+ const epistemicLayer = typeof node.epistemicLayer === "string" ? node.epistemicLayer : void 0;
2941
2378
  if (scopeTenantId && nodeTenantId && scopeTenantId !== nodeTenantId) {
2942
2379
  return false;
2943
2380
  }
2944
- if (epistemicLayer2 === "ontological" && nodeWorkspaceId === void 0) {
2381
+ if (epistemicLayer === "ontological" && nodeWorkspaceId === void 0) {
2945
2382
  return true;
2946
2383
  }
2947
2384
  if (!scopeWorkspaceId && node.publicationStatus === "published") {
@@ -2969,11 +2406,11 @@ function edgeMatchesWorkspaceReasoningScope(edge, scope) {
2969
2406
  return scopeWorkspaceId === edgeWorkspaceId;
2970
2407
  }
2971
2408
  async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
2972
- const epistemicLayer2 = typeof node?.epistemicLayer === "string" ? node.epistemicLayer : void 0;
2409
+ const epistemicLayer = typeof node?.epistemicLayer === "string" ? node.epistemicLayer : void 0;
2973
2410
  const resolved = {
2974
2411
  tenantId: normalizeScopeValue2(node?.tenantId),
2975
2412
  workspaceId: normalizeScopeValue2(node?.workspaceId),
2976
- epistemicLayer: epistemicLayer2,
2413
+ epistemicLayer,
2977
2414
  nodeType: typeof node?.nodeType === "string" ? node.nodeType : void 0
2978
2415
  };
2979
2416
  if (!node) {
@@ -3623,10 +3060,10 @@ function deriveSyntheticBackfillOpinion(source) {
3623
3060
  a: 0.5
3624
3061
  });
3625
3062
  }
3626
- const confidence2 = clamp012(readFiniteNumber(source.confidence) ?? 0);
3063
+ const confidence = clamp012(readFiniteNumber(source.confidence) ?? 0);
3627
3064
  return {
3628
- b: confidence2,
3629
- d: 1 - confidence2,
3065
+ b: confidence,
3066
+ d: 1 - confidence,
3630
3067
  u: 0,
3631
3068
  a: 0.5
3632
3069
  };
@@ -3670,10 +3107,10 @@ function formatTupleContradictionDescription(args) {
3670
3107
  return `Tuple-space contradiction detected: b=${args.opinion.b.toFixed(2)} > ${args.policy.beliefThreshold.toFixed(2)} and d=${args.opinion.d.toFixed(2)} > ${args.policy.disbeliefThreshold.toFixed(2)}.`;
3671
3108
  }
3672
3109
  function generateContentHash(text) {
3673
- const content2 = `belief:${text.trim().toLowerCase().replace(/\s+/g, " ")}`;
3110
+ const content = `belief:${text.trim().toLowerCase().replace(/\s+/g, " ")}`;
3674
3111
  let hash = 5381;
3675
- for (let i = 0; i < content2.length; i++) {
3676
- hash = (hash << 5) + hash + content2.charCodeAt(i);
3112
+ for (let i = 0; i < content.length; i++) {
3113
+ hash = (hash << 5) + hash + content.charCodeAt(i);
3677
3114
  hash &= hash;
3678
3115
  }
3679
3116
  return Math.abs(hash).toString(16).padStart(8, "0");
@@ -3750,8 +3187,8 @@ async function resolveBeliefScopeOrNull(ctx, args) {
3750
3187
  }
3751
3188
  async function getBeliefNodesForScope(ctx, scope, args) {
3752
3189
  const baseQuery = ctx.db.query("epistemicNodes").withIndex(
3753
- scope.topicId ? "by_topic_type" : "by_project_type",
3754
- (q) => scope.topicId ? q.eq("topicId", scope.topicId).eq("nodeType", "belief") : q.eq("projectId", scope.projectId).eq("nodeType", "belief")
3190
+ "by_topic_type",
3191
+ (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
3755
3192
  );
3756
3193
  const nodes = typeof args?.scanLimit === "number" ? await baseQuery.order("desc").take(args.scanLimit) : await baseQuery.collect();
3757
3194
  const scopedNodes = nodes.filter(
@@ -3902,7 +3339,7 @@ async function applyBeliefConfidenceChange(ctx, args) {
3902
3339
  }
3903
3340
  }
3904
3341
  const previousConfidence = node.confidence || 0.5;
3905
- const predictionMeta2 = node.predictionMeta || existingMetadata.predictionMeta;
3342
+ const predictionMeta = node.predictionMeta || existingMetadata.predictionMeta;
3906
3343
  const previousOpinion = readBeliefOpinionSnapshot(node, existingMetadata);
3907
3344
  const slB = args.belief;
3908
3345
  const slD = args.disbelief;
@@ -3929,7 +3366,7 @@ async function applyBeliefConfidenceChange(ctx, args) {
3929
3366
  currentBeliefStatus,
3930
3367
  {
3931
3368
  confidence: derivedConfidence,
3932
- predictionMeta: predictionMeta2,
3369
+ predictionMeta,
3933
3370
  metadata: existingMetadata
3934
3371
  }
3935
3372
  );
@@ -4583,8 +4020,8 @@ query({
4583
4020
  }
4584
4021
  }
4585
4022
  const query2 = ctx.db.query("epistemicNodes").withIndex(
4586
- scope.topicId ? "by_topic_type" : "by_project_type",
4587
- (q) => scope.topicId ? q.eq("topicId", scope.topicId).eq("nodeType", "belief") : q.eq("projectId", scope.projectId).eq("nodeType", "belief")
4023
+ "by_topic_type",
4024
+ (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
4588
4025
  );
4589
4026
  const nodes = await query2.order("desc").take(scanLimit);
4590
4027
  const scopedNodes = nodes.filter(
@@ -5222,9 +4659,13 @@ query({
5222
4659
  },
5223
4660
  returns: permissiveReturn,
5224
4661
  handler: async (ctx, args) => {
4662
+ const scope = await resolveBeliefScopeOrNull(ctx, args);
4663
+ if (!scope) {
4664
+ return { active: 0, superseded: 0, archived: 0, total: 0 };
4665
+ }
5225
4666
  const nodes = await ctx.db.query("epistemicNodes").withIndex(
5226
- args.topicId ? "by_topic_type" : "by_project_type",
5227
- (q) => args.topicId ? q.eq("topicId", args.topicId).eq("nodeType", "belief") : q.eq("projectId", args.projectId).eq("nodeType", "belief")
4667
+ "by_topic_type",
4668
+ (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
5228
4669
  ).collect();
5229
4670
  const counts = {
5230
4671
  active: 0,
@@ -5789,8 +5230,8 @@ query({
5789
5230
  return [];
5790
5231
  }
5791
5232
  const nodes = await ctx.db.query("epistemicNodes").withIndex(
5792
- scope.topicId ? "by_topic_type" : "by_project_type",
5793
- (q) => scope.topicId ? q.eq("topicId", scope.topicId).eq("nodeType", "belief") : q.eq("projectId", scope.projectId).eq("nodeType", "belief")
5233
+ "by_topic_type",
5234
+ (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
5794
5235
  ).collect();
5795
5236
  return nodes.filter((n) => {
5796
5237
  const metadata = n.metadata;