Skip to content

feat(adapters)!: any CLI version, prompts on stdin, no harness restrictions - #123

Merged
DaXu999 merged 28 commits into
mainfrom
feat/harness-any-version
Nov 9, 2026
Merged

DaXu999 merged 28 commits into
mainfrom
feat/harness-any-version

Conversation

@DaXu999

@DaXu999 DaXu999 commented Nov 9, 2026

Copy link
Copy Markdown
Collaborator

Why

SharedOS decides whether a call that reaches it over MCP is allowed, denied or escalated. What the vendor CLI does with its own tools, which servers it loads and which version it runs are the harness's and the host's. The adapters still set restrictions of SharedOS's own, passed the prompt as one argument, and read output shapes that only some CLI versions print. The DeepSeek adapter read a vocabulary its headless profile never prints, so every dsh turn completed empty. Nothing in this repository pins a CLI version; the pins live in the host images.

What

  • Breaking: SharedOS no longer restricts a harness's own tools or MCP servers. Claude Code loses --disallowedTools and --strict-mcp-config; --allowedTools mcp__<server> stays, since it only skips the approval prompt for the SharedOS server. Codex loses -c project_root_markers=[]. The DeepSeek overlay loses failOnStartupError. A host that wants any of these appends it through args or its own file. Pi is the one exception on this branch: its launch is unchanged here, and the Pi branch owns it (see Related).
  • The prompt reaches Claude Code, Codex and DeepSeek on stdin. A prompt over 128 KiB no longer fails the launch with E2BIG, and one starting with - is not read as an option. Claude's argument list ends on a flag that takes no value, so a host token appended through args is never read as a tool name.
  • Codex connects to a bridge that takes a token through bearer_token_env_var and SHAREDOS_MCP_TOKEN, which Codex requires from 0.46. A reconnect notice no longer fails the turn; the CLI's error event is a new notice step, and an interrupted turn names the last notice in its failure. A Codex run whose required bridge did not start fails harness_not_connected with Codex's reason, and the process is ended.
  • DeepSeek runs its headless profile with --json and the new deepseekHeadlessProtocol reads that stream: output is final.text, the outcome comes from final.reason or the exit code. A run whose MCP client never reached the bridge fails harness_not_connected and dsh is ended, instead of doing the task with its own tools while the turn waited.
  • Claude Code results are read by subtype on every version. Any non-success result fails the turn; an API error's code is the frame's terminal_reason; retryability reads api_error_status first and then the words Claude Code 2.1.319 writes.
  • McpHarnessSpec.readDiagnostic lets a spec read stderr and non-frame stdout lines until the turn has an outcome, and may only fail a turn. HarnessProcess delivers stderr by the line. probeHarness takes an AbortSignal. An outcome at the ignored-frame limit ends the turn instead of failing it.
  • Conformance. mcp-conformance declares each CLI's own tools as harnessLocal and records the policy as the host's declaration. native-conformance runs each CLI with its own tools and records a CLI's own tool calls as run by the harness under harnessRan, not as refused. ADR 0014 gains a dated amendment.
  • Docs record the CLI versions each launch was found to need, as information: SharedOS enforces no floor.

27 files: 2,443 lines added, 417 removed. Of those, regenerated docs/api is 165 added and 59 removed, and tests are 1,026 added and 93 removed.

What a host has to update

The full list is in the CHANGELOG under Unreleased. The ones most likely to matter:

  • Claude Code, Codex and Pi seats now have the CLI's own tools and the machine's other MCP servers. A host that wants a restriction passes the CLI's own flag through args.
  • A host that writes Codex's config.toml itself sets SHAREDOS_MCP_TOKEN in Codex's environment; inline bearer_token is gone.
  • A host whose workspaceRoot sits inside a repository appends -c project_root_markers=[] for Codex.
  • HarnessStep has a new kind, notice. McpHarnessSpec.readDiagnostic and onDiagnostic lines are per line, not per chunk.
  • New exports: deepseekHeadlessProtocol, DEEPSEEK_HEADLESS_PROTOCOL_ID, SHAREDOS_MCP_TOKEN_VARIABLE, deepseekMcpEntryId. New error code harness_not_connected.

Related

Supersedes #120, whose merge commit was removed from main so this branch could be rebased onto #119 and checked on that base before merging. Same 28 commits, same tree.

Follow-up to #118. Siblings off main: the Pi branch, which moves Pi to its native MCP client and owns every Pi change, including dropping --no-builtin-tools and --no-session, and rebases onto main after this merges; and the limit-notice branch, which tells the model its limits.

Checks

  • pnpm check is green: format, typecheck, vitest 1205, test:release 7/7, docs:api:check and conformance:check (172 pass, manifest up to date).
  • Each CLI behaviour named above was checked against the installed binary without a paid model call: Claude Code 2.1.319, Codex 0.167.0 (and 0.46, 0.98, 0.99 for required), dsh 0.2.2-rc.1, with a stand-in model endpoint where a turn had to run.
  • Reviewed by a second agent; every finding is fixed on the branch.

@DaXu999
DaXu999 merged commit 5f81a0e into main Nov 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant