
TL;DR
I founded Nibbble to give independent restaurants loyalty tools that fit how they actually operate. It is a live multi-tenant SaaS at app.nibbble.io: three role-specific portals, Square POS, Stripe billing, and a shared token layer, shipped 2026-04-22 and still running. A four-restaurant customer council validated it, two are in active beta, and it is pre-revenue by design. The strategy and design are mine end to end; Ahsan Amjed was my developer collaborator, with two others co-authoring commits.
Three surfaces, not one role-gated app
The easy version is a punch card with a login screen. Independent restaurants need a system that respects how they actually operate: the owner thinks about margin and repeat visits, staff need speed between orders, customers need a reason to return without homework.
Started with the operating model, not the feature list. Nibbble is three products sharing one spine (owner, staff, customer), each with a different job on the same architecture. The harder challenge was keeping that system coherent while building primarily with AI agents. Without the right scaffolding, agents drift the system every week.
Three users, one system
One shared layer. Three distinct surfaces.
Lane 01
Owner
- Surface
- Management console
- Goal
- Configure rewards, read the numbers.
Lane 02
Staff
- Surface
- Counter app
- Goal
- Apply and redeem between orders.
Lane 03
Customer
- Surface
- Wallet + scan flow
- Goal
- Earn points, redeem at checkout.
Shared foundation
- Shared data model
- Design tokens
- Role-based access
Integrations
- Square POS
- Stripe billing
- Rewards engine
Three portals, one product
3 points

