The Guardrails Are the Product

An AI operations layer runs the reporting for a $5M, five-city cleaning company. Here is everything it is forbidden to touch — and the three places that prohibition has documented exceptions.

Ilya — owner, NW Maids. Written 5 August 2026. All figures below are as of that date.


The operating situation

NW Maids does roughly $5M a year in residential cleaning across five cities, with more than 100 cleaners in the field. The back office is three people, all remote. I run the company remotely too. Founded 2013.

That ratio is the whole reason any of this exists. A field-service business at this size normally carries a dispatch desk, a support desk, and someone whose entire job is chasing reporting. We don't. The gap gets filled by a deterministic automation layer that has existed for years, and — since late May 2026 — by an AI operations layer sitting on top of it.

The AI layer has been in production for about ten weeks. The self-hosted infrastructure underneath it has been in production for about four (VPS provisioned 6 July 2026). That is recent, and I am not going to pretend otherwise. Anyone evaluating this should weight it accordingly.

I'm not a traditional engineer. I built this through AI-assisted development, running privileged commands myself, with Claude as the technical guide.


What this is not

Let me kill the obvious misreading first, because the honest version is more interesting than the hype version.

This is not an AI that runs my company. It doesn't answer customers. It doesn't assign cleaners. It doesn't screen applicants. It doesn't resolve complaints. It doesn't set prices. Four entire functions of this business have essentially zero AI involvement, by design.

What it is: an operations analyst and chief-of-staff that reads nearly every system in the company on a schedule, notices things, and stages decisions for a human. The internal file that governs it is called CEO_INSTRUCTIONS.md, which — I'll say it before you do — oversells what it is. It's a constitution for an analyst, not a mandate for an executive.

The interesting engineering here isn't the capability. Capability is cheap now. The interesting part is the constraint: what a system like this is stopped from doing, how that stop is actually enforced, and what happens the four times the stop didn't hold.


The architecture, end to end

BUSINESS INPUTS          booking system · CRM/email engine · call tracking · SMS ·
                         shared inbox · Google Business Profiles · Local Services Ads ·
                         rank tools · web analytics · time tracking · accounting
                                    │
                                    ▼
WORKFLOW / DATA LAYER    ~150+ deterministic automations (no model in the loop):
                         inbox routing & labeling · form→booking→CRM enrollment ·
                         hiring pipeline glue · job lifecycle logging · SOP checklists ·
                         drip/win-back/referral sends
                                    │
                                    ▼
AI REASONING LAYER       23 recurring scheduled jobs. Each one reads the constitution
                         first, then its own data sources, then decides whether
                         anything a human needs to see actually happened.
                                    │
                                    ▼
STAGED ACTIONS           inbox_for_you.md — a plain markdown approval queue.
                         Fixed format: Decision needed / Options A–C / My recommendation.
                         Plus done_for_review.md and state/decisions_log.md.
                                    │
                                    ▼
DASHBOARDS & ALERTS      CSV trackers (ranks, leads, bookings) · internal Slack for two
                         job types only · email for new website leads
                                    │
                                    ▼
HUMAN ESCALATION         Me, for anything touching the five hard-stops.
                         Staffing coordinator for off-policy cleaner invites.
                         Support lead for negative feedback. Listings coordinator
                         for profile and photo work.

Note what the approval surface actually is: a markdown file. There is no console, no approval GUI, no workflow product. I open a file and read it. That's a real limitation and I'll come back to it in the section on what transfers.


The five hard-stops

The constitution stops the system on five classes of action. Each one routes to me instead of executing.

  1. Spending money
  2. Messaging any real person
  3. Publishing public content
  4. Changing booking, pricing, or customer data
  5. Using a credential it wasn't granted

Now the part most write-ups of this kind leave out.

How the stops are actually enforced

Mostly by written policy the model follows — not by permission walls. I want to be exact about this, because it's the claim a serious evaluator will push on hardest, and because overstating it would poison everything else in this document.

There are three real technical controls:

Control Type Scope
Credential scoping Technical The system can only act through connectors and browser sessions I'm already logged into. It never enters passwords. I type privileged and server credentials myself. What it doesn't hold, it cannot use.
CRM API write-block Technical Direct API writes to the CRM return 403. Any CRM change has to route through a human-driven UI path.
No payment instrument Technical, by omission It holds no payment method. The ads job is explicitly forbidden from entering or modifying payment methods and budgets — and also has nothing to enter one with.

Everything else is behavioral. The booking system, the Google Business Profiles, and the live website are all technically writable by this system. It refrains because the constitution says to. That's it.

If you want the one-sentence honest version: read-only is enforced primarily by a written constitution the model follows plus credential scoping, not by hard read-only permissions on each system.

The 7/20 incident below is the proof that this distinction is not academic.

The three documented exceptions

Three of the five stops carry a standing pre-approval I granted deliberately. I'd rather publish these than have someone discover them:

