{"templateId":"markdown","sharedDataIds":{},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Osmosis Use Case Analysis: Papr Capability Assessment","siteUrl":"https://platform.papr.ai","description":"Papr Memory is an AI-native memory layer that lets developers add production-ready memory to their AI agents and apps with just a few lines of code."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"osmosis-use-case-analysis-papr-capability-assessment"},"children":["Osmosis Use Case Analysis: Papr Capability Assessment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Date:"]}," February 16, 2026",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Developer:"]}," Osmosis Project",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Use Case:"]}," Documentary knowledge governance with evidence-anchored claims"]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"executive-summary"},"children":["Executive Summary"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Can the developer use Papr for their use case?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["YES - with custom schema design"]},", but they'll need to build governance logic on top."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key Finding:"]}," Papr provides a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["strong foundation"]}," for the storage, retrieval, and relationship-tracking layer. However, the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["epistemological tracking"]}," (conflict detection, corroboration scoring, temporal versioning) requires custom application logic built on top of Papr's primitives."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Recommendation:"]}," Use Papr as the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["knowledge graph + retrieval engine"]},", build ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Osmosis governance layer"]}," on top using custom schemas and GraphQL analytics."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"understanding-the-osmosis-system"},"children":["Understanding the Osmosis System"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"core-mission"},"children":["Core Mission"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Building a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["documentary knowledge governance system"]}," focused on:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Evidence-anchored claims"]}," - Assertions tied to specific source evidence"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cross-document validation"]}," - Detecting conflicts and corroboration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Structured knowledge"]}," - Not just retrieval, but epistemological tracking"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"philosophical-approach"},"children":["Philosophical Approach"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is fundamentally about ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["knowledge provenance and confidence"]},":"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["What do we know?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["How confident are we?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Where did it come from?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Does it conflict with other sources?"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["How has our understanding evolved over time?"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"the-5-questions---detailed-analysis"},"children":["The 5 Questions - Detailed Analysis"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"question-1-handling-conflicting-statements"},"children":["Question 1: Handling Conflicting Statements"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["\"How does Papr handle situations where different documents assert conflicting statements or values?\""]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"what-papr-provides-"},"children":["What Papr Provides ✅"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Automatic Deduplication + Multi-Source Tracking:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you define unique_identifiers in your schema:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"schema = {\n    \"Claim\": {\n        \"properties\": {\n            \"subject\": {\"type\": \"string\"},\n            \"predicate\": {\"type\": \"string\"},\n            \"object\": {\"type\": \"string\"}\n        },\n        \"unique_identifiers\": [\"subject\", \"predicate\", \"object\"]  # Triple-based dedup\n    }\n}\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Papr automatically:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Deduplicates"]}," claims with same (subject, predicate, object)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Creates multiple EXTRACTED_FROM relationships"]}," to different sources"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merges into ONE node"]}," instead of creating duplicates"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example - Same claim from 3 documents:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Document 1: \"Product X costs $100\"\nDocument 2: \"Product X is priced at $100\"  \nDocument 3: \"Product X: $100\"\n\n→ Papr creates ONE Claim node:\n   Claim {subject: \"Product X\", predicate: \"costs\", object: \"$100\"}\n     ← EXTRACTED_FROM → Source: doc_1\n     ← EXTRACTED_FROM → Source: doc_2\n     ← EXTRACTED_FROM → Source: doc_3\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Conflict Detection - Built into GraphQL:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Query automatically shows:\n# 1. All claims for same subject (grouped by Papr's dedup)\n# 2. Count of sources per claim (via EXTRACTED_FROM relationships)\n# 3. Different values (different object values)\n\nquery = \"\"\"\nquery ConflictDetection($subject: String!) {\n  claims(where: { subject: $subject }) {\n    object  # The value\n    sources {  # Auto-counted by Papr\n      document_id\n      version\n      date\n    }\n  }\n}\n\"\"\"\n\nresult = await client.graphql.query(query, {\"subject\": \"Product X\"})\n\n# Returns:\n# Claim 1: object=\"$100\", sources=[doc_1, doc_2, doc_3] (3 sources)\n# Claim 2: object=\"$150\", sources=[doc_4] (1 source)\n# → CONFLICT DETECTED: 2 different values for same subject\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Resolution Logic:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Developer decides resolution strategy:\n# - Count-based: \"Pick claim with most sources\" (3 > 1 → $100 wins)\n# - Freshness: \"Pick claim from most recent document\"\n# - Authority: \"Pick claim from official source\"\n# - Combined: \"Most sources from official docs\"\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["What They Can Build:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Custom schema for Claims\nschema = client.schemas.create(\n    name=\"Osmosis Claims Schema\",\n    node_types={\n        \"Claim\": {\n            \"properties\": {\n                \"statement\": {\"type\": \"string\", \"required\": True},\n                \"subject\": {\"type\": \"string\"},      # \"Product X\"\n                \"predicate\": {\"type\": \"string\"},    # \"costs\"\n                \"object\": {\"type\": \"string\"},       # \"$100\"\n                \"confidence\": {\"type\": \"float\"},\n                \"extracted_at\": {\"type\": \"datetime\"}\n            },\n            \"unique_identifiers\": [\"statement\"]\n        },\n        \"Source\": {\n            \"properties\": {\n                \"document_id\": {\"type\": \"string\", \"required\": True},\n                \"version\": {\"type\": \"string\"},\n                \"page\": {\"type\": \"integer\"},\n                \"section\": {\"type\": \"string\"}\n            }\n        },\n        \"ConflictSet\": {\n            \"properties\": {\n                \"subject\": {\"type\": \"string\"},\n                \"predicate\": {\"type\": \"string\"},\n                \"detected_at\": {\"type\": \"datetime\"},\n                \"resolution_status\": {\"type\": \"string\", \"enum_values\": [\"unresolved\", \"resolved\", \"ignored\"]}\n            }\n        }\n    },\n    relationship_types={\n        \"EXTRACTED_FROM\": {\n            \"allowed_source_types\": [\"Claim\"],\n            \"allowed_target_types\": [\"Source\"]\n        },\n        \"CONFLICTS_WITH\": {\n            \"allowed_source_types\": [\"Claim\"],\n            \"allowed_target_types\": [\"Claim\"]\n        },\n        \"MEMBER_OF\": {\n            \"allowed_source_types\": [\"Claim\"],\n            \"allowed_target_types\": [\"ConflictSet\"]\n        }\n    }\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Conflict Detection Logic (Custom):"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# 1. Extract claims from documents\nclient.memory.add(\n    content=\"Product X costs $100 according to pricing sheet\",\n    memory_policy={\n        \"mode\": \"auto\",\n        \"schema_id\": osmosis_schema_id,\n        \"node_constraints\": [\n            {\n                \"node_type\": \"Claim\",\n                \"set\": {\n                    \"subject\": \"Product X\",\n                    \"predicate\": \"costs\",\n                    \"object\": \"$100\",\n                    \"confidence\": 0.95\n                }\n            }\n        ]\n    }\n)\n\n# 2. Periodic conflict detection service\nasync def detect_conflicts():\n    # Query all claims about same subject+predicate\n    query = \"\"\"\n    query FindPotentialConflicts($subject: String!, $predicate: String!) {\n      claims(where: {\n        subject: $subject,\n        predicate: $predicate\n      }) {\n        id\n        object\n        confidence\n        extracted_from {\n          document_id\n          version\n        }\n      }\n    }\n    \"\"\"\n    \n    result = await client.graphql.query(query, {\"subject\": \"Product X\", \"predicate\": \"costs\"})\n    \n    # Find claims with different objects\n    unique_values = set(claim['object'] for claim in result['claims'])\n    \n    if len(unique_values) > 1:\n        # CONFLICT DETECTED\n        conflict_set_id = create_conflict_set()\n        for claim in result['claims']:\n            link_claim_to_conflict(claim['id'], conflict_set_id)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"gap-analysis-️"},"children":["Gap Analysis ⚠️"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Papr automatically deduplicates"]}," same claim across sources"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Papr tracks all sources"]}," per claim via EXTRACTED_FROM relationships"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["GraphQL can count sources"]}," and compare different values"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Conflict identification"]}," is just: \"same subject, different objects, >1 claim\""]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["⚠️ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Resolution strategy"]}," is custom logic (count-based, freshness, authority)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["⚠️ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["ConflictSet nodes"]}," optional (for tracking resolution workflow)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Verdict:"]}," Papr handles 80% automatically (dedup, multi-source tracking, querying). Developer adds 20% (resolution rules, workflow tracking)."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"question-2-contextual-metadata-vs.-explicit-claims"},"children":["Question 2: Contextual Metadata vs. Explicit Claims"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["\"Does the graph model distinguish between contextual metadata and explicit claims?\""]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"what-papr-provides--1"},"children":["What Papr Provides ✅"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Two Ways to Add Metadata:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["1. Memory-level metadata"]}," (about the source/context):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"client.memory.add(\n    content=\"API rate limit is 1000 requests/hour\",\n    metadata={\n        # Contextual metadata - NOT extracted, just stored\n        \"source_type\": \"documentation\",\n        \"version\": \"v2.0\",\n        \"last_updated\": \"2026-01-15\",\n        \"authority\": \"official\",\n        \"document_section\": \"rate-limits\"\n    },\n    memory_policy={\"mode\": \"auto\", \"schema_id\": osmosis_schema_id}\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["2. Node property overrides"]}," (forced onto extracted nodes):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"client.memory.add(\n    content=\"API rate limit is 1000 requests/hour\",\n    memory_policy={\n        \"mode\": \"auto\",  # Still let LLM extract the claim\n        \"schema_id\": osmosis_schema_id,\n        \"node_constraints\": [\n            {\n                \"node_type\": \"Claim\",\n                \"set\": {\n                    # Metadata injected directly onto node\n                    \"document_version\": \"v2.0\",\n                    \"source_authority\": \"official\",\n                    \"extraction_date\": \"2026-01-15\",\n                    \"reviewed\": False,\n                    # LLM extracts: subject, predicate, object\n                    # Developer injects: version, authority, etc.\n                }\n            }\n        ]\n    }\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key Difference:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Memory metadata"]},": Stored on memory object, queryable via memory search"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Node properties"]},": Stored on graph nodes, queryable via GraphQL, part of entity"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Auto-extracted"]},": LLM extracts from content (subject, predicate, object)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Property overrides"]},": Developer forces specific values (version, authority, dates)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Schema-Level Distinction:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# They can model the distinction in their schema\nnode_types={\n    \"Claim\": {  # First-class claim\n        \"properties\": {\n            \"statement\": {\"type\": \"string\"},\n            \"confidence\": {\"type\": \"float\"},\n            \"claim_type\": {\"type\": \"string\", \"enum_values\": [\"fact\", \"opinion\", \"policy\"]}\n        }\n    },\n    \"SourceMetadata\": {  # Contextual information\n        \"properties\": {\n            \"version\": {\"type\": \"string\"},\n            \"authority_level\": {\"type\": \"string\"},\n            \"publication_date\": {\"type\": \"datetime\"}\n        }\n    }\n}\n\nrelationship_types={\n    \"HAS_METADATA\": {\n        \"allowed_source_types\": [\"Claim\"],\n        \"allowed_target_types\": [\"SourceMetadata\"]\n    }\n}\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"gap-analysis-️-1"},"children":["Gap Analysis ⚠️"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Memory metadata"]},": Contextual info about source"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Property overrides"]},": Force metadata onto nodes"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Auto-extraction"]},": LLM extracts claims from content"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Clear separation"]},": metadata vs node properties vs extracted properties"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Flexible control"]},": Choose what's auto-extracted vs injected"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Verdict:"]}," Full control over metadata vs claims. Use memory.metadata for context, node_constraints.set for forced properties, auto mode for extracted claims."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"question-3-versioned-knowledge-/-temporal-evolution"},"children":["Question 3: Versioned Knowledge / Temporal Evolution"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["\"Is there a notion of versioned knowledge or temporal evolution across documents?\""]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"what-papr-provides--2"},"children":["What Papr Provides ✅"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Timestamp Tracking:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Every memory has ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.timestamp"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Can filter by time ranges"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Time-weighted search available"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Two Version Approaches:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Approach 1: Version as node property"]}," (simpler):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Add version directly on Claim nodes\nclient.memory.add(\n    content=\"API v1.0 rate limit is 100/hour\",\n    memory_policy={\n        \"mode\": \"auto\",\n        \"schema_id\": osmosis_schema_id,\n        \"node_constraints\": [\n            {\n                \"node_type\": \"Claim\",\n                \"set\": {\n                    \"version\": \"v1.0\",\n                    \"effective_from\": \"2024-01-01\",\n                    \"effective_until\": \"2025-06-01\"\n                    # LLM extracts: subject, predicate, object\n                }\n            }\n        ]\n    }\n)\n\n# Query by version\nquery = \"\"\"\nquery GetClaimsByVersion($subject: String!, $version: String!) {\n  claims(where: { subject: $subject, version: $version }) {\n    object\n    effective_from\n    effective_until\n  }\n}\n\"\"\"\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Approach 2: Separate Version nodes"]}," (more structured):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Create explicit version chain\nnode_types={\n    \"KnowledgeVersion\": {\n        \"properties\": {\n            \"subject\": {\"type\": \"string\"},\n            \"version\": {\"type\": \"string\"},\n            \"effective_from\": {\"type\": \"datetime\"},\n            \"effective_until\": {\"type\": \"datetime\"}\n        }\n    }\n}\n\nrelationship_types={\n    \"SUPERSEDES\": {\n        \"allowed_source_types\": [\"KnowledgeVersion\"],\n        \"allowed_target_types\": [\"KnowledgeVersion\"]\n    },\n    \"VERSION_OF\": {\n        \"allowed_source_types\": [\"Claim\"],\n        \"allowed_target_types\": [\"KnowledgeVersion\"]\n    }\n}\n\nrelationship_types={\n    \"SUPERSEDES\": {\n        \"allowed_source_types\": [\"KnowledgeVersion\"],\n        \"allowed_target_types\": [\"KnowledgeVersion\"]\n    },\n    \"VERSION_OF\": {\n        \"allowed_source_types\": [\"Claim\"],\n        \"allowed_target_types\": [\"KnowledgeVersion\"]\n    }\n}\n\n# Store versioned claims\nclient.memory.add(\n    content=\"API v1.0 says rate limit is 100/hour\",\n    memory_policy={\n        \"mode\": \"auto\",\n        \"schema_id\": osmosis_schema_id,\n        \"node_constraints\": [\n            {\n                \"node_type\": \"Claim\",\n                \"set\": {\n                    \"as_of_version\": \"v1.0\",\n                    \"statement\": \"rate limit is 100/hour\"\n                }\n            },\n            {\n                \"node_type\": \"KnowledgeVersion\",\n                \"set\": {\n                    \"version\": \"v1.0\",\n                    \"effective_from\": \"2024-01-01T00:00:00Z\",\n                    \"effective_until\": \"2025-06-01T00:00:00Z\"\n                }\n            }\n        ]\n    }\n)\n\n# Query version history\nquery = \"\"\"\nquery GetVersionHistory($subject: String!) {\n  versions: knowledge_versions(\n    where: { subject: $subject }\n    order_by: { effective_from: ASC }\n  ) {\n    version\n    effective_from\n    effective_until\n    claims {\n      statement\n    }\n    supersedes {\n      version\n    }\n  }\n}\n\"\"\"\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Temporal Queries:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Point-in-time query (custom logic)\nasync def get_knowledge_at_time(subject: str, timestamp: datetime):\n    \"\"\"Get what we knew about subject at specific time.\"\"\"\n    query = \"\"\"\n    query PointInTime($subject: String!, $timestamp: DateTime!) {\n      claims(where: {\n        subject: $subject,\n        version: {\n          effective_from: { $lte: $timestamp },\n          effective_until: { $gte: $timestamp }\n        }\n      }) {\n        statement\n        version\n        sources {\n          document_id\n        }\n      }\n    }\n    \"\"\"\n    return await client.graphql.query(query, {\n        \"subject\": subject,\n        \"timestamp\": timestamp.isoformat()\n    })\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"gap-analysis-️-2"},"children":["Gap Analysis ⚠️"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ Timestamps on all memories (automatic)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Can inject version via property overrides"]}," (node_constraints.set)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ Can model versions as explicit nodes (more structured)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ Can create version chains (SUPERSEDES relationships)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ Time-based filtering in queries"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["⚠️ Version semantics defined by developer (what version means)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["⚠️ Point-in-time queries via effective_from/effective_until filters"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Verdict:"]}," Temporal tracking is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["straightforward via property injection"]},". Two options: (1) version property on claims, or (2) separate version nodes with relationships."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"question-4-source-evidence-vs.-inferred-relationships"},"children":["Question 4: Source Evidence vs. Inferred Relationships"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["\"Are graph relationships strictly tied to source evidence, or can they be inferred dynamically?\""]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"what-papr-provides--3"},"children":["What Papr Provides ✅"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Two Graph Generation Modes:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["1. Auto Mode (Extraction-based):"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# LLM extracts relationships from content\nclient.memory.add(\n    content=\"Jane Smith works at Acme Corp as CTO. Acme Corp is partnered with TechVentures.\",\n    memory_policy={\"mode\": \"auto\", \"schema_id\": osmosis_schema_id}\n)\n\n# Papr automatically creates:\n# - Jane Smith (Person node)\n# - Acme Corp (Company node)\n# - TechVentures (Company node)\n# - WORKS_AT relationship (Jane -> Acme)\n# - PARTNERED_WITH relationship (Acme -> TechVentures)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Each extracted relationship is tied to the memory (source):"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"(Memory) --EXTRACTED--> (Relationship) --CONNECTS--> (Node)\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["2. Manual Mode (Explicit):"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Developer specifies exact graph structure\nclient.memory.add(\n    content=\"Explicit claim linking\",\n    memory_policy={\n        \"mode\": \"manual\",\n        \"nodes\": [\n            {\"id\": \"claim_1\", \"type\": \"Claim\", \"properties\": {\"statement\": \"X\"}},\n            {\"id\": \"claim_2\", \"type\": \"Claim\", \"properties\": {\"statement\": \"Y\"}}\n        ],\n        \"relationships\": [\n            {\n                \"source\": \"claim_1\",\n                \"target\": \"claim_2\",\n                \"type\": \"SUPPORTS\",\n                \"properties\": {\"confidence\": 0.8, \"inferred\": False}\n            }\n        ]\n    }\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Custom Inference Layer:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Developer can build inference rules\nasync def infer_transitive_relationships():\n    \"\"\"Example: If A→B and B→C, infer A→C\"\"\"\n    \n    # 1. Query existing relationships\n    query = \"\"\"\n    query GetChains {\n      relationships(where: { type: \"RELATED_TO\" }) {\n        source { id }\n        target { id }\n        properties\n      }\n    }\n    \"\"\"\n    \n    result = await client.graphql.query(query)\n    \n    # 2. Find transitive patterns\n    chains = find_transitive_chains(result['relationships'])\n    \n    # 3. Create inferred relationships\n    for chain in chains:\n        await client.memory.add(\n            content=f\"Inferred relationship: {chain['source']} -> {chain['target']}\",\n            memory_policy={\n                \"mode\": \"manual\",\n                \"relationships\": [\n                    {\n                        \"source\": chain['source'],\n                        \"target\": chain['target'],\n                        \"type\": \"RELATED_TO\",\n                        \"properties\": {\n                            \"inferred\": True,\n                            \"inference_rule\": \"transitive\",\n                            \"confidence\": 0.7\n                        }\n                    }\n                ]\n            }\n        )\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Relationship Provenance:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Can track whether relationship is extracted or inferred\nrelationship_types={\n    \"SUPPORTS\": {\n        \"properties\": {\n            \"provenance_type\": {\n                \"type\": \"string\", \n                \"enum_values\": [\"extracted\", \"inferred\", \"manual\"]\n            },\n            \"extraction_source\": {\"type\": \"string\"},\n            \"inference_rule\": {\"type\": \"string\"}\n        }\n    }\n}\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"gap-analysis-️-3"},"children":["Gap Analysis ⚠️"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ Relationships are tied to source memories (provenance)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ Can mark relationships as extracted vs inferred"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ Manual mode for explicit relationship creation"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["❌ No built-in inference engine"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["❌ No rule-based relationship derivation"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["❌ Transitive/logical inference requires custom code"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Verdict:"]}," Relationships are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["primarily extracted, not inferred"]},". Developer can build inference layer using GraphQL queries + manual relationship creation."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"question-5-single-source-vs.-multi-source-corroboration"},"children":["Question 5: Single-Source vs. Multi-Source Corroboration"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["\"Do you differentiate between single-source extracted claims and multi-source corroborated knowledge?\""]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"what-papr-provides--4"},"children":["What Papr Provides ✅"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Entity Resolution Across Sources:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Document 1\nclient.memory.add(\n    content=\"Product X costs $100 (from pricing sheet)\",\n    memory_policy={\"mode\": \"auto\", \"schema_id\": osmosis_schema_id}\n)\n\n# Document 2  \nclient.memory.add(\n    content=\"Product X is priced at $100 (from sales deck)\",\n    memory_policy={\"mode\": \"auto\", \"schema_id\": osmosis_schema_id}\n)\n\n# Document 3\nclient.memory.add(\n    content=\"Product X: $100 (from website)\",\n    memory_policy={\"mode\": \"auto\", \"schema_id\": osmosis_schema_id}\n)\n\n# Papr's entity resolution merges \"Product X\" into single node\n# Can query which memories reference it\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Corroboration is Built-In via Deduplication:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Papr automatically:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Merges same claim from multiple sources → ONE node"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Creates EXTRACTED_FROM relationship for each source"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["GraphQL can count these relationships"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Simple Query to Get Corroboration:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# No custom service needed - just query!\nquery = \"\"\"\nquery GetClaimCorroboration($subject: String!) {\n  claims(where: { subject: $subject }) {\n    object\n    statement\n    sources {  # Papr automatically populates this\n      document_id\n      version\n      authority\n      date\n    }\n  }\n}\n\"\"\"\n\nresult = await client.graphql.query(query, {\"subject\": \"Product X price\"})\n\n# Analyze results\nfor claim in result['data']['claims']:\n    source_count = len(claim['sources'])\n    official_count = sum(1 for s in claim['sources'] if s['authority'] == 'official')\n    \n    print(f\"Claim: {claim['object']}\")\n    print(f\"  Supported by {source_count} sources ({official_count} official)\")\n    \n    # Apply resolution rules\n    if source_count >= 3 and official_count >= 2:\n        print(f\"  ✅ High confidence (3+ sources, 2+ official)\")\n    elif source_count == 1:\n        print(f\"  ⚠️ Single source - needs verification\")\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Optional: Store Computed Score:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# If you want to cache the score on the node\nawait client.memory.add(\n    content=f\"Update corroboration score\",\n    memory_policy={\n        \"mode\": \"manual\",\n        \"node_constraints\": [{\n            \"node_type\": \"Claim\",\n            \"search\": {\"properties\": [{\"name\": \"id\", \"mode\": \"exact\", \"value\": claim_id}]},\n            \"set\": {\n                \"source_count\": source_count,\n                \"corroboration_score\": source_count / 5.0\n            }\n        }]\n    }\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key Point:"]}," Counting sources is a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["simple GraphQL query"]},", not a complex background service. Papr's deduplication does the heavy lifting."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"gap-analysis-️-4"},"children":["Gap Analysis ⚠️"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Entity merging across sources"]}," (automatic via unique_identifiers)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Multi-source relationships"]}," (EXTRACTED_FROM to each source)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["GraphQL counts sources"]}," (via relationship traversal)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["✅ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Simple query"]}," shows source count and details"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["⚠️ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Corroboration formula"]}," is developer's choice (count? weighted? freshness?)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["⚠️ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Caching score"]}," optional (can compute on-demand or store on node)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Verdict:"]}," Multi-source tracking is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["automatic"]},". Counting sources is a simple GraphQL query. Developer only chooses scoring formula (if needed)."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recommended-architecture"},"children":["Recommended Architecture"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"┌─────────────────────────────────────────────────────────────┐\n│                   OSMOSIS APPLICATION LAYER                  │\n│  ┌──────────────────────────────────────────────────────┐  │\n│  │  Governance Services (Custom Logic)                  │  │\n│  │  • Conflict Detection                                │  │\n│  │  • Corroboration Scoring                            │  │\n│  │  • Version History Management                        │  │\n│  │  • Inference Engine (transitive, rule-based)       │  │\n│  │  • Evidence Strength Calculation                    │  │\n│  └──────────────────────────────────────────────────────┘  │\n│                           ↕︎                                  │\n│  ┌──────────────────────────────────────────────────────┐  │\n│  │  Osmosis Data Model (Custom Schema)                 │  │\n│  │  • Claim nodes (statement, confidence, version)     │  │\n│  │  • Source nodes (document, page, authority)         │  │\n│  │  • ConflictSet nodes (subject, resolution_status)   │  │\n│  │  • KnowledgeVersion nodes (version, timespan)       │  │\n│  │  • EXTRACTED_FROM, CONFLICTS_WITH, SUPERSEDES       │  │\n│  └──────────────────────────────────────────────────────┘  │\n└─────────────────────────────────────────────────────────────┘\n                            ↕︎\n┌─────────────────────────────────────────────────────────────┐\n│                    PAPR MEMORY API                           │\n│  ┌──────────────────────────────────────────────────────┐  │\n│  │  Knowledge Graph Storage                             │  │\n│  │  • Neo4j graph database                              │  │\n│  │  • Custom schema support                             │  │\n│  │  • Node/relationship creation                        │  │\n│  │  • Entity resolution & merging                       │  │\n│  └──────────────────────────────────────────────────────┘  │\n│  ┌──────────────────────────────────────────────────────┐  │\n│  │  Hybrid Retrieval Engine                             │  │\n│  │  • Vector embeddings (semantic search)               │  │\n│  │  • Keyword search (BM25)                             │  │\n│  │  • Graph traversal (multi-hop)                       │  │\n│  └──────────────────────────────────────────────────────┘  │\n│  ┌──────────────────────────────────────────────────────┐  │\n│  │  GraphQL Query Layer                                 │  │\n│  │  • Complex relationship queries                      │  │\n│  │  • Aggregations & analytics                          │  │\n│  │  • Multi-hop traversals                              │  │\n│  └──────────────────────────────────────────────────────┘  │\n└─────────────────────────────────────────────────────────────┘\n"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"why-can-they-build-this-with-papr"},"children":["Why Can They Build This with Papr?"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"core-strengths-that-enable-osmosis"},"children":["Core Strengths That Enable Osmosis"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"1.-"},"children":["1. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Custom Schema System"]}," ✅"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Full control over domain ontology\nschema = client.schemas.create(\n    name=\"Osmosis\",\n    node_types={\n        \"Claim\": {...},\n        \"Source\": {...},\n        \"ConflictSet\": {...},\n        \"Evidence\": {...}\n    },\n    relationship_types={\n        \"EXTRACTED_FROM\": {...},\n        \"CONFLICTS_WITH\": {...},\n        \"SUPPORTS\": {...},\n        \"REFUTES\": {...}\n    }\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Why This Matters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Define exactly what a \"claim\" is"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Model provenance relationships explicitly"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Track conflict resolution status"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Store confidence/corroboration scores"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"2.-"},"children":["2. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Node Constraints"]}," ✅"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Force properties onto nodes\nmemory_policy={\n    \"node_constraints\": [\n        {\n            \"node_type\": \"Claim\",\n            \"set\": {\n                \"confidence\": 0.95,\n                \"extraction_method\": \"llm\",\n                \"extracted_at\": \"2026-02-16T10:00:00Z\",\n                \"document_version\": \"v2.1\"\n            }\n        }\n    ]\n}\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Why This Matters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Every claim gets metadata automatically"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Consistent property injection"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Source attribution baked in"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Version tracking per claim"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"3.-"},"children":["3. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["GraphQL Analytics"]}," ✅"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Complex queries for governance\nquery = \"\"\"\nquery ConflictAnalysis($subject: String!) {\n  conflict_sets(where: { subject: $subject, resolution_status: \"unresolved\" }) {\n    subject\n    predicate\n    claims {\n      statement\n      confidence\n      sources {\n        document_id\n        authority_level\n        version\n      }\n    }\n  }\n}\n\"\"\"\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Why This Matters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Find all conflicts for a subject"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Compare source authority levels"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Identify version discrepancies"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Aggregate corroboration counts"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"4.-"},"children":["4. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Flexible Metadata"]}," ✅"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Store any custom fields\nmetadata={\n    \"claim_type\": \"factual\",\n    \"extraction_confidence\": 0.92,\n    \"reviewed_by_human\": False,\n    \"conflict_status\": \"none\",\n    \"source_authority\": \"official\",\n    \"as_of_version\": \"v2.1\"\n}\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Why This Matters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Track governance workflow state"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Store review status"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Flag conflicts"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Version everything"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"5.-"},"children":["5. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Entity Resolution"]}," ✅"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Same entity mentioned in multiple documents → one node\n# \"Product X\", \"product x\", \"ProductX\" → merged automatically\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Why This Matters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cross-document references work"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Corroboration counting possible"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Conflict detection feasible"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No manual de-duplication needed"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"6.-"},"children":["6. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Provenance Built-In"]}," ✅"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every memory has:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["memory_id"]}," (unique)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["created_at"]}," (timestamp)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["source"]}," (where it came from)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["metadata.document_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["metadata.page"]},", etc."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Why This Matters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Trace every claim to source"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Audit trail automatic"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Evidence chain preserved"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Compliance-ready"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"what-they-still-need-to-build"},"children":["What They Still Need to Build"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1."},"children":["1. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Conflict Detection Service"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Periodic job\n@schedule.every(1).hours\nasync def detect_conflicts():\n    # Query claims by subject+predicate\n    # Find different values\n    # Create ConflictSet nodes\n    # Link claims to conflict sets\n    pass\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2."},"children":["2. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Corroboration Scoring Service"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Update scores based on source count\n@schedule.every(6).hours\nasync def update_corroboration():\n    # Count sources per claim\n    # Compute confidence score\n    # Update Claim.corroboration_score\n    pass\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3."},"children":["3. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Version History Service"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Track knowledge evolution\nasync def track_version_change(claim_id, new_version):\n    # Create new KnowledgeVersion node\n    # Link old version → new version (SUPERSEDES)\n    # Update claims to reference new version\n    pass\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4."},"children":["4. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Inference Engine"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Apply logical rules\nasync def apply_inference_rules():\n    # Transitive relationships\n    # Contradiction detection\n    # Support/refutation chains\n    pass\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"5."},"children":["5. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Governance UI"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Visualize conflicts, history, evidence\n# Allow manual conflict resolution\n# Show corroboration strength\n# Display version timelines\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"concrete-example-full-workflow"},"children":["Concrete Example: Full Workflow"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-upload-documents"},"children":["Step 1: Upload Documents"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Document 1 (v1.0 spec)\nclient.document.upload(\n    file=open(\"api_spec_v1.pdf\", \"rb\"),\n    schema_id=osmosis_schema_id,\n    metadata={\"version\": \"v1.0\", \"authority\": \"official\", \"date\": \"2024-01-01\"}\n)\n\n# Document 2 (v2.0 spec)\nclient.document.upload(\n    file=open(\"api_spec_v2.pdf\", \"rb\"),\n    schema_id=osmosis_schema_id,\n    metadata={\"version\": \"v2.0\", \"authority\": \"official\", \"date\": \"2025-06-01\"}\n)\n\n# Document 3 (blog post)\nclient.document.upload(\n    file=open(\"blog_pricing.md\", \"rb\"),\n    schema_id=osmosis_schema_id,\n    metadata={\"version\": \"unknown\", \"authority\": \"unofficial\", \"date\": \"2025-12-01\"}\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-2-extract-claims-automatic"},"children":["Step 2: Extract Claims (Automatic)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Papr's extraction creates:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Claim: \"Rate limit is 100/hour\"\n  ← EXTRACTED_FROM → Source: \"api_spec_v1.pdf\" (page 12)\n  version: \"v1.0\"\n  confidence: 0.95\n\nClaim: \"Rate limit is 1000/hour\"\n  ← EXTRACTED_FROM → Source: \"api_spec_v2.pdf\" (page 15)\n  version: \"v2.0\"\n  confidence: 0.98\n\nClaim: \"Rate limit is 1000/hour\"\n  ← EXTRACTED_FROM → Source: \"blog_pricing.md\" \n  version: \"unknown\"\n  confidence: 0.75\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-3-conflict-detection-simple-query"},"children":["Step 3: Conflict Detection (Simple Query)"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Query for all claims about \"Rate limit\"\nquery = \"\"\"\nquery FindConflicts($subject: String!) {\n  claims(where: { subject: $subject }) {\n    object\n    sources {\n      document_id\n      version\n      authority\n      date\n    }\n  }\n}\n\"\"\"\n\nresult = await client.graphql.query(query, {\"subject\": \"Rate limit\"})\n\n# Analyze: different values = conflict\nunique_values = set(claim['object'] for claim in result['claims'])\n\nif len(unique_values) > 1:\n    print(f\"⚠️ CONFLICT: {unique_values}\")\n    # Returns: {\"100/hour\", \"1000/hour\"}\n    \n    for claim in result['claims']:\n        print(f\"  {claim['object']}: {len(claim['sources'])} sources\")\n    # Output:\n    #   100/hour: 1 source (v1.0 spec)\n    #   1000/hour: 2 sources (v2.0 spec + blog)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-4-resolution-logic-custom"},"children":["Step 4: Resolution Logic (Custom)"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Osmosis resolution strategy: \"most recent official source wins\"\nasync def resolve_conflict(conflict_set_id):\n    # Query claims in conflict set\n    query = \"\"\"\n    query ConflictClaims($conflict_id: ID!) {\n      conflict_set(id: $conflict_id) {\n        claims {\n          id\n          object\n          sources {\n            authority\n            version\n            date\n          }\n        }\n      }\n    }\n    \"\"\"\n    \n    result = await client.graphql.query(query, {\"conflict_id\": conflict_set_id})\n    \n    # Filter official sources\n    official_claims = [c for c in result['claims'] \n                      if c['sources'][0]['authority'] == 'official']\n    \n    # Pick most recent\n    winner = max(official_claims, key=lambda c: c['sources'][0]['date'])\n    \n    # Update conflict set\n    await update_conflict_set(\n        conflict_set_id,\n        resolution_status=\"resolved\",\n        winner_claim_id=winner['id'],\n        resolution_rule=\"most_recent_official\"\n    )\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-5-apply-resolution-rules-simple-logic"},"children":["Step 5: Apply Resolution Rules (Simple Logic)"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# From Step 3, we have:\n# Claim 1: \"100/hour\" - 1 source (v1.0, official)\n# Claim 2: \"1000/hour\" - 2 sources (v2.0 official + blog unofficial)\n\n# Resolution strategy: \"Most sources from official documents\"\nclaims_analyzed = []\nfor claim in result['claims']:\n    official_sources = [s for s in claim['sources'] if s['authority'] == 'official']\n    claims_analyzed.append({\n        'value': claim['object'],\n        'total_sources': len(claim['sources']),\n        'official_sources': len(official_sources),\n        'most_recent': max(s['date'] for s in claim['sources'])\n    })\n\n# Apply scoring\ndef resolution_score(claim):\n    return (\n        claim['official_sources'] * 10 +  # Official sources weighted high\n        claim['total_sources'] * 2 +       # Total sources matter\n        recency_weight(claim['most_recent'])  # Recent is better\n    )\n\nwinner = max(claims_analyzed, key=resolution_score)\nprint(f\"✅ Resolved: {winner['value']}\")\n# Output: \"1000/hour\" (v2.0 is more recent + has official source)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-6-version-tracking-custom"},"children":["Step 6: Version Tracking (Custom)"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# Create version timeline\nawait create_version_node(\n    subject=\"Rate limit\",\n    version=\"v1.0\",\n    value=\"100/hour\",\n    effective_from=\"2024-01-01\",\n    effective_until=\"2025-06-01\"\n)\n\nawait create_version_node(\n    subject=\"Rate limit\",\n    version=\"v2.0\",\n    value=\"1000/hour\",\n    effective_from=\"2025-06-01\",\n    effective_until=None  # Current\n)\n\nawait create_supersedes_relationship(\n    old_version=\"v1.0\",\n    new_version=\"v2.0\"\n)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-7-query-history-graphql"},"children":["Step 7: Query History (GraphQL)"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"# What did we know about rate limits in March 2025?\nquery = \"\"\"\nquery HistoricalKnowledge($subject: String!, $date: DateTime!) {\n  knowledge_versions(where: {\n    subject: $subject,\n    effective_from: { $lte: $date },\n    effective_until: { $gte: $date }\n  }) {\n    version\n    value\n    claims {\n      statement\n      sources {\n        document_id\n      }\n    }\n  }\n}\n\"\"\"\n\nhistorical = await client.graphql.query(query, {\n    \"subject\": \"Rate limit\",\n    \"date\": \"2025-03-01T00:00:00Z\"\n})\n\n# Returns: \"100/hour\" (v1.0 was effective until June 2025)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"performance-considerations"},"children":["Performance Considerations"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-papr-handles-efficiently-"},"children":["What Papr Handles Efficiently ✅"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fast retrieval"]},": <150ms (when cached)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Entity resolution"]},": Automatic merging"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Vector search"]},": Semantic similarity"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Graph traversal"]},": Multi-hop relationships"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Hybrid ranking"]},": Keyword + semantic + graph"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-requires-optimization-️"},"children":["What Requires Optimization ⚠️"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Conflict detection"]},": Periodic batch jobs (don't run on every write)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Corroboration updates"]},": Background service, not real-time"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Version tracking"]},": Compute on demand, cache results"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Large-scale queries"]},": Use pagination, limit result sets"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"cost-estimation"},"children":["Cost Estimation"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"papr-cloud-costs"},"children":["Papr Cloud Costs"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Storage: ~$0.02/GB/month"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["API calls: ~$0.001 per search"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Document processing: ~$0.05 per document"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"for-10000-documents"},"children":["For 10,000 documents:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Storage: ~500 documents/GB → 20 GB → ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["$0.40/month"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Processing: 10,000 docs × $0.05 → ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["$500 one-time"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Search: 1M queries/month × $0.001 → ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["$1,000/month"]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"custom-logic-costs"},"children":["Custom Logic Costs"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Compute for services: ~$50-100/month (AWS Lambda/Cloud Run)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Database for governance state: ~$20/month (PostgreSQL)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Total: ~$1,100-1,200/month for production scale"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"decision-framework"},"children":["Decision Framework"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"use-papr-if"},"children":["Use Papr If:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["✅ Need knowledge graph + retrieval in one API",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"✅ Want entity resolution handled automatically",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"✅ Need hybrid search (semantic + keyword + graph)",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"✅ Schema flexibility is important",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"✅ GraphQL analytics valuable",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"✅ Prefer hosted/managed service"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"build-from-scratch-if"},"children":["Build from Scratch If:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["❌ Need built-in temporal graph (point-in-time snapshots)",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"❌ Require automatic inference engine",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"❌ Want conflict detection as core DB feature",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"❌ Need ACID transactions across graph operations",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"❌ Extreme performance requirements (microsecond latency)"]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recommended-next-steps"},"children":["Recommended Next Steps"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"phase-1-proof-of-concept-2-weeks"},"children":["Phase 1: Proof of Concept (2 weeks)"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Week 1:"]}," Design Osmosis schema in Papr"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Define Claim, Source, ConflictSet node types"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Define EXTRACTED_FROM, CONFLICTS_WITH relationships"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Test schema creation API"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Week 2:"]}," Implement basic workflow"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Upload 3 test documents with overlapping claims"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Extract claims via Papr's auto mode"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Write simple conflict detection script"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Query results via GraphQL"]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Success Criteria:"]}," Can detect conflicting claims across 3 documents"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"phase-2-core-services-4-weeks"},"children":["Phase 2: Core Services (4 weeks)"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Week 3-4:"]}," Build governance services"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Conflict detection (batch job)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Corroboration scoring"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Basic resolution logic"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Week 5-6:"]}," Add version tracking"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Model KnowledgeVersion nodes"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Track SUPERSEDES relationships"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Implement temporal queries"]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Success Criteria:"]}," Full workflow works end-to-end"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"phase-3-production-hardening-4-weeks"},"children":["Phase 3: Production Hardening (4 weeks)"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Week 7-8:"]}," Performance optimization"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Batch operations"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Caching strategies"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Query optimization"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Week 9-10:"]}," UI + monitoring"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Conflict visualization dashboard"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Evidence strength display"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Governance metrics"]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Success Criteria:"]}," Production-ready system"]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"final-recommendation"},"children":["Final Recommendation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["YES, use Papr as the foundation layer."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Reasoning:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["90% of infrastructure handled"]}," (storage, retrieval, graph, entity resolution)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Schema system enables custom modeling"]}," (claims, conflicts, versions)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["GraphQL provides analytics power"]}," (complex queries, aggregations)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Saves 6-12 months of development"]}," vs building from scratch"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Custom logic is straightforward"]}," (conflict detection, scoring, versioning)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Trade-offs:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Must build governance logic (but would need this even with custom DB)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No built-in temporal graph (but can model versions explicitly)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No automatic inference (but can add via custom services)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Bottom Line:"]}," Papr provides the hard parts (graph database, retrieval, entity resolution). The governance layer on top is domain-specific logic they'd build regardless of underlying database choice."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Next Step:"]}," Schedule architecture review call to walk through schema design and confirm approach."]}]},"headings":[{"value":"Osmosis Use Case Analysis: Papr Capability Assessment","id":"osmosis-use-case-analysis-papr-capability-assessment","depth":1},{"value":"Executive Summary","id":"executive-summary","depth":2},{"value":"Understanding the Osmosis System","id":"understanding-the-osmosis-system","depth":2},{"value":"Core Mission","id":"core-mission","depth":3},{"value":"Philosophical Approach","id":"philosophical-approach","depth":3},{"value":"The 5 Questions - Detailed Analysis","id":"the-5-questions---detailed-analysis","depth":2},{"value":"Question 1: Handling Conflicting Statements","id":"question-1-handling-conflicting-statements","depth":3},{"value":"What Papr Provides ✅","id":"what-papr-provides-","depth":4},{"value":"Gap Analysis ⚠️","id":"gap-analysis-️","depth":4},{"value":"Question 2: Contextual Metadata vs. Explicit Claims","id":"question-2-contextual-metadata-vs.-explicit-claims","depth":3},{"value":"What Papr Provides ✅","id":"what-papr-provides--1","depth":4},{"value":"Gap Analysis ⚠️","id":"gap-analysis-️-1","depth":4},{"value":"Question 3: Versioned Knowledge / Temporal Evolution","id":"question-3-versioned-knowledge-/-temporal-evolution","depth":3},{"value":"What Papr Provides ✅","id":"what-papr-provides--2","depth":4},{"value":"Gap Analysis ⚠️","id":"gap-analysis-️-2","depth":4},{"value":"Question 4: Source Evidence vs. Inferred Relationships","id":"question-4-source-evidence-vs.-inferred-relationships","depth":3},{"value":"What Papr Provides ✅","id":"what-papr-provides--3","depth":4},{"value":"Gap Analysis ⚠️","id":"gap-analysis-️-3","depth":4},{"value":"Question 5: Single-Source vs. Multi-Source Corroboration","id":"question-5-single-source-vs.-multi-source-corroboration","depth":3},{"value":"What Papr Provides ✅","id":"what-papr-provides--4","depth":4},{"value":"Gap Analysis ⚠️","id":"gap-analysis-️-4","depth":4},{"value":"Recommended Architecture","id":"recommended-architecture","depth":2},{"value":"Why Can They Build This with Papr?","id":"why-can-they-build-this-with-papr","depth":2},{"value":"Core Strengths That Enable Osmosis","id":"core-strengths-that-enable-osmosis","depth":3},{"value":"1. ✅","id":"1.-","depth":4},{"value":"2. ✅","id":"2.-","depth":4},{"value":"3. ✅","id":"3.-","depth":4},{"value":"4. ✅","id":"4.-","depth":4},{"value":"5. ✅","id":"5.-","depth":4},{"value":"6. ✅","id":"6.-","depth":4},{"value":"What They Still Need to Build","id":"what-they-still-need-to-build","depth":2},{"value":"1.","id":"1.","depth":3},{"value":"2.","id":"2.","depth":3},{"value":"3.","id":"3.","depth":3},{"value":"4.","id":"4.","depth":3},{"value":"5.","id":"5.","depth":3},{"value":"Concrete Example: Full Workflow","id":"concrete-example-full-workflow","depth":2},{"value":"Step 1: Upload Documents","id":"step-1-upload-documents","depth":3},{"value":"Step 2: Extract Claims (Automatic)","id":"step-2-extract-claims-automatic","depth":3},{"value":"Step 3: Conflict Detection (Simple Query)","id":"step-3-conflict-detection-simple-query","depth":3},{"value":"Step 4: Resolution Logic (Custom)","id":"step-4-resolution-logic-custom","depth":3},{"value":"Step 5: Apply Resolution Rules (Simple Logic)","id":"step-5-apply-resolution-rules-simple-logic","depth":3},{"value":"Step 6: Version Tracking (Custom)","id":"step-6-version-tracking-custom","depth":3},{"value":"Step 7: Query History (GraphQL)","id":"step-7-query-history-graphql","depth":3},{"value":"Performance Considerations","id":"performance-considerations","depth":2},{"value":"What Papr Handles Efficiently ✅","id":"what-papr-handles-efficiently-","depth":3},{"value":"What Requires Optimization ⚠️","id":"what-requires-optimization-️","depth":3},{"value":"Cost Estimation","id":"cost-estimation","depth":2},{"value":"Papr Cloud Costs","id":"papr-cloud-costs","depth":3},{"value":"For 10,000 documents:","id":"for-10000-documents","depth":3},{"value":"Custom Logic Costs","id":"custom-logic-costs","depth":3},{"value":"Decision Framework","id":"decision-framework","depth":2},{"value":"Use Papr If:","id":"use-papr-if","depth":3},{"value":"Build from Scratch If:","id":"build-from-scratch-if","depth":3},{"value":"Recommended Next Steps","id":"recommended-next-steps","depth":2},{"value":"Phase 1: Proof of Concept (2 weeks)","id":"phase-1-proof-of-concept-2-weeks","depth":3},{"value":"Phase 2: Core Services (4 weeks)","id":"phase-2-core-services-4-weeks","depth":3},{"value":"Phase 3: Production Hardening (4 weeks)","id":"phase-3-production-hardening-4-weeks","depth":3},{"value":"Final Recommendation","id":"final-recommendation","depth":2}],"frontmatter":{"seo":{"title":"Osmosis Use Case Analysis: Papr Capability Assessment"}},"lastModified":"2026-04-22T01:40:48.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/internal/planning/osmosis-use-case-analysis","userData":{"isAuthenticated":false,"teams":["anonymous"]}}