Skip to content
All work

Agentic AI · Production · Sealed at v1.0.0

Nistula Assistance

A WhatsApp host that quotes real prices, gets the job onto the right phone, and structurally cannot promise something nobody is going to do.

Built

2026 · built solo during a three-month internship

Stack

  • TypeScript
  • Fastify
  • Postgres
  • pg-boss
  • Claude Sonnet 4.5
  • WhatsApp Cloud API
  • eZee PMS

No live demo — the deployment was retired when the project was sealed.

01 — The problem

A guest asks the price. The model must not answer.

Guests message one number, at any hour, about anything — availability, rates, extra towels, a late checkout. An assistant that answers well is easy to build. An assistant that never invents a price is a different problem.

A language model that has seen a thousand rate cards will happily produce a plausible one. In hospitality that is not a glitch; it is a quote the property then has to honour, or refuse and lose the guest. The same applies to actions: an assistant that says “housekeeping is on the way” when no job was created has done real damage.

So the design puts the model where it is good — reading intent, writing naturally in the guest’s register — and takes the decisions away from it. Prices come only from a tool call against the live property management system. Actions exist only if a row was written. Then, after the model has written its reply and before anything is sent, a pipeline of deterministic checks reads what it produced and decides whether it may leave the building.

Two phones side by side: the guest asks for two extra towels and gets a reply, while housekeeping receives a task card with a job code.
The guest’s phone and housekeeping’s phone. The promise is only made after the job exists. · docs/readme-assets/hero-two-phones.png
Tools
7
quote, availability, booking link, booking lookup, staff task, memory, escalation
Tests
1,813
across 106 files, green on Node 22 and 24
Live backlog
62 items
drained in three polls with 0 errors and 0 ops alerts
Blockers caught
17
by review, behind an already-green test suite
02 — The decision

The checks run after the model, not in the prompt.

Asking a model nicely not to invent prices is a preference. Reading its output afterwards and refusing to send it is a rule. Everything interesting about this project follows from choosing the second one.

The guardrail pipeline sits between the model and the WhatsApp send. It re-reads the draft against what the tools actually returned this turn: a number that no tool produced fails price integrity; a commitment with no matching job row fails promise integrity; a reply that negotiates on rate fails the negotiation lock. A failing draft is rewritten or escalated to a human — it is never sent and softened.

The guardrail pipeline: a drafted reply is checked against tool results before sending.
The pipeline the repository calls the safety rails. · docs/readme-assets/safety-rails.png

The specification numbers the pipeline at seven checks — price integrity, promise integrity, negotiation lock, window check, identity honesty, length and format, leak scan. Two more, stay integrity and unit integrity, were added later and run in the same pass, so the telemetry enum lists nine rules against the plan’s seven. The count in the code is the honest one.

03 — What it actually ran against

A real property, a real backlog.

It was verified against a Meta test line and the property’s live eZee PMS rather than against fixtures. The clearest evidence is the first poll of the production queue: the poller drained the property’s entire un-acknowledged backlog in three passes — 62 real items mirrored and acknowledged, 0 errors, 0 operator alerts, covering 22 confirmed stays across Airbnb, Booking.com, MakeMyTrip and walk-ins, plus 40 cancellation tombstones.

The system in four lanes: guest conversation, tool calls, staff dispatch, and the operator console.
Four lanes — the guest, the model’s tools, staff dispatch, and the operator. · docs/readme-assets/system-four-lanes.png

The other piece of evidence is less flattering and more useful. Before merge, every chunk went through a multi-agent adversarial review whose only job was to find what the tests had not. On this project that gate caught seventeen blocker-class defects sitting behind a suite of 1,813 passing tests. A green suite proves the code does what its tests say; it does not prove the tests asked the right questions.

What it deliberately does not do

  • It does not negotiate. Rate is not a conversation. A guest pushing for a discount is handed to a human rather than met halfway by a model with no authority to discount.

  • It does not pretend to be a person. Identity honesty is one of the checks. If a guest asks whether they are talking to a human, the answer is no.

  • It has no live demo. The deployment was retired when the work was sealed at v1.0.0, so the repository, its tests and its review record are the whole of the public evidence.

What it gets wrong

The dependency audit in CI is set to continue-on-error, deliberately, at seal — a HIGH advisory in a transitive dependency was failing the pipeline without a fix available upstream. That is a known, dated compromise recorded in the repo rather than a silently disabled check.