{
  "@context": {
    "fhir": "http://hl7.org/fhir/",
    "fibo-fbc-fct-fse": "https://spec.edmcouncil.org/fibo/ontology/FBC/FunctionalEntities/FinancialServicesEntities/",
    "fibo-fbc-pas-fpas": "https://spec.edmcouncil.org/fibo/ontology/FBC/ProductsAndServices/FinancialProductsAndServices/",
    "olly": "https://ontology.dev.hiolly.com/ns/olly#",
    "owl": "http://www.w3.org/2002/07/owl#",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "schema": "https://schema.org/",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "snomed": "http://snomed.info/sct/",
    "socotra": "https://docs.socotra.com/api/",
    "xsd": "http://www.w3.org/2001/XMLSchema#"
  },
  "@graph": [
    {
      "@id": "olly:KafkaTopic",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:topicName",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:eventSchema",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "contracts",
      "rdfs:comment": "A Kafka topic carrying domain events between Olly services.",
      "rdfs:label": "KafkaTopic"
    },
    {
      "@id": "olly:McpTool",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:toolName",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:inputSchema",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "contracts",
      "rdfs:comment": "An MCP tool exposed by olly-mcp; consumed by AI agents.",
      "rdfs:label": "McpTool"
    },
    {
      "@id": "olly:Service",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:servicePort",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:serviceContainer",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "contracts",
      "rdfs:comment": "A deployable Olly microservice (e.g. claims, billing).",
      "rdfs:label": "Service"
    },
    {
      "@id": "olly:OpenSearchIndex",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:indexName",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "data",
      "rdfs:comment": "An OpenSearch index used for full-text or analytics queries.",
      "rdfs:label": "OpenSearchIndex"
    },
    {
      "@id": "olly:PostgresTable",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:tableName",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:primaryKey",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "data",
      "rdfs:comment": "A Postgres table owned by an Olly service, holding domain data.",
      "rdfs:label": "PostgresTable"
    },
    {
      "@id": "olly:SnowflakeTable",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:warehouseLayer",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "data",
      "rdfs:comment": "A Snowflake warehouse table for BI / actuarial reporting.",
      "rdfs:label": "SnowflakeTable"
    },
    {
      "@id": "olly:Account",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Account"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:name",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:billingLevel",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:displayNumber",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § Account — The Billing Entity",
          "docs/site/domain/billing.md § Premium Billing Cycle",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "openapi": [
          {
            "schema": "Account",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/accounts",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/accounts/{locator}",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/accounts/{locator}",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/accounts/list",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/accounts/{locator}/billingLevel",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/accounts/{locator}/number/generate",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/accounts/{locator}/number/set",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/accounts/{locator}/quotes/list",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/clients/accounts",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/accounts/{locator}/contacts/list",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/accounts/{locator}/contacts",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/accounts/{locator}/contacts/{contactLocator}",
            "service": "policy-admin"
          },
          {
            "method": "DELETE",
            "path": "/accounts/{locator}/contacts/{contactLocator}",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.accounts"
          }
        ],
        "socotra": [
          {
            "schema": "AccountListResponse",
            "spec_ref": "components/schemas/AccountListResponse"
          },
          {
            "schema": "AccountUpdateReplaceDataRequest",
            "spec_ref": "components/schemas/AccountUpdateReplaceDataRequest"
          }
        ]
      },
      "rdfs:comment": "The financial container that owns policies and receives invoices. An Account may bill at the\nACCOUNT level (all policies consolidated, typical for employer groups) or at the POLICY level\n(each policy billed independently). All Charges, Invoices, Payments, and LedgerEntries roll up\nto the Account. Aligned to Socotra's Account resource, which also represents a billing entity\nholding policies and financial balances.\n",
      "rdfs:label": "Account"
    },
    {
      "@id": "olly:AccumulatorBucket",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "member-portal-api",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/billing/installmentsAndInstallmentLattices.md (charges and billing concepts)"
        ],
        "openapi": [
          {
            "schema": "AccumulatorBucket",
            "spec": "api/openapi/member-portal-api.yaml",
            "spec_ref": "components/schemas/AccumulatorBucket"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A named counter that tracks a member's year-to-date spending against a specific benefit\nlimit — for example, the amount applied toward a deductible, out-of-pocket maximum, or visit cap.\nAccumulatorBuckets reset on the plan anniversary or calendar year boundary and are updated whenever a claim\nline is adjudicated. They feed eligibility checks during real-time prior-auth and claim decisions, ensuring\nthat benefit caps are correctly enforced across all submitted claims within a coverage period.\n",
      "rdfs:label": "Accumulator Bucket"
    },
    {
      "@id": "olly:Adjustment",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:type",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:amount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:reason",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:appliedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Ledger Entries (Double-Entry)"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.adjustments"
          }
        ]
      },
      "rdfs:comment": "A manual debit or credit applied to an Account outside of the regular invoice cycle,\nsuch as a pro-rata refund on mid-term cancellation or a goodwill credit. Adjustments generate corresponding\nLedgerEntry records that maintain double-entry balance.\n",
      "rdfs:label": "Adjustment"
    },
    {
      "@id": "olly:Appointment",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:episodeLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:providerLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:type",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:slotLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:linkOutUrl",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:scheduledAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:notes",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "care",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/providers.md § Credentialing Lifecycle"
        ],
        "openapi": [
          {
            "schema": "Appointment",
            "service": "care"
          },
          {
            "method": "GET",
            "path": "/episodes/{locator}/appointments",
            "service": "care"
          },
          {
            "method": "POST",
            "path": "/episodes/{locator}/appointments",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/appointments/{locator}/confirm",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/appointments/{locator}/attend",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/appointments/{locator}/cancel",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/appointments/{locator}/no-show",
            "service": "care"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "care",
            "table": "appointments"
          }
        ]
      },
      "rdfs:comment": "A scheduled encounter between a Member and a healthcare Provider, booked through the\ncare service. Appointments are linked to a care Episode and a specific ProviderSlot, and carry status\n(BOOKED, ATTENDED, CANCELLED) plus a telehealth link-out URL where applicable.\n",
      "rdfs:label": "Appointment"
    },
    {
      "@id": "olly:AuditItem",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "consent",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/workManagement/diaries.md (audit trail and diary concepts)"
        ],
        "openapi": [
          {
            "schema": "AuditItem",
            "spec": "api/openapi/consent.yaml",
            "spec_ref": "components/schemas/AuditItem"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "An immutable log record capturing who did what to which entity and when, supporting\nregulatory compliance and internal governance. Audit items are created automatically whenever a sensitive\nconsent, data-sharing, or policy action is performed, linking the acting user, the affected party, and the\noperation performed. They are append-only: no audit item can be modified or deleted, ensuring a tamper-evident\ntrail for GDPR and clinical data governance purposes.\n",
      "rdfs:label": "Audit Item"
    },
    {
      "@id": "olly:AuthToken",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:AuthToken"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "AuthTokenCreateRequest",
            "spec_ref": "components/schemas/AuthTokenCreateRequest"
          },
          {
            "schema": "AuthTokenResponse",
            "spec_ref": "components/schemas/AuthTokenResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A short-lived API credential issued to a service or external integration to authenticate against the\ninsurance platform API. AuthTokens are scoped to a tenant, carry an expiry timestamp, and are stored\nhashed. In Olly, API authentication is handled by Keycloak JWT tokens and OpenBao dynamic secrets;\nAuthToken as a platform-managed credential type is aspirational. Concept sourced from Socotra; not yet\nmodeled in Olly code.\n",
      "rdfs:label": "Auth Token"
    },
    {
      "@id": "olly:AutopayPreference",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:enabled",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:boolean"
        },
        {
          "@id": "olly:method",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Autopay"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.autopay_preferences"
          }
        ]
      },
      "rdfs:comment": "A per-policy flag indicating whether direct debit should be initiated\nautomatically on the invoice due date. When Enabled is true, the billing service triggers payment collection\nwithout manual intervention, reducing late-payment risk.\n",
      "rdfs:label": "Autopay Preference"
    },
    {
      "@id": "olly:AuxData",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:AuxData"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "AuxDataResponse",
            "spec_ref": "components/schemas/AuxDataResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "Extensible key-value metadata that can be attached to any Socotra entity (policy, account, claim, etc.)\nwithout requiring a schema change. AuxData entries are schematised via AuxDataKeySet definitions that\nspecify allowed keys, data types, and validation rules. In Olly, auxiliary data is currently stored as\nJSONB columns (e.g. Policy.Document, PolicyElement.Data); AuxData would provide a more structured,\nqueryable alternative. Concept sourced from Socotra; not yet modeled in Olly code.\n",
      "rdfs:label": "Aux Data"
    },
    {
      "@id": "olly:Benefit",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:benefitCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:annualLimit",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "snapshot": [
          {
            "file": "docs/superpowers/snapshots/2026-04-30-pre-code-evolution/ontology/concepts/domain/benefit.yaml",
            "reason": "hand-curated v0 — alignments and lifecycle ported forward"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A categorised allowance under a Coverage (e.g. \"annual physiotherapy\nvisits\", \"outpatient pharmacy\").\nAspirational: not currently backed by an Olly service or Postgres table.\n",
      "rdfs:label": "Benefit"
    },
    {
      "@id": "olly:BillingAggregate",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "group-scheme-service",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/billing/invoicing.md (invoice aggregation at account level)",
          "socotra/featureGuide/financials/accountingPrimer.md (account balance concepts)"
        ],
        "openapi": [
          {
            "schema": "BillingAggregate",
            "spec": "api/openapi/group-scheme-service.yaml",
            "spec_ref": "components/schemas/BillingAggregate"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "An aggregated billing view that summarises the financial position of all active policies\nwithin a Group Scheme, giving employers and brokers a consolidated picture of outstanding invoices, total\npremiums due, and payment status across their entire member cohort. BillingAggregate is computed from the\nbilling service's account and invoice data rather than stored as a persisted entity; it is assembled\non-demand when the employer portal requests the scheme billing dashboard. The concept parallels account-level\nbalance reporting in the Socotra platform, where invoice and payment totals roll up to the account.\n",
      "rdfs:label": "Billing Aggregate"
    },
    {
      "@id": "olly:BillingPlan",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:BillingPlan"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Invoice Lifecycle"
        ],
        "socotra": [
          {
            "schema": "BillingPlanRef",
            "spec_ref": "components/schemas/BillingPlanRef"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A product-level billing configuration that governs invoicing frequency, payment due dates, grace period\nlength, and retry strategy for a policy or account. BillingPlans abstract the billing rules away from\nindividual policies, enabling consistent billing across all policies on a product. Concept sourced from\nSocotra; not yet modeled as a separate entity in Olly code.\n",
      "rdfs:label": "Billing Plan"
    },
    {
      "@id": "olly:BrokerConfig",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:brokerId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:delegatedAuthorityLimit",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "broker-api",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "GET",
            "path": "/authority",
            "service": "broker-api"
          },
          {
            "method": "PUT",
            "path": "/authority",
            "service": "broker-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "broker-api",
            "table": "broker_api.broker_configs"
          }
        ]
      },
      "rdfs:comment": "Configuration for a broker integration, recording the broker's Party reference and\ntheir delegated authority limit — the maximum policy size the broker may bind without insurer\ncountersignature.\n",
      "rdfs:label": "Broker Config"
    },
    {
      "@id": "olly:BulkEnrollmentJob",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:schemeId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:total",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:processed",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:failedCount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:errors",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "group-scheme-service",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "POST",
            "path": "/schemes/{locator}/bulk-enrollments",
            "service": "group-scheme-service"
          },
          {
            "method": "GET",
            "path": "/bulk-enrollments/{jobLocator}/status",
            "service": "group-scheme-service"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "group-scheme-service",
            "table": "group_scheme.bulk_enrollment_jobs"
          }
        ]
      },
      "rdfs:comment": "An asynchronous batch job that processes a CSV or API upload of employee\nenrollments for a Group Scheme. Tracks total records, processed count, failure count, and per-row error\nmessages to enable partial recovery and audit.\n",
      "rdfs:label": "Bulk Enrollment Job"
    },
    {
      "@id": "olly:BulkEnrollmentJobError",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "group-scheme-service",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/policyManagement/policyTransactions.md (transaction validation errors)"
        ],
        "openapi": [
          {
            "schema": "BulkEnrollmentJobError",
            "spec": "api/openapi/group-scheme-service.yaml",
            "spec_ref": "components/schemas/BulkEnrollmentJobError"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A structured error record produced when a single row within a BulkEnrollmentJob fails\nto process — for example, because a member's identifier is missing, coverage dates are invalid, or a product\nrule rejects the application. Each error captures the offending row reference, error code, and human-readable\nmessage so that HR administrators can correct and resubmit without re-processing the entire batch. Errors are\naggregated on the parent BulkEnrollmentJob and surfaced in the employer portal's batch report view.\n",
      "rdfs:label": "Bulk Enrollment Job Error"
    },
    {
      "@id": "olly:BulkMember",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "group-scheme-service",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/policyManagement/policyTransactions.md (batch policy issuance context)"
        ],
        "openapi": [
          {
            "schema": "BulkMember",
            "spec": "api/openapi/group-scheme-service.yaml",
            "spec_ref": "components/schemas/BulkMember"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A single member record submitted as part of a BulkEnrollmentJob, representing one\nemployee or dependent whose coverage is being created or amended in a batch upload. BulkMember carries\nenough identity and coverage data (name, date of birth, product code, effective date) for the enrollment\nservice to validate and bind a policy without a live quote flow. Successfully processed BulkMember records\nresult in a fully active Member and MemberCoverage; failed rows generate BulkEnrollmentJobError entries.\n",
      "rdfs:label": "Bulk Member"
    },
    {
      "@id": "olly:Charge",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Charge"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:termId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:claimId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:claimLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:category",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:amount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:chargeDate",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:description",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Premium Billing Cycle",
          "docs/site/domain/billing.md § Ledger Entries (Double-Entry)"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.charges"
          }
        ],
        "socotra": [
          {
            "schema": "ChargeRef",
            "spec_ref": "components/schemas/ChargeRef"
          },
          {
            "schema": "ChargeCreateRequest",
            "spec_ref": "components/schemas/ChargeCreateRequest"
          },
          {
            "schema": "ChargeResponse",
            "spec_ref": "components/schemas/ChargeResponse"
          }
        ]
      },
      "rdfs:comment": "A discrete monetary obligation raised against an Account, categorised as PREMIUM, TAX, or FEE.\nCharges are the atomic unit of billing: each InvoiceLineItem references exactly one Charge, and each\nCharge generates a corresponding DEBIT LedgerEntry. Aligned to Socotra's Charge resource, which\nsimilarly represents a fee or premium amount applied to a policy account.\n",
      "rdfs:label": "Charge"
    },
    {
      "@id": "olly:Claim",
      "@type": "owl:Class",
      "olly:alignments": {
        "fhir": "fhir:Claim",
        "fibo": "fibo-fbc-pas-fpas:Claim",
        "socotra": "socotra:Claim"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:termId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:claimantPartyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:incidentDate",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:document",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:lifecycle": {
        "states": [
          "submitted",
          "in_review",
          "approved",
          "denied",
          "paid",
          "appealed"
        ]
      },
      "olly:ownerService": "claims",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § Claim State Machine",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "kafka": [
          {
            "schema": "Claim",
            "service": "claims"
          }
        ],
        "openapi": [
          {
            "schema": "Claim",
            "service": "claims"
          },
          {
            "method": "GET",
            "path": "/claims",
            "service": "claims"
          },
          {
            "method": "POST",
            "path": "/claims",
            "service": "claims"
          },
          {
            "method": "GET",
            "path": "/claims/{claimId}",
            "service": "claims"
          },
          {
            "method": "GET",
            "path": "/claims",
            "service": "member-portal-api"
          },
          {
            "method": "POST",
            "path": "/claims",
            "service": "member-portal-api"
          },
          {
            "method": "GET",
            "path": "/claims/{locator}",
            "service": "member-portal-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "claims",
            "table": "claims.claims"
          }
        ],
        "socotra": [
          {
            "schema": "ClaimRef",
            "spec_ref": "components/schemas/ClaimRef"
          }
        ]
      },
      "rdfs:comment": "A member's request for reimbursement of covered medical services. Claims are submitted\ncomplete and progress through adjudication (SUBMITTED → UNDER_REVIEW → APPROVED/REJECTED → PAID → CLOSED).\nEach Claim is itemised into ClaimLine records and may carry supporting ClaimDocument attachments.\nAligned to Socotra's Claim resource, which also represents an insurance loss event progressing through\nan adjudication lifecycle.\n",
      "rdfs:label": "Claim",
      "rdfs:subClassOf": "fibo-fbc-pas-fpas:Claim"
    },
    {
      "@id": "olly:ClaimDetail",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "member-portal-api",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/claims/fnol.md (claim lifecycle and data model)"
        ],
        "openapi": [
          {
            "schema": "ClaimDetail",
            "spec": "api/openapi/member-portal-api.yaml",
            "spec_ref": "components/schemas/ClaimDetail"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A denormalised read model that aggregates a Claim together with its ClaimLines,\nadjudication outcome, prior-auth reference, and payment amounts into a single response payload for the\nmember portal. ClaimDetail avoids multiple round-trips when displaying a claim receipt or EOB to a member.\nIt is not a separately persisted entity; the claims service assembles it on the fly from the underlying\nrelational tables and exposes it through the member-portal-api contract.\n",
      "rdfs:label": "Claim Detail"
    },
    {
      "@id": "olly:ClaimDocument",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:claimId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:filename",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:contentType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:url",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:uploadedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "claims",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § What Happens at Each Transition"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "claims",
            "table": "claims.claim_documents"
          }
        ]
      },
      "rdfs:comment": "A supporting file attached to a Claim during adjudication, such as a medical\ninvoice, discharge summary, or diagnostic report. ClaimDocument records store the S3 URL, content type, and\nupload timestamp; they are created when a claim enters PENDING_INFO status.\n",
      "rdfs:label": "Claim Document"
    },
    {
      "@id": "olly:ClaimEvent",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:claimId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:eventType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:fromStatus",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:toStatus",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:actor",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:note",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "claims",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § Appeal Process"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "claims",
            "table": "claims.claim_events"
          }
        ]
      },
      "rdfs:comment": "An immutable audit record of every status change, actor action, and note on a Claim.\nClaimEvents are append-only and include APPEAL_SUBMITTED and APPEAL_DENIED events alongside normal state\ntransitions, forming a complete adjudication audit trail.\n",
      "rdfs:label": "Claim Event"
    },
    {
      "@id": "olly:ClaimLine",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:claimId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:lineNumber",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:elementId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:coverageTermKey",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:description",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:amountClaimed",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:amountAllowed",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:amountPaid",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:reasonCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:metadata",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "claims",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § ClaimLine Explained"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "claims",
            "table": "claims.claim_lines"
          }
        ]
      },
      "rdfs:comment": "One itemised procedure or service within a Claim, corresponding to a loop in an EDI\n837 transaction. Records the billed amount (AmountClaimed), the plan-allowed amount (AmountAllowed), and the\nplan's payment (AmountPaid), with ANSI X12 reason codes for any contractual adjustment.\n",
      "rdfs:label": "Claim Line"
    },
    {
      "@id": "olly:ClaimSubmission",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "claims",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/claims/fnol.md (first notice of loss and claim creation)"
        ],
        "openapi": [
          {
            "schema": "ClaimSubmission",
            "spec": "api/openapi/claims.yaml",
            "spec_ref": "components/schemas/ClaimSubmission"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "The intake payload a member or provider submits to initiate the claims adjudication\nprocess. A ClaimSubmission bundles the member identifier, incident date, diagnosis codes, procedure codes,\nprovider reference, and any supporting document references into a single request. On successful ingestion\nthe claims service creates a Claim entity and transitions it to the SUBMITTED state, from which\nadjudication, prior-auth checks, and payment flow proceed.\n",
      "rdfs:label": "Claim Submission"
    },
    {
      "@id": "olly:ClaimSummary",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "member-portal-api",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/claims/fnol.md (claim data model overview)"
        ],
        "openapi": [
          {
            "schema": "ClaimSummary",
            "spec": "api/openapi/member-portal-api.yaml",
            "spec_ref": "components/schemas/ClaimSummary"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A lightweight projection of a Claim designed for list views in the member portal and\nbroker dashboard, returning only the fields needed for scanning — claim reference, date of service, provider\nname, status, and total amount — without the full line-item detail. ClaimSummary is generated by the claims\nservice at query time and is not persisted independently; it complements ClaimDetail by giving consumers a\nfast, paginated overview before they drill into individual claims.\n",
      "rdfs:label": "Claim Summary"
    },
    {
      "@id": "olly:Commission",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:brokerId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:rate",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:amount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "broker-api",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Commission",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/commissions",
            "service": "broker-api"
          },
          {
            "method": "POST",
            "path": "/commissions",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/commissions/{locator}",
            "service": "broker-api"
          },
          {
            "method": "PATCH",
            "path": "/commissions/{locator}/pay",
            "service": "broker-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "broker-api",
            "table": "broker_api.commissions"
          }
        ]
      },
      "rdfs:comment": "A fee payable to a broker when a policy they introduced is bound or renewed.\nCommission records capture the applicable rate, computed amount, and settlement status, and are reconciled\nagainst invoices generated by the billing service.\n",
      "rdfs:label": "Commission"
    },
    {
      "@id": "olly:Condition",
      "@type": "owl:Class",
      "olly:alignments": {
        "fhir": "fhir:Condition",
        "snomed": "snomed:64572001"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:conditionText",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "snapshot": [
          {
            "file": "docs/superpowers/snapshots/2026-04-30-pre-code-evolution/ontology/concepts/domain/condition.yaml",
            "reason": "hand-curated v0 — alignments and lifecycle ported forward"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A clinically established diagnosis attached to a Member, sourced from\nEncounter outputs or self-reported history.\nAspirational: not currently backed by an Olly service or Postgres table.\n",
      "rdfs:label": "Condition"
    },
    {
      "@id": "olly:ConfigBundle",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/policyManagement/policyManagementTopicIndex.md (tenant configuration concepts)"
        ],
        "openapi": [
          {
            "schema": "ConfigBundle",
            "spec": "api/openapi/policy-admin.yaml",
            "spec_ref": "components/schemas/ConfigBundle"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A versioned, tenant-scoped package of product and billing configuration that is\ndeployed atomically to the policy-admin service. A ConfigBundle bundles product definitions, rule sets,\nmarket profiles, document templates, and installment plan settings into a single artifact, ensuring that\nall configuration is consistent and auditable. Deploying a new ConfigBundle version advances the active\nproduct configuration without requiring individual resource updates, supporting zero-downtime configuration\nreleases.\n",
      "rdfs:label": "Config Bundle"
    },
    {
      "@id": "olly:ConsentItem",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "consent",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/workManagement/userAssociations.md (user data governance context)"
        ],
        "openapi": [
          {
            "schema": "ConsentItem",
            "spec": "api/openapi/consent.yaml",
            "spec_ref": "components/schemas/ConsentItem"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A single discrete consent decision within a ConsentRecord, capturing the consent type\n(e.g. NHS_DATA_SHARING, MARKETING_EMAIL, THIRD_PARTY_ACCESS), the decision value (granted or withdrawn),\nand the timestamp at which the decision was recorded. ConsentItems provide the granular audit trail\nrequired under GDPR Article 7 and NHS data governance standards, allowing each consent category to be\nindependently granted or withdrawn without affecting the member's other consent preferences.\n",
      "rdfs:label": "Consent Item"
    },
    {
      "@id": "olly:ConsentRecord",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:partyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:consentType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:granted",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:boolean"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "consent",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § Consent Types and Why They Matter"
        ],
        "openapi": [
          {
            "method": "GET",
            "path": "/consent/{partyLocator}",
            "service": "consent"
          },
          {
            "method": "PUT",
            "path": "/consent/{partyLocator}",
            "service": "consent"
          },
          {
            "method": "GET",
            "path": "/consent/{partyLocator}/audit",
            "service": "consent"
          },
          {
            "method": "GET",
            "path": "/consent",
            "service": "member-portal-api"
          },
          {
            "method": "PUT",
            "path": "/consent",
            "service": "member-portal-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "consent",
            "table": "consent.consent_records"
          }
        ]
      },
      "rdfs:comment": "A member's preference for a specific consent type (e.g. NHS_DATA_SHARING,\nWEARABLE_SYNC, MARKETING_COMMUNICATIONS), keyed by (PartyLocator, ConsentType). At most one record per\ncombination exists; the Granted boolean captures the current preference.\n",
      "rdfs:label": "Consent Record"
    },
    {
      "@id": "olly:Contact",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Contact"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "ContactRef",
            "spec_ref": "components/schemas/ContactRef"
          },
          {
            "schema": "ContactCreateRequest",
            "spec_ref": "components/schemas/ContactCreateRequest"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A named contact point associated with an Account or Policy — distinct from the Account holder Party.\nContacts carry a name, role (e.g. BILLING_CONTACT, BENEFITS_ADMINISTRATOR), email, and phone, enabling\nmultiple communication targets per account. In Olly, contact information is currently embedded in the\nParty record; Contact as a separate entity is aspirational. Concept sourced from Socotra; not yet\nmodeled in Olly code.\n",
      "rdfs:label": "Contact"
    },
    {
      "@id": "olly:Conversation",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:orgLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:userSub",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:title",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:persona",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "ai-chat",
      "olly:referencedIn": {
        "postgres": [
          {
            "pk": "id",
            "service": "ai-chat",
            "table": "conversations"
          }
        ]
      },
      "rdfs:comment": "An AI chat session between a user and the Olly AI assistant, scoped to an\norganisation (org_locator). Conversations contain an ordered sequence of Messages and carry a persona\nidentifier that controls the assistant's behaviour.\n",
      "rdfs:label": "Conversation"
    },
    {
      "@id": "olly:Coverage",
      "@type": "owl:Class",
      "olly:alignments": {
        "fhir": "fhir:Coverage",
        "fibo": "fibo-fbc-pas-fpas:InsuranceCoverage"
      },
      "olly:layer": "domain",
      "olly:ownerService": "eligibility",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § PolicyElement"
        ],
        "openapi": [
          {
            "method": "GET",
            "path": "/check",
            "service": "eligibility"
          },
          {
            "method": "GET",
            "path": "/members/{memberId}/coverage",
            "service": "eligibility"
          },
          {
            "method": "GET",
            "path": "/coverage",
            "service": "member-portal-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "eligibility",
            "table": "eligibility.member_coverage"
          }
        ]
      },
      "rdfs:comment": "The abstract insurance entitlement a Member holds under a Policy at a given point in\ntime. Coverage is the eligibility service's read model: it denormalises PolicyElement and MemberCoverage data\ninto a queryable form for fast eligibility checks during claim adjudication.\n",
      "rdfs:label": "Coverage"
    },
    {
      "@id": "olly:CoverageAccumulator",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:partyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:termId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accumulatorType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:coverageTermKey",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:limitAmount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:consumedAmount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:lastClaimLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "eligibility",
      "olly:referencedIn": {
        "docs": [
          "docs/architecture/overview.md § Data Flow"
        ],
        "openapi": [
          {
            "method": "GET",
            "path": "/members/{memberId}/deductible",
            "service": "eligibility"
          },
          {
            "method": "GET",
            "path": "/accumulators",
            "service": "member-portal-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "eligibility",
            "table": "eligibility.coverage_accumulators"
          }
        ]
      },
      "rdfs:comment": "A running balance tracking how much of a benefit limit a Member has consumed\nin a PolicyTerm — deductible, out-of-pocket maximum, or benefit-category cap. Accumulators are loaded and\nupdated during adjudication to determine how much the plan pays on each ClaimLine.\n",
      "rdfs:label": "Coverage Accumulator"
    },
    {
      "@id": "olly:CoverageTerm",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:CoverageTerm"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § PolicyTerm and PolicyElement"
        ],
        "socotra": [
          {
            "schema": "CoverageTermRef",
            "spec_ref": "components/schemas/CoverageTermRef"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A discrete benefit category within a product definition, specifying the type of coverage (e.g.\nINPATIENT_HOSPITAL, OUTPATIENT_SPECIALIST, MENTAL_HEALTH) and its associated benefit parameters such\nas copay, coinsurance percentage, deductible, and annual limit. In Olly, CoverageTerms are currently\nembedded as a JSONB blob on PolicyElement; Socotra models them as a first-class configurable resource.\nConcept sourced from Socotra; not yet modeled as a separate entity in Olly code.\n",
      "rdfs:label": "Coverage Term"
    },
    {
      "@id": "olly:CredentialingRequest",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:providerId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:submittedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:reviewedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:reviewerNotes",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "provider",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/providers.md § Credentialing Lifecycle"
        ],
        "openapi": [
          {
            "method": "POST",
            "path": "/credentialing",
            "service": "provider"
          },
          {
            "method": "GET",
            "path": "/credentialing/{npi}/status",
            "service": "provider"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "provider",
            "table": "provider.credentialing_requests"
          }
        ]
      },
      "rdfs:comment": "A provider's application to join the Olly network, implemented as a\nTemporal workflow to handle the multi-week human review process. Records submission timestamp, reviewer\ndecision (APPROVED/REJECTED), and reviewer notes; on approval, Provider.NetworkStatus is set to ACTIVE.\n",
      "rdfs:label": "Credentialing Request"
    },
    {
      "@id": "olly:CredentialingStatus",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "provider",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/policyManagement/policyStatus.md (status lifecycle patterns)"
        ],
        "openapi": [
          {
            "schema": "CredentialingStatus",
            "spec": "api/openapi/provider.yaml",
            "spec_ref": "components/schemas/CredentialingStatus"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A read-model snapshot of where a CredentialingRequest currently stands in the provider\nverification lifecycle. CredentialingStatus exposes the stage (e.g. DOCUMENTS_RECEIVED, VERIFICATION_IN_PROGRESS,\nAPPROVED, SUSPENDED), the date the last status change occurred, and any blocking reason notes. Brokers and\nnetwork managers query it to track which providers are cleared for service without reading the full\ncredentialing workflow history; it is updated whenever the underlying CredentialingRequest transitions\nstate.\n",
      "rdfs:label": "Credentialing Status"
    },
    {
      "@id": "olly:Credit",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Credit"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Ledger Entries (Double-Entry)"
        ],
        "socotra": [
          {
            "schema": "CreditResponse",
            "spec_ref": "components/schemas/CreditResponse"
          },
          {
            "schema": "CreditListResponse",
            "spec_ref": "components/schemas/CreditListResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "An unapplied balance on an Account that can be applied against future invoices — arising from\noverpayments, mid-term cancellation refunds, or goodwill adjustments. Credits are distributed\n(CreditDistribution) to specific invoices to reduce the amount due. In Olly, credits are currently\nhandled as CREDIT-direction LedgerEntries and Adjustment records; Socotra models them as a distinct\ndistributable entity. Concept sourced from Socotra; not yet a separate entity in Olly code.\n",
      "rdfs:label": "Credit"
    },
    {
      "@id": "olly:DeductibleStatus",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "eligibility",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/policyManagement/coverageTerms.md (deductible and limit coverage term types)"
        ],
        "openapi": [
          {
            "schema": "DeductibleStatus",
            "spec": "api/openapi/eligibility.yaml",
            "spec_ref": "components/schemas/DeductibleStatus"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A real-time snapshot of a member's progress toward satisfying the deductible threshold\non their active coverage for the current benefit period. DeductibleStatus combines the configured deductible\nlimit from the coverage terms with the year-to-date amounts applied from adjudicated claims, exposing the\nremaining balance a member must pay before the insurer begins covering costs. It is computed by the\neligibility service from AccumulatorBucket values and coverage term data, and is surfaced during eligibility\nchecks and in the member portal.\n",
      "rdfs:label": "Deductible Status"
    },
    {
      "@id": "olly:DeletionRequest",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:partyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:deleteType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:requestedByType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:reason",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:requestedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:completedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:attemptCount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "consent",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § GDPR Deletion Workflow"
        ],
        "openapi": [
          {
            "method": "POST",
            "path": "/consent/{partyLocator}/deletion",
            "service": "consent"
          },
          {
            "method": "GET",
            "path": "/consent/{partyLocator}/deletion/{id}",
            "service": "consent"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "consent",
            "table": "consent.deletion_requests"
          }
        ]
      },
      "rdfs:comment": "A GDPR Article 17 right-to-erasure request for a Party. SOFT deletion\nanonymises PHI fields while preserving referential integrity; HARD deletion purges all party data with\ntombstones. A Temporal workflow fans out the request to every service holding PHI for that PartyLocator.\n",
      "rdfs:label": "Deletion Request"
    },
    {
      "@id": "olly:Delinquency",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Delinquency"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Grace Period and Delinquency Handling"
        ],
        "socotra": [
          {
            "schema": "DelinquencyResponse",
            "spec_ref": "components/schemas/DelinquencyResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A formal delinquency record created when an Invoice remains unpaid past its grace period. Delinquency\ntracks the escalation timeline from missed payment through lapse notification to cancellation, and may\nbe subject to a moratorium (suspension of delinquency processing). In Olly, delinquency state is\ncurrently embedded in Invoice and Policy fields; Socotra models it as a standalone lifecycle entity.\nConcept sourced from Socotra; not yet a separate entity in Olly code.\n",
      "rdfs:label": "Delinquency"
    },
    {
      "@id": "olly:DiagnosticsReferral",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:episodeLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:referralType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:clinicLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:appointmentLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "care",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "GET",
            "path": "/episodes/{locator}/referrals",
            "service": "care"
          },
          {
            "method": "POST",
            "path": "/episodes/{locator}/referrals",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/referrals/{locator}/book",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/referrals/{locator}/complete",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/referrals/{locator}/cancel",
            "service": "care"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "care",
            "table": "diagnostics_referrals"
          }
        ]
      },
      "rdfs:comment": "A care-pathway instruction for a Member to undergo diagnostic tests (imaging,\nblood work, etc.), generated within a clinical Episode. Records the referring provider, target clinic, referral\ntype, and the resulting Appointment locator once booked.\n",
      "rdfs:label": "Diagnostics Referral"
    },
    {
      "@id": "olly:DiaryEntry",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:DiaryEntry"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "DiaryEntryResponse",
            "spec_ref": "components/schemas/DiaryEntryResponse"
          },
          {
            "schema": "DiaryEntryCreateRequest",
            "spec_ref": "components/schemas/DiaryEntryCreateRequest"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A time-stamped note or task record attached to an insurance entity (policy, claim, account), used by\noperations teams to track action items, follow-ups, and adjudicator notes. DiaryEntries differ from\naudit events in that they are authored by humans for human consumption and can be updated. Concept\nsourced from Socotra; in Olly, notes are currently embedded in claim and credentialing event records.\n",
      "rdfs:label": "Diary Entry"
    },
    {
      "@id": "olly:Disbursement",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Disbursement"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § What Happens at Each Transition"
        ],
        "socotra": [
          {
            "schema": "DisbursementRef",
            "spec_ref": "components/schemas/DisbursementRef"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "An outbound payment from the insurer to a payee — such as a claims payment to a provider or a refund\nto a policyholder. Disbursements are distinct from Payments (inbound premium receipts) and are tracked\nseparately for cash management and regulatory reporting. Concept sourced from Socotra; in Olly, provider\nclaim payments are currently modelled as outbound Payment records rather than a distinct Disbursement entity.\n",
      "rdfs:label": "Disbursement"
    },
    {
      "@id": "olly:Document",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Document"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:templateType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:marketCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:content",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "document-service",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § EDI 837 / 835 Context",
          "docs/architecture/overview.md § Data Flow"
        ],
        "openapi": [
          {
            "schema": "Document",
            "service": "document-service"
          },
          {
            "method": "GET",
            "path": "/documents/{locator}",
            "service": "document-service"
          },
          {
            "method": "GET",
            "path": "/eob/{claimId}",
            "service": "billing"
          },
          {
            "method": "GET",
            "path": "/documents",
            "service": "member-portal-api"
          },
          {
            "method": "GET",
            "path": "/documents/{locator}",
            "service": "member-portal-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "document-service",
            "table": "documents.documents"
          }
        ],
        "socotra": [
          {
            "schema": "DocumentListResponse",
            "spec_ref": "components/schemas/DocumentListResponse"
          },
          {
            "schema": "DocumentEventData",
            "spec_ref": "components/schemas/DocumentEventData"
          }
        ]
      },
      "rdfs:comment": "A generated or uploaded file associated with a policy, claim, or member record. Documents\ninclude policy schedules, Explanations of Benefit (EOBs), EDI-generated PDFs, and consent forms. Files are\nstored in S3 with SSE-KMS encryption and referenced by URL. Aligned to Socotra's Document resource, which\nsimilarly represents persisted document instances attached to insurance entities.\n",
      "rdfs:label": "Document"
    },
    {
      "@id": "olly:DocumentSummary",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "member-portal-api",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/documents/documentManagement.md (document retrieval and association)"
        ],
        "openapi": [
          {
            "schema": "DocumentSummary",
            "spec": "api/openapi/member-portal-api.yaml",
            "spec_ref": "components/schemas/DocumentSummary"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A lightweight projection of a Document containing only the metadata fields needed for\nlist and browse views — document reference, type, associated entity (policy or claim), creation date, and\ndownload URL — without the full binary payload. DocumentSummary allows the member portal to display a\ndocument inbox and let members choose which files to download, deferring retrieval of the actual content\nuntil explicitly requested. It mirrors the document management pattern described in the Socotra platform,\nwhere documents are associated with policies, transactions, quotes, and claims and retrieved by reference.\n",
      "rdfs:label": "Document Summary"
    },
    {
      "@id": "olly:EligibilityRoster",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "group-scheme-service",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/policyManagement/policyStatus.md (coverage and policy status)"
        ],
        "openapi": [
          {
            "schema": "EligibilityRoster",
            "spec": "api/openapi/group-scheme-service.yaml",
            "spec_ref": "components/schemas/EligibilityRoster"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A consolidated snapshot of eligibility status for every active member in a Group Scheme,\nused by HR administrators and brokers to verify that all employees have valid, in-force coverage. The\nEligibilityRoster aggregates MemberCoverage records across the scheme's policies and returns a structured\nlist showing each member's coverage tier, effective date, and eligibility status. It is assembled on demand\nfrom eligibility service data rather than persisted independently, and serves as the primary audit artefact\nfor group scheme compliance checks.\n",
      "rdfs:label": "Eligibility Roster"
    },
    {
      "@id": "olly:Encounter",
      "@type": "owl:Class",
      "olly:alignments": {
        "fhir": "fhir:Encounter"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:encounterType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:performedBy",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "olly:Provider"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "snapshot": [
          {
            "file": "docs/superpowers/snapshots/2026-04-30-pre-code-evolution/ontology/concepts/domain/encounter.yaml",
            "reason": "hand-curated v0 — alignments and lifecycle ported forward"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A clinical interaction between a Member and a Provider — appointment,\nhospital admission, telehealth call, etc.\nAspirational: not currently backed by an Olly service or Postgres table.\n",
      "rdfs:label": "Encounter"
    },
    {
      "@id": "olly:Enrollment",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/policyQuotation/quotes.md (quote issuance creating the policy)"
        ],
        "openapi": [
          {
            "schema": "Enrollment",
            "spec": "api/openapi/enrollment.yaml",
            "spec_ref": "components/schemas/Enrollment"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "The act and record of a member being admitted into a coverage product, tying a Party to\na Policy with a defined effective date and coverage tier. An Enrollment is initiated either through the\nquote-and-bind flow (for individual members) or via a BulkEnrollmentJob (for group schemes). Once complete,\nit results in an active MemberCoverage record that gates eligibility checks and claim adjudication. The\nenrollment service orchestrates the transition from a bound quote to an in-force policy, including\ntriggering billing setup and notification dispatch.\n",
      "rdfs:label": "Enrollment"
    },
    {
      "@id": "olly:EOBReference",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/documents/documentManagement.md (document association with financial entities)",
          "socotra/featureGuide/billing/invoicing.md (invoice document rendering)"
        ],
        "openapi": [
          {
            "schema": "EOBReference",
            "spec": "api/openapi/billing.yaml",
            "spec_ref": "components/schemas/EOBReference"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A pointer to an Explanation of Benefits document generated after a claim is adjudicated,\nlinking the claim to the rendered EOB file that details what was billed, what the insurer allowed, what\nwas applied to the deductible, and what the member owes. EOBReference stores the document locator and\nmetadata so the billing and member-portal services can surface the EOB alongside the invoice without\nre-fetching the full claim payload. It is analogous to the document reference pattern used throughout the\nSocotra platform where documents are associated with financial transactions.\n",
      "rdfs:label": "EOB Reference"
    },
    {
      "@id": "olly:Episode",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:triageSessionLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:careType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:summary",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:closedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "care",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Episode",
            "service": "care"
          },
          {
            "method": "GET",
            "path": "/episodes",
            "service": "care"
          },
          {
            "method": "POST",
            "path": "/episodes",
            "service": "care"
          },
          {
            "method": "GET",
            "path": "/episodes/{locator}",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/episodes/{locator}/cancel",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/episodes/{locator}/close",
            "service": "care"
          },
          {
            "method": "GET",
            "path": "/internal/episodes/{locator}",
            "service": "care"
          },
          {
            "method": "GET",
            "path": "/internal/members/{partyLocator}/episodes",
            "service": "care"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "care",
            "table": "episodes"
          }
        ]
      },
      "rdfs:comment": "A bounded care episode — a single clinical interaction or course of treatment — linking a\ntriage Session to one or more Appointments, Prescriptions, and DiagnosticsReferrals. Episodes carry a care\ntype (GP, SPECIALIST, MENTAL_HEALTH) and close when the clinical need is resolved.\n",
      "rdfs:label": "Episode"
    },
    {
      "@id": "olly:FieldDefinition",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:productVersionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:name",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:fieldType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:required",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:boolean"
        },
        {
          "@id": "olly:defaultValue",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:allowedValues",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:displayOrder",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "GET",
            "path": "/products/{productLocator}/versions/{version}/fields",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/products/{productLocator}/versions/{version}/fields",
            "service": "policy-admin"
          },
          {
            "method": "DELETE",
            "path": "/products/{productLocator}/versions/{version}/fields/{fieldLocator}",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.field_definitions"
          }
        ]
      },
      "rdfs:comment": "A product-level metadata schema entry that defines a custom field (name, type,\nrequired flag, allowed values) collectible on policies, quotes, or transactions of a given ProductVersion.\nField definitions drive dynamic form rendering in the employer and member portals.\n",
      "rdfs:label": "Field Definition"
    },
    {
      "@id": "olly:FinancialInstrument",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:FinancialInstrument"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Payment Methods"
        ],
        "socotra": [
          {
            "schema": "FinancialInstrumentResponse",
            "spec_ref": "components/schemas/FinancialInstrumentResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A stored payment method on file for an Account — such as a bank account (for direct debit), credit\ncard token (for card payments), or ACH routing details. FinancialInstruments are used by the autopay\nand billing services to initiate payment collection without requiring the account holder to re-enter\npayment details. Concept sourced from Socotra; Olly stores payment method details in payment gateway\ntokens but has no explicit FinancialInstrument entity yet.\n",
      "rdfs:label": "Financial Instrument"
    },
    {
      "@id": "olly:Fnol",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Fnol"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § Claim State Machine"
        ],
        "socotra": [
          {
            "schema": "FnolResponse",
            "spec_ref": "components/schemas/FnolResponse"
          },
          {
            "schema": "FnolCreateRequest",
            "spec_ref": "components/schemas/FnolCreateRequest"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "First Notice of Loss — the initial report filed by a policyholder or claimant to notify the insurer\nof an insured event before a full claim is submitted. An FNOL captures the date, nature, and location\nof the loss and creates a claim shell that the adjudication team can enrich. In Olly's current model,\nclaims are submitted complete; FNOL as a pre-claim stage is not yet implemented. Concept sourced from\nSocotra; not yet modeled in Olly code.\n",
      "rdfs:label": "FNOL"
    },
    {
      "@id": "olly:InstallmentPlan",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:InstallmentPlan"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Installment Schedules"
        ],
        "socotra": [
          {
            "schema": "InstallmentPlanRef",
            "spec_ref": "components/schemas/InstallmentPlanRef"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A configuration template that defines the frequency, number of installments, and billing rules for\nsplitting a premium into periodic payments. InstallmentPlans are assigned to products or accounts and\ndrive the generation of InstallmentSchedule instances. Concept sourced from Socotra; not yet modeled\nas a separate entity in Olly code (currently embedded in InstallmentSchedule).\n",
      "rdfs:label": "Installment Plan"
    },
    {
      "@id": "olly:InstallmentSchedule",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:totalAmount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:frequency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:installments",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:startDate",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Installment Schedules"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.installment_schedules"
          }
        ]
      },
      "rdfs:comment": "A plan for splitting an annual premium into periodic invoices. The billing\nscheduler reads active InstallmentSchedules and generates the next Invoice on each due date until all\ninstallments are exhausted, supporting MONTHLY, QUARTERLY, and ANNUAL frequencies.\n",
      "rdfs:label": "Installment Schedule"
    },
    {
      "@id": "olly:Invoice",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Invoice"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:totalAmount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:dueDate",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:finalisedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:paidAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Invoice Lifecycle",
          "docs/site/domain/billing.md § Grace Period and Delinquency Handling",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "kafka": [
          {
            "schema": "Invoice",
            "service": "billing"
          }
        ],
        "openapi": [
          {
            "schema": "Invoice",
            "service": "billing"
          },
          {
            "method": "GET",
            "path": "/invoices",
            "service": "billing"
          },
          {
            "method": "GET",
            "path": "/invoices/{invoiceId}",
            "service": "billing"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.invoices"
          }
        ],
        "socotra": [
          {
            "schema": "InvoiceResponse",
            "spec_ref": "components/schemas/InvoiceResponse"
          },
          {
            "schema": "InvoiceListResponse",
            "spec_ref": "components/schemas/InvoiceListResponse"
          }
        ]
      },
      "rdfs:comment": "A demand for premium payment issued to an Account for one billing period. Invoices progress\nthrough DRAFT → FINALISED → PAID (or VOID). Each Invoice contains one or more InvoiceLineItem rows and carries\ngrace period and delinquency timestamps used to trigger policy lapse. Aligned to Socotra's Invoice resource,\nwhich also models a billing statement with lifecycle states and settlement tracking.\n",
      "rdfs:label": "Invoice"
    },
    {
      "@id": "olly:InvoiceLineItem",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:invoiceId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:chargeId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:amount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:description",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Premium Billing Cycle"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.invoice_line_items"
          }
        ]
      },
      "rdfs:comment": "One line on an Invoice, linking to a specific Charge record (PREMIUM, TAX, or\nFEE) and its amount. The sum of all InvoiceLineItem amounts equals Invoice.TotalAmount; this denormalisation\nenables efficient invoice rendering without re-summing charges.\n",
      "rdfs:label": "Invoice Line Item"
    },
    {
      "@id": "olly:Judgement",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:sessionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:judgeModel",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:rubricVersion",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:toneScore",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:prdComplianceScore",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:safetyScore",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:summary",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:judgeInputTokens",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:judgeOutputTokens",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "triage",
      "olly:referencedIn": {
        "postgres": [
          {
            "pk": "id",
            "service": "triage",
            "table": "triage.judgements"
          }
        ]
      },
      "rdfs:comment": "An automated quality-scoring evaluation of a triage Session by a judge LLM, scoring\ntone, PRD compliance, and safety against a rubric. Judgements are produced by the triage evaluation harness\nand stored to track model regression across prompt versions.\n",
      "rdfs:label": "Judgement"
    },
    {
      "@id": "olly:LedgerAccount",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:LedgerAccount"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Ledger Entries (Double-Entry)"
        ],
        "socotra": [
          {
            "schema": "LedgerAccountResponse",
            "spec_ref": "components/schemas/LedgerAccountResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A named chart-of-accounts entry in the double-entry bookkeeping system, representing a category\nsuch as PREMIUM_RECEIVABLE, TAX_PAYABLE, or CLAIMS_EXPENSE. LedgerAccounts provide the account\nclassification dimension for regulatory financial reporting and actuarial analysis. In Olly, LedgerEntry\nrecords carry direction and type but are not yet categorised against a formal chart of accounts.\nConcept sourced from Socotra; not yet modeled in Olly code.\n",
      "rdfs:label": "Ledger Account"
    },
    {
      "@id": "olly:LedgerEntry",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:entryType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:referenceId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:referenceType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:direction",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:amount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:description",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Ledger Entries (Double-Entry)",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.ledger_entries"
          }
        ]
      },
      "rdfs:comment": "A double-entry bookkeeping record for every financial movement on an Account.\nEntryType values are CHARGE, PAYMENT, ADJUSTMENT_DEBIT, ADJUSTMENT_CREDIT, and REVERSAL; Direction is DEBIT\nor CREDIT. The net sum of all LedgerEntries for an Account equals its current balance.\n",
      "rdfs:label": "Ledger Entry"
    },
    {
      "@id": "olly:MarketProfile",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:code",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:currentVersion",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "POST",
            "path": "/market-profiles",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/market-profiles/{code}",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/market-profiles/list",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/market-profiles/{code}/current",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/internal/market-profiles/{code}/current",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.market_profiles"
          }
        ]
      },
      "rdfs:comment": "A versioned regulatory and billing configuration bundle for a specific jurisdiction\nor market segment. MarketProfiles govern which product features are available, which regulatory regime applies,\nand which document templates are used — enabling multi-market operation from a single platform.\n",
      "rdfs:label": "Market Profile"
    },
    {
      "@id": "olly:MarketProfileVersion",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:marketProfileId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:version",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:jurisdictionCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:regulatoryRegime",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:featureFlags",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:billingRules",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:mandatoryFields",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:documentTemplates",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:publishedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "POST",
            "path": "/market-profiles/{code}/versions",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/market-profiles/{code}/versions/list",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/market-profiles/{code}/versions/{version}",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/market-profiles/{code}/versions/{version}",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/market-profiles/{code}/versions/{version}/publish",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.market_profile_versions"
          }
        ]
      },
      "rdfs:comment": "A published snapshot of a MarketProfile at a point in time, capturing\njurisdiction code, regulatory regime, feature flags, billing rules, mandatory fields, and document template\nassignments. Policies reference the MarketProfileVersion in force at their inception date.\n",
      "rdfs:label": "Market Profile Version"
    },
    {
      "@id": "olly:Medication",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "care",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Medication",
            "spec": "api/openapi/care.yaml",
            "spec_ref": "components/schemas/Medication"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A reference to a drug or therapeutic agent within Olly's clinical data model, used\nprimarily in the context of Prescriptions issued during a care Episode. Medication records carry the drug\nname, formulary classification, and any relevant prior-auth requirements, enabling the platform to check\nwhether a prescribed drug is covered under a member's benefit plan before dispensing. The concept is\nclinical in origin and has no direct Socotra analogue; it exists in Olly to support the triage and care\npathway services.\n",
      "rdfs:label": "Medication"
    },
    {
      "@id": "olly:Member",
      "@type": "owl:Class",
      "olly:alignments": {
        "fhir": "fhir:Patient",
        "schema_org": "schema:Person"
      },
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § The Party Model",
          "docs/site/domain/index.md § People Concepts"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.parties"
          }
        ]
      },
      "rdfs:comment": "An individual insured person (primary subscriber or dependent) covered under a\nPolicyElement. A Member's identity is stored as a Party of type INDIVIDUAL; their coverage entitlements are in\nMemberCoverage. The term \"member\" is the business-facing umbrella for any covered person.\n",
      "rdfs:label": "Member",
      "rdfs:subClassOf": "schema:Person",
      "skos:altLabel": [
        "Insured",
        "Beneficiary"
      ]
    },
    {
      "@id": "olly:MemberCoverage",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:partyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyElementId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:elementStaticId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:termId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:productCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:elementType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:coverageTerms",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:effectiveFrom",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:effectiveTo",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "eligibility",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "eligibility",
            "table": "eligibility.member_coverage"
          }
        ]
      },
      "rdfs:comment": "The eligibility service's denormalised read model of a Member's active coverage\non a Policy and PolicyTerm. Populated by consuming enrollment.completed events, it enables fast eligibility\nlookups during claim adjudication without joining across enrollment tables.\n",
      "rdfs:label": "Member Coverage"
    },
    {
      "@id": "olly:Message",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:conversationId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:role",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:content",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:toolCalls",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:tokenUsage",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "ai-chat",
      "olly:referencedIn": {
        "postgres": [
          {
            "pk": "id",
            "service": "ai-chat",
            "table": "messages"
          }
        ]
      },
      "rdfs:comment": "A single turn in an AI chat Conversation — either a user message or an assistant\nresponse. Messages store the LLM role (user/assistant/tool), content, tool call metadata, and token usage\nfor cost tracking and prompt tracing via Langfuse.\n",
      "rdfs:label": "Message"
    },
    {
      "@id": "olly:Moratorium",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Moratorium"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "MoratoriumRef",
            "spec_ref": "components/schemas/MoratoriumRef"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A temporary suspension of billing enforcement actions (delinquency escalation, lapse, cancellation)\nfor a defined set of policies — typically applied during regulatory-mandated relief periods or\ncatastrophe events. Moratoriums carry match criteria to identify affected policies and a rule set\ngoverning which billing events are suppressed. Concept sourced from Socotra; not yet modeled in\nOlly code.\n",
      "rdfs:label": "Moratorium"
    },
    {
      "@id": "olly:NotificationLog",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:eventId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:eventType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:channel",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:subject",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:body",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:failureReason",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:attemptCount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:sentAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "notifications",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "POST",
            "path": "/send",
            "service": "notifications"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "notifications",
            "table": "notifications.notification_log"
          }
        ]
      },
      "rdfs:comment": "A delivery record for a single outbound notification (push, SMS, or email) sent\non behalf of a domain event. Captures the channel, status (SENT/FAILED), subject, body preview, attempt\ncount, and failure reason to support retry logic and delivery auditing.\n",
      "rdfs:label": "Notification Log"
    },
    {
      "@id": "olly:NotificationPreference",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:partyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:email",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:phone",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:preferredChannel",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:optedOutEvents",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "notifications",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "GET",
            "path": "/preferences",
            "service": "notifications"
          },
          {
            "method": "PUT",
            "path": "/preferences",
            "service": "notifications"
          },
          {
            "method": "GET",
            "path": "/preferences",
            "service": "member-portal-api"
          },
          {
            "method": "PUT",
            "path": "/preferences",
            "service": "member-portal-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "notifications",
            "table": "notifications.notification_preferences"
          }
        ]
      },
      "rdfs:comment": "A Member's channel and opt-out preferences for notifications. Records\npreferred delivery channel (PUSH, SMS, EMAIL), contact details, and the list of event types the member has\nexplicitly opted out of receiving.\n",
      "rdfs:label": "Notification Preference"
    },
    {
      "@id": "olly:NotificationPreferences",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "notifications",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "NotificationPreferences",
            "spec": "api/openapi/notifications.yaml",
            "spec_ref": "components/schemas/NotificationPreferences"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "The aggregate container of all NotificationPreference records for a given Member,\nrepresenting their complete channel and opt-in/opt-out configuration across event types. The notifications\nservice reads this container when deciding how to route an outbound notification — email, SMS, push, or\nin-app — checking each preference before dispatching. NotificationPreferences is returned as a single\nstructured object by the GET preferences endpoint so that the member portal can render the full preferences\nscreen in one call without assembling individual records client-side.\n",
      "rdfs:label": "Notification Preferences"
    },
    {
      "@id": "olly:Party",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:type",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:firstName",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:lastName",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:name",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:email",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:phone",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:address",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:dateOfBirth",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § The Party Model",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "openapi": [
          {
            "schema": "Party",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/parties",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/parties/{locator}",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/parties/{locator}",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/parties/list",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/parties/{locator}/roles/list",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/internal/parties/{locator}",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/clients/parties",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/profile",
            "service": "member-portal-api"
          },
          {
            "method": "PATCH",
            "path": "/profile",
            "service": "member-portal-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.parties"
          }
        ]
      },
      "rdfs:comment": "The unified identity record for any person or organisation on the platform — members,\nemployers, brokers, and providers all share this entity, distinguished by Type (INDIVIDUAL, ORGANISATION,\nPROVIDER). PHI fields are application-layer encrypted before storage; the Locator is the externally\nshareable stable reference.\n",
      "rdfs:label": "Party"
    },
    {
      "@id": "olly:PartyRole",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:partyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:entityType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:entityId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:role",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § PartyRole — Roles on Policies and Accounts"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.party_roles"
          }
        ]
      },
      "rdfs:comment": "A contextual role a Party plays on a specific entity (Account, Policy, or Quote). One\nParty can hold multiple roles across multiple entities — for example, ACCOUNT_HOLDER on an employer account\nand INSURED on individual policies.\n",
      "rdfs:label": "Party Role"
    },
    {
      "@id": "olly:Pathway",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:pathwayCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "snapshot": [
          {
            "file": "docs/superpowers/snapshots/2026-04-30-pre-code-evolution/ontology/concepts/domain/pathway.yaml",
            "reason": "hand-curated v0 — alignments and lifecycle ported forward"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A guided clinical decision flow (NHS 111 style) that maps a presenting\nSymptom set to a recommended care destination.\nAspirational: not currently backed by an Olly service or Postgres table.\n",
      "rdfs:label": "Pathway"
    },
    {
      "@id": "olly:Payment",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Payment"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:invoiceId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:amount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:currency",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:method",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:reference",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:settledAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "billing",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Payment Methods",
          "docs/site/domain/billing.md § Ledger Entries (Double-Entry)",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "kafka": [
          {
            "schema": "Payment",
            "service": "billing"
          }
        ],
        "openapi": [
          {
            "schema": "Payment",
            "service": "billing"
          },
          {
            "method": "POST",
            "path": "/payments",
            "service": "billing"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "billing",
            "table": "billing.payments"
          }
        ],
        "socotra": [
          {
            "schema": "PaymentRef",
            "spec_ref": "components/schemas/PaymentRef"
          },
          {
            "schema": "PaymentCreateRequest",
            "spec_ref": "components/schemas/PaymentCreateRequest"
          },
          {
            "schema": "PaymentResponse",
            "spec_ref": "components/schemas/PaymentResponse"
          }
        ]
      },
      "rdfs:comment": "A record of funds received against an Invoice. Payments are collected via DIRECT_DEBIT,\nCARD, or BANK_TRANSFER. When a Payment reaches SETTLED status and the aggregate payments equal the Invoice\ntotal, the Invoice transitions to PAID and a CREDIT LedgerEntry is posted. Aligned to Socotra's Payment\nresource, which also represents a financial settlement event linked to a billing account.\n",
      "rdfs:label": "Payment"
    },
    {
      "@id": "olly:Policy",
      "@type": "owl:Class",
      "olly:alignments": {
        "fhir": "fhir:Coverage",
        "fibo": "fibo-fbc-pas-fpas:InsurancePolicy",
        "schema_org": "schema:Product",
        "socotra": "socotra:Policy"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:quoteId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:productVersionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:inceptionDate",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:jurisdiction",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:region",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:document",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:lifecycle": {
        "states": [
          "draft",
          "quoted",
          "bound",
          "active",
          "lapsed",
          "cancelled",
          "expired"
        ]
      },
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § Policy Lifecycle",
          "docs/site/domain/policies.md § PolicyStatus State Machine",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "openapi": [
          {
            "schema": "Policy",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/portfolio/policies",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/portfolio/policies/{locator}",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/accounts/{locator}/policies/list",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/enroll",
            "service": "enrollment"
          },
          {
            "method": "PUT",
            "path": "/enroll/{enrollmentId}",
            "service": "enrollment"
          },
          {
            "method": "POST",
            "path": "/enroll/{enrollmentId}/qle",
            "service": "enrollment"
          },
          {
            "method": "POST",
            "path": "/cobra/elect",
            "service": "enrollment"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.policies"
          }
        ],
        "socotra": [
          {
            "schema": "PolicyListResponse",
            "spec_ref": "components/schemas/PolicyListResponse"
          },
          {
            "schema": "PolicyResponse",
            "spec_ref": "components/schemas/PolicyResponse"
          }
        ]
      },
      "owl:disjointWith": {
        "@id": "olly:Quote"
      },
      "rdfs:comment": "The master insurance contract between an insurer and an Account. A Policy is created when\na Quote is accepted and the first premium collected. It accumulates PolicyTerm records on annual renewal and\ntracks status through ACTIVE, LAPSED, CANCELLED, and EXPIRED states. Aligned to Socotra's Policy resource,\nwhich also represents a central insurance contract entity with term and transaction sub-records.\n",
      "rdfs:label": "Policy",
      "rdfs:subClassOf": [
        "fibo-fbc-pas-fpas:InsurancePolicy",
        "schema:Product"
      ],
      "skos:altLabel": [
        "Cover",
        "Plan",
        "Enrollment"
      ]
    },
    {
      "@id": "olly:PolicyElement",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:transactionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:staticId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:elementType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:data",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:coverageTerms",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:effectiveFrom",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:effectiveTo",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § PolicyTerm and PolicyElement",
          "docs/site/domain/members.md § Employee vs. Dependent"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.policy_elements"
          }
        ]
      },
      "rdfs:comment": "One insured unit within a PolicyTerm — either an employee (primary subscriber) or\na dependent. PolicyElement carries the per-member benefit schedule (copay, coinsurance, deductibles, OOP max)\nas a CoverageTerms JSON blob, and a stable StaticID used to track accumulators across term versions.\n",
      "rdfs:label": "Policy Element"
    },
    {
      "@id": "olly:PolicyFieldValue",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:fieldDefinitionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:value",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.policy_field_values"
          }
        ]
      },
      "rdfs:comment": "A value for a custom FieldDefinition on a specific Policy, supporting the\nproduct's dynamic data model. PolicyFieldValues allow product teams to add configurable data fields to\npolicies without database schema migrations.\n",
      "rdfs:label": "Policy Field Value"
    },
    {
      "@id": "olly:PolicyTerm",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:termNumber",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:effectiveFrom",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:effectiveTo",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § PolicyTerm and PolicyElement",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.policy_terms"
          }
        ]
      },
      "rdfs:comment": "One bounded coverage period on a Policy, typically annual. PolicyTerms carry a\nsequential TermNumber, inclusive EffectiveFrom/EffectiveTo dates, and a status that mirrors the parent Policy.\nAccumulators, ClaimLines, and MemberCoverage records are all scoped to a specific PolicyTerm.\n",
      "rdfs:label": "Policy Term"
    },
    {
      "@id": "olly:PolicyTransaction",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:PolicyTransaction"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:termId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:category",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:effectiveDate",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:date"
        },
        {
          "@id": "olly:document",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § Enrollment, Renewal, Endorsement, and Cancellation",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.policy_transactions"
          }
        ],
        "socotra": [
          {
            "schema": "PolicyTransactionListResponse",
            "spec_ref": "components/schemas/PolicyTransactionListResponse"
          },
          {
            "schema": "PolicyTransactionResponse",
            "spec_ref": "components/schemas/PolicyTransactionResponse"
          }
        ]
      },
      "rdfs:comment": "An immutable record of every post-issuance change to a Policy, including\nISSUANCE, RENEWAL, ENDORSEMENT, CANCELLATION, REINSTATEMENT, and REVERSAL. Each transaction carries an\nEffectiveDate that may differ from the processing date, and optionally references a PolicyTerm. Aligned to\nSocotra's PolicyTransaction resource, which similarly records structured change events against a policy.\n",
      "rdfs:label": "Policy Transaction"
    },
    {
      "@id": "olly:Premium",
      "@type": "owl:Class",
      "olly:alignments": {
        "fibo": "fibo-fbc-pas-fpas:Premium"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:amount",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:decimal"
        },
        {
          "@id": "olly:cadence",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "snapshot": [
          {
            "file": "docs/superpowers/snapshots/2026-04-30-pre-code-evolution/ontology/concepts/domain/premium.yaml",
            "reason": "hand-curated v0 — alignments and lifecycle ported forward"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "The amount payable by the Member (or scheme) for a Policy, on a\nconfigurable cadence.\nAspirational: not currently backed by an Olly service or Postgres table.\n",
      "rdfs:label": "Premium"
    },
    {
      "@id": "olly:Prescription",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:episodeLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:providerLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:medication",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:issuedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "care",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Prescription",
            "service": "care"
          },
          {
            "method": "GET",
            "path": "/episodes/{locator}/prescriptions",
            "service": "care"
          },
          {
            "method": "POST",
            "path": "/episodes/{locator}/prescriptions",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/prescriptions/{locator}/fill",
            "service": "care"
          },
          {
            "method": "PATCH",
            "path": "/prescriptions/{locator}/void",
            "service": "care"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "care",
            "table": "prescriptions"
          }
        ]
      },
      "rdfs:comment": "A medication prescription issued by a healthcare Provider within a care Episode,\nrecording the medication name, prescribing provider, and issue timestamp. Prescriptions may be linked to\nprior auth requirements for formulary-controlled drugs.\n",
      "rdfs:label": "Prescription"
    },
    {
      "@id": "olly:PriorAuth",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:providerId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:memberPartyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:procedureCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:document",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:submittedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:reviewedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "claims",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § Prior Authorization Flow",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "openapi": [
          {
            "method": "POST",
            "path": "/prior-auth",
            "service": "claims"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "claims",
            "table": "claims.prior_auths"
          }
        ]
      },
      "rdfs:comment": "A pre-approval from the insurer required before certain procedures are performed.\nPriorAuth progresses from PENDING through APPROVED or DENIED. Claims for procedures requiring prior auth\nthat lack an APPROVED record are automatically rejected with ANSI reason code CO-15.\n",
      "rdfs:label": "Prior Auth"
    },
    {
      "@id": "olly:Product",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Product"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:code",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:name",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:lob",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "openapi": [
          {
            "schema": "Product",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/products",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/products/{locator}",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/products/{locator}",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/products/list",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/products/{locator}/activate",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/products/{locator}/deactivate",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.products"
          }
        ],
        "socotra": [
          {
            "schema": "ProductRef",
            "spec_ref": "components/schemas/ProductRef"
          }
        ]
      },
      "rdfs:comment": "An insurance plan definition (e.g. \"Olly Select PMI\") owned by policy-admin. A Product\ngroups one or more versioned benefit schedules (ProductVersion). It carries a Line of Business (lob) classifier\nand a status lifecycle from DRAFT through ACTIVE to RETIRED. Aligned to Socotra's Product configuration entity,\nwhich also defines the schema and rules governing policies written under it.\n",
      "rdfs:label": "Product"
    },
    {
      "@id": "olly:ProductVersion",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:productId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:version",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:policySchema",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:claimSchema",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:elementSchema",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:chargeTypes",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:publishedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "POST",
            "path": "/products/{locator}/versions",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/products/{locator}/versions/list",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/products/{locator}/versions/{version}",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/products/{locator}/versions/{version}",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/products/{locator}/versions/{version}/publish",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/internal/product-versions/{id}/fields",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/config/validate",
            "service": "policy-admin"
          },
          {
            "method": "POST",
            "path": "/config/deploy",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/config/{locator}/download",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/config/{locator}/download/{version}",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.product_versions"
          }
        ]
      },
      "rdfs:comment": "A published, immutable version of an insurance Product containing the policy\nschema, claim schema, element schema, charge types, and status lifecycle. Quotes and Policies reference a\nspecific ProductVersion to ensure benefit schedules remain stable after changes to the parent Product.\n",
      "rdfs:label": "Product Version"
    },
    {
      "@id": "olly:Provider",
      "@type": "owl:Class",
      "olly:alignments": {
        "fhir": "fhir:Practitioner",
        "schema_org": "schema:MedicalOrganization"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:npi",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:partyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:name",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:specialty",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:networkStatus",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:address",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:phone",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:email",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:activatedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "provider",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/providers.md § Provider Entity",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "kafka": [
          {
            "schema": "Provider",
            "service": "provider"
          }
        ],
        "openapi": [
          {
            "schema": "Provider",
            "service": "provider"
          },
          {
            "method": "GET",
            "path": "/providers",
            "service": "provider"
          },
          {
            "method": "GET",
            "path": "/providers/{npi}",
            "service": "provider"
          },
          {
            "method": "GET",
            "path": "/providers/{providerLocator}/slots",
            "service": "care"
          },
          {
            "method": "POST",
            "path": "/providers/{providerLocator}/slots",
            "service": "care"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "provider",
            "table": "provider.providers"
          }
        ]
      },
      "rdfs:comment": "A credentialed healthcare organisation or individual practitioner in the Olly network.\nIdentified by NPI (National Provider Identifier) for use in EDI 837 transactions and prior auth requests.\nNetworkStatus (PENDING/ACTIVE/INACTIVE) determines in-network claim adjudication rates and member\ncost-sharing obligations.\n",
      "rdfs:label": "Provider",
      "rdfs:subClassOf": "schema:MedicalOrganization",
      "skos:altLabel": [
        "HealthcareProvider"
      ]
    },
    {
      "@id": "olly:ProviderSlot",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:providerLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:startTime",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:endTime",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:appointmentLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "care",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "PATCH",
            "path": "/slots/{locator}/block",
            "service": "care"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "care",
            "table": "provider_slots"
          }
        ]
      },
      "rdfs:comment": "A specific bookable time window at a Provider, with start/end times and a status\n(AVAILABLE/BOOKED/CANCELLED). When a Member books an Appointment, the linked ProviderSlot transitions to\nBOOKED; cancellations restore it to AVAILABLE.\n",
      "rdfs:label": "Provider Slot"
    },
    {
      "@id": "olly:Quote",
      "@type": "owl:Class",
      "olly:alignments": {
        "fibo": "fibo-fbc-pas-fpas:Quote",
        "socotra": "socotra:Quote"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:accountId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:productVersionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:document",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:expiresAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § Quote → Policy Issuance Flow",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "openapi": [
          {
            "schema": "Quote",
            "service": "broker-api"
          },
          {
            "method": "POST",
            "path": "/quotes",
            "service": "broker-api"
          },
          {
            "method": "GET",
            "path": "/quotes/{locator}",
            "service": "broker-api"
          },
          {
            "method": "PATCH",
            "path": "/quotes/{locator}/price",
            "service": "broker-api"
          },
          {
            "method": "PATCH",
            "path": "/quotes/{locator}/underwrite",
            "service": "broker-api"
          },
          {
            "method": "PATCH",
            "path": "/quotes/{locator}/issue",
            "service": "broker-api"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.quotes"
          }
        ],
        "socotra": [
          {
            "schema": "QuoteListResponse",
            "spec_ref": "components/schemas/QuoteListResponse"
          },
          {
            "schema": "QuoteResponse",
            "spec_ref": "components/schemas/QuoteResponse"
          },
          {
            "schema": "QuoteCreateRequest",
            "spec_ref": "components/schemas/QuoteCreateRequest"
          }
        ]
      },
      "owl:disjointWith": {
        "@id": "olly:Policy"
      },
      "rdfs:comment": "A priced proposal that precedes a Policy. Quotes advance through DRAFT → PRICED →\nUNDERWRITTEN → ACCEPTED/DECLINED → (if accepted) converted to a Policy. A Quote holds the rated premium,\nbenefit schedule, and applicant data as a JSONB Document blob, and expires after a configurable timestamp.\nAligned to Socotra's Quote resource, which also models a priced insurance proposal that can be accepted or\ndeclined.\n",
      "rdfs:label": "Quote"
    },
    {
      "@id": "olly:QuoteEvent",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:quoteId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:eventType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:payload",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § Quote → Policy Issuance Flow"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.quote_events"
          }
        ]
      },
      "rdfs:comment": "An immutable audit record of every status change on a Quote — from DRAFT through\npricing, underwriting, acceptance or decline, and expiry. QuoteEvents capture the event type and payload at\neach transition, forming the complete quote history.\n",
      "rdfs:label": "Quote Event"
    },
    {
      "@id": "olly:QuoteFieldValue",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:quoteId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:fieldDefinitionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:value",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.quote_field_values"
          }
        ]
      },
      "rdfs:comment": "A value for a custom FieldDefinition collected on a Quote during the\napplication process. Analogous to PolicyFieldValue but scoped to the pre-issuance quote, supporting the\nsame product-defined dynamic data model.\n",
      "rdfs:label": "Quote Field Value"
    },
    {
      "@id": "olly:Recommendation",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "triage",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Recommendation",
            "spec": "api/openapi/triage.yaml",
            "spec_ref": "components/schemas/Recommendation"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "The structured clinical disposition produced by the triage engine at the end of a\nmember's triage Session, advising the appropriate care pathway — for example, self-care, GP consultation,\nurgent care, or emergency services. A Recommendation bundles the suggested action, the urgency level, and\na plain-language rationale derived from the member's reported symptoms and clinical reasoning. It is the\nterminal output of a completed triage conversation and may trigger a DiagnosticsReferral or Appointment\nbooking depending on the pathway selected.\n",
      "rdfs:label": "Recommendation"
    },
    {
      "@id": "olly:Role",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Role"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/architecture/overview.md § Security Boundaries"
        ],
        "socotra": [
          {
            "schema": "RoleListResponse",
            "spec_ref": "components/schemas/RoleListResponse"
          },
          {
            "schema": "RoleCreateRequest",
            "spec_ref": "components/schemas/RoleCreateRequest"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A named permission bundle that can be assigned to platform users, controlling which resources and\noperations they can access. Roles are evaluated by the OPA policy engine at APISIX and within each\nservice. In Olly, roles are managed in Keycloak as realm roles; a platform-native Role entity would\nenable programmatic role management without Keycloak API calls. Concept sourced from Socotra; not yet\nmodeled as a standalone entity in Olly code.\n",
      "rdfs:label": "Role"
    },
    {
      "@id": "olly:Rule",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:ruleSetId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:code",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:priority",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:condition",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:effect",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:message",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Rule",
            "service": "policy-admin"
          },
          {
            "method": "PUT",
            "path": "/products/{productLocator}/versions/{version}/rulesets/{name}/rules",
            "service": "policy-admin"
          },
          {
            "method": "PATCH",
            "path": "/products/{productLocator}/versions/{version}/rulesets/{name}/rules/{ruleLocator}",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.rules"
          }
        ]
      },
      "rdfs:comment": "A single executable policy rule within a RuleSet, with a condition expression, an effect\n(e.g. REJECT, SURCHARGE, FLAG), a human-readable message, and a priority. Rules are evaluated by the\nunderwriting and adjudication engines against quote or claim data.\n",
      "rdfs:label": "Rule"
    },
    {
      "@id": "olly:RuleEvaluation",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:ruleId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:ruleSetId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:entityType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:entityId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:conditionResult",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:boolean"
        },
        {
          "@id": "olly:effectApplied",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:evaluatedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.rule_evaluations"
          }
        ]
      },
      "rdfs:comment": "An audit record of a single Rule being evaluated against a specific entity\n(Quote, Claim, or Policy). Captures whether the condition matched, which effect was applied, and the\ntimestamp, providing a traceable decision log for regulatory audit.\n",
      "rdfs:label": "Rule Evaluation"
    },
    {
      "@id": "olly:RuleInput",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/underwriting.md (underwriting plugin and flag evaluation)"
        ],
        "openapi": [
          {
            "schema": "RuleInput",
            "spec": "api/openapi/policy-admin.yaml",
            "spec_ref": "components/schemas/RuleInput"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "The structured context object passed into a RuleSet evaluation, containing the data\nrequired for the underwriting or adjudication engine to assess each Rule's condition. RuleInput bundles\nthe entity under evaluation (quote, claim, or policy), the triggering event, and any auxiliary data fields\n(demographic, clinical, or financial) that rules may reference. It is constructed at evaluation time from\nthe current state of the entity and discarded after evaluation, with the results persisted as RuleEvaluation\naudit records.\n",
      "rdfs:label": "Rule Input"
    },
    {
      "@id": "olly:RuleSet",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:productVersionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:name",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:trigger",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "openapi": [
          {
            "method": "POST",
            "path": "/products/{productLocator}/versions/{version}/rulesets",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/products/{productLocator}/versions/{version}/rulesets/list",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/products/{productLocator}/versions/{version}/rulesets/{name}",
            "service": "policy-admin"
          },
          {
            "method": "GET",
            "path": "/internal/products/{productLocator}/versions/{version}/rulesets/{name}",
            "service": "policy-admin"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "policy-admin",
            "table": "policy_admin.rule_sets"
          }
        ]
      },
      "rdfs:comment": "A named collection of Rules associated with a ProductVersion and a trigger context\n(e.g. QUOTE_UNDERWRITING, CLAIM_ADJUDICATION). RuleSets are the unit of rule configuration: adding or\nretiring rules is done by publishing a new RuleSet version.\n",
      "rdfs:label": "Rule Set"
    },
    {
      "@id": "olly:RuleSetBundle",
      "@type": "owl:Class",
      "olly:layer": "domain",
      "olly:ownerService": "policy-admin",
      "olly:referencedIn": {
        "docs": [
          "socotra/featureGuide/underwriting.md (underwriting configuration and rule sets)"
        ],
        "openapi": [
          {
            "schema": "RuleSetBundle",
            "spec": "api/openapi/policy-admin.yaml",
            "spec_ref": "components/schemas/RuleSetBundle"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A versioned collection of RuleSets packaged together for deployment as a coherent\nconfiguration update. A RuleSetBundle groups all the rule sets that belong to a single ProductVersion and\ntrigger context (underwriting, adjudication, billing) so they can be validated, tested, and published\natomically. Publishing a new bundle replaces the prior active rule configuration for the product version\nwithout requiring individual rule set updates, mirroring the tenant configuration deployment model\ndescribed in the Socotra platform where all rule and configuration artefacts are deployed together.\n",
      "rdfs:label": "Rule Set Bundle"
    },
    {
      "@id": "olly:Scheme",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:code",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:name",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:employerPartyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "group-scheme-service",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § Employer Group Scheme → Member Relationship"
        ],
        "openapi": [
          {
            "schema": "Scheme",
            "service": "group-scheme-service"
          },
          {
            "method": "GET",
            "path": "/schemes",
            "service": "group-scheme-service"
          },
          {
            "method": "POST",
            "path": "/schemes",
            "service": "group-scheme-service"
          },
          {
            "method": "GET",
            "path": "/schemes/list",
            "service": "group-scheme-service"
          },
          {
            "method": "GET",
            "path": "/schemes/{locator}",
            "service": "group-scheme-service"
          },
          {
            "method": "PATCH",
            "path": "/schemes/{locator}",
            "service": "group-scheme-service"
          },
          {
            "method": "GET",
            "path": "/schemes/{locator}/billing",
            "service": "group-scheme-service"
          },
          {
            "method": "GET",
            "path": "/schemes/{locator}/eligibility",
            "service": "group-scheme-service"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "group-scheme-service",
            "table": "group_scheme.schemes"
          }
        ]
      },
      "rdfs:comment": "An employer group insurance arrangement linking an employer Party to a cohort of member\npolicies. Schemes are administered by the group-scheme service, carry a locator code used in bulk enrollment\nuploads, and scope the employer portal to the correct member population.\n",
      "rdfs:label": "Scheme"
    },
    {
      "@id": "olly:SchemeMember",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:schemeId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:memberPartyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:policyLocator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "group-scheme-service",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/members.md § Employer Group Scheme → Member Relationship"
        ],
        "openapi": [
          {
            "method": "GET",
            "path": "/schemes/{locator}/members",
            "service": "group-scheme-service"
          },
          {
            "method": "POST",
            "path": "/schemes/{locator}/members",
            "service": "group-scheme-service"
          },
          {
            "method": "DELETE",
            "path": "/schemes/{locator}/members/{memberPartyLocator}",
            "service": "group-scheme-service"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "group-scheme-service",
            "table": "group_scheme.scheme_members"
          }
        ]
      },
      "rdfs:comment": "The association between a Group Scheme and an individual member's policy.\nSchemeMember records the member's Party locator, policy locator, and enrollment status, enabling the\nemployer portal to list and manage all covered employees within the scheme.\n",
      "rdfs:label": "Scheme Member"
    },
    {
      "@id": "olly:Segment",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Segment"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "SegmentResponse",
            "spec_ref": "components/schemas/SegmentResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A named sub-division of a policy's insured population or coverage period used for targeted billing\nand reporting — for example, separating employee-only from family coverage tiers, or dividing a\nmulti-location employer account by cost centre. Segments drive differential premium calculation and\nclaims allocation. Concept sourced from Socotra; not yet modeled in Olly code.\n",
      "rdfs:label": "Segment"
    },
    {
      "@id": "olly:Session",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:userId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:pathwayId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:currentStateId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:sex",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:age",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        },
        {
          "@id": "olly:chiefComplaint",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:status",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:disposition",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:completedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "triage",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Session",
            "service": "triage"
          },
          {
            "method": "POST",
            "path": "/sessions",
            "service": "triage"
          },
          {
            "method": "GET",
            "path": "/sessions/{locator}",
            "service": "triage"
          },
          {
            "method": "PATCH",
            "path": "/sessions/{locator}/abandon",
            "service": "triage"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "triage",
            "table": "triage.sessions"
          },
          {
            "pk": "id",
            "service": "triage-legacy",
            "table": "triage.sessions"
          }
        ]
      },
      "rdfs:comment": "A single AI triage interaction in which a user works through a clinical decision tree\n(pathway) to receive a disposition. Sessions carry chief complaint, demographic parameters (sex, age),\ncurrent pathway state, and a final disposition (e.g. SEE_GP, GO_TO_ED, SELF_CARE).\n",
      "rdfs:label": "Session"
    },
    {
      "@id": "olly:Symptom",
      "@type": "owl:Class",
      "olly:alignments": {
        "snomed": "snomed:404684003"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:symptomText",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "snapshot": [
          {
            "file": "docs/superpowers/snapshots/2026-04-30-pre-code-evolution/ontology/concepts/domain/symptom.yaml",
            "reason": "hand-curated v0 — alignments and lifecycle ported forward"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A presenting complaint reported by a Member during triage, mapped to\nSNOMED-CT clinical findings where licensed.\nAspirational: not currently backed by an Olly service or Postgres table.\n",
      "rdfs:label": "Symptom"
    },
    {
      "@id": "olly:Template",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Template"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:marketCode",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:templateType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:contentHtml",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "document-service",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/claims.md § EDI 837 / 835 Context"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "document-service",
            "table": "documents.templates"
          }
        ],
        "socotra": [
          {
            "schema": "TemplateResponse",
            "spec_ref": "components/schemas/TemplateResponse"
          }
        ]
      },
      "rdfs:comment": "A reusable HTML/text layout used by the document service to generate member-facing\ncommunications — policy schedules, welcome letters, Explanation of Benefits PDFs, and renewal notices.\nTemplates are keyed by market code and template type. Aligned to Socotra's Template resource, which also\ndefines document generation templates used for policy documents and correspondence.\n",
      "rdfs:label": "Template"
    },
    {
      "@id": "olly:Term",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Term"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § PolicyTerm and PolicyElement"
        ],
        "socotra": [
          {
            "schema": "TermListResponse",
            "spec_ref": "components/schemas/TermListResponse"
          },
          {
            "schema": "TermResponse",
            "spec_ref": "components/schemas/TermResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "In Socotra's model, a Term represents a versioned coverage period on a policy, analogous to Olly's\nPolicyTerm. The Term entity in Socotra carries the full effective date range, premium amount for that\nperiod, and a list of insured elements. Olly's PolicyTerm and PolicyElement together cover this concept.\nConcept sourced from Socotra; Olly models this as PolicyTerm + PolicyElement.\n",
      "rdfs:label": "Term"
    },
    {
      "@id": "olly:TransactionFieldValue",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:transactionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:fieldDefinitionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:value",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.transaction_field_values"
          }
        ]
      },
      "rdfs:comment": "A value for a custom FieldDefinition collected on a PolicyTransaction\n(e.g. an endorsement or renewal), capturing transaction-specific dynamic data defined by the product schema.\n",
      "rdfs:label": "Transaction Field Value"
    },
    {
      "@id": "olly:Turn",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:sessionId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:role",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:content",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:stateId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:toolName",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:toolArgs",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:toolResult",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "triage",
      "olly:referencedIn": {
        "openapi": [
          {
            "schema": "Turn",
            "service": "triage"
          },
          {
            "method": "POST",
            "path": "/sessions/{locator}/respond",
            "service": "triage"
          },
          {
            "method": "GET",
            "path": "/sessions/{locator}/recommendation",
            "service": "triage"
          }
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "triage",
            "table": "triage.turns"
          },
          {
            "pk": "id",
            "service": "triage-legacy",
            "table": "triage.turns"
          }
        ]
      },
      "rdfs:comment": "A single conversational exchange within a triage Session — one user input plus the agent's\nresponse. Turns record the pathway state before and after the exchange, any tool calls made by the agent,\nand tool results, enabling full replay of the triage interaction.\n",
      "rdfs:label": "Turn"
    },
    {
      "@id": "olly:UnderwritingFlag",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:UnderwritingFlag"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:locator",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:quoteId",
          "@type": "owl:ObjectProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:flagType",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:reason",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:voidedAt",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:dateTime"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "enrollment",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/policies.md § Quote → Policy Issuance Flow",
          "docs/site/domain/index.md § Concept-to-Struct Mapping"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "enrollment",
            "table": "enrollment.underwriting_flags"
          }
        ],
        "socotra": [
          {
            "schema": "UnderwritingFlagCreateRequest",
            "spec_ref": "components/schemas/UnderwritingFlagCreateRequest"
          },
          {
            "schema": "UnderwritingFlagResponse",
            "spec_ref": "components/schemas/UnderwritingFlagResponse"
          }
        ]
      },
      "rdfs:comment": "An individual underwriter decision (APPROVE, BLOCK, or DECLINE) applied to a\nQuote. Multiple flags can coexist on a single Quote; the strictest decision wins. Flags record the reason\nfor the decision and can be voided if superseded. Aligned to Socotra's UnderwritingFlag resource, which\nsimilarly captures underwriting decisions during the quote review process.\n",
      "rdfs:label": "Underwriting Flag"
    },
    {
      "@id": "olly:User",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:User"
      },
      "olly:hasProperty": [
        {
          "@id": "olly:username",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:apiKeyHash",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:sex",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:age",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:integer"
        }
      ],
      "olly:layer": "domain",
      "olly:ownerService": "triage",
      "olly:referencedIn": {
        "docs": [
          "docs/architecture/overview.md § Technology Choices"
        ],
        "postgres": [
          {
            "pk": "id",
            "service": "triage",
            "table": "triage.users"
          }
        ],
        "socotra": [
          {
            "schema": "UserListResponse",
            "spec_ref": "components/schemas/UserListResponse"
          },
          {
            "schema": "UserCreateRequest",
            "spec_ref": "components/schemas/UserCreateRequest"
          },
          {
            "schema": "UserUpdateRequest",
            "spec_ref": "components/schemas/UserUpdateRequest"
          }
        ]
      },
      "rdfs:comment": "An authenticated platform user — in the triage service context, a triage agent identified by\nusername and hashed API key, with demographic attributes (sex, age) used for clinical pathway routing.\nPlatform-wide human identity is managed in Keycloak. Aligned to Socotra's User resource, which also\nrepresents an authenticated operator with access credentials.\n",
      "rdfs:label": "User"
    },
    {
      "@id": "olly:Webhook",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Webhook"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "WebhookListResponse",
            "spec_ref": "components/schemas/WebhookListResponse"
          },
          {
            "schema": "WebhookResponse",
            "spec_ref": "components/schemas/WebhookResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "An outbound HTTP callback registration that delivers domain events (e.g. policy.issued,\nclaims.adjudicated) to external systems in real time. Webhooks carry an endpoint URL, subscribed\nevent types, authentication headers, and retry strategy. Concept sourced from Socotra; Olly currently\ndelivers events via Kafka topics rather than HTTP webhooks.\n",
      "rdfs:label": "Webhook"
    },
    {
      "@id": "olly:Workgroup",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:Workgroup"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "socotra": [
          {
            "schema": "WorkgroupCreateRequest",
            "spec_ref": "components/schemas/WorkgroupCreateRequest"
          },
          {
            "schema": "WorkgroupResponse",
            "spec_ref": "components/schemas/WorkgroupResponse"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "A named team of operations staff (claims adjusters, underwriters, credentialing reviewers) to whom\nwork items can be assigned. Workgroups enable round-robin or skill-based routing of claims, prior auth\nrequests, and credentialing reviews. Concept sourced from Socotra; Olly currently assigns reviewers\ndirectly; a Workgroup abstraction is aspirational.\n",
      "rdfs:label": "Workgroup"
    },
    {
      "@id": "olly:WriteOff",
      "@type": "owl:Class",
      "olly:alignments": {
        "socotra": "socotra:WriteOff"
      },
      "olly:layer": "domain",
      "olly:ownerService": "tbd",
      "olly:referencedIn": {
        "docs": [
          "docs/site/domain/billing.md § Grace Period and Delinquency Handling"
        ],
        "socotra": [
          {
            "schema": "WriteOffResponse",
            "spec_ref": "components/schemas/WriteOffResponse"
          },
          {
            "schema": "WriteOffRequest",
            "spec_ref": "components/schemas/WriteOffRequest"
          }
        ]
      },
      "olly:status": "aspirational",
      "rdfs:comment": "The formal accounting recognition that an outstanding receivable (unpaid invoice or charge) will not\nbe collected, resulting in a credit entry to the PREMIUM_RECEIVABLE ledger account. Write-offs are\ntypically applied after a policy has been cancelled following the lapse window. Concept sourced from\nSocotra; not yet modeled as a separate entity in Olly code.\n",
      "rdfs:label": "Write Off"
    },
    {
      "@id": "olly:ApisixRoute",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:routePath",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:upstream",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "infra",
      "rdfs:comment": "An APISIX gateway route mapping a public path to a service.",
      "rdfs:label": "ApisixRoute"
    },
    {
      "@id": "olly:KeycloakClient",
      "@type": "owl:Class",
      "olly:hasProperty": [
        {
          "@id": "olly:clientId",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        },
        {
          "@id": "olly:authFlow",
          "@type": "owl:DatatypeProperty",
          "rdfs:range": "xsd:string"
        }
      ],
      "olly:layer": "infra",
      "rdfs:comment": "A Keycloak client (web-employer, web-member, etc.) used for auth.",
      "rdfs:label": "KeycloakClient"
    },
    {
      "@id": "olly:coverageOf",
      "@type": "owl:ObjectProperty",
      "owl:inverseOf": "olly:hasCoverage",
      "rdfs:domain": "olly:Coverage",
      "rdfs:range": "olly:Policy"
    },
    {
      "@id": "olly:coversMember",
      "@type": "owl:ObjectProperty",
      "rdfs:domain": "olly:Policy",
      "rdfs:range": "olly:Member"
    },
    {
      "@id": "olly:hasCoverage",
      "@type": "owl:ObjectProperty",
      "owl:inverseOf": "olly:coverageOf",
      "rdfs:domain": "olly:Policy",
      "rdfs:range": "olly:Coverage"
    },
    {
      "@id": "olly:ownedByService",
      "@type": "owl:ObjectProperty",
      "rdfs:domain": "olly:PostgresTable",
      "rdfs:range": "olly:Service"
    },
    {
      "@id": "olly:storedInTable",
      "@type": "owl:ObjectProperty",
      "rdfs:domain": "olly:Policy",
      "rdfs:range": "olly:PostgresTable"
    }
  ]
}