ops.cartshop.net LIVE

CartWise Ops

The control surface for the agent fleet. Separate repo, separate deploy, no connection to the consumer app. Built Aug 13, 2026.

Beta users
2 Β· 1 active
Onboarding
10–12 next wk
Agents live
0 / 3 planned
Spend
$0 /mo so far

Standing as of tonight

βœ…
Slack app β€” CartWise OpsCreated from manifest, installed. Six bot scopes. Messages tab on. Both credentials in Supabase secrets.
done
βœ…
cartwise-ops repoPrivate. Separate from the app repo β€” a push to one cannot deploy the other.
done
βœ…
ops.cartshop.netCloudflare Pages project + CNAME. This page is the proof.
done
βœ…
Intake β€” 18 questionsVoice, guardrails, escalation, reports, beta scoreboard. See the Spec tab.
done
βœ…
$600/month propagatedbusiness.md Β· brand-guide.md Β· voice-guide.md Β· icp.md. "$100/week" left intact β€” it's proof, not promise.
done
βœ…
Supabase secrets cleanedStray client-ID row deleted. Six clean secrets remain.
done
⬜
CLAUDE_CODE_OAUTH_TOKENNeeds a terminal β€” claude setup-token. Blocks the fixer, nothing else.
tomorrow

Decisions locked today

P0 autonomyAuto-rollback first. Revert to last known-good in ~90s, then a PR for the real fix. Zero unreviewed code ships.
Build orderSpine β†’ console β†’ Slack β†’ one agent. Protected.
PlatformClaude on Max. No Hermes, no second orchestrator.
Grocery numberunder $600/month as the promise Β· under $100/week stays as the proof
Beta termsOne month free, told to their face, then paid. No card on file, no auto-charge.
DashboardOwn repo, own Pages project, own subdomain. Survives the native-mobile migration.

Tomorrow β€” top 3

1
GitHub tokenclaude setup-token β†’ repo secret CLAUDE_CODE_OAUTH_TOKEN β†’ install github.com/apps/claude on Cartwise only.
2 min
2
Error monitoringSentry free tier. Right now nothing anywhere records a break. Your bug SOP needs a log and there are none.
15 min
3
Uptime check60-second check asserting a marker on cartshop.net. Its failure webhook is the P0 trigger β€” without it P0 is undefined. Today proved the gap: the only way we found out was you telling me.
10 min

What I build while you sleep and after

WorkBlocked by
CLAUDE.md in both repos β€” scope + never-touch, so any session knows which world it's innothing
Supabase schema β€” messages / threads / runs / feedback / errors, single-writer lock, RLSnothing
POST /messages β€” one append API, idempotency, transactional outboxnothing
Slack event handler β€” signature verification against the saved secretsnothing
Knowledge base β€” compiled from index.src.html + the five real questionsnothing
triage agent β€” prompt, schema, eval set, escalation rulesnothing
5 smoke tests β€” incl. item-survives-reload, which guards the save path directlynothing
Slack Event Subscriptions URLthe edge function existing
fixer agent β€” GitHub Action, guardrails, severity routingtomorrow's #1

To Tuesday

FriSpine live Β· Slack wired both ways Β· Sentry + uptime Β· CLAUDE.md in both repos
Sat–Suntriage running on real feedback Β· daily brief posting to Slack Β· KB drafted
Monconcierge in staging β€” you review 20 real answers before it touches a user
TueSpine + console + Slack + triage live. fixer opening its first PR.
Not in Tuesday: realtime voice, the fixer deploying on its own, marketing, finance. Weeks 2–4. Tuesday is the foundation with one agent standing on it β€” the only sequence where next week is cheap instead of a rewrite.

Support voice

Every reply: mirror β†’ explain β†’ act β†’ timeline. Warm, informal, short. Three or four sentences. Names Oleg, never "our support team."

How-do-I

Got it β€” you added items at the store and they're not showing up at home.

That's an offline save. The app kept them on your phone and hasn't pushed them up yet β€” nothing's lost.

Open CartWise on wifi and they'll sync in about 5 seconds. Still missing after that? Tell me and I'll get you on a call with Oleg.

Bug β€” carries a commitment

Got it β€” scanner opens but won't read anything on your iPhone.

That's a real bug, not you. I've logged it with your app version and sent it to Oleg.

He's on it, and I'll message you right here when it's fixed. Meanwhile you can add items by name from the search box.

Feature request β€” receipt, never a promise

Got it β€” you want the list split by store so you're not backtracking.

That's a good one and it's on the list now. I can't tell you if or when it'll get built β€” Oleg decides that off what everyone's asking for.

If it's blocking you, tell me how and I'll flag it higher.

Never a date. "I'll message you when it's fixed" is a promise the system can keep. "By Friday" is one it will eventually break β€” and with families who know you personally, a broken promise costs more than a vague one.

Guardrails β€” never, no exceptions

