{
  "schema": "zenith.ontology-viewer/v1",
  "id": "zendo",
  "label": "Zendo",
  "role": "Concierge extension",
  "status": "Prototype",
  "version": "0.5.0",
  "namespace": "urn:zendo:concierge:v1#",
  "description": "The concierge vocabulary for guests, trip briefs, planning, recommendations, selections and booking drafts.",
  "boundary": "A local prototype extending Rolodex Person. A selection or booking draft does not reserve inventory, authorize payment, or create a confirmed booking.",
  "source": {
    "label": "Zendo concierge · application schema",
    "files": [
      {
        "name": "ontology-catalog.json",
        "sha256": "c928d2c0568dd4c5cdefe95689b4c1262a88236acb70030916a5c697b62dc608"
      },
      {
        "name": "guest-workspace.schema.json",
        "sha256": "5949a020e6f4352a326fc5253c3a3fff96853d0c55c21906af8799b71925d376"
      },
      {
        "name": "concierge-ontology.jsonld",
        "sha256": "19abd6e005c35a2e13c59063b67a9ff5842aa09d67654b1257dd0133fc61d67d"
      }
    ]
  },
  "dependencies": [
    {
      "label": "Rolodex v0.8.0",
      "module": "rolodex",
      "note": "Guest declares a specialization of Person. No live Runtime adapter or registered contact binding."
    }
  ],
  "related": [
    {
      "module": "zendo-core",
      "label": "Zendo core candidate",
      "note": "The broader peer, service-request and guest-context design is a separate review candidate. This catalogue describes the current concierge prototype."
    }
  ],
  "sections": [],
  "terms": [
    {
      "id": "guest",
      "label": "Guest",
      "kind": "Record",
      "group": "People & trips",
      "description": "The human person in the guest role; a local specialization of Rolodex Person.",
      "iri": "urn:zendo:concierge:v1#Guest",
      "parent": "https://zenith-research.ca/ontology/terms/Person",
      "fields": [
        {
          "name": "schema",
          "type": "\"zendo.guest/v1\"",
          "required": true,
          "schema": {
            "const": "zendo.guest/v1"
          }
        },
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string",
            "maxLength": 120
          }
        },
        {
          "name": "revision",
          "type": "integer",
          "required": true,
          "description": "Record-local revision; distinct from the workspace version.",
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "name",
          "type": "string",
          "required": true,
          "description": "Guest-selected or concierge-entered display identity.",
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        },
        {
          "name": "company",
          "type": "string",
          "required": false,
          "description": "Optional organisation display text; no directory membership is implied.",
          "schema": {
            "type": "string",
            "maxLength": 100
          }
        }
      ],
      "rules": [
        "Guest extends Rolodex Person, beneath Entity. A role does not confer authentication or booking authority.",
        "Guest identity and the acting concierge/Hermes session are distinct.",
        "The profile describes the person; it is not a second identity."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "guest.id; stable existing guest IDs are preserved."
        },
        {
          "label": "Owner",
          "value": "Local guest identity; no verified Rolodex contact binding."
        }
      ],
      "links": [
        {
          "label": "has trip brief",
          "target": "trip-brief",
          "note": "1 → 0..*"
        }
      ]
    },
    {
      "id": "guest-profile",
      "label": "Guest profile",
      "kind": "Record",
      "group": "People & trips",
      "description": "Reusable context about a Guest: prompted sections, notes and pinned places.",
      "iri": "urn:zendo:concierge:v1#GuestProfile",
      "fields": [
        {
          "name": "schema",
          "type": "\"zendo.guest-profile/v1\"",
          "required": true,
          "schema": {
            "const": "zendo.guest-profile/v1"
          }
        },
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string",
            "maxLength": 120
          }
        },
        {
          "name": "revision",
          "type": "integer",
          "required": true,
          "description": "Record-local revision; distinct from the workspace version.",
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "name",
          "type": "string",
          "required": true,
          "description": "Guest-selected or concierge-entered display identity.",
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        },
        {
          "name": "company",
          "type": "string",
          "required": false,
          "description": "Optional organisation display text; no directory membership is implied.",
          "schema": {
            "type": "string",
            "maxLength": 100
          }
        },
        {
          "name": "notes",
          "type": "string",
          "required": true,
          "description": "Ordinary freeform notes in the owning record.",
          "schema": {
            "type": "string",
            "maxLength": 2000
          }
        },
        {
          "name": "preferences",
          "type": "string",
          "required": true,
          "description": "Enduring interests and routines; soft retrieval context.",
          "schema": {
            "type": "string",
            "maxLength": 4000
          }
        },
        {
          "name": "profileId",
          "type": "string",
          "required": false,
          "description": "Identity of the reusable profile record.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "guestId",
          "type": "string",
          "required": false,
          "description": "The Guest this record concerns.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "chunks",
          "type": "array",
          "required": false,
          "description": "Prompted topic responses with source, revision and contribution history.",
          "schema": {
            "type": "array",
            "maxItems": 7,
            "items": {
              "$ref": "#/$defs/ProfileChunk"
            }
          }
        }
      ],
      "rules": [
        "A profile describes one Guest. Profile chunks describe topics; they are not new identity classes.",
        "Company is optional; notes are ordinary freeform notes.",
        "Guest-provided, concierge-observed and agent-suggested are sources, not separate profile types.",
        "Profile context informs matching. Hard trip requirements require an explicit brief edit.",
        "Pinned places are places the guest specifically likes; relevant places belong to a trip brief.",
        "Profile edits preserve the active brief, recommendations, selection and draft.",
        "Guest-only confirmation remains unavailable until a verified guest session exists."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "guestProfile.profileId; guestId points to Guest. id remains the legacy guest-ID alias."
        },
        {
          "label": "Owner",
          "value": "Concierge-maintained context with attributed contributions; no authenticated guest editor is simulated."
        }
      ],
      "links": [
        {
          "label": "pins place",
          "target": "context-reference",
          "note": "1 → 0..*"
        },
        {
          "label": "describes",
          "target": "guest",
          "note": "1 → 1"
        },
        {
          "label": "has topic response",
          "target": "profile-chunk",
          "note": "1 → 0..*"
        }
      ]
    },
    {
      "id": "profile-chunk",
      "label": "Profile chunk",
      "kind": "Record",
      "group": "People & trips",
      "description": "One prompted, retrievable topic response with source, revision and contribution history.",
      "fields": [
        {
          "name": "schema",
          "type": "\"zendo.profile-chunk/v1\"",
          "required": true,
          "schema": {
            "const": "zendo.profile-chunk/v1"
          }
        },
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "guestId",
          "type": "string",
          "required": true,
          "description": "The Guest this record concerns.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "profileId",
          "type": "string",
          "required": true,
          "description": "Identity of the reusable profile record.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "topicId",
          "type": "feeling-at-home | daily-rhythm | household-needs | errands-services | interests-personal-style | general-preferences | notes",
          "required": true,
          "description": "Stable taxonomy topic; the prompt is guidance, not a guest fact.",
          "schema": {
            "enum": [
              "feeling-at-home",
              "daily-rhythm",
              "household-needs",
              "errands-services",
              "interests-personal-style",
              "general-preferences",
              "notes"
            ]
          }
        },
        {
          "name": "response",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string",
            "maxLength": 4000
          }
        },
        {
          "name": "revision",
          "type": "integer",
          "required": true,
          "description": "Record-local revision; distinct from the workspace version.",
          "schema": {
            "type": "integer",
            "minimum": 0
          }
        },
        {
          "name": "basis",
          "type": "guest-provided | concierge-observation | agent-suggested | unattributed",
          "required": true,
          "description": "Reported information source, distinct from the actor who entered it.",
          "schema": {
            "enum": [
              "guest-provided",
              "concierge-observation",
              "agent-suggested",
              "unattributed"
            ]
          }
        },
        {
          "name": "updatedBy",
          "type": "object | null",
          "required": true,
          "schema": {
            "type": [
              "object",
              "null"
            ]
          }
        },
        {
          "name": "updatedAt",
          "type": "string | null",
          "required": true,
          "schema": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        {
          "name": "guestConfirmation",
          "type": "null",
          "required": true,
          "description": "Guest-only and currently unavailable; never inferred from a concierge source label.",
          "schema": {
            "type": "null",
            "description": "Guest-only; no verified guest confirmation endpoint is implemented."
          }
        },
        {
          "name": "contributions",
          "type": "array",
          "required": true,
          "description": "Append-only service-recorded response revisions, enteredBy actor and timestamp.",
          "schema": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "revision",
                "response",
                "basis",
                "enteredBy",
                "at"
              ]
            }
          }
        }
      ],
      "rules": [
        "Five prompted topics plus general preferences and notes. Existing text is retained without inferred categorization.",
        "Guest-provided is a reported basis, not proof the guest authored or confirmed the entry.",
        "Hermes can fill empty sections or revise its own suggestions; recorded information is protected.",
        "Agent suggestions remain labeled and are excluded from default place/home matching. Explicit profile retrieval may inspect them.",
        "Guest confirmation is a separate guest-only policy, currently unimplemented."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "profileId + topicId; stable across edits."
        },
        {
          "label": "Owner",
          "value": "Shared command workflow; author comes from the actual transport actor."
        }
      ],
      "links": []
    },
    {
      "id": "trip-brief",
      "label": "Trip brief",
      "kind": "Record",
      "group": "People & trips",
      "description": "One stay’s purpose, destination, dates, party, budget and explicit requirements.",
      "fields": [
        {
          "name": "schema",
          "type": "\"zendo.trip-brief/v1\"",
          "required": true,
          "schema": {
            "const": "zendo.trip-brief/v1"
          }
        },
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string",
            "maxLength": 120
          }
        },
        {
          "name": "guestId",
          "type": "string",
          "required": true,
          "description": "The Guest this record concerns.",
          "schema": {
            "type": "string",
            "maxLength": 120
          }
        },
        {
          "name": "revision",
          "type": "integer",
          "required": true,
          "description": "Record-local revision; distinct from the workspace version.",
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "purpose",
          "type": "string",
          "required": true,
          "description": "Why this particular stay is needed.",
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          }
        },
        {
          "name": "destination",
          "type": "\"Vancouver\"",
          "required": true,
          "description": "Current prototype destination.",
          "schema": {
            "const": "Vancouver"
          }
        },
        {
          "name": "start",
          "type": "string",
          "required": true,
          "description": "Check-in local calendar date.",
          "schema": {
            "type": "string",
            "format": "date"
          }
        },
        {
          "name": "end",
          "type": "string",
          "required": true,
          "description": "Check-out local calendar date.",
          "schema": {
            "type": "string",
            "format": "date"
          }
        },
        {
          "name": "budget",
          "type": "number",
          "required": true,
          "description": "Monthly budget in CAD; not a quoted or charged amount.",
          "schema": {
            "type": "number",
            "minimum": 1000,
            "maximum": 100000
          }
        },
        {
          "name": "currency",
          "type": "\"CAD\"",
          "required": true,
          "schema": {
            "const": "CAD"
          }
        },
        {
          "name": "beds",
          "type": "integer",
          "required": true,
          "schema": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4
          }
        },
        {
          "name": "guests",
          "type": "integer",
          "required": true,
          "schema": {
            "type": "integer",
            "minimum": 1,
            "maximum": 8
          }
        },
        {
          "name": "mustHaves",
          "type": "array",
          "required": true,
          "description": "Explicit hard requirements for this stay.",
          "schema": {
            "type": "array",
            "maxItems": 8,
            "items": {
              "enum": [
                "Workspace",
                "Parking",
                "Pet friendly",
                "Gym",
                "Water view"
              ]
            }
          }
        },
        {
          "name": "notes",
          "type": "string",
          "required": true,
          "description": "Ordinary freeform notes in the owning record.",
          "schema": {
            "type": "string",
            "maxLength": 2000
          }
        }
      ],
      "rules": [
        "Changed trip requirements invalidate its recommendation and request draft.",
        "Identical saves preserve both. The shortlist remains available.",
        "The model allows future trips; this prototype has one active trip."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "brief.id → guestProfile.id"
        },
        {
          "label": "Owner",
          "value": "Concierge workflow; linked to one guest."
        }
      ],
      "links": [
        {
          "label": "has relevant place",
          "target": "context-reference",
          "note": "1 → 0..*"
        },
        {
          "label": "considers",
          "target": "shortlist-entry",
          "note": "1 → 0..*"
        },
        {
          "label": "has itinerary option",
          "target": "context-reference",
          "note": "1 → 0..*"
        }
      ]
    },
    {
      "id": "planning-session",
      "label": "Planning session",
      "kind": "Record",
      "group": "Homes & places",
      "description": "A working map dataset of generated references. It can be kept with the brief for later review without becoming requirements or favourites.",
      "fields": [
        {
          "name": "schema",
          "type": "\"zendo.planning-session/v1\"",
          "required": true,
          "schema": {
            "const": "zendo.planning-session/v1"
          }
        },
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "guestId",
          "type": "string",
          "required": true,
          "description": "The Guest this record concerns.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "briefId",
          "type": "string",
          "required": true,
          "description": "Active trip reference for trip scope; null for reusable guest scope.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "briefRevision",
          "type": "integer",
          "required": true,
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "input",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "inputHash",
          "type": "string",
          "required": true,
          "description": "Digest of the profile/brief/reference input used to detect stale planning context.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "workspaceVersion",
          "type": "integer",
          "required": true,
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "createdBy",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "createdAt",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "method",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "retention",
          "type": "working | retained",
          "required": true,
          "description": "Working map or retained brief-linked review snapshot.",
          "schema": {
            "enum": [
              "working",
              "retained"
            ]
          }
        },
        {
          "name": "points",
          "type": "array",
          "required": true,
          "schema": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/$defs/PlanningPoint"
            }
          }
        },
        {
          "name": "datasetHash",
          "type": "string",
          "required": true,
          "description": "Integrity fingerprint of the exact generated point dataset; not signed external proof.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "keptAt",
          "type": "string",
          "required": false,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "keptBy",
          "type": "object",
          "required": false,
          "schema": {
            "type": "object"
          }
        }
      ],
      "rules": [
        "Generate replaces only the working map; keep freezes a separate brief-linked review snapshot.",
        "Working sessions survive local restart until regenerated or discarded. No automatic expiry is claimed.",
        "Keep preserves inputs, revisions, point sources, generating actor, method and dataset hash. No evaluation or training is executed.",
        "Changed profile/brief/reference inputs mark the working map stale. Historical snapshots retain their original meaning.",
        "Discard removes only the working dataset. Kept snapshots and operational history remain."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "planningSession.id; retained snapshots in planningSessions[].id"
        },
        {
          "label": "Owner",
          "value": "Concierge/Hermes planning workflow, linked to one guest and brief revision."
        }
      ],
      "links": [
        {
          "label": "plans for",
          "target": "trip-brief",
          "note": "0..* → 1"
        },
        {
          "label": "contains generated reference",
          "target": "planning-point",
          "note": "1 → 0..*"
        }
      ]
    },
    {
      "id": "planning-point",
      "label": "Planning point",
      "kind": "Record",
      "group": "Homes & places",
      "description": "An exploratory place on a planning map; relevance does not establish guest preference.",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "entityId",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "kind",
          "type": "\"place\"",
          "required": true,
          "schema": {
            "const": "place"
          }
        },
        {
          "name": "title",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string",
            "maxLength": 120
          }
        },
        {
          "name": "category",
          "type": "Work | Lifestyle | Transport | Other",
          "required": true,
          "schema": {
            "enum": [
              "Work",
              "Lifestyle",
              "Transport",
              "Other"
            ]
          }
        },
        {
          "name": "lat",
          "type": "number",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": 49.15,
            "maximum": 49.4
          }
        },
        {
          "name": "lng",
          "type": "number",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": -123.35,
            "maximum": -122.9
          }
        },
        {
          "name": "reason",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "evidence",
          "type": "array",
          "required": true,
          "schema": {
            "type": "array"
          }
        },
        {
          "name": "sourceUrl",
          "type": "string | null",
          "required": true,
          "schema": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        {
          "name": "source",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "method",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "generatedBy",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "status",
          "type": "\"generated\"",
          "required": true,
          "schema": {
            "const": "generated"
          }
        }
      ],
      "rules": [
        "Generated is not a confirmed trip place or profile favourite.",
        "Point evidence and actor are preserved when explicitly promoting it to a saved reference.",
        "Hermes can add client discoveries to the current working map. Profile pins remain concierge-only with recorded guest interest."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "point ID within a planning session"
        },
        {
          "label": "Owner",
          "value": "Generating method or client discovery; actual actor supplied by transport."
        }
      ],
      "links": []
    },
    {
      "id": "context-reference",
      "label": "Context reference",
      "kind": "Record",
      "group": "Homes & places",
      "description": "A place and why it matters, with explicit guest-profile or trip scope.",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string",
            "maxLength": 120
          }
        },
        {
          "name": "guestId",
          "type": "string",
          "required": true,
          "description": "The Guest this record concerns.",
          "schema": {
            "type": "string",
            "maxLength": 120
          }
        },
        {
          "name": "scope",
          "type": "guest | brief",
          "required": true,
          "description": "Guest-profile or active-trip ownership of a place reference.",
          "schema": {
            "enum": [
              "guest",
              "brief"
            ]
          }
        },
        {
          "name": "briefId",
          "type": "string | null",
          "required": true,
          "description": "Active trip reference for trip scope; null for reusable guest scope.",
          "schema": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        {
          "name": "label",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          }
        },
        {
          "name": "category",
          "type": "Work | Lifestyle | Transport | Other",
          "required": true,
          "schema": {
            "enum": [
              "Work",
              "Lifestyle",
              "Transport",
              "Other"
            ]
          }
        },
        {
          "name": "lat",
          "type": "number",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": 49.15,
            "maximum": 49.4
          }
        },
        {
          "name": "lng",
          "type": "number",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": -123.35,
            "maximum": -122.9
          }
        },
        {
          "name": "notes",
          "type": "string",
          "required": true,
          "description": "Ordinary freeform notes in the owning record.",
          "schema": {
            "type": "string",
            "maxLength": 2000
          }
        },
        {
          "name": "status",
          "type": "suggested | confirmed",
          "required": true,
          "schema": {
            "enum": [
              "suggested",
              "confirmed"
            ]
          }
        },
        {
          "name": "placeId",
          "type": "string | null",
          "required": false,
          "schema": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        {
          "name": "source",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "createdBy",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "updatedBy",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "confirmedBy",
          "type": "object | null",
          "required": true,
          "schema": {
            "type": [
              "object",
              "null"
            ]
          }
        },
        {
          "name": "relationship",
          "type": "pinned | relevant | profile-context | itinerary-option",
          "required": false,
          "description": "Pinned guest preference, relevant trip place, or unclassified older profile context.",
          "schema": {
            "enum": [
              "pinned",
              "relevant",
              "profile-context",
              "itinerary-option"
            ],
            "description": "Reference role. itinerary-option is a brief-scoped candidate place, not a reservation, scheduled visit or durable guest favourite."
          }
        },
        {
          "name": "preferenceEvidence",
          "type": "object | null",
          "required": false,
          "description": "The guest’s expressed interest as recorded by the concierge; not authenticated guest approval.",
          "schema": {
            "type": [
              "object",
              "null"
            ],
            "description": "Guest-stated interest, recordedBy/recordedAt and guestConfirmation null. Required by service for new profile pins."
          }
        },
        {
          "name": "planningOrigin",
          "type": "object | null",
          "required": false,
          "description": "Server-verified source session, point and dataset lineage.",
          "schema": {
            "type": [
              "object",
              "null"
            ],
            "description": "Planning session/point IDs, dataset hash, original source/evidence and generating actor, assigned by service."
          }
        }
      ],
      "rules": [
        "Guest scope is reusable and has no brief ID. Trip scope binds to the active brief.",
        "Suggested context is not treated as a confirmed fact.",
        "Creator, source and confirming concierge are separate attributions.",
        "New profile pins require a concierge-recorded statement of the guest’s expressed interest. Hermes cannot pin profile favourites.",
        "Earlier guest references remain profile-context until explicitly reviewed; no liking is inferred by migration.",
        "Explicit promotion from a planning point carries its source session and dataset lineage.",
        "Trip-scoped itinerary-option references are candidates, not scheduled visits, reservations or profile favourites."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "context.referencePoints[].id"
        },
        {
          "label": "Owner",
          "value": "Concierge confirms; Hermes may propose."
        }
      ],
      "links": [
        {
          "label": "can reference",
          "target": "place-document",
          "note": "0..* → 0..1"
        },
        {
          "label": "may be promoted from",
          "target": "planning-point",
          "note": "0..* → 0..1"
        }
      ]
    },
    {
      "id": "place-document",
      "label": "Place document",
      "kind": "Record",
      "group": "Homes & places",
      "description": "A retrievable place description, distinct from a guest’s interest in that place.",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "description": "Stable document identity.",
          "required": true
        },
        {
          "name": "entityId",
          "type": "string",
          "description": "Place-catalog identity.",
          "required": true
        },
        {
          "name": "title",
          "type": "string",
          "description": "Place name.",
          "required": true
        },
        {
          "name": "lat / lng",
          "type": "number",
          "description": "Representative geographic point.",
          "required": true
        },
        {
          "name": "chunks[]",
          "type": "object[]",
          "description": "Named description chunks with text.",
          "required": true
        },
        {
          "name": "revision",
          "type": "string",
          "description": "Content hash revision.",
          "required": true
        },
        {
          "name": "sourceUrl",
          "type": "string | null",
          "description": "Reference supplied by the place seed.",
          "required": true
        }
      ],
      "rules": [
        "Representative coordinates do not guarantee an entrance or current opening hours.",
        "Retrieval uses words and topics, with source chunks and content revisions."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "place:<seed-id> and named chunk IDs"
        },
        {
          "label": "Owner",
          "value": "Curated local place corpus."
        }
      ],
      "links": []
    },
    {
      "id": "home-listing",
      "label": "Home listing",
      "kind": "Record",
      "group": "Homes & places",
      "description": "A rental candidate with synthetic location, availability, amenities and monthly rate.",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "description": "Local synthetic listing ID.",
          "required": true
        },
        {
          "name": "location",
          "type": "object",
          "description": "Latitude, longitude and location accuracy.",
          "required": true
        },
        {
          "name": "price",
          "type": "number",
          "description": "Illustrative monthly CAD rate.",
          "required": true
        },
        {
          "name": "beds / baths / guests",
          "type": "number",
          "description": "Property capacity.",
          "required": true
        },
        {
          "name": "amenities[]",
          "type": "string[]",
          "description": "Listing features.",
          "required": true
        },
        {
          "name": "availableFrom / availableTo",
          "type": "date",
          "description": "Sample availability window.",
          "required": true
        },
        {
          "name": "manager",
          "type": "string",
          "description": "Manager display name, not an authenticated account.",
          "required": true
        }
      ],
      "rules": [
        "Sample IDs are not Runtime or provider listing IDs.",
        "Monthly rates are illustrative; a match is not a quote or availability guarantee."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "properties[].id"
        },
        {
          "label": "Owner",
          "value": "Synthetic catalog in this repository."
        }
      ],
      "links": []
    },
    {
      "id": "fit-result",
      "label": "Fit result",
      "kind": "Record",
      "group": "Decisions & evidence",
      "description": "A derived checklist for a home against the active trip brief.",
      "fields": [
        {
          "name": "score",
          "type": "integer",
          "description": "Percentage of requirement checks passed.",
          "required": true
        },
        {
          "name": "checks[]",
          "type": "object[]",
          "description": "Explicit labels and pass/fail results.",
          "required": true
        }
      ],
      "rules": [
        "Profile interests supply context but do not silently become hard constraints.",
        "The score describes passed fixture checks, not suitability or live inventory."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "property.fit within the active workspace"
        },
        {
          "label": "Owner",
          "value": "Service-derived; never a profile preference."
        }
      ],
      "links": [
        {
          "label": "evaluates against",
          "target": "trip-brief",
          "note": "0..* → 1"
        },
        {
          "label": "evaluates",
          "target": "home-listing",
          "note": "0..* → 1"
        }
      ]
    },
    {
      "id": "shortlist-entry",
      "label": "Shortlist entry",
      "kind": "Record",
      "group": "Decisions & evidence",
      "description": "A considered home and the concierge’s visible comparison note.",
      "fields": [
        {
          "name": "propertyId",
          "type": "string",
          "description": "The considered home.",
          "required": true
        },
        {
          "name": "guestId / briefId",
          "type": "string",
          "description": "Explicit owner links on new entries.",
          "required": false
        },
        {
          "name": "note",
          "type": "string",
          "description": "Visible benefits and tradeoffs.",
          "required": true
        },
        {
          "name": "addedBy / addedAt",
          "type": "string",
          "description": "Actor and time of addition.",
          "required": true
        }
      ],
      "rules": [
        "New records carry guestId and briefId. Legacy records inherit their single-workspace scope.",
        "Removing the recommended home also clears its recommendation and draft."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "propertyId within the active brief"
        },
        {
          "label": "Owner",
          "value": "Concierge and Hermes through shared commands."
        }
      ],
      "links": [
        {
          "label": "refers to",
          "target": "home-listing",
          "note": "0..* → 1"
        }
      ]
    },
    {
      "id": "recommendation",
      "label": "Recommendation",
      "kind": "Record",
      "group": "Decisions & evidence",
      "description": "An authored proposal for a trip brief and home; several proposals can coexist.",
      "fields": [
        {
          "name": "schema",
          "type": "\"zendo.recommendation/v1\"",
          "required": true,
          "schema": {
            "const": "zendo.recommendation/v1"
          }
        },
        {
          "name": "id",
          "type": "string",
          "required": true,
          "description": "Stable record ID; on Guest Profile, the legacy guest-ID alias.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "guestId",
          "type": "string",
          "required": true,
          "description": "The Guest this record concerns.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "briefId",
          "type": "string",
          "required": true,
          "description": "Active trip reference for trip scope; null for reusable guest scope.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "briefRevision",
          "type": "integer",
          "required": true,
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "propertyId",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "reason",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          }
        },
        {
          "name": "createdBy",
          "type": "object",
          "required": true,
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "createdAt",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "status",
          "type": "current | review-needed | withdrawn",
          "required": true,
          "schema": {
            "enum": [
              "current",
              "review-needed",
              "withdrawn"
            ]
          }
        },
        {
          "name": "legacy",
          "type": "boolean",
          "required": false,
          "schema": {
            "type": "boolean"
          }
        }
      ],
      "rules": [
        "Adding a recommendation does not select it or change an existing draft.",
        "A changed brief retains history and marks current proposals review-needed.",
        "Review-needed and withdrawn proposals cannot be selected. Recommending again creates a new proposal for the current revision."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "recommendations[].id"
        },
        {
          "label": "Owner",
          "value": "Recommending concierge or Hermes actor."
        }
      ],
      "links": [
        {
          "label": "is for",
          "target": "trip-brief",
          "note": "0..* → 1"
        },
        {
          "label": "proposes",
          "target": "home-listing",
          "note": "0..* → 1"
        }
      ]
    },
    {
      "id": "selection",
      "label": "Selection",
      "kind": "Record",
      "group": "Decisions & evidence",
      "description": "The single chosen recommendation for this trip; separate from the proposals.",
      "fields": [
        {
          "name": "recommendationId",
          "type": "string",
          "required": false,
          "description": "Chosen proposal, distinct from recommendation authorship.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "briefId",
          "type": "string",
          "required": false,
          "description": "Active trip reference for trip scope; null for reusable guest scope.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "briefRevision",
          "type": "integer",
          "required": false,
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "propertyId",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "reason",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "selectedBy",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "selectedAt",
          "type": "string",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "rules": [
        "Choosing a different recommendation clears its old request draft. Re-selecting the same recommendation preserves it.",
        "Legacy selection.set still creates a recommendation and selects it in one command.",
        "The Book now shortcut composes shortlist, recommendation/selection and local draft commands. It never books externally."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "selection.recommendationId; legacy selections retain their original fields."
        },
        {
          "label": "Owner",
          "value": "Selecting actor through the shared workflow."
        }
      ],
      "links": [
        {
          "label": "prepares",
          "target": "booking-draft",
          "note": "1 → 0..1"
        },
        {
          "label": "chooses",
          "target": "recommendation",
          "note": "0..1 → 1"
        }
      ]
    },
    {
      "id": "booking-draft",
      "label": "Booking request draft",
      "kind": "Record",
      "group": "Decisions & evidence",
      "description": "A local message asking a manager to confirm a proposed stay.",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "description": "Local draft identity.",
          "required": true
        },
        {
          "name": "propertyId",
          "type": "string",
          "description": "Recommended home.",
          "required": true
        },
        {
          "name": "message",
          "type": "string",
          "description": "Editable request text.",
          "required": true
        },
        {
          "name": "status",
          "type": "constant: draft",
          "description": "Local draft state only.",
          "required": true
        },
        {
          "name": "guestId / briefId / briefRevision",
          "type": "references",
          "description": "Explicit decision scope on new records.",
          "required": false
        },
        {
          "name": "createdBy / createdAt",
          "type": "string",
          "description": "Actor and draft time.",
          "required": true
        }
      ],
      "rules": [
        "Nothing is sent, held, reserved or charged.",
        "The draft is not a Runtime ReservationProjection.",
        "Identity changes preserve message text; a concierge should review it."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "request.id"
        },
        {
          "label": "Owner",
          "value": "Local concierge workspace."
        }
      ],
      "links": []
    },
    {
      "id": "actor",
      "label": "Actor",
      "kind": "Record",
      "group": "Authority & interface",
      "description": "The person or Hermes session performing a command, distinct from the guest.",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "description": "Acting identity.",
          "required": true
        },
        {
          "name": "kind",
          "type": "concierge | hermes",
          "description": "Operator category.",
          "required": true
        },
        {
          "name": "sessionId",
          "type": "string",
          "description": "Host/browser session reference.",
          "required": true
        },
        {
          "name": "authority",
          "type": "string",
          "description": "Local authority source.",
          "required": true
        },
        {
          "name": "plugin",
          "type": "string",
          "description": "Client-reported plugin version.",
          "required": false
        }
      ],
      "rules": [
        "Actor and authority are not supplied by model command arguments.",
        "The prototype’s local actor is not a production identity/delegation proof.",
        "A human actor may resolve to Rolodex Person and a Hermes actor to Agent through a future verified adapter. An acting session is distinct from the guest on whose behalf it operates."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "Service-derived actor.id and sessionId"
        },
        {
          "label": "Owner",
          "value": "Local loopback session or native plugin transport."
        }
      ],
      "links": [
        {
          "label": "performs",
          "target": "provenance-event",
          "note": "1 → 0..*"
        },
        {
          "label": "contributes to",
          "target": "profile-chunk",
          "note": "0..* → 0..*"
        }
      ]
    },
    {
      "id": "provenance-event",
      "label": "Provenance event",
      "kind": "Record",
      "group": "Decisions & evidence",
      "description": "A visible command, actor, input and revision linked to earlier local history.",
      "fields": [
        {
          "name": "command / commandId",
          "type": "string",
          "description": "Operation and idempotency identity.",
          "required": true
        },
        {
          "name": "actor",
          "type": "Actor",
          "description": "The acting session.",
          "required": true
        },
        {
          "name": "guestId / briefId",
          "type": "references",
          "description": "Guest and active-trip context on new events.",
          "required": true
        },
        {
          "name": "guestRevision / tripBriefRevision",
          "type": "integer",
          "description": "Record-local revision counters on new events.",
          "required": true
        },
        {
          "name": "briefVersion",
          "type": "integer",
          "description": "Legacy name for workspace revision.",
          "required": true
        },
        {
          "name": "source / details",
          "type": "object",
          "description": "Source scope and visible command input.",
          "required": true
        },
        {
          "name": "previousHash / hash",
          "type": "string | null",
          "description": "Local ledger integrity links.",
          "required": true
        },
        {
          "name": "trainingEligibility",
          "type": "excluded | pending-review",
          "description": "Review intent, not consent or training.",
          "required": true
        }
      ],
      "rules": [
        "A local hash chain is not signed external evidence or provider reconciliation.",
        "Historical event hashes are preserved by additive migrations.",
        "Workspace revision and trip revision are different counters."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "events[].id and commandId"
        },
        {
          "label": "Owner",
          "value": "Shared service command path."
        }
      ],
      "links": [
        {
          "label": "records active context",
          "target": "trip-brief",
          "note": "0..* → 1"
        }
      ]
    },
    {
      "id": "capture-settings",
      "label": "Capture settings",
      "kind": "Record",
      "group": "Authority & interface",
      "description": "Operator intent to flag future events for training review.",
      "fields": [
        {
          "name": "trainingReviewEnabled",
          "type": "boolean",
          "required": true,
          "description": "Operator intent to flag future events for review; not guest consent.",
          "schema": {
            "type": "boolean"
          }
        }
      ],
      "rules": [
        "This flag is not guest consent, disclosure authorization or a completed training action.",
        "The setting is separate from the profile and trip brief."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "Workspace-owned captureSettings"
        },
        {
          "label": "Owner",
          "value": "Concierge only."
        }
      ],
      "links": []
    },
    {
      "id": "workspace-state",
      "label": "UI workspace state",
      "kind": "Record",
      "group": "Authority & interface",
      "description": "Navigation, filters, layout, open sheets, map camera and unsaved editor drafts.",
      "fields": [
        {
          "name": "view",
          "type": "enum",
          "description": "Discover, shortlist, booking, activity or ontology.",
          "required": true
        },
        {
          "name": "filters / sort / layout",
          "type": "object",
          "description": "Presentation of candidates.",
          "required": true
        },
        {
          "name": "guestSection / guestOpen",
          "type": "state",
          "description": "Profile/brief sheet selection and visibility.",
          "required": true
        },
        {
          "name": "inspector / selectedId",
          "type": "state",
          "description": "Open property or context inspector.",
          "required": true
        },
        {
          "name": "briefDraft / profileDraft",
          "type": "object | null",
          "description": "Independent unsaved form edits.",
          "required": true
        },
        {
          "name": "map camera / hover",
          "type": "transient state",
          "description": "View position and visual emphasis.",
          "required": true
        }
      ],
      "rules": [
        "Filtering does not change trip requirements or profile preferences.",
        "Guest sheets are independent of the property inspector.",
        "The map camera is not a geographic reference record."
      ],
      "facts": [
        {
          "label": "Identity",
          "value": "Browser/session state"
        },
        {
          "label": "Owner",
          "value": "Presentation layer."
        }
      ],
      "links": []
    }
  ],
  "rawArtifacts": [
    "catalog.json",
    "ontology.jsonld",
    "schema.json"
  ]
}
