Inspiration

COVID destroyed a lot of family businesses around here. I wanted a way to embed AI as a layer between people and businesses in real life — an intelligent way to find, search and discover experiences, food, products and services together — to drive real economic activity for local businesses and give people a reason to get out and explore again.

Most local tools ask a business to build a website, install an app, or learn a dashboard. Most owners never will. So Lucilla meets them where they already are: a shop texts one sentence and it's listed. On the other side, a person texts what they actually want and gets real local deals, rewards and experiences with friends, not alone.

The goal is connecting communities and enriching them with better experiences: learning what people are genuinely looking for, and putting that in front of the businesses who can provide it.

What it does

Three surfaces, one agent: SMS, WhatsApp and in-app.

For businesses, SMS is the wedge. A shop texts one sentence name, what they sell, hours — and they are listed. No app install, no website, no dashboard. They then text a keyword deal ("TACO10 - 10% off tacos") and that deal is what earns them a pin on the map. They can text to change hours, add what they sell, post an event, check how many people claimed, or ask what customers in their area are looking for.

For consumers, you text what you actually want in plain language "cheap barber open right now", "best shawarma", "somewhere for six people on Friday" and get real local businesses with whatever deal is running. You can claim a deal by texting its keyword, get USDC cashback, join a group or a meetup, and find events near you.

The loop that makes it a business rather than a demo: a claimable deal is what earns the map pin, a claim is what proves a customer walked in, and those claims are what the ranking learns from.

How we built it

The agent is not a chatbot wrapper. An inbound message runs through a deterministic router first — commands, keyword claims, owner flows, host queues and the model is consulted where the code would otherwise guess. One rule governs that split: a cheap check may say YES fast, but it must never be the thing that says NO.

Every message writes one row to a single learning spine (connector_turns): what was asked, which branch answered, what was retrieved, what was replied, and resolved twenty minutes later — what the person actually did (claimed, redeemed, rephrased, went silent). A grader labels those turns, and nightly jobs fold the labels back into the structures the router reads on the next message: a nearest-neighbour route memory built from graded asks, a dynamic lexicon of phrases people actually use, an eval set that gates every deploy, and per-business ranking priors learned only from real outcomes.

Because there is no real traffic yet, the same loop is driven by a sandbox: 1,000-conversation waves of LLM personas — consumers, owners, hosts, joiners, Spanish speakers, typo-prone texters — run against the deployed build for about $2 a wave, graded turn by turn, bucketed by failure cluster, fixed, and re-run.

Challenges we ran into

The hardest problem was not the model, it was knowing when the model is wrong. Three examples that shaped the architecture:

A regex gate meant a real grocer's listing message never reached the classifier at all. He was answered as if he were a customer searching, 28 times, with the same sentence. The model never saw his message. That produced the rule above, and a conversation guard that notices when the agent repeats itself and escalates instead of looping.

The agent once told an owner his promo was live when nothing had been created. Checking the database instead of believing the reply caught three separate false claims in one day. Status is now computed from the real gate and handed to the model as a fact it may not contradict.

Our own cost circuit breaker disabled the AI API for the whole product because a legitimate training wave looked like a runaway. It now uses declared load windows and a soft halt before it ever disables a service.

Accomplishments that we're proud of

The self-improving loop works and is measured, not asserted. Across sandbox waves the misroute rate fell from 28.9% to 15.8%, each drop traced to a specific fixed cluster. Wave 6 ran 2,751 turns for $2.60 and added deterministic scoring for whether the agent holds context across ten-turn conversations.

The whole thing runs at a cost that makes local viable: about $0.000022 per graded turn, one embedding per user intent, and a reply that fits in a single SMS segment.

What we learned

Comments describe code, never data. Every claim about production in this project had to be a query. That habit caught a public stats page reporting 241 users when 170 of those documents were empty seeded shells with no account behind them, and a business profile that silently failed to load because two parts of the system wrote the same field in two different shapes.

What's next for Lucilla

Onboarding businesses across Hamilton in person, because the first real claims are what the ranking has been built to learn from and cannot be simulated. Then the group brain — a per-person and per-group profile so the agent knows when to speak, what to suggest, and when to stay quiet — and putting the matching side of the product on the same learning spine as search.

Additional info (judges only)

Cloud Run, Firestore, Pub/Sub

Reason: all Cloud Functions are v2, which run on Cloud Run. Firestore is the primary datastore. Pub/Sub is used via onMessagePublished. Cloud SQL and GKE are NOT used — do not tick them. Also true but not on their list: Cloud Tasks, Cloud Scheduler, Cloud Monitoring, Secret Manager, BigQuery, Cloud Storage.

Sponsor / special prizes: opt in to Startup Excellence Submitter type: see NOTE below Country of residence: Canada Category: Taskmaster Organization name: Lucilla Inc Project start date: 08-20-26 Repo URL: https://github.com/superbigroach/lucilla-agentic-submission Reproducible testing instructions in README: Yes Hosted project URL: https://lucilla.app Startup prize org: 16699448 Canada Corporation Startup prize corporate email: s.borjas@lucilla.ca

Built With

Share this project:

Updates

posted an update

THE PROBLEM

Every local shop already has customers walking past. What it does not have is an agent layer between the two. The shop owner has no app, no dashboard, no time, and no way to answer a stranger who is standing outside asking "who does this near me?" So the shop stays invisible while the customer, 200 metres away, never learns it exists. Both sides are one message apart and neither has anything that speaks for them.

Every tool built for this asks the shop to come to it: sign up, log in, fill a listing form, upload photos, learn a dashboard. That is the wrong direction. A shop should be able to say what it does in one sentence, the way it would to a person, and be represented from then on.

THE VALUE

Lucilla is that agent layer. It sits on a phone number, so the business needs nothing installed: it texts one sentence and an agent classifies it, geocodes it, enriches it, asks only for what is still missing, registers a promotion, and publishes a findable listing with a live deal. From then on the agent answers for that shop, day and night, in 16 languages.

On the customer side the same agent answers in plain words. No keyword, no promo code to know in advance. Ask for what you want, get a redeemable code, walk in.

One agent, both sides of the counter, and neither of them had to learn software.

Please use this video for submission its explained in comments and description,

https://youtu.be/AzqhQORt1TI

Log in or sign up for Devpost to join the conversation.

Submission history