Admission control (why heavy agent work waits and you never do)
When Omniscio is doing a lot at once — several agents building, searching, installing and starting sessions — a set of machine-wide gates holds the heaviest of that work back so the app stays responsive. Every gate is bounded and fails open, so a job is delayed at worst and then runs anyway; it is never blocked indefinitely. The trade is deliberate and one-directional: slow the agents, never the user.
What it is
Admission control is not one feature — it is a family of gates, each guarding a different way a burst of work can hurt the machine. The ones that matter to you:
- Heavy-job broker — caps how many heavy background job-trees (builds, tests, big installs) start at once, widening the spacing between starts as the CPU heats up.
- Disk-pressure and RAM-floor holds — hold new heavy admissions during a disk storm or when memory is collapsing, so the machine drains instead of tipping over.
- Search admission — thread-caps and gates an agent's
rg/grepwalks, and batches thefind -execshape that would otherwise fork-bomb the box. - Git admission — a light pool caps an agent's shell git walks and the app's own git polls while the machine is loaded.
- Spawn admission — paces agent package-manager tree-starts (
npm/npx/pnpm) and programmatic session spawns box-wide. - Dependency installs — an install takes a turn in a shared slot, so only one process writes the package store at a time; if it cannot win the slot inside its window it is refused and can be retried, never run beside another store writer.
Every one of those is fail-open and kill-switched: under a fault, or with its switch set, the gate steps aside and the work runs unpaced. A gate here can only ever delay work — it never skips a check, never weakens a test, and never turns a pass into a fail.
Where to find it
- Settings → Performance carries the dials you can actually change: the spacing applied to session starts when many come back at once, and the wait between automation-created sessions.
- The governance control screen (
npm run perf:control,GET /perf/control, and the Performance Monitor panel) is where you see every gate at once — its counters, its coverage and its kill-switch name. That surface is documented in full on Governance control and triage. - There is no per-gate on/off screen. Each gate's escape hatch is a named environment switch read through the governor-switch helper, and the control screen prints the name of the one you would need.
How it behaves
Bounded waits, tiered on purpose. A lightweight interactive admit (an agent's search or git walk) must never look hung, so it waits only seconds; a heavy queued job (a build behind other builds) legitimately queues for tens of minutes. The tiers are declared in one place so a new gate references its tier rather than copying a bare number: 20 s for interactive admits, 90 s for a nested sub-cap inside an admission the caller already holds, 10 min for the broker, 30 min for heavy queued work, 45 min for the build queue, and a 5 s process-start tier for the spawn-pacing round trip.
The whole local phase is capped too. Individually-bounded caps are not enough on their own, because one run traverses several of them in sequence and nothing bounded their sum against the run's own ceiling — measured, that is how runs spent their entire ceiling queueing locally and returned no verdict at all. So a run now arms a pre-dispatch phase budget: one absolute deadline covering roughly half the run's ceiling, which every admission wait clamps to. Once it is spent, a wait becomes zero and the caller lands on its existing fail-open path and goes and does the work.
Nothing here can make things worse. The phase budget can only ever shorten a wait, never lengthen one, so it cannot introduce a hang; its worst case is the pre-existing fail-open the pools already take on timeout. And the gates for your own input are held to a hard rule — the focused session's grants are released above the mode branch and above the token bucket, so a non-zero "user interactive held" reading means a change stopped releasing that class, which is a violation rather than tuning.
It is deliberately observable rather than silent. The control screen renders not-counted, unproven and unknown instead of a reassuring zero, because a counter that moves proves a gate is reached, and only a hold or a refusal proves it acts.
For agents
This page covers the live admission gates. The inventory heading "Box Reliability / Admission Control" is a machine-wide subject with no single screen; the nearest surfaces are the control screen (perf-control.md) and the severe-lag dial (severe-lag-background-pacing.md), neither of which documents what the gates do — that is what this page is for. Do not map this subject to heavy-job-pacing.md: that page documents a retired system and says so in its own title. Pointing a live subject at a retired page fakes coverage.
Code: the timeout tiers are declared once in scripts/lib/admit-timeouts.mjs (INTERACTIVE_ADMIT_TIMEOUT_MS, SUBCAP_ADMIT_TIMEOUT_MS, BROKER_QUEUE_TIMEOUT_MS, HEAVY_QUEUE_TIMEOUT_MS, BUILD_QUEUE_TIMEOUT_MS, PROCESS_START_ADMIT_TIMEOUT_MS, INSTALL_ADMISSION_DEADLINE_MS) — never re-derive a cap by hand. The pre-dispatch budget is scripts/lib/admission-budget.mjs (armAdmissionBudget, PRE_DISPATCH_BUDGET_FRACTION = 0.5, ADMISSION_DEADLINE_ENV, kill switch AMC_DISABLE_ADMISSION_BUDGET). In src/main a governor is read through governorSwitch(id, role) from src/main/utils/governor-switch.ts — never a raw process.env.AMC_* — and the counters live in src/main/utils/governor-counters.ts. The family's contract is agent-load-governance-contract.md; the control surface's own invariants are in perf-control.md.
Related
- perf-control.md — the one screen showing what is being paced, by which governor, and why
- severe-lag-background-pacing.md — the dial for spacing background starts during severe lag
- heavy-job-pacing.md — the retired pacing system this family replaced
- slow-computer-part-2.md — the user-side view of a spawn storm and what the app does about it
- perf-status.md — the machine's own numbers in full
Last verified 2026-10-06