sharness.ai / the design / the spectrum · this page as markdown

From a hello world to sgit: the spectrum

Status: design, with P0 runnable and two sgit rows measured. SHarness has to protect the simplest case, a hello world, as well as a Claude Code session, a tool, an agent that runs all day on untrusted text, and a complex application like sgit. This page lays those out as five profiles of one harness, says what each needs, and maps how sgit's next version stays compatible. Measured rows are as of 24 Oct 2026.
The spectrum: five profiles from a hello world to sgit, which components each switches on, its mode and its status.
The same components, more of them switched on. No profile changes the protocol; each adds a policy layer.

1. The five profiles

P0 · a hello worldP1 · a Claude Code sessionP2 · a tool or MCP serverP3 · a newsroom agentP4 · sgit
What runsone child process (python -c, curl, a script)the orchestrator: Claude Code, the Agent SDK, your own loopone program that answers requests: an MCP server, a fetcher, a converteran agent loop that reads feeds, pages and documents around the clockan application that holds secrets: vault keys, tokens, signing keys
Threatit writes where it should not, or phones homeprompt injection drives the tools; the API key sits in the harnessa crafted input exploits its parser; it exfiltrates what it was givenuntrusted text acts through the agent, all day, unattendedthe key leaks to disk, argv, the transcript; a confused deputy pushes elsewhere
Policyv0: files read, write and exec; network none or ports; no_new_privsL0 to L3 for the orchestrator: an execute allowlist (node, rg, the bash client), its state folder writable, the llm and bash ports onlyL2 and L3 for the app: its folder, its endpoints, no execP1 plus: the workspace read-only, feed hosts allowlisted, bash profile analyse only, writes only through sharness.fs to one folderL0 to L5, per subcommand: status gets op=read and no write key; clone gets one host and one writable folder
Componentsthe kernel onlylauncher, bash, llm, kms (for the API key), net, fslauncher, fs, netlauncher, fs, net, bash, two sharness.llm policies (privileged and quarantined), kmslauncher, fs, net, kms
Modetransparenttransparent: ANTHROPIC_BASE_URL, HTTPS_PROXY, Bash denied and sharness.bash as the only shell, a one-line hooktransparent: a folder and a proxytransparent, with sgit inside as the one harness-aware appharness-aware where it handles keys; transparent everywhere else
Who runs the launcherthe process itself: a Setting, not a Boundarya script above the agent on a laptop; the platform in the end statethe platform or a scriptthe platforma script or the platform
Statusrunnable: sharness-ai hello, measured 5 of 5designed; Claude Code's own sandbox is the stand-in for sharness.bash todaydesigneddesigned; the newsroom's agents are the use case, not yet a userdesigned; read-only commands already run under a v0 policy (§3)

Two things hold across the row. First, the policy for a harder profile is the policy for an easier one plus a layer: P1 is P0 applied to the orchestrator with four ports allowed; P3 is P1 with the workspace read-only and a second model policy. Second, the components do not change between profiles; they are switched on. That is what makes one CLI project for all of them the right shape for now (roadmap decision 7).

2. The simplest cases first

P0 today. sharness-ai hello builds a deny-all policy for the running interpreter, runs probes under it and reports: read allowed, writes refused, a TCP connect refused, a wrong hash runs nothing. It is the memo's acceptance test for one process and the first rung of the ladder. The caveat it prints is the gap to P1: a process that applies a policy to its children does not bind itself.

P1, the first step that binds the agent. A script on a laptop starts Claude Code under a Landlock domain and a non-root uid, with ANTHROPIC_BASE_URL pointing at sharness.llm and the built-in Bash tool removed by a bare Bash deny rule, so sharness.bash as an MCP server is the only shell. The orchestrator can execute only node, rg and the bash client; it can write only its own state folder; it can connect only to the llm and bash ports. Every side door is on Enforcing the process tree, and E06 is the experiment that tests them. Until then, Claude Code's own sandbox (bubblewrap, a network namespace, a hostname proxy) is the stand-in for sharness.bash, and a policy should be able to generate its settings (decision 9).

