id: https://sniff.world/schema/owner-fact
name: sniff_owner_fact
title: "Sniff OwnerFact: per-field privacy born on the living Record"
version: 0.2.2
license: https://creativecommons.org/licenses/by/4.0/

description: >-
  LinkML root for owner-contributed facts on user dogs (the living-dog layer).
  Where CoverageFrame models reasoned ABSENCE over the genetics substrate, OwnerFact
  models privacy-born PRESENCE on the living dog: the same immune grammar, opposite
  polarity.


  A fact is born with a FactVisibility intent that is refuse-null (never a database
  default), and its effective exposure is COMPOSED under the dog's visibility tier
  and the owner's trust tier, never read from raw intent alone. `science` here means
  eligible to COUNT in an anonymized cohort, not safe to RENDER a cohort rate: any
  aggregate still passes the cohort-frame and apoptosis rules before it can be shown.


  Instances live in Turso (dog_facts); the pure composition logic lives in
  web/src/lib/consumer/fact-core.mjs. This schema is the contract those obey.

prefixes:
  linkml: https://w3id.org/linkml/
  sniff: https://sniff.world/schema/
  ECO: http://purl.obolibrary.org/obo/ECO_
  dcterms: http://purl.org/dc/terms/
default_prefix: sniff
default_range: string

imports:
  - linkml:types

see_also:
  - https://sniff.world/schema/coverage-frame

keywords:
  - privacy by construction
  - register wall
  - owner-contributed data
  - consent

classes:

  OwnerFact:
    description: >-
      One owner-contributed fact about a dog, born with a FactVisibility intent
      (refuse-null). The value is carried under a stable typed key; provenance
      records whether it was declared, measured, or imported.
    tree_root: true
    slots:
      - id
      - dog_id
      - kind
      - key
      - value
      - visibility
      - provenance
      - created_at
      - n
      - basis
      - floor_id

  FactExposure:
    description: >-
      The result of composing a fact's visibility intent with the dog's visibility
      tier and the owner's trust tier. `science` here is an eligibility gate to
      count, not a permission to render a cohort rate.
    slots:
      - owner
      - science
      - showcase

slots:

  id:
    identifier: true
    description: The fact identifier.

  dog_id:
    required: true
    description: The user_dogs id this fact belongs to; never the Founder dogs table.

  kind:
    range: FactKindEnum
    required: true
    description: The category of fact.

  key:
    required: true
    description: >-
      A stable key such as acquisition_window, diet_class, free_note, or a
      dog-questions id.

  value:
    required: true
    description: A JSON string for structured keys, or raw text for a free note.

  visibility:
    range: FactVisibilityEnum
    required: true
    description: >-
      The owner's intent only, never a database default; refused if null at write
      time. Effective exposure is composed downstream, never read from here alone.

  provenance:
    range: FactProvenanceEnum
    required: true
    description: How the value was obtained.

  created_at:
    range: datetime
    description: When the fact was written.

  n:
    range: integer
    minimum_value: 0
    description: >-
      Denominator when this fact is later aggregated. A single owner fact is
      n=1. Cohort renders still pass the cohort-frame floor.

  basis:
    description: >-
      How the value was produced when distinct from provenance. Typical values
      are declared, measured, owner_register, or this_dog_lived. No score.

  floor_id:
    description: Which par an aggregate of this fact must clear before it may render.

  owner:
    range: boolean
    description: Visible to the owner in their own record.

  science:
    range: boolean
    description: >-
      Eligible to count in an anonymized cohort. The cohort-frame and apoptosis
      rules still gate any aggregate before it can be rendered.

  showcase:
    range: boolean
    description: Eligible for public showcase when the dog is public and trust clears.

enums:

  FactKindEnum:
    description: The category of an owner-contributed fact.
    permissible_values:
      answer:
        description: A response to a dog-questions item.
      lifestyle:
        description: A structured lifestyle seed such as acquisition window or diet class.
      note:
        description: A free-text owner note; born private.
      vet_doc:
        description: A clinical document handle; born private, handling deferred.

  FactVisibilityEnum:
    description: >-
      The owner's per-field visibility intent. The same three-value vocabulary is
      shared across the record (see INV-116); it is refuse-null and fails closed to
      private.
    permissible_values:
      private:
        description: The owner's own lens only.
      science:
        description: Eligible for an anonymized cohort count when trust clears; never shown publicly.
      public:
        description: Eligible for showcase when the dog is public and trust clears.

  FactProvenanceEnum:
    description: >-
      How a value was obtained. ECO evidence-code bindings are a planned Phase 2
      extension; they are omitted here rather than asserted unverified.
    permissible_values:
      declared:
        description: Owner-reported, carried in estimated language.
      measured:
        description: Instrument or lab-backed.
      imported:
        description: Brought in from an external source with a provenance trail.