Check points, redeem rewards, view history. The smallest scope, tuned for a few seconds at the counter.
What I did
- Defined the product strategy for independent restaurants, not enterprise chains. The customer council of four restaurants validated decisions before they shipped.
- Designed the core experience across owner, staff, and customer workflows. Three distinct surfaces with different primary actions: admin carries full configuration weight, staff is built around one high-frequency action during rush, customer is built for scan-and-go on a phone.
- Led the production v1 build with Ahsan Amjed: Square POS integration, Stripe billing, multi-tenant Postgres with row-level security, and scheduled operational jobs. Launched 2026-04-22 at app.nibbble.io.
- Created a shared design-token system so three portals feel like one product. Three distinct layouts, one coherent system.
The fork that organized the design: one role-gated app, or three distinct surfaces. The cheap path was a single app that hid and revealed sections by role. It ships faster and shares one codebase. I rejected it because the three users are not the same person with different permissions. They have different anxieties and different tempos: the owner reasons about margin, the server needs one action during a rush, the customer wants scan-and-go with no homework. Role-gating would have forced a shared layout to serve all three and served none of them well. I shipped three distinct surfaces on one shared data model and token layer instead. The token layer is what pays down the cost of that decision: three layouts stay coherent without three separate design systems to maintain.
Built around the people at the register
Three roles. Four questions each.
Role 01
Owner
- Job
- Grow repeat visits and protect margin.
- Anxiety
- Is this worth my time to run?
- Core action
- Configure rewards, read the daily numbers.
- Success
- Regulars coming back on their own.
Role 02
Staff
- Job
- Run it between orders.
- Anxiety
- Don't slow the line.
- Core action
- Apply and redeem in seconds.
- Success
- Fast, no friction at the counter.
Role 03
Customer
- Job
- Get rewarded for loyalty.
- Anxiety
- Not another chore.
- Core action
- Earn and redeem at checkout.
- Success
- A real reason to return.
Three portals, one shared layer
Discrete scopes, one product surface.
Portal 01
Customer
- Scan and go redeem.
- View points history.
Portal 02
Staff
- Search and check in during rush.
- Manage orders.
Portal 03
Admin
- Configure loyalty rules.
- Stripe billing.
- Multi-tenant analytics.
Shared data and tokens
- Postgres with RLS
- HeroUI v3 contracts
- Square POS
- Stripe
- OpenClaw routing
The AI operating model that kept the system coherent
Building primarily with AI agents drifts the system on a weekly clock. Left to the prompt alone, agents touch files they should not, let docs fall out of sync with code, and re-solve problems the codebase already solved. On a three-portal SaaS held together by a shared token layer, that drift is the difference between one coherent product and three that slowly diverge.
So I put the safety in the runner, not the prompt, where an agent cannot argue its way past it. The auto-fix loop runs behind a hard path allow-list with a one-file-per-fix limit, a pre-push hook blocks any code change that skips a docs update, and CI requires a second-model review before anything merges. A codebase-memory graph lets agents query the system's structure before editing instead of grepping blind.
That is governance with a receipt, not a slogan: the loop has landed 17 real commits against real failures, gated behind the allow-list rather than running as a demo. Speed did not become drift.
Autofix commits landed
Local Ollama loop on Nibbble, 2026.
Free per attempt. Real diffs, allow-list gated.
Phase 2 shipped (2026-07)
Four features that close the loop from product promise to measurable outcome, shipped via parallel worktree agents with Ahsan Amjed:
- White-label theming: the customer portal now renders in the restaurant's brand colors and logo. Previously admin stored the brand data; Phase 2 applied it end-to-end.
- Baseline event log: the north-star metric (repeat-visit lift) was previously unmeasurable because insights were snapshots. The event log makes it measurable for the first time. Cohort queries follow in the next phase.
- PWA home-screen layer: diners authenticate via phone OTP and are mobile-first. The PWA manifest and service worker give the customer portal a native-feeling install path on the device they already have in their pocket.
- Notification delivery worker: provider-pluggable (log default, Twilio env-gated). Enqueues on tier upgrade and punch-card completion with deduplication, so the notification loop is closed end-to-end rather than scaffolded and waiting.
A security fix that became a class-level fix
A punch-card bug (one restaurant could award loyalty value to another restaurant's customers) revealed a pattern across multiple staff-authenticated routes: each trusted a restaurant_id supplied in the request body rather than binding it to the caller's token. The routes were distinct but the vulnerability was the same shape.
Fixed the routes, then widened the CI guard to cover every verifyStaffAuth route, not just the admin paths the structural test already watched. The class is now enforced at the CI layer, not just at the instance that surfaced the problem.
What changed
Nibbble moved from idea to live SaaS with a business model, a customer council, a production foundation, and a system for keeping product decisions coherent as it grows.
- Production multi-tenant SaaS running at app.nibbble.io since 2026-04-22: three portals, Square POS, Stripe billing, multi-tenant data layer.
- A customer council of four restaurants, two in active beta. Pre-revenue by design: at this stage the asset is operator-validated product decisions and production discipline, with revenue as the next milestone.
- Phase 2 shipped: white-label theming, baseline event log (north-star now measurable), PWA, and notification delivery, wired end-to-end.
- A documented multi-agent development stack where design, product, and engineering choices stayed connected through the build.
Commit attribution
- Mohsin
- 387
- Others
- 25
Reflection
Encode the guardrail where it cannot be argued away. Putting the allow-list, docs gate, and second-model review in the build system rather than the prompt is what let a small team move fast without the system fragmenting. A prompt can be forgotten or overridden; a runner cannot. That is the pattern I carry into any AI-native team I lead.
Stress-test the roadmap from the demand side, not just the engineering side. Running a three-lens review (CEO, CTO, CDO seats, each grounded in a code audit before forming an opinion) surfaced that the roadmap was complete and well-sequenced for engineering while missing its entire demand side: no pilots, no positioning, no revenue motion. Only role-forcing exposed it. The output was a new "Prove it" phase inserted before product expansion: positioning one-pager, named pilots, and the baseline event log that makes lift measurable. The roadmap now carries all three lenses with provenance, ready for Ahsan and me to ratify owners and dates.
Two things I would do differently:
1. I optimized for build discipline before I had demand proof. Nibbble is pre-revenue by design, but that framing can hide a real risk. I built runner-level rails, a docs-sync gate, and a token layer before a single restaurant paid. The next proof has to be usage, retention, revenue, or operator behavior, not more build velocity or a cleaner commit history. If I ran this again, I would spend the customer council on willingness-to-pay signals earlier, not just design validation. 2. Three surfaces was the right call, but I under-invested in the seam too long. The three-portal decision holds up. What I would change is timing: the shared token layer is the only thing keeping three layouts from becoming three design systems, and I treated it as infrastructure to harden later rather than the load-bearing decision it was. Running this with a Director of Product Design team, a design-systems lead would own that token layer from day one.
Nibbble is what it looks like to turn ambiguity into a shipped product without letting it fragment.
