Domain Loadout Router
July 9, 2026 · View on GitHub
OMK routes incoming tasks to a domain capability profile ("inherited document") before dispatch. Each profile is a curated bundle of skills, MCP servers, hooks, a tool gate, an authority, and a detailed English routing prompt — all selected from the live capability inventory. The router is deterministic, I/O-free, and explainable.
Auto-generated from
src/core/domain-loadouts.ts+src/core/domain-router.ts. Regenerate withnode --import tsx scripts/gen-domain-docs.mjs.
How routing works
- Signal extraction. The task text (plus optional path hints and upstream tags) is lowercased and scored against every domain's triggers.
- Weighted multi-signal scoring.
keyword— literal phrase occurrences (counted, capped at 3) × weight.regex— intent cluster tested once against the task text × weight.extension— file suffix on any path hint × weight.path— path fragment contained in any path hint × weight.
- Ranking. Domains are sorted best-first; ties break by registry order (deterministic).
- Confidence.
- top score ≥ 8 →
confident - 4 ≤ top score < 8 →
tentative - top score < 4 (or zero signals) →
fallbacktogeneral
- top score ≥ 8 →
- Ambiguity. When the runner-up is within 2 of a tentative leader, the result is flagged
ambiguous(the leader still wins; the caller can ask for clarification).
Thresholds: STRONG_THRESHOLD = 8, WEAK_THRESHOLD = 4, AMBIGUITY_MARGIN = 2.
Domains (13 + 1 fallback)
frontend-ui— Frontend & UIvisual-qa— Visual QA & Website Cloningkorean-document— Korean Document (HWP/HWPX)backend-api— Backend & APIdata-science— Data Science & Analysissecurity-audit— Security Auditdevops-infra— DevOps & Infrastructureresearch— Research & Investigationmobile— Mobile (iOS / Android / KMP)docs-writing— Docs & Technical Writingqa-testing— QA & Testinggrok-harness— Grok xAI Harnessai-agent-ops— AI Agent Engineering & Opsgeneral— General (fallback)
Worked examples
| task | path hints | routed to | confidence | reason |
|---|---|---|---|---|
build a responsive login form with tailwind | src/app/page.tsx | frontend-ui | confident | Frontend & UI selected (20) |
scan for xss and sql injection vulnerabilities | — | security-audit | confident | Security Audit selected (19) |
do a literature review on RLHF, cite arxiv | — | research | confident | Research & Investigation selected (17) |
write a dockerfile and deploy to vercel | Dockerfile | devops-infra | confident | DevOps & Infrastructure selected (19) |
fix the failing playwright e2e tests | tests/login.test.ts | qa-testing | confident | QA & Testing selected (28) |
add a postgres migration for the users table | — | backend-api | confident | Backend & API selected (11) |
train a classifier on the dataset, plot results | notebooks/model.ipynb | data-science | confident | Data Science & Analysis selected (22) |
hello there | — | general | fallback | no domain signals detected |
Composition with role loadouts
A domain profile is a LoadoutProfile, so it composes with the existing role-based system (BUILTIN_LOADOUTS: inspect / plan / code / test / review / security / package-maintainer). The domain gates which skills/MCP/hooks are active; the role sets authority/tools/commands. Use domainLoadoutProfiles() to get plain profiles consumable by applyLoadoutProfile().
API
import { routeDomain } from "./core/domain-router.ts";
const result = routeDomain({ task: "build a login form", paths: ["page.tsx"] });
// result.primary -> DomainProfile
// result.confidence -> "confident" | "tentative" | "fallback"
// result.scores -> ranked DomainScore[] with matchedSignals
// result.ambiguous -> boolean
Adding a domain
- Add a new entry to
DOMAIN_PROFILESinsrc/core/domain-loadouts.ts(id, label, authority, tools, curated skills/mcp/hooks, triggers, routingPrompt). - The router and docs pick it up automatically — no other code changes.
- Run
npm run check(biome + tsgo + tests) and regenerate docs.