Stop Exception Granted
Messaging a real person The Local Services Ads job can send review requests to satisfied, already-booked customers. Internal Slack posts to my own team are also permitted — team-facing, not customer-facing. 15 July 2026
Publishing public content The quarterly testimonials job publishes refreshed review content directly to live website pages and a microsite. It then asks me only for a CDN cache purge. Standing
Changing booking/customer data The Local Services Ads job marks leads as booked and files valid lead disputes in the ad console. Standing

So the accurate claim is not "it never messages customers or publishes content." The accurate claim is: every action of those classes is blocked by default, and three narrow, dated, single-purpose carve-outs exist that I granted explicitly and can revoke. That's a weaker sentence and a truer one.

Approval volume

inbox_for_you.md took roughly 40–70 appended items per week through late July, peaking at 12–13 in a day, tapering to 3–7 per day in early August.

Caveat that matters: those entries mix genuine decision-needed escalations with status and FYI notes. The pure "blocked action awaiting approval" subset is smaller and I don't tally it separately. I could give you a clean approvals-per-week number only by tagging inbox entries by type, which I don't currently do. So I won't give you one.


The 23 jobs

Exact count as of today: 23 recurring, enabled AI jobs, plus 5 dated one-time tasks and a retained tail of ~30 completed one-offs. I had been saying "about 22" from a late-July internal count; the live number is 23. Every one of these is AI-assisted or draft-and-check. None are fully autonomous except where the standing exceptions above apply.

# Job Cadence What it does Department Class
1 Daily operations run Daily Works unblocked tasks, stages drafts, logs decisions Cross-functional Draft+check
2 PR / media scan Daily Drafts pitches in my voice from journalist-request feeds Marketing/PR Draft+check
3 Local PR & backlinks Daily Verifies targets, stages outreach drafts. Never sends Marketing/PR Draft+check
4 Job-invites review Daily Posts to Slack only when an invite needs changing Scheduling AI-assisted
5 Review allocation Weekly Re-runs value-per-review model across 4 profiles Marketing/SEO AI-assisted
6 Testimonials refresh Quarterly Publishes review content to live pages Marketing/SEO Standing exception
7 Security advisories Monthly CVE report for the self-hosted apps IT/Ops AI-assisted
8 Booking attribution Daily Yesterday's bookings + rolling 7-day intent Reporting AI-assisted
9 Price-increase churn watch Daily Flags objections, stages rate-freeze offers Retention Draft+check
10 Win-back reply tracking Daily Logs and surfaces responders Retention AI-assisted
11 Lead-alert health check Daily Silent unless the alert path itself is broken Lead intake AI-assisted
12 Comms watch (daily) Daily Silent incident log across email, SMS, calls Inbound messages AI-assisted
13 Comms watch (weekly) Weekly Patterns, surfaced only if actionable Inbound messages Draft+check
14 Local Services Ads maintenance Daily Matches leads; marks booked, files disputes, sends review requests Ads/Lead intake Standing exception
15 Listing-violation tracking Weekly Flags previously-reported listings still in violation SEO AI-assisted
16 Payroll hours pull Weekly Reports hours to pay. The pay run is human Payments AI-assisted
17 Portland profile recovery watch Daily Watches a delisted profile until restored SEO AI-assisted
18 Commercial lead tracker Daily Logs new B2B leads to CSV + Slack Lead intake (B2B) AI-assisted
19 Directory listing check Daily Presence check on a third-party list SEO AI-assisted
20 Property-manager watch Weekdays Recommends actions on B2B/vendor-portal activity B2B AI-assisted
21 Map-pack rankings Daily Appends to rankings CSV. Read-only, silent SEO AI-assisted
22 Organic rankings Weekly 25-pair snapshot + week-over-week summary SEO AI-assisted
23 Proven-roster refresh Weekly Rebuilds per-city proven-cleaner roster from history Scheduling AI-assisted

Two of those jobs are worth calling out for what they don't do. Job 4 reviews cleaner invites and posts to Slack only when one is off-policy — it never sends an invite. Job 23 rebuilds the roster of proven cleaners per city — and never assigns one to a job.


The deterministic layer underneath

The AI jobs sit on top of a much larger rule-based layer with no model in it at all. Counts below were verified in a 29–31 July pass and have not been re-counted live; treat them as accurate as of late July.

Platform Count What it does
Chatwoot automations ~116 Inbound routing, labeling, auto-acknowledgement
Chatwoot canned replies 179 Suggested answers — a library, not an autoresponder
Activepieces flows 14 Form→booking→CRM enrollment, hiring glue, job lifecycle logging
Donetick recurring checklists ~49 Onboarding and support SOPs
Donetick conditional checklists 8 Branching SOPs
ActiveCampaign automations Uncounted Drip, win-back, referral, review-request sends

So: on the order of 150+ deterministic automations, with one platform's set never enumerated. I'd rather report an honest "uncounted" than round it into the headline.

The Chatwoot set is the one most likely to be misread. Those 116 automations tag, route, and suggest. They do not compose customer answers. There is no AI autoresponder on my support inbox.

(The self-hosting migration that produced this stack — replacing $573/month of SaaS with a $51/month box, and the security grounds on which I rejected n8n, FreeScout, and Vikunja — is a separate write-up.)


The department map

Eight departments, four class labels, gaps included.