πŸ”΄
Never disclose the size of the businessRevenue, user counts, team size. "You're one of our first families" is warm, true, and hands over your entire scale.
πŸ”΄
Never guarantee a feature will be builtFeatures get a receipt. Bugs get a commitment. Different contracts.
πŸ”΄
Never promise a dateFor anything.
πŸ”΄
Never invent an answerIf the KB doesn't cover it, say so and offer the call.
πŸ”΄
Never discuss competitorsNot by name, not by comparison.
πŸ”΄
Never touch the save-path guardsblobHasContent / hadDataRef. Never edit index.html directly. Never merge its own PR.

Escalation β€” never a bot reply

Lost data Β· wrong prices Β· any mention of a charge Β· severity=blocker Β· three turns without resolution Β· a clearly angry user Β· anything the KB doesn't cover Β· any request for a human. Scheduling is its own branch β€” the concierge hands off to Cal.com, it doesn't negotiate times in prose.

Slack routing

πŸ”΄ Red flags β€” any hourSite down Β· data loss Β· auth broken Β· a user reporting a charge Β· error spike Β· security
🟑 Everything elseHeld for the 7am brief. Bugs, requests, questions, PRs waiting, cost changes
Six red-flag triggers, no more. If that list grows, the channel gets muted β€” and then the real emergency gets missed too. Anything ambiguous is amber.

Beta scoreboard

SignalPass
⭐ Week-3 plan built unpromptedThe headline. Everything else is a floor.
Zero data-loss eventsGuard never trips; no household loses items unexplained
Sync integrityNo silent offline-save orphans
Zero P0sSite never down, auth never broken
Full weekly cycleplan β†’ list β†’ shop β†’ pantry update, at least once
What this beta does not prove: willingness to pay. Twelve people who know Oleg saying they'd pay is politeness, not evidence. The paywall launch is the real experiment.

Two repos, two worlds

RepoHoldsDeploys to
CartwiseThe consumer app. index.src.html β†’ build.mjs β†’ index.html + sw.jscartshop.net
cartwise-ops privateThis console, agent prompts, SOPs, edge functionsops.cartshop.net
Why not one repo with an ops/ folder: the app's Pages project builds from the repo root, so cartshop.net/ops/ would have been a live public URL. Separate repos make that impossible rather than something a redirect rule has to remember to prevent. It also means the fixer working on app code can never touch ops, and the native-mobile migration doesn't drag the console along with it.
A different domain adds nothing. The isolation you want lives at the repo layer and it's already there. Keep .info/.net for if the console ever becomes its own product.

Session hygiene β€” the real answer

Each repo gets a CLAUDE.md stating its scope and its never-touch list. Any session that opens either repo reads it first and knows which world it's in. That's the "logic to make sure we're working in the right place" β€” it's a file, not a domain.

The spine β€” one log, three windows

1
Single append APISlack and this console both call one POST /messages. Neither writes to the database directly, neither keeps its own history.
2
Idempotency from upstream keysTelegram/Slack retry on any non-2xx. Without this you get duplicate agent runs.
3
Single writer per threadStops a voice turn at the desk and a phone message from spawning two concurrent runs. The loser queues.
4
Transactional outboxAgent output and run state commit together; a relay fans out afterward. Prevents "sent to Slack but never saved."
Vendor memory β€” a voice session's context, Slack-side state, any conversation ID a provider hands you β€” is never the source of truth. It dies with the socket and is invisible to the other client.

Departments

NowGatedOpens at
πŸ— Product & EngineeringπŸ“£ Growth & Contentβ‰₯300 WAU or first ad dollar
πŸ’¬ CustomerπŸ’° Financefirst revenue or $100 ad spend
πŸ“Š Ops & IntelligenceπŸ”’ Trust & Compliancepayments live, >5k users, or PII past email
🀝 Partnerships & DataWalmart approval or 2nd retailer
πŸ‘₯ People & Delegationfirst hire

Parked, not dropped

ItemComes back
πŸ”– Paywall & monetization
Trial mechanics, auto-renew compliance, price, payment method. Research done and saved.
Before the beta ends
Onboarding tutorial
First week with the assistant β†’ one week manual β†’ import a recipe. Highest-leverage thing for the week-3 metric.
Before the families land
Google Calendar connector β†’ events land in iOS Calendar10 min, anytime
Business social accounts (IG Β· TikTok Β· YT Β· FB)Next week β€” Oleg
2–3 weeks of content generated, ready to pasteNext week β€” Oleg
Partner email β€” Resend on a subdomainBefore launch
Realtime voice β€” OpenAI Platform, separate billing from ChatGPT BusinessPhase 3

Waiting on Oleg

✏️
Correct the "what CartWise does" paragraphDraft is in the agent spec. Edit it, don't rewrite it β€” it's the first thing every family reads.
✏️
Approve answer #5 β€” "how does this actually save me money"Claude drafts, Oleg approves before it ships. The sales answer. An agent must never improvise it.
✏️
Veto the "never change" listClaude proposes from index.src.html, Oleg strikes what's wrong.
One thing worth putting on next week's list while it's fresh: the tutorial is the highest-leverage thing between now and week 3. The concierge answers families who get stuck; the tutorial stops them getting stuck. Same knowledge, and it's the one that actually moves the scoreboard.