The defaults
Everything an instance runs on has a value, and every value is one of two kinds: a setting with a default, or a number written in the code. This page is both lists — what you can change and where, then what you cannot, what each fixed value governs, and why it is fixed rather than a setting. Read it before asking for a knob: the reason a value is fixed is usually the answer.
What can be changed
Nine places hold everything that is yours. An update replaces the payload —
bin/ and lib/ — and touches none of them; the
customization page says how each one is used.
| where | what | default |
|---|---|---|
| the install: a flag, or a question on the terminal | --root, --user, --leader | none — asked, never guessed |
--leader-model, --worker-model | opus, sonnet | |
--port | 0 — a free one, chosen at each start | |
--auth | login; the other answer is inherit | |
--source, --force | never asked: where the toolkit is, and whether to install into a directory that is not empty | |
openovai.json, written by the installer | user, leader, models, port, auth | the answers above |
openovai.json, read when present | idle | { "fyi": [10, 50], "force": 55, "all": 1 } minutes |
context | { "warning": 200000, "step": 20000, "error": 300000 } tokens; step is the Leader's own, since a Worker's size reaches the Leader at the warning and the error only | |
park | { "deadline": 1800, "timeout": 20, "margin": 15 } seconds | |
typing | { "quiet": 10, "cap": 30 } seconds; 0 in either turns the hold off — the typing hold, with a worked timeline | |
quota | { "5h": [90, 95], "7d": [97, 99] } percent | |
desk | { "limit": 131072 } bytes, 128 KB: a desk file past it is saved whole beside itself as STATE-<time>.md and its seat told once per crossing | |
| one Worker's desk | desks/<Name>/MODEL, written by hire when a model was named | absent: the usual one, models.worker |
| the environment | XDG_DATA_HOME | ~/.local/share; the runtimes live under <data>/openovai/ |
OPENOVAI_NODE_DIST | https://nodejs.org/dist — where Node.js is fetched from | |
CLAUDE_CODE_OAUTH_TOKEN | read only under --auth inherit; removed from every seat's environment otherwise | |
.claude/settings.json and .claude/allowed.md | the permission rules: allow, deny, ask | the seeded set; yours from the first permission popup on |
knowledge/ | one Markdown note per topic, written and edited by every seat | empty, but for the common.md every session is given |
customization/ | common.md, leader.md, worker.md, each framed into the sessions it is for | empty |
plugins/ | one .mjs per tool the instance serves itself | empty |
| the browser, per page | the theme; the two notification switches; the switch that hides the messages between sessions from the Leader's panel, kept as openovai-comms | light; both off; shown |
ovai update | --from <url or directory>, --downgrade | the latest release on GitHub; never older than the instance is on |
The six keys read when present are honoured and nowhere else: the installer does not write
them, the terminal does not ask for them, and ovai configuration does not print
them. A value of the wrong shape falls back to the default for that key.
Models
A model is a word: an alias or a full name, a letter or digit then up to sixty-three letters,
digits, dots, dashes or underscores, with an effort after one slash if you want one:
opus/high. That is the whole check, at install, in a desk's MODEL
and at hire alike, and there is no list behind it — nothing in the toolkit
accepts one model or one effort by name or refuses another, on purpose: a workspace that may be
installed on a model has to be able to hire onto it, and a list would be a second answer to
what the account can run. A model the account has not got is refused by the harness at the
first turn, not by the instance; an effort it does not know is ignored with a warning on the
harness's stderr, and the seat runs at the harness's default.
The part before the slash goes to the harness as --model, the effort as
--effort; the levels it takes are low, medium,
high, xhigh and max. With no effort written, none is
passed and the harness picks its own for the model, medium for Opus 5.5 and
Sonnet 5.5. A seat never takes CLAUDE_CODE_EFFORT_LEVEL from the shell the server
was started in, since the harness reads it before --effort. Everywhere a model is
shown, it is shown as written. A new instance offers opus for the Leader and
sonnet for the Workers; an installed one keeps the models it has.
Fast mode, the harness's /fast, runs Opus faster at a higher price per token,
billed from the account's usage credits. It is off for every seat, whatever the User's own
setting says: a seat runs in print mode, where the harness allows fast mode only when the
settings it is started with say "fastMode": true, and that setting switches it on
for the whole session rather than making it available. At the command line a person turns fast
mode on for the one session in front of them. Here the Leader starts Workers on demand, and ten
of them on fast mode could run up a large bill within minutes. Fast mode may come back later as
a choice per Worker, beside its model and effort.
What cannot be changed
Every value below is written in the code and the same in every instance. The last column is
why: a fixed value is a decision, and the decision is what you would be asking to reopen. The
file named is where it lives, under lib/.
Sign-in and the address
| value | governs | file | why fixed |
|---|---|---|---|
127.0.0.1 | the address the page listens on | chat/runtime.mjs | the page signs a browser in with a one-time link, not a password; a wider bind is a security decision the toolkit does not offer |
| 10 minutes, once | how long a link from ovai start or ovai url signs a browser in, and how often | chat/signin.mjs | long enough to copy into a browser, not worth finding in a scrollback; the browser then stays signed in across restarts and updates |
1024–65535, or 0 | what --port accepts | install.mjs | the unprivileged range |
inherit, login | the two ways an instance signs in | install.mjs | a closed set: an account of its own, or the machine's token |
ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN | never inherited by a seat, whatever the instance was installed with | claude.mjs | either would run a seat as somebody else, or against somebody else's bill |
what Claude Code puts on a session: its id, pid, entry point, effort, messaging socket and token; and PWD, OLDPWD | dropped by the server and every seat it starts, so ovai start typed in a session's shell hands that session on to nothing; CLAUDE_CODE_OAUTH_TOKEN stays under inherit | claude.mjs | a seat is a session of this instance, never a child of the one that started the server |
Names
| value | governs | file | why fixed |
|---|---|---|---|
| the roster: Paul, Jane, Jack, Pete, Anna, Mark, Lucy, Tom, Eva, Sam, Nora, Ben, Mia, Leo, Zoe, Max, Ivy, Finn, Ada, Noah, Ella, Owen, Ruby, Hugo, Iris, Otto, Lena, Axel, Nina, Theo | what a Worker is called when the Leader names nobody: the least recently used free name, in this order | desks.mjs | the same thirty in every instance, so a name means one person for as long as thirty names allow |
a letter, then up to 31 letters, digits, _ or - | what a name is: the User's, the Leader's, a Worker's | desks.mjs | a name is a directory under desks/ and a word in every message |
Leader, Worker | the two roles | desks.mjs | the vocabulary every persona and every tool is written in |
Clocks and thresholds
| value | governs | file | why fixed |
|---|---|---|---|
| 60 minutes | when an idle seat goes cold: the life of its prompt cache; the 50-minute FYI counts down to it | chat/lifecycle.mjs | the vendor's number, not the instance's |
| 5 minutes | after the critical idle event, before a Leader that has not stopped itself is ended; for a Worker closed for idling or a spent window, or by stop_worker or restart_worker with an interrupt, how long after the turn that read the close its desk is waited for | chat/lifecycle.mjs | one desk write and one stop take seconds |
| 60 seconds; 200 ms | how often the clocks are read; how often a park looks at who has stopped | chat/lifecycle.mjs | mechanism |
| 10 minutes; 2 minutes | how long a popup that holds a session's call waits before it is a Deny; the same when one of the session's subagents made the call; read on a one-minute clock | chat/lifecycle.mjs | a person who has not answered in that long is not at the panel; a subagent is not built to be stopped, and the session's prompt cache lives 5 minutes |
| 10 seconds | a wait on a permission popup long enough to be written on the panel as Waited N seconds for permission | chat/lifecycle.mjs | under that there is no gap to explain |
| 2 seconds | how often, at most, the page tells the server a key went into a seat's box; the typing hold's quiet counts from the last one it heard | chat/panels.mjs | a beat well inside the quiet is enough |
| 1 minute | of two rows saying when a session ended or started, less than this apart, only the first is drawn | chat/render.mjs | an end and a start seconds after it are one moment; both stay in the conversation, and only the drawing leaves one out |
| 10 seconds | a tool call slow enough to get a row of its own on the panel | chat/server.mjs | the same reason |
| 500 ms; 3 | how long a word on the tool line stays up; how many wait behind it | chat/panels.mjs | readable at a glance, and nothing lost |
| 30 seconds | how long a stopped Worker's panel stays on the page | chat/panels.mjs | long enough to read how it ended |
| 30 minutes; 2 seconds; 10 seconds | how long a tool call may take over the tools connection (a park); how long an interrupted turn is given to say so; how long a session that is ending is given to end its turn | chat/session.mjs | bounds on the harness, measured or guessed and said so in the code |
| 5 seconds; 5 minutes; 60 seconds; 5 minutes; 15 minutes; 10 seconds | how often the server looks at whether the usage wants reading; how old a reading may get while a page is open; how old a reading may get before a turn's end or a page load reads it again; how long a failed reading is left alone; how old a reading is drawn dimmed; the request's timeout | chat/server.mjs, chat/usage.mjs | one endpoint, asked politely |
| 30 seconds; 60 seconds | how long ovai start waits for the server to answer; how long a release fetch is given | ovai.mjs, release.mjs | a server binds in a second; the rest is a machine under load |
Limits
| value | governs | file | why fixed |
|---|---|---|---|
| 120; 80 | write_desk: the title, the status | chat/server.mjs | title and status share one header line |
80 characters; | & ; < > $ ` and a newline | an exact-command rule — the one Claude Code would save for a command no rule is composed for — longer than this or holding any of those is not offered as Always; the rules composed for a compound's sides are offered whatever its length, and none is drawn from inside a backtick or $( span; a rule naming one file is never offered as Always either, only settled by the Leader | chat/permissions.mjs | longer than a line of the permission popup, or holding shell syntax, it is a one-off written out in full, and as a rule it would fill the panel and never match again; the words on a button are the rule it writes, so it is left off rather than shortened |
| 100 000 characters | one message, from the composer or the message tool | chat/server.mjs | a message is a message, not a file |
| 200 characters | how much of a refused tool result the tooltip shows | chat/session.mjs | a tooltip |
a letter, then up to 31 letters, digits or -; description, inputSchema, run | what a plugin file may be called; what it has to export | plugins.mjs | the plugin contract; the sixteen built-in names are taken |
four fields and nothing else; at least three lowercase hyphenated tags, no duplicates; sources that are paths from the instance directory, URLs or <user>; a date that is not in the future; a lowercase hyphenated filename | what a note under knowledge/ is, and what validate reads back | chat/server.mjs | the shape of what the workspace knows: a contract short enough to hold in your head is one every seat keeps |
The page
| value | governs | file | why fixed |
|---|---|---|---|
| light | the theme before a choice is made | chat/page.html | the toggle is the setting |
| off; off | the two notification switches before a choice is made | chat/page.html | a browser prompt nobody asked for is the wrong first impression |
| shown | the messages between sessions on the Leader's panel before a choice is made | chat/page.html | the Leader's panel hears the whole room until you say otherwise |
| on; on | the two auto mode switches, the Leader's and the Workers', at every start of the server; a switch turned off holds until the server stops, and is kept nowhere | chat/session.mjs | a seat works as the Claude Code CLI does, which starts in auto |
| 40 % | how much of the window the composer may grow to | chat/page.html | the rows above it are what you are reading |
OpenOv AI | the page title, and the title of every notification | chat/panels.mjs | the product's name |
| ls cat echo pwd head tail grep find wc which diff stat du cd | the commands a permission popup offers no rule for when a compound has one of them as a side | chat/permissions.mjs | read-only by nature; any other side the instance does not hold is offered by its first word |
The instance on disk
| value | governs | file | why fixed |
|---|---|---|---|
desks/ reference/ projects/ temp/ archive/ knowledge/ plugins/ customization/ .claude/ .local/ | the directories an instance is made of | install.mjs, desks.mjs, claude.mjs | every grant and every persona names them; a rename is a fork, not a setting |
openovai.json, instructions.json, runtime.json, runtime.log, page-session, page-link, introduced, claude-variables; STATE.md, conversation.json, persona.md, MODEL, mcp.json in a desk; STATUS.md, status.json in the Leader's | the files the toolkit writes | seed.mjs, instructions.mjs, chat/runtime.mjs, chat/signin.mjs, chat/server.mjs, chat/status.mjs, variables.mjs, desks.mjs | the instance directory, file by file |
knowledge/common.md | the one note handed to every session at its start, in a frame that names it | desks.mjs | a workspace needs one page a newcomer is given rather than has to find; the rest of the directory is searched, not handed out |
workspace | the one directory name Claude Code files the instance's transcripts under, whatever path the instance sits at | claude.mjs | so an instance moved or copied still finds its own threads: no absolute path anywhere in it |
CLAUDE.md, CLAUDE.local.md, .claude/CLAUDE.md, .claude/rules/** | the instruction files a seat does not obey from any directory under the three trees | instructions.mjs | a cloned repository's instructions are its author's, not this workspace's; the instance directory's own are read |
autoContinueAtUsageLimit on; autoMemoryEnabled off; attribution off | the harness's own settings for the instance's account | seed.mjs | a seat waiting on a dialog at a keyboard nobody sits at has left the room; a second memory is a second answer; a commit is the seat's |
the seeded allow, ask and deny rules, and the subagent hook that hands a subagent customization/common.md | what a fresh instance never stops for, what it stops for, and what no seat does with a tool | desks.mjs, seed.mjs, hooks/subagent.mjs, run through hooks/run.sh on the pinned Node.js | the seed is fixed; the file it seeds is yours from then on |
| the mechanics every seat is told, the two role templates and the desk template | what every Leader and every Worker is told at start: common.md first, then leader.md or worker.md, each in an <ovai source="…"> frame that names it; the Leader also gets introduction.md, the one screen that says what ovai is, in a frame of its own after its role | templates/ | customization/ is framed in beside them; the mechanism the personas describe is the toolkit's |
The runtime and the update
| value | governs | file | why fixed |
|---|---|---|---|
| Node.js 24.21.0, Claude Code 2.1.314 | what every instance of this release runs on | RUNTIME | the pair is chosen and tested when a release is cut; a fix in either reaches you through the next release, never through a range resolved at install |
--permission-mode auto | the harness mode every seat is started in, whenever the server starts; a switch on the Leader's head turned off is default, Manual, for that role until the server stops | chat/session.mjs | to work as the Claude Code CLI does, whose classifier settles a call no rule settles; named explicitly, since print mode starts in Manual from Claude Code 2.1.302 |
bin/, lib/ | the payload: what ovai update replaces whole | payload.mjs | everything else is yours and is left as it is; a file of yours a fresh install would have seeded is seeded, once |
| the latest release on GitHub | where openovai and ovai update look when told nothing | release.mjs | --from is the other answer |
help status configuration start stop restart plugin login claude update | the ovai commands | ovai.mjs | the reference has each one |
Reference: everything with a name, in tables.