Open source
An open-source agent harness you can swap out
Reading the source is the easy half. Replacing the adapter without rewriting your agents is the half that decides whether the harness is yours. Kortix is the open-source AI Operating System, and its harness boundary is a single module.
Where the harness lives in four agent tools
Where the rules live decides who can change them, and whether a second runtime can read them.
What open means at the harness layer
Agent = Model + Harness. The model contains the intelligence and the harness makes that intelligence useful (LangChain). Open source at that layer makes three promises. You can read the controls the agent runs under. You can replace the runtime that enforces them. Your agent files keep working after you do.
Most tools pass the first test and fail the third. Claude Code keeps its controls in settings JSON: .claude/settings.json, the shared project file your team commits, and ~/.claude/settings.json, your own copy for every project, with allow, ask and deny rules for each tool (Claude Code settings). Standing instructions live apart from those files, in CLAUDE.md. You can read every rule you write. What you cannot do is carry those rules to another runtime, because the program that reads them ships closed.
Codex CLI takes a different shape. It is OpenAI's coding agent that runs locally (Codex CLI), with personal defaults in ~/.codex/config.toml and project overrides in a .codex/config.toml that loads only for a trusted project (Codex config). The config is a file you can read and review. The agent that reads it runs on the machine in front of you.
OpenHands sits one layer up, as a self-hosted developer control center that runs OpenHands, Claude Code, Codex, Gemini, Pi, OpenCode or any ACP-compatible agent, on local, Docker, VM or cloud backends (OpenHands). That is genuine portability of the agent, and it is a separate question from portability of the harness. Each agent it launches still reads its own configuration, so swapping the agent does not move the rules.
Three tests for the word open
Can you read the controls. Find the file that decides what the agent may call, what it must ask about and what it can never touch. If that answer is a settings screen behind a login, the first test fails, whatever the repository says.
Is the adapter one module. Search the runtime for the place that imports a concrete agent loop. Kortix states the rule in its harness boundary README: "harness.ts is the only module that imports a concrete adapter. It resolves the implementation and exposes a definition for configuration, boot, and service creation." Two adapters are registered: pi, which every new session runs, and opencode, which is deprecated. An unknown id fails the boot.
Do the agent files move. Take one agent file to the second adapter and see what has to change. If the answer is the prompt, the permission and the model, the file was never portable. If the answer is nothing under the agent directories, the harness is doing its job.
The swap test, in an afternoon
A team can settle the question without a migration project. Four questions, each answerable from the repository and one test session.
Where does the agent live? In Kortix it is agents/<name>.md, and the manifest points at it with a file field. On the other side of the test, look for the same thing: a path in version control, not a row in a console.
Can you read it in a diff? Open a change request that edits one rule and read what a reviewer sees. A permission change that arrives as a diff is reviewable. A permission change that arrives as a click leaves no trace in the history of the repo.
Does the same file run on a second adapter? Boot one session on the other adapter with the same agent file and ask it to state its own rules. Kortix makes that concrete: there is no per-request switching, one box runs one harness for the life of the box, so the test is a second box rather than a flag.
What does the target handle worse? Kortix answers this before the switch through a preflight, POST /v1/projects/:p/sessions/:s/log/switch-preflight. The answer reports whether the switch can happen, whether the new box restores the log, what the session uses that the target handles worse (losses) and everything the target lacks (unsupported).
What you lose on a switch
A switch has a bill, and the honest harness shows it before you pay. The preflight exists because the losses are specific. A new adapter may not implement a capability the session uses. The target may handle a feature worse. A log may restore without a piece of its history.
Kortix keeps the switch auditable at the session level. With log restore on, a box that boots a different harness restores the log and records the switch in harness.history, so the transcript shows where one runtime handed over to the next. A new version of the same harness adds no entry, which keeps the history about real moves.
One small rule keeps that from rotting. New behavior is built behind a capability, RUNTIME_CAPABILITIES, and never behind a check on which harness is running. The README gives the same instruction to anyone adding to pi/ or shared/. A branch on the harness name is how a boundary turns into a fork, and a fork is the version nobody can test against a second adapter.
The file layout decides who owns the work
The layout at the root of a Kortix project is harness neutral: agents/<name>.md, skills/<name>/SKILL.md, memory/, tools/<name>.ts, plus harnesses/opencode/ and harnesses/pi/ for the files only one harness reads (kortix.yaml). Everything a person edits to change how the company works sits outside those last two folders. Swapping the adapter touches the adapter's folder, not the agent files.
The manifest follows the same split. kortix.yaml carries one agents: map per project and is governance only: connectors, secrets, kortix_permissions, skills, workspace, enabled, plus file. Behavior lives in the .md file. Its frontmatter holds the description, the model, the mode, the temperature and the permission, and the body is the prompt. The manifest's grants are deny-by-default: an omitted connectors, secrets, kortix_permissions or skills grant resolves to "none" and a scoped specialist starts locked down (kortix.yaml).
That split is what makes the swap test affordable. A rule the whole company follows sits in a file reviewers can see. A rule that only fits one runtime sits in that runtime's folder, where anyone can see it is the exception.
A harness you can hold
Kortix keeps your agents, the skills they share, your company memory and every connector in one git repo, versioned and diffable (Kortix on GitHub). One isolated sandbox per session. Each session has its own isolated machine and branch. Session work reaches main through a change request. Merge is default-deny for agents. Approval gates you set. Off until you set them.
Run it on Kortix Cloud, in your VPC, or on your own on-prem network. Self-host is free. The adapters, the boundary module and the manifest sit in the same repository you read to run it. So "can I replace this" is answered by a pull request, not by a support ticket.
One box, one harness, and a preflight before a switch
`loadConfig` reads it BEFORE the adapter loads its own environment, so only theselected adapter's variables are parsed. There is no per-request switching: onebox, one harness, for the life of the box. A new box of an OpenCode sessionboots pi. With `session_log_restore` on, that box restores the log into pi andrecords the switch in `harness.history` ("Harness history, a switch" below).`POST /v1/projects/:p/sessions/:s/log/switch-preflight` (apps/api) answersThe adapter boundary is one module, and the switch is a read before it is a migration.
Questions the comparison raises
Each answer covers the harness layer, not the model.
- Is there an open-source agent harness?
Yes. Kortix ships an open-source agent harness inside its AI Operating System, where the adapters, agent files and rules are files you can read and replace. The manifest and agent files sit in the repository, and the runtime that enforces the rules is code you can read, fork and audit.
- Can you self-host the harness?
Yes. Kortix runs on Kortix Cloud, in your VPC, or on your own on-prem network, and self-host is free. A self-hosted instance still boots one harness per box, so the swap test works the same way.
- Does an open harness mean open model?
No. A harness is the environment around the model, and the model is a separate choice, so an open harness can run a closed model. What the harness decides is the rules, the tools and the checks around it.
Run the swap test on your own stack
Read the adapter boundary, then boot a second box on the other harness and read the losses before you commit to the move.