Department Rule-based AI-assisted Draft+check Still fully human
Lead intake Form→booking→CRM; lead alerts; call attribution Booking-attribution report; commercial-lead tracker; alert health check Answering, quoting, closing. The conversion is 100% human
Scheduling Invite-blast mechanism (human-operated) Invite policy review; proven-roster rebuild Coverage confirmation. No AI assigns a cleaner
Inbound messages Routing, labeling, auto-ack, canned suggestions Comms watch (24h no-reply safety net) Every substantive reply
Marketing Drip sends once live; review requests (9–5 PT window) Campaign and win-back copy, staged for send approval Strategy, offers, final send authorization
Hiring Application→sheet→CRM; scheduler redirect; e-sign webhook Sourcing, screening, every decision. Deliberately low-AI
Job problems Cancelled-booking logging only 24h no-reply flags No-shows, complaints, re-cleans, credits. No AI resolves a complaint
Reporting Most of the 23 jobs Weekly comms review Financial reporting — still partial, accounting audit open
Payments Charge at booking via the booking platform Weekly payroll hours pull The pay run, bookkeeping, B2B invoicing. No automated collections

Where the AI layer does essentially nothing: hiring decisions, complaint resolution, cleaner assignment, and supplies/inventory — the last of which is entirely off-system. Nothing tracks or reorders supplies. That's not automation restraint, that's just a gap, and it's the one I'd fix first.

The pattern, if you want it in one line: AI covers observation and analysis. Humans cover judgment, money, and anything a customer will read.


Four times it went wrong

Guardrails only mean something if you say what happened when they didn't hold.

7/20 — Accidental win-back send

Working near a send-hot campaign editor triggered a real win-back send that wasn't meant to go out. Root cause: the email platform treats an in-progress edit as sendable, with no confirmation gate. Caught in the same session. The fix is a standing rule — verify campaign status is 0 before and after any edit, never work near "Send now."

That guardrail is a behavioral rule. The platform still has no technical block. This is the incident that proves the enforcement model: a policy-level stop failed, and the only thing that caught it was a human noticing.

7/21 — Stale-DNS tenant leak

An orphaned proxied subdomain record, left over from a migration, resolved into a different tenant's space. Found during unrelated DNS work. I don't know how long it was exposed. Fix: a DNS-hygiene rule to delete or edge-redirect stale proxied records. Also policy, not an automated check.

Timezone false positive

The ads console renders timestamps in UTC+7. An analysis read those raw and concluded that leads were arriving after hours. They weren't. A related version of the same bug misdated a support thread as new because a stray reply bumped an old one. Retracted on review. Fix: always derive true Pacific time explicitly, and date incidents by the substantive message rather than the thread timestamp.

I include this one because it's the least dramatic and the most representative. An AI ops layer's most common failure isn't a rogue action — it's a confidently wrong conclusion drawn from a correctly-read but misinterpreted field. Most of the real work is defending against that.

7/16 — Portland profile blackout

A mailbox consolidation done before transferring Google Business Profile ownership knocked the Portland listing off Maps. The profile's owner was the mailbox. Detected when the listing dropped. Still under daily recovery watch as of today — this one is not resolved. Fix: transfer profile ownership to the primary account before touching any city mailbox.

All four guardrails are policy, not technical controls. The safety of this system comes from a followed constitution and four hard-won operating rules, not from permission walls. State that plainly or don't state it at all.

Two things I abandoned

Social auto-posting — built it, deleted it. Reddit auto-answering — killed before launch. Both for the same reason: they put a model in direct contact with a public audience with no human in the path, which is precisely the thing the constitution exists to prevent. Building them was a lapse in my own judgment, not a technical failure.


What I don't measure

Published deliberately, because the absence of these numbers is the most common tell that a system like this is being oversold.

If someone shows you an AI operations write-up with confident numbers in all six of those categories, ask how they were instrumented.


What transfers to a multi-site rollup — and what doesn't

This is the question I'd ask if I were on the other side of the table.

Transfers cleanly:

Does not transfer, and I won't pretend otherwise:

What I'd build first if I were doing this across a rollup portfolio: typed approval routing, technical write-blocks replacing the three policy-only stops, scoped service credentials replacing browser sessions, and a pre-deployment baseline capture so the second site can prove what the first one only asserts.


The honest summary

A three-person remote back office runs a $5M, five-city, 100+ cleaner field-service operation. Underneath sits 150-plus deterministic automations. On top sit 23 AI jobs that watch nearly every system in the business and stage decisions in a markdown file.

The AI does not answer customers, assign cleaners, screen applicants, resolve complaints, or set prices. It is stopped from five classes of action by a written constitution, three real technical controls, and three documented standing exceptions I granted on purpose.

Ten weeks in production. Four incidents worth publishing. Six things I can't measure.

That's the whole system. The constraint list is longer than the capability list, and that's not an accident — it's the design.


I'm currently available for operations leadership roles, and I consult with remote-run, multi-location field-service businesses on this kind of build. If you're evaluating whether any of the above would survive contact with your operation, I'm happy to tell you which parts wouldn't.