Quickstart with the demo company
Last updated October 5, 2026
On this page
- Before you start
- Create the demo company
- What is in the demo company
- People and teams
- Modules and agents
- Records
- The refund over the cap
- Connections and triggers
- Start the demo
- Sign in
- Your first 30 minutes
- 1. Ask an agent (3 minutes)
- 2. Watch a governed write wait (5 minutes)
- 3. Approve the parked refund as Ada (5 minutes)
- 4. Read the event log and replay the run (5 minutes)
- 5. Pause and resume a module (5 minutes)
- Without a model key, and with one
- No key: the stub planner
- With a key
- Starting over and moving on
- Not possible yet
- For developers
- The command line on the demo
- The API
ok demo creates a small, ready-made software company on your own machine.
You can sign in as any of its people, ask its agents for things, watch an
agent's action wait for a person, approve it, and read the record of
everything that happened. You need no account anywhere and no model key.
By the end of this page you have a working workspace and have followed two approvals from start to finish.
The demo is for development only. Local fakes stand in for every outside system (mail, billing, helpdesk, GitHub, analytics and the rest), so nothing leaves your machine. Its connections may reach any local service over plain http, and every sign-in token is printed in your terminal. Never put the demo on a network you do not control, and never use its state file for real work. For a real company, see Self-hosting, backups and upgrades.
A few terms used on this page:
| Term | Meaning |
|---|---|
| Module | A packaged part of the company (CRM, Support and so on) that brings its own records, agents, tools and pages. See Modules. |
| Agent | A software worker that plans and acts for a person, inside the limits the company sets. See Agents. |
| Approval | A person's yes or no on one action an agent wants to take. The agent's run waits (it is parked) until someone decides. See Inbox and approvals. |
| Brain | The company's shared records, such as leads and tickets. See Brain. |
| Stub planner | What answers in place of a model when no model key is set. See Without a model key, and with one. |
Before you start#
You need the OrchKernel source, Node.js with npm (for the workspace's web pages) and a Rust toolchain. Build once, from the top of the source folder:
(cd ui && npm ci && npm run build) # builds the workspace's web pages
cargo build --release # builds the binary, with those pages inside
alias ok=./target/release/orchkernel
The binary is called orchkernel; the alias lets you type ok as this guide
does. Build the web pages first: a binary built without them still runs, but
the browser shows only "UI not built. Run npm run build in ui/."
Create the demo company#
ok demo
This creates a folder orchkernel-demo in the current folder (use
ok demo --dir <path> to put it elsewhere) and prints what it made:
Created the demo company in orchkernel-demo (development only).
people ada (admin) and fiona, sam, alice, maya, tom, pat, erin, eli
teams Sales, Support, Product, Engineering, Founder's office
modules crm, sales, marketing, support, support-ops, product, product-ops, tech, founder, context
records 19 sample records: customers, leads at every stage, open tickets,
and ticket T-1042 asking for a refund of 250.00 (over the 100.00 cap)
tools 12 connections, each to a local fake; no real account is used
Start it:
ok demo serve --dir orchkernel-demo
It ends by pointing at docs/demo.md, a file in the source folder. This page
covers the same steps.
The folder holds state.db (the whole company) and a plans folder (see
For developers).
Running ok demo again in the same place is refused: "Error: orchkernel-demo
already holds a demo company; pass --force to start over". ok demo --force
throws the old company away and creates a fresh one.
What is in the demo company#
People and teams#
| Id | Name | Role | Team | Reports to |
|---|---|---|---|---|
ada |
Ada Park | Admin | none | |
fiona |
Fiona Reyes | Founder, leads the Founder's office | Founder's office | |
sam |
Sam Ortiz | Sales lead | Sales | Fiona |
alice |
Alice Chen | Sales rep | Sales | Sam |
maya |
Maya Patel | Support lead | Support | Fiona |
tom |
Tom Becker | Support agent | Support | Maya |
pat |
Pat Kim | Product manager, leads Product | Product | Fiona |
erin |
Erin Walsh | Engineering lead | Engineering | Fiona |
eli |
Eli Novak | Engineer | Engineering | Erin |
Ada governs the company: she alone sees People, Modules and Setup in the sidebar, and she approves what the rules send to an admin. She does not read the Sales or Support records herself.
Modules and agents#
Every department module is enabled and healthy: CRM, Sales, Marketing, Support, Support operations, Product, Product operations, Tech, Founder and Context. Each module's team is bound to the company team of the same name; Marketing's agents work in the Sales team. Directory lists 35 agents, all at the Standard trust tier.
Records#
| Collection | What is there |
|---|---|
| Leads | 7, at every stage. Northwind Traders and Contoso Health are won (the customers). Litware is "contacted" and waiting on a follow up from Alice. |
| Contacts | 2: Rosa Diaz (Northwind) and Dana Brooks (Litware) |
| Tickets | 5, four of them open, including T-1042 |
| Roadmap items | 3: Single sign-on (SAML), Faster CSV export, Mobile app |
| Feature requests | 1: SAML single sign-on, 7 votes |
| Incidents | 1: Export workers saturated (sev2, mitigated) |
Who reads what follows the modules' rules, so the same question gets a different answer depending on who asks:
| Person | Leads | Contacts | Tickets | Incidents |
|---|---|---|---|---|
| sam (sales lead) | all 7 | 2 | no | no |
| alice (sales rep) | her own 4 | 2 | no | no |
| maya, tom (Support) | no | no | all 5 | 1 |
| pat (Product) | no | no | all 5 | no |
| erin, eli (Engineering) | no | no | no | 1 |
| ada, fiona | no | no | no | no |
Everyone reads the roadmap items and the feature request.
The refund over the cap#
Ticket T-1042: Northwind was charged twice for September and asks for 250.00 back. The Support operations module lets an agent refund up to 100.00 on its own; anything over that waits for an admin, whatever the agent's trust tier. So an agent's refund on T-1042 always stops for Ada.
Connections and triggers#
A connection is the company's link to one outside tool server. There is one
per tool server, named demo ads, demo apollo, demo billing, demo cms,
demo ga4, demo github, demo google, demo gsc, demo helpdesk,
demo pagerduty, demo sentry and demo stripe. None has a secret. When the
demo runs, each points at a local fake that answers like the real system
would.
Every trigger (a schedule, a webhook or a change to the data that starts an agent by itself) is Off, so nothing runs until someone asks. You can turn one on later (see Pause and resume a module).
Start the demo#
ok demo serve
If you created the demo elsewhere, add --dir <path>. The server listens on
127.0.0.1:8080; change it with --bind, for example
--bind 127.0.0.1:8811. (The OK_BIND setting is not read here.)
The terminal shows demo: 12 local fakes started; 12 connections point at them and OrchKernel serving on http://127.0.0.1:8080, and prints:
OrchKernel demo (development only: local fakes stand in for every tool)
Workspace http://127.0.0.1:8080
Model none configured: a stub planner answers the walkthrough's asks.
Set ANTHROPIC_API_KEY (or an llm.yaml) and restart for a real model.
Egress development mode: connections may reach loopback over plain http,
so an admin can point one at any local service.
Sign in by pasting a person's token on the sign-in page (valid 7 days;
the next start revokes these and prints new ones):
ada admin orchk_34ab…
fiona founder, leads the Founder's office orchk_4838…
sam sales lead orchk_4b0d…
alice sales rep orchk_a0ef…
maya support lead orchk_8d1c…
tom support agent orchk_c3d4…
pat product manager, leads Product orchk_22e3…
erin engineering lead orchk_cb52…
eli engineer orchk_495f…
followed by a short list of first things to try and "Stop with Ctrl+C. Your changes stay in the state file." Each token is longer than shown here.
- Keep this terminal open. Ctrl+C stops the demo. Everything you do is
kept in
orchkernel-demo/state.dbfor the next start. - Every start issues new tokens and revokes the ones the previous start printed. After a restart, sign in again with the new ones; an old one is refused with "That token wasn't recognised or has expired."
- If the address is taken, the start fails with "Error: Address already in
use (os error 48)" (the number depends on your system), but only after it
has printed the banner and the tokens. Those tokens are no use. Start again
with another
--bind. - Model says whether a real model answers. With no key, the stub planner answers the asks on this page.
Sign in#
- Open the Workspace address in a browser. You see the OrchKernel sign-in card: "Sign in with the token an admin gave you.", a Token box and Sign in.
- Copy maya's token from the terminal, paste it into Token and press Sign in.
- You land on Threads. The sidebar shows Inbox, Threads, Work and Curation, the module pages under their sections (for Maya: Context, Engineering, Marketing, Product, Support), and under Company: Brain, Knowledge, Directory, Governance and Events. At the bottom left: Maya Patel, Support lead, and Sign out.
- Click Brain, then Tickets: "5 rows you can read · as Maya Patel", with T-1042 at the top and its refund of $250.00.
To become someone else, press Sign out and paste another person's token. On a phone, the sidebar is behind the menu button at the top left and the inbox is the icon at the top right, with the unread count beside it.
Prefer typing a name to pasting tokens? Start with
ok demo serve --dev-auth. It prints no tokens; instead it says the server
trusts the x-ok-actor header and lists the ids. On the sign-in page open
Development mode (server started with --dev-auth), type a person's id
(maya) under Actor id and press Continue as actor. Anyone who can
reach the server can then act as anyone, so --dev-auth refuses any address
but loopback.
Your first 30 minutes#
Follow these in order: later steps use what earlier ones did.
1. Ask an agent (3 minutes)#
As maya:
- Click Threads. Under Talk to an agent, Support · your team lists the Support team's agents: Churn-risk watcher, Knowledge-base writer, QA reviewer, Support Agent, Triage.
- Click Support Agent. A page "New conversation with Support Agent" opens, with Support Agent already picked.
- Type
What is open?and press Ask agent (or Ctrl+Enter, ⌘+Enter on a Mac). - The conversation shows your message, then the agent's answer: a table of the four open tickets (T-1042, T-1043, T-1044, T-1045), then Done: What is open?. The right-hand panel lists the participants and the task, marked Done.
The answer table shows each field's stored value, so money is in cents:
T-1042's refund_cents reads 25000, which is $250.00.
Clicking an agent you already have a conversation with opens that conversation again instead of a new one.
Now sign out and sign in as alice. Click Sales Assistant, type
Show my pipeline and press Ask agent. You get Alice's four leads only
(Contoso Health, Tailspin Toys, Litware, Adventure Works). The agent acts for
Alice and reads only what she may read; Sam asking the same question sees all
seven. The value column is in cents too (Contoso Health's 1800000 is
$18,000.00).
More on conversations and threads: Asking an agent and Threads.
2. Watch a governed write wait (5 minutes)#
Still as alice, in the same conversation with the Sales Assistant:
- Type
Email a follow up to my contacted leadand press Ask agent. - A notice says "Sales Assistant needs your approval: Send email". The
conversation shows an approval card, Send email, marked Pending:
"Sales Assistant asks to send email.", To
dana@litware.example, Subject "Following up on our demo", and the email's text. Under it, the rule that held it: "Agents never send email without the rep approving the draft". Nothing has been sent. In the right-hand panel the task reads Parked and Approvals lists the card as Pending. - Open Why am I asked?. It lists every check the action passed (Alice's delegation, no pause or kill switch, the skill, the budgets) and the one that stopped it: "A CRM rule requires approval: Agents never send email without the rep approving the draft", then "Alice Chen would be asked, and the run would wait until they decide" and "The policy asks the person it acts for."
- Click Inbox in the sidebar if you like: the same card sits under Waiting on you. Come back to the conversation with Threads, then Conversation with Sales Assistant under Your threads.
- Press Approve on the card.
- The card turns Approved ("Approved by Alice Chen"), and the agent
carries on: its answer shows Next follow up three days from today,
Sent
msg-18c2f1a9(the message id from the mail fake) and Todana@litware.example. The task reads Done.
To see the other outcome, ask the same thing again and press Reject on the new card. A box opens: "Say why, so the agent and the requester know". Type a reason if you like and press Confirm reject. The card turns Rejected ("Rejected by Alice Chen"), the agent answers "Nothing was done." marked Declined, and the task reads Cancelled. No email is sent.
3. Approve the parked refund as Ada (5 minutes)#
Sign out and sign in as maya.
- Threads, then Churn-risk watcher under Talk to an agent.
- Type
Northwind wants a refund for the double chargeand press Ask agent. - The watcher works in rounds: it reads ticket T-1042, looks up Northwind's
account in the billing fake, then asks to refund 250.00. After a second
or two an approval card appears: Issue a refund or credit,
Pending, "Churn-risk watcher asks to issue a refund or credit on
behalf of Maya Patel.", Amount $250.00, Invoice
inv-2026-09-1042, Reason "Double charge on the September invoice (ticket T-1042)", and the rule: "Goodwill credits by agents over the cap of 100.00 in the account currency per call need an admin, whatever the trust tier". Below it: Waiting for an admin (Ada Park). No notice pops up for this one; the card simply appears in the conversation. - Maya has no Approve button. She leads the team the agent works for, but the rule wants an admin. Why does this need approval? shows the same kind of checks as before, ending "A Support operations rule requires approval: ...", "Ada Park would be asked, and the run would wait until they decide" and "The policy asks anyone with the admin role."
- Sign out and sign in as ada. The sidebar's Inbox shows a count.
- Click Inbox. Under Waiting on you is the same refund card. Press Approve.
- Because this moves money, the card asks "Issue a refund or credit of $250.00? It runs as soon as you approve." with Cancel and Approve $250.00. Press Approve $250.00.
- A notice says Approved and the card leaves the inbox.
- Sign in as maya again and open Conversation with Churn-risk watcher
under Your threads. The card reads "Approved by Ada Park", and the
watcher's answer follows: "Refunded after an admin approved it.",
Amount $250.00, Invoice
inv-2026-09-1042, Refundre_3Rk0a1Lq(the billing fake's refund id). The task reads Done.
Had Ada pressed Reject, no refund would be made and the run would end saying so. More in Inbox and approvals.
4. Read the event log and replay the run (5 minutes)#
As ada:
- Click Events. This is the append-only log of everything that happened, newest first; nothing in it can be changed. The line above the list reads "Audit chain: N events, not checkpointed yet", where N is a few hundred by now.
- In Type, choose Approval requested. Two rows: "Approval asked of Ada Park for tool.call(support-ops.billing.refund)" and "Approval asked of Alice Chen for tool.call(gmail.send)". (If you tried Reject in step 2, there is a third row for Alice.)
- Choose Tool called. Three rows: "support-ops.billing.refund called by
Churn-risk watcher", "support-ops.billing.account called by Churn-risk
watcher" and "gmail.send called by Sales Assistant". Click a row to see
its details: the event number, the time, who did it, the raw type
(
tool_called) and its data. - Click Work. It opens on Open tasks; click the Runs tab ("Runs (4)", more if you asked other things). Every run is listed with its state, agent, task, steps, cost, tokens and start time.
- Click the Churn-risk watcher run (task "Northwind wants a refund for the double charge"). A panel opens: "Churn-risk watcher acting for Maya Patel", then the Trace: Used the skill Churn-risk watching, each Planned the next step, Read Tickets: 1 row, Billing account Ok, Asked for approval, Approval Approved, Issue a refund or credit Ok, a Round line after each round, Kept 1 lesson, and the Output.
- Open Replay (raw events) at the bottom. This is the run rebuilt from
the event log alone:
run_started, eachpolicy_evaluateddecision (the refund's readsrequire_approvalwith the reasonrule support-ops-refunds-need-admin: ...),tool_called,approval_requested,run_parked,approval_resolvedbyada,run_resumed, the refund'stool_calledandrun_finished.
With the stub planner, its planning steps still show as model calls: the
events name the model mock-default, and the run counts tokens but costs
$0.00. More in Events and the audit log.
5. Pause and resume a module (5 minutes)#
As ada:
- Click Modules. It opens on the Catalog tab. Click the Installed tab: all ten modules read Enabled and Ok.
- Click Support operations. Its page shows the state, health, version, who set it up and what it requires (Support).
- Press Pause. A confirmation says "Pause Support operations? Its agents, tools and triggers stop and its pages hide; data and settings stay." Press Pause. The state turns Paused and the button becomes Resume.
- Sign in as maya and open Threads. The Churn-risk watcher, Knowledge-base writer and QA reviewer chips read paused and cannot be clicked, and the Support operations page is gone from the sidebar. In her existing conversation with the watcher, the agent picker shows "Churn-risk watcher (paused by an admin)", so Ask agent stays greyed out. The Support Agent and Triage (the Support module) still work.
- Back as ada, open Support operations again and press Resume. There is no confirmation; the state returns to Enabled and Maya's chips work again.
- On the same module page, open the Automation tab. It lists the module's four triggers, all Off: Kb morning (weekdays at 9:00), Qa morning (weekdays at 8:00), Churn on ticket change (a change to tickets) and Churn sweep (weekdays at 8:30). Change automation opens a list with a checkbox per trigger and Save. With no model the stub planner answers those runs too; with a real model they cost money, which is why the demo starts with them off.
The Catalog tab lists every module the company could enable; in the demo each one already says Enabled. More in Modules.
Without a model key, and with one#
No key: the stub planner#
With no key, a stub planner answers instead of a model. It is not a model: it answers the asks on this page with fixed plans (the open tickets, the pipeline, the follow up email, the refund). Anything else gets a note instead of an answer. For example, Pat asking the Product Agent "What should we build next quarter?" gets "No model is configured, so the demo's stub planner answered. ...", which names the keys to set, and the task still reads Done. The governance is real either way: the policy checks, the approvals, the fakes' calls and the event log are the same as with a model.
Changes to skills and playbooks run evals, which need a model. Without one, an eval the stub cannot answer shows as not run, never failed, and the change waits. See Changing a skill or playbook.
With a key#
- Stop the demo (Ctrl+C).
- Set a key, for example
export ANTHROPIC_API_KEY=...(orOPENAI_API_KEY,GEMINI_API_KEY,OLLAMA_HOST), or put anllm.yamlin the folder you start from. - Run
ok demo serveagain. The Model line now names the default model and where it came from ("..., configured from ..."). The server also checks each key in the background and prints a warning for one that is refused. - Sign in with the new tokens and ask anything: the agents plan for real.
What changes and what does not:
| Stub planner | Real model | |
|---|---|---|
| Which asks work | The ones on this page | Any |
| Exact steps and wording | Fixed | Vary from run to run |
| Refund over the cap waits for an admin | Yes | Yes |
| Agent's email waits for the rep | Yes | Yes |
| Cost | Nothing ($0.00 on every run) | Model tokens, shown per run under Work |
The demo's tickets are restricted customer data, and a model only sees data up
to the level it is allowed. From the environment, Anthropic's models and
Ollama may take restricted data; the built-in OpenAI and Gemini models stop
at confidential, so with only one of their keys the Churn-risk watcher's
refund ask is refused for lack of an allowed model. In an llm.yaml, give the
model max_sensitivity: restricted. See Models.
Starting over and moving on#
| You want to | Do |
|---|---|
| Stop | Ctrl+C in the terminal running ok demo serve |
| Carry on later | ok demo serve again, and sign in with the new tokens. Your threads, approvals and runs are still there. |
| Throw everything away | Stop, then ok demo --force, then ok demo serve |
| Try one real system | See Connections and integrations. ok demo serve re-points only connections that still point at 127.0.0.1, so one you point at a real system stays as you set it. |
| Set up a real company | Do not start from the demo. Start from a clean state with ok init; see Setting up a company and Self-hosting. |
Not possible yet#
- Running the demo for other people over a network. It is for one person on
one machine;
--dev-authrefuses any address but loopback. - Changing how long the printed tokens last (7 days) or keeping them across a restart.
- Choosing which modules or people the demo company has. Use
ok initwith a blueprint for that. - Money in agent answer tables is shown in cents, not formatted as in Brain.
For developers#
The command line on the demo#
Stop the server first: a command opens the same state file and writes it when it finishes. Then name the file and a person:
ok --state orchkernel-demo/state.db --as ada module list
ok --state orchkernel-demo/state.db --as maya brain query tickets
ok --state orchkernel-demo/state.db --as ada runs
ok --state orchkernel-demo/state.db replay --run <run-id>
module list prints one line per module (support-ops enabled ok bundled Support operations); runs lists each run's id, state, agent, steps and
cost, which gives you the id for replay.
orchkernel-demo/plans/ holds the walkthrough's plans as JSON
(follow-up.json, leads.json, tickets.json). In developer mode (add
?dev=1 to the workspace address) a conversation has an Explicit plan
button where you can paste one; ok ask --plan <file> takes one too.
The API#
Every printed token works as a bearer token against /api:
curl -s -H "Authorization: Bearer $MAYA_TOKEN" \
-H 'content-type: application/json' -d '{}' \
http://127.0.0.1:8080/api/brain/collections/tickets/query
returns Maya's five tickets as JSON; the same call with Ada's token answers
403 with {"error":"denied","message":"brain: access denied: ada may not read tickets"}.
Asking a paused module's agent through the API
(POST /api/threads/<id>/ask with {"agent":"churn-watcher","text":"..."})
answers 403 denied: "policy denied run: kill switch engaged: support-ops is
paused". The message and its task are still recorded in the conversation,
though, and the task runs as soon as the module is resumed.
GET /api/health answers {"dev_auth":false,"ok":true}, with dev_auth: true when the server was started with --dev-auth. See the
CLI and API reference.