Integrations for Hotels — External System Mediation
Status: Integration Architecture
Sources: Integration Matrix & System Adapters Specification, Apache Camel Compliance Gateway (compliance-camel, :8181), Jijibora Architecture — Design Thesis in Developer Terms, AGENTS.md — Sovereign OS / Cosmic Circuit mandates 6 & 7
1. Canonical Mediation Model
External systems never connect directly to each other or mutate SurrealDB schema. All peers participate as mediated peers through Apache Camel (:8181) → NATS JetStream (:4222) → SurrealDB canonical primitives:
- Hotel PMS / POS / OTAs
- ERPNext (finance/procurement)
- OpenMAINT / CMDBuild (CMMS)
- Plane.io (task & project management)
- Synapse / Matrix (staff chat)
- Fleetbase (logistics & dispatch)
- MinIO (object storage)
- Gotenberg (PDF generation)
- Keycloak (identity & access)
- Solver Gateway
:3070(optimisation)
The State of Record (SoR) boundary is split: Sovereign OS owns operational state and approvals; each external peer owns its domain of fiscal/technical authority.
2. PMS (Property Management System) — System of Engagement
Role: Guest-facing reservations, check-in/check-out, room rates, channel manager (OTAs). The PMS remains the guest system of engagement; Sovereign OS is the headless state of record.
Mediation: PMS webhooks → Camel → cns://claim/type/hotel/reservation claim; room occupancy bound via truth_edge lease; folio lines mirrored to ERPNext for fiscal.
SoR boundary: PMS owns fiscal reservation details (rates, taxes, channel commissions); Sovereign owns operational state (occupancy, housekeeping, maintenance links, PoCE audit).
Conflict rule: Sovereign wins on approval/operational state; PMS wins on fiscal reservation details.
3. ERPNext — Finance & Procurement SoR
Endpoint: http://localhost:8000/api/resource (ERPNext API)
Role: Vendor ledger, fiscal Purchase Orders, stock intake, general ledger, accounts payable.
Adapter logic (H-4 / Process 1):
- Requisition claim transitions to
APPROVEDvia PoCE session - Camel executes idempotent
POST /api/resource/Purchase Orderwith headerX-Idempotency-Key: {requisition_id} - ERPNext
name(e.g.,PO-2026-00412) recorded inintegration_entity(system: "erpnext") - Goods receipt matched to PO; three-way match before payment release
SoR boundary: Sovereign owns requisition assembly, budget threshold routing, dual-custody approvals, delivery compliance. ERPNext owns fiscal GL, tax computation (VAT/GST), accounts payable disbursement.
Conflict rule: Sovereign wins on approval state; ERPNext wins on fiscal ledger.
Fail closed: If ERPNext returns 5xx or times out, Camel aborts with HTTP 502 Bad Gateway. No synthetic PO IDs (dummy_po_123).
4. OpenMAINT / CMDBuild — Facilities & Maintenance (CMMS)
Endpoint: http://localhost:8080/rest/v3
Role: Physical asset catalog, room/asset bookings, maintenance work order generation.
Adapter logic (H-3 / Process 8):
- Fault incident claim → Camel → OpenMAINT
openmaint.v1.cmd.workorder.create - Returned WO id stored in
integration_entity(system: "openmaint") - OpenMAINT schedules technician; updates sync back over NATS JetStream to the task claim
- On completion, technician submits photo evidence; PoCE finalizes work order; payroll claim released
SoR boundary: Sovereign owns operational allocation, user reservation, purpose, sign-off. OpenMAINT owns asset spec, serial number, depreciated value, maintenance history.
Conflict rule: Sovereign wins on booking availability; OpenMAINT wins on asset spec.
5. Plane.io — Task & Project Management
Endpoint: http://localhost:8091/v1
Role: Engineering task boards, capex project tracking, renovation work tracking.
Adapter logic:
- Task claim (
cns://workflow/task) → Camel → Plane issue creation - Plane
issue_idlinked inintegration_entity(system: "plane") - Plane webhooks (
issue.updated) → Camel → update task claim status in SurrealDB (bi-directional sync)
SoR boundary: Sovereign owns checklist completion, evidentiary hashes, sign-offs. Plane owns state column (Todo/Done), board lane, estimate points.
Conflict rule: Last-write-wins mediated by PoCE revision timestamps.
6. Synapse (Matrix) — Staff Communication
Endpoint: http://localhost:8008/_matrix/client/r0
Role: Real-time E2E-encrypted discussion rooms for staff collaboration (Process 5) and meeting notes (Process 4).
Adapter logic:
- Discussion thread claim created → Camel →
POST /_matrix/client/r0/createRoomwith alias#thread_{id}:hotel.local room_idstored inintegration_entity(system: "synapse")- Inbound Matrix events via Synapse Application Service → NATS subject
ingress.v1.synapse.message - Camel listens, mirrors verified messages as
cns://collaboration/discussion_commentclaims
SoR boundary: Synapse is real-time transport/ciphertext stream; Sovereign is authoritative record (governance promotion, consensus record, thread parent).
7. Fleetbase — Logistics & Dispatch
Endpoint: http://localhost:9002/v1
Role: Multi-stop vehicle dispatch, delivery routing (linens, F&B supplies, laundry, amenities).
Adapter logic: Confirmed purchase orders requiring transport dispatch a routing job to Fleetbase via Camel; returns delivery tracking waypoints.
8. MinIO — Object Storage (Evidence & Assets)
Endpoint: :9000 / :9001
Role: Storage of evidentiary attachments (housekeeping photos, maintenance photos, incident evidence), mood board assets, exported PDFs.
Integrity rule: All media in MinIO must have SHA-256 hash recorded in the Sovereign claim.evidence array or truth_node.attributes. No hash, no valid evidence.
9. Gotenberg — PDF Generation
Endpoint: :3094
Role: Immutable, signed PDF documents for folios, invoices, BEOs, mood board decks, insurance packets, compliance packets.
Routes: /services/playbook/moodboard/{board_id}/export-pdf; folio/invoice export on check-out.
10. Keycloak — Identity & Access
Endpoint: :8081
Role: Staff and guest identity realms, OIDC/OAuth2, BBS+ credential anchoring, APF role resolution.
Integration: X-Sovereign-DID-Proof header (Ed25519 or BBS+ signature) on cross-tenant API calls. APF (s230) resolve_effective(user, app, scope) answers "what may this principal do in this property scope".
11. Solver Gateway — Optimisation (:3070)
Endpoint: POST /v1/decisions (decision-request-v1 → decision-result-v1); NATS svc.solver.v1.<capability>.<version>.solve
Hotel use cases:
procurement.basket_split@1(branch_and_bound 1.4.0): split F&B basket across vendors for least cost — proposes only; buyer disposes- Housekeeping route optimization: attendant route sequencing — proposes; housekeeping supervisor confirms
- Maintenance crew routing: technician dispatch sequencing — proposes; engineering lead confirms
Fail closed: If solver-gateway is down/unreachable → 503 invent_refuse. Never return synthetic OPTIMAL, fill plans, or routes (D-09 — Optimization Capability (developer) failure catalog F1).
12. NATS JetStream — Event Spine
Endpoint: :4222
All hotel playbook events ride the criteria fan-out subjects (platform.criteria.v1.*). Subjects are declared in NATS KV lookups (canonical_subject, canonical_event_type, pipeline_id) — never invented in code. Outbox persistence via nats_outbox (s150) is the durable delivery anchor; the DB is SoR; NATS is the bus.
13. Error Handling & Fail-Closed Behavior
| Scenario | Response |
|---|---|
| ERPNext / OpenMAINT / Plane / PMS 5xx or timeout | HTTP 502 Bad Gateway, RFC 7807 problem details; queued in nats_outbox for exponential retry |
| Solver-gateway down | 503 invent_refuse; no synthetic OPTIMAL/plan |
| NATS / Kestra down | 502/503; no fill invented; LIVE flag unmet → refuse |
| External sync succeeds but DB write succeeds | Outbox retry up to 5 times, then operator alert via Prometheus/Grafana |
| No matching lookup band / missing registration | Refuse; never fill gap with plausible substitute |
Zero synthetic adapter payloads: No dummy coordinates, dummy suppliers, hardcoded org IDs, or Array.from() fake routes to satisfy a downstream contract. Return HTTP 400 if the caller's request does not match the real service contract (docs/schemas/decision-request-v1.json).