Skip to content

Use cases

View as Markdown

Each of these is built from registered actions, functions and events. The names are the real ones; the parameter schemas are in the API reference.

A property does not start by switching systems. A connector reads what the property already runs, lands every record verbatim, and folds it into the model through the same actions a person would use. Mews, Apaleo and Cloudbeds have connectors today.

  1. Register the connector. Apply register_connector with a display name, the source kind (pms, pos, …), the provider, the mapping references for each vendor stream (mews_rate@1, mews_resource@1, …), and a secret_ref: the name of the credential in the secret store, never the credential itself. The validator refuses credential-shaped values. The connector’s business id, CN-…, is the source every landed row carries.

  2. Run a sync. start_connector_sync opens a connector_sync_run; the extraction side pulls from the vendor on its schedule and lands rows in the raw staging area exactly as they arrived. Nothing is dropped or coerced at the door.

  3. Fold through actions. The loader replays each landed row through the mapping’s declared actions, validated, idempotent and audited like any other write. complete_connector_sync closes the run with its counts, so the sync is itself an object you can read, and every record it wrote is on the event log with that run as its origin.

  4. Rehearse the switchover. When the hotel decides to run on Aerandil, the cutover is rehearsed against its own data first, comparing what the model says against what the PMS says, before the day it happens.

Related: pause_connector, resume_connector, repoint_connector_mapping and retire_connector manage the connector’s life; the switchover_shadow metric reports the comparison.

A guest taps their room key at the bar and the charge lands on their bill. The key is a locator, never an authenticator, so a cloned card buys nothing.

  1. Issue the credential at check-in. issue_access_credential binds a physical or mobile key to the stay, with a per_charge_cap and a daily_cap. Its token is what a reader picks up; it resolves to the stay’s open folio and nothing else.

  2. Resolve the tap. The terminal reads the card and the till calls resolve_access_credential, or POST /v1/key-charge/tap on a cell with a terminal bridge, which triggers the read and resolves it in one step. Resolution requires an active credential, an unexpired expires_at, and an in-house stay; it answers with the guest’s name for the member of staff to confirm.

  3. Post the charge. After confirmation, post_charge_by_credential posts to the folio the credential resolved to, bounded by the caps. The charge, the folio and the credential are all on the event log with the till’s principal.

  4. Revoke at check-out. check_out revokes every credential on the stay, and revoke_access_credential does it early. A revoked card fails closed at the reader; its token is removed and only a hint stays behind for audit.

An agent that proposes, a person who confirms

Section titled “An agent that proposes, a person who confirms”

An agent’s tools are the same actions the desk uses, with the same scopes. For a write that moves money, touches identity, or carries other high stakes, the agent does not apply; it proposes, and a person decides.

  1. The agent proposes. propose_action records a frozen, auditable proposed_action: the target action, its parameters, the subject, the agent’s rationale and confidence, a bounded snapshot of the context it saw, and who must confirm: the guest, a member of staff, or an approval gate. A second proposal for the same action and subject supersedes the first.

  2. A gate opens. For staff approval at scale, request_approval_gate opens a durable approval_gate with a strategy (any_one, all, quorum, role_based, ordered_chain, separation_of_duties), the eligible roles or principals, the excluded ones (the requesting agent among them), a risk tier, and where the notification surfaced. The context shown to approvers is frozen and hashed.

  3. A person decides. decide_approval_gate records an approval_decision (approve, reject, request_changes, delegate, abstain) against the gate’s current context hash, so a decision made on stale facts is refused. An agent’s decision can be recorded for the audit but cannot satisfy a gate that requires a human.

  4. The kernel fires, or not. On approval the proposed action runs through the same engine as everything else, and its events carry both the agent that proposed it and the person who approved it. reject_proposed_action closes it with a reason; an unconfirmed proposal expires on its own, by default after 24 hours.

Every step is on the event log, so “who did what, and on whose authority” is a query, not a reconstruction.