created_date: 2026-07-04 last_modified_date: 2026-07-08 last_modified_summary: Added public /pricing page (Stripe-aware CTAs, gated until keys land); registered in smoke.sh.
SSOT for every user-facing flow implied by the UI, with a working-status grade per flow. Use this for QA planning, onboarding honesty, and prioritising fixes.
Related docs
- Cloud vs local workflows — builder vs browser; local CLI tools (
runTool) - Responsive design — mobile shell constraints
scripts/smoke.sh— automated route health (not flow completeness)src/config/navigation.ts— sidebar route SSOT
| Name | What it is today | User-facing? |
|---|---|---|
| Loki | In-app assistant on /loki — OpenClaw main agent via openclaw-gateway.ts (loki-core.ts). Same brain as Telegram when gateway is up. |
Yes — product name in nav, composer, Settings → Voice |
| Ivy | Legacy persona name for the OpenClaw assistant (pre–FleetCrown rebrand). Still appears in old docs, content/thoughts author lines, DB channel key ivy (UI label → "Loki" in project-detail-types.ts), and ops runbooks (migrate-openclaw.sh). |
No in current UI — do not use in new copy |
| OpenClaw gateway | Infrastructure Loki talks to (WebSocket). Was sometimes called "Ivy gateway" in ops docs. | Internal |
runTool / local CLIs |
Shell-out layer (lib/tools.ts) for gog calendar, weather.sh, git scripts on a machine with tools installed — not Loki. Calendar on hosted prod returns runtimeOnly: true (no Google CLI on box). |
N/A |
Rule: User-facing assistant = Loki. Ivy is historical; migrate docs/comments when touched. Calendar/weather depend on local CLI tools or cloud fallbacks (open-meteo for weather), not on Loki.
| # | Initiative | Status |
|---|---|---|
| 1 | Flow-status matrix in this doc | [x] Done 2026-07-04 |
| 2 | Authenticated smoke + PIN on prod (npm run test:authenticated-smoke) |
[x] 115/115 2026-07-04 |
| 3 | UI honesty labels on Control/Loki/Terminal (queued / needs builder / needs GitHub) | [x] executor-copy.ts + ExecutorHonestyChip on Control intents, Loki composer, Terminal toggle |
| 4 | Fix top “feels broken” gaps (setup→sign-in, verify-email enforcement, /control/workspace) |
[x] Setup auto sign-in; verify-email optional banner + email copy; workspace gated on hosted |
| Mark | Meaning |
|---|---|
[x] |
Smoke-verified on prod 2026-07-04 — page loads or API GET returns 2xx (no error boundary) |
[~] |
Partial — grade B/C/D, queues, needs runtime, or smoke-only (not full user outcome) |
[ ] |
Not verified — no automated or manual E2E proof yet |
| Grade | Meaning | “Works 100%” for the user? |
|---|---|---|
| A | UI + API + persistence complete in production with DB + auth only | Yes |
| B | Wired correctly; needs an external runtime (builder, OpenClaw/Loki gateway, Groq, local CLIs, Stripe, GitHub OAuth, OrangeCat OIDC, etc.) | No — queues, degrades, or blocks until dep is up |
| C | Partial — known gap, misleading surface, or graceful degradation | No |
| D | Stub, redirect-only, or explicit roadmap — UI oversells capability | No |
“Full implied outcome” = the user gets what the button/copy suggests without extra setup. On hosted prod (fleetcrown.orangecat.ch), ~37% of mapped flows meet that bar (~75 of ~203). ~63% need a builder, integration, or have a known gap.
| Method | Scope | Result |
|---|---|---|
Production scripts/smoke.sh (unauthenticated) |
44 routes | 44/44 OK |
npm run test:authenticated-smoke (prod) |
115 probes session + PIN + CRUD + RAG + billing SSOT | 115/115 OK (2026-07-04) |
npm run dogfood:loki:ci (prod, builder online) |
Loki dispatch → Terminal Cloud UI | ok 2026-07-04 |
npm run dogfood:ui-flows:ci (prod, PIN) |
PE11/H05/G07/M04/ST02/PR04/X07 UI flows | ok 2026-07-04 |
npm run dogfood:machine:ci (prod) |
X05 full path when local Fleet Runner online | skips when desktop offline |
SMOKE_PRIVATE_PIN + git push |
Pre-push test:pre-push-prod-dogfood |
reads .env.local; smoke + ui-flows + machine; loki when builder online (ok 2026-07-04) |
| Unit/inline tests | auth, onboarding, execution-access, workspace-access, dispatch-gates, fleet-kick, loop-ssot, executor | all passed |
| Codebase mapping | Every page.tsx, shell component, api/*/route.ts |
complete |
Script: scripts/test/authenticated-smoke.ts. Resolves a session via (in order):
FLEETCROWN_SESSION_TOKEN(COCKPIT_SESSION_TOKENlegacy)SMOKE_EMAIL+SMOKE_PASSWORD(credentials sign-in)- JWT mint with
AUTH_SECRET+ prod user row (works because Auth.js uses JWT strategy — thesessionstable is empty) - Brave browser profile copy (
AUTH_MODE=browser)
Optional: SMOKE_PRIVATE_PIN unlocks private-zone API probes (fleetcrown-pz cookie; reads legacy cockpit-pz).
Report written to .tmp/authenticated-smoke-report.json.
Prod run (2026-07-04, jwt-mint, PIN unlocked via SMOKE_PRIVATE_PIN):
| Area | Result | Implication for grades |
|---|---|---|
| All 20 authenticated pages | HTTP 200, no error boundary | Page shells A |
| Control/Loki/Terminal/Projects APIs | 200 | Read paths A |
Private-zone APIs (/api/goals, people, habits, events) |
200 with PIN | CRUD flows A when unlocked |
| Private-zone APIs without PIN | 403 | Expected gate — not broken |
/api/workspaces |
403 (hosted gate) | Workspace flow stays C |
/api/stripe/portal |
503 (Stripe not configured) | Billing stays B |
/api/calendar, /api/weather, /api/github |
200 on prod | Today tool cards A for read |
Dynamic /api/projects/<id>, /api/people/<id>, OC publish GET |
200 | Drawer/dossier load A |
115/115 probes passed with session + PIN unlock on production.
Dogfood: SMOKE_PRIVATE_PIN=… BASE=https://fleetcrown.orangecat.ch npm run dogfood:loki:ci — UI round-trip Loki → dispatch bubble → Terminal Cloud (requires builder online for ok: true).
UI flows: SMOKE_PRIVATE_PIN=… npm run dogfood:ui-flows:ci — Ask Loki from People card, habits heatmap, goal → Control prefill + harmless full dispatch when builder is online, prompt fork, Run with Loki modal.
Re-run:
# Full authenticated probe suite
BASE=https://fleetcrown.orangecat.ch npm run test:authenticated-smoke
# With private-zone unlock (operator PIN — never commit)
SMOKE_PRIVATE_PIN=… BASE=https://fleetcrown.orangecat.ch npm run test:authenticated-smoke
# Legacy route smoke with a minted token
FLEETCROWN_SESSION_TOKEN=… BASE=https://fleetcrown.orangecat.ch npm run smoke- S01 Sidebar navigation — A
- S02 Mobile bottom tabs (Today · Control · Loki · More) — A
- S03 Mobile More sheet → nav + Settings + Unlock — A
- S04 Cmd/Ctrl+K palette — search nav — A
- S05 Palette — jump to project on Control (
?focus=) — A nav - [~] S06 Palette — run NL command → inject — B
- [~] S07 Palette — voice dictation — B
- [~] S08 Palette — agent prompt shortcuts → inject — B
- [~] S09 Palette — switch agent — B
- S10 Ask Loki button →
/loki?q=— A - S11 Sessions drawer — fleet snapshot GET — A read
- S12 Sessions drawer → focus on Control — A
- [~] S13 Push notifications bell — C (VAPID / browser support)
- S14 Theme toggle — A
- S15 Brand version → Releases — A
- S16 Footer → System — A
- S17 Lock private zone — A
- S18 Sign out — A
- S19 Pull-to-refresh — A
- S20 Auto-refresh cadence — A
- S21 SSE bridge DB refresh — A
- S22 Escape closes modal/drawer — A
- A01 Landing
/— A - A02 Sign up (email/password) — A
- [~] A03 Sign in — GitHub OAuth — B
- [~] A04 Sign in — Google OAuth — B
- [~] A05 Sign in — OrangeCat OIDC — B
- [~] A06 Sign in — X OAuth 1.0a — B
- A07 Sign in — email/password — A
- [~] A08 Sign in — owner key tab — C
- A09 OAuthAccountNotLinked error — A
- [~] A10 Forgot password — A UI; B email delivery
- A11 Reset password (token) — A
- [~] A12 Verify email — A link works; C not enforced at login
- A13 Resend verification — A
- A14 Accept invite
/invite/[token]— A - [~] A15 First-time setup
/setup— C (no email on user) - [~] A16
/→/setupwhen 0 users — C - A17 Public marketing pages — A
- A17b Pricing
/pricing— A public page; CTAs start free (Stripe checkout whenisStripeReady()) - A18 Download Fleet Runner — A
- A19 Legal / docs / releases — A
- A20 Frontier public digest — A read
- A21 Thoughts list + essay — A read; D no in-app author UI
- [~] A22 Public profile
/u/[username]— C - [~] A23 X-login complete — B
- A24 Onboarding redirect when incomplete — A
- A25 Onboarding — set username — A
- A26 Onboarding — create / skip project — A
- [~] A27 Onboarding — connect Fleet Runner — C
- A28 Team invitee skips project step — A
- A29 Returning user onboarding heal — A
- A30 Private zone PIN unlock
/unlock— A - A31 Private zone inline gate
(private)/*— A - A32 Today hides private data when locked — A
- A33 Private API 403 when locked — A
- T01 Page load + summary — A / C when PIN locked
- T02 First-run banner → Control — A
- [~] T03 Plan my day / Wrap up day → Loki — A opens; B AI reply
- [~] T04 Log a conversation (modal) — B + PIN
- T05 Capture thought CRUD — A
- T06 SummaryBar deep links — A
- [~] T07 TodayWatch + LokiNudge (Groq compose) — B
- T08 FleetBriefCard — A
- [~] T09 RecentRuns + dispatch — B
- [~] T10 Action queue approve/reject/all — B + PIN
- [~] T11 Dismiss alert — B + PIN
- [~] T12 Goals/events due + Loki — B + PIN
- [~] T13 Abandon stuck goal — B + PIN
- [~] T14 Calendar card — C on hosted (
runtimeOnly); B needsgoglocally - T15 Weather card — A on prod (open-meteo fallback); B if all sources down
- [~] T16 Habits inline check-off — A with PIN; C locked
- [~] T17 Commitments CRUD + fulfill — B + PIN
- [~] T18 Subscriptions upcoming (read) — B + PIN
- T19 LockedZoneBanner → unlock — A
- L01 SSR prefetch — A
- L02 Load projects + conversations — A
- L03 Filter by project — A
- L04 Deep link
?project=/?q=— A - L05
loki:prefillevent — A - L06 New / select / delete conversation — A
- [~] L07 Send chat message (OpenClaw / Groq fallback) — B
- [~] L08 Send dispatch to project — B builder
- L09 Command without project → picker — A
- L10 Agent/model picker — A
- [~] L11 Voice input — B
- [~] L12 Attach files / paste image — A upload; B vision
- L13 Suggested action chips — A
- [~] L14 Fleet commands (kick, business plan, create project, …) — B
- [~] L15 Multi-project dispatch — B
- [~] L16 Screenshot dispatch — B
- [~] L17 Footer → Control / terminals — A nav; B streams
- L18 Mobile drawers — A
- [~] L19 Prompts “Run” via
/api/loki— B
- C01 Load fleet + SSE patches — A
- C02 Refresh / pull-to-refresh / deep link focus — A select; B tab focus
- C03 Runner offline banner — A
- [~] C04 Pair Fleet Runner (in-app) — B Electron
- [~] C05 Install agent CLIs — B
- [~] C06 Empty: GitHub bulk import — B
- [~] C07 Empty: ~/dev bulk import — B Fleet Runner
- [~] C08 Empty: Bootstrap modal — B
- C09 Empty: manual add project — A
- [~] C10 Fleet autopilot + fleet-kick — A PATCH; B kick
- [~] C11 Bulk build / pause — B / A
- C12 Search / sort rail — A
- C13 Open dossier / URL / profile drawer — A
- [~] C14 Switch agent — B
- [~] C15 Focus terminal — B
- [~] C16 Git sync / commit & push — B local
- [~] C17 Capacity auto-reroute — B
- [~] C18 Ready banner + slots 1–9 — B
- C19 Auto-continue pause/play — A
- [~] C20 Send prompt (Enter) — B inject
- C21 Queue prompt (Alt+Enter) — A queue CRUD
- [~] C22 Voice in composer — B
- [~] C23 Orchestration intents (next best, test&fix, …) — B
- [~] C24 Clear context — B local only
- C25 Prompt library fill — A
- [~] C26 Launch agent — B
- [~] C27 Queue AI merge — B LLM
- [~] C28 Workspaces: focus/close/inject/peek — B
- [~] C29 Retry failed command — B
- [~] C30 Agent defaults save / apply tabs — A save; B apply
- [~] C31 Modals: NewProject / Launch / Bootstrap — A–B
- C32
/control/importpage — A load; B import action - C33
/control/import-localcopy script — A copy; B terminal exec - C34
/control/new-from-scratch— A load; B GitHub create - [~] C35
/control/workspaceserver PTY — C gated on prod
- TR01 Cloud / This computer toggle — A
- TR02 Deep link
?source=&tab=— A - [~] TR03 Cloud tab xterm stream — B box-runner
- [~] TR04 This computer tab stream — B Fleet Runner
- [~] TR05 Local dev tabs/splits — C dev only
- TR06 Mobile immersive expand — A
- P01 List / search / filter chips — A
- P02 Open dossier vs quick-edit drawer — A
- P03
?new=1&name=OrangeCat deep link — A - P04 NewProjectButton entity create — A
- P05 GitHub CI panel — A API smoke; B if github tool down
- P06 Dossier read (Now / Next / Done) — A
- P07 Quick-edit: name/desc/status/maturity/delete — A
- [~] P08 OrangeCat publish — B OC OIDC
- [~] P09 Brief fill / enrich from repo — A CRUD; B AI
- [~] P10 Business plan generate + queue — B
- P11 Log activity interaction — A
- P12 Prompts tab cron jobs — A
- [~] P13 Goals tab link/create/unlink — A + PIN
- P14 Org/team readonly enforcement — A
- P15 Settings → Projects registry CRUD — A
- PE01 Page load — A + PIN
- PE02 GET
/api/peoplelist — A smoke - PE03 GET
/api/people/<id>— A smoke - PE04 Search / sort / health filter — A smoke GET
- PE05 Load more pagination — A smoke GET offset
- PE06 Create person (modal) — A smoke POST
- PE07 Person drawer — name/desc edit — A smoke PATCH
- PE08 Delete person — A smoke DELETE
- PE09 Attributes / channels CRUD — A smoke POST/DELETE attrs
- PE10 Log interaction — A smoke POST
- PE11 Ask Loki from card — E2E UI (
dogfood:ui-flows:ci) - [~] PE12 All above when PIN locked — C (403)
- G01 Page load — A + PIN
- G02 GET
/api/goals— A smoke - G03 Create goal / sub-goal — A smoke POST
- G04 Inline edit title/desc/progress/date — A smoke PATCH
- G05 Milestones add/toggle/remove — A smoke PATCH milestones
- G06 Complete / abandon / delete — A smoke DELETE
- [~] G07 Control dispatch from card — B UI prefill →
/control+ harmless full-dispatch smoke when builder online (dogfood:ui-flows:ciok 2026-07-04) - [~] G08 When PIN locked — C
- H01 Page load — A + PIN
- H02 GET
/api/habits— A smoke - H03 Create habit — A smoke POST
- H04 Inline edit / toggle active / today done — A smoke PATCH
- H05 Heatmap display — E2E UI (
dogfood:ui-flows:ci, 60 cells) - H06 Link/unlink goals — A smoke POST/DELETE goals
- H07 Delete habit — A smoke DELETE
- E01 Page load — A + PIN
- E02 GET
/api/events— A smoke - E03 Create event — A smoke POST
- E04 Inline edit — A smoke PATCH
- E05 Archive / delete — A smoke PATCH archive + DELETE
- M01 Page load — A + PIN
- M02 Create subscription — A smoke POST
- M03 Mark paid / inline edit / cancel / reactivate / delete — A smoke PATCH/POST/DELETE
- [~] M04 External verify/cancel URLs — B SSOT smoke + UI links on
/money(dogfood:ui-flows:ci)
- ME01 Page load + stats — A + PIN
- ME02 RAG index stats (embeddings server) — A smoke GET
/api/memory/rag-stats(chunks=23on prod 2026-07-04)
- PR01 Browse defaults + user prompts — A
- PR02 Create / edit / delete user prompt — A smoke POST/PATCH/DELETE
- PR03 Search / scope / category filters — A
- PR04 Fork template — E2E (
dogfood:ui-flows:ci) - [~] PR05 Run now — B Loki (
dogfood:ui-flows:cimodal →/api/lokiresult) - PR06 Schedule cron — A smoke POST/PATCH (disabled after create)
- AC01 Timeline filters — A
- [~] AC02 Generate LLM digest — B
- AC03 Legacy redirects →
/activity— A - [~] AC04
GET /api/decisions/feed— D no UI
- SY01 System stats poll — A
- SY02 Fleet doctor — A smoke GET
- [~] SY03 Frontier proposals accept/dismiss — B smoke GET + 404 validation (no prod mutation)
- [~] SY04 Global auto-continue all — B
- SY05 Cron jobs list — A
- SY06 Cron run-now / edit — A smoke POST/PATCH; run-now 503 on hosted (needs openclaw)
- SY07 Memory / failures / audit cards read — A
- ST01 Profile — name, username — A smoke PATCH
- [~] ST02 Account — OAuth connect/disconnect — B smoke lists accounts + settings Connect shell (
dogfood:ui-flows:ci); full OAuth needs browser - [~] ST03 Account — set/change password — B smoke rejects wrong password; change needs real credential
- ST04 Notifications prefs — A smoke PATCH
- ST05 Appearance — A
- ST06 Voice (Loki writing voice) — A smoke PATCH
- ST07 Privacy — PIN set/change/remove — A
- [~] ST08 Privacy — export/delete — D roadmap
- ST09 Location — A page
- ST10 Agent tokens list — A smoke
- ST11 Agent token mint/revoke — A smoke POST/DELETE
- ST12 Fleet lifecycle / beacon — A smoke PUT/PATCH
- ST13 Projects registry — A
- ST14 Team invite create — A page
- [~] ST15 Billing / Stripe — B (503 portal on prod)
- [~] CH01
GET /api/checkout/:plan— B - [~] CH02
POST /api/stripe/checkout— B - [~] CH03 Billing portal — B smoke 503
- [~] CH04 Webhook subscription sync — B smoke rejects invalid webhook signature (503 when Stripe off on prod)
- CH05 Plan limits on project count — A enforcement
- [~] OC01 Connect OrangeCat OIDC — B
- OC02 Publish GET state — A smoke
- [~] OC03 Publish POST — B smoke 409 when OC not linked
- [~] OC04 Auto-promote dev-log — B cron
- OC05 OC → FC
?new=1&name=— A
- [~] D01
fleetcrown://auth?token=— B - [~] D02 Auto-pair agent token IPC — B
- [~] D03 Scan ~/dev for import — B
- [~] D04 Local peek IPC — B
- [~] D05
import-from-local.shcurl pipe — B
- [~] X01 Loki chat → OpenClaw reply — B API 200; dogfood UI dispatch ok 2026-07-04
- [~] X02 Loki dispatch → Control — B dogfood links + dispatch API 200
- [~] X03 Control inject — B API queues (
mode: queued|direct); agent run needs builder - [~] X04 Terminal Cloud peek-stream — B API 200; dogfood loads
/terminal?source=server - [~] X05 Terminal This computer via Fleet Runner — B loki dogfood shell always;
dogfood:machine:ci+ open-tabs/peek whenbuilderPresence.local - [~] X06 Orchestration “Next best” / continue — B API 503 on cloud for some adapters; box-runner when online
- [~] X07 Prompt Run now → Loki — B
dogfood:ui-flows:cimodal result 2026-07-04 - [~] X08 GitHub create-with-github — B validation probe; full flow needs GitHub OAuth
- [~] X09 OrangeCat publish POST — B 409 when OC not linked (expected on prod)
These are deliberately not automated in CI because they require a third-party
account UI, signed webhook secret, or live billing destination. Keep screenshots
or report notes in .tmp/ only.
- Open
/settingson prod as the operator. - In Account, click the GitHub connect action and complete GitHub OAuth.
- Confirm
/api/sessionsstill returns 200 and the account appears in the settings account list. - Disconnect only a non-primary OAuth account; do not remove the last sign-in method.
- Reconnect and confirm sign-in still works in a clean browser profile.
- In Stripe test mode, send a signed
checkout.session.completedor subscription lifecycle event to the prod webhook endpoint. - Confirm the webhook returns 2xx and the subscription state changes in
/moneyor the relevant account billing view. - Replay the same event and confirm idempotency: no duplicate subscription row or duplicated activity.
- Send one event with an invalid signature and confirm it is rejected.
- Open
/moneywith the private zone unlocked. - For a subscription that has
verifyUrl, click the source/verify action and confirm it opens the expected provider URL in a new tab. - For a subscription that has
cancelUrl, click cancel/manage and confirm it opens the expected provider cancellation or account-management URL. - Do not complete a real cancellation unless intentionally testing a disposable subscription.
| Bucket | Count | Notes |
|---|---|---|
[x] Smoke-verified |
~151 | + ME02 RAG chunks on prod |
[~] Partial / needs runtime |
~95 | M04/ST02/CH04 partial; X05/X07 when builder |
[ ] Not E2E verified |
~0 | Manual runbooks remain for full OAuth / Stripe live / external click-through |
| Total checklist items | ~250 | Sections 0–15 |
Full implied outcome on hosted prod (grade A end-to-end): still ~40% — smoke proves shells and read APIs; execution and many mutations are unchecked.
- Control + Loki dispatch — queues until box-runner or Fleet Runner executes (
executor-copy.tshas copy; not on every control). - Orchestration intents — non-claude adapters 503 on cloud; some openclaw paths 501.
- Terminal — Cloud needs box-runner; This computer needs desktop app.
- Loki chat — OpenClaw gateway required for “real” Loki; else Groq fallback or 503. (Not the old “Ivy” name.)
- Today calendar — hosted shows
runtimeOnlyempty state; needsgogon a machine with Google CLI. - Thoughts — no compose/publish in app (markdown files only).
- Email verification — sent but never blocks access.
- Setup
/setup— can dead-end without OAuth or owner key. - Privacy export/delete — roadmap copy in Settings.
/control/workspace— exists but prod steers users to Terminal/Runner.
When adding a UI action:
- Add a row here with ID, API route, and honest grade.
- If the flow is cloud vs local, also update cloud-local-workflows.md.
- Add the page route to
scripts/smoke.shif it is a new top-levelpage.tsx. - Add authenticated GET probes to
scripts/test/authenticated-smoke.tswhen the route is session-gated. - Execution API probes +
npm run dogfood:loki:cifor Loki → Terminal UI;npm run dogfood:ui-flows:cifor card/modal flows (see §15). - Bump
last_modified_dateandlast_modified_summaryon this file.
When fixing a gap, upgrade the grade and note the change in last_modified_summary.