P2 and P3 need nothing P1 does not, except the dual-LLM split for P3: the model that reads the feed has no tools and a strict output schema; the model that plans never sees the feed. Both are two sharness.llm policies on Agents §5. P3 is where the newsroom's agents land, and their file and network behaviour policies written down are the first real test of the schema (research note §4).

3. sgit's next version: the compatibility map

sgit 0.24.0 reads the vault key in many places (the origin article counts 27 sites in 17 files). The design's rule is that an app needs harness awareness only where it handles secrets or where a policy must understand its protocol; everything else is transparent. So the map has two halves: what already works unchanged, and what changes, in steps that each leave sgit working exactly as before when nothing is switched on (the sgit pack's own compatibility document: with nothing switched on, sgit behaves as 0.24.0 does; sealed and plain clones side by side; a staged rollout).

What runs unchanged today, measured

On 24 Oct 2026, sgit 0.24.0 as installed from PyPI, under a v0 policy allowing the system and the key store read-only, no writes and no network (sharness-ai run, in one Claude agent workspace, as of 24 Oct 2026):

CommandResult
sgit --versionruns, prints sgit-ai v0.24.0
sgit pki listruns, prints No key pairs found.
sgit pki keygenreaches the passphrase prompt (interactive; not completed in the probe)
any command that writes to the clone or reaches the vault serverwould be refused by the policy as written; a P4 policy adds one writable folder and port 443

Method: sharness-ai run --policy p.json -- sgit … with files.read of /usr, /lib, /lib64, /bin, /etc and ~/.sg-send, files.write empty, network: "none". sgit --version made 36 distinct syscalls under strace -c (the design's strace -f count was 38). This is the transparent mode working for the commands that need no key and no network: nothing in sgit changed.

What changes, in steps

StepChange in sgitCompatible becausePolicy it enables
0Fix two weaknesses whatever else happens: private keys from pki keygen move from PBKDF2 at 2,048 iterations to Argon2id; Secrets__Store's fixed salt becomes per-user randomno interface changes
1The door: one Key_Source interface ("vault id and derived keys for this folder"), reading vault_key today; every call site goes through it; lazy imports per subcommandno behaviour change; the tests prove it; a smaller footprint shrinks the policy (--version opens 1,104 files today)per-subcommand L4 policies become small enough to write
2Key_Source backed by the KMS protocol: clone --sealed, vault_key.sealed, vault seal-local, vault seal --to; plain keys refused on argv when SHARNESS_AI_POLICY_HASH is set; show-key refused on a sealed clonea plain clone still works as 0.24.0 does; sealed and plain clones side by side; conversion is one command that verifies before it deletesthe key never on disk, argv or stdout; sharness.net filters traffic
3The full split: vault crypto and server I/O move into sharness.net; the app asks for operations, not keysthe app's commands and output do not change; only where the work happensthe app holds no keys and has no network at all
4sharness.fs as the only writer; later, optionally, a FUSE mountthe clone folder looks the same to every toolbusiness rules on disk enforced outside the app
5the P-256 ECDH envelope for hardware keys; commit signing with the session identityadditivehardware-backed KMS

How sgit detects it is inside the harness: the environment the launcher (or today, sharness-ai run) sets, SHARNESS_AI_POLICY_HASH and SHARNESS_AI_POLICY_ID, plus the identity file in .sg_vault/local/ naming the KMS endpoint. With neither present, sgit is 0.24.0. The per-command flows for steps 2 and 3 are drawn on Keys and the KMS §4; the full refactor path is on the Roadmap.

4. What this page does not claim

Sources: Components (transparent vs harness-aware); Agents and LLMs §2 and §5; Enforcing the process tree; Roadmap (the refactor path); Keys and the KMS §4; the sgit pack's compatibility document, linked from the source documents; the sgit probe of 24 Oct 2026 described above.