The complete picture: what a client experiences, the full architecture behind it, where every external call is made and what it costs — and where we can make it cheaper. Written for a non-technical reader, with the technical depth folded in along the way (look for the ⚙ boxes).
01 · The idea in one picture
A Marcus Instance is a hosted AI developer dedicated to one client. Their team writes what they want as user stories. Marcus plans it, builds it, runs the app, tests every user journey, documents everything — then publishes the evidence and waits. Nothing ships until a human on the client's side clicks Approve.
approvals), raised automatically by the build flows (ready, design-lab) and gated on by scripts via an exit-code contract: approval wait --id … exits 0 approved / 3 pending / 4 changes-requested — so a pipeline literally cannot proceed past a pending decision. The client decides through a tokened link (#approval=<uuid>&t=<token>); the token is the only credential that can write, it's checked inside a security definer RPC, and it's stored in a table with zero anonymous read policies. Duplicate raises are deduped — a re-run reuses the open decision and reproduces the same link.
02 · A milestone, day by day
Client time per milestone: a few hours of decisions, not days of supervision. The blue cards are the only ones that need them.
03 · The full architecture
Three zones: the client's world (their people, board, repository — everything they already own), the per-client instance Kinetech operates (one isolated machine per client), and shared Kinetech services (the evidence store and dashboard). External paid services sit outside all three, reached only through metered, controlled paths.
marcus toolchain under repo-law process gates (plan gate, verification ladder, fail-closed READY). Toolchain: mxcli MDL as primary model writer, Mendix Platform SDK for Team Server working copies, mx.exe for consistency checks, BSON-level surgery where grammars fall short — 82 pillars, ~4,500 test assertions. App under test: mxcli docker run stack (runtime + Postgres) driven by puppeteer; a11y via axe-core; load via k6. Local AI: src/llm/provider.ts routes local-first to Ollama, paid fallback only when local can't do the capability. Meter: src/ledger/inference-usage.ts parses agent transcripts + the router log into a costed per-build gate row. Evidence store schema: builds, gate_results (append-only sink incl. scorecard + usage rows), approvals/approval_tokens, audit_events (per-app hash chain: hash = H(body + prev_hash)). Console: static web app on Netlify; anonymous key is read-only by RLS; the only anonymous write path is the token-checked decide_approval RPC. Comms policy: data/comms-policy.json + pure evaluator — outward writes (Slack/Jira) check per-client channel rules; unknown clients fail closed.
04 · Where every call is made
Everything a Marcus Instance does either stays on its own machine (free) or crosses the network to a named service. This is the complete list of those crossings. Amber = costs money per use. Green = free. Blue = infrastructure with a flat monthly fee. Only the amber rows cost per-use money, and every amber row is metered per build.
| # | Call site (who makes the call) | Destination | Purpose | Cost | Metered? |
|---|---|---|---|---|---|
| 1 | Agent loop — the AI developer thinking and working Claude Code harness, every reasoning/tool step | Anthropic API | Planning, writing model & code, reading test output, deciding next steps | PAID — ~85–95% of all spend | ✔ per build, from session transcripts |
| 2 | LLM router — pillar features (UI critique, doc-fill, translation, role narratives, feedback enrichment) src/llm/provider.ts · llmComplete() | Local Ollama first; Anthropic only as fallback | Mechanical AI passes | $0 local paid fallback | ✔ every call, both providers |
| 3 | Legacy direct callers — a handful of older features not yet moved onto the router agent, ai-doc-seed, review-narrative, translation-*, image-to-mockup | Anthropic API | Same class of work as #2 | PAID — migration debt | ✔ via transcripts; router migration closes the gap |
| 4 | In-app feedback widget (in delivered client apps) JA_SubmitFeedback Java action | Anthropic (optional) + Jira | Turn user feedback into tickets | $0-stub is the default | enrichment runs local-first offline |
| 5 | Evidence & approvals — every verify/ready run ledger, approval CLI, flow hooks | Supabase (Kinetech) | Store builds, gates, approvals, audit chain | ~$25/mo flat, all clients | n/a |
| 6 | Team Server pushes git + Platform SDK, with SP commit metadata | Client's Mendix Team Server | Deliver the work | free | n/a |
| 7 | Board reads/writes stories-push, feedback router — comms-policy gated | Client's Jira / Epics | Stories in, tickets out | free | policy-gated per client |
| 8 | Module installs marketplace-install via Content API | Mendix Marketplace | Headless module installs | free | n/a |
| 9 | Everything else — compiles, app runtime, browser drives, screenshots, voice transcription (whisper), accessibility scans, load tests | stays on the instance VM | The actual engineering | $0 — local compute | n/a |
The one-sentence takeaway: the only meaningful per-use cost in the whole system is the AI reasoning itself (rows 1–3), it all goes to one vendor, and we already meter it per build — a real 2-hour reading on our own machine came to 99 calls / 35.4M tokens / ≈ $36.50.
05 · What an instance costs to run
Monthly cost per active instance (straw-man ranges; the meter replaces these with real numbers per client). Inference scales with build cadence — a quiet month costs almost nothing.
inference-usage gate row on every build: (1) the agent loop's own per-message usage records parsed from Claude Code session transcripts (deduped by message id, cache-write 5m/1h split priced 1.25×/2.0×), and (2) an append-only router log written by every llmComplete() call — including $0 local calls, so paid-calls-avoided is itself visible evidence. Unknown models are flagged unpriced, never silently guessed. Pricing basis: public per-MTok rates, cache reads at 0.1× input.
06 · Where we can save
Since inference is ~85–95% of per-use cost, that's where the levers are. Honest split: some savings are already built in, some are one engineering pass away, and one — running our own AI models — is worth doing for part of the workload but cannot replace the core.
| Lever | What it does | Est. saving / instance-mo | Status |
|---|---|---|---|
| Local-first AI routing | Mechanical AI passes (critique, docs, translation, enrichment) run on our own machine at $0; the paid API is only a fallback | $100–300 vs naïve all-API | BANKED — enforced in code |
| Prompt caching | Repeated context (rules, docs, history) billed at ~10% of full price | ~50–70% of what input would cost | BANKED — measured in the meter |
| $0-stub feedback default | Client-app feedback files raw tickets free; enrichment runs local-first offline | small but structural | BANKED |
| Batch API for verification passes | Gate re-runs, critiques, and doc passes aren't latency-sensitive — the batch endpoint is 50% off | $150–400 | READY — one engineering pass |
| Effort tiering | Run mechanical steps at low reasoning effort, save the deep thinking for design/debugging | $100–300 | READY — tune with meter data |
| Router migration (call map #3) | Move the legacy direct-API callers onto the local-first router | $50–150 | READY — known list |
| Self-hosted LLM (GPU box) | See the analysis below — real, but bounded | $100–400 at maturity | EXPLORE — staged |
| BYO API key (client's own) | The client's Anthropic key in their instance vault — inference bills to them directly, at roughly 15–25% off their monthly. Removes our most volatile cost line entirely and dissolves any reseller question; the meter becomes their cost-transparency view | eliminates the amber rows from OUR ledger per BYO client | BANKED — zero engineering, offered as a plan modifier |
| Subscription seats vs metered API | For BUNDLED clients only: if hosted instances may run on subscription seats, inference becomes a flat ~$100–200/mo | $500–2,000 on bundled plans | EXPLORE — a licensing question for Anthropic; moot for BYO-key clients |
Can we stand up our own model and stop paying per token? Partially — and the split matters:
Recommendation: bank the two READY levers first (batch + effort tiering: ~$250–700/instance-mo for a few days' work), buy one GPU box for the fleet when we pass ~3 instances, and pursue the subscription-seat question in parallel — it's the only lever bigger than all the others combined.
07 · Trust & control
| Boundary | Plain language | Mechanism |
|---|---|---|
| Client credentials | Tokens the client issues, scoped to the minimum, revocable by them any time — and they never leave the instance | per-client vault on the isolated VM; never in code, models, or the evidence store |
| Nothing ships unapproved | Work waits on a human click | approval gates with exit-code enforcement; branch isolation until accepted |
| Decisions are signatures | Only the person holding the decision link can decide, and it's on the record | per-approval secret token, checked server-side; decider + note + timestamp stored |
| Everything is on the record | Who did what, when, and why — provable later | append-only evidence + hash-chained audit ledger (tampering breaks the chain) |
| Outward messages are policied | Marcus can't ping the wrong channel or clutter a client board | per-client comms policy config; unknown clients fail closed |
| Kill switch | Any instance can be stopped instantly | per-instance stop; one client, one blast radius |
08 · Operations — escalations, responses, and the question budget
Clients pay to not go back and forth. So the human interface is designed as a strict budget: the client is asked exactly four kinds of question, ever — and everything else either gets done, or climbs an escalation ladder that exhausts the machine's options before any person is interrupted.
| The client hears from Marcus when… | Form | Never |
|---|---|---|
| A decision gate is reached — approve scope · ratify roles · pick a design · accept a milestone | A decision link on their Console; one click + optional note | ❌ "How should we…?" ❌ "Do you want us to… or will you…?" ❌ Anything answerable from the model, the board, prior approvals, or config. Material implementation choices get made and recorded in the audit trail — not asked. |
| A decision goes stale — pending > 48h | One-line nudge with the same link (repeats every 72h; work is parked, never guessed at) | |
| A milestone lands | Evidence summary + what's next |
| Rung | What the instance does | Human involved? |
|---|---|---|
| 1 · Recall | Searches the knowledge corpus for a recorded fix — most walls have been hit before, and the fix is written down | No |
| 2 · Re-survey | Re-checks its tools for a capability it missed — recorded limitations are treated as hypotheses to retest, not facts | No |
| 3 · Alternate route | Tries the other sanctioned paths for the same outcome (different writer, different layer) | No |
| 4 · Escalate | Files a structured ticket on the Kinetech ops board: what it tried at rungs 1–3, the evidence bundle (logs, model state, build history), severity, and which client is affected. Fires the on-call alert. | Kinetech engineer — SLA per the response level agreed in your engagement |
| 5 · Absorb | The resolution is written back into the knowledge corpus and, where applicable, the toolchain — so rung 4 never fires for this wall again, on any client's instance | Engineer, once — then never again |
Why support load falls over time: rung 5 is the flywheel. Every escalation any client ever triggers becomes a rung-1 answer for the whole fleet. The support cost curve bends down as the corpus grows — we've already retired three "permanent" human steps this way.
autonomy config: decision gates, never-ask list, stale-approval cadence) ships in data/comms-policy.json; the escalation ladder rungs 1–3 are enforced repo law (scar lookup, re-survey rule, routing matrix); the feedback widget → enrich → route pipeline runs against real client boards. Workstream 1.7 (ops automation) adds: the structured rung-4 escalation filer (auto-ticket + evidence bundle + Slack on-call), stale-approval nudge scheduler, and the fleet view on the Console (per-instance status/cost/pending-decisions rollup).
09 · Technical appendix
mx-check · unit-tests · user-test (driven journeys, positive + negative per role) · test-coverage · mockup · screenshots · a11y (axe, WCAG 2.1 AA) · security-scan · vuln-scan · performance · load (k6) · documentation (100% in-model) · user-guide · nav-icons · login · seed · inference-usage (cost) · rollup: release-scorecard (6 graded dimensions). A gate that never ran shows not-configured — absence is visible, never silent. ready is the fail-closed verdict over all of it, including a per-sprint full per-role UX audit.
builds(app, trigger, started/finished, pass/fail counts, ok) → gate_results(build_id, gate, status, metrics jsonb, detail, artifacts) — append-only, scorecard + usage ride as rows, no schema churn. approvals(app, kind: roles|design|spec|ready, title, payload jsonb, status: pending|approved|changes_requested, requested/decided by+at, note) + approval_tokens (service-role-only) + decide_approval() RPC. audit_events(app, seq, kind, actor, body, prev_hash, hash) — unique(app, seq), hash-chained.
npm run approval -- request|list|status|wait|decide · npm run ready (auto-raises acceptance) · npm run design-lab (auto-raises design decision) · npm run verify (gates → Console) · npm run ledger (manifest + usage row) · npm run comms-check -- --app X --channel Y · npm run handoff-pack -- --app X --spec … (client-facing Studio Pro checklist) · npm run marketplace-install · mxf ship (end-to-end governed build).
Status when this was written: approval surface, metering, comms policy, and handoff packs are built and live-verified. Instance isolation (the per-client VM packaging) is the next workstream. Pricing figures are straw-man ranges the meter will replace with measured data during the pilot.